ruff-only pre-commit

This commit is contained in:
Georges-Antoine Assi
2024-05-18 11:47:42 -04:00
parent 1957942689
commit 880345f20c
102 changed files with 305 additions and 183 deletions

View File

@@ -6,5 +6,3 @@ labels: other
assignees: ''
---

View File

@@ -6,5 +6,3 @@ labels: ui/ux
assignees: ''
---

View File

@@ -228,4 +228,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -256,4 +256,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

21
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,21 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: 'https://github.com/pre-commit/pre-commit-hooks'
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: 'https://github.com/astral-sh/ruff-pre-commit'
rev: v0.4.4
hooks:
- id: ruff
args:
- '--fix'
- id: ruff-format
# - repo: 'https://github.com/pre-commit/mirrors-mypy'
# rev: v1.10.0
# hooks:
# - id: mypy

View File

@@ -1,13 +1,13 @@
# v3.0.3 (_25-03-2024_)
## Fixed
## Fixed
- Removed ``PUID/GUID`` environment variables. Instead, use the ``user: "XXXX:XXXX"`` entry in docker-compose to set the owner of newly created file/folders and mounted volumes
<br>
# v3.0.2 (_25-03-2024_)
> [!WARNING]
> [!WARNING]
> RomM has been organized in ``github`` and ``dockerhub``! New images will be upload to ``rommapp/romm`` repository on dockerhub and ghcr.
## Added
@@ -29,7 +29,7 @@
# v3.0.1 (_13-03-2024_)
> [!WARNING]
> [!WARNING]
> This hotfix requires a few changes:
* A new volume has to be bound to `/redis-data`, check the [docker-compose.example.yml file](https://github.com/rommapp/romm/blob/3.0.1/examples/docker-compose.example.yml)
@@ -89,7 +89,7 @@
## Changed
- Platforms can only be deleted from RomM's database. Checkbox to delete platform from filesystem have been removed.
<br>
# v2.3.0 (_08-01-2024_)
@@ -123,7 +123,7 @@
## Changed
- Now region and language tags are case insensitive to show ``emojis``.
<br>
# v2.2.0 (_31-12-2023_)
@@ -132,7 +132,7 @@
- Support for ``productID`` in the file name for ``switch`` titles.
- Rom name sorting now sorts smarter, avoiding leading articles such ``The`` or ``A``, like in ``The Legend of Zelda``. Closes [#449](https://github.com/rommapp/romm/issues/449) and [#450](https://github.com/rommapp/romm/issues/450)
- Support for file names with multiple ``regions`` and ``languages``. Also uses ``emojis`` to display them. Closes [#473](https://github.com/rommapp/romm/issues/473)
- Added a button to manually ``run`` all tasks. Closes [#437](https://github.com/rommapp/romm/issues/437)
- Added a button to manually ``run`` all tasks. Closes [#437](https://github.com/rommapp/romm/issues/437)
- Now if a game doesn't have cover, it will show a screenshot if available. Closes [#455](https://github.com/rommapp/romm/issues/455)
- Added a little warning icon in the platform selector if the platform is not found by IGDB.
- Now if a platform is not found by IGDB, the platform name is ``titleized``. Ex: ``pocket-challenge-v2 -> Pocket Challenge V2``. Closes [#486](https://github.com/rommapp/romm/issues/486)
@@ -140,7 +140,7 @@
- Support for support for AES/MVS. Closes [#503](https://github.com/rommapp/romm/issues/503)
- Added [Helm Chart](https://artifacthub.io/packages/helm/crystalnet/romm) to deploy on Kubernetes by @psych0d0g
- ``Rescan unidentified`` added to the scan view, allowing to rescan only those entries that IGDB couldn't identify in previous scans. Closes [#519](https://github.com/rommapp/romm/issues/519)
- ``Config file`` visualization added to the new ``Config`` tab in the ``Control Panel``. Partially implements some concepts of [#457](https://github.com/rommapp/romm/issues/457)
- ``Config file`` visualization added to the new ``Config`` tab in the ``Control Panel``. Partially implements some concepts of [#457](https://github.com/rommapp/romm/issues/457)
## Fixed
- Now sorting by size in the gallery table view works as expected. Closes [#423](https://github.com/rommapp/romm/issues/423)
@@ -156,7 +156,7 @@
- Fixed multi-part games download when any part of the game contains a ``comma`` in the name. Closes [#520](https://github.com/rommapp/romm/issues/520)
## Changed
- Improved the docker ``init scripts`` handling by @psych0d0g.
- Improved the docker ``init scripts`` handling by @psych0d0g.
- Now the ``scan`` can continue after failing finding roms for one platform. Closes [#460](https://github.com/rommapp/romm/issues/460)
- Logs improved a lot.
@@ -382,7 +382,7 @@
## Fixed
- Download feature is now fixed for RomM structucture 1
## Changed
- Library path binding changed from ``/library`` to ``/romm/library``. Check [docker-compose](examples/docker-compose.example.yml)
- Library path binding changed from ``/library`` to ``/romm/library``. Check [docker-compose](examples/docker-compose.example.yml)
<br>
@@ -403,7 +403,7 @@
# v1.5 (_30-03-2023_)
> [!WARNING]
> [!WARNING]
> In order to make the new features to work, it is mandatory this time to drop all the database. This will only make you need to re-scan, but you won't lose the cover changes or file changes you made. I apologize for the inconveniences this may cause, as this is a new software, it may change a little bit the first weeks, at least until I can develop a proper way to migrate between versions. I hope you can understand these initial wipes in order to make a better tool.
## Added
@@ -435,7 +435,7 @@
## Fixed
**`Breaking change`** - **This breaking change only applies for mariaDB users**:
Some users reported errors when scanning files with large names because file_names are limited to 100 characters in the database. As I want to give as much flexibility as possible I changed some database columns.
Some users reported errors when scanning files with large names because file_names are limited to 100 characters in the database. As I want to give as much flexibility as possible I changed some database columns.
If you didn't make a lot of manual changes you can just get rid of the database and recreate it, scanning your library again. If you did some changes and don't want to lose the progress, you should do this changes manually from the mariadb container (or wherever you have your mariadb database) since there is not any kind of CLI for this migration.
@@ -486,8 +486,8 @@ Columns to modify (examples in case that you set it with database name as romm,
- Game names parentheses are now omitted when searching game in IGDB, allowing game names to have tags.
<br>
# v1.0 (_27-03-2023_)
## Added
- Birth of RomM

View File

@@ -24,7 +24,7 @@ cp env.template .env
### - Install system dependencies
```sh
# https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/c/install/#Installation_via_Package_Repository_(Linux):
# https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/c/install/#Installation_via_Package_Repository_(Linux):
sudo apt install libmariadb3 libmariadb-dev pipx
```

View File

@@ -1,7 +1,7 @@
<div align="center">
<img src=".github/resources/romm_complete.svg" height="220px" width="auto" alt="romm logo">
<h3 style="font-size: 25px;">
A beautiful, powerful, self-hosted rom manager.
</h3>
@@ -18,7 +18,7 @@
</div>
</div>
> [!WARNING]
> [!WARNING]
> Version 3.0 introduces exciting new fetures that require some changes to how RomM is setup and configured. **If you're currently running a 2.x version, please review the [migration guide](https://github.com/rommapp/romm/wiki/Upgrading-to-3.0) before upgrading.**
# Overview
@@ -51,7 +51,7 @@ Before running the [image][docker-tags], ensure that Docker is installed and run
3. Create a docker-compose.yml file by referring to the example [docker-compose.yml][docker-compose-example] file for guidance, and customize it for your setup with [the available environment variables][wiki-env-variables].
4. Launch the container(s) with `docker-compose up -d`.
> [!NOTE]
> [!NOTE]
> **If you are having issues with RomM, please review the [wiki page][wiki-troubleshooting-url] for troubleshooting steps and common issues.**
# Configuration
@@ -92,6 +92,14 @@ As mentioned in the installation section, RomM requires a specific folder struct
│ │ ├─ my_game_cd2.iso
│ │
│ ├─ rom_1.iso
├─ bios/
│ ├─ gba/
│ │ ├─ gba_bios.bin
│ │
│ ├─ ps/
│ ├─ scph1001.bin
| ├─ scph5501.bin
| ├─ scph5502.bin
</pre>
</td>
<td>
@@ -106,6 +114,8 @@ As mentioned in the installation section, RomM requires a specific folder struct
│ ├─ roms/
│ ├─ rom_1.gba
│ ├─ rom_2.gba
| ├─ bios/
| ├─ gba_bios.bin
├─ ps/
│ ├─ roms/
@@ -114,6 +124,10 @@ As mentioned in the installation section, RomM requires a specific folder struct
│ │ ├─ my_game_cd2.iso
│ │
│ ├─ rom_1.iso
| ├─ bios/
| ├─ scph1001.bin
| ├─ scph5501.bin
| ├─ scph5502.bin
</pre>
</td>
</tr>

View File

@@ -5,6 +5,7 @@ Revises: 2.0.0
Create Date: 2023-09-12 18:18:27.158732
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.exc import OperationalError
@@ -87,7 +88,7 @@ def upgrade() -> None:
nullable=True,
existing_server_default=sa.text("'[]'"),
)
try:
with op.batch_alter_table("roms", schema=None) as batch_op:
batch_op.create_foreign_key(

View File

@@ -5,6 +5,7 @@ Revises: 0009_models_refactor
Create Date: 2023-09-14 09:57:13.487331
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

View File

@@ -5,6 +5,7 @@ Revises: 0010_igdb_id_integerr
Create Date: 2023-09-16 15:28:29.221475
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

View File

@@ -5,40 +5,43 @@ Revises: 0011_drop_has_cover
Create Date: 2023-12-03 10:54:46.859106
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = '0012_add_regions_languages'
down_revision = '0011_drop_has_cover'
revision = "0012_add_regions_languages"
down_revision = "0011_drop_has_cover"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('roms', schema=None) as batch_op:
batch_op.add_column(sa.Column('regions', sa.JSON(), nullable=True))
batch_op.add_column(sa.Column('languages', sa.JSON(), nullable=True))
with op.batch_alter_table("roms", schema=None) as batch_op:
batch_op.add_column(sa.Column("regions", sa.JSON(), nullable=True))
batch_op.add_column(sa.Column("languages", sa.JSON(), nullable=True))
with op.batch_alter_table('roms', schema=None) as batch_op:
with op.batch_alter_table("roms", schema=None) as batch_op:
# Set default values for languages and regions
batch_op.execute("UPDATE roms SET languages = '[]'")
batch_op.execute("UPDATE roms SET regions = JSON_ARRAY(region)")
batch_op.drop_column('region')
batch_op.drop_column("region")
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('roms', schema=None) as batch_op:
batch_op.add_column(sa.Column('region', mysql.VARCHAR(length=20), nullable=True))
with op.batch_alter_table("roms", schema=None) as batch_op:
batch_op.add_column(
sa.Column("region", mysql.VARCHAR(length=20), nullable=True)
)
with op.batch_alter_table('roms', schema=None) as batch_op:
with op.batch_alter_table("roms", schema=None) as batch_op:
batch_op.execute("UPDATE roms SET region = JSON_EXTRACT(regions, '$[0]')")
batch_op.drop_column('languages')
batch_op.drop_column('regions')
batch_op.drop_column("languages")
batch_op.drop_column("regions")
# ### end Alembic commands ###

View File

@@ -62,7 +62,9 @@ def migrate_to_mysql() -> None:
if table_name == "alembic_version":
continue
table_data = sqlite_conn.execute(text(f"SELECT * FROM {table_name}")).fetchall()
table_data = sqlite_conn.execute(
text(f"SELECT * FROM {table_name}")
).fetchall()
# Insert data into MariaDB table
for row in table_data:

View File

@@ -5,6 +5,7 @@ Revises: 0014_asset_files
Create Date: 2024-02-13 17:57:25.936825
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

View File

@@ -5,35 +5,42 @@ Revises: 0016_user_last_login_active
Create Date: 2024-04-28 11:58:18.927734
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '0017_rom_notes'
down_revision = '0016_user_last_login_active'
revision = "0017_rom_notes"
down_revision = "0016_user_last_login_active"
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('rom_notes',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('last_edited_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.Column('raw_markdown', sa.Text(), nullable=False),
sa.Column('is_public', sa.Boolean(), nullable=True),
sa.Column('rom_id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['rom_id'], ['roms.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('rom_id', 'user_id', name='unique_rom_user_note')
op.create_table(
"rom_notes",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column(
"last_edited_at",
sa.DateTime(timezone=True),
server_default=sa.text("now()"),
nullable=False,
),
sa.Column("raw_markdown", sa.Text(), nullable=False),
sa.Column("is_public", sa.Boolean(), nullable=True),
sa.Column("rom_id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(["rom_id"], ["roms.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("rom_id", "user_id", name="unique_rom_user_note"),
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('rom_notes')
op.drop_table("rom_notes")
# ### end Alembic commands ###

View File

@@ -1,10 +1,11 @@
"""init to 1.6.2
Revision ID: 1.6.2
Revises:
Revises:
Create Date: 2023-04-10 23:02:37.472055
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.exc import OperationalError

View File

@@ -5,6 +5,7 @@ Revises: 1.6.2
Create Date: 2023-04-10 23:13:43.591414
"""
from alembic import op
import sqlalchemy as sa

View File

@@ -5,6 +5,7 @@ Revises: 1.6.3
Create Date: 2023-04-15 02:28:24.023871
"""
from alembic import op
import sqlalchemy as sa

View File

@@ -5,6 +5,7 @@ Revises: 1.8
Create Date: 2023-04-17 12:03:19.163501
"""
from alembic import op
import sqlalchemy as sa

View File

@@ -5,6 +5,7 @@ Revises: 1.8.1
Create Date: 2023-05-09 00:00:19.143526
"""
from alembic import op
import sqlalchemy as sa

View File

@@ -5,8 +5,8 @@ Revises: 1.8.2
Create Date: 2023-05-17 12:59:44.344356
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.

View File

@@ -5,6 +5,7 @@ Revises: 1.7.1
Create Date: 2023-04-17 12:03:19.163501
"""
from alembic import op
import sqlalchemy as sa

View File

@@ -5,6 +5,7 @@ Revises: 1.8.3
Create Date: 2023-08-10 22:18:24.012779
"""
from alembic import op
import sqlalchemy as sa

View File

@@ -13,7 +13,7 @@ def begin_session(func):
try:
with args[0].session.begin() as s:
kwargs['session'] = s
kwargs["session"] = s
return func(*args, **kwargs)
except ProgrammingError as e:
log.critical(str(e))

View File

@@ -49,5 +49,5 @@ def heartbeat() -> HeartbeatResponse:
"TITLE": "Scheduled Switch TitleDB update",
"MESSAGE": "Updates the Nintendo Switch TitleDB file",
},
}
},
}

View File

@@ -4,6 +4,8 @@ from fastapi import Request
from models.platform import Platform
from .firmware import FirmwareSchema
class PlatformSchema(BaseModel):
id: int
slug: str
@@ -21,9 +23,12 @@ class PlatformSchema(BaseModel):
from_attributes = True
@classmethod
def from_orm_with_request(cls, db_platform: Platform, request: Request) -> "PlatformSchema":
def from_orm_with_request(
cls, db_platform: Platform, request: Request
) -> "PlatformSchema":
platform = cls.model_validate(db_platform)
platform.firmware_files = [
FirmwareSchema.model_validate(f) for f in sorted(db_platform.firmware, key=lambda x: x.file_name)
FirmwareSchema.model_validate(f)
for f in sorted(db_platform.firmware, key=lambda x: x.file_name)
]
return platform

View File

@@ -1,5 +1,6 @@
from pydantic import BaseModel
class SearchRomSchema(BaseModel):
igdb_id: int | None = None
moby_id: int | None = None

View File

@@ -30,9 +30,7 @@ async def run_task(request: Request, task: str) -> MessageResponse:
RunTasksResponse: Standard message response
"""
tasks = {
"switch_titledb": update_switch_titledb_task
}
tasks = {"switch_titledb": update_switch_titledb_task}
await tasks[task].run()
return {"msg": f"Task {task} run successfully!"}

View File

@@ -1,8 +1,18 @@
import pytest
from datetime import timedelta
from handler.tests.conftest import setup_database, clear_database, admin_user, editor_user, viewer_user, platform, rom, save, state # noqa
from handler.auth import oauth_handler
from handler.tests.conftest import ( # noqa
setup_database,
clear_database,
admin_user,
editor_user,
viewer_user,
platform,
rom,
save,
state,
)
from ..auth import ACCESS_TOKEN_EXPIRE_MINUTES, REFRESH_TOKEN_EXPIRE_DAYS

View File

@@ -14,7 +14,7 @@ def test_delete_saves(access_token, save):
assert response.status_code == 200
body = response.json()
assert body['msg'] == "Successfully deleted 1 saves"
assert body["msg"] == "Successfully deleted 1 saves"
def test_delete_states(access_token, state):
@@ -26,4 +26,4 @@ def test_delete_states(access_token, state):
assert response.status_code == 200
body = response.json()
assert body['msg'] == "Successfully deleted 1 states"
assert body["msg"] == "Successfully deleted 1 states"

View File

@@ -10,12 +10,12 @@ def test_config():
assert response.status_code == 200
config = response.json()
assert config.get('EXCLUDED_PLATFORMS') == []
assert config.get('EXCLUDED_SINGLE_EXT') == []
assert config.get('EXCLUDED_SINGLE_FILES') == []
assert config.get('EXCLUDED_MULTI_FILES') == []
assert config.get('EXCLUDED_MULTI_PARTS_EXT') == []
assert config.get('EXCLUDED_MULTI_PARTS_FILES') == []
assert config.get('PLATFORMS_BINDING') == {}
assert config.get('ROMS_FOLDER_NAME') == 'roms'
assert config.get('FIRMWARE_FOLDER_NAME') == 'bios'
assert config.get("EXCLUDED_PLATFORMS") == []
assert config.get("EXCLUDED_SINGLE_EXT") == []
assert config.get("EXCLUDED_SINGLE_FILES") == []
assert config.get("EXCLUDED_MULTI_FILES") == []
assert config.get("EXCLUDED_MULTI_PARTS_EXT") == []
assert config.get("EXCLUDED_MULTI_PARTS_FILES") == []
assert config.get("PLATFORMS_BINDING") == {}
assert config.get("ROMS_FOLDER_NAME") == "roms"
assert config.get("FIRMWARE_FOLDER_NAME") == "bios"

View File

@@ -9,14 +9,17 @@ client = TestClient(app)
def test_heartbeat():
response = client.get("/heartbeat")
assert response.status_code == 200
heartbeat = response.json()
assert heartbeat.get('VERSION') == github_handler.get_version()
assert heartbeat.get('WATCHER').get('ENABLED')
assert heartbeat.get('WATCHER').get('TITLE') == "Rescan on filesystem change"
assert heartbeat.get('SCHEDULER').get('RESCAN').get('ENABLED')
assert heartbeat.get('SCHEDULER').get('RESCAN').get('CRON') == "0 3 * * *"
assert heartbeat.get('SCHEDULER').get('RESCAN').get('TITLE') == "Scheduled rescan"
assert heartbeat.get('SCHEDULER').get('SWITCH_TITLEDB').get('ENABLED')
assert heartbeat.get('SCHEDULER').get('SWITCH_TITLEDB').get('CRON') == "0 4 * * *"
assert heartbeat.get('SCHEDULER').get('SWITCH_TITLEDB').get('TITLE') == "Scheduled Switch TitleDB update"
assert heartbeat.get("VERSION") == github_handler.get_version()
assert heartbeat.get("WATCHER").get("ENABLED")
assert heartbeat.get("WATCHER").get("TITLE") == "Rescan on filesystem change"
assert heartbeat.get("SCHEDULER").get("RESCAN").get("ENABLED")
assert heartbeat.get("SCHEDULER").get("RESCAN").get("CRON") == "0 3 * * *"
assert heartbeat.get("SCHEDULER").get("RESCAN").get("TITLE") == "Scheduled rescan"
assert heartbeat.get("SCHEDULER").get("SWITCH_TITLEDB").get("ENABLED")
assert heartbeat.get("SCHEDULER").get("SWITCH_TITLEDB").get("CRON") == "0 4 * * *"
assert (
heartbeat.get("SCHEDULER").get("SWITCH_TITLEDB").get("TITLE")
== "Scheduled Switch TitleDB update"
)

View File

@@ -6,7 +6,9 @@ client = TestClient(app)
def test_get_raw_asset(access_token):
response = client.get("/raw/assets/users/557365723a31/saves/n64/mupen64/Super Mario 64 (J) (Rev A).sav")
response = client.get(
"/raw/assets/users/557365723a31/saves/n64/mupen64/Super Mario 64 (J) (Rev A).sav"
)
assert response.status_code == 403
response = client.get(

View File

@@ -112,9 +112,7 @@ def update_user(
cleaned_data = {}
if form_data.username and form_data.username != user.username:
existing_user = db_user_handler.get_user_by_username(
form_data.username.lower()
)
existing_user = db_user_handler.get_user_by_username(form_data.username.lower())
if existing_user:
raise HTTPException(
status_code=400, detail="Username already in use by another user"

View File

@@ -19,4 +19,4 @@ OAuthCredentialsException = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
)

View File

@@ -5,7 +5,8 @@ class ConfigNotReadableException(Exception):
def __repr__(self) -> str:
return self.message
class ConfigNotWritableException(Exception):
def __init__(self):
self.message = "Config file is not writable. Check config.yml permissions"

View File

@@ -45,14 +45,18 @@ class RomAlreadyExistsException(Exception):
def __repr__(self):
return self.message
class FirmwareNotFoundException(Exception):
def __init__(self, platform: str):
self.message = f"Firmware not found for platform {platform}. {folder_struct_msg}"
self.message = (
f"Firmware not found for platform {platform}. {folder_struct_msg}"
)
super().__init__(self.message)
def __repr__(self):
return self.message
class FirmwareAlreadyExistsException(Exception):
def __init__(self, firmware_name: str):
self.message = f"Can't rename: {firmware_name} already exists"

View File

@@ -1 +1,7 @@
from handler.tests.conftest import setup_database, clear_database, admin_user, editor_user, viewer_user # noqa
from handler.tests.conftest import ( # noqa
setup_database,
clear_database,
admin_user,
editor_user,
viewer_user,
)

View File

@@ -10,8 +10,12 @@ from handler.auth.hybrid_auth import HybridAuthBackend
def test_verify_password():
assert auth_handler.verify_password("password", auth_handler.get_password_hash("password"))
assert not auth_handler.verify_password("password", auth_handler.get_password_hash("notpassword"))
assert auth_handler.verify_password(
"password", auth_handler.get_password_hash("password")
)
assert not auth_handler.verify_password(
"password", auth_handler.get_password_hash("notpassword")
)
def test_authenticate_user(admin_user: User):

View File

@@ -114,7 +114,7 @@ class FSHandler(ABC):
def parse_file_extension(self, file_name) -> str:
match = re.search(EXTENSION_REGEX, file_name)
return match.group(1) if match else ""
def _exclude_files(self, files, filetype) -> list[str]:
cnfg = cm.get_config()
excluded_extensions = getattr(cnfg, f"EXCLUDED_{filetype.upper()}_EXT")

View File

@@ -226,8 +226,7 @@ def test_get_file_name_with_no_tags():
file_name = "007 - Agent Under Fire.nkit.iso"
assert (
fs_rom_handler.get_file_name_with_no_tags(file_name)
== "007 - Agent Under Fire"
fs_rom_handler.get_file_name_with_no_tags(file_name) == "007 - Agent Under Fire"
)
file_name = "Jimmy Houston's Bass Tournament U.S.A..zip"
@@ -306,9 +305,7 @@ def test_get_file_name_with_no_extension():
def test_get_file_extension():
assert (
fs_rom_handler.parse_file_extension("Super Mario Bros. (World).nes") == "nes"
)
assert fs_rom_handler.parse_file_extension("Super Mario Bros. (World).nes") == "nes"
assert (
fs_rom_handler.parse_file_extension("007 - Agent Under Fire.nkit.iso")
== "nkit.iso"

File diff suppressed because one or more lines are too long

View File

@@ -14,8 +14,18 @@ class QueuePrio(Enum):
LOW = "low"
redis_client = Redis(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, username=REDIS_USERNAME, db=REDIS_DB)
redis_url = f"redis://{REDIS_USERNAME}:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}" if REDIS_PASSWORD else f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}"
redis_client = Redis(
host=REDIS_HOST,
port=REDIS_PORT,
password=REDIS_PASSWORD,
username=REDIS_USERNAME,
db=REDIS_DB,
)
redis_url = (
f"redis://{REDIS_USERNAME}:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}"
if REDIS_PASSWORD
else f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}"
)
high_prio_queue = Queue(name=QueuePrio.HIGH.value, connection=redis_client)
default_queue = Queue(name=QueuePrio.DEFAULT.value, connection=redis_client)

View File

@@ -308,9 +308,7 @@ def _scan_asset(file_name: str, path: str):
"file_path": path,
"file_name": file_name,
"file_name_no_tags": fs_asset_handler.get_file_name_with_no_tags(file_name),
"file_name_no_ext": fs_asset_handler.get_file_name_with_no_extension(
file_name
),
"file_name_no_ext": fs_asset_handler.get_file_name_with_no_extension(file_name),
"file_extension": fs_asset_handler.parse_file_extension(file_name),
"file_size_bytes": file_size,
}

View File

@@ -12,6 +12,9 @@ class SocketHandler:
client_manager=socketio.AsyncRedisManager(redis_url),
)
self.socket_app = socketio.ASGIApp(self.socket_server, socketio_path="/ws/socket.io")
self.socket_app = socketio.ASGIApp(
self.socket_server, socketio_path="/ws/socket.io"
)
socket_handler = SocketHandler()

View File

@@ -32,7 +32,7 @@ async def test_scan_rom():
"multi": False,
"files": ["Paper Mario (USA).z64"],
},
ScanType.QUICK
ScanType.QUICK,
)
assert rom.__class__ == Rom

View File

@@ -22,11 +22,56 @@ class StdoutFormatter(logging.Formatter):
msg: str = "%(message)s"
date: str = "[%(asctime)s] "
FORMATS: dict = {
logging.DEBUG: COLORS['pink'] + level + COLORS['reset'] + dots + COLORS['blue'] + identifier + COLORS['cyan'] + date + COLORS['reset'] + msg,
logging.INFO: COLORS['grey'] + level + COLORS['reset'] + dots + COLORS['blue'] + identifier + COLORS['cyan'] + date + COLORS['reset'] + msg,
logging.WARNING: COLORS['orange'] + level + COLORS['reset'] + dots + COLORS['blue'] + identifier_warning + COLORS['cyan'] + date + COLORS['reset'] + msg,
logging.ERROR: COLORS['red'] + level + COLORS['reset'] + dots + COLORS['blue'] + identifier + COLORS['cyan'] + date + COLORS['reset'] + msg,
logging.CRITICAL: COLORS['bold_red'] + level + COLORS['reset'] + dots + COLORS['blue'] + identifier_critical + COLORS['cyan'] + date + COLORS['reset'] + msg
logging.DEBUG: COLORS["pink"]
+ level
+ COLORS["reset"]
+ dots
+ COLORS["blue"]
+ identifier
+ COLORS["cyan"]
+ date
+ COLORS["reset"]
+ msg,
logging.INFO: COLORS["grey"]
+ level
+ COLORS["reset"]
+ dots
+ COLORS["blue"]
+ identifier
+ COLORS["cyan"]
+ date
+ COLORS["reset"]
+ msg,
logging.WARNING: COLORS["orange"]
+ level
+ COLORS["reset"]
+ dots
+ COLORS["blue"]
+ identifier_warning
+ COLORS["cyan"]
+ date
+ COLORS["reset"]
+ msg,
logging.ERROR: COLORS["red"]
+ level
+ COLORS["reset"]
+ dots
+ COLORS["blue"]
+ identifier
+ COLORS["cyan"]
+ date
+ COLORS["reset"]
+ msg,
logging.CRITICAL: COLORS["bold_red"]
+ level
+ COLORS["reset"]
+ dots
+ COLORS["blue"]
+ identifier_critical
+ COLORS["cyan"]
+ date
+ COLORS["reset"]
+ msg,
}
def format(self, record):

View File

@@ -2,17 +2,17 @@ from logger.logger import log
def test_logger(caplog):
log.debug("Testing debug message")
assert "debug message" in caplog.text
log.debug("Testing debug message")
assert "debug message" in caplog.text
log.info("Testing info message")
assert "info message" in caplog.text
log.info("Testing info message")
assert "info message" in caplog.text
log.warning("Testing warning message")
assert "warning message" in caplog.text
log.warning("Testing warning message")
assert "warning message" in caplog.text
log.error("Testing error message")
assert "error message" in caplog.text
log.error("Testing error message")
assert "error message" in caplog.text
log.critical("Testing critical message")
assert "critical message" in caplog.text
log.critical("Testing critical message")
assert "critical message" in caplog.text

View File

@@ -1 +1,12 @@
from handler.tests.conftest import setup_database, clear_database, rom, platform, admin_user, editor_user, viewer_user, save, state, screenshot # noqa
from handler.tests.conftest import ( # noqa
setup_database,
clear_database,
rom,
platform,
admin_user,
editor_user,
viewer_user,
save,
state,
screenshot,
)

View File

@@ -1,13 +1,25 @@
from models.assets import Save, State, Screenshot
def test_save(save: Save):
assert "test_platform_slug/saves/test_emulator/test_save.sav" in save.full_path
assert "/api/raw/assets/test_platform_slug/saves/test_emulator/test_save.sav" in save.download_path
assert (
"/api/raw/assets/test_platform_slug/saves/test_emulator/test_save.sav"
in save.download_path
)
def test_state(state: State):
assert "test_platform_slug/states/test_emulator/test_state.state" in state.full_path
assert "/api/raw/assets/test_platform_slug/states/test_emulator/test_state.state" in state.download_path
assert (
"/api/raw/assets/test_platform_slug/states/test_emulator/test_state.state"
in state.download_path
)
def test_screenshot(screenshot: Screenshot):
assert "test_platform_slug/screenshots/test_screenshot.png" in screenshot.full_path
assert "/api/raw/assets/test_platform_slug/screenshots/test_screenshot.png" in screenshot.download_path
assert (
"/api/raw/assets/test_platform_slug/screenshots/test_screenshot.png"
in screenshot.download_path
)

View File

@@ -1,3 +1,3 @@
def test_rom(rom):
assert rom.file_path == "test_platform_slug/roms"
assert rom.full_path == "test_platform_slug/roms/test_rom.zip"
assert rom.full_path == "test_platform_slug/roms/test_rom.zip"

View File

@@ -99,7 +99,9 @@ if __name__ == "__main__":
# Sort platforms by key
supported_platforms = dict(sorted(supported_platforms.items()))
print("Below is a list of all supported platforms/systems/consoles and their respective folder names. **The folder name is case-sensitive and must be used exactly as it appears in the list below.**")
print(
"Below is a list of all supported platforms/systems/consoles and their respective folder names. **The folder name is case-sensitive and must be used exactly as it appears in the list below.**"
)
print("\n")
print("|Platform Name|Folder Name|IGDB|Mobygames|")
print("|---|---|---|---|")

View File

@@ -7,11 +7,11 @@ events {
}
http {
client_body_temp_path /tmp/client_body 1 2;
fastcgi_temp_path /tmp/fastcgi 1 2;
proxy_temp_path /tmp/proxy;
uwsgi_temp_path /tmp/uwsgi;
scgi_temp_path /tmp/scgi;
client_body_temp_path /tmp/client_body 1 2;
fastcgi_temp_path /tmp/fastcgi 1 2;
proxy_temp_path /tmp/proxy;
uwsgi_temp_path /tmp/uwsgi;
scgi_temp_path /tmp/scgi;
sendfile on;
client_max_body_size 0;

View File

@@ -7,7 +7,7 @@ IGDB_CLIENT_ID=
IGDB_CLIENT_SECRET=
# Mobygames
MOBYGAMES_API_KEY=
MOBYGAMES_API_KEY=
# Database config
DB_HOST=127.0.0.1

View File

@@ -21,7 +21,7 @@ exclude:
## Multi files games section
# Will apply to files that are in sub-folders (multi-disc roms, games with updates, DLC, patches, etc.)
multi_file:
# Exclude matched 'folder' names to be scanned (RomM identifies folders as multi file games)
# Exclude matched 'folder' names to be scanned (RomM identifies folders as multi file games)
names:
- 'my_multi_file_game'
- 'DLC'

View File

@@ -7,4 +7,3 @@ info@brittneymurphydesign.com
It is free for personal and non-profit use. If you would like to use this font commercially, please purchase a commercial license (only $5) at www.brittneymurphydesign.com.
You are free to redistribute this font as long as you include this ReadMe file with the font file and don't try to claim the font as free or as your own.

View File

@@ -228,4 +228,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -9,4 +9,3 @@ export type AddFirmwareResponse = {
uploaded: number;
firmware: Array<FirmwareSchema>;
};

View File

@@ -7,4 +7,3 @@ export type AddRomsResponse = {
uploaded_roms: Array<string>;
skipped_roms: Array<string>;
};

View File

@@ -6,4 +6,3 @@
export type Body_add_firmware_firmware_post = {
files: Array<Blob>;
};

View File

@@ -6,4 +6,3 @@
export type Body_add_roms_roms_post = {
roms: Array<Blob>;
};

View File

@@ -6,4 +6,3 @@
export type Body_add_saves_saves_post = {
saves: Array<Blob>;
};

View File

@@ -6,4 +6,3 @@
export type Body_add_screenshots_screenshots_post = {
screenshots: Array<Blob>;
};

View File

@@ -6,4 +6,3 @@
export type Body_add_states_states_post = {
states: Array<Blob>;
};

View File

@@ -12,4 +12,3 @@ export type Body_token_token_post = {
client_secret?: (string | null);
refresh_token?: (string | null);
};

View File

@@ -6,4 +6,3 @@
export type Body_update_rom_roms__id__put = {
artwork?: (Blob | null);
};

View File

@@ -6,4 +6,3 @@
export type Body_update_user_users__id__put = {
avatar?: (Blob | null);
};

View File

@@ -16,4 +16,3 @@ export type ConfigResponse = {
FIRMWARE_FOLDER_NAME: string;
HIGH_PRIO_STRUCTURE_PATH: string;
};

View File

@@ -28,4 +28,3 @@ export type CursorPage_RomSchema_ = {
*/
next_page?: (string | null);
};

View File

@@ -17,4 +17,3 @@ export type FirmwareSchema = {
md5_hash: string;
sha1_hash: string;
};

View File

@@ -8,4 +8,3 @@ import type { ValidationError } from './ValidationError';
export type HTTPValidationError = {
detail?: Array<ValidationError>;
};

View File

@@ -15,4 +15,3 @@ export type HeartbeatResponse = {
ANY_SOURCE_ENABLED: boolean;
METADATA_SOURCES: MetadataSourcesDict;
};

View File

@@ -7,4 +7,3 @@ export type IGDBPlatform = {
igdb_id: number;
name?: string;
};

View File

@@ -10,4 +10,3 @@ export type IGDBRelatedGame = {
type: string;
cover_url: string;
};

View File

@@ -6,4 +6,3 @@
export type MessageResponse = {
msg: string;
};

View File

@@ -7,4 +7,3 @@ export type MetadataSourcesDict = {
IGDB_API_ENABLED: boolean;
MOBY_API_ENABLED: boolean;
};

View File

@@ -7,4 +7,3 @@ export type MobyGamesPlatform = {
moby_id: number;
name?: string;
};

View File

@@ -17,4 +17,3 @@ export type PlatformSchema = {
rom_count: number;
firmware_files?: Array<FirmwareSchema>;
};

View File

@@ -25,4 +25,3 @@ export type RomIGDBMetadata = {
ports?: Array<IGDBRelatedGame>;
similar_games?: Array<IGDBRelatedGame>;
};

View File

@@ -11,4 +11,3 @@ export type RomMobyMetadata = {
alternate_titles?: Array<string>;
platforms?: Array<MobyGamesPlatform>;
};

View File

@@ -12,4 +12,3 @@ export type RomNoteSchema = {
is_public: boolean;
readonly user__username: string;
};

View File

@@ -56,4 +56,3 @@ export type RomSchema = {
user_notes?: Array<RomNoteSchema>;
readonly sort_comparator: string;
};

View File

@@ -22,4 +22,3 @@ export type SaveSchema = {
emulator: (string | null);
screenshot: (ScreenshotSchema | null);
};

View File

@@ -9,4 +9,3 @@ export type SchedulerDict = {
RESCAN: TaskDict;
SWITCH_TITLEDB: TaskDict;
};

View File

@@ -18,4 +18,3 @@ export type ScreenshotSchema = {
created_at: string;
updated_at: string;
};

View File

@@ -13,4 +13,3 @@ export type SearchRomSchema = {
moby_url_cover?: string;
url_screenshots: Array<string>;
};

View File

@@ -22,4 +22,3 @@ export type StateSchema = {
emulator: (string | null);
screenshot: (ScreenshotSchema | null);
};

View File

@@ -11,4 +11,3 @@ export type StatsReturn = {
SCREENSHOTS: number;
FILESIZE: number;
};

View File

@@ -9,4 +9,3 @@ export type TaskDict = {
MESSAGE: string;
CRON: string;
};

View File

@@ -8,4 +8,3 @@ export type TinfoilFeedSchema = {
directories: Array<string>;
success: string;
};

View File

@@ -9,4 +9,3 @@ export type TokenResponse = {
token_type: string;
expires: number;
};

View File

@@ -9,4 +9,3 @@ export type UploadedSavesResponse = {
uploaded: number;
saves: Array<SaveSchema>;
};

View File

@@ -11,4 +11,3 @@ export type UploadedScreenshotsResponse = {
url_screenshots: Array<string>;
merged_screenshots: Array<string>;
};

View File

@@ -9,4 +9,3 @@ export type UploadedStatesResponse = {
uploaded: number;
states: Array<StateSchema>;
};

View File

@@ -15,4 +15,3 @@ export type UserSchema = {
last_login: (string | null);
last_active: (string | null);
};

View File

@@ -8,4 +8,3 @@ export type ValidationError = {
msg: string;
type: string;
};

View File

@@ -8,4 +8,3 @@ export type WatcherDict = {
TITLE: string;
MESSAGE: string;
};

View File

@@ -11,4 +11,3 @@ export type WebrcadeFeedSchema = {
background: string;
categories: Array<Record<string, any>>;
};

Some files were not shown because too many files have changed in this diff Show More