Illustrate monthly reports and add viewing pattern breakdowns
This commit is contained in:
@@ -142,6 +142,34 @@ def completed_month(month: str | None) -> str:
|
||||
return period["month"]
|
||||
|
||||
|
||||
async def illustrated_recap(report, account, public_url, unsubscribe_url, *, preview=False, **kwargs):
|
||||
"""Embed only signed artwork from this account's report; missing art is optional."""
|
||||
import base64
|
||||
import re
|
||||
from .insights_artwork import get_artwork
|
||||
runtime = get_runtime_settings()
|
||||
images = []
|
||||
report = {**report, "top_titles": [dict(row) for row in report.get("top_titles", [])]}
|
||||
|
||||
async def picture(index, row):
|
||||
match = re.fullmatch(r"/insights/artwork/([a-f0-9]{32})\?token=([0-9]+\.[a-f0-9]{64})", row.get("artwork_url") or "")
|
||||
if not match:
|
||||
return
|
||||
try:
|
||||
data, mime = await get_artwork(account, runtime, *match.groups())
|
||||
cid = f"recap-title-{index}@magent"
|
||||
row["email_artwork"] = f"data:{mime};base64,{base64.b64encode(data).decode()}" if preview else f"cid:{cid}"
|
||||
images.append({"cid": cid, "data": data, "subtype": mime.split("/")[1]})
|
||||
except Exception:
|
||||
pass # An unavailable poster must never prevent a personal report.
|
||||
|
||||
await asyncio.gather(*(picture(i, row) for i, row in enumerate(report["top_titles"][:3])))
|
||||
rendered = mail.render_recap(report, account["username"], public_url, unsubscribe_url, **kwargs)
|
||||
if not preview:
|
||||
rendered["inline_images"] = images
|
||||
return rendered
|
||||
|
||||
|
||||
async def preview(user: dict, month: str | None) -> dict:
|
||||
account = current_account(user)
|
||||
selected = completed_month(month)
|
||||
@@ -156,8 +184,8 @@ async def preview(user: dict, month: str | None) -> dict:
|
||||
raise RecapError("Your report is temporarily unavailable. Please try again shortly.", 502) from exc
|
||||
if report["state"] != "ready":
|
||||
raise RecapError("Connect Jellystat and link your Jellyfin account to preview your recap.")
|
||||
return {"month": selected, "email": account.get("email"), **mail.render_recap(
|
||||
report, account["username"], config["public_url"], config["public_url"] + "/profile#monthly-recaps")}
|
||||
return {"month": selected, "email": account.get("email"), **await illustrated_recap(
|
||||
report, account, config["public_url"], config["public_url"] + "/profile#monthly-recaps", preview=True)}
|
||||
|
||||
|
||||
def queue_test(user: dict, month: str | None, request_id: str) -> dict:
|
||||
@@ -200,7 +228,7 @@ async def process_delivery(delivery: dict) -> None:
|
||||
if report["state"] != "ready" or (report["is_partial"] and delivery["kind"] != "on_demand"):
|
||||
raise mail.DeliveryError("failed", "A complete personal report is not available.")
|
||||
unsubscribe = f"{delivery['public_url']}/email-recaps#" + urlencode({"action": "unsubscribe", "token": sub["unsubscribe_token"]})
|
||||
rendered = mail.render_recap(report, account["username"], delivery["public_url"], unsubscribe, test=delivery["kind"] == "test", requested=delivery["kind"] == "on_demand")
|
||||
rendered = await illustrated_recap(report, account, delivery["public_url"], unsubscribe, test=delivery["kind"] == "test", requested=delivery["kind"] == "on_demand")
|
||||
|
||||
def before_data():
|
||||
eligible_delivery(delivery)
|
||||
|
||||
Reference in New Issue
Block a user