File size: 3,509 Bytes
0491fc6 33f8f7c 0491fc6 56921b4 059bbb9 07d1566 0491fc6 56921b4 059bbb9 33f8f7c 56921b4 07d1566 0491fc6 33f8f7c 0491fc6 56921b4 0491fc6 56921b4 0491fc6 56921b4 0491fc6 56921b4 0491fc6 56921b4 0491fc6 56921b4 0491fc6 56921b4 07d1566 56921b4 0491fc6 56921b4 0491fc6 059bbb9 56921b4 |
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 |
from flask import Flask, request, jsonify, Response
import random
import string
from collections import deque
import threading
from datetime import datetime, timedelta
app = Flask(__name__)
transfers = {}
transfer_data = {}
transfer_lock = threading.Lock()
CLEANUP_INTERVAL = 300 # 5 минут
def generate_short_id(length=8):
while True:
token = ''.join(random.choices(string.ascii_letters + string.digits, k=length))
if token not in transfers:
return token
def cleanup_old_transfers():
while True:
now = datetime.now()
with transfer_lock:
to_delete = []
for transfer_id, data in transfers.items():
if now - data['last_activity'] > timedelta(seconds=CLEANUP_INTERVAL):
to_delete.append(transfer_id)
for transfer_id in to_delete:
del transfers[transfer_id]
del transfer_data[transfer_id]
threading.Event().wait(CLEANUP_INTERVAL)
@app.route('/create_transfer', methods=['POST'])
def create_transfer():
filename = request.json.get('filename')
filesize = request.json.get('filesize', 0)
transfer_id = generate_short_id(8)
with transfer_lock:
transfers[transfer_id] = {
'filename': filename,
'filesize': filesize,
'created': datetime.now(),
'last_activity': datetime.now(),
'completed': False
}
transfer_data[transfer_id] = deque()
return jsonify({'transfer_id': transfer_id})
@app.route('/upload/<transfer_id>', methods=['POST'])
def upload_file(transfer_id):
with transfer_lock:
if transfer_id not in transfers:
return jsonify({'error': 'Invalid transfer ID'}), 404
transfers[transfer_id]['last_activity'] = datetime.now()
data = request.data
if data:
transfer_data[transfer_id].append(data)
if request.headers.get('X-Transfer-Complete') == 'true':
transfers[transfer_id]['completed'] = True
return jsonify({'status': 'OK', 'received': len(data)})
@app.route('/download/<transfer_id>', methods=['GET'])
def download_file(transfer_id):
def generate():
with transfer_lock:
if transfer_id not in transfers:
return
transfers[transfer_id]['last_activity'] = datetime.now()
transfer = transfers[transfer_id]
data_queue = transfer_data[transfer_id]
while True:
with transfer_lock:
if data_queue:
chunk = bytes(data_queue.popleft())
yield chunk
elif transfer['completed']:
break
else:
# Ждем новые данные
pass
threading.Event().wait(0.1)
if transfer_id not in transfers:
return jsonify({'error': 'Invalid transfer ID'}), 404
return Response(
generate(),
mimetype='application/octet-stream',
headers={
'Content-Disposition': f'attachment; filename="{transfers[transfer_id]["filename"]}"',
'Content-Length': str(transfers[transfer_id]['filesize'])
}
)
if __name__ == '__main__':
threading.Thread(target=cleanup_old_transfers, daemon=True).start()
app.run(host='0.0.0.0', port=7860, threaded=True) |