support partial library rebuilds

This commit is contained in:
iou1name 2020-01-03 12:14:37 -05:00
parent f171721915
commit 7643a13b54
2 changed files with 20 additions and 27 deletions

View File

@ -26,17 +26,6 @@ def db_execute(*args, **kwargs):
DB_LOCK.release() DB_LOCK.release()
return res return res
def db_execute_unsafe(*args, **kwargs):
"""
A non-thread-safe version of `db_execute()`. Only use if you're
certain there will be no competing threads for the database.
"""
with sqlite3.connect('musik.db') as con:
con.row_factory = sqlite3.Row
cur = con.cursor()
res = cur.execute(*args, **kwargs)
return res
def db_execute_many(*args, **kwargs): def db_execute_many(*args, **kwargs):
""" """
Same as `db_executei()` except with `cur.executemany()`. Same as `db_executei()` except with `cur.executemany()`.
@ -54,8 +43,9 @@ def init_database():
Initializes the database. Initializes the database.
""" """
try: try:
db_execute_unsafe("SELECT * FROM tracks LIMIT 1").fetchone() db_execute("SELECT * FROM tracks LIMIT 1").fetchone()
except sqlite3.OperationalError: except sqlite3.OperationalError:
DB_LOCK.release()
db_execute("CREATE TABLE tracks(" db_execute("CREATE TABLE tracks("
"filepath TEXT PRIMARY KEY," "filepath TEXT PRIMARY KEY,"
"artist TEXT," "artist TEXT,"
@ -66,7 +56,8 @@ def init_database():
"tracknumber TEXT," "tracknumber TEXT,"
"title TEXT," "title TEXT,"
"genre TEXT," "genre TEXT,"
"length TEXT" "length TEXT,"
"last_modified INTEGER"
")" ")"
) )
build_library(MUSIC_DIR) build_library(MUSIC_DIR)
@ -81,11 +72,19 @@ def build_library(root_dir):
if not os.path.splitext(file)[1][1:] in MUSIC_EXT: if not os.path.splitext(file)[1][1:] in MUSIC_EXT:
continue continue
filepath = os.path.join(root_dir, dir_name, file) filepath = os.path.join(root_dir, dir_name, file)
filepaths.append(filepath) last_modified = os.path.getmtime(filepath)
filepaths.append((filepath, last_modified))
tracks_prev = db_execute("SELECT * FROM tracks")
tracks_prev = {track['filepath']: track for track in tracks_prev}
global worker global worker
def worker(filepath): def worker(tup):
"""Worker for multi-processing tracks.""" """Worker for multi-processing tracks."""
filepath, last_modified = tup
track_prev = tracks_prev.get(filepath)
if track_prev:
if track_prev['last_modified'] >= last_modified:
return tuple(track_prev)
data = read_track(filepath) data = read_track(filepath)
return data return data
@ -102,8 +101,9 @@ def build_library(root_dir):
if percent >= prev_percent + 2.5: if percent >= prev_percent + 2.5:
print(f"{percent}%") print(f"{percent}%")
prev_percent = percent prev_percent = percent
db_execute("DELETE FROM tracks")
db_execute_many( db_execute_many(
"INSERT INTO tracks VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", "INSERT INTO tracks VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
tracks tracks
) )
print("Done") print("Done")
@ -131,23 +131,13 @@ def read_track(filepath):
genre = m.get('genre', [''])[0] genre = m.get('genre', [''])[0]
length = str(int(m.info.length) // 60) + ":" length = str(int(m.info.length) // 60) + ":"
length += str(int(m.info.length) % 60) length += str(int(m.info.length) % 60)
last_modified = os.path.getmtime(filepath)
d = locals() d = locals()
d.pop('m') d.pop('m')
return tuple(d.values()) return tuple(d.values())
def insert_track(data):
"""
Inserts a new item into the `tracks` table. `data` should be a tuple
containing an item for every column in the `tracks` table. See the
table declarion in `init_database()` for more information.
"""
db_execute(
"INSERT INTO tracks VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
data
)
def get_artist_albums(artist): def get_artist_albums(artist):
""" """
Returns a list of all albums produced by the specified `artist`. Returns a list of all albums produced by the specified `artist`.

View File

@ -116,4 +116,7 @@ def coverart():
if __name__ == "__main__": if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
database.build_library(database.MUSIC_DIR)
app.run(host='0.0.0.0', port=5150) app.run(host='0.0.0.0', port=5150)