Skip to content
This repository has been archived by the owner on Feb 9, 2024. It is now read-only.

Commit

Permalink
Allow the subsonic scan to create the database entries , obviating th…
Browse files Browse the repository at this point in the history
…e need for the the scan command for matching to a subsonic collection
  • Loading branch information
mayhem committed Dec 31, 2023
1 parent 1c594ac commit 6d386e9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 52 deletions.
20 changes: 9 additions & 11 deletions lb_content_resolver/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,6 @@ def add_or_update_recording(self, mdata):
"""

with db.atomic() as transaction:
if mdata is not None:
details = " %d%% " % (100 * self.total / self.audio_file_count)
details += " %-30s %-30s %-30s" % ((mdata.get("recording_name", "") or "")[:29],
(mdata.get("release_name", "") or "")[:29],
(mdata.get("artist_name", "") or "")[:29])
else:
details = ""

try:
recording = Recording.select().where(Recording.file_path == mdata['file_path']).get()
except:
Expand All @@ -169,7 +161,7 @@ def add_or_update_recording(self, mdata):
duration=mdata["duration"],
track_num=mdata["track_num"],
disc_num=mdata["disc_num"])
return "added", details
return "added"

recording.artist_name = mdata["artist_name"]
recording.release_name = mdata["release_name"]
Expand All @@ -181,7 +173,7 @@ def add_or_update_recording(self, mdata):
recording.track_num = mdata["track_num"]
recording.disc_num = mdata["disc_num"]
recording.save()
return "updated", details
return "updated"

def read_metadata_and_add(self, relative_path, format, mtime, update):
"""
Expand Down Expand Up @@ -216,8 +208,14 @@ def read_metadata_and_add(self, relative_path, format, mtime, update):
mdata["release_mbid"] = self.convert_to_uuid(mdata["release_mbid"])
mdata["recording_mbid"] = self.convert_to_uuid(mdata["recording_mbid"])

details = " %d%% " % (100 * self.total / self.audio_file_count)
details += " %-30s %-30s %-30s" % ((mdata.get("recording_name", "") or "")[:29],
(mdata.get("release_name", "") or "")[:29],
(mdata.get("artist_name", "") or "")[:29])


# now add/update the record
return self.add_or_update_recording(mdata)
return self.add_or_update_recording(mdata), details

return "error", "Failed to read metadata from audio file."

Expand Down
90 changes: 49 additions & 41 deletions lb_content_resolver/subsonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from lb_content_resolver.utils import bcolors
import config

# TODO: TEST FS scan


class SubsonicDatabase(Database):
'''
Expand Down Expand Up @@ -39,13 +41,14 @@ def sync(self):

print("Checked %s albums:" % self.total)
print(" %5d albums matched" % self.matched)
print(" %5d albums with errors" % self.error)
print(" %5d recordings with errors" % self.error)

def run_sync(self):
"""
Perform the sync between the local collection and the subsonic one.
"""

from icecream import ic
print("[ connect to subsonic ]")
conn = libsonic.Connection(config.SUBSONIC_HOST, config.SUBSONIC_USER, config.SUBSONIC_PASSWORD, config.SUBSONIC_PORT)
cursor = db.connection().cursor()
Expand All @@ -69,6 +72,9 @@ def run_sync(self):
pbar = tqdm(total=len(album_ids))
recordings = []

# cross reference subsonic artist id to artitst_mbid
artist_id_index = {}

for album in albums:
album_info = conn.getAlbum(id=album["id"])

Expand All @@ -84,51 +90,53 @@ def run_sync(self):
self.error += 1
continue

cursor.execute(
"""SELECT recording.id
, track_num
, COALESCE(disc_num, 1)
FROM recording
WHERE release_mbid = ?""", (album_mbid, ))

# create index on (track_num, disc_num)
release_tracks = {(row[1], row[2]): row[0] for row in cursor.fetchall()}

if len(release_tracks) == 0:
pbar.write("For album %s" % album_mbid)
pbar.write("loaded %d of %d expected tracks from DB." %
(len(release_tracks), len(album_info["album"].get("song", []))))

msg = ""
if "song" not in album_info["album"]:
msg += " No songs returned\n"
else:
for song in album_info["album"]["song"]:
if (song["track"], song.get("discNumber", 1)) in release_tracks:
recordings.append((release_tracks[(song["track"], song["discNumber"])], song["id"]))
else:
msg += " Song not matched: '%s'\n" % song["title"]

recordings = []
for song in album_info["album"]["song"]:
album = album_info["album"]

if "artistId" in song:
artist_id = song["artistId"]
else:
artist_id = album["artistId"]

if artist_id not in artist_id_index:
artist = conn.getArtistInfo2(artist_id)
try:
artist_id_index[artist_id] = artist["artistInfo2"]["musicBrainzId"]
except KeyError:
pbar.write(bcolors.FAIL + "FAIL " + bcolors.ENDC + "recording '%s' by '%s' has no artist MBID" %
(album["name"], album["artist"]))
pbar.write("Consider retagging this file with Picard! ( https://picard.musicbrainz.org )")
self.error += 1
continue
if msg == "":
pbar.write(bcolors.OKGREEN + "OK " + bcolors.ENDC + "album %-50s %-50s" %
(album["name"][:49], album["artist"][:49]))
self.matched += 1
else:
pbar.write(bcolors.FAIL + "FAIL " + bcolors.ENDC + "album %-50s %-50s" %
(album["name"][:49], album["artist"][:49]))
pbar.write(msg)
self.error += 1

if len(recordings) >= self.BATCH_SIZE:
self.update_recordings(recordings)
recordings = []


# if "musicBrainzId" not in song:
# song_details = conn.getSong(song["id"])
# ic(song_details)

self.add_or_update_recording({
"artist_name": song["artist"],
"release_name": song["album"],
"recording_name": song["title"],
"artist_mbid": artist_id_index[artist_id],
"release_mbid": album_mbid,
"recording_mbid": "",
"duration": song["duration"] * 1000,
"track_num": song["track"],
"disc_num": song["discNumber"],
"subsonic_id": song["id"],
"file_path": "",
"mtime": datetime.datetime.now()
})

pbar.write(bcolors.OKGREEN + "OK " + bcolors.ENDC + "album %-50s %-50s" %
(album["name"][:49], album["artist"][:49]))
self.matched += 1
self.total += 1
pbar.update(1)

if len(recordings) >= self.BATCH_SIZE:
self.update_recordings(recordings)


def update_recordings(self, recordings):
"""
Expand Down

0 comments on commit 6d386e9

Please sign in to comment.