mirror of
https://github.com/rommapp/romm.git
synced 2026-06-28 14:56:01 +00:00
First batch of work for hasheous
This commit is contained in:
39
backend/alembic/versions/0044_hasheous_id.py
Normal file
39
backend/alembic/versions/0044_hasheous_id.py
Normal file
@@ -0,0 +1,39 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 0044_hasheous_id
|
||||
Revises: 0043_launchbox_id
|
||||
Create Date: 2025-06-16 03:15:42.692551
|
||||
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "0044_hasheous_id"
|
||||
down_revision = "0043_launchbox_id"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
with op.batch_alter_table("roms", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("hasheous_id", sa.Integer(), nullable=True))
|
||||
batch_op.add_column(
|
||||
sa.Column(
|
||||
"hasheous_metadata",
|
||||
sa.JSON().with_variant(
|
||||
postgresql.JSONB(astext_type=sa.Text()), "postgresql"
|
||||
),
|
||||
nullable=True,
|
||||
)
|
||||
)
|
||||
batch_op.create_index("idx_roms_hasheous_id", ["hasheous_id"], unique=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
with op.batch_alter_table("roms", schema=None) as batch_op:
|
||||
batch_op.drop_index("idx_roms_hasheous_id")
|
||||
batch_op.drop_column("hasheous_metadata")
|
||||
batch_op.drop_column("hasheous_id")
|
||||
@@ -85,6 +85,11 @@ PLAYMATCH_API_ENABLED: Final = str_to_bool(
|
||||
os.environ.get("PLAYMATCH_API_ENABLED", "false")
|
||||
)
|
||||
|
||||
# HASHEOUS
|
||||
HASHEOUS_API_ENABLED: Final = str_to_bool(
|
||||
os.environ.get("HASHEOUS_API_ENABLED", "false")
|
||||
)
|
||||
|
||||
# AUTH
|
||||
ROMM_AUTH_SECRET_KEY: Final = os.environ.get(
|
||||
"ROMM_AUTH_SECRET_KEY", secrets.token_hex(32)
|
||||
|
||||
@@ -6,6 +6,7 @@ from config import (
|
||||
ENABLE_SCHEDULED_RESCAN,
|
||||
ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA,
|
||||
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB,
|
||||
HASHEOUS_API_ENABLED,
|
||||
LAUNCHBOX_API_ENABLED,
|
||||
OIDC_ENABLED,
|
||||
OIDC_PROVIDER,
|
||||
@@ -51,13 +52,15 @@ def heartbeat() -> HeartbeatResponse:
|
||||
or MOBY_API_ENABLED
|
||||
or RA_API_ENABLED
|
||||
or LAUNCHBOX_API_ENABLED
|
||||
or PLAYMATCH_API_ENABLED,
|
||||
or PLAYMATCH_API_ENABLED
|
||||
or HASHEOUS_API_ENABLED,
|
||||
"IGDB_API_ENABLED": IGDB_API_ENABLED,
|
||||
"SS_API_ENABLED": SS_API_ENABLED,
|
||||
"MOBY_API_ENABLED": MOBY_API_ENABLED,
|
||||
"STEAMGRIDDB_API_ENABLED": STEAMGRIDDB_API_ENABLED,
|
||||
"RA_API_ENABLED": RA_API_ENABLED,
|
||||
"LAUNCHBOX_API_ENABLED": LAUNCHBOX_API_ENABLED,
|
||||
"HASHEOUS_API_ENABLED": HASHEOUS_API_ENABLED,
|
||||
# Platmatch requires use of the IGDB API
|
||||
"PLAYMATCH_API_ENABLED": PLAYMATCH_API_ENABLED and IGDB_API_ENABLED,
|
||||
},
|
||||
|
||||
@@ -31,6 +31,7 @@ class MetadataSourcesDict(TypedDict):
|
||||
RA_API_ENABLED: bool
|
||||
LAUNCHBOX_API_ENABLED: bool
|
||||
PLAYMATCH_API_ENABLED: bool
|
||||
HASHEOUS_API_ENABLED: bool
|
||||
|
||||
|
||||
class FilesystemDict(TypedDict):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from .hasheous_handler import HasheousHandler
|
||||
from .igdb_handler import IGDBHandler
|
||||
from .launchbox_handler import LaunchboxHandler
|
||||
from .moby_handler import MobyGamesHandler
|
||||
@@ -13,3 +14,4 @@ meta_sgdb_handler = SGDBBaseHandler()
|
||||
meta_ra_handler = RAHandler()
|
||||
meta_pm_handler = PlaymatchHandler()
|
||||
meta_launchbox_handler = LaunchboxHandler()
|
||||
meta_hasheous_handler = HasheousHandler()
|
||||
|
||||
1321
backend/handler/metadata/hasheous_handler.py
Normal file
1321
backend/handler/metadata/hasheous_handler.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -819,7 +819,13 @@ SEARCH_FIELDS = ("game.id", "name")
|
||||
# name: a.innerText
|
||||
# }))
|
||||
|
||||
IGDB_PLATFORM_LIST = (
|
||||
|
||||
class SlugToIGDB(TypedDict):
|
||||
slug: str
|
||||
name: str
|
||||
|
||||
|
||||
IGDB_PLATFORM_LIST: list[SlugToIGDB] = [
|
||||
{"slug": "visionos", "name": "visionOS"},
|
||||
{"slug": "meta-quest-3", "name": "Meta Quest 3"},
|
||||
{"slug": "atari2600", "name": "Atari 2600"},
|
||||
@@ -1036,7 +1042,11 @@ IGDB_PLATFORM_LIST = (
|
||||
{"slug": "onlive-game-system", "name": "OnLive Game System"},
|
||||
{"slug": "vc", "name": "Virtual Console"},
|
||||
{"slug": "airconsole", "name": "AirConsole"},
|
||||
)
|
||||
]
|
||||
|
||||
IGDB_PLATFORMS_BY_SLUG: dict[str, SlugToIGDB] = {
|
||||
platform["slug"]: platform for platform in IGDB_PLATFORM_LIST
|
||||
}
|
||||
|
||||
IGDB_PLATFORM_CATEGORIES: dict[int, str] = {
|
||||
0: "Unknown",
|
||||
|
||||
@@ -8,6 +8,7 @@ from handler.database import db_platform_handler
|
||||
from handler.filesystem import fs_asset_handler, fs_firmware_handler, fs_rom_handler
|
||||
from handler.filesystem.roms_handler import FSRom
|
||||
from handler.metadata import (
|
||||
meta_hasheous_handler,
|
||||
meta_igdb_handler,
|
||||
meta_launchbox_handler,
|
||||
meta_moby_handler,
|
||||
@@ -15,6 +16,7 @@ from handler.metadata import (
|
||||
meta_ra_handler,
|
||||
meta_ss_handler,
|
||||
)
|
||||
from handler.metadata.hasheous_handler import HasheousRom
|
||||
from handler.metadata.igdb_handler import IGDBPlatform, IGDBRom
|
||||
from handler.metadata.launchbox_handler import LaunchboxPlatform, LaunchboxRom
|
||||
from handler.metadata.moby_handler import MobyGamesPlatform, MobyGamesRom
|
||||
@@ -49,6 +51,7 @@ class MetadataSource:
|
||||
RA = "ra" # RetroAchivements
|
||||
LB = "lb" # Launchbox
|
||||
PM = "pm" # Playmatch
|
||||
HASHEOUS = "hasheous" # Hasheous
|
||||
|
||||
|
||||
async def _get_main_platform_igdb_id(platform: Platform):
|
||||
@@ -150,6 +153,8 @@ async def scan_platform(
|
||||
else LaunchboxPlatform(launchbox_id=None, slug=platform_attrs["slug"])
|
||||
)
|
||||
|
||||
await meta_hasheous_handler.get_platforms()
|
||||
|
||||
platform_attrs["name"] = platform_attrs["slug"].replace("-", " ").title()
|
||||
platform_attrs.update(
|
||||
{
|
||||
@@ -423,6 +428,21 @@ async def scan_rom(
|
||||
|
||||
return IGDBRom(igdb_id=None)
|
||||
|
||||
async def fetch_hasheous_rom() -> HasheousRom:
|
||||
if (
|
||||
MetadataSource.HASHEOUS in metadata_sources
|
||||
and platform.fs_slug
|
||||
and (
|
||||
newly_added
|
||||
or scan_type == ScanType.COMPLETE
|
||||
or (scan_type == ScanType.PARTIAL and not rom.hasheous_id)
|
||||
or (scan_type == ScanType.UNIDENTIFIED and not rom.hasheous_id)
|
||||
)
|
||||
):
|
||||
return await meta_hasheous_handler.get_rom(rom_attrs)
|
||||
|
||||
return HasheousRom(igdb_id=None)
|
||||
|
||||
# Run both metadata fetches concurrently
|
||||
(
|
||||
igdb_handler_rom,
|
||||
@@ -431,6 +451,7 @@ async def scan_rom(
|
||||
ra_handler_rom,
|
||||
launchbox_handler_rom,
|
||||
playmatch_handler_rom,
|
||||
hasheous_handler_rom,
|
||||
) = await asyncio.gather(
|
||||
fetch_igdb_rom(),
|
||||
fetch_moby_rom(),
|
||||
@@ -438,6 +459,7 @@ async def scan_rom(
|
||||
fetch_ra_rom(),
|
||||
fetch_launchbox_rom(platform.slug),
|
||||
fetch_playmatch_rom(),
|
||||
fetch_hasheous_rom(),
|
||||
)
|
||||
|
||||
# Only update fields if match is found
|
||||
|
||||
@@ -120,6 +120,7 @@ class Rom(BaseModel):
|
||||
ss_id: Mapped[int | None]
|
||||
ra_id: Mapped[int | None]
|
||||
launchbox_id: Mapped[int | None]
|
||||
hasheous_id: Mapped[int | None]
|
||||
|
||||
__table_args__ = (
|
||||
Index("idx_roms_igdb_id", "igdb_id"),
|
||||
@@ -128,6 +129,7 @@ class Rom(BaseModel):
|
||||
Index("idx_roms_ra_id", "ra_id"),
|
||||
Index("idx_roms_sgdb_id", "sgdb_id"),
|
||||
Index("idx_roms_launchbox_id", "launchbox_id"),
|
||||
Index("idx_roms_hasheous_id", "hasheous_id"),
|
||||
)
|
||||
|
||||
fs_name: Mapped[str] = mapped_column(String(length=450))
|
||||
@@ -154,6 +156,9 @@ class Rom(BaseModel):
|
||||
launchbox_metadata: Mapped[dict[str, Any] | None] = mapped_column(
|
||||
CustomJSON(), default=dict
|
||||
)
|
||||
hasheous_metadata: Mapped[dict[str, Any] | None] = mapped_column(
|
||||
CustomJSON(), default=dict
|
||||
)
|
||||
|
||||
path_cover_s: Mapped[str | None] = mapped_column(Text, default="")
|
||||
path_cover_l: Mapped[str | None] = mapped_column(Text, default="")
|
||||
|
||||
@@ -30,6 +30,9 @@ PLAYMATCH_API_ENABLED=
|
||||
# LaunchBox
|
||||
LAUNCHBOX_API_ENABLED=
|
||||
|
||||
# Hasheous
|
||||
HASHEOUS_API_ENABLED=
|
||||
|
||||
# Database config
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
|
||||
BIN
frontend/assets/scrappers/hasheous.png
Normal file
BIN
frontend/assets/scrappers/hasheous.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 295 KiB |
@@ -11,5 +11,6 @@ export type MetadataSourcesDict = {
|
||||
RA_API_ENABLED: boolean;
|
||||
LAUNCHBOX_API_ENABLED: boolean;
|
||||
PLAYMATCH_API_ENABLED: boolean;
|
||||
HASHEOUS_API_ENABLED: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ const defaultHeartbeat: Heartbeat = {
|
||||
STEAMGRIDDB_API_ENABLED: false,
|
||||
LAUNCHBOX_API_ENABLED: false,
|
||||
PLAYMATCH_API_ENABLED: false,
|
||||
HASHEOUS_API_ENABLED: false,
|
||||
},
|
||||
FILESYSTEM: {
|
||||
FS_PLATFORMS: [],
|
||||
|
||||
@@ -63,6 +63,14 @@ const metadataOptions = computed(() => [
|
||||
? t("scan.disabled-by-admin")
|
||||
: "",
|
||||
},
|
||||
{
|
||||
name: "Hasheous",
|
||||
value: "hasheous",
|
||||
logo_path: "/assets/scrappers/hasheous.png",
|
||||
disabled: !heartbeat.value.METADATA_SOURCES?.HASHEOUS_API_ENABLED
|
||||
? t("scan.disabled-by-admin")
|
||||
: "",
|
||||
},
|
||||
{
|
||||
name: "Playmatch",
|
||||
value: "pm",
|
||||
|
||||
Reference in New Issue
Block a user