File size: 2,332 Bytes
0b67e3c
 
9cb9bf5
0b67e3c
 
 
 
059bbb9
0b67e3c
 
059bbb9
0b67e3c
 
 
 
 
33f8f7c
0b67e3c
 
 
 
 
 
 
 
 
0491fc6
0b67e3c
 
 
 
 
 
 
 
 
 
 
 
 
6048a58
0b67e3c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
07d1566
0b67e3c
 
 
 
 
 
 
 
059bbb9
0b67e3c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from flask import Flask, request, jsonify, Response
from flask_executor import Executor
import uuid
import time
import logging
from collections import defaultdict, deque
from threading import Lock

app = Flask(__name__)
executor = Executor(app)

# Хранилище для передачи чанков
transfers = defaultdict(deque)
locks = defaultdict(Lock)
metadata = {}
CHUNK_TIMEOUT = 300  # 5 минут

@app.route('/create_transfer', methods=['POST'])
def create_transfer():
    transfer_id = str(uuid.uuid4())
    metadata[transfer_id] = {
        'filename': request.json.get('filename', 'file'),
        'created_at': time.time(),
        'completed': False
    }
    return jsonify({'transfer_id': transfer_id})

@app.route('/upload/<transfer_id>', methods=['POST'])
def upload_chunk(transfer_id):
    if transfer_id not in metadata:
        return jsonify({'error': 'Invalid transfer ID'}), 404
    
    with locks[transfer_id]:
        chunk = request.data
        if chunk:
            transfers[transfer_id].append(chunk)
        else:
            metadata[transfer_id]['completed'] = True
    
    return jsonify({'status': 'ok'})

@app.route('/stream/<transfer_id>')
def stream_chunks(transfer_id):
    def generate():
        last_activity = time.time()
        
        while True:
            with locks[transfer_id]:
                if transfers[transfer_id]:
                    chunk = transfers[transfer_id].popleft()
                    last_activity = time.time()
                    yield chunk
                elif metadata.get(transfer_id, {}).get('completed', False):
                    break
                elif time.time() - last_activity > CHUNK_TIMEOUT:
                    break
            
            time.sleep(0.1)  # Задержка для уменьшения нагрузки
        
        # Очистка данных
        if transfer_id in metadata:
            del metadata[transfer_id]
            del transfers[transfer_id]
            del locks[transfer_id]

    return Response(
        generate(),
        mimetype='application/octet-stream',
        headers={
            'Content-Disposition': f'attachment; filename="{metadata[transfer_id]["filename"]}"',
            'Transfer-Encoding': 'chunked'
        }
    )

if __name__ == '__main__':
    app.run(debug=True)