Skip to content

[Feature] Genre Metadata Exclusion List (Blocklist) #235

Description

@MitchBelcher

What's your idea?

Add the ability to define a list of excluded values or a "blocklist" for the genre metadata field that will prevent specific strings from ever being written to a book's genre field, regardless of which provider it is from. This would give users a simple, permanent fix for providers consistently returning specific unwanted or inaccurate genre field values without requiring any per-book intervention.

What problem does it solve?

Metadata providers - Google Books, iTunes, sometimes even the better ones like Goodreads or Hardcover - frequently return genre metadata values that don't align with reality, or potentially don't align with a particular user's library structure/plans. Let's look at a couple examples:

  • "Audiobook" routinely appears in the genre metadata, even for an ebook library. It appears because the provider platform likely sells or has matching data for an audiobook format version of the same title. Using myself as an example, I would prefer to never have this genre tag automatically applied, at least not to the "Books" library.
  • "Adult" also appears frequently, and while useful to some, may just be erroneous to others that may wish to try and keep their metadata more refined. That aside, it can sometimes appear on non-adult content simply due to the provider it's coming from having poorly defined genre rules, etc...

There is currently no way to prevent these values or others from being written to a particular metadata field. The only available workflows around this are:

  • Remove the offending provider from the Metadata Providers list or Field Rules entirely, which loses the potentially useful or otherwise desired genre metadata from that provider
  • Manually delete the unwanted genre metadata values from every affected book after each fetch/import, which does not reasonably scale with larger libraries, and if settings are set incorrectly for this intention the metadata may auto-refresh and re-apply the removed values anyway
  • Lock the genre metadata fields in question on each individual book after manual curation/intervention, which obviously also does not scale and doesn't prevent the root cause

Anything else? (optional)

The proposed feature would add a "Genre Blocklist" input underneath the genre field inside Settings->Metadata->Field Rules inside the existing "Advanced Fetch Behavior" panel near the "Combine genres from all selected providers" toggle button. This would be a single flat list of strings that BookOrbit would never write to the genre field of a book, regardless of provider it was sourced from.

Suggested UI: A text input field inside the "Advanced Fetch Behavior" section that accepts a list of comma-separated strings. Any value found that matches anything inside the blocklist is stripped from the results before a merge strategy runs.

Scope:

  • Global, across all metadata providers
  • Applies to both auto-fetch and manual search operations (auto-fill or search online)
  • Case-insensitive (could be a toggleable setting to make it case-sensitive potentially)
  • Will not retroactively apply to existing books, only prevents new writes of blocklisted values

Use Cases:

  • In a solely ebook library, you could blocklist/exclude "audiobook" since you intend there to never be anything other than ebook file types within, making this tag inaccurate
  • In a comics library, you could blocklist/exclude "graphic novel" to prevent pollution with a potentially separate graphic novel library

Potential Architecture Solution:
The current metadata fetch pipeline for genres flows as follows:

Provider A returns: ["Science Fiction", "Audiobook", "Fiction"]
Provider B returns: ["Sci-Fi", "Fiction"]
                     ↓
           mergeGenres() in metadata-fetch-pipeline.ts
           (deduplicates case-insensitively across all providers)
                     ↓
           Merge strategy (fillMissing | overwrite | overwriteIfProvided)
                     ↓
           Written to book: ["Science Fiction", "Audiobook", "Fiction"]

This feature could insert a single filtering step inside "mergeGenres()" before any genre is added to the merged output like so:

Provider A returns: ["Science Fiction", "Audiobook", "Fiction"]
Provider B returns: ["Sci-Fi", "Fiction"]
                     ↓
           mergeGenres() — skips any genre whose lowercase token is in blockSet
                     ↓
           Merged result: ["Science Fiction", "Fiction", "Sci-Fi"]
                     ↓
           Merge strategy (unchanged)
                     ↓
           Written to book: ["Science Fiction", "Fiction", "Sci-Fi"]

Filtering inside mergeGenres() is a potentially important decision - it would ensure blocked genres never reach the final strategy so all existing merge behavior can be untouched and continues to work as-is.

Both the background auto-fetch codepath (book-metadata-fetch-orchestrator.service.ts) and the user-initiated refresh path (book.service.ts -> refreshMetadata()) call the same applyPreferences() -> mergeGenres() method chain inside metadata-fetch-pipeline.ts, so this architecture could make a single change to affect both update paths.

Want to help?

Yes, I'd like to implement this

Before submitting

  • I've searched existing issues and this hasn't been requested yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature request or capability proposal.releasedIssue or PR is included in a released version.status:in-progressA contributor is actively working on this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions