Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.4.0 #1061

Merged
merged 86 commits into from
Aug 7, 2024
Merged

v3.4.0 #1061

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
6eb8e6a
misc: Add Redis async cache
adamantike Jul 21, 2024
e1cec57
Merge pull request #1010 from rommapp/misc/add-async-cache
adamantike Jul 22, 2024
6d8a871
misc: Migrate MobyGamesHandler to async
adamantike Jul 22, 2024
bb01cf6
Create config.batocera-retrobat.yml
TyroneSlothrop Jul 22, 2024
52a9605
Merge branch 'master' into patch-1
gantoine Jul 22, 2024
634e68e
Merge pull request #1013 from TyroneSlothrop/patch-1
gantoine Jul 22, 2024
7c6dfa8
feat: Use ContextVar to share httpx AsyncClient instance between requ…
adamantike Jul 23, 2024
b9da728
Merge pull request #1011 from rommapp/misc/migrate-moby-handler-to-async
adamantike Jul 23, 2024
cfd2e12
Update config.batocera-retrobat.yml
TyroneSlothrop Jul 23, 2024
c81fe52
Merge pull request #1016 from TyroneSlothrop/patch-2
gantoine Jul 24, 2024
56066d6
misc: Migrate filesystem resource handler to async
adamantike Jul 24, 2024
158b16c
Merge pull request #1017 from rommapp/misc/migrate-filesystem-resourc…
adamantike Jul 24, 2024
959e896
misc: Replace pytest-vcr dependency with pytest-recording
adamantike Jul 24, 2024
e7e37f4
Merge pull request #1021 from rommapp/misc/replace-pytest-vcr-with-py…
gantoine Jul 24, 2024
2bfc3c4
misc: Refactor scan process by splitting single function
adamantike Jul 25, 2024
92b2365
start making collecitons public
Jul 25, 2024
377d460
Merge pull request #1024 from rommapp/misc/refactor-scan-process
adamantike Jul 25, 2024
7555c06
[ROMM-1025] Replace game-and-watch with g-and-w
Jul 25, 2024
38a500f
Merge branch 'master' into romm-1025
zurdi15 Jul 25, 2024
fafd485
Merge pull request #1026 from rommapp/romm-1025
gantoine Jul 25, 2024
ad3a588
filter collections for each user
gantoine Jul 25, 2024
141edf9
Merge pull request #1028 from rommapp/share-public-collections
gantoine Jul 26, 2024
aced1f1
misc: Migrate IGDBBaseHandler to async
adamantike Jul 24, 2024
96699a2
fix: Catch ProtocolError when writing screenshots/covers
adamantike Jul 25, 2024
146c26c
Merge pull request #1023 from rommapp/misc/migrate-igdb-handler-to-async
adamantike Jul 27, 2024
c5b150c
fix: Enable flake8-async rules in ruff and fix warnings
adamantike Jul 27, 2024
d1fda90
fix: Add missing awaits on read/write for async opened files
adamantike Jul 27, 2024
9b52a4b
Merge pull request #1030 from rommapp/fix/enable-async-rules-ruff
adamantike Jul 27, 2024
9319081
fix: Return early if IGDB finds an exact match
adamantike Jul 27, 2024
fe5759f
fix: Initialize context on scheduled task
adamantike Jul 27, 2024
66f4c0a
Merge pull request #1033 from rommapp/fix/scheduled-switch-title-db-run
adamantike Jul 27, 2024
9246f87
Merge pull request #1032 from rommapp/fix/quick-return-if-igdb-exact-…
adamantike Jul 27, 2024
749e4d6
misc: Use PYTEST_VERSION variable to detect Pytest runs
adamantike Jul 27, 2024
33e6c23
Merge pull request #1034 from rommapp/misc/use-PYTEST_VERSION-to-dete…
adamantike Jul 27, 2024
16cb380
misc: Use async interface for stream-zip
adamantike Jul 27, 2024
05a85d5
Merge pull request #1035 from rommapp/misc/use-async-stream-zip
adamantike Jul 27, 2024
8e3ae30
[ROMM-1031] Remove persistent overlay prevents back navigation
gantoine Jul 27, 2024
1e33d18
[ROMM-1029] Store and re-use last saved biois/save/state/core
gantoine Jul 28, 2024
30a6ec3
make it platform/rom specific
gantoine Jul 28, 2024
4b487c2
remove the selection if it was manually de-selected
gantoine Jul 28, 2024
de2ac3d
Merge pull request #1037 from rommapp/romm-1029
gantoine Jul 28, 2024
0759985
Added additional platform icons
Casuallynoted Jul 28, 2024
514fc9b
Update ATTRIBUTIONS
Casuallynoted Jul 28, 2024
c34f147
Additional icons, for software platfoms
Casuallynoted Jul 28, 2024
d136807
Delete frontend/assets/platforms/palm-os.ico
Casuallynoted Jul 28, 2024
ebfd9dd
Add files via upload
Casuallynoted Jul 28, 2024
352fd95
Merge pull request #1038 from Casuallynoted/master
gantoine Jul 28, 2024
49296aa
[ROMM-1019] Clickable filter btns on details view
gantoine Jul 28, 2024
77ba874
[ROMM-1020] Fix firmware pagination on mount
gantoine Jul 28, 2024
29bb08e
[ROMM-1018] Fix scanning selected roms
gantoine Jul 29, 2024
1e1d856
Merge pull request #1042 from rommapp/romm-1018
gantoine Jul 29, 2024
05de165
Merge pull request #1041 from rommapp/romm-1020
gantoine Jul 29, 2024
6941514
Add button to show duplicates
gantoine Jul 29, 2024
fce451a
[ROMM-1012] Fix multi-file download in gakllery view
gantoine Jul 29, 2024
48bdfb9
Hotfix and link from related games
gantoine Jul 29, 2024
535cb5a
Merge pull request #1045 from rommapp/hotfix-related-games
gantoine Jul 29, 2024
1e58417
Fix incorrectly converted platform icons
Casuallynoted Jul 30, 2024
072fc9e
Merge pull request #1046 from Casuallynoted/master
gantoine Jul 30, 2024
697723a
Add missing space
HellLord77 Aug 2, 2024
9f7058d
Merge pull request #1048 from HellLord77/fix-typo
gantoine Aug 2, 2024
8cd4cf1
pull sibling roms from backend
gantoine Aug 2, 2024
c77ca88
try fix ignore generated
gantoine Aug 2, 2024
ebd0c07
Merge pull request #1044 from rommapp/romm-1012
gantoine Aug 3, 2024
eba529b
Merge branch 'master' into romm-1019
zurdi15 Aug 4, 2024
f437bac
Merge pull request #1036 from rommapp/romm-1031
gantoine Aug 4, 2024
6d366aa
Update frontend/src/components/Details/Info/GameInfo.vue
gantoine Aug 4, 2024
6d6b96b
Merge branch 'master' into romm-1019
gantoine Aug 4, 2024
ed96603
Merge pull request #1040 from rommapp/romm-1019
gantoine Aug 4, 2024
b06b0f4
Merge pull request #1043 from rommapp/romm-1022
gantoine Aug 4, 2024
32823af
added right click to open in a new tab in home btn
zurdi15 Aug 4, 2024
7e52b50
Merge pull request #1054 from rommapp/romm-1052
gantoine Aug 4, 2024
ebe570d
Fix to AdditionalContent types
gantoine Aug 5, 2024
9b4206a
Merge pull request #1055 from rommapp/type-fix-additional-content
gantoine Aug 5, 2024
b9a68ad
fix re-generate csrftoken when expired
zurdi15 Aug 5, 2024
02cf0fd
added autocompletion to login
zurdi15 Aug 5, 2024
45aeaf3
fix: Backend URL redirection logic
adamantike Aug 5, 2024
805a688
update vite config
gantoine Aug 5, 2024
a53c091
fix endpoint tests
gantoine Aug 5, 2024
d17cdd6
hopefully actually fix csrf tokens
gantoine Aug 5, 2024
cbab9f6
Merge pull request #1058 from rommapp/fix/fastapi-redirections
adamantike Aug 5, 2024
ada7f5f
Merge branch 'master' into fix/csrf-token
zurdi15 Aug 5, 2024
76d6798
Merge pull request #1057 from rommapp/fix/csrf-token
gantoine Aug 6, 2024
8abbae4
misc: Make backend handle URLs with trailing slash
adamantike Aug 7, 2024
5e17efc
Merge pull request #1059 from rommapp/misc/backend-handle-trailing-slash
adamantike Aug 7, 2024
cbeac18
Drop ROMM_AUTH_USERNAME and ROMM_AUTH_PASSWORD env variables
gantoine Aug 7, 2024
51ee99e
Merge pull request #1060 from rommapp/drop-auth-user-pass
gantoine Aug 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@ name: Run Pytest

on:
pull_request:
paths-ignore:
- "docker/**"
- "examples/*"
- "frontend/**"
paths:
- "backend/**"
push:
branches:
- "master"
paths-ignore:
- "docker/**"
- "examples/*"
- "frontend/**"
paths:
- "backend/**"

permissions: read-all

Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Run Typescript Typecheck

on:
pull_request:
paths:
- "frontend/**"
push:
branches:
- "master"
paths:
- "frontend/**"

permissions: read-all

jobs:
typecheck:
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: "18"

- name: Install dependencies
run: npm install
working-directory: frontend

- name: Run typecheck
run: npm run typecheck
working-directory: frontend
8 changes: 7 additions & 1 deletion .trunk/configs/ruff.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
[lint]
# Generic, formatter-friendly config.
select = ["B", "D3", "E", "F"]
# ASYNC: flake8-async.
# B: flake8-bugbear.
# D3: flake8-docstrings (D3xx).
# E: pycodestyle errors.
# F: Pyflakes.
select = ["ASYNC", "B", "D3", "E", "F"]

# Never enforce `E501` (line length violations). This should be handled by formatters.
ignore = ["E501"]
2 changes: 1 addition & 1 deletion .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ lint:
ignore:
- linters: [ALL]
paths:
- src/__generated__/**
- frontend/src/__generated__/**
- docker/Dockerfile
definitions:
- name: eslint
Expand Down
2 changes: 1 addition & 1 deletion DEVELOPER_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ touch romm_mock/library/roms/switch/metroid.xci
mkdir -p romm_mock/resources
mkdir -p romm_mock/assets
mkdir -p romm_mock/config
touch romm_mock/config.yml
touch romm_mock/config/config.yml
```

### Setting up the backend
Expand Down
5 changes: 3 additions & 2 deletions backend/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@
ROMM_DB_DRIVER: Final = os.environ.get("ROMM_DB_DRIVER", "mariadb")

# AUTH
ROMM_AUTH_USERNAME: Final = os.environ.get("ROMM_AUTH_USERNAME", "admin")
ROMM_AUTH_PASSWORD: Final = os.environ.get("ROMM_AUTH_PASSWORD", "admin")
ROMM_AUTH_SECRET_KEY: Final = os.environ.get(
"ROMM_AUTH_SECRET_KEY", secrets.token_hex(32)
)
Expand Down Expand Up @@ -85,3 +83,6 @@
"SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON",
"0 4 * * *", # At 4:00 AM every day
)

# TESTING
IS_PYTEST_RUN: Final = bool(os.environ.get("PYTEST_VERSION", False))
3 changes: 2 additions & 1 deletion backend/endpoints/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
from endpoints.responses import MessageResponse
from endpoints.responses.oauth import TokenResponse
from exceptions.auth_exceptions import AuthCredentialsException, DisabledException
from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi import Depends, HTTPException, Request, status
from fastapi.security.http import HTTPBasic
from handler.auth import auth_handler, oauth_handler
from handler.database import db_user_handler
from utils.router import APIRouter

ACCESS_TOKEN_EXPIRE_MINUTES: Final = 30
REFRESH_TOKEN_EXPIRE_DAYS: Final = 7
Expand Down
40 changes: 21 additions & 19 deletions backend/endpoints/collections.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
from shutil import rmtree

from anyio import open_file
from config import RESOURCES_BASE_PATH
from decorators.auth import protected_route
from endpoints.responses import MessageResponse
Expand All @@ -10,13 +11,14 @@
CollectionNotFoundInDatabaseException,
CollectionPermissionError,
)
from fastapi import APIRouter, Request, UploadFile
from fastapi import Request, UploadFile
from handler.database import db_collection_handler
from handler.filesystem import fs_resource_handler
from handler.filesystem.base_handler import CoverSize
from logger.logger import log
from models.collection import Collection
from sqlalchemy.inspection import inspect
from utils.router import APIRouter

router = APIRouter()

Expand Down Expand Up @@ -58,19 +60,19 @@ async def add_collection(
path_cover_l,
path_cover_s,
artwork_path,
) = fs_resource_handler.build_artwork_path(_added_collection, file_ext)
) = await fs_resource_handler.build_artwork_path(_added_collection, file_ext)

artwork_file = artwork.file.read()
file_location_s = f"{artwork_path}/small.{file_ext}"
with open(file_location_s, "wb+") as artwork_s:
artwork_s.write(artwork_file)
async with await open_file(file_location_s, "wb+") as artwork_s:
await artwork_s.write(artwork_file)
fs_resource_handler.resize_cover_to_small(file_location_s)

file_location_l = f"{artwork_path}/big.{file_ext}"
with open(file_location_l, "wb+") as artwork_l:
artwork_l.write(artwork_file)
async with await open_file(file_location_l, "wb+") as artwork_l:
await artwork_l.write(artwork_file)
else:
path_cover_s, path_cover_l = fs_resource_handler.get_cover(
path_cover_s, path_cover_l = await fs_resource_handler.get_cover(
overwrite=True,
entity=_added_collection,
url_cover=_added_collection.url_cover,
Expand Down Expand Up @@ -100,7 +102,8 @@ def get_collections(request: Request) -> list[CollectionSchema]:
list[CollectionSchema]: List of collections
"""

return db_collection_handler.get_collections(user_id=request.user.id)
collections = db_collection_handler.get_collections()
return CollectionSchema.for_user(request.user.id, collections)


@protected_route(router.get, "/collections/{id}", ["collections.read"])
Expand Down Expand Up @@ -128,6 +131,7 @@ async def update_collection(
request: Request,
id: int,
remove_cover: bool = False,
is_public: bool | None = None,
artwork: UploadFile | None = None,
) -> CollectionSchema:
"""Update collection endpoint
Expand Down Expand Up @@ -159,8 +163,8 @@ async def update_collection(
cleaned_data = {
"name": data.get("name", collection.name),
"description": data.get("description", collection.description),
"is_public": is_public if is_public is not None else collection.is_public,
"roms": list(set(roms)),
"is_public": data.get("is_public", collection.is_public),
"user_id": request.user.id,
}

Expand All @@ -174,31 +178,29 @@ async def update_collection(
path_cover_l,
path_cover_s,
artwork_path,
) = fs_resource_handler.build_artwork_path(collection, file_ext)
) = await fs_resource_handler.build_artwork_path(collection, file_ext)

cleaned_data["path_cover_l"] = path_cover_l
cleaned_data["path_cover_s"] = path_cover_s

artwork_file = artwork.file.read()
file_location_s = f"{artwork_path}/small.{file_ext}"
with open(file_location_s, "wb+") as artwork_s:
artwork_s.write(artwork_file)
async with await open_file(file_location_s, "wb+") as artwork_s:
await artwork_s.write(artwork_file)
fs_resource_handler.resize_cover_to_small(file_location_s)

file_location_l = f"{artwork_path}/big.{file_ext}"
with open(file_location_l, "wb+") as artwork_l:
artwork_l.write(artwork_file)
async with await open_file(file_location_l, "wb+") as artwork_l:
await artwork_l.write(artwork_file)
cleaned_data.update({"url_cover": ""})
else:
if data.get(
"url_cover", ""
) != collection.url_cover or not fs_resource_handler.cover_exists(
collection, CoverSize.BIG
if data.get("url_cover", "") != collection.url_cover or not (
await fs_resource_handler.cover_exists(collection, CoverSize.BIG)
):
cleaned_data.update(
{"url_cover": data.get("url_cover", collection.url_cover)}
)
path_cover_s, path_cover_l = fs_resource_handler.get_cover(
path_cover_s, path_cover_l = await fs_resource_handler.get_cover(
overwrite=True,
entity=collection,
url_cover=data.get("url_cover", ""),
Expand Down
3 changes: 2 additions & 1 deletion backend/endpoints/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
ConfigNotReadableException,
ConfigNotWritableException,
)
from fastapi import APIRouter, HTTPException, Request, status
from fastapi import HTTPException, Request, status
from logger.logger import log
from utils.router import APIRouter

router = APIRouter()

Expand Down
3 changes: 2 additions & 1 deletion backend/endpoints/feeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
TinfoilFeedSchema,
WebrcadeFeedSchema,
)
from fastapi import APIRouter, Request
from fastapi import Request
from handler.database import db_platform_handler, db_rom_handler
from models.rom import Rom
from utils.router import APIRouter

router = APIRouter()

Expand Down
3 changes: 2 additions & 1 deletion backend/endpoints/firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from decorators.auth import protected_route
from endpoints.responses import MessageResponse
from endpoints.responses.firmware import AddFirmwareResponse, FirmwareSchema
from fastapi import APIRouter, File, HTTPException, Request, UploadFile, status
from fastapi import File, HTTPException, Request, UploadFile, status
from fastapi.responses import FileResponse
from handler.database import db_firmware_handler, db_platform_handler
from handler.filesystem import fs_firmware_handler
from handler.scan_handler import scan_firmware
from logger.logger import log
from utils.router import APIRouter

router = APIRouter()

Expand Down
4 changes: 2 additions & 2 deletions backend/endpoints/heartbeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON,
)
from endpoints.responses.heartbeat import HeartbeatResponse
from fastapi import APIRouter
from handler.database import db_user_handler
from handler.filesystem import fs_platform_handler
from handler.metadata.igdb_handler import IGDB_API_ENABLED
from handler.metadata.moby_handler import MOBY_API_ENABLED
from handler.metadata.sgdb_handler import STEAMGRIDDB_API_ENABLED
from utils import get_version
from utils.router import APIRouter

router = APIRouter()


@router.get("/heartbeat")
def heartbeat() -> HeartbeatResponse:
"""Endpoint to set the CSFR token in cache and return all the basic RomM config
"""Endpoint to set the CSRF token in cache and return all the basic RomM config

Returns:
HeartbeatReturn: TypedDict structure with all the defined values in the HeartbeatReturn class.
Expand Down
5 changes: 3 additions & 2 deletions backend/endpoints/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
from endpoints.responses.platform import PlatformSchema
from exceptions.endpoint_exceptions import PlatformNotFoundInDatabaseException
from exceptions.fs_exceptions import PlatformAlreadyExistsException
from fastapi import APIRouter, Request
from fastapi import Request
from handler.database import db_platform_handler
from handler.filesystem import fs_platform_handler
from handler.metadata.igdb_handler import IGDB_PLATFORM_LIST
from handler.scan_handler import scan_platform
from logger.logger import log
from models.platform import Platform
from utils.router import APIRouter

router = APIRouter()

Expand All @@ -33,7 +34,7 @@ async def add_platforms(request: Request) -> PlatformSchema:
fs_platform_handler.add_platforms(fs_slug=fs_slug)
except PlatformAlreadyExistsException:
log.info(f"Detected platform: {fs_slug}")
scanned_platform = scan_platform(fs_slug, [fs_slug])
scanned_platform = await scan_platform(fs_slug, [fs_slug])
return db_platform_handler.add_platform(scanned_platform)


Expand Down
3 changes: 2 additions & 1 deletion backend/endpoints/raw.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from config import ASSETS_BASE_PATH
from decorators.auth import protected_route
from fastapi import APIRouter, Request
from fastapi import Request
from fastapi.responses import FileResponse
from utils.router import APIRouter

router = APIRouter()

Expand Down
11 changes: 11 additions & 0 deletions backend/endpoints/responses/collection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime

from models.collection import Collection
from pydantic import BaseModel


Expand All @@ -22,3 +23,13 @@ class CollectionSchema(BaseModel):

class Config:
from_attributes = True

@classmethod
def for_user(
cls, user_id: int, collections: list["Collection"]
) -> list["CollectionSchema"]:
return [
cls.model_validate(c)
for c in collections
if c.user_id == user_id or c.is_public
]
Loading
Loading