64 lines
1.9 KiB
Python
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)
|