allow download raw project as json
This commit is contained in:
@ -391,7 +391,10 @@ class HipsterfyPlaylistItem(object):
|
||||
|
||||
|
||||
class HipsterfyPlaylist(object):
|
||||
def __init__(self, playlist_uri, hipsterfy:Hipsterfy):
|
||||
def __init__(self, playlist_uri: str, hipsterfy:Hipsterfy, serialized_raw_data:List[Dict[str, Any]] = None ):
|
||||
if serialized_raw_data:
|
||||
self._tracks_data = [HipsterfyPlaylistItem(item) for item in serialized_raw_data]
|
||||
return
|
||||
self._playlist_uri = playlist_uri
|
||||
self._hipsterfy = hipsterfy
|
||||
self._tracks_data = []
|
||||
@ -416,3 +419,8 @@ class HipsterfyPlaylist(object):
|
||||
"""Returns the list of HipsterfyPlaylistItem objects representing the tracks in the playlist.
|
||||
"""
|
||||
return self._tracks_data
|
||||
def get_raw_playlist_data(self) -> List[Dict[str, Any]]:
|
||||
"""Returns the raw playlist data as a list of dictionaries.
|
||||
"""
|
||||
return [item._raw_data for item in self._tracks_data]
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ from io import BytesIO
|
||||
from hipsterfy.hipsterfy import Hipsterfy, HipsterfyPlaylist, HipsterfyPlaylistItem, CardStyle
|
||||
import qrcode
|
||||
|
||||
pn.extension("filedropper")
|
||||
|
||||
pn.extension("filedownload", "notifications", "location")
|
||||
|
||||
@ -12,13 +13,25 @@ pn.extension("filedownload", "notifications", "location")
|
||||
def create_panel_page(hipsterfy: Hipsterfy, playlist_uri: str=None, root_url = None) -> pn.Template:
|
||||
|
||||
# create widgets
|
||||
mode = pn.widgets.RadioButtonGroup(name='Input Mode', options=['Playlist URI', 'Upload JSON'], button_type='success', value='Playlist URI', sizing_mode='stretch_width')
|
||||
playlist_uri = pn.widgets.TextInput(name='Playlist URI', value=playlist_uri or '', placeholder='Enter Spotify Playlist URI')
|
||||
json_upload = pn.widgets.FileDropper(name='Upload Playlist JSON', accepted_filetypes=['application/json'], sizing_mode='stretch_width')
|
||||
primary_item = pn.widgets.Select(name='Primary Item', options=HipsterfyPlaylistItem.get_available_properties(), value="release_year")
|
||||
secondary_item = pn.widgets.Select(name='Secondary Item', options=HipsterfyPlaylistItem.get_available_properties(), value="title")
|
||||
additional_items = pn.widgets.MultiChoice(name='Additional Items', options=HipsterfyPlaylistItem.get_available_properties(), value=["artists", "album", "popularity"])
|
||||
card_style = pn.widgets.Select(name='Card Style', options=[style.value for style in CardStyle], value=CardStyle.FULL_ALBUM_COVER.value)
|
||||
cards_per_row_widget = pn.widgets.IntSlider(name="Cards per Row in print", start=1, end=8, value=4, step=1)
|
||||
|
||||
def on_mode_change(event):
|
||||
if mode.value == 'Playlist URI':
|
||||
playlist_uri.visible = True
|
||||
json_upload.visible = False
|
||||
else:
|
||||
playlist_uri.visible = False
|
||||
json_upload.visible = True
|
||||
mode.param.watch(on_mode_change, 'value')
|
||||
on_mode_change(None) # Initial call to set visibility
|
||||
|
||||
pn.state.location.sync(playlist_uri, {"value": "playlist_uri"})
|
||||
pn.state.location.sync(primary_item, {"value": "primary_item"})
|
||||
pn.state.location.sync(secondary_item, {"value": "secondary_item"})
|
||||
@ -39,6 +52,10 @@ def create_panel_page(hipsterfy: Hipsterfy, playlist_uri: str=None, root_url = N
|
||||
label="Download Back Cards (HTML)", button_type="success", visible=False, filename="hipsterfy_back_cards.html", sizing_mode='stretch_width'
|
||||
)
|
||||
|
||||
download_json_data_button = pn.widgets.FileDownload(
|
||||
label="Download Playlist Data (JSON)", button_type="success", visible=False, filename="hipsterfy_raw_playlist_data.json", sizing_mode='stretch_width'
|
||||
)
|
||||
|
||||
playlist_instructions = pn.pane.HTML(
|
||||
"""
|
||||
<div>
|
||||
@ -110,6 +127,16 @@ def create_panel_page(hipsterfy: Hipsterfy, playlist_uri: str=None, root_url = N
|
||||
download_back_html_button.callback = lambda: BytesIO(generate_html(cards_back, row_reverse=True))
|
||||
download_back_html_button.visible = True
|
||||
|
||||
# Raw Playlist Data as JSON
|
||||
def generate_playlist_json():
|
||||
import json
|
||||
uri = playlist_uri.value.strip()
|
||||
hipsterfy_playlist = HipsterfyPlaylist(uri, hipsterfy)
|
||||
data = hipsterfy_playlist.get_raw_playlist_data()
|
||||
return json.dumps(data, indent=4).encode() # FileDownload erwartet Bytes
|
||||
download_json_data_button.callback = lambda: BytesIO(generate_playlist_json())
|
||||
download_json_data_button.visible = True
|
||||
|
||||
print_instructions.visible = True # Show print instructions after generating preview
|
||||
|
||||
pn.state.notifications.success("Download buttons updated successfully!. Download and print them from the sidebar")
|
||||
@ -135,7 +162,15 @@ def create_panel_page(hipsterfy: Hipsterfy, playlist_uri: str=None, root_url = N
|
||||
return
|
||||
|
||||
# create HipsterfyPlaylist instance
|
||||
hipsterfy_playlist = HipsterfyPlaylist(uri, hipsterfy)
|
||||
if mode.value == 'Upload JSON':
|
||||
if len(json_upload.value) == 0:
|
||||
pn.state.notifications.error("Please upload a valid JSON file containing playlist data.")
|
||||
return
|
||||
import json
|
||||
raw_data = json.loads(list(json_upload.value.values())[0].decode())
|
||||
hipsterfy_playlist = HipsterfyPlaylist(uri, hipsterfy, serialized_raw_data=raw_data)
|
||||
else:
|
||||
hipsterfy_playlist = HipsterfyPlaylist(uri, hipsterfy)
|
||||
|
||||
new_back_cards = []
|
||||
new_front_cards = []
|
||||
@ -168,6 +203,8 @@ def create_panel_page(hipsterfy: Hipsterfy, playlist_uri: str=None, root_url = N
|
||||
|
||||
create_preview_button.on_click(create_preview)
|
||||
|
||||
|
||||
|
||||
# Dynamischer QR-Code für die Player-App
|
||||
def generate_qr_code_base64(url):
|
||||
qr = qrcode.QRCode(box_size=4, border=2)
|
||||
@ -199,9 +236,9 @@ def create_panel_page(hipsterfy: Hipsterfy, playlist_uri: str=None, root_url = N
|
||||
title='Hipsterfy',
|
||||
sidebar=[
|
||||
player_qr_pane, # <-- Dynamischer QR-Code ganz oben in der Sidebar
|
||||
playlist_instructions, playlist_uri, primary_item, secondary_item, additional_items, card_style,
|
||||
playlist_instructions, mode, json_upload, playlist_uri, primary_item, secondary_item, additional_items, card_style,
|
||||
cards_per_row_widget,
|
||||
create_preview_button, download_front_html_button, download_back_html_button, print_instructions
|
||||
create_preview_button, download_front_html_button, download_back_html_button, download_json_data_button, print_instructions
|
||||
],
|
||||
main=[pn.Row(front_cards_column, back_cards_column, sizing_mode='stretch_width')],
|
||||
accent_base_color='indigo',
|
||||
|
||||
Reference in New Issue
Block a user