initial version

This commit is contained in:
2025-07-20 22:14:06 +02:00
parent 62166624dc
commit 5a0727abac
3 changed files with 145 additions and 35 deletions

View File

@ -31,33 +31,51 @@ class Hipsterfy(object):
class HipsterfyPlaylistItem(object):
def _generate_qr_code_base64(self, url):
qr: qrcode.QRCode[PilImage | PyPNGImage] = qrcode.QRCode(box_size=2, border=2)
qr: qrcode.QRCode[PilImage | PyPNGImage] = qrcode.QRCode(box_size=6, border=6)
qr.add_data(url)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
buffered = BytesIO()
img.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue()).decode()
return f'<img src="data:image/png;base64,{img_str}" alt="QR Code" style="margin-top:4px;"/>'
img_html = f'<img src="data:image/png;base64,{img_str}" alt="QR Code" style="margin-top: 12px; width: 150px; height: 150px; border-radius: 18px; box-shadow: 0 2px 8px rgba(0,0,0,0.15);"/>'
def generate_hipsterfy_front_card(self, include_preview:bool = False):
return img_html
def generate_hipsterfy_front_card(self, include_preview:bool = False, print_mode:bool = False):
# generates the square front card only with the centered qr code
preview_html = self.embed_html if include_preview else ""
if not self._qr_html:
return ""
if print_mode:
# Minimalistisches Layout für Druck: kein Hintergrund, kein Schatten, kein Rahmen
card_style = """
width: 300px; height: 300px;
border: 1.5px;
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
background: none;
margin: 18px;
box-shadow: none;
transition: none;
"""
else:
card_style = """
width: 300px; height: 300px;
border: 1.5px solid #222;
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #f9f9f9 60%, #e0e0e0 100%);
margin: 18px;
box-shadow: 0 6px 24px rgba(0,0,0,0.13), 0 1.5px 4px rgba(0,0,0,0.07);
transition: box-shadow 0.2s;
"""
return f"""
<div style="
width: 300px; height: 300px;
border: 1.5px solid #222;
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #f9f9f9 60%, #e0e0e0 100%);
margin: 18px;
box-shadow: 0 6px 24px rgba(0,0,0,0.13), 0 1.5px 4px rgba(0,0,0,0.07);
transition: box-shadow 0.2s;
">
<div style="{card_style}">
<div style="text-align: center;">
<div style="margin-top: 8px;">
{self._qr_html}
@ -65,13 +83,13 @@ class HipsterfyPlaylistItem(object):
</div>
<div style="margin-top: 18px; color: #888; font-size: 0.95em;">
<span>Scan for Spotify Preview</span>
<span>Scan Code to play Sample</span>
</div>
</div>
</div>
"""
def generate_hipsterfy_back_card(self, primary_property, secondary_property, additional_properties:List[str]=None, album_cover_gb:bool = True):
def generate_hipsterfy_back_card(self, primary_property, secondary_property, additional_properties:List[str]=None, album_cover_gb:bool = True, print_mode:bool = False):
# generates the back card with primary and secondary property and additional properties
additional_html = ""
if additional_properties:
@ -109,8 +127,8 @@ class HipsterfyPlaylistItem(object):
transition: box-shadow 0.2s;
">
<div style="text-align: center; padding: 24px 18px 18px 18px; background: rgba(0,0,0,0.35); border-radius: 12px;">
<h3 style="margin: 0 0 8px 0; font-size: 1.35em; color: #fff; text-shadow: 0 2px 8px #000;">{getattr(self, primary_property)}</h3>
<p style="margin: 0 0 12px 0; font-size: 1.1em; color: #e0e0e0; text-shadow: 0 1px 4px #000;">{getattr(self, secondary_property)}</p>
<h3 style="margin: 0 0 8px 0; font-size: 1.35em; color: #fff; text-shadow: 0 2px 8px #000;">{getattr(self, primary_property)}</h3>
{additional_html}
</div>
</div>