Commit Graph

398 Commits

Author SHA1 Message Date
Georges-Antoine Assi
69e2373453 cleanup archive member 2026-05-29 20:54:32 -04:00
Georges-Antoine Assi
10d731d823 cleanup 2026-05-29 11:58:53 -04:00
Georges-Antoine Assi
ae60d14f81 Merge branch 'master' into feat/composite-hashing-archives 2026-05-29 11:50:17 -04:00
Georges-Antoine Assi
207d0dc4c6 feat(hashing): persist per-member hashes on archive RomFile
Internal members of multi-file archives (zip/tar/7z/rar) are now hashed
individually (crc/md5/sha1) and stored in a new `archive_members` JSON
column on the archive's RomFile, alongside the existing composite hash
used for hash-database matching. Only the archive itself is surfaced as
a RomFile so full_path keeps pointing at a file that exists on disk,
which is the constraint that previously forced us to choose between
composite-only or broken downloads.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 09:41:04 -04:00
Georges-Antoine Assi
1a560d3660 cleanup 2026-05-24 18:57:38 -04:00
Georges-Antoine Assi
fb13f54f48 cleanup 2026-05-24 17:43:01 -04:00
Claude
8fcc16bad2 refactor(roms): replace denormalized columns with deferred column_property
Drop the migration and the multi_file / top_level_file_count columns on
roms; express both as deferred column_property correlated subqueries
against rom_files instead. The gallery list and detail queries opt in
via undefer, so they get the values computed in the same SELECT via
indexed subqueries (rom_id index already in place); other code paths
that don't read the flags pay nothing.

This keeps the gallery perf win (no rom_files load for cards) without
introducing schema state that has to stay in sync with rom_files at
write time.
2026-05-24 20:41:44 +00:00
Claude
5adffeca71 perf(roms): skip rom_files load on gallery list endpoint
The gallery list endpoint was eager-loading every rom_file row for each
paginated ROM via selectinload, then re-joining each row back to its
parent rom for the is_top_level computation. For platforms with extracted
multi-file ROMs (Xbox 360 ~1394 files/ROM, Switch ~199 files/ROM), this
made /api/roms time out at 120s even with a rom_id index.

Cards never displayed individual files — only the has_simple_single_file
/ has_nested_single_file / has_multiple_files booleans that derive from
the file list. Denormalize the underlying state onto roms as multi_file
(folder-based vs single-file) and top_level_file_count, recompute the
booleans from those columns, drop the selectinload from filter_roms, and
move the files field from SimpleRomSchema to DetailedRomSchema so the
gallery payload no longer ships file rows.

Also drop the redundant joinedload(RomFile.rom) and switch the relation
to lazy="select" so subsequent file.rom accesses resolve from the
session identity map instead of re-JOINing the parent rom per file row.

ShowQRCode.vue's folder-based DS/3DS fallback now fetches the detailed
rom on demand, since SimpleRom no longer carries files.
2026-05-24 15:02:02 +00:00
copilot-swe-agent[bot]
f284ef2fba fix: treat libretro-matched roms as identified
Agent-Logs-Url: https://github.com/rommapp/romm/sessions/9cc2e55e-af48-40bd-b2e9-492b6fd6046a

Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-05-20 19:14:35 +00:00
Spinnich
01f0b1d2b5 feat(hashing): compute raw CHD hashes and route disc-data SHA1 to Hasheous
CHD files now follow the same hash logic as all other file types — CRC32,
MD5, and SHA1 are computed from raw container bytes. This allows
ScreenScraper to log KO entries for unrecognised CHD files, which it
could not do when only the disc-data SHA1 was being computed.

The CHD header SHA1 (disc-data SHA1) is separately extracted and stored
in a new chd_sha1_hash field on RomFile, with a migration adding the
column to rom_files. Hasheous receives only this disc-data SHA1 (no
CRC/MD5) since it indexes disc-based games by disc-data SHA1, not raw
file hashes.

The RAHasher multi-file path now passes the largest CHD directly instead
of a /* wildcard, which RAHasher cannot expand. Hash computations are
wrapped in asyncio.to_thread to avoid blocking the event loop during
large reads.

Hash-lookup metadata handlers (ScreenScraper, Hasheous, Playmatch) now
fall back to rom.files (stored DB hashes) when fs_rom files are not
rehashed, fixing hash-based matching for UNMATCHED and UPDATE scan types.

The Disc SHA-1 is displayed in the ROM detail view for both single-file
(FileInfo.vue) and multi-file (FileSelectItem.vue) CHD games.
2026-05-17 08:01:05 -04:00
Georges-Antoine Assi
8fc426b35c Import local LaunchBox videos
LaunchBox stores videos under /romm/launchbox/Videos/<Platform>/<Game>.<ext>
but the handler only extracted YouTube IDs; LAUNCHBOX_VIDEOS_DIR was
defined and unused. Add _get_video() to surface local videos as
launchbox-file:// URLs, thread a populate_rom_specific_paths() through
the scan pipeline to set video_path once the rom is known, and mirror
the SS/gamelist branch in the scan socket so store_media_file actually
copies the video into the rom's resource directory. Rom.path_video now
also reads from launchbox_metadata.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 12:13:42 -04:00
copilot-swe-agent[bot]
ce5624b470 Add index on rom_files(rom_id) to fix PostgreSQL performance issue
Agent-Logs-Url: https://github.com/rommapp/romm/sessions/7bb628cb-282d-44c3-b912-9c81212611a9

Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-04-14 02:35:19 +00:00
Georges-Antoine Assi
4928041593 manual cleanu 2026-04-12 11:04:12 -04:00
Georges-Antoine Assi
6df31e2cc0 Merge branch 'master' into libretro-handler 2026-04-12 10:14:26 -04:00
Georges-Antoine Assi
522df9d31a feat: add libretro thumbnails as an artwork source
Adds the libretro thumbnail repository as a first-class artwork source so
region-correct box art (PAL/Europe, Japan, etc.) can be matched directly
to ROM filenames, addressing rommapp/romm#3239.

Implementation follows the SGDB handler pattern (artwork-only, no game
metadata): MetadataSource enum entry, scan-time fetch wired into the
SCAN_ARTWORK_PRIORITY loop, /search/roms integration, MatchRom dialog
chip + cover selection, and a heartbeat flag.

Matching is exact case-insensitive against the directory listing first
(so a ROM named "(Europe)" lands on the (Europe) artwork), with a
JaroWinkler fuzzy fallback at 0.8 that strips parenthetical tags from
both sides. Listings are cached in Redis with a 24h TTL.

`libretro_id` is persisted on the Rom model as the SHA1 hex of the
matched libretro filename — stable across scans, distinct per region,
indexed for lookup. Migration 0077 adds the column.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:57:20 -04:00
Georges-Antoine Assi
3991e1b6ed fix: scan stalls on platforms with 10k+ already-scanned ROMs
The scan was spending excessive time on large platforms even when all ROMs
were already scanned. Root causes: per-ROM UPDATE queries for skipped ROMs
(10k individual writes), missing composite index on (platform_id, fs_name)
causing full table scans, NOT IN clauses with 10k+ values in
mark_missing_roms(), and redundant filesystem reads.

Changes:
- Add bulk_mark_present() for batch-updating skipped ROMs in one query
- Move skip detection from _identify_rom to the batch loop so skipped ROMs
  never enter the async scan pipeline, and report progress for them
- Add composite index idx_roms_platform_id_fs_name via migration 0077
- Rewrite mark_missing_roms() with flip-based approach: mark all missing,
  then un-mark present ones in chunks of 1000
- Cache filesystem reads in scan_platforms() to avoid double directory
  traversal (precounting + scanning)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:20:40 -04:00
Georges-Antoine Assi
ae03b0b322 ingest playtime with sync sessions 2026-04-06 21:32:13 -04:00
Georges-Antoine Assi
e5cb29ae80 Merge branch 'master' into feature/play-session-ingest 2026-04-06 12:42:15 -04:00
Georges-Antoine Assi
f2e8e337b2 Merge branch 'master' into save-sync 2026-04-05 21:47:53 -04:00
Georges-Antoine Assi
7c41fb5bac revert fs_name sibling roms 2026-04-05 17:57:48 -04:00
Abdessamad Derraz
6aa543c3ff fix: correct ZX Spectrum +3 ROM hashes 2026-03-27 16:43:06 +01:00
nendo
75302ed59a Add play session ingest for game time tracking
Backend API for collecting and querying play sessions, modeled after
the Argosy session data format. Clients submit batches per device,
recording both the session window and screen-on time.
2026-03-22 20:22:55 +09:00
Georges-Antoine Assi
e1b07cacfc make devices actually unique 2026-03-15 20:09:33 -04:00
Georges-Antoine Assi
b3fbbf59fb add tests 2026-03-14 23:35:04 -04:00
Georges-Antoine Assi
e6ddc5da11 bot attempt at save sync 2026-03-14 22:13:38 -04:00
nendo
ea5b7546aa refactor: address PR #3114 review feedback
- Use atomic getdel for pairing code exchange
- Add cascade="all, delete-orphan" to User.client_tokens
- Move generate/hash_client_token into AuthHandler as static methods
- Extract endpoint helpers to utils/client_tokens.py
2026-03-11 10:56:35 +09:00
nendo
d97791f1d4 fix: address PR review feedback
- Add back_populates="client_tokens" to ClientToken.user relationship
- Fix rate limit race condition: increment-first pattern instead of
  read-then-write
- Remove unused User import from tests
- Add i18n keys to all non-en_US locales
2026-03-11 10:56:35 +09:00
nendo
e0b25fbc6c feat(client-tokens): add client API tokens with QR pairing flow
Long-lived, revocable, scope-restricted tokens for external clients
(mobile apps, retro handhelds, third-party tools). Includes:

- Backend: model, migration, DB handler, auth integration (rmm_ prefix
  routing in HybridAuthBackend), CRUD + pairing + exchange endpoints,
  rate limiting, scope intersection enforcement, admin oversight
- Frontend: settings page with token management table, stepped
  create/deliver dialog (config -> copy/pair), QR code with RomM logo,
  admin token table, standalone /pair page for QR scan landing
- /pair page supports custom-scheme callbacks for app deep linking,
  falls back to displaying code for manual entry
- 33 backend tests across 5 classes (CRUD, auth, isolation, pairing,
  admin)
2026-03-11 10:56:35 +09:00
Georges-Antoine Assi
478b7b970a run fmt 2026-03-10 16:53:36 -04:00
Jamie Bond
1e6f0d6000 Add property for path_video and refactor places which use similar logic to access video paths 2026-03-10 20:32:54 +01:00
Georges-Antoine Assi
6461078721 loosen rules around fetch matching screenshots 2026-02-19 10:18:56 -05:00
Georges-Antoine Assi
bbb1ba3ec0 cahanges from bot review 2026-02-19 09:36:12 -05:00
Georges-Antoine Assi
5b1dfe2ba1 [ROMM-3031] Fix screenshot property on save/state 2026-02-18 23:23:35 -05:00
Georges-Antoine Assi
c6e9ce5bbd filter out non-owned collections when adding 2026-02-08 09:52:55 -05:00
Georges-Antoine Assi
0da88e4727 Merge pull request #2984 from zeroSteiner/fix/issue/2451
Fix #2451: Group games with same name but different tags as versionsr
2026-02-03 23:27:41 -05:00
Spencer McIntyre
d95899333f Add the migration for the new view 2026-02-03 20:12:54 -05:00
nendo
a236123e4f feat(saves): add slot-based save sync with content hash deduplication
- Add device registration and save synchronization
- Implement slot-based save organization with datetime tagging
- Add conflict detection for multi-device sync scenarios
- Add content hash computation for save deduplication
- Support ZIP inner-file hashing for consistent deduplication
- Add confirm_download endpoint for sync state management
- Add overwrite parameter to bypass conflict checks
2026-01-31 21:57:22 +09:00
Georges-Antoine Assi
24fef1139b Merge branch 'master' into feature/device-registration-save-sync 2026-01-28 19:42:57 -05:00
Georges-Antoine Assi
e50016b26b Add CHEAT to RomFile category types 2026-01-25 19:18:43 -05:00
nendo
36eec298d1 Add device-based save synchronization
Implement device registration and save sync tracking to enable
multi-device save management with conflict detection.

- Device CRUD endpoints (POST/GET/PUT/DELETE /api/devices)
- Save sync state tracking per device
- Conflict detection on upload (409 when device has stale sync)
- Download sync tracking (optimistic and confirmed modes)
- Track/untrack saves per device
- DEVICES_READ/WRITE scopes for authorization
2026-01-18 16:50:44 +09:00
DevOldSchool
331ed76187 Applied feedback from gemini code assist review. 2026-01-05 12:38:07 +10:00
DevOldSchool
86a6804447 Added player count metadata from SS. Displays on game detail screen and added a filter under search for player counts. 2026-01-05 11:57:30 +10:00
SaraVieira
fe14067667 feature: Add addtional editable metadata 2026-01-02 17:30:05 +00:00
zurdi
8eb9668275 Merge branch 'master' into 816-uiux-make-user-settings-cross-browserdevice 2025-12-31 11:48:25 +00:00
zurdi
649597b494 fix RA badgeds download 2025-12-31 01:34:37 +00:00
Georges-Antoine Assi
734645aa07 cache top level files 2025-12-30 16:45:32 -05:00
Georges-Antoine Assi
a45bde142e [HOTFIX] Multi roms should only consider top-level files 2025-12-30 16:37:55 -05:00
Georges-Antoine Assi
0971026f95 Add support for version tag 2025-12-30 11:37:06 -05:00
zurdi
ec4d157905 Add user UI settings management and update related components
- Introduced `ui_settings` column in the users table via Alembic migration.
- Updated UserForm and UserSchema models to include `ui_settings`.
- Enhanced user update endpoint to handle `ui_settings`.
- Created a new composable `useUISettings` for managing UI settings with local storage.
- Refactored UI components to utilize the new `useUISettings` for theme and language settings.
2025-12-16 23:16:36 +00:00
Georges-Antoine Assi
324932184a Move merged_screenshots and merged_ra_metadata to simple RomSchema 2025-12-02 10:32:17 -05:00