I am relative new to beets. I use both Musicbrainz and Discogs as a meta source.
For Plex/PlexAmp I need to use tag called releasetype
to get sorting for singles, eps, albums working.
In the beets library/database I do see in both albums and items tables contain an albumtype
and albumtypes
but a lot are empty.
So I thought to write a beets plugin that sets a releasetype
tag to all the items within an album.
I was thinking to build functionality:
- Add
releasetype
tag onbeet import
. - Add
releasetype
tag command incase you want to do it after import:beet releasetype
. - Add 'releasetype
tag command based on album name
beet releasetype -a ‘Album name’`.
Can someone tell me how write a custom tag to an item? I thought I need to use MediaFile for this but it looks like I cannot add custom tags only predefined.
Then the second question is this the right approach? Or should I use the library/database fields albumtype
and albumtypes
.
Thanks in advance.
What I have so far:
from beets.plugins import BeetsPlugin
from beets.ui import Subcommand
from mediafile import MediaFile
import inquirer
class ReleaseTypePlugin(BeetsPlugin):
def __init__(self):
super(ReleaseTypePlugin, self).__init__()
self.config.add({
'album_length_threshold': 1800, # 30 minutes in seconds
'ep_length_threshold': 1800, # 30 minutes in seconds
'single_track_limit': 3,
'ep_track_limit': 6
})
def commands(self):
cmd = Subcommand(
'releasetype', help='Assign release type')
cmd.parser.add_option(
'--album', '-a', help='Album name')
cmd.func = self.release_type
return [cmd]
def release_type(self, lib, opts, args):
if opts.album:
album_name = opts.album
album = lib.albums(album_name)[0]
if album:
release_type = self.determine_release_type(album)
self.set_release_type(album, release_type)
else:
print(f"No album found with name: {album_name}")
else:
for album in lib.albums():
release_type = self.determine_release_type(album)
self.set_release_type(album, release_type)
self._log.info('Release type set for album: %s' % album)
def determine_release_type(self, album):
album_length_treshold = self.config['album_length_threshold'].get(int)
ep_length_threshold = self.config['ep_length_threshold'].get(int)
single_track_limit = self.config['single_track_limit'].get(int)
ep_track_limit = self.config['ep_track_limit'].get(int)
total_tracks = len(album.items())
total_length = sum(item.length for item in album.items())
if total_tracks <= single_track_limit:
release_type = 'single'
elif total_tracks <= ep_track_limit and total_length <= ep_length_threshold:
release_type = 'ep'
elif total_tracks >= ep_track_limit and total_length > album_length_treshold:
release_type = 'album'
secondary_release_type = self.determine_secondary_release_type()
if secondary_release_type:
release_type = f'{release_type}; {secondary_release_type}'
else:
release_type = None
return release_type
def determine_secondary_release_type(self):
questions = [
inquirer.List(
'secondary_release_type',
message='Please select a secondary release type:',
choices=['', 'Compilation', 'Demo',
'DJ-mix', 'Live', 'Remix', 'Soundtrack']
)
]
answers = inquirer.prompt(questions)
secondary_release_type = answers.get('secondary_release_type').lower()
if secondary_release_type:
return secondary_release_type
return None
def set_release_type(self, album, release_type):
for item in album.items():
mf = MediaFile(item.path)
mf.mgfile['releasetype'] = release_type
mf.save()