Commit graph

20 commits

Author SHA1 Message Date
jlightner
daf892edad feat: Add pause/resume buttons, paused status badge, and Paused filter…
- "src/frontend/src/pages/Queue.tsx"
- "src/frontend/src/api/hooks/useQueue.ts"
- "src/frontend/src/components/StatusBadge.tsx"

GSD-Task: S07/T04
2026-04-04 07:13:13 +00:00
jlightner
61da729fa4 feat: Add MissingFileScanner service with cursor-based batched filesyst…
- "src/services/missing-file-scanner.ts"
- "src/__tests__/missing-file-scanner.test.ts"
- "src/types/index.ts"
- "src/db/schema/content.ts"

GSD-Task: S06/T01
2026-04-04 06:31:11 +00:00
jlightner
b4d730d42f feat: Wired NFO generation into DownloadService with feature flag check…
- "src/services/download.ts"
- "src/__tests__/download.test.ts"

GSD-Task: S05/T03
2026-04-04 06:16:03 +00:00
jlightner
7f6f3dcccf feat: Built NfoGenerator service producing Kodi-compatible NFO XML with…
- "src/services/nfo-generator.ts"
- "src/__tests__/nfo-generator.test.ts"
- "src/types/index.ts"
- "src/db/repositories/channel-repository.ts"
- "src/__tests__/sources.test.ts"

GSD-Task: S05/T02
2026-04-04 06:12:35 +00:00
jlightner
73c232a845 test: Built stateless MediaServerService with scan triggering, connecti…
- "src/services/media-server.ts"
- "src/__tests__/media-server.test.ts"

GSD-Task: S04/T02
2026-04-04 05:53:30 +00:00
jlightner
05045828d8 feat: Wire keyword filter into scheduler scan flow — exclude/include pa…
- "src/services/scheduler.ts"
- "src/__tests__/scheduler.test.ts"
- "src/db/repositories/channel-repository.ts"

GSD-Task: S03/T03
2026-04-04 05:41:55 +00:00
jlightner
cc031a78a9 test: Implement matchesKeywordFilter engine with pipe-separated pattern…
- "src/services/keyword-filter.ts"
- "src/__tests__/keyword-filter.test.ts"

GSD-Task: S03/T02
2026-04-04 05:38:37 +00:00
jlightner
fb731377bd feat: Wire FormatProfile.outputTemplate into DownloadService with conte…
- "src/services/download.ts"
- "src/services/file-organizer.ts"

GSD-Task: S02/T03
2026-04-04 05:25:41 +00:00
jlightner
71175198bd test: Add resolveTemplate and validateTemplate methods to FileOrganizer…
- "src/services/file-organizer.ts"
- "src/__tests__/file-organizer.test.ts"

GSD-Task: S02/T02
2026-04-04 05:23:22 +00:00
jlightner
22077e0eb1 feat: Add POST /api/v1/download/url/confirm endpoint for ad-hoc downloa…
- "src/server/routes/adhoc-download.ts"
- "src/services/download.ts"
- "src/services/queue.ts"
- "src/__tests__/adhoc-download-api.test.ts"

GSD-Task: S01/T03
2026-04-04 05:12:11 +00:00
jlightner
8150b1f6cf chore: Made content_items.channelId nullable via SQLite table recreatio…
- "src/db/schema/content.ts"
- "src/types/index.ts"
- "src/db/repositories/content-repository.ts"
- "src/services/queue.ts"
- "drizzle/0012_adhoc_nullable_channel.sql"
- "drizzle/meta/_journal.json"

GSD-Task: S01/T01
2026-04-04 05:03:40 +00:00
jlightner
7de71f1062 fix: strip # from filenames — breaks Plex scanner
Some checks failed
CI / test (push) Failing after 17s
Plex interprets # as a URL fragment delimiter, causing files with # in
the name to be silently skipped during library scans.

- Added # to FORBIDDEN_CHARS in file-organizer.ts sanitizer
- Bulk-renamed 100 existing files on disk
- Updated 100 filePath records in DB to match
2026-04-04 03:15:11 +00:00
jlightner
aa09bc089c feat: Generic platform + YouTube enhancements (chapters, SponsorBlock, thumbnails)
Generic Platform:
- New 'generic' platform type — catch-all for any URL yt-dlp supports
- GenericSource resolves channel metadata from any URL via yt-dlp extractors
- Content type auto-detection (video/audio/livestream) from yt-dlp metadata
- Works with Vimeo, Twitch, Bandcamp, Dailymotion, and 1000+ other sites
- Registered in both scheduler registry and channel route registry
- Frontend: indigo badge, URL detection fallback, AddChannelModal support

YouTube Enhancements:
- embedChapters: --embed-chapters flag on FormatProfile
- embedThumbnail: --embed-thumbnail flag on FormatProfile
- sponsorBlockRemove: --sponsorblock-remove with configurable categories
  (sponsor, selfpromo, interaction, intro, outro, preview, music_offtopic, filler)
- Migration 0011: adds columns to format_profiles table
- All three configurable per format profile via API and (future) Settings UI
2026-04-04 02:45:02 +00:00
jlightner
f494d31e60 fix: raise default scan limit from 100 to 500, use 999 for initial scans
- Default scanLimit increased to 500 (was 100, missing most channel content)
- First scan (lastCheckedAt === null) uses max(scanLimit, 999) for full catalog
- Discovery timeout scales with limit: 60s base + 30s per 500 items
- Updated platform-settings-repository defaults to match
2026-04-03 22:07:24 +00:00
jlightner
4546ddb4ea feat: real-time scan streaming with fire-and-forget API and cancel support
- Scan endpoint returns 202 immediately, runs in background
- Items appear in real-time via WebSocket scan:item-discovered events
- Phase 1 (fast flat-playlist) runs first with discoveryOnly flag
- Phase 2 (slow enrichment) runs as background post-scan pass
- Added POST /api/v1/channel/:id/scan-cancel endpoint
- AbortController support in scheduler for scan cancellation
- Frontend: Scan button toggles to Stop button during scan
- Frontend: Live item count shown during scanning
- Frontend: useCancelScan hook for cancel functionality
- Moved tubearr config to local Docker volume (SQLite on CIFS fix)
2026-04-03 21:43:23 +00:00
jlightner
cdd1128632 feat: Added typed scan event pipeline — EventBus emits scan:started/ite…
- "src/services/event-bus.ts"
- "src/services/scheduler.ts"
- "src/index.ts"
- "src/server/routes/websocket.ts"

GSD-Task: S05/T01
2026-04-03 07:23:39 +00:00
jlightner
c057b6a286 feat(S01+S04): server-side pagination, search/filter, download engine hardening
S01 — Server-Side Pagination:
- Added getChannelContentPaginated() to content repository with search, filter, sort
- Channel content API now supports ?page, ?pageSize, ?search, ?status, ?contentType, ?sortBy, ?sortDirection
- Backwards-compatible: no params returns all items (legacy mode)
- Frontend useChannelContentPaginated hook with keepPreviousData
- ChannelDetail page: search bar, status/type filter dropdowns, pagination controls
- Sorting delegated to server (removed client-side sortedContent)
- Item count shown in Content header (e.g. '121 items')

S04 — Download Engine Hardening:
- yt-dlp auto-update on production startup (native -U with pip fallback)
- Error classification: rate_limit, format_unavailable, geo_blocked, age_restricted, private, network
- Format fallback chains: preferred res → best under res → single best → any
- Improved parseFinalPath: explicit non-path prefix detection, extension validation
- Error category included in download:failed events
- classifyYtDlpError() exported from yt-dlp module for downstream use
2026-04-03 02:29:49 +00:00
John Lightner
0541a5f1d1 WIP: in-progress WebSocket download progress & event bus
Snapshot of active development by separate Claude instance.
Includes: event bus, progress parser, WebSocket route,
download progress bar component, SSE contexts/hooks.
Not tested or validated — commit for migration to dev01.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:34:26 -05:00
John Lightner
dbe163bdbb chore(M007/S01): auto-commit after research-slice 2026-03-24 23:04:09 -05:00
John Lightner
4606dce553 feat: Tubearr — full project state through M006/S01
Migrated git root from W:/programming/Projects/ to W:/programming/Projects/Tubearr/.
Previous history preserved in Tubearr-full-backup.bundle at parent directory.

Completed milestones: M001 through M005
Active: M006/S02 (Add Channel UX)
2026-03-24 20:20:10 -05:00