Anish commited on
Commit
e000e33
·
1 Parent(s): 8bdb51c

[Updated Feature] > Updated every file_route, user_route, so that guest users can login and only upload 5 videos, 1 image per IP

Browse files
backend/app/ai/video/aggregator.py CHANGED
@@ -5,7 +5,7 @@ logger = logging.getLogger(__name__)
5
 
6
  WEIGHTS = {
7
  "frames": 0.40,
8
- "motion": 0.20,
9
  "noise": 0.15,
10
  "diffusion": 0.15,
11
  "metadata": 0.10
 
5
 
6
  WEIGHTS = {
7
  "frames": 0.40,
8
+ "motion": 0.20,
9
  "noise": 0.15,
10
  "diffusion": 0.15,
11
  "metadata": 0.10
backend/app/api/file_routes.py CHANGED
@@ -1,15 +1,17 @@
1
- from fastapi import APIRouter, Depends, UploadFile, File as FastAPIFile, Request, Header
2
  from sqlalchemy.orm import Session
3
  from app.db.session import get_db
4
- from app.core.auth_dependancy import get_current_user
5
  from app.services.file_service import upload_file_service
6
  from app.services.file_query_service import get_user_files
7
  from app.services.file_detail_service import get_file_detail
8
  from app.services.file_delete_service import delete_file_service
9
  from app.models.user_model import User
10
- from app.worker.tasks import process_file_task
11
  from app.core.limiter import limiter
12
  from app.security.turnstile import verify_turnstile_token
 
 
13
 
14
  router = APIRouter(prefix="/files", tags=["files"])
15
 
@@ -51,11 +53,20 @@ def list_user_files(
51
  @router.get("/{file_id}")
52
  def get_file(
53
  file_id: int,
 
54
  db: Session = Depends(get_db),
55
- current_user: User = Depends(get_current_user)
56
  ):
57
- file = get_file_detail(db, file_id, current_user.id)
58
-
 
 
 
 
 
 
 
 
59
  return format_file_response(file)
60
 
61
  @router.post("/upload")
@@ -65,18 +76,43 @@ async def upload_file(
65
  file: UploadFile = FastAPIFile(...),
66
  cf_turnstile_response: str = Header(None, alias="cf-turnstile-response"),
67
  db: Session = Depends(get_db),
68
- current_user: User = Depends(get_current_user)
69
  ):
70
  client_ip = request.client.host
71
  await verify_turnstile_token(cf_turnstile_response, client_ip)
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  saved_file = upload_file_service(
74
  db=db,
75
  file=file,
76
- user_id=current_user.id
 
77
  )
78
 
79
  process_file_task.delay(saved_file.id)
 
 
 
80
 
81
  return {
82
  "message": "File uploaded. Processing started",
 
1
+ from fastapi import APIRouter, Depends, UploadFile, File as FastAPIFile, Request, Header, HTTPException
2
  from sqlalchemy.orm import Session
3
  from app.db.session import get_db
4
+ from app.core.auth_dependancy import get_current_user, get_optional_user
5
  from app.services.file_service import upload_file_service
6
  from app.services.file_query_service import get_user_files
7
  from app.services.file_detail_service import get_file_detail
8
  from app.services.file_delete_service import delete_file_service
9
  from app.models.user_model import User
10
+ from app.worker.tasks import process_file_task, delete_guest_file_task
11
  from app.core.limiter import limiter
12
  from app.security.turnstile import verify_turnstile_token
13
+ from datetime import datetime, UTC
14
+ from app.models.file_model import File
15
 
16
  router = APIRouter(prefix="/files", tags=["files"])
17
 
 
53
  @router.get("/{file_id}")
54
  def get_file(
55
  file_id: int,
56
+ request: Request,
57
  db: Session = Depends(get_db),
58
+ current_user: User = Depends(get_optional_user)
59
  ):
60
+ file = db.query(File).filter(File.id == file_id).first()
61
+ if not file:
62
+ raise HTTPException(status_code=404, detail="File not found")
63
+
64
+ if file.owner_id is not None:
65
+ if not current_user or current_user.id != file.owner_id:
66
+ raise HTTPException(status_code=403, detail="Not authorized")
67
+ else:
68
+ if request.client.host != file.ip_address:
69
+ raise HTTPException(status_code=403, detail="Not authorized for this guest file")
70
  return format_file_response(file)
71
 
72
  @router.post("/upload")
 
76
  file: UploadFile = FastAPIFile(...),
77
  cf_turnstile_response: str = Header(None, alias="cf-turnstile-response"),
78
  db: Session = Depends(get_db),
79
+ current_user: User = Depends(get_optional_user)
80
  ):
81
  client_ip = request.client.host
82
  await verify_turnstile_token(cf_turnstile_response, client_ip)
83
 
84
+ if not current_user:
85
+ today = datetime.now(UTC).date()
86
+ today_start = datetime(today.year, today.month, today.day, tzinfo=UTC)
87
+
88
+ guest_files = db.query(File).filter(
89
+ File.ip_address == client_ip,
90
+ File.owner_id == None,
91
+ File.created_at >= today_start
92
+ ).all()
93
+
94
+ videos_count = sum(1 for f in guest_files if f.filetype.startswith("video/"))
95
+ images_count = sum(1 for f in guest_files if f.filetype.startswith("image/"))
96
+ is_video = file.content_type.startswith("video/")
97
+
98
+ if is_video and videos_count >= 1:
99
+ raise HTTPException(status_code=429, detail="Guest limit reached: 1 Video per day. Please login.")
100
+ elif not is_video and images_count >= 5:
101
+ raise HTTPException(status_code=429, detail="Guest limit reached: 5 Images per day. Please login.")
102
+
103
+ user_id = current_user.id if current_user else None
104
+
105
  saved_file = upload_file_service(
106
  db=db,
107
  file=file,
108
+ user_id=user_id,
109
+ ip_address=client_ip
110
  )
111
 
112
  process_file_task.delay(saved_file.id)
113
+
114
+ if not current_user:
115
+ delete_guest_file_task.apply_async((saved_file.id,), countdown=900)
116
 
117
  return {
118
  "message": "File uploaded. Processing started",
backend/app/core/auth_dependancy.py CHANGED
@@ -5,8 +5,10 @@ from app.core.config import settings
5
  from sqlalchemy.orm import Session
6
  from app.db.session import get_db
7
  from app.models.user_model import User
 
8
 
9
  security = HTTPBearer()
 
10
 
11
  def get_current_user(
12
  credentials: HTTPAuthorizationCredentials = Depends(security),
@@ -29,4 +31,22 @@ def get_current_user(
29
  if user is None:
30
  raise HTTPException(status_code=401, detail="User not found")
31
 
32
- return user
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  from sqlalchemy.orm import Session
6
  from app.db.session import get_db
7
  from app.models.user_model import User
8
+ from typing import Optional
9
 
10
  security = HTTPBearer()
11
+ optional_security = HTTPBearer(auto_error=False)
12
 
13
  def get_current_user(
14
  credentials: HTTPAuthorizationCredentials = Depends(security),
 
31
  if user is None:
32
  raise HTTPException(status_code=401, detail="User not found")
33
 
34
+ return user
35
+
36
+ def get_optional_user(
37
+ credentials:
38
+ Optional[HTTPAuthorizationCredentials] = Depends(optional_security),
39
+ db: Session = Depends(get_db)
40
+ ):
41
+ if not credentials:
42
+ return None
43
+
44
+ token = credentials.credentials
45
+ try:
46
+ payload = jwt.decode(token, settings.JWT_SECRET, algorithms=["HS256"])
47
+ user_id = payload.get("user_id")
48
+ if not user_id:
49
+ return None
50
+ return db.query(User).filter(User.id == user_id).first()
51
+ except JWTError:
52
+ return None
backend/app/models/file_model.py CHANGED
@@ -12,6 +12,7 @@ class File(Base):
12
  filesize = Column(Integer, nullable=False)
13
  heatmap_path = Column(String, nullable=True)
14
  timeline_data = Column(String, nullable=True)
 
15
 
16
  owner_id = Column(Integer, ForeignKey("users.id"))
17
  created_at = Column(DateTime, default=datetime.now(UTC))
 
12
  filesize = Column(Integer, nullable=False)
13
  heatmap_path = Column(String, nullable=True)
14
  timeline_data = Column(String, nullable=True)
15
+ ip_address = Column(String, nullable=True)
16
 
17
  owner_id = Column(Integer, ForeignKey("users.id"))
18
  created_at = Column(DateTime, default=datetime.now(UTC))
backend/app/services/file_service.py CHANGED
@@ -3,7 +3,7 @@ from fastapi import UploadFile
3
  from app.models.file_model import File
4
  from app.utils.file_handler import ( validate_file, generate_unique_filename, save_file )
5
 
6
- def upload_file_service(db: Session, file: UploadFile, user_id: int):
7
  size = validate_file(file)
8
  safe_name = generate_unique_filename(file.filename)
9
  path = save_file(file, safe_name)
@@ -13,7 +13,8 @@ def upload_file_service(db: Session, file: UploadFile, user_id: int):
13
  filepath=path,
14
  filetype=file.content_type,
15
  filesize=size,
16
- owner_id=user_id
 
17
  )
18
 
19
  db.add(file_record)
 
3
  from app.models.file_model import File
4
  from app.utils.file_handler import ( validate_file, generate_unique_filename, save_file )
5
 
6
+ def upload_file_service(db: Session, file: UploadFile, user_id: int = None, ip_address: str = None):
7
  size = validate_file(file)
8
  safe_name = generate_unique_filename(file.filename)
9
  path = save_file(file, safe_name)
 
13
  filepath=path,
14
  filetype=file.content_type,
15
  filesize=size,
16
+ owner_id=user_id,
17
+ ip_address=ip_address
18
  )
19
 
20
  db.add(file_record)
backend/app/worker/tasks.py CHANGED
@@ -1,5 +1,6 @@
1
  import logging
2
  import socket
 
3
  from datetime import datetime, UTC
4
  from celery.exceptions import SoftTimeLimitExceeded
5
  from app.worker.celery_app import celery_app
@@ -20,6 +21,7 @@ logger = logging.getLogger(__name__)
20
  acks_late=True,
21
  reject_on_worker_lost=True
22
  )
 
23
  def process_file_task(self, file_id: int):
24
  worker_id = socket.gethostname()
25
  logger.info(f"Starting Celery worker process for file_id: {file_id}")
@@ -81,3 +83,24 @@ def process_file_task(self, file_id: int):
81
 
82
  finally:
83
  db.close()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import logging
2
  import socket
3
+ import os
4
  from datetime import datetime, UTC
5
  from celery.exceptions import SoftTimeLimitExceeded
6
  from app.worker.celery_app import celery_app
 
21
  acks_late=True,
22
  reject_on_worker_lost=True
23
  )
24
+
25
  def process_file_task(self, file_id: int):
26
  worker_id = socket.gethostname()
27
  logger.info(f"Starting Celery worker process for file_id: {file_id}")
 
83
 
84
  finally:
85
  db.close()
86
+
87
+ @celery_app.task
88
+ def delete_guest_file_task(file_id: int):
89
+ db = SessionLocal()
90
+ try:
91
+ from app.models.file_model import File
92
+ db_file = db.query(File).filter(File.id == file_id).first()
93
+ if db_file:
94
+ if os.path.exists(db_file.filepath):
95
+ os.remove(db_file.filepath)
96
+ if db_file.heatmap_path and os.path.exists(db_file.heatmap_path):
97
+ os.remove(db_file.heatmap_path)
98
+
99
+ db.delete(db_file)
100
+ db.commit()
101
+ logger.info(f"Guest file {file_id} wiped from servers after 15 minutes.")
102
+
103
+ except Exception as e:
104
+ logger.error(f"Failed to auto-delete guest file {file_id}: {e}")
105
+ finally:
106
+ db.close()