refactor: new database format
This commit is contained in:
parent
bfa64547e8
commit
575d363de3
93
database.py
93
database.py
@ -112,10 +112,10 @@ class Condition:
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
SETTING_DB_VERSION = 1
|
||||||
|
MUSIC_DB_VERSION = 1
|
||||||
|
|
||||||
class SettingsDatabase:
|
class SettingsDatabase:
|
||||||
version = 1
|
|
||||||
|
|
||||||
def __init__(self, db_path):
|
def __init__(self, db_path):
|
||||||
self.db_path = db_path
|
self.db_path = db_path
|
||||||
|
|
||||||
@ -127,10 +127,10 @@ class SettingsDatabase:
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
def has_table(self):
|
def has_table(self, table):
|
||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
tables = cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='botamusique';").fetchall()
|
tables = cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?;", (table,)).fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
if len(tables) == 0:
|
if len(tables) == 0:
|
||||||
return False
|
return False
|
||||||
@ -140,17 +140,16 @@ class SettingsDatabase:
|
|||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
if self.has_table():
|
if self.has_table('botamusique'):
|
||||||
# check version
|
# check version
|
||||||
result = cursor.execute("SELECT value FROM botamusique WHERE section=? AND option=?",
|
ver = self.getint("bot", "db_version", fallback=None)
|
||||||
("bot", "db_version")).fetchall()
|
|
||||||
|
|
||||||
if len(result) == 0 or int(result[0][0]) != self.version:
|
if ver is None or ver != SETTING_DB_VERSION:
|
||||||
old_name = "botamusique_old_%s" % datetime.datetime.now().strftime("%Y%m%d")
|
# old_name = "botamusique_old_%s" % datetime.datetime.now().strftime("%Y%m%d")
|
||||||
cursor.execute("ALTER TABLE botamusique RENAME TO %s" % old_name)
|
# cursor.execute("ALTER TABLE botamusique RENAME TO %s" % old_name)
|
||||||
|
cursor.execute("DROP TABLE botamusique")
|
||||||
conn.commit()
|
conn.commit()
|
||||||
self.create_table()
|
self.create_table()
|
||||||
self.set("bot", "old_db_name", old_name)
|
|
||||||
else:
|
else:
|
||||||
self.create_table()
|
self.create_table()
|
||||||
|
|
||||||
@ -165,9 +164,7 @@ class SettingsDatabase:
|
|||||||
"value TEXT, "
|
"value TEXT, "
|
||||||
"UNIQUE(section, option))")
|
"UNIQUE(section, option))")
|
||||||
cursor.execute("INSERT INTO botamusique (section, option, value) "
|
cursor.execute("INSERT INTO botamusique (section, option, value) "
|
||||||
"VALUES (?, ?, ?)", ("bot", "db_version", "1"))
|
"VALUES (?, ?, ?)", ("bot", "db_version", SETTING_DB_VERSION))
|
||||||
cursor.execute("INSERT INTO botamusique (section, option, value) "
|
|
||||||
"VALUES (?, ?, ?)", ("bot", "music_db_version", "0"))
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
@ -248,20 +245,61 @@ class MusicDatabase:
|
|||||||
def __init__(self, db_path):
|
def __init__(self, db_path):
|
||||||
self.db_path = db_path
|
self.db_path = db_path
|
||||||
|
|
||||||
# connect
|
self.db_version_check_and_create()
|
||||||
|
|
||||||
|
def has_table(self, table):
|
||||||
|
conn = sqlite3.connect(self.db_path)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
tables = cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?;", (table,)).fetchall()
|
||||||
|
conn.close()
|
||||||
|
if len(tables) == 0:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def create_table(self):
|
||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
# check if table exists, or create one
|
cursor.execute("CREATE TABLE music ("
|
||||||
cursor.execute("CREATE TABLE IF NOT EXISTS music ("
|
|
||||||
"id TEXT PRIMARY KEY, "
|
"id TEXT PRIMARY KEY, "
|
||||||
"type TEXT, "
|
"type TEXT, "
|
||||||
"title TEXT, "
|
"title TEXT, "
|
||||||
|
"keywords TEXT, "
|
||||||
"metadata TEXT, "
|
"metadata TEXT, "
|
||||||
"tags TEXT)")
|
"tags TEXT, "
|
||||||
|
"path TEXT, "
|
||||||
|
"create_at DATETIME DEFAULT CURRENT_TIMESTAMP"
|
||||||
|
")")
|
||||||
|
cursor.execute("INSERT INTO music (id, title) "
|
||||||
|
"VALUES ('info', ?)", (MUSIC_DB_VERSION,))
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
def db_version_check_and_create(self):
|
||||||
|
conn = sqlite3.connect(self.db_path)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
if self.has_table('music'):
|
||||||
|
ver = cursor.execute("SELECT title FROM music WHERE id='info'").fetchone()
|
||||||
|
if ver and int(ver[0]) == MUSIC_DB_VERSION:
|
||||||
|
conn.close()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
cursor.execute("ALTER TABLE music RENAME TO music_old")
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
self.create_table()
|
||||||
|
|
||||||
|
cursor.execute("INSERT INTO music (id, type, title, metadata, tags)"
|
||||||
|
"SELECT id, type, title, metadata, tags FROM music_old")
|
||||||
|
cursor.execute("DROP TABLE music_old")
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
else:
|
||||||
|
self.create_table()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def insert_music(self, music_dict):
|
def insert_music(self, music_dict):
|
||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@ -269,19 +307,25 @@ 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']
|
||||||
|
path = music_dict['path']
|
||||||
|
keywords = music_dict['keywords']
|
||||||
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']
|
||||||
del music_dict['tags']
|
del music_dict['tags']
|
||||||
|
del music_dict['path']
|
||||||
|
del music_dict['keywords']
|
||||||
|
|
||||||
cursor.execute("INSERT OR REPLACE INTO music (id, type, title, metadata, tags) VALUES (?, ?, ?, ?, ?)",
|
cursor.execute("INSERT OR REPLACE INTO music (id, type, title, metadata, tags, path, keywords) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||||
(id,
|
(id,
|
||||||
type,
|
type,
|
||||||
title,
|
title,
|
||||||
json.dumps(music_dict),
|
json.dumps(music_dict),
|
||||||
tags))
|
tags,
|
||||||
|
path,
|
||||||
|
keywords))
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
@ -323,7 +367,7 @@ class MusicDatabase:
|
|||||||
|
|
||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
|
results = cursor.execute("SELECT id, type, title, metadata, tags, path, keywords FROM music "
|
||||||
"WHERE %s" % condition_str, filler).fetchall()
|
"WHERE %s" % condition_str, filler).fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
@ -373,8 +417,8 @@ class MusicDatabase:
|
|||||||
def query_random_music(self, count):
|
def query_random_music(self, count):
|
||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
|
results = cursor.execute("SELECT id, type, title, metadata, tags, path, keywords FROM music "
|
||||||
"WHERE id IN (SELECT id FROM music ORDER BY RANDOM() LIMIT ?)", (count,)).fetchall()
|
"WHERE id != 'info' AND id IN (SELECT id FROM music ORDER BY RANDOM() LIMIT ?)", (count,)).fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
return self._result_to_dict(results)
|
return self._result_to_dict(results)
|
||||||
@ -388,6 +432,9 @@ class MusicDatabase:
|
|||||||
music_dict['title'] = result[2]
|
music_dict['title'] = result[2]
|
||||||
music_dict['id'] = result[0]
|
music_dict['id'] = result[0]
|
||||||
music_dict['tags'] = result[4].strip(",").split(",")
|
music_dict['tags'] = result[4].strip(",").split(",")
|
||||||
|
if result[5]:
|
||||||
|
music_dict['path'] = result[5]
|
||||||
|
music_dict['keywords'] = result[6]
|
||||||
if not music_dict['tags'][0]:
|
if not music_dict['tags'][0]:
|
||||||
music_dict['tags'] = []
|
music_dict['tags'] = []
|
||||||
|
|
||||||
|
@ -51,10 +51,9 @@ class FileItem(BaseItem):
|
|||||||
if os.path.exists(self.uri()):
|
if os.path.exists(self.uri()):
|
||||||
self._get_info_from_tag()
|
self._get_info_from_tag()
|
||||||
self.ready = "yes"
|
self.ready = "yes"
|
||||||
|
self.keywords = self.title + " " + self.artist
|
||||||
else:
|
else:
|
||||||
super().__init__(bot, from_dict)
|
super().__init__(bot, from_dict)
|
||||||
self.path = from_dict['path']
|
|
||||||
self.title = from_dict['title']
|
|
||||||
self.artist = from_dict['artist']
|
self.artist = from_dict['artist']
|
||||||
self.thumbnail = from_dict['thumbnail']
|
self.thumbnail = from_dict['thumbnail']
|
||||||
if not self.validate():
|
if not self.validate():
|
||||||
@ -75,6 +74,10 @@ 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
|
||||||
|
|
||||||
|
if not self.keywords:
|
||||||
|
self.keywords = self.title + " " + self.artist # migrate from previous version
|
||||||
|
self.version += 1
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -43,6 +43,7 @@ class BaseItem:
|
|||||||
self.title = ""
|
self.title = ""
|
||||||
self.path = ""
|
self.path = ""
|
||||||
self.tags = []
|
self.tags = []
|
||||||
|
self.keywords = ""
|
||||||
self.version = 0 # if version increase, wrapper will re-save this item
|
self.version = 0 # if version increase, wrapper will re-save this item
|
||||||
|
|
||||||
if from_dict is None:
|
if from_dict is None:
|
||||||
@ -52,6 +53,9 @@ class BaseItem:
|
|||||||
self.id = from_dict['id']
|
self.id = from_dict['id']
|
||||||
self.ready = from_dict['ready']
|
self.ready = from_dict['ready']
|
||||||
self.tags = from_dict['tags']
|
self.tags = from_dict['tags']
|
||||||
|
self.title = from_dict['title']
|
||||||
|
self.path = from_dict['path']
|
||||||
|
self.keywords = from_dict['keywords']
|
||||||
|
|
||||||
def is_ready(self):
|
def is_ready(self):
|
||||||
return True if self.ready == "yes" else False
|
return True if self.ready == "yes" else False
|
||||||
@ -105,4 +109,10 @@ class BaseItem:
|
|||||||
self.bot.send_msg(msg)
|
self.bot.send_msg(msg)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {"type": self.type, "id": self.id, "ready": self.ready, "path": self.path, "tags": self.tags}
|
return {"type": self.type,
|
||||||
|
"id": self.id,
|
||||||
|
"ready": self.ready,
|
||||||
|
"title": self.title,
|
||||||
|
"path": self.path,
|
||||||
|
"tags": self.tags,
|
||||||
|
"keywords": self.keywords}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user