beetbox / beets

music library manager and MusicBrainz tagger
http://beets.io/
MIT License
12.92k stars 1.82k forks source link

$track numbering loses it's zero padding if inside an if statement #3709

Closed HackingPheasant closed 4 years ago

HackingPheasant commented 4 years ago

Problem

$track numbering loses it's zero padding if inside an if statement


With a default path set as following (Padding as expected):

default: Music/%upper{%left{$albumartist_sort,1}}/$albumartist/%if{$hasyear,($year)} $album%aunique{} $alb_type$alb_status$media_type/%if{$multidisc,Disc $disc/}$track. $title

My tack listings are zero padded and look like the following screenshot Screenshot from 2020-08-01 14-55-21

When I have it inside an if statement (Padding fails):

default: Music/%upper{%left{$albumartist_sort,1}}/$albumartist/%if{$hasyear,($year)} $album%aunique{} $alb_type$alb_status$media_type/%if{$multidisc,Disc $disc/}%if{alt_tracks,$track_alt,$track}. $title

My track listings are not zero padded and look like the following screenshot Screenshot from 2020-08-01 14-56-42


Switching from %if{alt_tracks,$track_alt,$track}. $title to $track. $title:

$ beets -vv move
user configuration: /home/matt/.config/beets/config.yaml
data directory: /home/matt/.config/beets
plugin paths: 
Sending event: pluginload
inline: adding item field alt_tracks
inline: adding album field alb_status
inline: adding album field alb_type
inline: adding album field media_type
inline: adding album field hasyear
inline: adding album field multidisc
library database: /home/matt/Audio/.musiclibrary.db
library directory: /home/matt/Audio
Sending event: library_opened
Moving 0 items (36 already in place).
Sending event: cli_exit
matt@thonkpad ~/.steam/root/steamapps/music $ beets -vv move
user configuration: /home/matt/.config/beets/config.yaml
data directory: /home/matt/.config/beets
plugin paths: 
Sending event: pluginload
inline: adding item field alt_tracks
inline: adding album field alb_status
inline: adding album field alb_type
inline: adding album field media_type
inline: adding album field hasyear
inline: adding album field multidisc
library database: /home/matt/Audio/.musiclibrary.db
library directory: /home/matt/Audio
Sending event: library_opened
Moving 9 items (27 already in place).
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/1. Hip Hop Bee Bop (Don't Stop).flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/2. In the Beginning.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/3. Man Made.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/4. Together Again.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/5. Hip Hop Bee Bop (Don't Stop), Part 2.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/6. Six Simple Synthesizers.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/7. Techno Trax.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/8. Street Clap.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/9. Heatstroke.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
Sending event: cli_exit
extrafiles: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop -> /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop (Hip Hop Bee Bop by Man Parrish, 9 tracks)

Switching from $track. $title back to %if{alt_tracks,$track_alt,$track}. $title (Aka reverting my config change):

$ beets -vv move
user configuration: /home/matt/.config/beets/config.yaml
data directory: /home/matt/.config/beets
plugin paths: 
Sending event: pluginload
inline: adding item field alt_tracks
inline: adding album field alb_status
inline: adding album field alb_type
inline: adding album field media_type
inline: adding album field hasyear
inline: adding album field multidisc
library database: /home/matt/Audio/.musiclibrary.dblibrary directory: /home/matt/Audio
Sending event: library_opened
Moving 9 items (27 already in place).
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/01. Hip Hop Bee Bop (Don't Stop).flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/02. In the Beginning.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/03. Man Made.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/04. Together Again.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/05. Hip Hop Bee Bop (Don't Stop), Part 2.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/06. Six Simple Synthesizers.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/07. Techno Trax.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/08. Street Clap.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
moving: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop/09. Heatstroke.flac
Sending event: before_item_moved
Sending event: item_moved
Sending event: database_change
Sending event: database_change
Sending event: cli_exit
extrafiles: /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop -> /home/matt/Audio/Music/P/Man Parrish/(1993) Hip Hop Bee Bop (Hip Hop Bee Bop by Man Parrish, 9 tracks)

Setup

My configuration is:

## Beets Configuration file.
## ~./config/beets/config.yaml

# Define directorty for music and beets db
library: ~/Audio/.musiclibrary.db
directory: ~/Audio/

# Load plugins to extended beets (both internal and 3rd party)
plugins:
    # Autotagger Extensions
    - fromfilename
    # Metadata Plugins
    - edit
    - fetchart
    - embedart
    - ftintitle
    - lastgenre
    - mbsync
    # Path Format Plugins
    - inline
    # Interoperability
    - badfiles
    - play
    # Miscellaneous Plugins
    - audit
    - convert
    - duplicates
    - export
    - fuzzy
    - info
    - missing
    - random
    - web
    # Other/External Plugins
    - extrafiles 

# Program configuration
threaded: yes

ui:
    color: yes

import:
    write: yes
    copy: yes
    move: no
    resume: ask
    incremental: yes
    quiet_fallback: skip
    log: ~/Audio/.beet.log
    bell: yes
    languages: en jp de 

per_disc_numbering: true

aunique:
    # Drop some disambiguation fallbacks
    disambuguators: media mastering label catalognum albumdisambig releasegroupdisambig

match:
    preferred:
        media: ['Vinyl', 'CD', 'Digital Media|File']

# Done in order listed. Default is special and will always go at the end.
# e.g. If I had an album with the albumtype $soundtrack and $compilation
# Then the path that matchs first takes precedence.
paths: 
    # Beets inbuilt paths
    default: Music/%upper{%left{$albumartist_sort,1}}/$albumartist/%if{$hasyear,($year)} $album%aunique{} $alb_type$alb_status$media_type/%if{$multidisc,Disc $disc/}%if{alt_tracks,$track_alt,$track}. $title
    comp: Music/Various Artists/$album%aunique{} %if{$hasyear,($year)} $alb_type$alb_status$media_type/%if{$multidisc,Disc $disc/}%if{alt_tracks,$track_alt,$track}. $title
    singleton: Music/Individual Songs/$artist - $title
    # Beets extra/other album types
    albumtype:soundtrack: Music/Original Sound Tracks (OST)/$album%aunique{} %if{$hasyear,($year)} $alb_type$alb_status$media_type/%if{$multidisc,Disc $disc/}%if{alt_tracks,$track_alt,$track}. $title
    albumtype:audiobook: Audiobooks/$albumartist/$album%aunique{} %if{$hasyear,($year)} $media_type/%if{$multidisc,Disc $disc/}%if{alt_tracks,$track_alt,$track}. $title
    albumtype:other: Other/%upperi{%left{$albumartist_sort,1}}/$albumartist/%if{$hasyear,($year)} $album%aunique{} $alb_type$alb_status$media_type/%if{$multidisc,Disc $disc/}%if{alt_tracks,$track_alt,$track}. $title

# Inline replacements used in path formatting
#
# Note: You may need to add a 'u' in-front of text to signify unicode in python 2
# Unicode is default in python 3 so its not needed
# TODO:
# - Note if Reissue/Remaster
# - Check Beets Padding issue for tracks and multidisc releases https://github.com/beetbox/beets/issues/3352
# - Borrow ideas from this config https://gist.github.com/RollingStar/86e041338df295afbbf77a9027903068
# - Split Anime/Game genre soundtracks out of the OST path using genre:game etc
# - Classic genre which is sorted by composer

album_fields:
    alb_status: |
        # MB returns 4 values describing how "offical" a release is, they are:
        # Official, Promotional, Bootleg, and Pseudo-Release
        # We only note the middle two.
        # https://musicbrainz.org/doc/Release#Status
        if 'Promo' in albumstatus:
            return '[Promo]'
        elif 'Bootleg' in albumstatus:
            return '[Bootleg]'
        else:
            return None
    # Check if https://github.com/beetbox/beets/issues/2200 affects below
    alb_type: |
        alb_types = None
        albumtypes_list = {
            'ep': 'EP',
            'single': 'Single',
            'live': 'Live',
            'remix': 'Remix',
            'dj-mix': 'DJ-mix',
            'mixtape/street': 'Mixtape⧸Street',
        }
        for key, value in albumtypes_list.items():
            if albumtype == key:
                alb_types += "[" + str(value) + "]"
        if alb_types is not None:
            return alb_types.strip()
        else:
            return None

    media_type: |
        # https://musicbrainz.org/doc/Release/Format
        # Lets Merge the variations of the same medium into the main medium name (Opinonated)
        media_list = {
            '12" Vinyl': 'Vinyl',
            '10" Vinyl': 'Vinyl',
            '7" Vinyl': 'Vinyl',
            'Cassette': 'Cassette',
            'Digital Media': 'Digital Release',
        }
        # Lets omit these instead of converging them under a similar label like above (Opinonated)
        media_types_to_omit = ['CD', 'CD-R', 'Enhanced CD', 'CDDA', 'Blu-spec CD', 'SHM-CD', 'HQCD', '']
        if items[0].media in media_list:
            return "[" + str(media_list[items[0].media]) + "]"
        elif items[0].media in media_types_to_omit:
            return None
        else:
            return "[" + str(items[0].media) + "]"

    hasyear: 1 if year > 0 else 0
    multidisc: 1 if disctotal > 1 else 0

item_fields:
    alt_tracks: 1 if media in ['12" Vinyl', '10" Vinyl', '7" Vinyl', 'Vinyl', 'Cassette'] else 0

# Plugin and Misc Configurations

# Beets will remove empty directory after import if these are the only things left in it
# Currently isn't used in here by default, this is because we copy instead of move files
clutter: ["Thumbs.DB", ".DS_Store", "*.m3u", "*.m3u8", "*.sfv"]

fetchart:
    store_source: yes

embedart:
    # No auto-embedded album art
    auto: no

convert:
    # auto: yes
    copy_album_art: yes
    album_art_maxwidth: 1080
    dest: ~/Audio/Music [Mobile version]/
    embed: yes
    never_convert_lossy_files: yes
    format: mp3
    formats:
        mp3:
            command: ~/.scripts/flac-to-mp3.sh $source $dest
            extension: mp3
        opus:
            command: ffmpeg -i $source -y -vn -acodec libopus -ab 128k $dest
            extension: opus
            # extension opus.ogg
            # Above is to work around android media scanner, opus is included 
            # in the file extension for making it easier on me in the future
            # when android media scanner picks up opus extensions properly

extrafiles:
    patterns:
        artworkdir: 
          - '[aA]rtwork/'
        scansdir:
          - '[sS]cans/'
        logncue:
          - '*.cue'
          - '*.log'
          - '*.accurip'
          - '*.txt'
    paths:
        artworkdir: $albumpath/Artwork
        scansdir: $albumpath/Scans
        logncue: $albumpath/$filename

lastgenre:
    count: 5

play:
    command: /usr/bin/mpv

Looking at a comment in issue 3352, it mentions that beets zero pads the track automatically (to 2 digits at least), which leads me to believe that this is missed if you go down a different code path then what is considered "default"

sampsyo commented 4 years ago

Hi! I think perhaps a simpler explanation here is that $track_alt is unpadded—so it's not actually the %if doing this, but that $track has the padding applied but $track_alt is just a "normal field" (a flexible attribute, in fact) and doesn't get automatically padded.

$track_alt was added in #2363, and as the thread implies, it's not always a number—hence the lack of padding by default.

Some ways to add padding might include the inline plugin or extending the types plugin to allow use of the PaddedInt type.

HackingPheasant commented 4 years ago

But the $track_alt option isn't used in the files in the screenshot its $track that gets used.

$track_alt is only used in my config if the album is Vinyl or Cassette. Which have thier numbering as A1, A2 and so on (on MusicBrainz), so I don't expect that to be padded.

~~So to double check everything is correct on my end, %if{alt_tracks,$track_alt,$track} is in reality is %if{condition,truetext,falsetext} according to docs~~

My condition used above is

item_fields:
    alt_tracks: 1 if media in ['12" Vinyl', '10" Vinyl', '7" Vinyl', 'Vinyl', 'Cassette'] else 0

Which should only trigger $track_alt on Vinyl and Cassettes and $track on everything else, correct? As the two albums I had tested (created a new library for testing my config changes) where a digital release and a CD, which shouldn't trigger the above.

Is there any way I get more detailed info for use in this info?

EDIT: Let me try replacing $track-alt with track to try and eliminate one option, will up-date this comment with the results

EDIT 2: Ignore the above, items seems @sampsyo was on point that $track_alt was getting used. Now to check why 1 if media in ['12" Vinyl', '10" Vinyl', '7" Vinyl', 'Vinyl', 'Cassette'] else 0 doesn't work anymore as it use to work in my past versions of my beets config. It's probably safe to close this issue as its basically user error

EDIT 3: Main difference between current config and past configs is the use of the album_fields as well as item_fields, in the past I have exclusively used item_fields, could this have any affect on my results/outcome?

sampsyo commented 4 years ago

A good way to debug these things is to use beet ls -f to try out various combinations. Like this:

beet ls -f '$track_alt - $album'
beet ls -f '$media $alt_tracks - $album'

I don't see anything obviously wrong with that definition, but maybe checking that all the values hold what you think they hold would be useful.

HackingPheasant commented 4 years ago
$ beet ls -f '$track_alt - $album'
1 - Celeste Original Soundtrack
2 - Celeste Original Soundtrack
3 - Celeste Original Soundtrack
4 - Celeste Original Soundtrack
5 - Celeste Original Soundtrack
6 - Celeste Original Soundtrack
7 - Celeste Original Soundtrack
8 - Celeste Original Soundtrack
9 - Celeste Original Soundtrack
10 - Celeste Original Soundtrack
11 - Celeste Original Soundtrack
12 - Celeste Original Soundtrack
13 - Celeste Original Soundtrack
14 - Celeste Original Soundtrack
15 - Celeste Original Soundtrack
16 - Celeste Original Soundtrack
17 - Celeste Original Soundtrack
18 - Celeste Original Soundtrack
19 - Celeste Original Soundtrack
20 - Celeste Original Soundtrack
21 - Celeste Original Soundtrack

And if I was to run above with $track it shows padding as intended.

$ beet ls -f '$media $alt_tracks - $album'
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack
Digital Media 0 - Celeste Original Soundtrack

The media doesn't fit the true condition for $alt_tracks so why does the true text condition still take precedence?

sampsyo commented 4 years ago

You can keep debugging that too!! Try using the %if expression and other variants in beet ls -f to try to understand what's going on.

HackingPheasant commented 4 years ago

I was missing $ in front of the alt_tracks, so the if condition never had anything to check and automatically defaulted to the first value.

Closing because of user error. A nice potential feature can be that beet could complain that an %if condition doesn't actually check anything