parthmax commited on
Commit
4ab541b
Β·
verified Β·
1 Parent(s): 9de8bc6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -65
app.py CHANGED
@@ -1,6 +1,5 @@
1
  from fastapi import FastAPI, UploadFile, Request
2
  from fastapi.responses import FileResponse, HTMLResponse
3
- from fastapi.templating import Jinja2Templates
4
  from fastapi.middleware.cors import CORSMiddleware
5
  import os
6
  import uuid
@@ -10,83 +9,105 @@ import threading
10
  app = FastAPI()
11
 
12
  # CORS
13
-
14
  app.add_middleware(
15
- CORSMiddleware,
16
- allow_origins=["*"],
17
- allow_credentials=True,
18
- allow_methods=["*"],
19
- allow_headers=["*"],
20
  )
21
 
22
- templates = Jinja2Templates(directory="templates")
23
-
24
  UPLOAD_DIR = "uploads"
25
  os.makedirs(UPLOAD_DIR, exist_ok=True)
26
 
27
- # Store file timestamps
28
-
29
  file_times = {}
 
30
 
31
- # Serve frontend
32
-
33
  @app.get("/", response_class=HTMLResponse)
34
- def home(request: Request):
35
- return templates.TemplateResponse("index.html", {"request": request})
36
-
37
- # Upload
38
 
 
39
  @app.post("/upload")
40
  async def upload(file: UploadFile):
41
- file_id = str(uuid.uuid4())[:8]
42
- filename = file.filename.replace(" ", "*")
43
- file_path = f"{UPLOAD_DIR}/{file_id}*{filename}"
44
-
45
- ```
46
- with open(file_path, "wb") as f:
47
- f.write(await file.read())
48
-
49
- # Save upload time
50
- file_times[file_path] = time.time()
51
-
52
- return {"link": f"/file/{file_id}_{filename}"}
53
- ```
54
-
55
- # Download
56
-
57
- @app.get("/file/{filename}")
58
- def get_file(filename: str):
59
- file_path = f"{UPLOAD_DIR}/{filename}"
60
-
61
- ```
62
- if not os.path.exists(file_path):
63
- return {"error": "File expired or not found"}
64
-
65
- return FileResponse(file_path)
66
- ```
67
-
68
- # 🧹 AUTO DELETE THREAD
69
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  def cleanup_files():
71
- while True:
72
- now = time.time()
73
-
74
- ```
75
- for path in list(file_times.keys()):
76
- if now - file_times[path] > 300: # 5 minutes = 300 sec
77
- if os.path.exists(path):
78
- os.remove(path)
79
- del file_times[path]
80
-
81
- time.sleep(60) # check every 1 minute
82
- ```
83
-
84
- # Start cleanup thread
85
 
86
  threading.Thread(target=cleanup_files, daemon=True).start()
87
 
88
- # Run
89
-
90
- if **name** == "**main**":
91
- import uvicorn
92
- uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=True)
 
1
  from fastapi import FastAPI, UploadFile, Request
2
  from fastapi.responses import FileResponse, HTMLResponse
 
3
  from fastapi.middleware.cors import CORSMiddleware
4
  import os
5
  import uuid
 
9
  app = FastAPI()
10
 
11
  # CORS
 
12
  app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
  )
19
 
 
 
20
  UPLOAD_DIR = "uploads"
21
  os.makedirs(UPLOAD_DIR, exist_ok=True)
22
 
23
+ # Store file metadata: path -> {time, original_name}
 
24
  file_times = {}
25
+ file_meta = {}
26
 
27
+ # ── Serve frontend ────────────────────────────────────────────────────────────
 
28
  @app.get("/", response_class=HTMLResponse)
29
+ def home():
30
+ with open("templates/index.html", "r") as f:
31
+ return HTMLResponse(content=f.read())
 
32
 
33
+ # ── Upload ────────────────────────────────────────────────────────────────────
34
  @app.post("/upload")
35
  async def upload(file: UploadFile):
36
+ file_id = str(uuid.uuid4())[:8]
37
+ # Sanitize filename β€” replace spaces with underscores, keep extension safe
38
+ safe_name = file.filename.replace(" ", "_")
39
+ file_path = os.path.join(UPLOAD_DIR, f"{file_id}_{safe_name}")
40
+
41
+ with open(file_path, "wb") as f:
42
+ f.write(await file.read())
43
+
44
+ # Save upload time and original name
45
+ file_times[file_path] = time.time()
46
+ file_meta[file_path] = file.filename
47
+
48
+ download_id = f"{file_id}_{safe_name}"
49
+ return {
50
+ "link": f"/file/{download_id}",
51
+ "file_id": download_id,
52
+ "original_name": file.filename,
53
+ "expires_in": 300,
54
+ }
55
+
56
+ # ── Download ──────────────────────────────────────────────────────────────────
57
+ @app.get("/file/{file_id:path}")
58
+ def get_file(file_id: str):
59
+ file_path = os.path.join(UPLOAD_DIR, file_id)
60
+
61
+ if not os.path.exists(file_path):
62
+ from fastapi.responses import JSONResponse
63
+ return JSONResponse(status_code=404, content={"error": "File expired or not found"})
64
+
65
+ # Check if expired (extra safety check)
66
+ if file_path in file_times:
67
+ if time.time() - file_times[file_path] > 300:
68
+ if os.path.exists(file_path):
69
+ os.remove(file_path)
70
+ file_times.pop(file_path, None)
71
+ file_meta.pop(file_path, None)
72
+ from fastapi.responses import JSONResponse
73
+ return JSONResponse(status_code=410, content={"error": "File has expired"})
74
+
75
+ original_name = file_meta.get(file_path, os.path.basename(file_path))
76
+ return FileResponse(
77
+ file_path,
78
+ filename=original_name,
79
+ headers={"Content-Disposition": f'attachment; filename="{original_name}"'},
80
+ )
81
+
82
+ # ── File status endpoint (for countdown UI) ───────────────────────────────────
83
+ @app.get("/status/{file_id:path}")
84
+ def file_status(file_id: str):
85
+ file_path = os.path.join(UPLOAD_DIR, file_id)
86
+ if file_path not in file_times:
87
+ return {"exists": False}
88
+ elapsed = time.time() - file_times[file_path]
89
+ remaining = max(0, 300 - elapsed)
90
+ return {
91
+ "exists": os.path.exists(file_path),
92
+ "remaining_seconds": int(remaining),
93
+ "original_name": file_meta.get(file_path, ""),
94
+ }
95
+
96
+ # ── Auto-delete thread ────────────────────────────────────────────────────────
97
  def cleanup_files():
98
+ while True:
99
+ now = time.time()
100
+ for path in list(file_times.keys()):
101
+ if now - file_times[path] > 300: # 5 minutes
102
+ if os.path.exists(path):
103
+ os.remove(path)
104
+ file_times.pop(path, None)
105
+ file_meta.pop(path, None)
106
+ time.sleep(60) # check every 1 minute
 
 
 
 
 
107
 
108
  threading.Thread(target=cleanup_files, daemon=True).start()
109
 
110
+ # ── Run ───────────────────────────────────────────────────────────────────────
111
+ if __name__ == "__main__":
112
+ import uvicorn
113
+ uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=True)