Commit Graph
74 Commits
Author SHA1 Message Date
nessi cef785361f feat: add preferred audio/subtitle badge highlighting with localStorage persistence and mobile badge visibility controls
Add DOMContentLoaded script to apply preferred-audio/preferred-subs classes from localStorage to badges in movies/sonarr/missing tables. Add applyPreferred() function with querySelectorAll iteration over tbody rows, forEach loop through column 4/5 badges, classList.remove/add for className assignment, and parentElement.prepend() to reorder preferred badge first. Add setInterval(
2026-08-16 13:11:18 +02:00
nessi d9033cbb6e fix: add whitespace after opening brace in mobile responsive table styles media query 2026-08-16 13:08:51 +02:00
nessi 2f71f92165 feat: add legacy mobile navigation cleanup with auto-close on outside click, escape key, and window resize
Add DOMContentLoaded script to mark .nav with legacy-mobile-nav class and hide via @media(max-width:700px) display:none!important. Add closeAll() function to remove mobile-nav-open/open/mobile-drawer-open classes across body/drawer/shade/backdrop elements. Add document click handler to close drawer when clicking outside .mobile-drawer-clone/.mobile-nav/.brand on mobile. Add Escape keydown listener
2026-08-16 13:06:58 +02:00
nessi 62d19c26a1 feat: enhance PWA manifest with multi-size icons, window controls overlay, and German locale settings
Add id "/" and lang "de" fields to manifest.json. Add display_override with window-controls-overlay/standalone options and prefer_related_applications:false. Replace single media-mark.svg icon with 192x192 and 512x512 sized variants (media-mark-192.svg, media-mark-512.svg) containing gradient background, yellow strokes, and green circle with glow filter. Update service worker cache to v3 with scope "/" parameter
2026-08-16 13:05:48 +02:00
nessi c2df06dda8 feat: replace mobile navigation drawer implementation with cloned drawer approach and enhanced styling
Replace mobile-nav-backdrop/mobile-nav-close drawer with mobile-drawer-clone/mobile-drawer-shade implementation using cloned navigation content. Add DOMContentLoaded script to create aside.mobile-drawer-clone with cloned .nav innerHTML, prepended close button (×), and mobile-drawer-shade backdrop. Add @media(max-width:700px) styles for drawer with fixed positioning, min(84vw,320px) width, translate
2026-08-16 13:00:05 +02:00
nessi e84bc9c695 feat: add mobile drawer styling injection and close button inline styles for navigation drawer positioning and appearance
Add DOMContentLoaded script to inject inline fontSize/padding styles on .mobile-nav-close button. Add drawerStyle createElement with @media(max-width:700px) rules for .nav.mobile-drawer-open class with fixed positioning, 82vw/310px width, translate3d transform, and z-index:1000. Add mobile-drawer-open class toggle to closeNav/openNav functions alongside mobile-nav-open body class
2026-08-16 12:58:10 +02:00
nessi 1f658adf71 feat: add mobile navigation drawer with backdrop, close button, and responsive table layout optimizations
Add mobile-nav-backdrop/mobile-nav-close elements with DOMContentLoaded script for hamburger navigation. Add .brand click handler to open navigation on mobile (<700px) with body.mobile-nav-open class toggle. Add backdrop/close button click handlers and nav button delegation to close drawer. Style .nav as fixed left-side drawer with 310px max-width, translateX(-105%) default, and translateX(
2026-08-16 12:55:11 +02:00
nessi e3dae93d33 feat: add sticky positioning to series/missing table summaries with shadow on expand and overflow visibility
Add overflow:visible to .series-category and .missing-table containers. Add position:sticky with top:64px and z-index:30 to series/missing-series summary elements for persistent header visibility during scroll. Add box-shadow to [open] summary state for visual depth indication when expanded.
2026-08-16 12:36:25 +02:00
nessi 44fbfaded4 feat: add RAID/storage error resilience with stale data fallback and parallel SMART health checks
Add datastore_cache raid/raid_at fields for RAID status caching with 60-second fallback window. Extract smart_status() function from raid_status() to enable parallel execution. Add ThreadPoolExecutor submission for SMART checks across all RAID disks with concurrent futures. Update SMART logging to check "PASSED" status explicitly instead of regex match presence. Add stale/warning fields to datastore_snapshot() when fresh
2026-08-16 12:34:26 +02:00
nessi cc7d719465 feat: add system load average, uptime, and process count to dashboard with responsive detail cards and iconify indicators
Add os.getloadavg() to system_metrics() with (0,0,0) fallback for AttributeError/OSError. Add /proc/uptime parsing for uptime_seconds with float conversion and 0 fallback. Add /proc process counting by iterating numeric entries with OSError exception handling. Add load/uptime_seconds/processes fields to /api/system response with rounded values.

Add DOMContentLoaded script to inject #
2026-08-16 12:32:08 +02:00
nessi c15cc17142 feat: add overview and insight card icons with MutationObserver and refactor RAID countdown with reset callback
Add overview-icon/insight-icon script with iconify API integration for movie/TV/alert/download icons (overview) and check/playlist/database/monitor icons (insight). Add color-coded URL encoding (%238bc9f2 blue, %23d7adf3 purple, %23ff9e9e red, %236ae29a green for overview; blue/purple/yellow/green for insight). Add MutationObserver to reapply icons on DOM changes. Add .overview-icon img
2026-08-16 12:29:34 +02:00
nessi 87898fb2b2 feat: add live RAID status countdown timer with 5-second auto-refresh indicator
Add DOMContentLoaded script to inject #raidRefreshCountdown element next to #raidStatusBadge showing "Update in Xs" countdown. Add .raid-status-side flexbox styling with column layout, flex-end alignment, and 4px gap. Style countdown with #8d9aaa color, 10px font-size, and nowrap. Update countdown every 250ms with 5-second interval reset.
2026-08-16 12:26:11 +02:00
nessi 022c628b23 feat: add iconify icons to navigation tabs with color-coded indicators for each section
Replace text-only navigation buttons with iconify SVG icons: dashboard (view-dashboard-outline, blue), Radarr (movie-open-outline, orange), Sonarr (television-classic, cyan), missing (alert-outline, red), downloads (download-box-outline, yellow), and datastore (harddisk, blue). Add .nav-tab-icon styling with 15px dimensions, 6px right margin, and -3px vertical alignment.
2026-08-16 12:24:12 +02:00
nessi 24b2a3a12f feat: add file-based logging with hourly rotation and configurable retention period
Add LOG_FILE and LOG_RETENTION_HOURS environment variables to .env.example with defaults /data/media-max.log and 6 hours. Install TimedRotatingFileHandler with hourly rotation, 1 backup, UTF-8 encoding, and UTC timestamps. Add OSError exception handling with warning log when file logging unavailable. Add warn_on_nonzero parameter to _read_command() with default True and disable for smartctl -H calls to suppress expected
2026-08-16 12:22:06 +02:00
nessi 02a5db61be feat: add udev serial detection, comprehensive logging, and SAT fallback for SMART health checks on RAID disks
Install udev package and mount /run/udev:/host-run-udev:ro for udev by-id symlink access. Add raid_log_state global to track RAID status changes and hardware_log_once set to prevent duplicate hardware warnings. Update scan_datastore_storage() with info/error logging for scan lifecycle and disk usage. Add _read_command() debug/warning/error logging for all subprocess calls with command text
2026-08-16 12:18:40 +02:00
nessi 10eb3a4191 feat: add /host-sys volume mount and HOST_SYS_PATH environment variable for sysfs serial fallback and SMART health detection
Add HOST_SYS_PATH=/host-sys to .env.example and app.py config with /host-sys default. Update _device_serial() to check HOST_SYS_PATH/class/block and HOST_SYS_PATH/block before fallback /sys paths for serial reads. Update raid_status() SMART regex to match both "SMART overall-health self-assessment test result" and "SMART Health Status" with case-insensitive flag for NVMe/SSD compatibility. Add /
2026-08-16 12:14:10 +02:00
nessi f7638dd5d5 feat: add sysfs serial fallback for RAID disks and responsive disk grid layout with improved styling
Add _device_serial() to read disk serials from /sys/class/block/{name}/device/serial and /sys/block/{name}/device/serial when lsblk cannot expose them in Docker containers. Update raid_status() to use sysfs fallback before defaulting to "—" for missing serials. Add .raid-disks 2-column grid with 6px gap, .raid-disk 7px/9px padding, .raid-disk small 1px top margin, and .raid-smart 85% opacity. Add mobile
2026-08-16 12:11:47 +02:00
nessi 0c922d4f5d feat: add human-readable RAID recovery formatting with German time units and improved member detection from mdstat
Add format_transfer_rate() to convert mdstat rates (e.g., 133628K/sec) into readable values like "130.5 MB/s" using 1024-based units. Add format_remaining_time() to convert mdstat durations (e.g., 450.1min) into compact German format like "7 Std. 30 Min." with day/hour/minute components. Update raid_status() to parse member devices directly from array_line in /proc/mdstat to avoid cross
2026-08-16 12:10:17 +02:00
nessi 5ddf506f20 feat: add datastore view with storage categories, RAID status monitoring, and live recovery tracking
Add scan_datastore_storage() to walk DATASTORE_PATH and categorize media by directory structure (movies/series/anime/kdrama/downloads/other) with size/file counts. Add raid_status() to parse /proc/mdstat and mdadm --detail for RAID level, active/failed devices, and recovery progress. Add /api/datastore endpoint with 15-minute cache for storage scans and live RAID updates. Install mdadm/util-linux/
2026-08-16 11:55:45 +02:00
nessi 6f0c222e93 feat: add section headings for movies and series in missing view with language-aware labels and styled indicators
Add addMissingSections() function to inject "Filme ohne Deutsch"/"Movies without German" heading before #missingMovies table and "Serien ohne Deutsch"/"Series without German" before first .missing-series element. Style .missing-section-heading with 9px border-radius, uppercase 12px/800 text, 10px/13px padding, and glowing dot indicator. Apply blue gradient/border for .movies section
2026-08-15 13:39:06 +02:00
nessi 6b010c8ade feat: split downloads view into active and queued sections with separate tables and dynamic row distribution
Replace single downloads table with two-section layout: "Aktive Downloads" for downloading items and "Weitere Queue-Einträge" for queued/paused items. Inject dual-table HTML structure with section headers showing item counts. Update renderDownloads() to distribute rows by status into activeDownloadsBody/otherDownloadsBody with fallback empty states. Add .download-table grid layout, .download-section styling
2026-08-15 13:36:42 +02:00
nessi c8d2b9f454 feat: add dynamic favicon injection script and update dashboard eyebrow from "MEDIA CONTROL CENTER" to "MEDIA MAX"
Add DOMContentLoaded script to dynamically inject shortcut icon link element with media-mark.svg if not already present. Update dashboard hero eyebrow text from "MEDIA CONTROL CENTER" to "MEDIA MAX" for consistent branding.
2026-08-15 13:11:31 +02:00
nessi 42ed29ac51 refactor: rebrand application from "Radarr Language Dashboard" to "Media Max" across all files
Update project name from "Radarr Language Dashboard v2" to "Media Max" in README.md, docker-compose.yml service/container names, app.py logger name and service definition, manifest.json name/short_name/description, and templates/index.html title and header elements. Update docker exec command example in README to use new container name.
2026-08-15 13:06:54 +02:00
nessi ceb4dfe120 feat: add missing table styling with bordered layout, header background, and consistent padding for improved visual structure
Add .missing-table wrapper with 10px padding and style nested table with 100% width, 8px bottom margin, border, 10px border-radius, and overflow:hidden. Set thead th with 38px height, 12px horizontal padding, #2d3540 background, and right borders (except last-child). Set .missing-series summary min-height to 42px with flex center alignment. Add duplicate style block at end
2026-08-15 13:01:44 +02:00
nessi 3874415dc3 feat: add dynamic dashboard missing counter sync with season zero toggle and visibility filtering
Add syncDashboardMissingCounter() function to update #dashboardMissing with count of visible missing items (movies + non-hidden episodes excluding season-zero-hidden). Call on page load and after #showSeasonZero change with setTimeout(0) to reflect filtered totals in dashboard widget.
2026-08-15 12:55:52 +02:00
nessi 844227ba67 feat: add dynamic missing media heading translation with language toggle support and disable table row animations
Add updateMissingHeading() function to toggle #missingMovies heading between 'Media'/'Medien' based on document.documentElement.lang. Call on page load and after #languageToggle click with setTimeout(0) to ensure DOM updates. Add .missing-table styles with table-layout:fixed and transform:none/animation:none on tbody tr to disable row animations and hover effects.
2026-08-15 12:55:07 +02:00
nessi d0c29b7a38 feat: add season zero visibility toggle in settings with dynamic filtering for Sonarr and missing episodes views
Add showSeasonZero checkbox in settings panel with toggle styling (42x23px switch, green when active). Implement applySeasonZeroPreference() to filter S00E episodes via .season-zero-hidden class and hide empty series with .season-zero-empty. Update missing count in nav badge and stats to exclude hidden season zero episodes. Add dynamic hint text toggle between "eingeblendet"/"ausgeblendet". Remove season zero exclusion from is_german_review_candidate() in app.py to
2026-08-15 12:53:19 +02:00
nessi 77a36cae55 feat: add transparent toolbar styling for radarr view with reduced padding and enhanced input backgrounds
Add .view#radarr.active with 12px row-gap and style .toolbar with 0/10px padding, transparent background/border, and no shadow. Style toolbar inputs/selects with rgba(42,46,54,.82) background, #454d59 border, and #303640 focus state for improved visual integration.
2026-08-15 12:50:51 +02:00
nessi 4762952e11 feat: add category-specific styling for Sonarr series groups and missing episodes table with enhanced visual hierarchy
Add .view#sonarr with 4px bottom padding and transparent #seriesList background. Style .series-category containers with 18px bottom margin, 13px border-radius, gradient backgrounds, and 10px/28px shadow. Add category headings with 13px/16px padding, bottom border, gradient background, and 3px left accent border. Style nested .series with 8px/10px margins, 9px border-radius, reduced shadows, and hover state
2026-08-15 12:49:39 +02:00
nessi 8312294a1d feat: add fixed 34px height to toolbar and stats with vertical alignment in radarr grid layout, restore auto height on mobile
Set explicit 34px height on .view#radarr>.toolbar (margin-bottom:0) and .view#radarr>.stats (align-self:stretch, align-items:stretch) with .stat children using flexbox center alignment for consistent desktop row height. Restore auto height and initial alignment in mobile breakpoint to preserve responsive wrapping behavior.
2026-08-15 12:46:24 +02:00
nessi c090431f01 feat: add view visibility toggle system with .active class for tab content display
Replace static #radarr grid with .view#radarr that displays:none by default and shows grid layout when .active class is applied. Update mobile breakpoint to use .view#radarr.active selector for responsive block layout, enabling dynamic tab switching without page reloads.
2026-08-15 12:44:45 +02:00
nessi 5b0289a383 feat: rename #movies grid container to #radarr for consistent service-specific naming
Rename CSS selector from #movies to #radarr in both desktop grid layout and mobile responsive breakpoint to align with service-specific naming convention used throughout the application.
2026-08-15 12:43:07 +02:00
nessi f449e2d2f0 feat: add two-column grid layout for movies tab with toolbar and stats side-by-side on desktop
Add #movies grid container with toolbar in column 1, stats in column 2 (nowrap, aligned center), and table spanning both columns. Collapse to single-column block layout on mobile (<760px) to maintain responsive behavior.
2026-08-15 12:41:44 +02:00
nessi 0905f4fa75 feat: reduce toolbar padding and input height with adjusted border radius and shadow for more compact layout
Decrease toolbar vertical padding from 10px to 1px, reduce border-radius from 10px to 8px, adjust box-shadow from 0 10px 28px to 0 8px 20px, and decrease gap from 9px to 8px. Set explicit input/select height to 30px with 5px/9px padding for consistent compact sizing.
2026-08-15 12:40:25 +02:00
nessi cdfa29d25f feat: replace Simple Icons CDN with Iconify API for SABnzbd, Seerr, Prowlarr, Easynews, Bazarr, and Lingarr service icons
Replace Simple Icons URLs with Iconify API endpoints for SABnzbd (mdi:download-box), Seerr (mdi:movie-search), Prowlarr (mdi:radar), Easynews (mdi:cloud-download), Bazarr (mdi:subtitles), and Lingarr (mdi:forum) while preserving original brand colors via color query parameters. Keep Simple Icons for Radarr, Sonarr, Jellyfin, qBittorrent, and LibreTranslate.
2026-08-15 12:39:53 +02:00
nessi e49216dca5 feat: add category-based grouping for Sonarr series with anime and K-drama tag detection
Add tag fetching from Sonarr API and category_for() function to classify series based on normalized tags (anime, kdrama, standard). Parse tag labels/names into normalized strings removing non-alphanumeric characters for matching. Add category and category_label fields to series groups.

Update index route to build series_categories list grouping series by category key (anime/Anime, kdrama/K-Dramen, standard/Standard) and pass
2026-08-15 12:37:58 +02:00
nessi 2b8b0cd5e9 feat: move navigation tabs from main content to header with responsive mobile layout and icon-only display on small screens
Add header-nav class to mainNav and move it before headerActions in header. Add dynamic stylesheet hiding .head-title/.head-sub, styling .header-nav with flex layout, 4px gap, 22px left margin, transparent background, and 8px/11px button padding. Add responsive breakpoints at 850px (scrollable nav with hidden scrollbar, max-width calc(100vw - 250px)) and 560px (icon-only buttons
2026-08-15 12:35:13 +02:00
nessi e508035474 feat: replace custom SVG service icons with official brand icons from Simple Icons CDN
Add officialServiceIcons dictionary mapping service keys to Simple Icons CDN URLs for Radarr, Sonarr, SABnzbd, Jellyfin, Seerr, Prowlarr, Easynews, qBittorrent, Bazarr, Lingarr, and LibreTranslate. Override serviceIconSvg entries with img tags loading brand icons. Add inline styles to SVG fallback icons (19px, stroke styling) and img elements (20px, object-fit contain). Add 500ms interval to reapply icon styles after DOM
2026-08-15 12:34:01 +02:00
nessi d69f82d995 feat: add service status monitoring to dashboard with parallel health checks for 14 services
Add SERVICE_DEFINITIONS list with Radarr, Sonarr, SABnzbd, Jellyfin, Seerr, Prowlarr, Easynews as Indexer, qBittorrent, Bazarr, Lingarr, LibreTranslate, Sonarr-Prowlarr Proxy, Radarr-Prowlarr Proxy, and Dashboard. Add check_service() to perform HTTP/API health checks with configurable timeout. Add refresh_services() to run checks in parallel using service_check_executor ThreadPoolExecutor with 16 workers.
2026-08-15 12:28:14 +02:00
nessi a90b516f49 fix: replace glob() with iterdir() in external_subtitle_files() to handle square brackets in media filenames
Replace glob pattern matching with iterdir() + startswith() filtering to avoid glob interpreting square brackets (e.g., [Bluray-1080p]) as pattern characters. Add OSError exception handling to return empty list when directory access fails.
2026-08-14 14:32:28 +02:00
nessi 04ca437054 feat: merge external subtitle files with embedded subtitle languages in media row display
Update media_row() to combine embedded subtitle_languages from ffprobe with external subtitle files detected via external_subtitle_languages(). Apply unique_langs() to deduplicate language codes when local_path is available, ensuring both .mkv internal subs and external .srt/.ass files appear in the subtitle language list.
2026-08-14 14:30:22 +02:00
nessi ba906d4748 feat: add yellow glow styling to download navigation badge for improved visibility
Add download-nav-count specific styles with yellow background (#f4c430), darker text (#17191d), lighter border (#ffd95a), and glowing box-shadow for visual prominence matching dashboard disk icon color scheme.
2026-08-14 13:39:18 +02:00
nessi 10bf5c32d3 feat: add active download count badge to downloads navigation tab with auto-hide when zero
Add download-nav-count span to downloads nav button with hidden class and downloadNavCount id. Update renderDownloads() to extract active_count from data, update badge text content, and toggle hidden class based on count. Add fetchDownloads() call on page load to populate initial badge state.
2026-08-14 13:33:10 +02:00
nessi 61d65d5988 feat: add external subtitle file detection with language parsing and cache invalidation on subtitle changes
Add EXTERNAL_SUBTITLE_EXTENSIONS set with common subtitle formats (.srt, .ass, .ssa, .vtt, .sub, .idx, .sup). Add external_subtitle_files() to glob subtitle files matching media stem and external_subtitle_languages() to parse language codes from filenames (de/deu/ger/german/deutsch, en/eng/english, fr/fra/fre/french/französisch, es/spa/spanish/spanisch, it/ita/italian/italienisch).

Update run_ffprobe() to merge external subtitle
2026-08-14 13:25:37 +02:00
nessi b5365170fb feat: add parallel file scanning with dedicated executor and support for scanning all sources simultaneously
Add scan_executor ThreadPoolExecutor with 4 workers for parallel file scanning. Import as_completed from concurrent.futures to process scan results. Replace sequential scan_one() loop with parallel futures submission and result collection using as_completed().

Update /api/rescan endpoint to accept "all" source parameter for scanning both Radarr and Sonarr simultaneously. Fix cache deletion
2026-08-14 13:22:15 +02:00
nessi 644c54a6f6 feat: refactor disk name layout to use CSS Grid with icon spanning both rows and add disk path support
Change disk-name from flex to grid layout with 2-column template (20px icon + flexible content). Update ::before icon to span both rows using grid-row:1/span 2 with zero margin. Add grid-template-rows auto/auto with conditional single row when disk-path is missing. Style disk-path in column 2 row 2 with nowrap and hide when empty. Set min-width:92px and line-height:1.1 for consistent sizing.
2026-08-14 11:10:01 +02:00
nessi bcefa02c32 feat: add dashboard insights section with media statistics and status cards showing file counts, missing items, and monitoring status
Add dashboard_stats dictionary to index() route calculating movie/episode totals, available files, missing items, and downloading counts. Pass stats to template for dashboard insights display.

Add dashboard-insights CSS grid with 4 insight cards showing media availability (movies/episodes), monitoring status, and live updates. Each card has color-coded icon with
2026-08-14 11:08:31 +02:00
nessi f63ba5381b feat: add PWA support with service worker, manifest, and auto-scan configuration for offline capability and mobile installation
Add manifest.json with app metadata, theme colors, and icon configuration for installable PWA. Add service worker (sw.js) with shell caching strategy for offline support - caches static assets on install, cleans old caches on activate, and implements network-first fetch with cache fallback for non-API requests.

Update index.html with PWA meta tags (theme-color, mobile
2026-08-13 22:03:53 +02:00
nessi 0d48c9eef2 fix: remove redundant display:flex from dashboard-view and add explicit display:none rule for inactive dashboard view
Remove duplicate display:flex declaration from .dashboard-view base class (already inherited from .view.active). Add .view.dashboard-view:not(.active) display:none rule to ensure dashboard view is properly hidden when inactive, preventing layout issues with flex-direction:column on non-active views.
2026-08-13 21:59:41 +02:00
nessi cce2f9fbb0 feat: add decorative icons to dashboard metrics with color-coded backgrounds for CPU, RAM, and disk usage indicators
Add ::before pseudo-elements with inline-grid centering to meter and disk-name elements. Style CPU meter with blue circular icon (◔), RAM meter with purple stacked icon (▤), and disk labels with yellow bar icon (▰). Each icon has matching semi-transparent background and colored text. Update dashboard view display to flex and align icon containers.
2026-08-13 16:43:30 +02:00