feat: some tags function

This commit is contained in:
Terry Geng 2020-03-07 16:07:58 +08:00
parent 659fab48b4
commit 749647aad2
7 changed files with 114 additions and 7 deletions

View File

@ -10,7 +10,7 @@ import util
import variables as var import variables as var
from librb import radiobrowser from librb import radiobrowser
from database import SettingsDatabase, MusicDatabase from database import SettingsDatabase, MusicDatabase
from media.playlist import get_item_wrapper, get_item_wrapper_by_id from media.playlist import get_item_wrapper, get_item_wrapper_by_id, get_item_wrappers_by_tags
from media.file import FileItem from media.file import FileItem
from media.url_from_playlist import PlaylistURLItem, get_playlist_info from media.url_from_playlist import PlaylistURLItem, get_playlist_info
from media.url import URLItem from media.url import URLItem
@ -771,6 +771,40 @@ def cmd_mode(bot, user, text, command, parameter):
bot.interrupt() bot.interrupt()
bot.launch_music() bot.launch_music()
def cmd_play_tags(bot, user, text, command, parameter):
if not parameter:
bot.send_msg(constants.strings('bad_parameter', command=command))
return
msgs = [constants.strings('multiple_file_added') + "<ul>"]
count = 0
tags = parameter.split(",")
tags = list(map(lambda t: t.strip(), tags))
music_wrappers = get_item_wrappers_by_tags(bot, tags)
for music_wrapper in music_wrappers:
count += 1
log.info("cmd: add to playlist: " + music_wrapper.format_debug_string())
msgs.append("<li><b>{}</b> (<i>{}</i>)</li>".format(music_wrapper.item().title, ", ".join(music_wrapper.item().tags)))
if count != 0:
msgs.append("</ul>")
var.playlist.extend(music_wrappers)
send_multi_lines(bot, msgs, text, "")
else:
bot.send_msg(constants.strings("no_file"), text)
def cmd_tag(bot, user, text, command, parameter):
pass
def cmd_untag(bot, user, text, command, parameter):
pass
def cmd_list_tagged(bot, user, text, command, parameter):
pass
def cmd_drop_database(bot, user, text, command, parameter): def cmd_drop_database(bot, user, text, command, parameter):
global log global log

View File

@ -161,7 +161,8 @@ class MusicDatabase:
id = music_dict['id'] id = music_dict['id']
title = music_dict['title'] title = music_dict['title']
type = music_dict['type'] type = music_dict['type']
tags = ",".join(music_dict['tags']) tags = ",".join(music_dict['tags']) + ","
del music_dict['id'] del music_dict['id']
del music_dict['title'] del music_dict['title']
del music_dict['type'] del music_dict['type']
@ -192,7 +193,7 @@ class MusicDatabase:
if isinstance(value, str): if isinstance(value, str):
condition.append(key + "=?") condition.append(key + "=?")
filler.append(value) filler.append(value)
else: elif isinstance(value, dict):
condition.append(key + " " + value[0] + " ?") condition.append(key + " " + value[0] + " ?")
filler.append(value[1]) filler.append(value[1])
@ -210,7 +211,39 @@ class MusicDatabase:
music_dict = json.loads(result[3]) music_dict = json.loads(result[3])
music_dict['type'] = result[1] music_dict['type'] = result[1]
music_dict['title'] = result[2] music_dict['title'] = result[2]
music_dict['tags'] = result[4].split(",") music_dict['tags'] = result[4].strip(",").split(",")
music_dict['id'] = result[0]
music_dicts.append(music_dict)
return music_dicts
else:
return None
def query_music_by_tags(self, tags):
condition = []
filler = []
for tag in tags:
condition.append('tags LIKE ?')
filler.append("%{:s},%".format(tag))
condition_str = " AND ".join(condition)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
"WHERE %s" % condition_str, filler).fetchall()
conn.close()
if len(results) > 0:
music_dicts = []
for result in results:
music_dict = json.loads(result[3])
music_dict['type'] = result[1]
music_dict['title'] = result[2]
music_dict['tags'] = result[4].strip(",").split(",")
music_dict['id'] = result[0] music_dict['id'] = result[0]
music_dicts.append(music_dict) music_dicts.append(music_dict)

View File

@ -74,7 +74,7 @@ class FileItem(BaseItem):
self.send_client_message(constants.strings('file_missed', file=self.path)) self.send_client_message(constants.strings('file_missed', file=self.path))
return False return False
self.version = 1 # 0 -> 1, notify the wrapper to save me when validate() is visited the first time self.version += 1 # 0 -> 1, notify the wrapper to save me when validate() is visited the first time
self.ready = "yes" self.ready = "yes"
return True return True

View File

@ -60,6 +60,16 @@ class BaseItem:
def prepare(self): def prepare(self):
return True return True
def add_tag(self, tag):
if tag not in self.tags:
self.tags.append(tag)
self.version += 1
def remove_tag(self, tag):
if tag not in self.tags:
self.tags.remove(tag)
self.version += 1
def format_song_string(self, user): def format_song_string(self, user):
return self.id return self.id

View File

@ -48,6 +48,17 @@ class MusicLibrary(dict):
self[id] = item_builders[kwargs['type']](bot, **kwargs) # newly built item will not be saved immediately self[id] = item_builders[kwargs['type']](bot, **kwargs) # newly built item will not be saved immediately
return self[id] return self[id]
def get_items_by_tags(self, bot, tags):
music_dicts = self.db.query_music_by_tags(tags)
items = []
for music_dict in music_dicts:
id = music_dicts['id']
type = music_dict['type']
self[id] = item_loaders[type](bot, music_dict)
items.append(self[id])
return items
def fetch(self, bot, id): def fetch(self, bot, id):
music_dicts = self.db.query_music(id=id) music_dicts = self.db.query_music(id=id)
if music_dicts: if music_dicts:

View File

@ -19,7 +19,7 @@ class PlaylistItemWrapper:
self.user = user self.user = user
self.type = type self.type = type
self.log = logging.getLogger("bot") self.log = logging.getLogger("bot")
self.version = 1 self.version = 0
def item(self): def item(self):
return self.lib[self.id] return self.lib[self.id]
@ -55,6 +55,18 @@ class PlaylistItemWrapper:
def uri(self): def uri(self):
return self.item().uri() return self.item().uri()
def add_tag(self, tag):
self.item().add_tag(tag)
if self.item().version > self.version:
self.version = self.item().version
self.lib.save(self.id)
def remove_tag(self, tag):
self.item().remove_tag(tag)
if self.item().version > self.version:
self.version = self.item().version
self.lib.save(self.id)
def is_ready(self): def is_ready(self):
return self.item().is_ready() return self.item().is_ready()
@ -88,6 +100,13 @@ def get_item_wrapper_by_id(bot, id, user):
else: else:
return None return None
def get_item_wrappers_by_tags(bot, tags, user):
items = var.library.get_items_by_tags(bot, tags)
ret = []
for item in items:
ret.append(PlaylistItemWrapper(var.library, item.id, item.type, user))
return ret
def get_playlist(mode, _list=None, index=None): def get_playlist(mode, _list=None, index=None):
if _list and index is None: if _list and index is None:
index = _list.current_index index = _list.current_index

View File

@ -111,7 +111,7 @@ class RadioItem(BaseItem):
self.type = "radio" self.type = "radio"
def validate(self): def validate(self):
self.version = 1 # 0 -> 1, notify the wrapper to save me when validate() is visited the first time self.version += 1 # 0 -> 1, notify the wrapper to save me when validate() is visited the first time
return True return True
def is_ready(self): def is_ready(self):