Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PICARD-2607: Add a “_genre” variable #2545

Merged
merged 13 commits into from
Jan 1, 2025
Merged

Conversation

rakim0
Copy link
Contributor

@rakim0 rakim0 commented Oct 19, 2024

Summary

  • This is a…
    • Bug fix
    • Feature addition
    • Refactoring
    • Minor / simple change (like a typo)
    • Other
  • Describe this change in 1-2 sentences:
    Adds a custom field for folksonomy tags and genre.

Problem

There was no custom field for folksonomy tags. User was forced to either set all genre as genre tags or all folksonomy tags as Genre.
This PR aims to resolve it by introducing two new tags _folksonomy_tag and _genre.

Solution

To get both _genres and _folksonomy tags from the MusicBrainz server, I removed the 'use_folksonomy` check in picard/items.py and stored the tags in respective variables. Then for writing the metadata, I added two new functions in picard/track.py that would update the metadata with _genre and _folksonomy_tag. And before writing genre into the file, check whether genre should be set to _folksonomy_tag or _genre itself.

Check for 'Use only my genre' option is still done in picard/items.py

Action

Additional actions required:

  • Update Picard documentation (please include a reference to this PR)
  • Other (please specify below)

The check has been moved here from picard/mbjson.py as we are
loading _genres and _folksonomy_tags regardless of user setting.
Thus for filling in the actual genre tag, we are checking the user
preference.
@rakim0
Copy link
Contributor Author

rakim0 commented Oct 19, 2024

I tried to follow the Contribution Guidelines as much as possible but was a bit unsure about having multiple commits but couldn't figure a good commit message so broke the commit into 4 parts.

@Sophist-UK
Copy link
Contributor

I am really unclear whether this is actually a bug fix. And if it is an enhancement instead, then if it is not going to do something much more generalised, then it least needs to make sure it will be compatible with a future generalised function.

The issue with Genres is that there are so many competing sources of variable quality - many are free-form rather than a fixed list, those that are fixed lists have different fixed lists, and even when there are identical names, the definitions may be different or the allocation subjective. So if you are trying to fill a genre tag from multiple sources, you need to make sense of the mess you may often be given. In addition, there really needs to be needs to be a hierarchy i.e. there are many sub-forms of "Rock", and indeed these need to be many-to-many because there are also fusion genres which are sub-categories of more than one parent category.

So Picard IMO really needs to provide several generalised functions...

  1. Putting downloaded genres into separate metadata variables
  2. Providing functionality to clean-up these multiple lists of genres
  3. Providing functionality to consolidate them down into a single genre list for a track.
  4. Providing a plugin category for genre downloading - various types (artist, album, track) from various sources (MB being only one possible source of genre data).

I therefore encourage the authors and reviewers of this PR to think about the above and do their best to at least try to guide this PR into a form that is in the same general direction and which will at a minimum not make delivery of comprehensive genre functionality more difficult and ideally at least takes us a step in that direction.

(See also: Lyric handling which has similar (but simpler) plugin-based requirements.)

Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

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

Thanks a lot for this PR. I initially thought we can handle it more simple inside mbjson and directly write the values for _genres and _folksonomy_tags in the metadadata object there. But your implementation of storing the list with counts is more complex but needed to run the proper filtering later on.

Also tests should be fixed.

picard/item.py Outdated Show resolved Hide resolved
picard/mbjson.py Outdated Show resolved Hide resolved
picard/track.py Outdated Show resolved Hide resolved
picard/track.py Outdated Show resolved Hide resolved
@phw
Copy link
Member

phw commented Oct 20, 2024

I therefore encourage the authors and reviewers of this PR to think about the above and do their best to at least try to guide this PR into a form that is in the same general direction and which will at a minimum not make delivery of comprehensive genre functionality more difficult and ideally at least takes us a step in that direction.

@rakim-0 @Sophist-UK We have a separate ticket PICARD-2054 for this, but this needs additional considerations. But it has no effect on this story, which is only about adding the _genres and _folksonomy_tags variables with data loaded from MB.

Genres for separate sources would be handled by the genre handling functions in item.py. Generally we have most functionality available for this, and probably we could change plugins to use MetadataItem.add_genre / MetadataItem.add_folksonomy tags feature. But for full implementation we should have genre providers similar to cover art providers that can be enabled / disabled. If we do this correctly we could also solve additional tickets, e.g. we could have providers separately for recordings, releases, artist etc. and users could choose.

It's not unlikely that if we implement this the code added here will need some refactoring as well, but that needs to be done when PICARD-2054 actually gets implemented.

@rakim0
Copy link
Contributor Author

rakim0 commented Oct 20, 2024

I'll squash the smaller commits after I fix the tests.

Check for _genres and _folksonomy_tags individually as both are filled in separately
now.
@rakim0
Copy link
Contributor Author

rakim0 commented Oct 22, 2024

Fixed tests and resolved most comments.
I'm just unsure about this one: #2545 (comment) (filtering out genres from the folksonomy tags).

@zas zas requested a review from phw November 5, 2024 19:49
picard/track.py Outdated Show resolved Hide resolved
picard/track.py Outdated Show resolved Hide resolved
phw
phw previously approved these changes Nov 12, 2024
Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the updates. This looks good to me and should work.

zas
zas previously approved these changes Nov 12, 2024
Copy link
Collaborator

@zas zas left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for your contribution.

@rdswift
Copy link
Collaborator

rdswift commented Nov 13, 2024

If you don't mind, can you please enter a ticket to update the Picard documentation to include this new variable? I suspect that the page that needs to be updated is https://github.com/metabrainz/picard-docs/blob/master/variables/variables_basic.rst

Thanks.

This function would remove the tags that are present in genre.
@rakim0 rakim0 dismissed stale reviews from zas and phw via 58286b7 November 17, 2024 10:29
picard/track.py Outdated Show resolved Hide resolved
phw
phw previously approved these changes Nov 18, 2024
Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

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

Thank you again. For me this looks great. Waiting for last review from @zas

@phw phw requested a review from zas November 18, 2024 07:11
Copy link
Collaborator

@zas zas left a comment

Choose a reason for hiding this comment

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

Declaring attributes as "protected" (prefixing them with underscore) is good, but then they aren't meant to be used outside the class, apart its subclasses.

For _genres and _folksonomy_tags, please check carefully, and use the getter method if not in the class itself or a subclass.

picard/track.py Outdated Show resolved Hide resolved
picard/track.py Outdated Show resolved Hide resolved
test/test_mbjson.py Show resolved Hide resolved
test/test_mbjson.py Show resolved Hide resolved
test/test_mbjson.py Show resolved Hide resolved
test/test_mbjson.py Outdated Show resolved Hide resolved
test/test_mbjson.py Outdated Show resolved Hide resolved
picard/track.py Outdated Show resolved Hide resolved
picard/track.py Outdated Show resolved Hide resolved
picard/track.py Outdated Show resolved Hide resolved
@Sophist-UK
Copy link
Contributor

Declaring attributes as "protected" (prefixing them with underscore) is good, but then they aren't meant to be used outside the class, apart its subclasses.

Aside from in tests, are these used outside the class?

Because I wonder whether using protected attributes in tests is actually a good thing or not. (And funny enough about 20mins before reading this I was considering exactly this question but for PHP - except in PHP protected attributes are not actually accessible outside a class except through reflection manipulation).

The reason I wonder is because the idea behind protecting them is to prevent their use in genuine application code that shouldn't have access - and tests are IMO a special case. So on the one hand, making them non-protected fits the language intent and avoids e.g. codacy flags, but then makes them available to other genuine code when they probably should be hidden - and on the other hand using protected attributes outside the class in tests may lead to issues if Python ever decides that protected really means protected.

On the whole, my personal opinion leans towards continuing to have them as protected attributes and using them outside the class only in tests - and I am wondering how to achieve this in php tests using reflection.

@zas
Copy link
Collaborator

zas commented Dec 30, 2024

@rakim0 any update on this?

@rakim0
Copy link
Contributor Author

rakim0 commented Dec 31, 2024

@zas Made the changes

Copy link
Collaborator

@zas zas left a comment

Choose a reason for hiding this comment

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

LGTM

@zas zas requested review from phw and rdswift January 1, 2025 11:22
Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the contribution and for following up on all the discussions and change requests. LGTM

@phw phw merged commit 2e1877f into metabrainz:master Jan 1, 2025
48 checks passed
@rakim0 rakim0 deleted the picard-2607 branch January 2, 2025 09:52
@phw phw mentioned this pull request Jan 8, 2025
5 tasks
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.

5 participants