Commit Graph
101 Commits
Author SHA1 Message Date
nessi 5d7e452aaf feat: add non-blocking datastore refresh with dedicated lock and improve service worker offline handling
Add datastore_refresh_lock to prevent concurrent refresh operations. Extract refresh_datastore_storage() function with non-blocking lock acquisition using acquire(blocking=False). Update datastore_snapshot() to spawn background thread for refresh when cache is stale but return immediately with cached data. Add offline fallback HTML page to service worker for navigate requests with 503 status for
2026-08-21 20:55:19 +02:00
nessi 1882d4e137 feat: add data-title attribute to series details elements and optimize series filtering with display:none for better performance
Add data-title="{{ group.title|lower }}" to details.series elements. Update applySeries() to read series title from detail.dataset.title instead of parsing summary textContent. Add explicit display:none style to hidden rows and details alongside hidden class for improved rendering performance
2026-08-21 20:49:47 +02:00
nessi a2f411c578 feat: extend Radarr toolbar styling to Sonarr series-toolbar with matching background/border/focus states
Apply row-gap:12px to .view#sonarr.active alongside #radarr. Extend toolbar padding/background/border/box-shadow rules to .view#sonarr>.series-toolbar. Add .series-toolbar input/select to background:rgba(42,46,54,.82) and border-color:#454d59 rules. Include .series-toolbar input:focus/select:focus in background:#303640 focus state
2026-08-21 20:08:37 +02:00
nessi 8ec43481c7 feat: add series filtering toolbar with search/audio/subtitle/state filters and data attributes for episode rows
Add toolbar with seriesSearch input and seriesAudioFilter/seriesSubFilter/seriesStateFilter selects to #sonarr section. Add data-title/data-audio/data-subs/data-state attributes to episode table rows including series title in data-title. Implement applySeries() function to filter episodes by search query, audio language, subtitle language, and state with series/category hiding when no
2026-08-21 20:01:44 +02:00
nessi 34af0a4ad9 feat: add language detection from subtitle track titles and scanner versioning to invalidate stale cache entries
Add SCANNER_VERSION constant set to 2 and include in run_ffprobe() output. Create language_from_text() helper to infer language from track titles using token matching with German/English/Japanese/Korean/French/Spanish/Italian aliases. Apply language_from_text() to subtitle streams when ffprobe reports "und" language tag by checking title field. Update cached() to validate scanner_version matches
2026-08-21 19:29:25 +02:00
nessi 67e588bfc8 feat: add scan status indicator to missing-German view and update poll() to track missing source status
Add #missingStatus span to missing section stats with "Scan wird vorbereitet …" text. Change missing section data-source from "radarr" to "missing". Update poll() function to select #missingStatus element and call updateScanStatus() for data.missing when element exists
2026-08-21 15:42:29 +02:00
nessi dfbeec4dc0 feat: add "Nur Ohne Deutsch" scan option to rescan only current missing-German entries without clearing cache
Add "missing" job state to jobs dict with idle/total/done/error tracking. Update start_scan() to handle "missing" source by filtering radarr_rows() and sonarr_groups() for is_german_review_candidate() entries without has_german_track(). Skip cache deletion for missing-German scan in api_rescan() with comment explaining cache preservation. Add "Nur Ohne Deutsch" option to scanSource select
2026-08-21 15:36:27 +02:00
nessi 58c8ad3bcc feat: add mobile performance optimizations with scroll-behavior and animation disabling for screens below 700px
Add media query to disable smooth scrolling with scroll-behavior:auto on html. Remove backdrop-filter from header/dashboard/cards/panels/tables and box-shadow from panels. Disable transform/animation on table rows and series items with transform:none/animation:none. Add contain:layout paint to tablewrap with overscroll-behavior-x:contain and contain:layout style to view for performance
2026-08-17 19:42:54 +02:00
nessi f5d8b4189c chore: add static directory to Docker image build with COPY instruction
Add COPY static ./static to Dockerfile to include static assets (CSS/JS/images) in container image alongside templates directory
2026-08-17 19:42:10 +02:00
nessi 7469ec7b9f feat: add mobile navigation hide rules for screens below 700px with pointer-events and visibility overrides
Add media query to hide legacy-mobile-nav and mobile-drawer-open with display:none/visibility:hidden/pointer-events:none. Set mobile-nav-backdrop display:none and mobile-drawer-clone/mobile-drawer-shade pointer-events:none when not open
2026-08-17 19:40:14 +02:00
nessi be68853a74 refactor: replace SVG icons with PNG format in manifest and update apple-touch-icon reference
Replace media-mark-192.svg/media-mark-512.svg with .png equivalents in manifest.json icon entries and update image/svg+xml to image/png MIME types. Add media-mark-192.png and media-mark-512.png binary assets. Update sw.js SHELL array to cache .png files instead of .svg. Change apple-touch-icon href from media-mark.svg to media-mark-192.png in index.html head
2026-08-17 19:38:38 +02:00
nessi 2096fc5d11 chore: bump service worker cache version to v5 and add manifest cache-busting parameter
Increment CACHE_NAME from media-max-shell-v4 to v5 in sw.js. Update service worker registration query parameter from v=4 to v=5 in index.html. Add v=5 cache-busting parameter to manifest.json link tag. Remove duplicate service worker registration script block from template footer
2026-08-17 19:36:04 +02:00
nessi 14a4c6ce7b docs: convert README to German with comprehensive feature documentation and deployment guide
Replace English README with German documentation covering all features: Radarr/Sonarr media tracking with quality/audio/subtitle analysis, SABnzbd download monitoring with language detection, dashboard with service status/CPU/RAM/storage/I/O pressure/library stats, datastore with categories/capacity/RAID status/rebuild progress/SMART/temperature/serial numbers. Add detailed configuration sections for path mapping between Radarr/Sonarr and container volumes
2026-08-17 19:35:21 +02:00
nessi 806886da46 feat: expand language detection patterns with 8 additional languages and enhanced token matching
Add Italian/Portuguese/Korean/Chinese/Dutch/Russian to patterns list with standard/ISO 639-2 codes (ita/por/pt br/kor/chi/zho/nld/ned/rus). Enhance German patterns with " ger "/" deu " tokens and French with " français "/" fre " variants. Add corresponding language codes to codes dict (it/pt/ko/zh/nl/ru). Format patterns list with multi-line structure for readability
2026-08-17 19:33:39 +02:00
nessi ffd995e50b refactor: wrap RAID and I/O pressure panels in flex column container with stretch alignment and remove bottom margin from I/O panel
Add .datastore-grid align-items:stretch and .datastore-right-stack flex column with gap:12px/min-height:100%. Set .datastore-right-stack .raid-panel flex:1/margin:0 and #ioPressurePanel flex:0 0 auto. Remove margin:0 0 12px from #ioPressurePanel base rule. Add DOMContentLoaded script to create datastore-right-stack div, replaceChild raid panel with stack in grid, and append pressure/
2026-08-17 19:31:08 +02:00
nessi 75f6de91b6 refactor: move I/O pressure panel into RAID section and capacity panel into categories section with DOM restructuring script
Remove max-width:calc(50% - 6px) from #ioPressurePanel and set max-width:none. Add .datastore-grid>.datastore-panel>.datastore-capacity and .datastore-grid>.raid-panel>#ioPressurePanel margin/padding rules. Add DOMContentLoaded script to select datastore root/grid/capacity/pressure elements, identify categories and raid sections from grid.children[0]/[1], and prepend capacity to
2026-08-17 19:28:14 +02:00
nessi d4c24f02d4 feat: add smart_serial() function to extract manufacturer serial numbers from SMART data with fallback chain and parallel execution
Add smart_serial() function with smartctl -i command execution, fallback to -d sat mode, and Serial Number: field regex extraction with WWN/0x prefix filtering to prefer physical serial over logical identifiers. Add serial_futures dict with service_check_executor.submit() calls for parallel serial reads alongside smart_futures/temperature_futures. Update raid_status() disk
2026-08-17 19:27:21 +02:00
nessi 02449a80de refactor: replace dynamic temperature injection with static rendering in RAID disk template and add I/O pressure panel with PSI metrics
Remove DOMContentLoaded script for raid-temperature DOM manipulation with MutationObserver and replace with inline disk.temperature rendering in renderDatastore() RAID devices map. Add #ioPressurePanel CSS with 50% max-width/12px margin/14px padding and io-pressure-bars grid with 42px/48px/1fr columns. Add DOMContentLoaded script to create ioPressurePanel section
2026-08-17 19:25:30 +02:00
nessi b275164be9 feat: add Linux PSI I/O pressure monitoring with real-time dashboard panel and auto-refresh on DOM mutations
Add io_pressure() function to parse /proc/pressure/io with line splitting, key-value extraction from some/full metrics, and OSError/ValueError exception handling returning available:False on failure. Add io_pressure() call to datastore_snapshot() return dict. Add DOMContentLoaded script to create #ioPressurePanel section with datastore-panel/io-pressure-panel classes, innerHTML with I/O-
2026-08-17 19:21:49 +02:00
nessi c6c2437732 refactor: prioritize Temperature_Celsius raw value extraction before unit-based parsing in SMART temperature detection
Swap Temperature_Celsius to first position in ordered list before Current Drive Temperature/Drive Temperature/Temperature: patterns. Add Temperature_Celsius.*-\s*(-?\d{1,3}) regex to extract raw value from attribute line with 0-150 range validation before falling back to explicit unit pattern matching to improve accuracy when both formatted and raw temperature values are present
2026-08-16 20:13:34 +02:00
nessi 01b6a7fd4e refactor: prioritize Current Drive Temperature and Temperature: field patterns over Temperature_Celsius in SMART parsing and reorder -x before -A in sat mode commands
Update temperature line matching to first search for Current Drive Temperature/Drive Temperature/Temperature: patterns, then append Temperature_Celsius lines, before falling back to generic temperature/airflow keywords. Swap smartctl -x -d sat command before -A -d sat in fallback chain to improve attribute detection on SATA drives behind
2026-08-16 20:12:28 +02:00
nessi c2e2f7552f feat: prioritize Temperature_Celsius over Airflow_Temperature in SMART parsing to prefer physical drive temperature
Reorder temperature line matching to first search for Temperature_Celsius/Drive_Temperature/Current Drive Temperature attributes before falling back to generic temperature/airflow keywords. Add ordered list construction with preferred patterns first, then append remaining temperature lines, to ensure physical drive temperature is selected over airflow sensor when both are present in
2026-08-16 20:11:34 +02:00
nessi f820a99c7c refactor: reorder smartctl command fallback chain to prioritize -d sat mode before standard commands
Move -d sat variants of -A and -x commands to front of fallback chain before non-sat equivalents in smart_temperature() function to improve compatibility with SATA drives behind USB/RAID controllers
2026-08-16 20:09:53 +02:00
nessi 9373e93e7f feat: improve SMART temperature parsing with multi-command fallback and enhanced line-based extraction logic
Replace regex pattern matching with extract() helper that iterates through output lines, filters for temperature/airflow keywords, and extracts values using explicit unit patterns (°C/Celsius/degrees C) with 0-150 range validation or fallback to last plausible number in line. Add smartctl -x/-x -d sat commands to fallback chain after -A/-A -d sat attempts with early return on first successful
2026-08-16 20:08:29 +02:00
nessi 310b36317e feat: add drive temperature monitoring with async updates and multi-pattern SMART parsing
Add smart_temperature() function with smartctl -A command execution, fallback to -d sat mode, and regex patterns for Temperature_Celsius/Airflow_Temperature_Cel/Drive_Temperature/Current Drive Temperature attributes plus Temperature: field parsing with 1-3 digit capture and °C formatting. Add temperature_futures dict with service_check_executor.submit() calls for parallel temperature reads alongside smart_futures. Add disk["
2026-08-16 20:07:19 +02:00
nessi 71752483f6 feat: add error_summary() helper to replace verbose exception tracebacks with concise German error messages
Add error_summary() function to format exceptions as single-line log messages with 240-char limit and special handling for requests.RequestException as "Dienst nicht erreichbar". Replace log.exception() calls with log.error() using error_summary() across service_monitor, scan_datastore_storage, sab_downloads, scan_one, start_scan, index, downloads, system, and datastore endpoints. Update user-facing error messages to German "momentan nicht verfügbar/
2026-08-16 17:31:21 +02:00
nessi 5723a5d2a0 feat: add service worker route with cache-control headers and update PWA manifest icons for proper maskable support
Add /sw.js route with send_from_directory to serve service worker from root scope with Service-Worker-Allowed:/ and Cache-Control:no-cache headers. Add navigator.serviceWorker.register() script to index.html with load event listener and scope:/ parameter. Update service worker cache to v4 with media-mark-192.svg/media-mark-512.svg additions to SHELL array.

Update manifest.json icons
2026-08-16 17:29:21 +02:00
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