|
from flask import Flask, request, jsonify, Response |
|
import random |
|
import string |
|
import threading |
|
from queue import Queue |
|
|
|
app = Flask(__name__) |
|
transfer_queues = {} |
|
lock = threading.Lock() |
|
|
|
def generate_id(): |
|
return ''.join(random.choices(string.ascii_letters + string.digits, k=8)) |
|
|
|
@app.route('/create_transfer', methods=['POST']) |
|
def create_transfer(): |
|
transfer_id = generate_id() |
|
with lock: |
|
transfer_queues[transfer_id] = { |
|
'queue': Queue(maxsize=10), |
|
'filename': request.json['filename'], |
|
'active': False |
|
} |
|
return jsonify({'transfer_id': transfer_id}) |
|
|
|
@app.route('/upload/<transfer_id>', methods=['POST']) |
|
def upload(transfer_id): |
|
if transfer_id not in transfer_queues: |
|
return jsonify({'error': 'Invalid ID'}), 404 |
|
|
|
chunk = request.data |
|
try: |
|
transfer_queues[transfer_id]['queue'].put(chunk, timeout=30) |
|
return jsonify({'status': 'ok'}) |
|
except: |
|
return jsonify({'error': 'Receiver not connected'}), 408 |
|
|
|
@app.route('/download/<transfer_id>') |
|
def download(transfer_id): |
|
def generate(): |
|
with lock: |
|
if transfer_id not in transfer_queues: |
|
yield 'Transfer ID invalid' |
|
return |
|
|
|
transfer = transfer_queues[transfer_id] |
|
transfer['active'] = True |
|
|
|
try: |
|
while True: |
|
chunk = transfer['queue'].get(timeout=30) |
|
yield chunk |
|
except: |
|
transfer_queues.pop(transfer_id, None) |
|
|
|
headers = { |
|
'Content-Disposition': f'attachment; filename="{transfer_queues[transfer_id]["filename"]}"' |
|
} |
|
return Response(generate(), mimetype='application/octet-stream', headers=headers) |
|
|
|
if __name__ == '__main__': |
|
app.run(host='0.0.0.0', port=5000, threaded=True) |