6 class DatabaseError(Exception):
10 class SettingsDatabase:
13 def __init__(self, db_path):
14 self.db_path = db_path
17 conn = sqlite3.connect(self.db_path)
18 cursor = conn.cursor()
20 self.db_version_check_and_create()
26 conn = sqlite3.connect(self.db_path)
27 cursor = conn.cursor()
28 tables = cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='botamusique';").fetchall()
34 def db_version_check_and_create(self):
35 conn = sqlite3.connect(self.db_path)
36 cursor = conn.cursor()
40 result = cursor.execute("SELECT value FROM botamusique WHERE section=? AND option=?",
41 ("bot", "db_version")).fetchall()
43 if len(result) == 0 or int(result[0][0]) != self.version:
44 old_name = "botamusique_old_%s" % datetime.datetime.now().strftime("%Y%m%d")
45 cursor.execute("ALTER TABLE botamusique RENAME TO %s" % old_name)
48 self.set("bot", "old_db_name", old_name)
54 def create_table(self):
55 conn = sqlite3.connect(self.db_path)
56 cursor = conn.cursor()
57 cursor.execute("CREATE TABLE IF NOT EXISTS botamusique ("
61 "UNIQUE(section, option))")
62 cursor.execute("INSERT INTO botamusique (section, option, value) "
63 "VALUES (?, ?, ?)", ("bot", "db_version", "1"))
64 cursor.execute("INSERT INTO botamusique (section, option, value) "
65 "VALUES (?, ?, ?)", ("bot", "music_db_version", "0"))
69 def get(self, section, option, **kwargs):
70 conn = sqlite3.connect(self.db_path)
71 cursor = conn.cursor()
72 result = cursor.execute("SELECT value FROM botamusique WHERE section=? AND option=?", (section, option)).fetchall()
78 if 'fallback' in kwargs:
79 return kwargs['fallback']
81 raise DatabaseError("Item not found")
83 def getboolean(self, section, option, **kwargs):
84 return bool(int(self.get(section, option, **kwargs)))
86 def getfloat(self, section, option, **kwargs):
87 return float(self.get(section, option, **kwargs))
89 def getint(self, section, option, **kwargs):
90 return int(self.get(section, option, **kwargs))
92 def set(self, section, option, value):
93 conn = sqlite3.connect(self.db_path)
94 cursor = conn.cursor()
95 cursor.execute("INSERT OR REPLACE INTO botamusique (section, option, value) "
96 "VALUES (?, ?, ?)", (section, option, value))
100 def has_option(self, section, option):
101 conn = sqlite3.connect(self.db_path)
102 cursor = conn.cursor()
103 result = cursor.execute("SELECT value FROM botamusique WHERE section=? AND option=?", (section, option)).fetchall()
110 def remove_option(self, section, option):
111 conn = sqlite3.connect(self.db_path)
112 cursor = conn.cursor()
113 cursor.execute("DELETE FROM botamusique WHERE section=? AND option=?", (section, option))
117 def remove_section(self, section):
118 conn = sqlite3.connect(self.db_path)
119 cursor = conn.cursor()
120 cursor.execute("DELETE FROM botamusique WHERE section=?", (section, ))
124 def items(self, section):
125 conn = sqlite3.connect(self.db_path)
126 cursor = conn.cursor()
127 results = cursor.execute("SELECT option, value FROM botamusique WHERE section=?", (section, )).fetchall()
131 return list(map(lambda v: (v[0], v[1]), results))
135 def drop_table(self):
136 conn = sqlite3.connect(self.db_path)
137 cursor = conn.cursor()
138 cursor.execute("DROP TABLE botamusique")
143 def __init__(self, db_path):
144 self.db_path = db_path
147 conn = sqlite3.connect(self.db_path)
148 cursor = conn.cursor()
150 # check if table exists, or create one
151 cursor.execute("CREATE TABLE IF NOT EXISTS music ("
152 "id TEXT PRIMARY KEY, "
160 def insert_music(self, music_dict):
161 conn = sqlite3.connect(self.db_path)
162 cursor = conn.cursor()
164 id = music_dict['id']
165 title = music_dict['title']
166 type = music_dict['type']
167 tags = ",".join(music_dict['tags']) + ","
170 del music_dict['title']
171 del music_dict['type']
172 del music_dict['tags']
174 cursor.execute("INSERT OR REPLACE INTO music (id, type, title, metadata, tags) VALUES (?, ?, ?, ?, ?)",
178 json.dumps(music_dict),
184 def query_all_ids(self):
185 conn = sqlite3.connect(self.db_path)
186 cursor = conn.cursor()
187 results = cursor.execute("SELECT id FROM music").fetchall()
189 return list(map(lambda i: i[0], results))
191 def query_all_tags(self):
192 conn = sqlite3.connect(self.db_path)
193 cursor = conn.cursor()
194 results = cursor.execute("SELECT tags FROM music").fetchall()
196 for result in results:
197 for tag in result[0].strip(",").split(","):
198 if tag and tag not in tags:
203 def query_music(self, **kwargs):
207 for key, value in kwargs.items():
208 if isinstance(value, str):
209 condition.append(key + "=?")
211 elif isinstance(value, dict):
212 condition.append(key + " " + value[0] + " ?")
213 filler.append(value[1])
215 condition_str = " AND ".join(condition)
217 conn = sqlite3.connect(self.db_path)
218 cursor = conn.cursor()
219 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
220 "WHERE %s" % condition_str, filler).fetchall()
223 return self._result_to_dict(results)
225 def query_music_by_keywords(self, keywords):
229 for keyword in keywords:
230 condition.append('LOWER(title) LIKE ?')
231 filler.append("%{:s}%".format(keyword.lower()))
233 condition_str = " AND ".join(condition)
235 conn = sqlite3.connect(self.db_path)
236 cursor = conn.cursor()
237 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
238 "WHERE %s" % condition_str, filler).fetchall()
241 return self._result_to_dict(results)
243 def query_music_by_tags(self, tags):
248 condition.append('LOWER(tags) LIKE ?')
249 filler.append("%{:s},%".format(tag.lower()))
251 condition_str = " AND ".join(condition)
253 conn = sqlite3.connect(self.db_path)
254 cursor = conn.cursor()
255 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
256 "WHERE %s" % condition_str, filler).fetchall()
259 return self._result_to_dict(results)
261 def query_tags_by_ids(self, ids):
262 condition_str = " OR ".join(['id=?'] * len(ids))
264 conn = sqlite3.connect(self.db_path)
265 cursor = conn.cursor()
266 results = cursor.execute("SELECT id, tags FROM music "
267 "WHERE %s" % condition_str, ids).fetchall()
272 for result in results:
274 tags = result[1].strip(",").split(",")
275 lookup[id] = tags if tags[0] else []
279 def query_random_music(self, count):
280 conn = sqlite3.connect(self.db_path)
281 cursor = conn.cursor()
282 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
283 "WHERE id IN (SELECT id FROM music ORDER BY RANDOM() LIMIT ?)", (count,)).fetchall()
286 return self._result_to_dict(results)
288 def _result_to_dict(self, results):
291 for result in results:
292 music_dict = json.loads(result[3])
293 music_dict['type'] = result[1]
294 music_dict['title'] = result[2]
295 music_dict['id'] = result[0]
296 music_dict['tags'] = result[4].strip(",").split(",")
297 if not music_dict['tags'][0]:
298 music_dict['tags'] = []
300 music_dicts.append(music_dict)
306 def delete_music(self, **kwargs):
310 for key, value in kwargs.items():
311 if isinstance(value, str):
312 condition.append(key + "=?")
315 condition.append(key + " " + value[0] + " ?")
316 filler.append(value[1])
318 condition_str = " AND ".join(condition)
320 conn = sqlite3.connect(self.db_path)
321 cursor = conn.cursor()
322 cursor.execute("DELETE FROM music "
323 "WHERE %s" % condition_str, filler)
327 def drop_table(self):
328 conn = sqlite3.connect(self.db_path)
329 cursor = conn.cursor()
330 cursor.execute("DROP TABLE music")