beets-config/plugins/playlists.py

64 lines
1.9 KiB
Python

from beets.ui import print_
from beets.dbcore import FieldQuery
from beets.dbcore.query import SlowFieldSort
from .labels import LABELS_FIELD_NAME
import json
playlist_config = {}
def initialize_playlists(playlists):
for playlist in playlists:
playlist_config[playlist["name"]] = \
playlist["query"]
class InPlaylistQuery(FieldQuery):
def __init__(self, _, pattern: str, __):
super().__init__(LABELS_FIELD_NAME, pattern, False)
@classmethod
def value_match(self, pattern, jsonstr):
if jsonstr is not None:
playlist = pattern
labels = json.loads(jsonstr)
if playlist in labels:
# This song has been explicitly added to the playlist
return True
for label in playlist_config[playlist]:
if label in labels:
return True
return False
class PlaylistValueSort(SlowFieldSort):
def __init__(self, field, ascending=True, case_insensitive=True):
super().__init__(field, ascending, case_insensitive)
self.playlist_key = field[len("playlist:"):]
def sort(self, objs):
def key(obj):
labels_json = obj.get(LABELS_FIELD_NAME, None)
if not labels_json:
# No labels, return minimum value for sorting
return float('-inf') if self.ascending else float('inf')
labels = json.loads(labels_json)
if self.playlist_key in labels:
return labels[self.playlist_key]
matching_labels = \
[label for label in labels
if label in playlist_config[self.playlist_key]]
if len(matching_labels) == 0:
return float('-inf') if self.ascending else float('inf')
return sum([labels[label] for label in matching_labels])
return sorted(objs, key=key, reverse=not self.ascending)