Skip to content

lastgenre: Last.fm genre ignorelist#5744

Closed
JOJ0 wants to merge 4 commits intomasterfrom
lastgenre_forbidden
Closed

lastgenre: Last.fm genre ignorelist#5744
JOJ0 wants to merge 4 commits intomasterfrom
lastgenre_forbidden

Conversation

@JOJ0
Copy link
Member

@JOJ0 JOJ0 commented Apr 20, 2025

Description

Adds a global and artist-specific genre ignorelist to lastgenre. Ignorelist entries can use regex patterns or literal genre names and are configurable per artist or globally (*). Example:

fracture:
    ^(heavy|black|power|death)?\s?(metal|rock)$
*:
    electronic

This avoids incorrect genre assignments for artists with overlapping names (e.g., “Fracture” the DnB producer vs a Metal band)..

  • A mixture of regex and simple genre names is possible since regex patterns are precompiled and if that fails, escaped literal strings are added to the ignorelist.
  • Genre ignore filtering occurs at two stages: immediately after Last.fm fetching to prevent unwanted tags from entering the pipeline, and again during genre resolution to filter unwanted genres from existing file tags.

Why invent a file format?

YAML and INI formats were tested but proved cumbersome for regex patterns. A simple custom format is user-friendly and allows all regex patterns without special escaping or formatting.

Further notes

My personal roadmap for the lastgenre plugin: #5915

Feature idea originated from: #5721 (comment).

To Do

  • Documentation.
  • Changelog.
  • Tests.

@github-actions
Copy link

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

@JOJ0 JOJ0 changed the title Lastgenre forbidden Lastgenre forbidden for artist list Apr 20, 2025
@JOJ0 JOJ0 force-pushed the lastgenre_forbidden branch from 256a8a1 to c8199cb Compare August 4, 2025 08:48
@codecov
Copy link

codecov bot commented Aug 4, 2025

Codecov Report

❌ Patch coverage is 78.70370% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.80%. Comparing base (1943b14) to head (bbc82b8).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
beetsplug/lastgenre/__init__.py 84.81% 7 Missing and 5 partials ⚠️
beetsplug/lastgenre/client.py 21.42% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5744      +/-   ##
==========================================
+ Coverage   69.73%   69.80%   +0.07%     
==========================================
  Files         145      146       +1     
  Lines       18534    18620      +86     
  Branches     3023     3044      +21     
==========================================
+ Hits        12924    12998      +74     
- Misses       4976     4984       +8     
- Partials      634      638       +4     
Files with missing lines Coverage Δ
beetsplug/lastgenre/utils.py 100.00% <100.00%> (ø)
beetsplug/lastgenre/client.py 50.00% <21.42%> (-3.20%) ⬇️
beetsplug/lastgenre/__init__.py 78.15% <84.81%> (+2.61%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JOJ0 JOJ0 force-pushed the lastgenre_forbidden branch 8 times, most recently from 9cd4947 to a0e6054 Compare August 4, 2025 15:41
@JOJ0 JOJ0 changed the title Lastgenre forbidden for artist list Lastgenre global and artist-based genre _blacklist_ Aug 5, 2025
@JOJ0 JOJ0 changed the title Lastgenre global and artist-based genre _blacklist_ lastgenre: Global and artist-based genre blacklist Aug 5, 2025
@JOJ0 JOJ0 force-pushed the lastgenre_forbidden branch from a3daa01 to 4868326 Compare August 5, 2025 16:10
@JOJ0 JOJ0 marked this pull request as ready for review August 5, 2025 22:28
Copilot AI review requested due to automatic review settings August 5, 2025 22:28
@github-actions
Copy link

github-actions bot commented Aug 5, 2025

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

This comment was marked as outdated.

@JOJ0 JOJ0 force-pushed the lastgenre_forbidden branch from 5b24d49 to 13a01b1 Compare August 6, 2025 05:07
@JOJ0 JOJ0 marked this pull request as draft August 18, 2025 09:20
@JOJ0
Copy link
Member Author

JOJ0 commented Aug 18, 2025

Setting this back to draft. I'd like to fix this bug first: #5930

@JOJ0 JOJ0 force-pushed the lastgenre_forbidden branch 3 times, most recently from 58c1299 to 9e5f168 Compare August 28, 2025 05:39
@JOJ0 JOJ0 marked this pull request as ready for review August 28, 2025 06:34
@JOJ0 JOJ0 force-pushed the lastgenre_split_monolith branch 4 times, most recently from 42b0d45 to e49d7a3 Compare March 7, 2026 07:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

beetsplug/lastgenre/init.py:474

  • grug see log label suffix only say "whitelist" or "any". but now blacklist can filter too, so label "any" lie when blacklist active. grug want suffix reflect blacklist (ex: "any+blacklist" or similar) so debug logs tell truth.
                suffix = "whitelist" if self.whitelist else "any"
                label = f"{stage_label}, {suffix}"

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

beetsplug/lastgenre/init.py:483

  • grug see log label say whitelist vs any based only on self.whitelist. but now blacklist can filter too. when whitelist off but blacklist on, label say any even though not any. please include blacklist state in label (ex: blacklist, or whitelist+blacklist) so logs tell truth.
                suffix = "whitelist" if self.whitelist else "any"
                label = f"{stage_label}, {suffix}"
                if keep_genres:
                    label = f"keep + {label}"
                return self._format_genres(resolved_genres), label

beetsplug/lastgenre/init.py:322

  • grug see _resolve_genres docstring still talk only about whitelist filtering. now blacklist also filter and can skip c14n parent walk. please update docstring bullets so match new behavior (whitelist+blacklist).
        """Canonicalize, sort and filter a list of genres.

        - Returns an empty list if the input tags list is empty.
        - If canonicalization is enabled, it extends the list by incorporating
          parent genres from the canonicalization tree. When a whitelist is set,
          only parent tags that pass the whitelist filter are included;
          otherwise, it adds the oldest ancestor. Adding parent tags is stopped
          when the count of tags reaches the configured limit (count).
        - The tags list is then deduplicated to ensure only unique genres are
          retained.
        - If the 'prefer_specific' configuration is enabled, the list is sorted
          by the specificity (depth in the canonicalization tree) of the genres.
        - Finally applies whitelist filtering to ensure that only valid
          genres are kept. (This may result in no genres at all being retained).
        - Returns the filtered list of genres, limited to the configured count.

@github-actions
Copy link

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

beetsplug/lastgenre/init.py:486

  • grug see log label pick suffix "any" when whitelist off. but now blacklist can be on, so it not really "any". log say wrong thing, debug harder. suggest include blacklist state in suffix (ex: "blacklist" or "any+blacklist").
            if resolved_genres:
                suffix = "whitelist" if self.whitelist else "any"
                label = f"{stage_label}, {suffix}"
                if keep_genres:

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

@github-actions
Copy link

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

beetsplug/lastgenre/init.py:326

  • grug read docstring still talk like only whitelist filter at end, but now ignorelist also filter tags (and skip c14n walk). please update docstring bullets so it match real behavior, else reader confused.
        - Returns an empty list if the input tags list is empty.
        - If canonicalization is enabled, it extends the list by incorporating
          parent genres from the canonicalization tree. When a whitelist is set,
          only parent tags that pass the whitelist filter are included;
          otherwise, it adds the oldest ancestor. Adding parent tags is stopped
          when the count of tags reaches the configured limit (count).
        - The tags list is then deduplicated to ensure only unique genres are
          retained.
        - If the 'prefer_specific' configuration is enabled, the list is sorted
          by the specificity (depth in the canonicalization tree) of the genres.
        - Finally applies whitelist filtering to ensure that only valid
          genres are kept. (This may result in no genres at all being retained).
        - Returns the filtered list of genres, limited to the configured count.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

- Test file format (valid and error cases)
- Test regex pattern matching (_is_ignored)
- Test fullmatch FIXME required?
- Test _resolve_genres: ignored genres filtered
- Test _resolve_genres: c14n ancestry walk blocked for ignored tags
- Test _resolve_genres: without whitelist, oldest ancestor is kept
- Test _resolve_genres: whithout whitelist, ignored oldest ancestor is
  removed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

JOJ0 added 2 commits March 19, 2026 22:34
- Prevents wrong last.fm genres based on a per artist (or global) list of regex
  patterns that should be ignored.
  - Genre _ignoring_ happens in two places: Right after fetching the
    last.fm genre and in _resolve_genres.
  - As a fallback literal string matching can be used instead of
    supplying a regex pattern
- Includes docs for the new feature.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

@JOJ0
Copy link
Member Author

JOJ0 commented Mar 19, 2026

This PR is getting to messy with copilot reviews and changes, closing in favor of a fresh one for easier review: #6449

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

Labels

lastgenre plugin Pull requests that are plugins related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants