Commit Graph

9718 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
08324e8461 Disable Valkey snapshot write lock for internal cache
Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-06-12 19:24:54 +00:00
copilot-swe-agent[bot]
949dfcbc19 Initial plan 2026-06-12 19:16:43 +00:00
Georges-Antoine Assi
788527ad61 Merge pull request #3508 from rommapp/copilot/bug-fix-romm-folder-structure
fix: Structure A always takes priority over Structure B in library detection
2026-06-12 15:14:49 -04:00
Georges-Antoine Assi
49ef5097e4 fix: split structure detection into has_structure_path_a, fail loudly on bad layouts
Extract has_structure_path_a as its own cached property and have
has_structure_path_b delegate to it, removing duplicated isdir checks.
detect_library_structure and get_platforms_directory now read the named
properties instead of re-implementing the roms-path check inline.

Keep the inconclusive/bad-structure fallback defaulting to Structure A so
a malformed library raises FolderStructureNotMatchException rather than
listing the bare library root as a flat list of platforms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 14:59:01 -04:00
copilot-swe-agent[bot]
788d454d98 fix: prioritize Structure A over Structure B in library structure detection
When a top-level `roms/` folder exists (Structure A), never detect the
library as Structure B, even if individual `<platform>/roms/` directories
also exist. This prevents existing Structure A libraries from being broken
after upgrading to 4.9.0.

- `has_structure_path_b` in `config_manager.py` now returns `False` early
  when `{LIBRARY_BASE_PATH}/{ROMS_FOLDER_NAME}` is an existing directory
- `detect_library_structure()` in `platforms_handler.py` now explicitly
  checks Structure A (`os.path.exists(roms_path)`) before consulting
  `cnfg.has_structure_path_b`
- Updated test to assert Structure A wins when both layouts coexist

Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-06-12 16:35:01 +00:00
copilot-swe-agent[bot]
4ccad8ba17 Initial plan 2026-06-12 16:13:37 +00:00
Georges-Antoine Assi
2920ca96cf Merge pull request #3504 from rommapp/dependabot/uv/urllib3-2.7.0
Bump urllib3 from 2.6.3 to 2.7.0
4.9.0
2026-06-10 15:50:29 -04:00
dependabot[bot]
d38709a8d8 Bump urllib3 from 2.6.3 to 2.7.0
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.6.3 to 2.7.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.3...2.7.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.7.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-10 18:54:12 +00:00
Georges-Antoine Assi
2e89f85625 Merge pull request #3500 from Spinnich/fix/ra-hash-folder-disc-games
fix(ra): hash folder-based disc ROMs (.cue + .bin) for RetroAchievements
4.9.0-beta.3
2026-06-10 07:27:55 -04:00
Georges-Antoine Assi
8b9c3d3166 Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-10 07:01:19 -04:00
Georges-Antoine Assi
99e8f08513 Use mD5/shA1 keys in Hasheous lookup payload
Match the json-patch camelCase key names the Hasheous endpoint expects,
and update the lookup_rom test assertions accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:36:31 -04:00
Spinnich
f4e39c19bc fix(ra): hash folder-based disc ROMs (.cue + .bin) for RetroAchievements
Folder-stored disc games (the standard Redump .cue + .bin layout, .gdi
sets, multi-bin, etc.) never matched RetroAchievements. roms_handler
builds an `ra_path` ending in `/*` when the folder has no .chd, and
RAHasherService only rescued that glob for folders containing archives.
A folder of plain uncompressed tracks fell through, so the literal `*`
reached RAHasher via create_subprocess_exec (no shell to expand it),
which failed with "Could not open track" and stored an empty ra_hash.

Resolve the `/*` glob to a single real file before spawning RAHasher:
prefer a disc descriptor (.cue/.gdi/.m3u), which RAHasher follows to the
referenced tracks, otherwise fall back to the largest file in the folder
(raw .iso/.bin, or the main file of a multi-file cartridge set). This
mirrors the existing "pick the largest .chd" handling for CHD folders.

Fixes #3497.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:13:07 +00:00
Georges-Antoine Assi
69a7a13603 Merge pull request #3498 from rommapp/hasheous-lookup-all-hashes
Send all top-level file hashes to Hasheous lookup
2026-06-09 08:08:36 -04:00
Georges-Antoine Assi
08e8821b4b Fix mypy types in Hasheous _request and lookup_rom
Annotate request_kwargs as dict[str, Any] to accept the list json payload,
and file_hashes as dict[str, str | None] so the chd_sha1_hash branch and the
md5/sha1/crc branch unify cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 07:54:33 -04:00
Georges-Antoine Assi
650ab6925c Send all top-level file hashes to Hasheous lookup
The Hasheous ByHash endpoint now accepts an array of hash objects rather
than a single one. Send the hashes of every top-level file (using
chd_sha1_hash exclusively for files that have one) to improve lookup
accuracy, instead of picking only the largest file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 07:43:44 -04:00
Georges-Antoine Assi
f4960386e5 Merge pull request #3495 from rommapp/copilot/fix-smart-collection-crash
Fix smart collection status filter normalization for multi-value legacy payloads
4.9.0-beta.2
2026-06-08 12:01:28 -04:00
Georges-Antoine Assi
8366e288af run fmt 2026-06-08 11:53:42 -04:00
Georges-Antoine Assi
3f26398093 Merge pull request #3494 from rommapp/copilot/fix-safari-bezel-asset-error
Handle missing console bezel assets without rendering Safari broken-image overlay
2026-06-08 11:52:34 -04:00
Georges-Antoine Assi
3df3a8c712 Merge pull request #3490 from tmgast/feature/roms-list-include-expansions
Add opt-in files/siblings expansion to GET /api/roms
2026-06-08 11:31:41 -04:00
Georges-Antoine Assi
f077484b55 fix tests 2026-06-08 11:22:14 -04:00
Georges-Antoine Assi
cd101758fd cleanup for simplicity 2026-06-08 11:13:15 -04:00
Georges-Antoine Assi
036cf108f4 sinmplify siblings 2026-06-08 10:25:27 -04:00
copilot-swe-agent[bot]
7ab4052f93 Fix legacy smart collection status list normalization
Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-06-08 12:25:56 +00:00
copilot-swe-agent[bot]
a7751c55cd fix(console): hide bezel overlay when bezel asset fails to load
Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-06-08 12:17:15 +00:00
copilot-swe-agent[bot]
ed700c0075 Initial plan 2026-06-08 12:15:31 +00:00
copilot-swe-agent[bot]
0ff47ca5c2 Initial plan 2026-06-08 12:12:04 +00:00
nendo
cfdeab589a Derive sibling_ids from expanded siblings 2026-06-08 11:26:15 +09:00
nendo
f722d9234f Remove comment on files field 2026-06-08 10:57:54 +09:00
Georges-Antoine Assi
31512136a5 Merge pull request #3485 from rommapp/claude/fervent-bohr-4Db3f
Add rate limiting to metadata service API requests
2026-06-07 16:03:39 -04:00
Georges-Antoine Assi
5a5ae26590 changes from bot review 2026-06-07 15:16:40 -04:00
Georges-Antoine Assi
6acea1339f cahnges from bot review 2026-06-07 13:54:01 -04:00
Georges-Antoine Assi
41fd1eb6f1 wrap debugpy in DEV_MODE 2026-06-07 13:03:23 -04:00
Georges-Antoine Assi
e1bb3901b4 add debuggability 2026-06-07 09:16:50 -04:00
Georges-Antoine Assi
329f132389 remove comments 2026-06-07 08:34:34 -04:00
Georges-Antoine Assi
ab9b7bd775 changes from self review 2026-06-07 08:29:49 -04:00
Claude
105bca7e68 Add IGDBService rate-limiter unit test
The IGDB service acquires a rate-limiter slot before each request like the
other metadata services, but unlike them had no direct unit test asserting it
(IGDB is otherwise exercised via cassette-backed handler tests). Add a focused
test so the limiter call can't be silently removed or moved after the request.

https://claude.ai/code/session_01133QQuWvq8Zm25DZMP9PVr
2026-06-07 12:16:02 +00:00
nendo
37f0feab8c Add opt-in files/siblings expansion to GET /api/roms 2026-06-07 16:12:21 +09:00
Zurdi
bb82cf470a Merge pull request #3489 from rommapp/copilot/fix-auth-header-handling
Handle malformed Authorization headers in HybridAuthBackend without 500s
2026-06-07 00:36:24 +02:00
copilot-swe-agent[bot]
a2775ca2b8 fix: handle malformed authorization header in hybrid auth backend
Co-authored-by: zurdi15 <34356590+zurdi15@users.noreply.github.com>
2026-06-06 22:22:41 +00:00
copilot-swe-agent[bot]
27725c26b3 Initial plan 2026-06-06 22:14:01 +00:00
Claude
cd41422660 Use a concurrency limiter for ScreenScraper, honoring account threads
ScreenScraper enforces a per-account *thread* (concurrency) cap rather than
a request rate. Requests can take several seconds, so spacing out request
starts at 1/s could still leave multiple requests overlapping in flight,
exceeding the cap and getting rejected with ScreenScraper's custom HTTP codes.

- Add ConcurrencyLimiter: a runtime-resizable, loop-agnostic limiter that
  bounds simultaneous in-flight operations (held for the whole request via
  async context manager), instead of spacing request starts.
- Switch the ScreenScraper service from the req/s RateLimiter to a module-level
  ConcurrencyLimiter defaulting to a single thread.
- Recognize contributor/donor accounts: parse `ssuser.maxthreads` from each
  response and raise the concurrency allowance to match, so supporters scrape
  with their full thread count instead of the conservative default.

Adds unit tests for the limiter (blocking, wake-on-release, runtime resize)
and for the ScreenScraper slot-holding and thread-allowance updates.

https://claude.ai/code/session_01133QQuWvq8Zm25DZMP9PVr
2026-06-06 16:02:13 +00:00
Claude
8cc79f9e5c Add pre-emptive rate limiting to metadata API services
Wire the existing RateLimiter into the IGDB, ScreenScraper, MobyGames and
RetroAchievements services so requests are spaced under each provider's
documented req/s cap, instead of only reacting to HTTP 429 after the fact.

- IGDB: 4 req/s (documented hard limit)
- MobyGames: 1 req/s (free-tier burst cap)
- ScreenScraper: 1 req/s (free-tier throttle)
- RetroAchievements: 4 req/s (conservative; no published hard limit)

A slot is acquired before both the initial request and the timeout/429
retry. The reactive 2s 429 backoff is kept as a fallback. Tests neutralize
the shared limiters via an autouse fixture and assert acquire() is awaited.

https://claude.ai/code/session_01133QQuWvq8Zm25DZMP9PVr
2026-06-06 14:34:56 +00:00
Georges-Antoine Assi
56f65bb266 Merge pull request #3484 from rommapp/claude/busy-keller-gd2Ue
Fix Docker volume mounts to enable hardlink optimization
2026-06-06 10:31:39 -04:00
Georges-Antoine Assi
21f60b64aa add smol comment 2026-06-06 10:28:02 -04:00
Georges-Antoine Assi
a69f09b7f8 cleanup 2026-06-06 10:24:08 -04:00
Claude
6d533e0a25 fix(docker): declare /romm as single volume to enable asset hardlinks
PR #3388 added hardlink-based asset import/export (os.link with a
shutil.copy2 fallback) to avoid duplicating disk space. The Dockerfile
VOLUME instruction listed each /romm subdirectory (resources, library,
assets, config, sync) separately, which makes Docker create an
independent mount point for each one — even when the user bind-mounts a
single parent at /romm. Each mount point is its own st_dev, so every
cross-directory os.link() failed with EXDEV and silently fell back to a
full copy, defeating the optimization.

Declare the parent /romm directory instead so all subdirectories share a
single filesystem and hardlinks can succeed when paths reside on the same
underlying host filesystem.
2026-06-06 14:20:29 +00:00
Georges-Antoine Assi
84d4bf1235 Merge pull request #3482 from DevYukine/feat/playmatch-rate-limit
feat(playmatch): add ratelimiting
2026-06-06 10:10:22 -04:00
Georges-Antoine Assi
ec172dfeb1 use const 2026-06-06 09:58:17 -04:00
DevYukine
8006e4391d feat(playmatch): pre-emptive 4 req/s rate limiting with best-effort lookups 2026-06-06 04:16:21 +02:00
Georges-Antoine Assi
031fb57947 Merge pull request #3479 from tmgast/fix/save-device-attribution
Expose per-device save sync attribution and origin device
2026-06-05 19:37:47 -04:00