summaryrefslogtreecommitdiff
path: root/cmd
AgeCommit message (Collapse)Author
2026-05-17Restructure repo: move Go server into player-server/Paul Buetow
2026-05-10refactor(cmd/player): move appDeps and parseVersionFlag above mainPaul Buetow
2026-05-10Decouple podcast browse logic from BrowseSet via PodcastBrowser interfacePaul Buetow
Extract PodcastBrowser interface and podcastBrowseService implementation to move podcast-specific grid augmentation out of browseService.BrowseSet. - Remove PodcastRepo from BrowseServiceStore and MediaServiceStore. - browseService now delegates podcast set augmentation to an injected PodcastBrowser strategy (kept optional/nil-safe). - Add NewMediaServiceWithPodcastBrowser to wire a real PodcastBrowser (backed by PodcastRepo) in production while keeping the plain NewMediaService for existing callers/tests. - Update main.go to instantiate NewPodcastBrowseService and inject it. - Update browse_test.go to test PodcastBrowser-augmented paths through the new constructor signature. This keeps BrowseSet focused on files and folders only and removes the podcast dependency from the browse contract.
2026-05-09Extract SessionManager interface to fix DIP violationPaul Buetow
- Introduce auth.SessionManager interface in internal/auth/interfaces.go - Rename concrete struct to sessionManager (unexported) and have it satisfy interface - Update api/service layers to depend on interface, not concrete type - Add MockSessionManager for testing - Update all call sites and tests to use interface
2026-05-09Handle background worker panics for task 42Paul Buetow
2026-05-09more on thisPaul Buetow
2026-05-07task 31: introduce media streamer servicePaul Buetow
2026-05-07Refactor API server dependencies for task 11Paul Buetow
2026-05-07task 81: replace test sleeps with deterministic syncPaul Buetow
2026-05-06internal/service: inject http.Client into podcastService constructor (task 41)Paul Buetow
2026-05-06internal/service: log and concurrently process podcast feeds (task 91)Paul Buetow
- Add *slog.Logger to podcastService with NewPodcastServiceWithLogger. - Wire logger from cmd/player main.go. - Run CheckFeeds concurrently: one goroutine per feed with WaitGroup. - Add structured logging for start/finish per feed and overall count. - Log feed failures at Warn level so they are visible but not fatal. - Ensure nil logger safety with slog.Default fallback. - Add tests: empty list, concurrent OK, list error, single feed error, all feeds error.
2026-05-06Move background goroutine start out of wireDeps into startBackgroundWorkers ↵Paul Buetow
(task z0)
2026-05-05Fix podcast support critical bugs from code reviewPaul Buetow
- Fix boolean scanning from SQLite INTEGER columns (intToBool helper) - Fix BrowseSet LIMIT 0 returning zero episodes (use 1000 instead) - Fix checkFeed double-fetch by parsing from resp.Body directly + Add ParseFeedReader for body reuse - Fix file handle leak in DownloadEpisode (explicit Close before ImportMediaFile) - Fix incomplete rollback in DownloadEpisode (remove file + delete media row) - Fix 204 No Content handler writing 'null' body - Fix DownloadCoverImage to accept *http.Client with timeout - Deduplicate uniqueFilename into shared internal/service/filename.go - Wire frontend renderPodcastEpisodes into renderBrowse from API data - Refactor podcasts.js: remove extra API call, fix toggle toast, remove duplicate toast - Add Config.PodcastCheckMinutes + PODCAST_CHECK_INTERVAL_MINUTES env var - Start background CheckFeeds goroutine in main.go with ticker - Update NewPodcastService to accept checkInterval parameter - Log errors from CheckFeeds and episode creation instead of silently discarding
2026-05-05Add podcast support backend: RSS/Atom feeds, episode management, cover scrapingPaul Buetow
2026-05-04task l: rename binary from mediaplayer to playerPaul Buetow
2026-05-04task 7: refactor oversized functions into helpersPaul Buetow
Refactored the following functions per CLAUDE.md (50+ line limit): - internal/scanner/scanner.go: scanSet (192 → 56 lines) Extracted: ensureSet, loadExistingMedia, gatherCoverImages, thumbnailForVideo, thumbnailForImage, buildThumbnailPath, processNewFile, updateAudioThumbnails - internal/repository/migrate.go: Migrate (134 → 23 lines) Extracted: enableForeignKeys, execSchema; split schema into tablesSchema and indexesSchema constants - internal/config.go: LoadConfig (85 → 28 lines) Extracted: defaultConfig, loadNumericSettings, loadStringSettings, loadLogLevel, loadSecureCookies; added validLogLevels variable - cmd/mediaplayer/main.go: run / runWithSignal (114 → 26 / 26 lines) Extracted: parseVersionFlag, buildLogger, wireDeps, runServer, ensureSignalChannel, shutdownGracefully; introduced appDeps struct - internal/api/server.go: routes (96 → 8 lines) Extracted per route group: routesPublic, routesSharePublic, routesStatic, routesHTML, routesAuth, routesSets, routesMedia, routesNotes, routesProgress, routesShares, routesAdmin Added helpers: requireSession, requireAdmin, publicMethod - internal/service/browse.go: BrowseSet (85 → 26 lines) Extracted: prefixForParent, classifyMediaPath, buildFolderMap, folderHasCover, buildFolders All public interfaces remain unchanged. Tests pass: go test ./... -race -cover
2026-05-04task b: inject app context into AdminService and propagate cancellation to ↵Paul Buetow
background scans
2026-05-04task 6: narrow service interfaces in Server and MiddlewarePaul Buetow
Split Server struct to accept narrow service interfaces instead of fat composites (MediaService, AdminService). Each handler now depends only on its specific slice (MediaBrowseService, MediaWriteService, etc.). Split Middleware to depend on a narrow UserStore interface instead of full repository.Store. Updated all constructors, call sites, and tests. Added negative tests for nil AdminService and ProgressService returning 501 Not Implemented. References task 6.
2026-05-03Task 8: standardize scanner and handler loggingPaul Buetow
2026-05-03refactor(api): extract Remuxer interface and move ffmpeg/MPEG-TS/mime logic ↵Paul Buetow
to internal/probe Move LooksLikeMPEGTS, MimeTypeForFilename and the ffmpeg remux path out of the api transport layer into a new internal/probe/remux.go package. This removes os/exec and mime tables from the api layer, satisfying the DIP principle. - New probe.Remuxer interface with FFRemuxer implementation - Server depends on probe.Remuxer, injected via NewServer - Updated cmd/mediaplayer wiring and all test helpers - All tests pass: go test ./... -race -cover
2026-05-03test: raise coverage above 60% in cmd/mediaplayer, model, and probePaul Buetow
- cmd/mediaplayer: add runWithSignal injection point for testing; cover version flag, invalid flags, invalid config, normal shutdown, all log levels, invalid DB, and privileged-port bind failure. Refactor run() to delegate to runWithSignal with optional signal channel. - internal/config: allow PORT=0 (ephemeral) to support test server startup. Update AGENTS.md validation docs accordingly. - internal/model: add comprehensive ScanProgress tests (Start, Done, IncrementFile/Set, SetCurrentSet/FilesTotal, Copy isolation, and concurrent access). - internal/probe: add image tests for isImagePath (all extensions and case insensitivity), real EXIF extraction via ImageMagick + exiv2, Probe against real JPEG, MP4, empty file, and nonexistent paths. - internal/config_test: replace PORT=0 invalid-value test with PORT=-1.
2026-05-01Task 1: Create AuthService and route handleBootstrap/handleLogin through itPaul Buetow
Introduce service.AuthService interface with Bootstrap and Login methods, a concrete authService implementation, and a MockAuthService for testing. Wire AuthService into api.Server and update cmd/mediaplayer/main.go to use it. This removes direct store access from handleBootstrap and handleLogin, fixing the DIP violation. Sentinel errors (ErrAlreadyBootstrapped, ErrInvalidCredentials) are added to the service package so the API layer can map them to the correct HTTP status codes without leaking DB details. Files created: - internal/service/auth.go Files modified: - internal/service/service.go - internal/service/media.go - internal/service/mock.go - internal/repository/repository.go - internal/repository/mock.go - internal/api/server.go - internal/api/handlers_auth.go - internal/api/handlers_test.go - internal/api/handlers_more_test.go - cmd/mediaplayer/main.go
2026-05-01Rename Go module from codeberg.org/snonux/play to codeberg.org/snonux/playerPaul Buetow
2026-05-01Minimalist UI: hide all elements until activated; add help modal and ↵Paul Buetow
keyboard shortcuts - Redesign UI to be invisible by default: only header + '?' button shown - Press m to show sidebar, t for toolbar, / for search, ? for help - Add help modal with all keyboard shortcuts - Fix scanner to skip corrupt/unprobeable files instead of aborting - Fix scanner to skip thumbnail errors instead of aborting - Fix rescan to use background context so it completes after HTTP response - Rename project from KISS Media Player to Player
2026-04-30pa: raise aggregate test coverage to 81.5%Paul Buetow
2026-04-30ga — implement thumbnail and set cover regeneration end to endPaul Buetow
- mediaService: implement RegenerateThumbnail and RegenerateSetCover - Inject thumb.Generator and probe.Prober into MediaService - Update NewMediaService constructor and all call sites - Add service tests for success, failure, permission denied, and not-found - Add API tests for cover regeneration and thumbnail error mapping - All tests pass
2026-04-30fa: wire GCWorker startup and shutdown in cmd/mediaplayer/main.goPaul Buetow
- Refactor main into run(args) for testability and clean error propagation. - Create slog.Logger from cfg.LogLevel using TextHandler. - Instantiate service.NewGCWorker with store, clock, cfg.MediaRoot, and time.Duration(cfg.GCIntervalMinutes)*time.Minute. - Start GCWorker after construction and defer Stop for graceful shutdown. - Add cmd/mediaplayer/main_test.go as an integration smoke test wiring the GCWorker against a real SQLite store.
2026-04-30task ea: wire filesystem scanner into app and admin rescan endpointPaul Buetow
- Add scanner.Scanner and mediaRoot fields to adminService. - Update NewAdminService signature to accept scanner and mediaRoot. - Implement TriggerRescan delegation to injected scanner. - Wire probe.NewFFProber, thumb.NewFFmpegGenerator, and scanner.NewFSScanner in cmd/mediaplayer/main.go. - Add tests for TriggerRescan delegation, error propagation, and nil scanner.
2026-04-30Rename module to codeberg.org/snonux/play (task aa)Paul Buetow
- Update go.mod module path - Replace all internal imports from github.com/paul/kiss-media-player to codeberg.org/snonux/play - Run go mod tidy and gofmt -w .
2026-04-29fix: start HTTP server in main.goPaul Buetow