feat: 'search' command to search the db, and 'shortlist' to add songs from search result

This commit is contained in:
Terry Geng
2020-03-08 16:56:31 +08:00
parent 45b83af4ba
commit f7042db657
10 changed files with 226 additions and 73 deletions

View File

@ -3,13 +3,13 @@ from database import MusicDatabase
import json
import threading
from media.item import item_builders, item_loaders, item_id_generators
from media.item import item_builders, item_loaders, item_id_generators, dict_to_item, dicts_to_items
from database import MusicDatabase
import variables as var
import util
class MusicLibrary(dict):
class MusicCache(dict):
def __init__(self, db: MusicDatabase):
super().__init__()
self.db = db
@ -36,7 +36,11 @@ class MusicLibrary(dict):
def get_item(self, bot, **kwargs):
# kwargs should provide type and id, and parameters to build the item if not existed in the library.
# if cached
id = item_id_generators[kwargs['type']](**kwargs)
if 'id' in kwargs:
id = kwargs['id']
else:
id = item_id_generators[kwargs['type']](**kwargs)
if id in self:
return self[id]
@ -57,8 +61,7 @@ class MusicLibrary(dict):
if music_dicts:
for music_dict in music_dicts:
id = music_dict['id']
type = music_dict['type']
self[id] = item_loaders[type](bot, music_dict)
self[id] = dict_to_item(bot, music_dict)
items.append(self[id])
return items
@ -67,8 +70,7 @@ class MusicLibrary(dict):
music_dicts = self.db.query_music(id=id)
if music_dicts:
music_dict = music_dicts[0]
type = music_dict['type']
self[id] = item_loaders[type](bot, music_dict)
self[id] = dict_to_item(bot, music_dict)
return self[id]
else:
return None

View File

@ -154,7 +154,7 @@ class FileItem(BaseItem):
def format_song_string(self, user):
return constants.strings("file_item",
title=self.title,
artist=self.artist,
artist=self.artist if self.artist else '??',
user=user
)

View File

@ -28,6 +28,18 @@ item_builders['base'] = example_builder
item_loaders['base'] = example_loader
item_id_generators['base'] = example_id_generator
def dicts_to_items(bot, music_dicts):
items = []
for music_dict in music_dicts:
type = music_dict['type']
items.append(item_loaders[type](bot, music_dict))
return items
def dict_to_item(bot, music_dict):
type = music_dict['type']
return item_loaders[type](bot, music_dict)
class BaseItem:
def __init__(self, bot, from_dict=None):
self.bot = bot

View File

@ -10,7 +10,7 @@ from media.url import URLItem
from media.url_from_playlist import PlaylistURLItem
from media.radio import RadioItem
from database import MusicDatabase
from media.library import MusicLibrary
from media.cache import MusicCache
class PlaylistItemWrapper:
def __init__(self, lib, id, type, user):
@ -95,24 +95,25 @@ class PlaylistItemWrapper:
return self.item().display_type()
# Remember!!! Using these three get wrapper functions will automatically add items into the cache!
def get_item_wrapper(bot, **kwargs):
item = var.library.get_item(bot, **kwargs)
item = var.cache.get_item(bot, **kwargs)
if 'user' not in kwargs:
raise KeyError("Which user added this song?")
return PlaylistItemWrapper(var.library, item.id, kwargs['type'], kwargs['user'])
return PlaylistItemWrapper(var.cache, item.id, kwargs['type'], kwargs['user'])
def get_item_wrapper_by_id(bot, id, user):
item = var.library.get_item_by_id(bot, id)
item = var.cache.get_item_by_id(bot, id)
if item:
return PlaylistItemWrapper(var.library, item.id, item.type, user)
return PlaylistItemWrapper(var.cache, item.id, item.type, user)
else:
return None
def get_item_wrappers_by_tags(bot, tags, user):
items = var.library.get_items_by_tags(bot, tags)
items = var.cache.get_items_by_tags(bot, tags)
ret = []
for item in items:
ret.append(PlaylistItemWrapper(var.library, item.id, item.type, user))
ret.append(PlaylistItemWrapper(var.cache, item.id, item.type, user))
return ret
def get_playlist(mode, _list=None, index=None):
@ -235,7 +236,7 @@ class BasePlaylist(list):
counter += 1
if counter == 0:
var.library.free(removed.id)
var.cache.free(removed.id)
return removed
def remove_by_id(self, id):
@ -280,7 +281,7 @@ class BasePlaylist(list):
def clear(self):
self.version += 1
self.current_index = -1
var.library.free_all()
var.cache.free_all()
super().clear()
def save(self):
@ -330,7 +331,7 @@ class BasePlaylist(list):
self.log.debug("playlist: validating %s" % item.format_debug_string())
if not item.validate() or item.is_failed():
self.log.debug("playlist: validating failed.")
var.library.delete(item.id)
var.cache.delete(item.id)
self.remove_by_id(item.id)
self.log.debug("playlist: validating finished.")