|
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() |
|
|
|
|
|
KEEP_ALIVE_INTERVAL = 10 |
|
TRANSFER_TIMEOUT = 3600 |
|
|
|
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 |
|
|
|
@app.route('/download/<transfer_id>', methods=['GET']) |
|
def download_file(transfer_id): |
|
def generate(): |
|
last_activity = time.time() |
|
index = 0 |
|
|
|
while True: |
|
with transfer_lock: |
|
|
|
if time.time() - last_activity > TRANSFER_TIMEOUT: |
|
break |
|
|
|
transfer = transfers.get(transfer_id) |
|
if not transfer: |
|
break |
|
|
|
chunks = transfer_data.get(transfer_id, []) |
|
|
|
|
|
while index < len(chunks): |
|
yield chunks[index] |
|
last_activity = time.time() |
|
index += 1 |
|
|
|
if transfer['completed']: |
|
break |
|
|
|
|
|
if time.time() - last_activity > KEEP_ALIVE_INTERVAL: |
|
yield b'\0' |
|
last_activity = time.time() |
|
|
|
time.sleep(0.5) |
|
|
|
return Response( |
|
generate(), |
|
mimetype='application/octet-stream', |
|
headers={ |
|
'Content-Disposition': f'attachment; filename="{transfers[transfer_id]["filename"]}"', |
|
'Cache-Control': 'no-store' |
|
} |
|
) |