refactor: database logic, add type hints

This commit is contained in:
Terry Geng 2020-03-22 14:25:09 +08:00
parent 22e705a469
commit 3fb10905b7
6 changed files with 72 additions and 19 deletions

View File

@ -97,6 +97,7 @@ song_shortlist = []
def cmd_joinme(bot, user, text, command, parameter):
global log
print(bot.mumble.users[text.actor]['channel_id'])
bot.mumble.users.myself.move_in(
bot.mumble.users[text.actor]['channel_id'], token=parameter)

View File

@ -27,6 +27,8 @@ class Condition:
if self._order_by:
sql += f" ORDEY BY {self._order_by}"
print(sql)
print(self.filler)
return sql
def or_equal(self, column, equals_to, case_sensitive=True):
@ -94,6 +96,15 @@ class Condition:
return self
def or_not_sub_condition(self, sub_condition):
self.filler.extend(sub_condition.filler)
if self._sql:
self._sql += f"OR NOT ({sub_condition.sql()})"
else:
self._sql += f"NOT ({sub_condition.sql()})"
return self
def and_sub_condition(self, sub_condition):
self.filler.extend(sub_condition.filler)
if self._sql:
@ -103,6 +114,15 @@ class Condition:
return self
def and_not_sub_condition(self, sub_condition):
self.filler.extend(sub_condition.filler)
if self._sql:
self._sql += f"AND NOT({sub_condition.sql()})"
else:
self._sql += f"NOT ({sub_condition.sql()})"
return self
def limit(self, limit):
self._limit = limit
@ -323,14 +343,27 @@ class MusicDatabase:
del music_dict['path']
del music_dict['keywords']
cursor.execute("INSERT OR REPLACE INTO music (id, type, title, metadata, tags, path, keywords) VALUES (?, ?, ?, ?, ?, ?, ?)",
(id,
type,
title,
json.dumps(music_dict),
tags,
path,
keywords))
existed = cursor.execute("SELECT TRUE FROM music WHERE id=?", (id,)).fetchall()
if len(existed) == 0:
cursor.execute(
"INSERT INTO music (id, type, title, metadata, tags, path, keywords) VALUES (?, ?, ?, ?, ?, ?, ?)",
(id,
type,
title,
json.dumps(music_dict),
tags,
path,
keywords))
else:
cursor.execute("UPDATE music SET type=:type, title=:title, metadata=:metadata, tags=:tags, "
"path=:path, keywords=:keywords WHERE id=:id",
{'id': id,
'type': type,
'title': title,
'metadata': json.dumps(music_dict),
'tags': tags,
'path': path,
'keywords': keywords})
if not _conn:
conn.commit()
@ -423,7 +456,7 @@ class MusicDatabase:
conn.commit()
conn.close()
def query_tags(self, condition):
def query_tags(self, condition: Condition):
# TODO: Can we keep a index of tags?
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
@ -441,11 +474,17 @@ class MusicDatabase:
return lookup
def query_random_music(self, count):
def query_random_music(self, count, condition: Condition = None):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
results = []
if condition is None:
condition = Condition().and_not_sub_condition(Condition().and_equal('id', 'info'))
results = cursor.execute("SELECT id, type, title, metadata, tags, path, keywords FROM music "
"WHERE id IN (SELECT id FROM music WHERE id != 'info' ORDER BY RANDOM() LIMIT ?)", (count,)).fetchall()
"WHERE id IN (SELECT id FROM music WHERE %s ORDER BY RANDOM() LIMIT ?) ORDER BY RANDOM()"
% condition.sql(), condition.filler + [count]).fetchall()
conn.close()
return self._result_to_dict(results)

View File

@ -399,7 +399,8 @@ def build_library_query_condition(form):
tags = form['tags'].split(",")
for tag in tags:
condition.and_like("tags", f"%{tag},%", case_sensitive=False)
if tag:
condition.and_like("tags", f"%{tag},%", case_sensitive=False)
_keywords = form['keywords'].split(" ")
keywords = []

View File

@ -6,6 +6,7 @@ import time
import variables as var
from media.cache import CachedItemWrapper, get_cached_wrapper_from_dict, get_cached_wrapper_by_id
from database import Condition
def get_playlist(mode, _list=None, index=None):
@ -361,7 +362,10 @@ class AutoPlaylist(OneshotPlaylist):
self.mode = "autoplay"
def refresh(self):
dicts = var.music_db.query_random_music(var.config.getint("bot", "autoplay_length", fallback=5))
dicts = var.music_db.query_random_music(var.config.getint("bot", "autoplay_length", fallback=5),
Condition().and_not_sub_condition(
Condition().and_like('tags', "%don't autoplay,%")))
if dicts:
_list = [get_cached_wrapper_from_dict(var.bot, _dict, "AutoPlay") for _dict in dicts]
self.from_list(_list, -1)

View File

@ -134,7 +134,7 @@
<div id="filter-path" class="form-group row">
<label class="col-sm-2 col-form-label" for="filter-dir" style="max-width: none">Directory</label>
<div class="col-sm-8">
<select class="form-control form-control-sm" id="filter-dir" style="margin-top:5px;">
<select class="form-control form-control-sm" id="filter-dir" style="margin-top:5px;" disabled>
<option value="">.</option>
{% for dir in music_library.get_subdirs_recursively() %}
<option value="{{ dir }}">{{ dir }}</option>

View File

@ -1,14 +1,22 @@
bot = None
playlist = None
cache = None
from typing import Type, TYPE_CHECKING
if TYPE_CHECKING:
import mumbleBot
import media.playlist
import media.cache
import database
bot: 'mumbleBot.MumbleBot' = None
playlist: Type['media.playlist.BasePlaylist'] = None
cache: 'media.cache.MusicCache' = None
user = ""
is_proxified = False
dbfile = None
db = None
music_db = None
config = None
music_db: 'database.MusicDatabase' = None
config: 'database.SettingsDatabase' = None
bot_logger = None