Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- paths:
- #regex to match all items. (avoid having to separately define compilations and singletons.)
- title::.*: "$alb_main$i_cust_catalog$alb_main_suffix/$i_main"
- album_fields:
- alb_main: |
- from titlecase import titlecase
- import beets.plugins
- pthe = beets.plugins.template_funcs()['the']
- def alb_promo_boot(albumstatus):
- # official, promo, 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 ''
- def alb_exotic_type(albumtype):
- # no special noting of albums, EPs, and soundtracks
- if albumtype in {'album', 'ep', 'soundtrack'}:
- return ''
- # special case for proper spacing and caps
- elif 'spokenword' in albumtype:
- return 'Spoken Word'
- else:
- return str.title(albumtype)
- def alb_title(album, mb_albumartistid, allowed_length=3):
- '''convert long allcaps titles to title case, while leaving other titles alone'''
- # maybe this should be refactored into a per-country blacklist?
- # Japan loves allcaps but other countries are more selective.
- allowed_allcaps_artists = ['573fd3e2-3f61-4329-a6c1-89e20620b0b9']
- if album.isupper and len(album) > allowed_length:
- if mb_albumartistid not in allowed_allcaps_artists:
- return titlecase(album)
- if len(album) < 1:
- return "[untitled]"
- return album
- def alb_artist(albumartist, items):
- # get this from beets config itself?
- va_str = "Various Artists"
- if albumartist:
- return albumartist
- else:
- # the album probably has no MBid
- # return va_str if multiple artists are found on the album
- my_artists = set()
- for item in items:
- my_artists.add(item.artist)
- if len(my_artists) > 1:
- return va_str
- # every artist is the same
- return my_artists.pop()
- def alb_orig_year(item):
- if item.original_year > 0:
- return str(item.original_year)
- if item.year > 0:
- return str(item.year)
- else:
- return ''
- def alb_main():
- # the output string
- out = ''
- myartist = alb_artist(albumartist, items)
- if myartist:
- out += pthe(myartist)
- else:
- out += "No Artist"
- out += " - "
- if alb_promo_boot(albumstatus):
- out += alb_promo_boot(albumstatus)
- if alb_exotic_type(albumtype):
- # example: Promo, Spoken Word
- out += ", "
- else:
- out += " - "
- if alb_exotic_type(albumtype):
- out += alb_exotic_type(albumtype) + " - "
- # just grab the first item since original_year is
- # apparently an item level field???? need to verify
- out += alb_orig_year(items[0]) + " - "
- out += alb_title(album, mb_albumartistid)
- # % aunique{
- # album alb_orig_year_mm_dd albumartist albumstatus albumtype,
- # albumdisambig country label catalognum,
- # ()
- # }
- return out
- return alb_main()
- alb_main_suffix: |
- from random import seed, sample
- def alb_sample_tracks(tracks):
- # reproducible randomness for debugging. should be excluded for optimal randomness from album to album.
- # otherwise, any album with same number of tracks will get same sample of track numbers, I think
- seed(25)
- num_items = len(tracks)
- tracks_to_check = 10
- sample_size = min(tracks_to_check, num_items)
- test_tracks = sample(tracks, sample_size)
- return(test_tracks)
- def alb_subset_bitrate(items, min_kbps=150):
- '''get bitrate information for albums <150kbps.
- do nothing for higher-bitrate albums, because
- they are assumed to be perceptually lossless.'''
- # Should probably have some logic for surround sound (>2 channels),
- # but if you're dealing with audibly lossy surround tracks,
- # something has gone wrong in your life.
- test_tracks = alb_sample_tracks(items)
- sample_size = len(test_tracks)
- total_bitrate = 0
- for item in test_tracks:
- total_bitrate += item.bitrate
- album_br_bits_ps = total_bitrate / sample_size
- # music bitrates are base 10:
- # https://hydrogenaud.io/index.php/topic,12633.0.html
- album_br_kbps = album_br_bits_ps / 1000
- if album_br_kbps >= min_kbps:
- out_text = ''
- else:
- # return Opus, MP3, "Mixed", etc.
- # uses same test_tracks from earlier sample
- alb_format = set()
- for item in test_tracks[0:sample_size]:
- alb_format.add(item.format)
- if len(alb_format) != 1:
- alb_format = 'Mixed'
- else:
- alb_format = alb_format.pop()
- out_text = str(int(album_br_kbps)) + 'kbps ' + str(alb_format)
- return out_text
- def alb_main_suffix():
- out = ''
- mybitrate = alb_subset_bitrate(items)
- if mybitrate:
- out += "[" + alb_subset_bitrate + "]"
- return out
- return alb_main_suffix()
- item_fields:
- i_cust_catalog: |
- def i_reissue_year(year, original_year):
- if year > original_year:
- if original_year > 0:
- return str(year)
- return ''
- def i_cust_media(media):
- # see https://musicbrainz.org/doc/Release/Format
- # omit uninteresting formats
- # these formats are bit-identical to CD
- snake_oil_formats = ['Blu-spec CD', 'SHM-CD', 'HQCD']
- media_types_to_omit = snake_oil_formats + \
- ['CD', 'CD-R', 'Enhanced CD', 'CDDA', 'Digital Media', '']
- if media in media_types_to_omit:
- return ''
- # combine hybrid SACD with SACD, see https://en.wikipedia.org/wiki/Super_Audio_CD#Technology
- elif 'SACD' in media:
- return 'SACD'
- # combine all vinyl types into "Vinyl"
- elif 'Vinyl' in media:
- # https://en.wikipedia.org/wiki/VinylDisc
- if media == 'VinylDisc':
- # assume it's a CD
- return ''
- return 'Vinyl'
- elif "USB" in media:
- return 'USB'
- elif media == 'HD-DVD':
- return 'HD-DVD'
- elif 'DVD' in media or media == "DualDisc":
- return 'DVD'
- else:
- return media
- parsed_media = i_cust_media(media)
- result = i_reissue_year(year, original_year)
- # condition = custom attribute to note vinyl skips
- # and other noticable artifacts.
- result += ' ' + parsed_media # + i_condition()
- result = result.strip(' ')
- if result != '':
- return ' (' + result + ')'
- return result
- i_main: |
- def i_track(track):
- # untested
- if not track:
- return None
- # hotfix for beets' hardcoded 2-digit track numbers
- # https://github.com/beetbox/beets/issues/3352
- str_track = str(track)
- # pad based on length of highest track number (per disc).
- # may interact with per_disc_numbering, not sure
- length = len(str(tracktotal))
- if length < 2:
- length = 2
- return str_track.zfill(length)
- def i_disc_layer(disc, disctotal):
- # do nothing for single-disc releases
- if disctotal > 1:
- # todo should this be 'is not None'?
- if disc != '':
- str_disc = str(disc)
- # pad based on length of highest disc number.
- # ex. if total discs = 2 digits, pad 1 zero for discs 1-9 (01-09)
- legth_to_pad_to = len(str(disctotal))
- return str_disc.zfill(legth_to_pad_to)
- return ''
- def i_main():
- out = ''
- disc_layer = i_disc_layer(disc, disctotal)
- if disc_layer:
- # no space
- out += disc_layer + "-"
- mytrack = i_track(track)
- if mytrack:
- out += mytrack
- else:
- out += "[no track number]"
- out += ". "
- if title:
- out += str(title)
- else:
- out += '[unknown]'
- return out
- return i_main()
Advertisement
Add Comment
Please, Sign In to add comment