Skip to content

[pull] main from mhdzumair:main#269

Merged
pull[bot] merged 14 commits into
geek-cookbook:mainfrom
mhdzumair:main
Jun 1, 2026
Merged

[pull] main from mhdzumair:main#269
pull[bot] merged 14 commits into
geek-cookbook:mainfrom
mhdzumair:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Jun 1, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

mhdzumair and others added 14 commits June 1, 2026 09:34
- store_external_id: add created_at = NOW() to INSERT so the NOT NULL
  column doesn't silently fail the insert via let _ = ...
- link_to_catalogs: upsert the catalog row before linking so fresh
  installs with an empty catalog table don't produce 0-row results
- discover_prewarm link_to_catalog: same upsert-then-link pattern

Fixes #681 — native scrapers populate media/stream_media_link but
media_external_id, catalog, and media_catalog_link stay empty.
- meta.rs get_media_meta: convert query_as! to non-macro query_as so
  LEFT JOIN LATERAL columns (poster_url, background_url, imdb_rating)
  are decoded as Option<T> at runtime instead of non-nullable as
  inferred by the offline sqlx cache
- meta.rs get_episodes: same fix for thumbnail_url and fml.media_id
- streams.rs fetch_stream_playback_info: add ts.torrent_file to the
  GROUP BY clause in the non-series path

Fixes runtime errors:
  "meta query [tt...]: error decoding column 13: unexpected null"
  "episodes for media ...: error decoding column 5: unexpected null"
  "fetch_stream_playback_info: column 'ts.torrent_file' must appear in GROUP BY"
Previously fingerprint() used only file:line, so all warnings from the
same source location were bucketed together regardless of message — the
traceback stored the first message while the displayed message showed
the latest, causing the mismatch visible in the admin exception panel.

Changes:
- fingerprint() now hashes file:line + normalized message prefix (digit
  runs collapsed to 'N', first 80 chars) so errors with genuinely
  different text get separate entries; numeric variations like page
  numbers still cluster together
- store_event update path now also refreshes traceback to stay
  consistent with the updated message field
- response_json: when JSON parse fails and HTTP status is 401/403,
  return invalid_token.mp4 instead of api_error.mp4 — covers the case
  where a proxy/CDN returns an HTML 401 page instead of the API's JSON
  error body
- realdebrid check_cached: replace hand-rolled HTTP loop with
  get_torrent_list() so the request goes through rd_get → response_json
  → check_rd_error, giving consistent auth-error handling
- premiumize check_pm_error: detect "Not logged in" / "Invalid API key"
  / "unauthorized" messages and map them to invalid_token.mp4 instead
  of transfer_error.mp4
- contributions.rs + import_helpers.rs: bind initial_status / status as
  ContributionStatus enum instead of &str — Postgres rejects the text →
  contributionstatus cast at runtime
- playback_dedup.rs: downgrade stale-lock reclaim log from warn to debug;
  this is expected crash-recovery behavior, not an error condition
- encrypt.rs: downgrade AES padding error from warn to debug; malformed
  tokens are expected user-input noise, fully handled with a 400 response
Four tests that protect against the runtime bugs fixed in this batch:
- get_media_meta_null_poster_and_rating_external_id: movie with no
  poster/background/rating via tt_ lookup must not panic on null columns
- get_media_meta_null_poster_and_rating_internal_id: same via mf{id} path
- get_episodes_null_thumbnail_and_null_file_link: series with no
  episode_image/file_media_link must return episodes with None fields
- fetch_stream_playback_info_movie_group_by_is_complete: torrent stream
  with non-NULL torrent_file exercises the GROUP BY path that was missing
  ts.torrent_file
… token auth

- Add ENABLE_PROMETHEUS_METRICS (default false) so the /api/v1/metrics
  endpoint is opt-in; disabled instances return 404 (route not registered).
- Add PROMETHEUS_METRICS_TOKEN: when set, every scrape request must carry
  "Authorization: Bearer <token>" — enforced even on public instances.
- Update prometheus.yml, prometheus-dev.yml, and docker-compose-perf.yml
  to use the new metrics path and Authorization bearer credential; replace
  the defunct PROMETHEUS_DISABLE_AUTH flag with ENABLE_PROMETHEUS_METRICS.

fix(sports): store sports categories as catalogs only, not genres

- Remove genre_name param from find_or_create_sports_stub and drop all
  link_genre() calls inside it — sports sub-categories (Football, Formula
  Racing, etc.) should live in media_catalog_link, not the genre table.
- Update all four callers (dmm_hashlist, sport_video, ext_to, user_library)
  to drop the now-removed argument.
- Remove the genre field from CatalogSpec in ext_to.rs (was only used to
  feed the deleted parameter).
- Remove sports_category_to_genre from the parser re-export (function still
  exists in sports_parser.rs but has no external callers).
Serve debrid watchlist catalogs natively (hash lookup, delete-all meta/stream),
fix Seedr listing via root folder names, align Prowlarr credential resolution
with Python, and downgrade expected auth/rate-limit logs to debug.
Rebuild genre lists with parallel table scans instead of a heavy SQL join, filter blocked genres via the admin keyword cache at manifest time, and use shared provider short names (including Seedr as SDR).
…board

The admin request-metrics dashboard was always empty because
metrics_middleware only updated in-memory counters and never wrote to
Redis, while the admin readers expected Redis-backed data.

- metrics_middleware: after each non-health request, spawn a background
  task that writes aggregate stats to req_metrics:agg:{METHOD}:{route}
  hashes (HINCRBY/HINCRBYFLOAT for atomic increments), tracks endpoints
  in a req_metrics:endpoints sorted set, and pushes individual request
  JSON to a req_metrics:recent list (capped at 10k, TTL 1h)
- admin_extended: rewrite all five request-metrics handlers to read from
  the correct Redis schema (ZRANGE sorted set + HGETALL hashes for
  endpoint stats; LRANGE list for recent requests) instead of the old
  dead LIST+string schema that was never populated
Meta requests now create missing media on miss; stream requests enqueue background re-scrapes that run the full torrent+usenet fan-out with per-indexer parallel Prowlarr/Jackett tasks and dual Zilean endpoints.
@pull pull Bot locked and limited conversation to collaborators Jun 1, 2026
@pull pull Bot added the ⤵️ pull label Jun 1, 2026
@pull pull Bot merged commit dd624be into geek-cookbook:main Jun 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants