File size: 3,843 Bytes
0491fc6 33f8f7c 0491fc6 5c18c00 059bbb9 5c18c00 059bbb9 07d1566 0491fc6 5c18c00 059bbb9 5c18c00 33f8f7c 07d1566 0491fc6 5c18c00 0491fc6 5c18c00 0491fc6 5c18c00 0491fc6 5c18c00 0491fc6 5c18c00 0491fc6 5c18c00 07d1566 0491fc6 217266f 0491fc6 059bbb9 5c18c00 ae24aac |
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 110 111 112 113 114 115 116 117 118 119 |
from flask import Flask, request, jsonify, Response
import random
import string
import threading
import time
import os
from pathlib import Path
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 12 * 1024 * 1024 * 1024 # 12GB
UPLOAD_FOLDER = Path('uploads')
UPLOAD_FOLDER.mkdir(exist_ok=True)
transfers = {}
transfer_lock = threading.Lock()
TIMEOUT = 3600 # 1 час
CHUNK_SIZE = 1024 * 1024 # 1MB
def generate_short_id(length=10):
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():
filename = request.json.get('filename')
filesize = request.json.get('filesize', 0)
transfer_id = generate_short_id()
file_path = UPLOAD_FOLDER / f"{transfer_id}.dat"
with transfer_lock:
transfers[transfer_id] = {
'filename': filename,
'filesize': filesize,
'completed': False,
'last_activity': time.time(),
'file_path': file_path,
'file_handle': open(file_path, 'wb')
}
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
transfer = transfers[transfer_id]
transfer['last_activity'] = time.time()
try:
# Записываем полученные данные в файл
data = request.data
transfer['file_handle'].write(data)
transfer['file_handle'].flush()
if request.headers.get('X-Transfer-Complete') == 'true':
transfer['completed'] = True
transfer['file_handle'].close()
return jsonify({'status': 'chunk uploaded', 'received': len(data)})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/download/<transfer_id>', methods=['GET'])
def download_file(transfer_id):
def generate():
file_path = None
with transfer_lock:
if transfer_id not in transfers:
yield b'Transfer expired'
return
transfer = transfers[transfer_id]
file_path = transfer['file_path']
transfer['last_activity'] = time.time()
if not file_path.exists():
yield b'File not found'
return
with open(file_path, 'rb') as f:
while True:
chunk = f.read(CHUNK_SIZE)
if not chunk:
break
yield chunk
return Response(
generate(),
mimetype='application/octet-stream',
headers={'Content-Disposition': f'attachment; filename="{transfers[transfer_id]["filename"]}"'}
)
def cleanup_thread():
while True:
time.sleep(60 * 5) # Проверка каждые 5 минут
with transfer_lock:
now = time.time()
expired = []
for tid, t in transfers.items():
if now - t['last_activity'] > TIMEOUT:
expired.append(tid)
if 'file_handle' in t and not t['file_handle'].closed:
t['file_handle'].close()
if t['file_path'].exists():
t['file_path'].unlink()
for tid in expired:
del transfers[tid]
threading.Thread(target=cleanup_thread, daemon=True).start()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, threaded=True) |