File size: 3,608 Bytes
3205dff a460fdc 146248c b86f530 059bbb9 0b67e3c 146248c 5bb5d81 059bbb9 b86f530 be00d02 5bb5d81 33f8f7c 5bb5d81 b86f530 3205dff 5bb5d81 b86f530 5bb5d81 b86f530 5bb5d81 a71ce8a b86f530 5bb5d81 3205dff b86f530 5bb5d81 b86f530 3205dff b86f530 3205dff 5bb5d81 b86f530 5bb5d81 b86f530 a71ce8a b86f530 5bb5d81 a71ce8a b86f530 a71ce8a 059bbb9 0b67e3c b86f530 |
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
from flask import Flask, request, jsonify, Response
import random
import string
import threading
import time
from datetime import datetime, timedelta
app = Flask(__name__)
transfers = {}
transfer_data = {}
transfer_lock = threading.Lock()
# Настройки хранения данных
TRANSFER_LIFETIME = timedelta(hours=1) # Время хранения завершенных передач
CLEANUP_INTERVAL = 3600 # 5 минут в секундах
def cleanup_task():
"""Фоновая задача для очистки старых передач"""
while True:
time.sleep(CLEANUP_INTERVAL)
with transfer_lock:
now = datetime.now()
to_delete = []
for transfer_id, info in transfers.items():
if info['completed'] and (now - info['completed_time']) > TRANSFER_LIFETIME:
to_delete.append(transfer_id)
for transfer_id in to_delete:
del transfers[transfer_id]
del transfer_data[transfer_id]
threading.Thread(target=cleanup_task, daemon=True).start()
def generate_short_id(length=4):
while True:
token = ''.join(random.choices(string.ascii_letters + string.digits, k=length))
if token not in transfers:
return token
@app.route('/create_transfer', methods=['POST'])
def create_transfer():
data = request.json
transfer_id = generate_short_id()
with transfer_lock:
transfers[transfer_id] = {
'filename': data['filename'],
'filesize': data.get('filesize', 0),
'completed': False,
'created_time': datetime.now(),
'completed_time': None
}
transfer_data[transfer_id] = []
return jsonify({'transfer_id': transfer_id})
@app.route('/upload/<transfer_id>', methods=['POST'])
def upload_chunk(transfer_id):
if transfer_id not in transfers:
return jsonify({'error': 'Invalid transfer ID'}), 404
chunk = request.data
with transfer_lock:
transfer_data[transfer_id].append(chunk)
if request.headers.get('X-Transfer-Complete') == 'true':
transfers[transfer_id]['completed'] = True
transfers[transfer_id]['completed_time'] = datetime.now()
return jsonify({'status': 'chunk accepted'})
@app.route('/download/<transfer_id>', methods=['GET'])
def download_file(transfer_id):
def generate():
index = 0
while True:
with transfer_lock:
transfer = transfers.get(transfer_id)
if not transfer:
break
chunks = transfer_data.get(transfer_id, [])
# Отправляем все новые чанки
while index < len(chunks):
yield chunks[index]
index += 1
# Проверяем завершение передачи
if transfer['completed']:
break
time.sleep(1) # Ожидание новых чанков
if transfer_id not in transfers:
return jsonify({'error': 'Transfer not found'}), 404
return Response(
generate(),
mimetype='application/octet-stream',
headers={
'Content-Disposition': f'attachment; filename="{transfers[transfer_id]["filename"]}"',
'Transfer-Encoding': 'chunked'
}
)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, threaded=True) |