Files
manage/src/media_library_viewer/ui/library.py
T

52 lines
1.8 KiB
Python

"""Jellyfin library browser UI pieces."""
from __future__ import annotations
from typing import Any
import pandas as pd
import streamlit as st
from media_library_viewer.domain.media import media_streams
from media_library_viewer.utils import ticks_to_minutes
def show_item_card(client, item: dict[str, Any]) -> None:
"""Render a poster card in the Jellyfin library grid."""
try:
st.image(client.image_url(item["Id"]), use_container_width=True)
except Exception:
st.caption("No image")
st.markdown(f"**{item.get('Name', 'Untitled')}**")
meta = [item.get("Type", "")]
if item.get("ProductionYear"):
meta.append(str(item["ProductionYear"]))
minutes = ticks_to_minutes(item.get("RunTimeTicks"))
if minutes:
meta.append(f"{minutes} min")
st.caption(" - ".join([m for m in meta if m]))
if st.button("Open", key=f"open-{item['Id']}"):
st.session_state["selected_item_id"] = item["Id"]
def show_item_detail(client, item: dict[str, Any]) -> None:
"""Render detailed Jellyfin item metadata for the selected poster card."""
st.header(item.get("Name", "Untitled"))
left, right = st.columns([1, 2])
with left:
st.image(client.image_url(item["Id"]), use_container_width=True)
with right:
st.write(item.get("Overview") or "No overview.")
st.write("**Path:**", item.get("Path") or "Not exposed by Jellyfin")
st.write("**Genres:**", ", ".join(item.get("Genres", [])) or "-")
st.write("**Rating:**", item.get("CommunityRating") or "-")
st.write("**Official rating:**", item.get("OfficialRating") or "-")
streams = media_streams(item)
if streams:
st.subheader("Jellyfin media streams")
st.dataframe(pd.DataFrame(streams), use_container_width=True)
with st.expander("Raw Jellyfin JSON"):
st.json(item)