110 lines
2.6 KiB
Python
110 lines
2.6 KiB
Python
from beets import ui
|
|
from beets.plugins import BeetsPlugin
|
|
from beets.ui import Subcommand, print_
|
|
from beets.ui.commands import print_and_modify
|
|
|
|
from beets.dbcore import types
|
|
from beets.dbcore import FieldQuery
|
|
|
|
import optparse
|
|
|
|
import json
|
|
|
|
def do_modify_labels(lib, objs, label, action):
|
|
changed = []
|
|
|
|
for obj in objs:
|
|
labels = {}
|
|
if action != 2:
|
|
if "mylabels" in obj:
|
|
labels = json.loads(obj["mylabels"])
|
|
|
|
split = label.split(":")
|
|
|
|
if action == 0:
|
|
if len(split) == 1:
|
|
labels[label] = 0
|
|
else:
|
|
labels[split[0]] = int(split[1])
|
|
elif label in labels:
|
|
del labels[label]
|
|
|
|
obj_mods = {
|
|
"mylabels": json.dumps(labels)
|
|
}
|
|
if print_and_modify(obj, obj_mods, []) and obj not in changed:
|
|
changed.append(obj)
|
|
|
|
# Still something to do?
|
|
if not changed:
|
|
print_("No changes to make.")
|
|
return
|
|
|
|
# Confirm action.
|
|
changed = ui.input_select_objects(
|
|
"Really modify",
|
|
changed,
|
|
lambda o: print_and_modify(o, mods, dels),
|
|
)
|
|
|
|
# Apply changes to database and files
|
|
with lib.transaction():
|
|
for obj in changed:
|
|
obj.try_sync(True, False, False)
|
|
|
|
action_map = {
|
|
"add": 0,
|
|
"remove": 1,
|
|
"removeall": 2,
|
|
"show": 3
|
|
}
|
|
|
|
def modify_labels(lib, opts, args):
|
|
action = args[0]
|
|
|
|
if action not in action_map:
|
|
print_("%s is not a valid action. " % action)
|
|
print_("Valid actions are: add, remove, removeall, show")
|
|
return
|
|
|
|
actnum = action_map[action]
|
|
|
|
if actnum >= 2:
|
|
label = None
|
|
query = args[1:]
|
|
else:
|
|
label = args[1]
|
|
query = args[2:]
|
|
|
|
items = lib.items(query=query)
|
|
|
|
if actnum == 3:
|
|
for obj in items:
|
|
print_(obj.title)
|
|
if "mylabels" in obj:
|
|
print_(" " + "; ".join(obj["mylabels"]))
|
|
else:
|
|
do_modify_labels(lib, items, label, actnum)
|
|
|
|
labels_command = Subcommand('labels', help='Add or remove labels')
|
|
labels_command.func = modify_labels
|
|
|
|
class JSONHas(FieldQuery):
|
|
@classmethod
|
|
def value_match(self, pattern, val):
|
|
if val is not None:
|
|
labels = json.loads(val)
|
|
return pattern in labels
|
|
return False
|
|
|
|
class BeetsLabelsPlugin(BeetsPlugin):
|
|
# item_queries = { 'has_label': DelimitedHasExact }
|
|
# item_types = {'mylabels': types.SEMICOLON_SPACE_DSV}
|
|
|
|
def queries(self):
|
|
return {
|
|
"JSON@" : JSONHas
|
|
}
|
|
|
|
def commands(self):
|
|
return [labels_command]
|