Simple Classical: Picard 3 plugin for tagging classical music

I know there is Classical Extras but when I tried it, it felt very buggy and the UI is unusable in dark mode, so I made my own. Only tested on the newest beta of Picard 3.

Some of the main features:

  • Preview for all tags written
  • Presets for common players
  • Customizable hierarchy
  • Can create tags for recording date and location
  • Customizable rules for each tag

Looking for feedback or feature requests!

Screenshots:

6 Likes

This is a substantial piece of effort, so a big “Well done”!!

I want to be supportive of anyone who puts the effort into plugins like this and then share it for others to benefit, however I do have a few comments regarding its relationship to Classical Extras:

  1. I think it would be helpful to existing Classical Extras users if you could add some more information about similarities and differences in both general approach and specifics. For example, in terms of general approach, Classical Extras appears to me to be focused on creating private variables that you can then use in your own scripts for creating tags or naming files - whereas this seems to take a more direct and simpler approach to filling tags directly.

    I suspect that there is some unique functionality in Simple Classical, some functionality shared with Classical Extras and some functionality that is in Classical Extras which (perfectly reasonably) you have chosen not to duplicate - but I think it would help to have a table which covers these, and in particular covers the compatibility of common functionality.

  2. In the spirit of open source collaboration, I would personally like to see some sort of credit (even if only “inspired by”) for Classical Extras and its author Mark Evens.

  3. From a code style perspective, I have a couple of constructive and VERY optional comments:

    • You have not yet internationalised any strings - in Picard v2, plugins could not be internationalised, and there was certainly talk about enabling i18n in v3 plugins, but I am not sure whether this is available yet.
    • In v1/v2 plugins it was normal to use the QT designer to create a .ui file and then compile that into a separate .py file using PyQt. This is definitely your choice, but if you want collaboration with others on enhancements, this might be beneficial.
  4. Functionally, I am a music pologlot - I like pop/rock, jazz and classical, and I use Picard to tag each class. How easy is it to use this so it detects classical albums and ignores others?

  5. A long long time ago and (as it weirdly happens, also genuinely) in a land far far away, I wrote a v2 plugin called Abbreviate ArtistSort to solve the length problem for classical albums which often have e.g. composer, conductor and orchestra in the album artist field, and where you might have the composer as Johann Sebastian Bach which might better be listed as J.S. Bach / Bach, J.S. Is this functionality something that you might want to include in your plugin?

Anyway, keep up the good work.

4 Likes

It is, see picard/docs/PLUGINSV3/TRANSLATIONS.md at master · metabrainz/picard · GitHub

1 Like

Hey, thank you for the quick and thorough feedback.

      1. I’ve added a section about differences to Classical Extras :slight_smile:
  1. I’ve added i18n support with translations for German and Japanese (languages that I speak). Regarding the Qt Designer support, I’ll maybe consider it later. Currently some parts of the UI are automatically generated from data, which is not a good match for manual UI creation. (If someone were to make pull request, it’d consider it though.)

  2. Love the idea. I’ve added a feature to detect whether a release is classical or not. Fully customizable as well.

  3. I’m not sure how this could be included in the UI. I assume this involves custom string manipulation and heuristics? Or is this available in MB somewhere? It’s not a feature I would personally use, but if you have a way that integrates nicely with the UI and doesn’t result in garbled composers, I’m all for it.

I’ve just pushed the update, please check it out.

1 Like

The section you added to the ReadMe looks great!!

Regarding Abbreviate ArtistSort, IIRC the intention of my ancient plugin is to create a variable that can be used in a file naming script so that the sort order is preserved but the file names are shorter.

That said, I don’t think it was written in the best way:

  1. It actually uses the single-value concatenated variables as a starting point (albumartist, albumartistsort) rather than the multi-value equivalents (_albumartists, _albumartists_sort). This means that it has to do extra work to de-concatenate the strings at the right points because a “,” could be a comma in the name or a comma between different artists or a comma added to the sorted versions.

  2. The algorithm I used is a character by character algorithm and isn’t great. With hindsight it would be better to use a word by word algorithm or possibly something even simpler based on running an album/track metadata method and reparsing raw MB data instead.

This is a well-done plugin. I don’t really know about the classical specifics, but this looks like a great and modern replacement for Classical Extras. I also had a quick look over the general plugin code, and from a plugin 3 API perspective this is a well done plugin.

One suggestion is to use api.register_script_variable to register the custom tags and variables the plugin provides. This allows those variables to show up with a description in auto completes in the script or tag editor. E.g.

api.register_script_variable("ensemble", "Performing orchestra (understood by players MPD, Roon or Squeezebox)")
api.register_script_variable("_sc_depth", "Number of work levels")

Also since the last beta it is possible to regsiter config options to be available to be used in option profiles. This could be useful if users want to be able to quickly change between classical / non-classical tagging). To allow a setting to be used in profiles set the title and in_profile in the api.plugin_config.register_option call.

A bit tricky is it if you want to also allow highlighting of profile options in the option dialog. This requires setting OPTIONS on your OptionsPage subclass, which maps setting names to widget attributes in your class. For an example maybe see https://git.sr.ht/~phw/picard-plugin-theaudiodb/tree/main/item/__init__.py

3 Likes

Hey I just pushed a change that adds profile overriding and variable descriptions. Let me know what you think.

Btw, since I’m a new user, my responses need to be approved by an admin, so there might be a small delay until they show up.

1 Like

That’s actually an interesting use case. I didn’t see previously that variable names can be dynamic in this plugin. The original assumption was that a plugin would register its tags and variables once in the “enable” call. But for your case this is not sufficient.

You have solved this nicely with the tools available, but it is still a somewhat weird hack where you need to construct the module name to unregister. I think we should make it easier to allow a plugin resetting the registered variables.

Also registering the same variable multiple times from the same plugin should not result in multiple entries (the multiple entry support was implemented, because multiple plugins could potentially register the same name).

2 Likes

I would imagine that:

  • plugins adding fixed new variables at Picard startup (when no files / releases are loaded, and no web calls are in progress - so zero existing metadata)

is a far simpler use case than

  • dynamically allowing variables to be added and removed (via options UI) when metadata already exists files/releases are loaded and web calls might be in progress (or even simultaneously being converted into metadata)

What would the rules be for existing metadata if you add or remove variables?

  • Adding variables might require plugins and scripts to re-execute against a release (and in case multiple changes are happening, you wouldn’t want this to happen until all changes were finished, so how would you know when this has happened, and would you really want a significant issue like refreshing potentially hundreds or thousands of loaded releases to happen without user approval?)

  • Removing variables might require existing metadata to be deleted

Can we have a Github link please?

Changing the way variables are filled after config changes of the plugin is absolutely not different from changing scripts and a huge amount of other Picard options that apply during data loading.

There is a ticket about this, because it is not always obvious to the user, and maybe there should be some notification to the user when changing any such option. But it is a tricky issue to solve. A lot, if not most, options influence data loading in some way, and there is no straight forward way to apply this to loaded data apart from reloading everything (and doing so could overwrite manual changes).

In any case, this is not something the plugin needs to be concerned with right now.

1 Like

Unregister variable(s) and deduplication added in PICARD-3355: Allow plugins to unregister script variables by zas · Pull Request #3298 · metabrainz/picard · GitHub

I guess the easy way to handle this is that registering or unregistering a variable (or a tag variable - unclear whether hidden variables have the same problem or not) WHILST files or releases are loaded should result in some sort of warning to the user that they might need to reload their releases.

Hey, I seem to be kinda late to the discussion, but the discussed change is here.

Not sure if I implemented it correctly, but the way I solved the issue is that a loading album only ever sees the state that was valid at the time of loading. In-progress loading is unaffected if configuration changed mid-load. A reload should reflect the new tags/variables though.

1 Like