beets icon indicating copy to clipboard operation
beets copied to clipboard

Beet edit doesn't show custom tags

Open AlexChalk opened this issue 1 year ago • 0 comments

Thanks for all your work on this project.

Problem

I have a plugin that writes a custom album_sort tag to sort albums by year:

class AlbumSortPlugin(BeetsPlugin):
    def __init__(self, *args, **kwargs):
        album_sort_field = mediafile.MediaField(
            mediafile.MP3StorageStyle(u"TSOA"),
            mediafile.MP4StorageStyle(u"soal"),
            mediafile.StorageStyle(u"Album Sort")
        )
        self.add_media_field("album_sort", album_sort_field)
        self.register_listener("write", self.write)
        super().__init__(*args, **kwargs)

    def write(self, item, path, tags):
        if tags['original_year'] == 0:
            tag_year = tags['year']
        else:
            tag_year = tags['original_year']

        if not tags.get("album_sort", None):
            tags["album_sort"] = f"{tag_year} {tags['album']}"

This successfully writes the custom tags to my mp3s—they show up in e.g. mp3tag. However, when I run beet edit against the imported files, even with -f album_sort, they are not displayed.

I took a look at the docs, and beet update seemed like it would fix this, however it raised the following exception:

Traceback (most recent call last):
  File "/home/me/.local/bin/beet", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/me/.local/share/pipx/venvs/beets/lib/python3.11/site-packages/beets/ui/__init__.py", line 1865, in main
    _raw_main(args)
  File "/home/me/.local/share/pipx/venvs/beets/lib/python3.11/site-packages/beets/ui/__init__.py", line 1852, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/home/me/.local/share/pipx/venvs/beets/lib/python3.11/site-packages/beets/ui/commands.py", line 1742, in update_func
    update_items(
  File "/home/me/.local/share/pipx/venvs/beets/lib/python3.11/site-packages/beets/ui/commands.py", line 1694, in update_items
    item.store(fields=item_fields)
  File "/home/me/.local/share/pipx/venvs/beets/lib/python3.11/site-packages/beets/library.py", line 395, in store
    super().store(fields)
  File "/home/me/.local/share/pipx/venvs/beets/lib/python3.11/site-packages/beets/dbcore/db.py", line 585, in store
    tx.mutate(query, subvars)
  File "/home/me/.local/share/pipx/venvs/beets/lib/python3.11/site-packages/beets/dbcore/db.py", line 962, in mutate
    cursor = self.db._connection().execute(statement, subvals)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: no such column: album_sort

This suggests the new tag was never written to musiclibrary.db.

n.b. beet info does show the field (perhaps because it's reading the metadata directly).

Possible Solutions

Ideally, musiclibrary.db would store tags added by plugin write methods. If that's not possible

  • Plugin modification—is there something I can change that would write the tag to sqlite/help beet edit find it?
  • Reimporting the files does resolve the problem—this would be a workable solution if there is an import flag(s) that bypasses any modifications to metadata (not just -A, but also no scrub, no replaygain, no change whatsoever). Does something like this exist?

Setup

I'm running linux, beet --version output:

beets version 2.0.0
Python version 3.11.9
plugins: albumsort, badfiles, bandcamp, convert, duplicates, edit, embedart, fetchart, ftintitle, info, inline, replaygain, scrub

Thanks!

AlexChalk avatar Jun 16 '24 19:06 AlexChalk