Skip to content

Fork Changes

o51r15 edited this page Jun 25, 2026 · 2 revisions

Fork Changes

What started as a targeted PostgreSQL swap has grown into a substantial independent rewrite. This page documents everything that differs from the upstream Pinchflat project.


Backend

PostgreSQL replaces SQLite

The upstream project uses SQLite. This fork uses PostgreSQL.

  • SQLite + Oban is a structural mismatch. Oban was built for Postgres and the SQLite adapter causes write contention under load, query timeouts, and crash loops as library size grows.
  • Postgres handles concurrent job queues (indexing, downloading, metadata, file sync) correctly and without file locking issues.
  • Deployment requires a Postgres sidecar container. See Installation.

Oban Lifeline plugin

Jobs that get stuck in executing state after a crash or container restart are automatically rescued and re-queued after 30 minutes. The upstream does not include this plugin.

Metadata reliability

  • Scoped yt-dlp output template prevents multi-MB JSON truncation on resource-constrained hosts
  • Graceful error handling in the metadata worker prevents fetch failures from causing noisy Oban retries and discards

UI

The entire UI has been redesigned with a Sonarr-style layout.

  • Source library — poster card grid with download progress bars and one-click monitored toggles
  • Source detail page — fanart banner header, poster overlay, granular stats bar (Downloaded / Pending / Failed / Prevented / Skipped), horizontal action bar
  • Episode list — grouped by year (season analog) with collapsible sections, per-item status badges, and monitored toggles
  • Activity page — dedicated page replaces the cluttered home dashboard
  • System Status page — Pinchfork version, yt-dlp version, PostgreSQL version and database size, Oban queue health, and live bgutil PO token server status with one-click test

Source management

Source type selector

Channel vs Playlist is now user-selectable on the new source form before entering the URL. This overrides yt-dlp's auto-detection, which can misidentify channel handles as playlists on some architectures. The URL field label changes dynamically (Channel URL / Playlist URL) and the URL field is locked until a type is selected.

Metadata editor

A dedicated Edit Metadata page (accessible from the source action bar) provides:

  • Editable Name and Description fields with per-field lock toggles — locked fields are not overwritten by metadata refreshes
  • Custom poster upload (file or URL) — once set, the custom poster takes priority over auto-fetched images and is locked until removed

Content availability filtering

Per-source checkboxes to control whether public videos, members-only videos, or both are downloaded. The availability field is captured from yt-dlp at index time and re-evaluated on rescan.

Cookie behaviour

Per-source control over when cookies are used: Disabled / When Needed / All Operations.

Video client override

Select the yt-dlp player client per source. Used to bypass SABR-corrupted downloads or work around authentication issues on specific content. See SABR Bypass and PO Tokens.


yt-dlp

PO token support

Integration with the bgutil sidecar for YouTube PO token generation. Required for reliable downloads on some content. See SABR Bypass and PO Tokens.

yt-dlp version management

YT_DLP_VERSION environment variable controls update behavior: stable (default), nightly, master, pinned/none to disable, or a specific version string like 2025.12.08.


Media tracking

Error classification

error_type field on media items distinguishes permanent failures (members-only, unavailable, geo-blocked, age-restricted, premium-only) from transient ones (network errors, rate limits). Permanent failures automatically set prevent_download: true to stop retry cycles.

Prevention reason tracking

download_prevented_reason field distinguishes between manual prevention (user turned off download), policy blocks (system rules), and error-stops. This prevents re-indexing from accidentally re-enabling intentionally blocked items.


Additional features

YouTube API key tester

One-click API key validation from the Settings page.

Local temp staging

Downloads can stage to a local disk path before moving to the final destination. Eliminates partial-file issues when /downloads is a network share. See Local Temp Staging.


What has not changed

The following upstream features are unchanged in this fork and are documented in the upstream wiki:

  • Media profiles
  • SponsorBlock integration
  • RSS/podcast feeds
  • Apprise notifications
  • Custom yt-dlp options
  • Lifecycle scripts
  • Jellyfin/Plex/Kodi setup and file naming
  • Retention periods
  • Title filter regex
  • Output path templates

Clone this wiki locally