Bot commited on
Commit
ba1ea05
·
1 Parent(s): b1853e0

Add storage, delete_all, history, and auto-cleanup

Browse files
Files changed (1) hide show
  1. app.py +50 -6
app.py CHANGED
@@ -2,6 +2,7 @@ import asyncio
2
  import os
3
  import time
4
  import uuid
 
5
  import aiohttp
6
  from fastapi import FastAPI, BackgroundTasks, Request
7
  from fastapi.responses import FileResponse, StreamingResponse
@@ -9,8 +10,7 @@ from pydantic import BaseModel
9
 
10
  app = FastAPI()
11
 
12
- # In-memory store for download tasks
13
- # tasks = { "task_id": { "url": str, "status": "downloading"|"completed"|"error", "total_size": int, "downloaded": int, "speed": float, "file_path": str } }
14
  tasks = {}
15
 
16
  DATA_DIR = "/data"
@@ -19,15 +19,39 @@ os.makedirs(DATA_DIR, exist_ok=True)
19
  class DownloadRequest(BaseModel):
20
  url: str
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  async def download_file(task_id: str, url: str):
23
  file_path = os.path.join(DATA_DIR, f"{task_id}.bin")
24
  tasks[task_id] = {
 
25
  "url": url,
26
  "status": "downloading",
27
  "total_size": 0,
28
  "downloaded": 0,
29
  "speed": 0.0,
30
- "file_path": file_path
 
31
  }
32
 
33
  try:
@@ -43,7 +67,7 @@ async def download_file(task_id: str, url: str):
43
  last_downloaded = 0
44
 
45
  with open(file_path, 'wb') as f:
46
- async for chunk in response.content.iter_chunked(1024 * 1024): # 1MB chunks to save memory
47
  if not chunk:
48
  break
49
  f.write(chunk)
@@ -51,7 +75,7 @@ async def download_file(task_id: str, url: str):
51
  tasks[task_id]["downloaded"] = downloaded
52
 
53
  current_time = time.time()
54
- if current_time - last_time >= 1.0: # Update speed every second
55
  speed = (downloaded - last_downloaded) / (current_time - last_time)
56
  tasks[task_id]["speed"] = speed
57
  last_time = current_time
@@ -91,7 +115,6 @@ async def stream(task_id: str, request: Request):
91
 
92
  range_header = request.headers.get("Range")
93
  if range_header:
94
- # Simple range request handling for streaming
95
  byte1, byte2 = 0, None
96
  match = range_header.replace("bytes=", "").split("-")
97
  if match[0]:
@@ -124,6 +147,27 @@ async def stream(task_id: str, request: Request):
124
  else:
125
  return FileResponse(file_path)
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  if __name__ == "__main__":
128
  import uvicorn
129
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
2
  import os
3
  import time
4
  import uuid
5
+ import shutil
6
  import aiohttp
7
  from fastapi import FastAPI, BackgroundTasks, Request
8
  from fastapi.responses import FileResponse, StreamingResponse
 
10
 
11
  app = FastAPI()
12
 
13
+ # tasks = { "task_id": { ... } }
 
14
  tasks = {}
15
 
16
  DATA_DIR = "/data"
 
19
  class DownloadRequest(BaseModel):
20
  url: str
21
 
22
+ async def cleanup_old_files():
23
+ while True:
24
+ try:
25
+ now = time.time()
26
+ for filename in os.listdir(DATA_DIR):
27
+ filepath = os.path.join(DATA_DIR, filename)
28
+ if os.path.isfile(filepath):
29
+ # 24 hours = 86400 seconds
30
+ if now - os.path.getmtime(filepath) > 86400:
31
+ os.remove(filepath)
32
+ # Remove from tasks if exists
33
+ for tid, tinfo in list(tasks.items()):
34
+ if tinfo.get("file_path") == filepath:
35
+ del tasks[tid]
36
+ except Exception as e:
37
+ print(f"Cleanup error: {e}")
38
+ await asyncio.sleep(3600) # Check every hour
39
+
40
+ @app.on_event("startup")
41
+ async def startup_event():
42
+ asyncio.create_task(cleanup_old_files())
43
+
44
  async def download_file(task_id: str, url: str):
45
  file_path = os.path.join(DATA_DIR, f"{task_id}.bin")
46
  tasks[task_id] = {
47
+ "task_id": task_id,
48
  "url": url,
49
  "status": "downloading",
50
  "total_size": 0,
51
  "downloaded": 0,
52
  "speed": 0.0,
53
+ "file_path": file_path,
54
+ "timestamp": time.time()
55
  }
56
 
57
  try:
 
67
  last_downloaded = 0
68
 
69
  with open(file_path, 'wb') as f:
70
+ async for chunk in response.content.iter_chunked(1024 * 1024):
71
  if not chunk:
72
  break
73
  f.write(chunk)
 
75
  tasks[task_id]["downloaded"] = downloaded
76
 
77
  current_time = time.time()
78
+ if current_time - last_time >= 1.0:
79
  speed = (downloaded - last_downloaded) / (current_time - last_time)
80
  tasks[task_id]["speed"] = speed
81
  last_time = current_time
 
115
 
116
  range_header = request.headers.get("Range")
117
  if range_header:
 
118
  byte1, byte2 = 0, None
119
  match = range_header.replace("bytes=", "").split("-")
120
  if match[0]:
 
147
  else:
148
  return FileResponse(file_path)
149
 
150
+ @app.get("/storage")
151
+ async def get_storage():
152
+ total, used, free = shutil.disk_usage(DATA_DIR)
153
+ return {"total": total, "used": used, "free": free}
154
+
155
+ @app.post("/delete_all")
156
+ async def delete_all():
157
+ for filename in os.listdir(DATA_DIR):
158
+ filepath = os.path.join(DATA_DIR, filename)
159
+ try:
160
+ if os.path.isfile(filepath):
161
+ os.remove(filepath)
162
+ except Exception as e:
163
+ print(f"Failed to delete {filepath}: {e}")
164
+ tasks.clear()
165
+ return {"status": "success"}
166
+
167
+ @app.get("/history")
168
+ async def get_history():
169
+ return {"history": list(tasks.values())}
170
+
171
  if __name__ == "__main__":
172
  import uvicorn
173
  uvicorn.run(app, host="0.0.0.0", port=7860)