From fcf4ba3eb9d92d6f3b64fa9b71f6eeaada2b1430 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Sun, 15 Aug 2021 12:52:50 +0100 Subject: [PATCH] Implement full database scan --- app/model.py | 6 ++++ app/songdb.py | 88 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/app/model.py b/app/model.py index 1619e00..d9ea5e4 100644 --- a/app/model.py +++ b/app/model.py @@ -463,6 +463,12 @@ class Tracks(Base): return [a[0] for a in session.query(Tracks.path).all()] + @staticmethod + def get_all_tracks(session): + "Return a list of all tracks" + + return session.query(Tracks).all() + @classmethod def get_or_create(cls, session, path): DEBUG(f"Tracks.get_or_create(path={path})") diff --git a/app/songdb.py b/app/songdb.py index 42063cd..6366357 100755 --- a/app/songdb.py +++ b/app/songdb.py @@ -115,10 +115,78 @@ def create_track_from_file(session, path): return track -def full_update_db(): +def full_update_db(session): "Rescan all entries in database" - print("Full scan not yet implemented") + def log(msg): + INFO(f"full_update_db(): {msg}") + + def check_change(track_id, title, attribute, old, new): + if new > (old * 1.1) or new < (old * 0.9): + log( + "\n" + f"track[{track_id}] ({title}) " + f"{attribute} updated from {old} to {new}" + ) + + # Start with normal update to add new tracks and remove any missing + # files + log("update_db()") + update_db(session) + + # Now update track length, silence and fade for every track in + # database + + tracks = Tracks.get_all_tracks(session) + total_tracks = len(tracks) + log(f"Processing {total_tracks} tracks") + track_count = 0 + for track in tracks: + track_count += 1 + print(f"\rTrack {track_count} of {total_tracks}", end='') + + # Sanity check + tag = get_music_info(track.path) + if not tag['title']: + log(f"track[{track.id}] {track.title=}: No tag title") + continue + + if track.artist: + if track.artist != tag['artist']: + log( + f"track[{track.id}] artist mismatch: " + f"{track.artist=} {tag['artist']=}" + ) + continue + + # Update title + if track.title != tag['title']: + track.title = tag['title'] + + # Update numbers; log if more than 10% different + duration = int(round( + tag['duration'], Config.MILLISECOND_SIGFIGS) * 1000) + check_change(track.id, track.title, "duration", track.duration, + duration) + track.duration = duration + + audio = get_audio_segment(track.path) + + start_gap = leading_silence(audio) + check_change(track.id, track.title, "start_gap", track.start_gap, + start_gap) + track.start_gap = start_gap + + fade_at = fade_point(audio) + check_change(track.id, track.title, "fade_at", track.fade_at, + fade_at) + track.fade_at = fade_at + + silence_at = trailing_silence(audio) + check_change(track.id, track.title, "silence_at", track.silence_at, + silence_at) + track.silence_at = silence_at + session.commit() def get_audio_segment(path): @@ -196,22 +264,6 @@ def fade_point(audio_segment, fade_threshold=0, return int(trim_ms) -# Current unused (1 June 2021) -# def rescan_database(session): -# -# tracks = Tracks.get_all_tracks(session) -# total_tracks = len(tracks) -# track_count = 0 -# for track in tracks: -# track_count += 1 -# print(f"Track {track_count} of {total_tracks}") -# audio = get_audio_segment(track.path) -# track.start_gap = leading_silence(audio) -# track.fade_at = fade_point(audio) -# track.silence_at = trailing_silence(audio) -# session.commit() - - def trailing_silence(audio_segment, silence_threshold=-50.0, chunk_size=Config.AUDIO_SEGMENT_CHUNK_SIZE): return fade_point(audio_segment, silence_threshold, chunk_size)