Initial commit: modular Streamlit media viewer with Jellyfin, SSH tools, and docs
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user