Skip to content

feat(mediadb): toml settings for scraper bundle path and asset stat checks#927

Draft
BossRighteous wants to merge 1 commit into
mainfrom
toml-gamelists-path
Draft

feat(mediadb): toml settings for scraper bundle path and asset stat checks#927
BossRighteous wants to merge 1 commit into
mainfrom
toml-gamelists-path

Conversation

@BossRighteous

@BossRighteous BossRighteous commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

This is primarily to assist in batch storage and processing, so up to you if you think it's worthwhile.

All config fields optional

[scraper]
custom_gamelists_path = 'C:/Users/bossr/games/gamelists' # /{system.ID}/gamelist.xml
stat_gamelist_images = true

custom_gamelists_path (default "")
If defined, it will be used as another base path for gamelist lookups.
Where Launcher based system paths are derived from Folders[], which may have duplication and overlap (WonderSwan vs WonderSwanColor); this scan root will only check the literal SystemID string. I don't feel this is perfect but I think in the case of bundles this explicit Zaparoo system mapping is actually a better solution than continuing the fanout since it's not meant to be relative to actual roms/extension filters.

stat_gamelist_images (default false)
Recallbox gamelists have near guarantee that image paths defined were available when scraped. This can be trusted until it's time to load the asset via API.
Bundles would be made more flexible and convenient if defined image paths were first checked for existence.
Use case: batch gamelist.xmls could include game nodes with all known asset references and actual media could be managed from separate zips as requested.

<screenshot>./media/screenshot/ACME Animation Factory.png</screenshot>
<titlescreen>./media/titlescreen/ACME Animation Factory.png</titlescreen>
<boxart2d>./media/box2d/ACME Animation Factory.png</boxart2d>
<boxart3d>./media/box3d/ACME Animation Factory.png</boxart3d>
<logo>./media/logo/ACME Animation Factory.png</logo>

All of these could exists without error or bad scrape props being injected. If a user installed box2d and screenshot zips those would be found without a big burden.

If you like or dislike anything proposed feel free to suggest changes! I'll improve coverage if the overall strategy looks okay

Summary by CodeRabbit

  • New Features

    • Added scraper configuration with options for custom gamelists directory path.
    • Added option to enable statistics tracking for gamelist images.
    • Improved asset path resolution (images, videos, manuals) for custom gamelists.
  • Tests

    • Updated asset path normalization tests for improved filesystem validation.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR extends the gamelist.xml scraper to support custom gamelists with independent asset directories. Configuration enables specifying a custom gamelists path and an optional image statistics flag. Gamelist records now track a separate asset root path alongside the ROM root, enabling assets referenced in custom gamelist XML to resolve relative to the custom directory rather than the system root. The scraper also updates companion metadata handling to propagate asset paths through the metadata chain.

Changes

Custom Gamelists and Asset Path Resolution

Layer / File(s) Summary
Scraper configuration schema and accessors
pkg/config/config.go, pkg/config/configscraper.go
Configuration struct Values gains Scraper field; new Scraper config type defines optional CustomGamelistsPath and StatGamelistImages fields; accessor methods ScraperCustomGamelistsPath() and ScraperStatGamelistImages() safely read config under mutex with nil-safe handling.
Gamelist record and parsed file structure
pkg/database/scraper/gamelistxml/scraper.go
GamelistRecord and parsedGamelistFile structs add AssetRootPath field to track the base directory for resolving asset paths separately from ROM root.
Custom gamelist loading
pkg/database/scraper/gamelistxml/scraper.go
loadParsedGamelistSystem populates AssetRootPath for regular gamelists; new loadCustomGamelistFile helper reads custom gamelist XML from configured path and sets both RootPath and AssetRootPath for custom gamelist records.
Asset path resolution and pathProp refactoring
pkg/database/scraper/gamelistxml/scraper.go
MapToDB computes assetRoot from record.AssetRootPath (defaulting to system root) and uses it as the base for image/video/manual asset resolution. pathProp signature expanded to accept filesystem and checkExists parameters; it resolves asset paths via resolveESAssetPath, optionally validates file existence, and returns normalized property with MIME type.
Companion record AssetRootPath propagation
pkg/database/scraper/gamelistxml/scraper.go
companionParent struct gains AssetRootPath; companion parsing and record mapping now populate and carry AssetRootPath through companion metadata.
Test validation for pathProp
pkg/database/scraper/gamelistxml/scraper_test.go
TestPathProp_NormalizesSlashes updates to pass afero.NewOsFs() filesystem to pathProp, aligning test with revised function signature.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • ZaparooProject/zaparoo-core#776: Both PRs modify pkg/database/scraper/gamelistxml/scraper.go's gamelist.xml record construction/matching logic; this PR adds AssetRootPath propagation into GamelistRecord and path resolution, while the retrieved PR refactors LoadRecords and fallback matching.

Poem

🐰 Custom paths now bloom like clover,
Assets rooted where gamelists lead,
Companion tags follow the clover,
Each asset finds home, fulfilled is the deed!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately reflects the main changes: adding TOML configuration for scraper settings including custom gamelist bundle paths and asset statistics checks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch toml-gamelists-path

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@BossRighteous

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.78378% with 49 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/database/scraper/gamelistxml/scraper.go 43.10% 30 Missing and 3 partials ⚠️
pkg/config/configscraper.go 0.00% 16 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/database/scraper/gamelistxml/scraper_test.go (1)

1205-1213: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add targeted tests for the newly introduced custom-gamelist and stat-gated asset flows.

This change only updates the pathProp call signature; it does not add coverage for the new branches introduced in this PR (loadCustomGamelistFile, AssetRootPath propagation, and ScraperStatGamelistImages true/false behavior in MapToDB). Please add tests for those paths before merge.

As per coding guidelines, “Write tests for all new code — see TESTING.md and pkg/testing/README.md”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/database/scraper/gamelistxml/scraper_test.go` around lines 1205 - 1213,
The test suite only updated the pathProp call signature and lacks coverage for
the new branches; add targeted unit tests that exercise loadCustomGamelistFile
behavior, propagation of AssetRootPath through pathProp/MapToDB, and both
true/false cases of ScraperStatGamelistImages in MapToDB: create tests that (1)
simulate a custom-gamelist file and assert loadCustomGamelistFile is invoked and
parsed correctly, (2) set AssetRootPath and verify generated property paths from
pathProp/MapToDB use that root (including mixed separators normalization), and
(3) toggle ScraperStatGamelistImages and assert MapToDB includes or excludes
stat-gated image entries accordingly; reference functions:
loadCustomGamelistFile, AssetRootPath, pathProp, MapToDB,
ScraperStatGamelistImages to locate and extend tests.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pkg/database/scraper/gamelistxml/scraper_test.go`:
- Around line 1205-1213: The test suite only updated the pathProp call signature
and lacks coverage for the new branches; add targeted unit tests that exercise
loadCustomGamelistFile behavior, propagation of AssetRootPath through
pathProp/MapToDB, and both true/false cases of ScraperStatGamelistImages in
MapToDB: create tests that (1) simulate a custom-gamelist file and assert
loadCustomGamelistFile is invoked and parsed correctly, (2) set AssetRootPath
and verify generated property paths from pathProp/MapToDB use that root
(including mixed separators normalization), and (3) toggle
ScraperStatGamelistImages and assert MapToDB includes or excludes stat-gated
image entries accordingly; reference functions: loadCustomGamelistFile,
AssetRootPath, pathProp, MapToDB, ScraperStatGamelistImages to locate and extend
tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fcfcb64a-5e6f-42c0-b11f-b8add912504f

📥 Commits

Reviewing files that changed from the base of the PR and between 4bbf127 and d0637b3.

📒 Files selected for processing (4)
  • pkg/config/config.go
  • pkg/config/configscraper.go
  • pkg/database/scraper/gamelistxml/scraper.go
  • pkg/database/scraper/gamelistxml/scraper_test.go

@wizzomafizzo

Copy link
Copy Markdown
Member

they sound like good changes to me! i'm just getting a patch release ready but happy to to merge it after that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants