5 class DatabaseError(Exception):
8 class SettingsDatabase:
10 def __init__(self, db_path):
11 self.db_path = db_path
14 conn = sqlite3.connect(self.db_path)
15 cursor = conn.cursor()
17 self.db_version_check_and_create()
23 conn = sqlite3.connect(self.db_path)
24 cursor = conn.cursor()
25 tables = cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='botamusique';").fetchall()
31 def db_version_check_and_create(self):
32 conn = sqlite3.connect(self.db_path)
33 cursor = conn.cursor()
37 result = cursor.execute("SELECT value FROM botamusique WHERE section=? AND option=?",
38 ("bot", "db_version")).fetchall()
40 if len(result) == 0 or int(result[0][0]) != self.version:
41 old_name = "botamusique_old_%s" % datetime.datetime.now().strftime("%Y%m%d")
42 cursor.execute("ALTER TABLE botamusique RENAME TO %s" % old_name)
45 self.set("bot", "old_db_name", old_name)
51 def create_table(self):
52 conn = sqlite3.connect(self.db_path)
53 cursor = conn.cursor()
54 cursor.execute("CREATE TABLE IF NOT EXISTS botamusique ("
58 "UNIQUE(section, option))")
59 cursor.execute("INSERT INTO botamusique (section, option, value) "
60 "VALUES (?, ?, ?)" , ("bot", "db_version", "1"))
61 cursor.execute("INSERT INTO botamusique (section, option, value) "
62 "VALUES (?, ?, ?)" , ("bot", "music_db_version", "0"))
66 def get(self, section, option, **kwargs):
67 conn = sqlite3.connect(self.db_path)
68 cursor = conn.cursor()
69 result = cursor.execute("SELECT value FROM botamusique WHERE section=? AND option=?", (section, option)).fetchall()
75 if 'fallback' in kwargs:
76 return kwargs['fallback']
78 raise DatabaseError("Item not found")
80 def getboolean(self, section, option, **kwargs):
81 return bool(int(self.get(section, option, **kwargs)))
83 def getfloat(self, section, option, **kwargs):
84 return float(self.get(section, option, **kwargs))
86 def getint(self, section, option, **kwargs):
87 return int(self.get(section, option, **kwargs))
89 def set(self, section, option, value):
90 conn = sqlite3.connect(self.db_path)
91 cursor = conn.cursor()
92 cursor.execute("INSERT OR REPLACE INTO botamusique (section, option, value) "
93 "VALUES (?, ?, ?)" , (section, option, value))
97 def has_option(self, section, option):
98 conn = sqlite3.connect(self.db_path)
99 cursor = conn.cursor()
100 result = cursor.execute("SELECT value FROM botamusique WHERE section=? AND option=?", (section, option)).fetchall()
107 def remove_option(self, section, option):
108 conn = sqlite3.connect(self.db_path)
109 cursor = conn.cursor()
110 cursor.execute("DELETE FROM botamusique WHERE section=? AND option=?", (section, option))
114 def remove_section(self, section):
115 conn = sqlite3.connect(self.db_path)
116 cursor = conn.cursor()
117 cursor.execute("DELETE FROM botamusique WHERE section=?", (section, ))
121 def items(self, section):
122 conn = sqlite3.connect(self.db_path)
123 cursor = conn.cursor()
124 results = cursor.execute("SELECT option, value FROM botamusique WHERE section=?", (section, )).fetchall()
128 return list(map(lambda v: (v[0], v[1]), results))
132 def drop_table(self):
133 conn = sqlite3.connect(self.db_path)
134 cursor = conn.cursor()
135 cursor.execute("DROP TABLE botamusique")
140 def __init__(self, db_path):
141 self.db_path = db_path
144 conn = sqlite3.connect(self.db_path)
145 cursor = conn.cursor()
147 # check if table exists, or create one
148 cursor.execute("CREATE TABLE IF NOT EXISTS music ("
149 "id TEXT PRIMARY KEY, "
157 def insert_music(self, music_dict):
158 conn = sqlite3.connect(self.db_path)
159 cursor = conn.cursor()
161 id = music_dict['id']
162 title = music_dict['title']
163 type = music_dict['type']
164 tags = ",".join(music_dict['tags']) + ","
167 del music_dict['title']
168 del music_dict['type']
169 del music_dict['tags']
171 cursor.execute("INSERT OR REPLACE INTO music (id, type, title, metadata, tags) VALUES (?, ?, ?, ?, ?)",
175 json.dumps(music_dict),
181 def query_all_ids(self):
182 conn = sqlite3.connect(self.db_path)
183 cursor = conn.cursor()
184 results = cursor.execute("SELECT id FROM music").fetchall()
186 return list(map(lambda i: i[0], results))
188 def query_all_tags(self):
189 conn = sqlite3.connect(self.db_path)
190 cursor = conn.cursor()
191 results = cursor.execute("SELECT tags FROM music").fetchall()
193 for result in results:
194 for tag in result[0].strip(",").split(","):
195 if tag and tag not in tags:
200 def query_music(self, **kwargs):
204 for key, value in kwargs.items():
205 if isinstance(value, str):
206 condition.append(key + "=?")
208 elif isinstance(value, dict):
209 condition.append(key + " " + value[0] + " ?")
210 filler.append(value[1])
212 condition_str = " AND ".join(condition)
214 conn = sqlite3.connect(self.db_path)
215 cursor = conn.cursor()
216 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
217 "WHERE %s" % condition_str, filler).fetchall()
220 return self._result_to_dict(results)
222 def query_music_by_keywords(self, keywords):
226 for keyword in keywords:
227 condition.append('LOWER(title) LIKE ?')
228 filler.append("%{:s}%".format(keyword.lower()))
231 condition_str = " AND ".join(condition)
233 conn = sqlite3.connect(self.db_path)
234 cursor = conn.cursor()
235 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
236 "WHERE %s" % condition_str, filler).fetchall()
239 return self._result_to_dict(results)
241 def query_music_by_tags(self, tags):
246 condition.append('LOWER(tags) LIKE ?')
247 filler.append("%{:s},%".format(tag.lower()))
250 condition_str = " AND ".join(condition)
252 conn = sqlite3.connect(self.db_path)
253 cursor = conn.cursor()
254 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
255 "WHERE %s" % condition_str, filler).fetchall()
258 return self._result_to_dict(results)
260 def query_tags_by_ids(self, ids):
261 condition_str = " OR ".join(['id=?'] * len(ids))
263 conn = sqlite3.connect(self.db_path)
264 cursor = conn.cursor()
265 results = cursor.execute("SELECT id, tags FROM music "
266 "WHERE %s" % condition_str, ids).fetchall()
271 for result in results:
273 tags = result[1].strip(",").split(",")
274 lookup[id] = tags if tags[0] else []
278 def query_random_music(self, count):
279 conn = sqlite3.connect(self.db_path)
280 cursor = conn.cursor()
281 results = cursor.execute("SELECT id, type, title, metadata, tags FROM music "
282 "WHERE id IN (SELECT id FROM music ORDER BY RANDOM() LIMIT ?)", (count,)).fetchall()
285 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)
328 def drop_table(self):
329 conn = sqlite3.connect(self.db_path)
330 cursor = conn.cursor()
331 cursor.execute("DROP TABLE music")