Skip to content

Commit 208ed77

Browse files
committed
Merge branch 'master' into romm-2148
2 parents 964293f + 35f47ce commit 208ed77

189 files changed

Lines changed: 2232 additions & 1875 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.trunk/trunk.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ lint:
3939
- ruff@0.12.11
4040
- shellcheck@0.11.0
4141
- shfmt@3.6.0
42-
- svgo@4.0.0
4342
- taplo@0.10.0
4443
- trivy@0.66.0
4544
- trufflehog@3.90.5

backend/endpoints/collections.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import json
22
from io import BytesIO
3+
from typing import Annotated
34

4-
from fastapi import Request, UploadFile
5+
from fastapi import Path as PathVar
6+
from fastapi import Request, UploadFile, status
57

68
from config import str_to_bool
79
from decorators.auth import protected_route
@@ -388,22 +390,18 @@ async def update_smart_collection(
388390
return SmartCollectionSchema.model_validate(smart_collection)
389391

390392

391-
@protected_route(router.delete, "/{id}", [Scope.COLLECTIONS_WRITE])
392-
async def delete_collection(request: Request, id: int) -> None:
393-
"""Delete collections endpoint
394-
395-
Args:
396-
request (Request): Fastapi Request object
397-
{
398-
"collections": List of rom's ids to delete
399-
}
400-
401-
Raises:
402-
HTTPException: Collection not found
403-
"""
404-
393+
@protected_route(
394+
router.delete,
395+
"/{id}",
396+
[Scope.COLLECTIONS_WRITE],
397+
responses={status.HTTP_404_NOT_FOUND: {}},
398+
)
399+
async def delete_collection(
400+
request: Request,
401+
id: Annotated[int, PathVar(description="Collection internal id.", ge=1)],
402+
) -> None:
403+
"""Delete a collection by ID."""
405404
collection = db_collection_handler.get_collection(id)
406-
407405
if not collection:
408406
raise CollectionNotFoundInDatabaseException(id)
409407

@@ -418,17 +416,18 @@ async def delete_collection(request: Request, id: int) -> None:
418416
)
419417

420418

421-
@protected_route(router.delete, "/smart/{id}", [Scope.COLLECTIONS_WRITE])
422-
async def delete_smart_collection(request: Request, id: int) -> None:
423-
"""Delete smart collection endpoint
424-
425-
Args:
426-
request (Request): Fastapi Request object
427-
id (int): Smart collection id
428-
"""
429-
419+
@protected_route(
420+
router.delete,
421+
"/smart/{id}",
422+
[Scope.COLLECTIONS_WRITE],
423+
responses={status.HTTP_404_NOT_FOUND: {}},
424+
)
425+
async def delete_smart_collection(
426+
request: Request,
427+
id: Annotated[int, PathVar(description="Smart collection internal id.", ge=1)],
428+
) -> None:
429+
"""Delete a smart collection by ID."""
430430
smart_collection = db_collection_handler.get_smart_collection(id)
431-
432431
if not smart_collection:
433432
raise CollectionNotFoundInDatabaseException(id)
434433

backend/endpoints/firmware.py

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from fastapi import File, HTTPException, Request, UploadFile, status
1+
from typing import Annotated
2+
3+
from fastapi import Body, File, HTTPException, Request, UploadFile, status
24
from fastapi.responses import FileResponse
35

46
from config import DISABLE_DOWNLOAD_ENDPOINT_AUTH
@@ -216,46 +218,46 @@ def get_firmware_content(
216218
@protected_route(router.post, "/delete", [Scope.FIRMWARE_WRITE])
217219
async def delete_firmware(
218220
request: Request,
221+
firmware: Annotated[
222+
list[int],
223+
Body(
224+
description="List of firmware ids to delete from database.",
225+
embed=True,
226+
),
227+
],
228+
delete_from_fs: Annotated[
229+
list[int],
230+
Body(
231+
description="List of firmware ids to delete from filesystem.",
232+
default_factory=list,
233+
embed=True,
234+
),
235+
],
219236
) -> BulkOperationResponse:
220-
"""Delete firmware endpoint
221-
222-
Args:
223-
request (Request): Fastapi Request object.
224-
{
225-
"firmware": List of firmware IDs to delete
226-
}
227-
delete_from_fs (bool, optional): Flag to delete rom from filesystem. Defaults to False.
228-
229-
Returns:
230-
BulkOperationResponse: Bulk operation response with details
231-
"""
232-
233-
data: dict = await request.json()
234-
firmware_ids: list = data["firmware"]
235-
delete_from_fs: list = data["delete_from_fs"]
237+
"""Delete firmware."""
236238

237239
successful_items = 0
238240
failed_items = 0
239241
errors = []
240242

241-
for id in firmware_ids:
242-
firmware = db_firmware_handler.get_firmware(id)
243-
if not firmware:
243+
for id in firmware:
244+
fw = db_firmware_handler.get_firmware(id)
245+
if not fw:
244246
failed_items += 1
245247
errors.append(f"Firmware with ID {id} not found")
246248
continue
247249

248250
try:
249-
log.info(f"Deleting {hl(firmware.file_name)} from database")
251+
log.info(f"Deleting {hl(fw.file_name)} from database")
250252
db_firmware_handler.delete_firmware(id)
251253

252254
if id in delete_from_fs:
253-
log.info(f"Deleting {hl(firmware.file_name)} from filesystem")
255+
log.info(f"Deleting {hl(fw.file_name)} from filesystem")
254256
try:
255-
file_path = f"{firmware.file_path}/{firmware.file_name}"
257+
file_path = f"{fw.file_path}/{fw.file_name}"
256258
await fs_firmware_handler.remove_file(file_path=file_path)
257259
except FileNotFoundError:
258-
error = f"Firmware file {hl(firmware.file_name)} not found for platform {hl(firmware.platform.slug)}"
260+
error = f"Firmware file {hl(fw.file_name)} not found for platform {hl(fw.platform.slug)}"
259261
log.error(error)
260262
errors.append(error)
261263
failed_items += 1

backend/endpoints/platform.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ async def delete_platform(
204204
request: Request,
205205
id: Annotated[int, PathVar(description="Platform id.", ge=1)],
206206
) -> None:
207-
"""Delete a platform."""
207+
"""Delete a platform by ID."""
208208

209209
platform = db_platform_handler.get_platform(id)
210210
if not platform:

backend/endpoints/responses/search.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from handler.metadata.sgdb_handler import SGDBResource
2+
13
from .base import BaseModel
24

35

@@ -19,4 +21,4 @@ class SearchRomSchema(BaseModel):
1921

2022
class SearchCoverSchema(BaseModel):
2123
name: str
22-
resources: list
24+
resources: list[SGDBResource]

backend/endpoints/rom.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,13 +874,17 @@ async def delete_roms(
874874
request: Request,
875875
roms: Annotated[
876876
list[int],
877-
Body(description="List of rom ids to delete from database."),
877+
Body(
878+
description="List of rom ids to delete from database.",
879+
embed=True,
880+
),
878881
],
879882
delete_from_fs: Annotated[
880883
list[int],
881884
Body(
882885
description="List of rom ids to delete from filesystem.",
883886
default_factory=list,
887+
embed=True,
884888
),
885889
],
886890
) -> BulkOperationResponse:

backend/endpoints/saves.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime, timezone
2+
from typing import Annotated
23

3-
from fastapi import HTTPException, Request, UploadFile, status
4+
from fastapi import Body, HTTPException, Request, UploadFile, status
45

56
from decorators.auth import protected_route
67
from endpoints.responses.assets import SaveSchema
@@ -223,17 +224,32 @@ async def update_save(request: Request, id: int) -> SaveSchema:
223224
return SaveSchema.model_validate(db_save)
224225

225226

226-
@protected_route(router.post, "/delete", [Scope.ASSETS_WRITE])
227-
async def delete_saves(request: Request) -> list[int]:
228-
data: dict = await request.json()
229-
save_ids: list = data["saves"]
230-
231-
if not save_ids:
227+
@protected_route(
228+
router.post,
229+
"/delete",
230+
[Scope.ASSETS_WRITE],
231+
responses={
232+
status.HTTP_400_BAD_REQUEST: {},
233+
status.HTTP_404_NOT_FOUND: {},
234+
},
235+
)
236+
async def delete_saves(
237+
request: Request,
238+
saves: Annotated[
239+
list[int],
240+
Body(
241+
description="List of save ids to delete from database.",
242+
embed=True,
243+
),
244+
],
245+
) -> list[int]:
246+
"""Delete saves."""
247+
if not saves:
232248
error = "No saves were provided"
233249
log.error(error)
234250
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=error)
235251

236-
for save_id in save_ids:
252+
for save_id in saves:
237253
save = db_save_handler.get_save(user_id=request.user.id, id=save_id)
238254
if not save:
239255
error = f"Save with ID {save_id} not found"
@@ -262,4 +278,4 @@ async def delete_saves(request: Request) -> list[int]:
262278
error = f"Screenshot file {hl(save.screenshot.file_name)} not found for save {hl(save.file_name)}[{hl(save.rom.platform_slug)}]"
263279
log.error(error)
264280

265-
return save_ids
281+
return saves

backend/endpoints/states.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime, timezone
2+
from typing import Annotated
23

3-
from fastapi import HTTPException, Request, UploadFile, status
4+
from fastapi import Body, HTTPException, Request, UploadFile, status
45

56
from decorators.auth import protected_route
67
from endpoints.responses.assets import StateSchema
@@ -227,17 +228,32 @@ async def update_state(request: Request, id: int) -> StateSchema:
227228
return StateSchema.model_validate(db_state)
228229

229230

230-
@protected_route(router.post, "/delete", [Scope.ASSETS_WRITE])
231-
async def delete_states(request: Request) -> list[int]:
232-
data: dict = await request.json()
233-
state_ids: list = data["states"]
234-
235-
if not state_ids:
231+
@protected_route(
232+
router.post,
233+
"/delete",
234+
[Scope.ASSETS_WRITE],
235+
responses={
236+
status.HTTP_400_BAD_REQUEST: {},
237+
status.HTTP_404_NOT_FOUND: {},
238+
},
239+
)
240+
async def delete_states(
241+
request: Request,
242+
states: Annotated[
243+
list[int],
244+
Body(
245+
description="List of states ids to delete from database.",
246+
embed=True,
247+
),
248+
],
249+
) -> list[int]:
250+
"""Delete states."""
251+
if not states:
236252
error = "No states were provided"
237253
log.error(error)
238254
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=error)
239255

240-
for state_id in state_ids:
256+
for state_id in states:
241257
state = db_state_handler.get_state(user_id=request.user.id, id=state_id)
242258
if not state:
243259
error = f"State with ID {state_id} not found"
@@ -266,4 +282,4 @@ async def delete_states(request: Request) -> list[int]:
266282
error = f"Screenshot file {hl(state.screenshot.file_name)} not found for state {hl(state.file_name)}[{hl(state.rom.platform_slug)}]"
267283
log.error(error)
268284

269-
return state_ids
285+
return states

backend/endpoints/user.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,20 @@ async def update_user(
336336
return UserSchema.model_validate(db_user)
337337

338338

339-
@protected_route(router.delete, "/{id}", [Scope.USERS_WRITE])
340-
async def delete_user(request: Request, id: int) -> None:
341-
"""Delete user endpoint
342-
343-
Args:
344-
request (Request): Fastapi Request object
345-
user_id (int): User internal id
339+
@protected_route(
340+
router.delete,
341+
"/{id}",
342+
[Scope.USERS_WRITE],
343+
responses={
344+
status.HTTP_400_BAD_REQUEST: {},
345+
status.HTTP_404_NOT_FOUND: {},
346+
},
347+
)
348+
async def delete_user(
349+
request: Request,
350+
id: Annotated[int, PathVar(description="User internal id.", ge=1)],
351+
) -> None:
352+
"""Delete a user by ID.
346353
347354
Raises:
348355
HTTPException: User is not found in database

0 commit comments

Comments
 (0)