Skip to content

Commit

Permalink
Merge pull request #152 from phw/subsonic-playlist-id
Browse files Browse the repository at this point in the history
Allow specifying subsonic playlist ID to overwrite
  • Loading branch information
mayhem authored Dec 3, 2024
2 parents 48ef15d + 0eb0cb6 commit 5bb8bc1
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
15 changes: 9 additions & 6 deletions troi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,13 @@ def info_cmd(patch):
@click.option("-d", "--db_file", help="Database file for the local collection", required=False, is_flag=False)
@click.option('-t', '--threshold', default=.80, help="Minimum match percentage for metadata matches. Must be 0.0 - 1.0")
@click.option('-u', '--upload-to-subsonic', required=False, is_flag=True, help="upload playlist via subsonic API")
@click.option('-i', '--subsonic-id', required=False, help="overwrite existing subsonic playlist with the given ID")
@click.option('-m', '--save-to-m3u', required=False, help="save to specified m3u playlist")
@click.option('-j', '--save-to-jspf', required=False, help="save to specified JSPF playlist")
@click.option('-y', '--dont-ask', required=False, is_flag=True, help="save playlist without asking user")
@click.option('-q', '--quiet', 'quiet', help="Do no print out anything", required=False, is_flag=True)
@click.argument('jspf_playlist')
def resolve(db_file, threshold, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask, quiet, jspf_playlist):
def resolve(db_file, threshold, upload_to_subsonic, subsonic_id, save_to_m3u, save_to_jspf, dont_ask, quiet, jspf_playlist):
""" Resolve a global JSPF playlist with MusicBrainz MBIDs to files in the local collection"""
set_log_level(quiet)
db_file = db_file_check(db_file)
Expand All @@ -197,20 +198,21 @@ def resolve(db_file, threshold, upload_to_subsonic, save_to_m3u, save_to_jspf, d
lbrl = ListenBrainzRadioLocal(quiet)
playlist = read_jspf_playlist(jspf_playlist)
lbrl.resolve_playlist(threshold, playlist)
output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask)
output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask, subsonic_id)


@cli.command(name="lb-radio", context_settings=dict(ignore_unknown_options=True, ))
@click.option("-d", "--db_file", help="Database file for the local collection", required=False, is_flag=False)
@click.option('-t', '--threshold', default=.80, help="Minimum match percentage for metadata matches. Must be 0.0 - 1.0")
@click.option('-u', '--upload-to-subsonic', required=False, is_flag=True, help="upload playlist via subsonic API")
@click.option('-i', '--subsonic-id', required=False, help="overwrite existing subsonic playlist with the given ID")
@click.option('-m', '--save-to-m3u', required=False, help="save to specified m3u playlist")
@click.option('-j', '--save-to-jspf', required=False, help="save to specified JSPF playlist")
@click.option('-y', '--dont-ask', required=False, is_flag=True, help="save playlist without asking user")
@click.option('-q', '--quiet', 'quiet', help="Do no print out anything", required=False, is_flag=True)
@click.argument('mode')
@click.argument('prompt')
def lb_radio(db_file, threshold, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask, quiet, mode, prompt):
def lb_radio(db_file, threshold, upload_to_subsonic, subsonic_id, save_to_m3u, save_to_jspf, dont_ask, quiet, mode, prompt):
"""Use LB Radio to create a playlist from a prompt, using a local music collection"""
set_log_level(quiet)
db_file = db_file_check(db_file)
Expand All @@ -224,19 +226,20 @@ def lb_radio(db_file, threshold, upload_to_subsonic, save_to_m3u, save_to_jspf,
db.metadata_sanity_check(include_subsonic=upload_to_subsonic)
return

output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask)
output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask, subsonic_id)


@cli.command("weekly-jams", context_settings=dict(ignore_unknown_options=True, ))
@click.option("-d", "--db_file", help="Database file for the local collection", required=False, is_flag=False)
@click.option('-t', '--threshold', default=.80, help="Minimum match percentage for metadata matches. Must be 0.0 - 1.0")
@click.option('-u', '--upload-to-subsonic', required=False, is_flag=True, help="upload playlist via subsonic API")
@click.option('-i', '--subsonic-id', required=False, help="overwrite existing subsonic playlist with the given ID")
@click.option('-m', '--save-to-m3u', required=False, help="save to specified m3u playlist")
@click.option('-j', '--save-to-jspf', required=False, help="save to specified JSPF playlist")
@click.option('-y', '--dont-ask', required=False, is_flag=True, help="save playlist without asking user")
@click.option('-q', '--quiet', 'quiet', help="Do no print out anything", required=False, is_flag=True)
@click.argument('user_name')
def periodic_jams(db_file, threshold, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask, quiet, user_name):
def periodic_jams(db_file, threshold, upload_to_subsonic, subsonic_id, save_to_m3u, save_to_jspf, dont_ask, quiet, user_name):
"Generate a weekly jams playlist for your local collection"
set_log_level(quiet)
db_file = db_file_check(db_file)
Expand All @@ -251,7 +254,7 @@ def periodic_jams(db_file, threshold, upload_to_subsonic, save_to_m3u, save_to_j
db.metadata_sanity_check(include_subsonic=upload_to_subsonic)
return

output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask)
output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask, subsonic_id)


@cli.command(context_settings=dict(ignore_unknown_options=True, ))
Expand Down
4 changes: 2 additions & 2 deletions troi/content_resolver/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
DEFAULT_CHUNKSIZE = 100


def output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask):
def output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf, dont_ask, subsonic_id=None):
try:
recording = playlist.playlists[0].recordings[0]
except (KeyError, IndexError):
Expand All @@ -43,7 +43,7 @@ def output_playlist(db, playlist, upload_to_subsonic, save_to_m3u, save_to_jspf,

if dont_ask or ask_yes_no_question("Upload via subsonic? (Y/n)"):
logger.info("uploading playlist")
db.upload_playlist(playlist)
db.upload_playlist(playlist, subsonic_id)
return

if save_to_m3u or save_to_jspf:
Expand Down
19 changes: 15 additions & 4 deletions troi/content_resolver/subsonic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime
import logging

from libsonic.errors import DataNotFoundError
import peewee
from tqdm import tqdm

Expand Down Expand Up @@ -235,9 +236,7 @@ def update_recordings(self, recordings):
# , subsonic_id = excluded.subsonic_id
# , last_updated = excluded.last_updated""", recordings)



def upload_playlist(self, playlist):
def upload_playlist(self, playlist, playlist_id=None):
"""
Given a Troi playlist, upload the playlist to the subsonic API.
"""
Expand All @@ -253,4 +252,16 @@ def upload_playlist(self, playlist):
except KeyError:
continue

conn.createPlaylist(name=playlist.playlists[0].name, songIds=song_ids)
if playlist_id:
try:
remote_playlist = conn.getPlaylist(pid=playlist_id)
conn.updatePlaylist(
lid=playlist_id,
name=playlist.playlists[0].name,
songIdsToAdd=song_ids,
songIndexesToRemove=list(range(0, len(remote_playlist["playlist"]) - 1)),
)
except DataNotFoundError:
conn.createPlaylist(name=playlist.playlists[0].name, songIds=song_ids)
else:
conn.createPlaylist(name=playlist.playlists[0].name, songIds=song_ids)

0 comments on commit 5bb8bc1

Please sign in to comment.