Compare commits

...
2084 Commits
Author SHA1 Message Date
FoxxMD f5ad2ad29b chore(release): Bump version for release 2026-08-08 19:29:38 +00:00
FoxxMD 2e4acd0f00 fix: Add missing configureAs for ENV parsed components
#661
2026-08-08 19:24:45 +00:00
FoxxMD b9517bd066 docs: Add more type guidance for aio/file config 2026-08-07 17:22:20 +00:00
FoxxMD 335880249f chore(release): Bump version for release 2026-08-07 16:49:36 +00:00
Matt Foxx 5c2917f906 Merge pull request #660 from FoxxMD/ingressSot
Ingress sot
2026-08-07 12:34:15 -04:00
FoxxMD 124e857d9f fix: now playing playerUpdate event data 2026-08-07 14:53:02 +00:00
FoxxMD 5dee499381 test: fix failing tests from np data structure change 2026-08-07 14:53:02 +00:00
FoxxMD 10325fd4e6 refactor(now playing): Use more efficient solution for ingress now playing
Re-queue valid ingress NP update on client rather than spamming all clients with duplicate updates from memory source

This should have the same functional affect with way less log noise
2026-08-07 14:53:02 +00:00
FoxxMD 045890e243 feat(sourc): Add Ingress SOT type and force-push ingress player updates
#659
2026-08-07 14:53:02 +00:00
FoxxMD 685e48a7a6 fear(ui): Implement cache clearing mechanism #634 2026-08-06 20:20:11 +00:00
FoxxMD 7eb5104f0b feat(ui): Implement basic settings page 2026-08-06 19:34:02 +00:00
FoxxMD 4272e8ea58 feat(ui): Improve UX for theme switcher
* Remove three-state toggle
* Revert to system theme only when *user* initiated toggle results in same theme as system
2026-08-06 18:24:57 +00:00
FoxxMD 8e6d35a85b fix(lz endpoint): Fix missing early return when no sources for playing now response 2026-08-05 19:08:08 +00:00
FoxxMD 917d05f295 docs: Update configuration types language 2026-08-05 15:02:21 +00:00
FoxxMD 287c994643 docs: Some corrections and updated language 2026-08-05 14:15:25 +00:00
Matt Foxx 7980a0c856 Merge pull request #657 from FoxxMD/lastfmEndpointResponses
feat(lfm endpoint): Implement more api emulation
2026-08-05 09:28:43 -04:00
FoxxMD 9d2557cf6a feat(lfm endpoint): Handle scrobble payload variants 2026-08-04 22:14:03 +00:00
FoxxMD 6f8debc304 docs: Add lastfm endpoint alternative guidance 2026-08-04 18:50:59 +00:00
FoxxMD b53ae78d55 fix(lfm endpoint): Fix no response on no slug matched 2026-08-04 18:30:16 +00:00
FoxxMD 8723bc8890 fix(lfm endpoint): Improve regex slug matching to handle more variants 2026-08-04 18:29:41 +00:00
FoxxMD eca8ad2ce1 fix(lfm endpoint): Fix slug regex match 2026-08-04 18:16:39 +00:00
FoxxMD b6b8d3423f fix(lfm endpoint): Detect desired json response from accept header 2026-08-04 18:06:45 +00:00
FoxxMD fc027e8554 fix(lfm endpoint): remove duplicated method restrictions 2026-08-04 16:07:11 +00:00
FoxxMD 707da834bb docs: regenerate tealfm source env 2026-08-04 15:10:17 +00:00
FoxxMD 002520cd8a docs: Fix config.json example 2026-08-04 15:10:06 +00:00
FoxxMD 7ca84ce27f feat(lfm endpoint): Implement more api emulation #656
* Add optional username/apiKey config fields
* Identify Source by optional username/sk/api_key
* Emulate auth.getMobileSession response with sk derived from Source uid
* Update docs with guidance for multiple sources and improved setup language
2026-08-04 14:59:05 +00:00
FoxxMD 8af56cb561 revert: rollback tealfm source optional app password for now
This needs to be part of a larger refactor to require app password/permissions only for specific operations in the api client
2026-08-03 18:29:03 +00:00
FoxxMD 0e249b13a9 fix(source): Fix player cleanup for ingress sources
This bool check was backward. The scheduled task should no-op for polling sources and run cleanup for ingress sources

#652
2026-08-03 18:25:12 +00:00
FoxxMD 591b5c6618 fix(tealfm): app password for source is optional 2026-08-03 16:55:16 +00:00
FoxxMD 3c5b9cc402 fix(teal): teal client app password is required 2026-08-03 16:52:32 +00:00
FoxxMD 420a053e25 docs: update now playing for clients 2026-08-03 16:06:23 +00:00
FoxxMD 72f64953f6 chore: remove unused ts-zod config 2026-08-03 15:55:00 +00:00
Matt Foxx 8b8c2765c7 Merge pull request #654 from FoxxMD/configBuildSimplify
Simplify config validation and building
2026-08-03 11:53:23 -04:00
FoxxMD e1324921e9 fix: Fix missing name passed to component classes 2026-08-03 15:38:35 +00:00
FoxxMD 9f71fbef97 fix: prevent creating source/client with same id 2026-08-03 15:21:11 +00:00
FoxxMD dd22418c41 fix(tests): Fix missing required id 2026-08-03 14:56:33 +00:00
FoxxMD d296b825d6 Id logging and schema cleanup
* Guard against undefined name when logging component disabled
* Add id/name hint to config location
* inherit name/id field from common schema
2026-08-03 14:31:24 +00:00
FoxxMD 792ccc3c09 feat: Improve location wording for config errors 2026-08-03 13:39:14 +00:00
FoxxMD 6772e9934d refactor!: Enforce mandatory id for file/aio 2026-08-03 13:38:49 +00:00
FoxxMD 4ce7219214 fix: Skip ambigious configs during source parsing if configureAs is not present 2026-08-02 20:21:55 +00:00
FoxxMD b2ce42fecf simplify jellyfin mediatype usage for now 2026-08-01 19:12:04 +00:00
FoxxMD 46a061a602 docs: Update comma-separated list zod types for envs 2026-08-01 19:07:49 +00:00
FoxxMD ff7360fced docs: More env row generation improvements
* Always use `out` of common envs
* Wrapper function for normalizing descriptions with comma-separate lists
2026-08-01 19:07:35 +00:00
FoxxMD 425a0b2807 Partial fix for flattening complex zod types for docs 2026-08-01 17:47:44 +00:00
FoxxMD ad632f38d8 docs: regenerate env docs 2026-08-01 17:31:37 +00:00
FoxxMD 1d1b3b6f56 docs: Update env descriptions for id, name, and enable 2026-08-01 17:31:28 +00:00
FoxxMD 7575e8bff7 fix: Fix unhandled ZodTransform type generation 2026-08-01 17:31:03 +00:00
FoxxMD 31546ed4c1 fix: Early return on component add to prevent dynamic loading 2026-08-01 15:09:52 +00:00
FoxxMD bf9cdc141c re-add clients to aio json schema 2026-08-01 00:05:07 +00:00
FoxxMD 02ab1571b6 refactor: Convert validation client structures to dynamically import 2026-07-31 23:57:59 +00:00
FoxxMD 699bd02782 refactor: Convert validation structures to dynamically import 2026-07-31 23:41:56 +00:00
FoxxMD 0d45d06966 docs: Italicize required env properties 2026-07-31 23:41:12 +00:00
FoxxMD a93d02e1b7 env doc generation fixes 2026-07-31 20:50:41 +00:00
FoxxMD 513e2dde15 feat: Use env config generated from schema 2026-07-31 16:37:59 -04:00
FoxxMD 2fc90dcfda feat: Generate env markdown for components 2026-07-31 20:15:11 +00:00
FoxxMD fd2a178808 feat: Add env prefix to schema interface 2026-07-31 20:08:00 +00:00
FoxxMD 9f54d45576 fix(source): Fix missing defaults 2026-07-31 19:43:00 +00:00
FoxxMD 78aff32334 refactor: Extract source/client building into a function to reduce verbosity 2026-07-31 15:33:34 -04:00
FoxxMD 0115ccb862 refactor: Simplify ScrobbleSources config builder 2026-07-31 19:01:10 +00:00
FoxxMD 8a71663c9f Implement remaining source env schemas 2026-07-31 18:27:01 +00:00
FoxxMD 40eff0b901 refactor: Simplify ScrobbleClients config builder 2026-07-31 17:27:44 +00:00
FoxxMD 13acc56424 refactor client env schemas to reuse zod shape where possible 2026-07-31 10:39:14 -04:00
FoxxMD 09fc0ce15c Implement majority of source env schemas 2026-07-31 10:32:21 -04:00
FoxxMD 4fbdd71588 add EnvSourceSchema interface 2026-07-31 14:03:04 +00:00
FoxxMD 7cf105935e feat: Implement remaining env schemas for clients 2026-07-31 09:59:57 -04:00
FoxxMD 1bd10326eb add generic client env data validation interface 2026-07-31 13:31:52 +00:00
FoxxMD 74605caf15 add interface for env schemas 2026-07-31 13:10:13 +00:00
FoxxMD 7dec9a39e6 chore(release): Bump version for release 2026-07-30 17:50:57 +00:00
FoxxMD 90a8426748 Proof of concept: generate ENV docs from zod schema 2026-07-30 17:19:32 +00:00
FoxxMD 8469d161e9 feat: Reduce db write frequency when idle by buffering date updates #653 2026-07-30 12:37:38 +00:00
Matt Foxx 941f50bff2 Merge pull request #651 from FoxxMD/mbTrackGuard
fix: Guard against tracks/track in mb recording medium
2026-07-30 00:09:59 -04:00
FoxxMD f8d882cfcf docs: Clarify when activity is scrobbled 2026-07-29 19:37:40 +00:00
FoxxMD 0704cebe72 fix(webscrobbler): Fix bad access of PlayerState #650 2026-07-29 15:49:54 +00:00
FoxxMD e43a18bcbb fix: Guard against tracks/track in mb recording medium
Fixes #649
2026-07-29 15:18:45 +00:00
FoxxMD 0baa399e9f lint: Fix new error instantiation 2026-07-29 15:18:02 +00:00
FoxxMD 05b2e1c116 fix: Fix missing logPath base dir argument
NixOS/nixpkgs#519119
2026-07-28 21:22:56 +00:00
FoxxMD a0cdaeb01f docs: Add missing user type to user transform examples 2026-07-28 18:59:49 +00:00
FoxxMD 73c35751ed chore(release): Bump version for RC1 release 2026-07-28 17:27:57 +00:00
FoxxMD 516a8d2178 chore: Cleanup development comments 2026-07-28 17:27:23 +00:00
FoxxMD d595bf9961 chore: Remove zod development package and re-upgrade typescript to 6 2026-07-28 16:49:51 +00:00
FoxxMD 8345779030 refactor: cleaned up aio validation and client/source map 2026-07-28 16:43:51 +00:00
FoxxMD b58d39c90e feat(ui): Implement subsonic playback reporting indicators 2026-07-28 16:14:01 +00:00
FoxxMD 7074ece0a5 docs: Simplify subsonic playback reporting language 2026-07-28 16:13:49 +00:00
FoxxMD bfb0d6b392 refactor: Move platform constants/types to prevent frontend bundling backend code 2026-07-28 16:10:21 +00:00
Matt Foxx 5c3f49fb2f Merge pull request #647 from FoxxMD/zodExperimentRebase
feat: Replace ts-json-schema-generator + ajv with zod
2026-07-27 22:29:32 -04:00
Matt Foxx f70e680d55 Merge branch 'master' into zodExperimentRebase 2026-07-27 22:22:32 -04:00
Matt Foxx c2fda1e7d9 Merge pull request #640 from JannisPohle/feature/ignore-stale-subsonic-play-now-reports
fix: Ignore stale subsonic playing now reports
2026-07-27 22:18:44 -04:00
FoxxMD 70e4239e52 more cache config cleanup 2026-07-28 01:56:26 +00:00
FoxxMD d96073282c feat(cache): Remove deprecated cache configuration
Remove metadata/scrobble/auth config that was deprecated in 0.14.0
2026-07-28 01:56:26 +00:00
FoxxMD 2887600aa0 docs: Clarify language around id/name 2026-07-28 01:56:26 +00:00
FoxxMD 6f7aa6f567 remove unused interface names 2026-07-28 01:56:26 +00:00
FoxxMD 857f44fa14 docs: Add meta descriptions/titles for objects that become refs 2026-07-28 01:56:26 +00:00
FoxxMD d764b0204e fix(docs): Replace old json viewer links 2026-07-28 01:56:26 +00:00
FoxxMD ee2f988357 fix(docs): add aio json with reused refs to reduce file size 2026-07-28 01:56:26 +00:00
FoxxMD de69977d7e fix cf-json-schema-viz package name type 2026-07-28 01:56:26 +00:00
FoxxMD 6eab629168 remove unused patch 2026-07-28 01:56:26 +00:00
FoxxMD f21572bed0 chore: Remove ts-generator-schema rm from dockerfile layer 2026-07-28 01:56:26 +00:00
FoxxMD 98084665ba chore: remove ts-schema-generator and ajv 2026-07-28 01:56:26 +00:00
FoxxMD e8a91bb6de feat: Replace ajv/ts-schema-generator validation with pure zod 2026-07-28 01:56:26 +00:00
FoxxMD 206d1571ac feat(docs): Use zod for all doc schemas and simplify generation/usage 2026-07-28 01:56:26 +00:00
FoxxMD ebf6ec6957 add postCompare description 2026-07-28 01:56:26 +00:00
FoxxMD 03fc3e3a09 feat(docs): Inline defintions to prevent deduplication erasing descriptions 2026-07-28 01:56:26 +00:00
FoxxMD aa50842444 feat(docs): Don't hide top-level descriptions in json viewer 2026-07-28 01:56:26 +00:00
FoxxMD 03dbbdc2cf feat(docs): Patch schema viewer to show more descriptions 2026-07-28 01:56:26 +00:00
FoxxMD bf0b27924e more config annotation 2026-07-28 01:56:26 +00:00
FoxxMD e02a0cc6ae refactor(transform): Simplify transform config by removing untyped stages 2026-07-28 01:56:26 +00:00
FoxxMD ff4dd25a97 refactor(transform)!: Require user stage is typed 2026-07-28 01:56:26 +00:00
FoxxMD 28e0d03e6f Schema generation cleanup and vscode launch config fix 2026-07-28 01:56:22 +00:00
FoxxMD d7f2d6fa8e use zod for client validation 2026-07-28 01:55:25 +00:00
FoxxMD 8f33dc9f28 POC scrobble source validation at runtime 2026-07-28 01:55:25 +00:00
FoxxMD fe068a9216 refactor: Convert MonitorOptions to zod schema after rebase 2026-07-28 01:55:25 +00:00
FoxxMD 06b6e200f5 convert aioconfig 2026-07-28 01:55:25 +00:00
FoxxMD afea13e681 convert barrel client and source configs 2026-07-28 01:55:25 +00:00
FoxxMD f8401faf61 convert webhooks 2026-07-28 01:55:25 +00:00
FoxxMD 7c3590adf9 convert remaining source configs 2026-07-28 01:55:19 +00:00
FoxxMD 742025fecc feat: Convert source and client configs to zod 2026-07-28 01:54:41 +00:00
Jannis Pohle b983de1a58 docs: update subsonic source docs 2026-07-26 06:40:43 +00:00
Jannis Pohle ea77ea435a feat: add support for the playbackReport extension for OpenSubsonic
If the extension is provided by the server and playback data is reported by the client, make use of the new position and state fields when polling the current play entry from subsonic. If the new fields are not provided, fallback to the old timestamp based tracking listen progress.
2026-07-26 06:24:59 +00:00
FoxxMD ecf3273eb9 add zod packages 2026-07-24 16:51:31 -04:00
Jannis Pohle a79b697496 fix: add configuration key for disabling auto-detection of stale songs from subsonic servers via the minutesAgo field 2026-07-24 14:18:06 +00:00
Matt Foxx 79874c6c20 Merge pull request #645 from FoxxMD/ignoreRefactor
refactor: Expand monitoring behavior
2026-07-23 12:30:50 -04:00
FoxxMD aa91d2cb92 fix: Fix missed autoMonitor variable name change 2026-07-23 16:24:17 +00:00
FoxxMD c727445f76 fix: Fix api test fixtures for new api surface with monitoring 2026-07-23 15:32:57 +00:00
FoxxMD c25ca5297c docs: Replace should scrobble with monitoring behavior 2026-07-23 15:08:04 +00:00
FoxxMD 956054f387 refactor(ui): Update legacy ui to be compatible with new monitoring structure 2026-07-23 14:50:34 +00:00
FoxxMD 86ebd3d673 fix(ui): Only render component details when data is present 2026-07-23 14:36:08 +00:00
FoxxMD 0679937b54 feat!: Implement monitoring/ingore activity for all components
* Replace "manual listening behavior" for azuracast/icecast with monitoring functionality for all sources/clients
* Rename "systemScrobble" to "autoMonitor"
* Implement functionality for all sources/clients
2026-07-23 13:41:12 +00:00
Matt Foxx 61a2ff5180 Merge pull request #644 from FoxxMD/isrcNormalization
fix: Normalize ISRC values #643
2026-07-23 08:27:34 -04:00
Matt Foxx 26db80d8c7 Merge pull request #642 from FoxxMD/rockskyAlbumArtistFix
fix(rocksky): Fix missing albumArtist field #632
2026-07-22 15:23:42 -04:00
FoxxMD fc85790df5 fix: Normalize ISRC values #643
Spotify does not gaurantee non-hyphenated ISRC and musicbrainz won't search for hyphenated, so normalize before ISRC values downstream
2026-07-22 17:19:52 +00:00
FoxxMD 212ac27dd3 fix(rocksky): Fix missing albumArtist field #632 2026-07-22 16:01:36 +00:00
FoxxMD a30d1ae6a5 fix: Move project root dir constant location into backend-only scope
When in core its being pulled into vite bundler and causing build issues. It's only needed by backend anyways so move to backend-scope.
2026-07-22 15:40:44 +00:00
FoxxMD 5c586fb635 fix(storybook): Rename configure file causing ts to fail due to extension 2026-07-22 15:39:07 +00:00
FoxxMD de0d336325 fix(rocksky): Remove undefined keys from payload before sending 2026-07-22 15:38:18 +00:00
Matt Foxx 65d0c7c16b Merge pull request #641 from mattl/patch-1
Update librefm.mdx
2026-07-21 23:54:20 -04:00
Dr. Matt Lee fc6cc68d59 Update librefm.mdx 2026-07-21 18:10:16 -04:00
Matt Foxx 8c83969e95 Merge pull request #638 from FoxxMD/dataDirStandardize
Separate and standardize config/data dirs
2026-07-21 12:53:19 -04:00
Jannis Pohle 084dca73c1 fix: Ignore stale subsonic playing now reports
Ignore playing now entries from subsonic sources when their indicated start time from minutesAgo suggests that playback has been paused or stopped.
2026-07-19 07:01:41 +00:00
FoxxMD 7ac57ca757 feat(ui): Add theme switcher to header
#500
2026-07-17 16:41:24 +00:00
FoxxMD 1dc8c21716 docs: Add preview UI callout to landing 2026-07-17 14:53:57 +00:00
FoxxMD 6f8e7d3862 docs: Update intallation instructions with config/data dir guidance
#616
2026-07-16 16:14:24 -04:00
FoxxMD a6d33fc2ef feat: Move config and data dir creation into app
* only use docker init for fixing permission
  * don't rely on docker init for dir creation as other distros may need this functionality (nix)
* check for and create config/data dirs recursively on app start

#616
2026-07-16 16:14:24 -04:00
FoxxMD 26121ace10 feat: Separate config and data directories and use OS-standard paths, if present
* Break configDir into config and data directories so config and database/cache can be stored in different directories
* Use `env-paths` to fallback to OS-standard paths for config and data if CONFIG_DIR and DATA_DIR envs are not present
* Additionally fallback to process CWD/config if none of the above are present for some reason

#616
2026-07-16 16:14:24 -04:00
FoxxMD 27e5656a04 refactor: Replace projectDir with explicit path to project root, projectRootDir 2026-07-16 16:14:24 -04:00
Matt Foxx f3d7d59af6 Merge pull request #636 from Exerra/feat/apple-music
feat: Apple Music source
2026-07-16 15:45:04 -04:00
FoxxMD 2a4afefe64 feat(applemusic): Make album normalization user configurable and add guidance on usage 2026-07-16 16:41:36 +00:00
FoxxMD 1dba73ccb2 feat(client)!: Overhaul source scrobble filtering
* Use id OR name for matching client to scrobble to, during transition period
* Deprecate using name-only and warn when this is detected
* Consolidate logging filtered clients to one statement to reduce log noise
* Improve filter matching by making strings case and whitepsace insensitive
* On startup log `clients` options for sources
2026-07-16 15:51:54 +00:00
FoxxMD 3e82e035ac feat: Update string normalization with granular options 2026-07-16 15:49:01 +00:00
Exerra b12153fba9 docs(applemusic): improve formatting of developer tools shortcut
Updated the Apple Music configuration documentation to use <kbd> tags for keyboard shortcuts, improving readability.
2026-07-16 18:12:33 +03:00
Exerra 8c82412de4 docs: add detailed Apple Music authorization token extraction guide
Updated Apple Music configuration documentation with step-by-step instructions and screenshots for extracting authorization tokens in Chrome, Edge, Firefox, and Safari.
2026-07-16 17:15:58 +03:00
FoxxMD e804ce33ef fix(listenbrainz): Fix play fetch more indicator
latest_listen_ts is *always* the latest of *all-time*, not for the current min/max_ts range requested.

Instead, use count < than desired (and non-zero) to indicate more results
2026-07-15 20:49:37 +00:00
FoxxMD 3907fa5474 fix: Fix play fetch options logging data for pageless functions 2026-07-15 20:48:32 +00:00
FoxxMD a7b3593314 stage import rule from eslint-plugin-import-x 2026-07-15 19:08:48 +00:00
FoxxMD 76ef994067 fix: Implement unicorn eslint rules and fix them 2026-07-15 18:31:13 +00:00
FoxxMD c3cb3cf3a1 fix(client): Correct SOT scrobble api requests to not have the same from/to value 2026-07-15 17:34:37 +00:00
FoxxMD 8096219526 fix(client): Correct create/update timestamps for queues and scrobbles
* Ensure ingress queue always has an updated timestamp before dead creation
* Don't re-assign createdAt for scrobble after dead queue has already been updated
2026-07-15 17:02:29 +00:00
FoxxMD 67c1823195 feat(ui): Clean up scrobble timeline items
* Use timeline summary formatting to fix spacing
* Provide client name from fetched component data, if present, so scrobble summary is explicit where it sent/response scrobble from
2026-07-15 16:22:04 +00:00
FoxxMD 2014e78ade fix(ui): Stabilize play timeline item order 2026-07-15 14:51:42 +00:00
Exerra b3c332deeb refactor: replace Apple Music headers config with origin field
Replaces the generic `headers` configuration field with a specific `origin` field for Apple Music. Updates the config schema, environment variable handling, documentation, and source implementation to simplify origin header management.
2026-07-15 17:12:21 +03:00
Exerra 93a1042e03 test(applemusic): add tests for stripping EP/Single album suffixes
Added test cases to ensure that ' - EP' and ' - Single' suffixes are correctly stripped from Apple Music album names during the formatting process.
2026-07-15 16:21:10 +03:00
Exerra ba010240c0 feat(AppleMusicSource): include track URL in metadata
Added the web URL to the track metadata in AppleMusicSource to provide a direct link to the track.
2026-07-15 16:20:54 +03:00
FoxxMD 7f491d6974 fix: Fix hash router type 2026-07-15 13:08:04 +00:00
Exerra 74e67e0e41 feat(AppleMusicSource): include ISRC in track metadata
Added the isrc field to the track object in AppleMusicSource to improve track identification accuracy.
2026-07-15 15:59:49 +03:00
FoxxMD 1853f9abba fix(musicbrainz): Catch scenario where all search prereqs fail
#636
2026-07-15 12:58:40 +00:00
Exerra c13e7ebeec feat(applemusic): strip ' - EP' and ' - Single' from album names
Implemented album name normalization in AppleMusicSource to ensure consistency with other sources by removing standard suffixes from EPs and singles. Updated documentation to reflect this behavior.
2026-07-15 15:38:14 +03:00
Exerra 207354e799 docs(docsite): fix heading hierarchy in applemusic.mdx
Adjusted markdown heading levels to ensure proper document structure.
2026-07-15 15:36:51 +03:00
FoxxMD d7f6b17308 update boundary element linting to be more lenient
* allow core-tests from backend
* downgrade linting to warn
2026-07-15 12:23:53 +00:00
Exerra c069020aac docs(README.md): add Apple Music to supported sources list
Updated the README to include Apple Music in the list of supported scrobbling sources with a link to its documentation.
2026-07-15 13:52:53 +03:00
Exerra f84a0f190d test(applemusic): add integration tests for Apple Music module
Add new test suite for Apple Music backend logic
2026-07-15 13:39:27 +03:00
FoxxMD d0f43fbd2d feat(ui): Increase virtual play list height 2026-07-15 01:29:12 +00:00
FoxxMD b38168975e feat(ui): Compact filters
* move refresh/loading indicator into list type header
* Remove filter card title to trim filter real estate
2026-07-15 01:22:40 +00:00
Exerra a845ac10ce feat(applemusic): implement top-rebound recovery for duplicate plays
Added logic to detect and recover 'top-rebound' history patterns where Apple Music deduplicates re-listened tracks by bumping them to the top. This ensures intermediate tracks are captured and re-listened top tracks are processed correctly. Includes a new configuration option `recoverUnchangedTopHistory` to toggle this behavior.
2026-07-15 02:44:41 +03:00
Exerra 56fdb12683 feat(sources): update Apple Music configuration and environment variables
Refactored Apple Music source configuration to support token-based authentication via key files and custom headers. Renamed environment variable prefixes from 'AM' to 'APPLEMUSIC' for consistency.
2026-07-15 00:04:14 +03:00
Exerra 1f40e1e414 docs(applemusic): update configuration guide and add APPLEMUSIC_HEADERS
Added documentation for the APPLEMUSIC_HEADERS environment variable and updated code blocks with titles for better clarity in the Apple Music source configuration.
2026-07-15 00:03:06 +03:00
Exerra c1a260dc56 fix(AppleMusicSource): add authentication verification to connection checks
Implemented status code validation for Apple Music authentication and connection checks. The module now throws errors instead of failing silently when the API is unreachable or auth is invalid.
2026-07-14 21:56:59 +03:00
Exerra 5d34ea68af docs: update Apple Music configuration guide
Reorganized the Apple Music documentation to prioritize the Browser Token (Free) authentication method and clarify requirements for the paid MusicKit Key approach.
2026-07-14 21:27:23 +03:00
FoxxMD 41ea9e0aa7 feat(ui): Make timeline items more compact
#500
2026-07-14 15:23:37 +00:00
FoxxMD a9d91c2c8a fix circular buffer 2026-07-14 14:04:19 +00:00
FoxxMD a696436a75 fix: Fix missing early return for skipped stage 2026-07-14 13:47:57 +00:00
Exerra 4ae388676e chore(package-lock.json): update dependencies
Bump node-musickit-api to 3.1.0-next.5
2026-07-14 14:12:42 +03:00
Exerra 89b698d48d docs: add Apple Music source documentation
Add Apple Music to the sources overview table and the main documentation index.
2026-07-14 14:06:20 +03:00
Exerra b71a4cbbd6 build(package.json): bump node-musickit-api to v3.1.0-next.5
Updated node-musickit-api dependency to the latest next version.
2026-07-14 13:08:36 +03:00
Exerra a870cdc6f4 chore(package.json): update node-musickit-api to v3.1.0-next.4
Switched node-musickit-api dependency from a local path to version 3.1.0-next.4 from the registry.
2026-07-14 01:11:29 +03:00
Exerra c404dd5396 feat(applemusic): add support for custom headers in API requests
Introduced a `headers` configuration option to allow setting custom request headers, such as 'Origin', for Apple Music API requests. Updated configuration schema and source implementation to apply these headers.
2026-07-14 01:03:26 +03:00
Exerra cae845028d refactor(AppleMusicSource): use HistoryConsistencyResult type alias
Update parseRecentAgainstResponse return type signature to use the HistoryConsistencyResult alias instead of an inline object definition.
2026-07-14 00:50:58 +03:00
Exerra 1698c5d71e refactor(AppleMusicSource): clarify timestamp calculation logic
Updated comments in applyCalculatedTimestamps to reflect that Apple Music lacks track timestamps, necessitating a hacky estimation method.
2026-07-14 00:48:29 +03:00
Exerra 765d86e02b refactor(AppleMusicSource): extract timestamp calculation to method
Moved the reduceRight logic for calculating play timestamps into a dedicated private method 'applyCalculatedTimestamps' to improve code readability and maintainability.
2026-07-14 00:46:58 +03:00
Exerra f347b82d33 refactor(AppleMusicSource): remove redundant unknown type assertion
Cleaned up the type casting in the AppleMusicSource fetch logic by removing unnecessary unknown assertion.
2026-07-14 00:44:38 +03:00
Exerra 87aa9c461e refactor(AppleMusicSource): replace magic numbers with class constants
Introduced constants for history limits and track polling constraints to improve maintainability and readability within AppleMusicSource.
2026-07-14 00:44:25 +03:00
Exerra 417ce85bc7 refactor(AppleMusicSource): improve type safety and code readability
Refactored AppleMusicSource to use defined types for history consistency, updated the getRecentlyPlayedTracks limit type, and renamed variable for clarity.
2026-07-14 00:42:01 +03:00
Exerra c8d917cfe6 refactor(AppleMusicSource): replace AppleMusicTrack interface with Song type
Removed local AppleMusicTrack interface and updated formatPlayObj to utilize the shared Song type for improved type consistency.
2026-07-14 00:34:47 +03:00
Exerra 8c789123f9 refactor(AppleMusicSource): remove unused backlogged plays logic
Removed the unused `getBackloggedPlays` method and cleaned up the `getRecentlyDiscoveredPlays` logic in `AppleMusicSource` to streamline track processing.
2026-07-14 00:31:06 +03:00
Exerra 06ed3f4388 feat: add Apple Music source support
Implement Apple Music source, including configuration types, environment variable handling, and source initialization logic. Refactored SourceType definitions to improve maintainability.
2026-07-14 00:24:44 +03:00
FoxxMD fab2e4938d feat(ui): Persist log window state #500
Store opened state, and position/size, to local storage so logs stay where user wants them across refreshes/initial load.

Resets window to default position if any part of log window is outside viewport bounds on open.
2026-07-12 16:19:13 +00:00
FoxxMD fbcd1e1b9a refactor(ui): Fix conditional hook for SSE and add stories for header elements 2026-07-12 15:43:33 +00:00
FoxxMD d48f2bd4ac feat(ui): Replace now playing player with summary with reduced motion #500 2026-07-11 20:28:13 +00:00
FoxxMD e2dad463f6 feat: reduce now playing animation #500 2026-07-11 20:05:20 +00:00
FoxxMD 642af13f3c fix(ui): fix shiki instance creation 2026-07-10 21:26:51 +00:00
FoxxMD 4146b159bd feat(ui): Component list container max width based on selected grid width 2026-07-10 21:11:13 +00:00
FoxxMD 3a3a97132d fix jellyfin import? 2026-07-10 21:03:06 +00:00
FoxxMD 04a5b91694 feat(ui): Implement grid for desktop layout
Allow user-selected max grid width on non-mobile breakpoints

#500
2026-07-10 20:57:03 +00:00
FoxxMD 945f494a2e fix: top-level type import syntax
see eslint.config.js comments
2026-07-10 16:47:38 +00:00
FoxxMD 4b09909b33 update cacheable for per-operation ttl 2026-07-10 15:17:01 +00:00
FoxxMD a5a1365b72 chore: remove tsx from mocha extension 2026-07-10 15:16:42 +00:00
FoxxMD 6bc618c481 always cache mb url so we can log to transform input 2026-07-10 15:16:31 +00:00
FoxxMD 85d1a0e648 chore: fix code styling in musicbrainz transformer 2026-07-10 15:15:57 +00:00
FoxxMD 1ae45c6060 add npm script for generating esbuild bundle metadata 2026-07-10 13:34:15 +00:00
FoxxMD 7daa43a883 tree-shake shiki for chakra usage 2026-07-10 13:34:15 +00:00
FoxxMD f8501b2a2e chore: Remove tsx usage from vscode launch profiles 2026-07-10 13:34:15 +00:00
Matt Foxx 14c35edadf Merge pull request #633 from FoxxMD/node-ts-native
feat: Migrate to native node runtime everywhere
2026-07-09 16:25:27 -04:00
FoxxMD cbb9774a18 chore: remove tsx and usage in npm scripts 2026-07-09 20:24:16 +00:00
FoxxMD 7b1eb7c2c1 disable flaky test 2026-07-09 20:06:13 +00:00
FoxxMD 8c8d1e1673 chore: Configure no-unused-vars 2026-07-09 20:01:08 +00:00
FoxxMD fbdd504453 fxi: Fix linting rules related to functions and error causes 2026-07-09 19:52:13 +00:00
FoxxMD 612a90d7e7 fix: Fix many useless or missed variable assignments 2026-07-09 19:43:11 +00:00
FoxxMD de8ad60db8 allow no-empty-object-type with single extends interfaces 2026-07-09 19:34:24 +00:00
FoxxMD 43fd8ea807 refactor: autofix (eslint) prefer-const prefer-as-const and var rules 2026-07-09 19:33:54 +00:00
FoxxMD ec3a7e2d20 fix: Fix case block declarations 2026-07-09 19:20:26 +00:00
FoxxMD 981a211e56 refactor: remove all unused imports 2026-07-09 19:04:40 +00:00
FoxxMD c42b5cacaa refactor: Move files/imports to implement folder import isolation 2026-07-09 18:31:18 +00:00
FoxxMD 919907f1cb feat: Add eslint rules to enforce folder import boundaries 2026-07-09 18:14:31 +00:00
FoxxMD 9eac9fdfa1 chore: prevent vscode from reporting comments in config json are errors 2026-07-09 18:14:01 +00:00
FoxxMD 86cea49ed4 fix(ci): Use node for stanity run 2026-07-09 13:31:02 +00:00
FoxxMD 8fc892a738 test: Fix db error test using transient db 2026-07-09 13:27:55 +00:00
FoxxMD fd591be3d6 remove tsx from mocha setup 2026-07-09 13:27:39 +00:00
FoxxMD 63b23689a4 remove debug file 2026-07-09 13:27:27 +00:00
FoxxMD 3035d4c5e8 feat(docker): Remove tsx and typescript dependency from build 2026-07-09 12:58:15 +00:00
FoxxMD 7891133002 fix remaining type imports preventing docker container from running with tsx 2026-07-09 12:26:56 +00:00
FoxxMD 66db4d017e more fixes to get all tests passing 2026-07-09 12:17:03 +00:00
FoxxMD 15e55dc6c5 more refactoring to remove server packages from bundled vite build 2026-07-09 04:13:28 +00:00
FoxxMD 239fb5919e fix(ui): Exclude discord.js from vite deps 2026-07-09 02:54:44 +00:00
FoxxMD 7e53553a8e more fixes for file extensions 2026-07-09 02:36:51 +00:00
FoxxMD 4bd0345d1b replace file extensions and more import type fixes 2026-07-09 02:27:41 +00:00
FoxxMD b207109697 add allowImportingTsExtensions compiler option 2026-07-09 02:03:03 +00:00
FoxxMD 77de2a7526 fix remaining erasure issues 2026-07-09 01:59:58 +00:00
FoxxMD 69b19da6aa fix(eslint): ignore no-undef 2026-07-09 01:59:46 +00:00
FoxxMD f2e2d67668 initial work for using erasable types 2026-07-08 21:14:34 +00:00
FoxxMD 9c44ccb663 chore(release): bump version for release 2026-07-08 17:25:23 +00:00
FoxxMD f431f4d5af refactor(ui): Remove non-mobile sidebar and ad header links
* Remove non-mobile sidebar to free up some more screen real estate
* Add quick Links menu to header that hides on mobile breakpoint
2026-07-08 16:49:37 +00:00
FoxxMD be872d5ce1 fix(ui): Fix double mobile menu icon 2026-07-08 16:09:04 +00:00
FoxxMD 0246f7dfa6 fix(now playing): Fix realtime NP state handling
* Revert removing state on "should clear" statuses, causing false positive updates
* Insteat, filter out NP state to api based on "should clear" statuses
2026-07-08 15:43:42 +00:00
FoxxMD b57f325684 feat: Implement error persistence and live updated for components 2026-07-08 15:02:02 +00:00
FoxxMD 153f37e927 standardize props and components used in timeline 2026-07-08 14:01:11 +00:00
FoxxMD de4cb8a5c2 fix(ui): Conditionally render queue timeline items based on timestamp sameness and context 2026-07-08 13:38:18 +00:00
FoxxMD eb133e4f7e fix(ui): Fallback datetime for scrobble timeline item 2026-07-08 13:32:52 +00:00
FoxxMD a3e056e7c5 feat: Implement virtual states to make filtering play state easier
* Convert 'queued' and 'dead queued' play states to queue filters
* Fix relation filter sql generation for count query
2026-07-08 13:25:41 +00:00
FoxxMD 7d8b00ab22 fix(musicbrainz): Fix finding stage inputs in error causes 2026-07-07 20:33:15 +00:00
FoxxMD 8b633dd901 feat(musicbrainz): Store all queries to lifecycle inputs and persist even on errors
Should make MB debugging easier
2026-07-07 20:05:10 +00:00
FoxxMD f055cf683f feat: Add toJSON to custom errors so they serialize correctly automatically 2026-07-07 18:19:05 +00:00
FoxxMD baaa954f31 chore: Add eslint plugin for mocha tests 2026-07-07 17:54:19 +00:00
FoxxMD c727de9c40 refactor(ui): Refactor timeline items to be rendered independently and order by createdAt 2026-07-07 17:42:27 +00:00
FoxxMD e6f4a1dbd2 feat(client): Implement createdAt dates for scrobble actions 2026-07-07 16:37:45 +00:00
FoxxMD 3d6e86f258 feat(ui): Add queue states to timeline 2026-07-07 15:21:29 +00:00
FoxxMD e6130eb5eb feat(ui): Better error/warning indicators for timeline 2026-07-07 14:23:06 +00:00
FoxxMD 97b6042768 feat(ui): Implement basic error summary detection 2026-07-07 03:07:29 +00:00
FoxxMD b3c1ce6d8a feat(ui): Indicate failed scrobble is dead queued 2026-07-07 02:32:35 +00:00
FoxxMD 5daba47ac7 fix(ui): Fix conditional hook rendering 2026-07-06 20:08:18 +00:00
FoxxMD 8d7760df6d chore: Update eslint config to include react hooks rules 2026-07-06 20:07:51 +00:00
FoxxMD 75c95fdaa8 more error boundaries 2026-07-06 18:53:57 +00:00
FoxxMD e874ccc2d3 Add some error boundaries around components 2026-07-06 18:34:32 +00:00
FoxxMD 17e97b3a6a fix(ui): Fix now playing mode for player on client component details 2026-07-06 18:18:58 +00:00
FoxxMD c6389590fe fix api fixture typing for players 2026-07-06 18:05:52 +00:00
FoxxMD 7151d96b59 feat(ui): Implement log copy 2026-07-06 18:03:38 +00:00
FoxxMD b2b2018764 feat(ui): Use custom hook for player queries and fix now-playing forced re-render 2026-07-06 17:07:46 +00:00
FoxxMD 655b97ce1c feat(ui): Implement now playing ui element
* Reuse source player in always-nowplaying mode, reuse api structure
* Add expiration to player data to stop rendering player for non-realtime clients
2026-07-06 16:40:01 +00:00
FoxxMD 5c6edefc56 feat(ui): track virtual play key by uid rather than index
Should prevent pop-in and false update-indicator triggering
2026-07-02 21:32:48 +00:00
FoxxMD bf7fb4f558 feat(storybook): More accurate play list api mocking
* Reusable function for generic behavior
* Append to list and create unique plays on every page request
2026-07-02 21:32:02 +00:00
FoxxMD 32b64ff384 fix update icons not expiring 2026-07-02 20:00:04 +00:00
FoxxMD f6e0f4be4a feat(ui): Use play updatedAt field for determining updated icon 2026-07-02 19:44:19 +00:00
FoxxMD fb66f0ca84 feat(db): update updatedAt fields automatically 2026-07-02 19:43:48 +00:00
FoxxMD c4b1d72f3f feat(ui): Implement plays refresh 2026-07-02 15:55:37 +00:00
FoxxMD fb452eb40b feat(ui): try to constrain date picker size for mobile 2026-07-02 14:37:52 +00:00
FoxxMD d3fd03a78c feat(ui): Wrap all filters 2026-07-02 14:28:57 +00:00
FoxxMD 7b04e76c3b fix(ui): Accessing target/children when no ref, yet 2026-07-02 14:13:54 +00:00
FoxxMD 9f34c45192 fix(ui): Fix n+1 insertion bug on new play and add logging 2026-07-02 14:07:46 +00:00
FoxxMD 7ab0f710ff feat(ui): Better control over ephemeral updates to plays
* Use structuralSharing to add signal that play data was updated from invalidated query
* Make update badge more generic and fix timeout/re-render
* Play update story updates random play
2026-07-02 14:01:28 +00:00
FoxxMD ea1fb54de1 fix(ui): Revert datepicker formatting for now
Causing end date to jump back one day after every change?
2026-07-02 12:29:31 +00:00
FoxxMD 35fd84a1d0 feat(ui): Improve date picker useability
* reduce preset options to make smaller viewports easier to use
* Add icon to mobile users can avoid keyboard popup
* Disable openOnClick to avoid popup annoyance when user is trying to directly type dates
2026-07-02 01:07:20 +00:00
FoxxMD e498db8ad3 feat(ui): Implement flex wrapped hook 2026-07-01 22:44:17 +00:00
FoxxMD 145960ca04 feat(ui): Implement placeholder component state actions 2026-07-01 20:23:16 +00:00
FoxxMD 91ba24e165 feat(ui): Add placeholder primary actions from component state 2026-07-01 19:49:08 +00:00
FoxxMD 66fc7a2b09 feat(ui): Add back button on component details 2026-07-01 18:30:44 +00:00
FoxxMD 97a7c7044c feat(ui): Implement play actions in summary 2026-07-01 17:57:07 +00:00
FoxxMD 53d7de7e8d refactor(ui): Use custom hook for activity fetching 2026-07-01 17:12:55 +00:00
FoxxMD 32da14c08e make entire component header a link to details 2026-07-01 00:33:45 +00:00
FoxxMD c7f370f121 feat(ui): de-emphasize mode badge 2026-07-01 00:31:48 +00:00
FoxxMD 9d105173da refactor(storybook): More re-organizing 2026-06-30 22:47:47 +00:00
FoxxMD 3e7bbab5b0 refactor(storybook): organize storybook file and loglical 2026-06-30 21:03:14 +00:00
FoxxMD e04965eb35 fix(storybook): Fix router wiring for component list stories 2026-06-30 20:41:51 +00:00
FoxxMD f2c5e82665 keep names and sourcemap on build? 2026-06-30 20:28:07 +00:00
FoxxMD 4c41f0976d Add placeholder action buttons to play detail 2026-06-30 20:27:57 +00:00
FoxxMD db333184cc fix(ui): Fix text alignment in timeline titles 2026-06-30 20:27:38 +00:00
FoxxMD a5963a2333 (bad) ignore weird type error on cause unknown 2026-06-25 15:38:38 +00:00
FoxxMD 0fe81d6164 fix(ui): Fix content wrapping in detailed component 2026-06-25 15:13:52 +00:00
FoxxMD 3ad9f5dcac Add api fixture for generating fake errors 2026-06-25 15:13:27 +00:00
FoxxMD d39abe40c6 feat(ui): Hide error stacks at sm and below 2026-06-25 15:12:46 +00:00
FoxxMD 6f8ca72ccf fix(db): Fix accessing undefined lifecycle during retention cleanup 2026-06-24 19:29:35 +00:00
FoxxMD 2ae32ee19f feat(ui): Polish error alert 2026-06-24 19:21:15 +00:00
FoxxMD 2ac89c5db3 fix: Serialize errors at api boundary and fix recursive cause bug in error alert render 2026-06-24 18:27:34 +00:00
FoxxMD b0db1dd8bc feat(ui): Add error boundaries and better error detection for rendering 2026-06-24 17:18:26 +00:00
FoxxMD a603be6e22 fix(ui): Fix total stats count 2026-06-24 16:12:58 +00:00
FoxxMD 7ad23a76de fix(ui): Fix component summary not rendering live updates when no initial players 2026-06-24 15:51:48 +00:00
FoxxMD 4481646153 refactor(ui): Move query functions into factory 2026-06-24 15:51:26 +00:00
FoxxMD 5d2c9b557f refactor(ui): Move component player live add/delete into players container 2026-06-24 15:17:54 +00:00
FoxxMD eb69ae48f1 fix(ui): Ok to ignore empty error when rendering error alert 2026-06-24 14:19:54 +00:00
FoxxMD c7479b2f00 fix(ui): Fix player keys and use of floats 2026-06-24 14:18:46 +00:00
FoxxMD 8ae7a8d338 feat(ui): Implement live play insert 2026-06-24 14:14:17 +00:00
FoxxMD 7573c762c0 fix(db): Include input in created play data since some systems depend on this existing 2026-06-24 14:14:03 +00:00
FoxxMD 6d503a1a15 fix(storybook): Fix duplicate msw workers due to vite hot reload 2026-06-24 14:13:19 +00:00
FoxxMD 94d3ea5da8 fix: Fix typing for play update events 2026-06-24 01:10:05 +00:00
FoxxMD e998006e6c feat(ui): Implement live updates to activity summary and details 2026-06-24 00:52:01 +00:00
FoxxMD 234fc67ab2 refactor(client): Remove unnecessary notifier dependency 2026-06-23 20:05:33 +00:00
FoxxMD 37bb507359 feat(ui): Global sse status indicator 2026-06-23 19:51:14 +00:00
FoxxMD 1237056d59 feat(ui): Implement statuses for clients 2026-06-23 19:50:54 +00:00
FoxxMD 7174702f7b feat(ui): Implement status and state updates for sources 2026-06-23 18:44:19 +00:00
FoxxMD 3b721673c8 refactor(ui): Replace native links with react-router links 2026-06-23 16:10:52 +00:00
FoxxMD b64f0d2dd5 fix(ui): Fix color contrast for log lines 2026-06-23 16:03:20 +00:00
FoxxMD 7738dc004a feat(ui): Animate sleep indicator 2026-06-23 15:54:34 +00:00
FoxxMD 5c5563a917 Fix layout of state badge and status in component details 2026-06-23 15:48:32 +00:00
FoxxMD 7d08939a18 feat(ui): Implement sleeping indicator 2026-06-23 15:38:53 +00:00
FoxxMD fabc50aa62 switch back to directdomupdates for virtuallist 2026-06-23 13:40:42 +00:00
FoxxMD 4c0615d427 finally working infinite query loading 2026-06-23 13:31:16 +00:00
FoxxMD b4dd729150 refactor: Replace hardcoded queryopts
* Convert to json with deepreplacevalue
* hydrate dayjs at api boundary with generic object walker
2026-06-23 12:33:18 +00:00
FoxxMD f336089755 fix(ui): Fix header icon 2026-06-22 20:38:28 +00:00
FoxxMD 4fc6285081 fix: remove import that not longer exists 2026-06-22 20:26:04 +00:00
FoxxMD 0cf3e33fe6 fix artist alignment 2026-06-22 20:24:39 +00:00
FoxxMD ab424aee0d feat(ui): Implement track/artist/album text search 2026-06-22 20:21:54 +00:00
FoxxMD 9fb55d479d feat(ui): Add play count total and per day 2026-06-22 19:14:22 +00:00
FoxxMD c8fb01bbab Improvements to infinite querying 2026-06-22 18:00:00 +00:00
FoxxMD f008c4074d feat(ui): Implement infinite queries 2026-06-22 16:54:47 +00:00
FoxxMD d66922c99a Improve layout for activity summary 2026-06-22 16:16:05 +00:00
FoxxMD c7689199cc fix styling for filters 2026-06-22 15:21:49 +00:00
FoxxMD 9a8b6bfa09 feat(ui): wire up play filters to api 2026-06-22 14:47:44 +00:00
FoxxMD 45c8141137 with card 2026-06-20 02:34:52 +00:00
FoxxMD 4e7b3e9ceb better styling 2026-06-20 02:30:51 +00:00
FoxxMD dfcc9c32a8 partially working layout for filters 2026-06-20 02:17:00 +00:00
FoxxMD a3d891aa2f Add activity list heading 2026-06-19 20:52:46 +00:00
FoxxMD 088ae4a26a default to virtual list 2026-06-19 20:32:16 +00:00
FoxxMD f425b5a906 disable wdyr
causing issues with storybook
2026-06-19 20:11:15 +00:00
FoxxMD a4ddaeff61 install react-compiler 2026-06-19 20:10:55 +00:00
FoxxMD 8932224b57 add why-did-you-render for debugging 2026-06-19 20:00:48 +00:00
FoxxMD ffe2203ba5 implement virtual list with tanstack/virtual 2026-06-19 19:30:08 +00:00
FoxxMD 987819cc7c fix missing key warnings on react nodes 2026-06-19 15:50:39 +00:00
FoxxMD 974a017e5a feat(ui): Implement query-key-factory and activity summary fetchable 2026-06-19 15:39:58 +00:00
FoxxMD 594a59347e refactor activity summary into own component 2026-06-19 14:09:36 +00:00
FoxxMD b0970c6653 chore: standardize component type 2026-06-19 13:47:54 +00:00
FoxxMD d8017dda62 fix: fix typing on api fixture for queues 2026-06-18 20:33:20 +00:00
FoxxMD a8c3e88ec9 fix(ui): Fix progress background when in a container 2026-06-18 20:31:39 +00:00
FoxxMD 7bf31a7fc7 add chevron left button 2026-06-18 20:26:11 +00:00
FoxxMD deb3310e3f fix: Fix preserving play original data until it is persisted 2026-06-18 20:18:15 +00:00
FoxxMD 5450b48eb3 fix(ui): correct query args for showing plays by seen/desc 2026-06-18 20:17:50 +00:00
FoxxMD 70a94cff9b fix(ui): Fix showing error indicator when error is null 2026-06-18 20:17:32 +00:00
FoxxMD ff31259092 feat(ui): Implement fetchable play lists and detailed components 2026-06-18 19:41:02 +00:00
FoxxMD 8b4f1849f6 feat: Implement api endpoints for individual components, plays, and individual plays 2026-06-18 19:40:29 +00:00
FoxxMD 110ffad7d7 docs: Update atproto descriptions 2026-06-18 16:49:35 +00:00
FoxxMD 62a0670b4d Add players to detailed source component 2026-06-18 15:54:00 +00:00
FoxxMD 7a1142fdd5 actions placeholder 2026-06-18 15:20:58 +00:00
FoxxMD 5def3cde99 fix(ui): Fix accordion context 2026-06-18 14:54:27 +00:00
FoxxMD 075fa877ed Move player tooltip to bottom right position 2026-06-18 14:36:22 +00:00
FoxxMD 6ffb46a65a chore: Fix storybook theming, again 2026-06-18 14:12:21 +00:00
FoxxMD ac5f34ea5f fix(ui): Fix width of tooltip popover 2026-06-18 14:09:48 +00:00
FoxxMD 9975f377d0 fix(ui): Fix colors in player buffer tooltip to match system colors with contrast 2026-06-18 14:05:55 +00:00
FoxxMD 76b4606d17 chore: Use system theme for storybook 2026-06-18 14:05:36 +00:00
FoxxMD 1244e0ee3e fix(ui): Use more lenient css selectors for progress bar 2026-06-18 13:53:15 +00:00
FoxxMD c56b16e2e6 fix: Fix auth cache validation and fallback 2026-06-18 13:43:10 +00:00
FoxxMD 831fd420ff feat(ui): Add player buffer tooltip 2026-06-18 13:27:16 +00:00
FoxxMD 2125f92bd8 feat(ui): Implement player buffering real time positiono 2026-06-18 12:42:26 +00:00
FoxxMD 42c9383dda partial buffered player updates working 2026-06-18 03:06:53 +00:00
FoxxMD f5eab006f5 feat(ui): Implement buffering player progress with mui 2026-06-18 02:19:08 +00:00
FoxxMD 5a2c664fe1 fix(atproto): Fix rate limit expiration and display 2026-06-18 00:56:30 +00:00
FoxxMD d7cbb7c9bd fix: Fix missing implementation on test component 2026-06-17 21:22:20 +00:00
FoxxMD 8afe30bfd4 feat(ui): Implement stats, stat change indicator, and iniitial component detail 2026-06-17 21:19:18 +00:00
FoxxMD 24b67fc430 feat(ui): Implement better live stat indicators 2026-06-17 19:59:06 +00:00
FoxxMD d01a00ad13 feat(atproto): Implement rate limit checks 2026-06-17 17:02:19 +00:00
FoxxMD ac250eba39 feat(ui): Implement real state reporting for components 2026-06-17 14:56:47 +00:00
FoxxMD 778a2d6565 feat(ui): add activity indicator to logs panel 2026-06-17 13:57:19 +00:00
FoxxMD 0b9a7b78df feat(ui): Live player add/remove based on sse updates 2026-06-17 13:24:23 +00:00
FoxxMD 6b93e839fa fix(atproto): fix not throwing applogin exception 2026-06-17 01:56:55 +00:00
FoxxMD 7e6040ce7b fix(ui): Fix accessing components before db is ready 2026-06-17 01:46:45 +00:00
FoxxMD d4b2057c41 fix: fix nullish access of dbcomponent during testing 2026-06-17 01:44:26 +00:00
FoxxMD bc04603fb4 fix: closest match needs id to update updatedAt 2026-06-17 01:42:37 +00:00
FoxxMD ba2a23e039 fix: Fix app migrations table name inconsistency 2026-06-17 01:24:06 +00:00
FoxxMD 6bfe203a34 fix(atproto): Fix not throwing on applogin error 2026-06-17 01:08:40 +00:00
FoxxMD 8c6f34ebc7 fix: Guard against undefined synced reason 2026-06-17 01:05:48 +00:00
FoxxMD 18e20123c2 fix(ui): fix z-index on logs panel 2026-06-16 22:07:54 +00:00
FoxxMD dc44f6c921 feat(ui): Implement fetchable logs with filtering 2026-06-16 20:46:51 +00:00
FoxxMD a19fd42a5b feat(ui): Implement float logs 2026-06-16 20:15:17 +00:00
FoxxMD 206fd62f70 feat(ui): Splitter logs 2026-06-16 19:30:12 +00:00
FoxxMD 6123503ee8 feat(ui): Implement logs component 2026-06-16 18:12:54 +00:00
FoxxMD b751c6f5f9 feat(ui): Implement side nav 2026-06-16 15:33:55 +00:00
FoxxMD d1ef09ba0d feat(ui): Implement header 2026-06-15 21:08:29 +00:00
FoxxMD d073642203 feat(ui): Implement live updates with sse 2026-06-15 19:17:50 +00:00
FoxxMD 9bb48fbf13 POC player live update 2026-06-15 17:17:08 +00:00
FoxxMD bf8f1175ce feat(ui): Implement static component list in app entrypoint 2026-06-15 14:43:13 +00:00
FoxxMD 4bfcc40571 poc multi page 2026-06-12 17:57:54 +00:00
FoxxMD 892d035d7a feat(ui): Implement component summary list 2026-06-12 16:03:07 +00:00
FoxxMD d4019e6dea feat(ui): Implement Player and api fixtures 2026-06-11 20:48:10 +00:00
FoxxMD 3ce94f443a feat(ui): Implement component overview and api fixtures 2026-06-11 18:55:11 +00:00
FoxxMD b863a9773a better optimization of activity details 2026-06-11 00:18:46 +00:00
FoxxMD 489d7d12cb improvements to play list and story 2026-06-11 00:18:36 +00:00
FoxxMD 63c7ea7809 fea(ui): Implement tanstack-query for ActivityDetails and mock in storybook 2026-06-10 20:44:51 +00:00
FoxxMD a6a019e9fd activity ui improvements 2026-06-10 19:45:13 +00:00
FoxxMD dbd1c81c90 update timelline component
* make activity optional with fallback loading render
* fix storybook default args with constant
2026-06-10 19:06:13 +00:00
FoxxMD 2b42b40c0a update storybook 2026-06-10 19:05:01 +00:00
FoxxMD 4230674c2c some ui fixes 2026-06-10 17:36:53 +00:00
FoxxMD b0955270ba refactor: Remove indexed prop from PlayMeta
* Remove indexed any prop so meta is stricter (better catching bugs)
* Implement mergeable generic with meta where we do need extra prop
* Fix bad usage of meta now that indexed prop is gone
2026-06-10 01:54:35 +00:00
FoxxMD a194f752bb refactor: Remove lifecycleless types 2026-06-10 01:54:35 +00:00
FoxxMD 4180ae0c6b feat(migrations): Implement play lifecycle location migration 2026-06-10 01:54:35 +00:00
FoxxMD 3227541f34 feat(db): Add unix timestamp to database bakup file and fix test for detecting it 2026-06-10 01:54:35 +00:00
FoxxMD e949da3830 refactor: Move all lifecycle properties to top-level Play
And remove lifecycle from meta
2026-06-10 01:54:35 +00:00
FoxxMD e13d86b1d0 feat: Add more identying data to lifecycle step 2026-06-10 01:54:35 +00:00
FoxxMD f7577c43e0 refactor: Move scrobble to top level of play object 2026-06-10 01:54:35 +00:00
FoxxMD f3531f41ec feat: Add creation timestamps to lifecycle data 2026-06-10 01:54:35 +00:00
FoxxMD d9d37c68fc Implement api fixtures 2026-06-10 01:54:35 +00:00
FoxxMD 3bb887763f refactor: Move original play data to top-level property in play
* Simplifies lifecycle
* Simplifies play generation for testing
2026-06-10 01:54:35 +00:00
FoxxMD c65504ee9f feat(ui): Define initial API contract 2026-06-10 01:54:35 +00:00
FoxxMD 373fdb0dc2 fix(ui): Gaurd against undefined code prop 2026-06-10 01:54:35 +00:00
FoxxMD 825d0da532 fix(ui): Gaurd againast missing duration 2026-06-10 01:54:35 +00:00
FoxxMD 2efdada4c0 fix(musicbrainz): Fix default assignment of weights in stage config
Should not assign a default value so that stage defaults are not overriden in stage config when no explicit config is given.

Fixes #627
2026-06-10 01:41:41 +00:00
Matt Foxx 01afe9006a Merge pull request #626 from FoxxMD/lzImport
fix(listenbrainz endpoint): `import` handling and error responses
2026-06-09 11:48:24 -04:00
FoxxMD da9edb2116 feat(lzendpoint): Improved error handling
* Return error response when no sources found by request, or none configured
* try-catch and return well-formatted error response if source handling fails
2026-06-09 13:42:54 +00:00
FoxxMD d5c886d718 fix(listenbrainz): Handle 'import' listen_type with multiple scrobbles
#625
2026-06-09 13:28:44 +00:00
FoxxMD e99351407e fix(musicbrainz): Fix order of release priority list
Should be reversed since we use index as score, so "first" in the list should have the highest index/score

#624
2026-06-08 15:38:55 +00:00
Matt Foxx d9184fa350 Merge pull request #623 from FoxxMD/mpdArtistAssignment
fix(mpd): Assign empty array if artists not defined
2026-06-07 22:22:38 -04:00
Matt Foxx e4af1e3f18 Merge pull request #619 from FoxxMD/atprotoHistory
feat: Implement historical scrobble querying for atproto clients
2026-06-07 11:51:33 -04:00
FoxxMD 9ca4f3fa62 fix(mpd): Assign empty array if artists not defined
#621
2026-06-07 15:47:43 +00:00
FoxxMD 20e3f22f3f docs(azuracast): Add clearer guidance on station configuration and access 2026-06-05 19:55:14 +00:00
FoxxMD bca9e195c9 feat(scrobblers): Detect sync gap and resolve sync status if filled 2026-06-05 19:10:29 +00:00
FoxxMD 8b1765cb03 fix: Fix missing type in prometheus stats 2026-06-05 15:21:34 +00:00
FoxxMD 0605cf1fd5 feat: Implement compaction prometheus statistics 2026-06-05 15:05:53 +00:00
FoxxMD 07d6487875 feat: Implement database play prometheus stats
* Total plays by component/state
* Total historical plays by client
2026-06-05 14:54:29 +00:00
FoxxMD 6222aa5899 fix(rocksky): Do not persist scrobble payloads as historical plays 2026-06-05 13:33:04 +00:00
FoxxMD 47f61b491e fix: Fix tables used in historical play repository 2026-06-05 13:23:59 +00:00
FoxxMD 42818c51c1 feat(rocksky): Update configuration and document new token 2026-06-04 20:44:24 +00:00
FoxxMD a0fee4184e chore(rocksky): Bump version to get new exports 2026-06-04 20:23:26 +00:00
FoxxMD 470a70f951 feat(rocksky): Implement historical scrobbles 2026-06-04 20:07:08 +00:00
FoxxMD 2d2b3a6d48 feat(rocksky): Implement native sdk 2026-06-04 19:18:14 +00:00
FoxxMD 6f40dd387e chore(atproto): Remove unused @atproto packages 2026-06-04 17:58:12 +00:00
FoxxMD 2445336ec0 refactor(atproto): Remove unused oauth implementation
Oauth will need a larger, ground-up rewrite if/when its eventually done. Remove the old, unusued implementation for now to reduce complexity.
2026-06-04 17:54:41 +00:00
FoxxMD 41d181e02f refactor: Replace @atproto with @atcute for abstract/app api implementation 2026-06-04 17:50:40 +00:00
FoxxMD ff158c99cd refactor: Move some stateless functions out of atproto class 2026-06-04 16:05:58 +00:00
FoxxMD c1cdcd016a refactor: Move more atproto-generic function into abstract api base 2026-06-04 15:37:01 +00:00
FoxxMD fcb9092f8a refactor: Rename bluesky to atproto, classes 2026-06-04 15:14:45 +00:00
FoxxMD ba2bd0cc8a refactor(teal): Refactor atproto api implementation out of tight teal coupling 2026-06-04 15:12:37 +00:00
FoxxMD f224ce6b6a refactor: Rename bluesky to atproto 2026-06-04 14:51:49 +00:00
FoxxMD c74678e9ef feat(scrobbler): Improve historical scrobbler hydration
* Refactor post init behavior into promise so we can fallback to recent sync if full hydration fails
  * This way user can still compare real time scrobble activity without full hydration
* Simplify sync status usage
  * Log reason based on presence of sync error
  * Always try to do full hydration if not synced
* Fix missing logging for hydration error
* Add MS-scrobbled scrobbles to historical database
2026-06-04 13:53:08 +00:00
FoxxMD 1b1770ff29 chore(release): Bump version for release 2026-06-03 19:20:22 +00:00
Matt Foxx 41d3a63c42 Merge pull request #615 from FoxxMD/artistCreditCleanup
fix: Add missing artist credit transforms
2026-06-03 15:07:46 -04:00
FoxxMD 52240aa13b feat(teal): Implement historical scrobble searching for existing scrobbles and auto hydrate, or sync recent, on init 2026-06-03 19:06:26 +00:00
FoxxMD 95d7d276d7 refactor(teal): Generate and use real lexicon definitions for tealfm implementation
Removes hand-rolled interfaces and generates interfaces+validation for official lexicon definitions
2026-06-03 18:14:20 +00:00
FoxxMD 18c520ce2f feat(tealfm): Stream repo CAR to monitor download progress 2026-06-03 16:33:40 +00:00
FoxxMD fb65cb222a fix: fix rebase conflicts 2026-06-03 16:33:33 +00:00
FoxxMD c4f028fd2c feat(tealfm): Implement historical scrobble hydration 2026-06-03 16:33:24 +00:00
FoxxMD b85452f5c6 feat: Implement historical scrobble client abstract class 2026-06-03 16:32:16 +00:00
FoxxMD 6546ee3db2 Add package for atproto repo car handling 2026-06-03 16:29:57 +00:00
FoxxMD f0e798c052 fix: Add missing artist credit transforms
Fixes #613
2026-06-03 13:24:32 +00:00
FoxxMD 44424f2570 fix: more logging and arg fixes after re-generating lock file 2026-06-03 13:24:10 +00:00
FoxxMD 72df520300 chore: re-generate lock file
* Caused by npm/cli#6301
* will make packaging for nix easier NixOS/nixpkgs#519119
2026-06-03 12:54:31 +00:00
FoxxMD 25c783051d fix: Fix argument order for logger labels 2026-06-03 12:50:16 +00:00
FoxxMD 264bc31af6 Merge branch 'storybookRefresh' 2026-06-02 14:11:04 +00:00
FoxxMD e0bdb8fe3c docs: Fix typo in jriver docs 2026-06-02 12:52:09 +00:00
FoxxMD 4d7c93f7dc fix(maloja): Fix source maloja envs
#610
2026-06-01 22:32:15 +00:00
FoxxMD dd54075c52 docs: Fix bad config example for id on aio in 0.14.0 upgrade 2026-06-01 19:37:02 +00:00
FoxxMD ff08b6327d docs: Comment out required upgrade callout, for now
Unnessary information since there is nothing > 0.14.0. May confuse some users. Can uncomment after 0.14.1 or later.
2026-06-01 19:27:09 +00:00
FoxxMD 76392a9668 chore(release): Bump version for release 2026-06-01 18:45:20 +00:00
FoxxMD f47faabf7c docs: Remove example of caching for transform best practices
Example is already in the main cache configuration docs. Consolidate/remove the transform example so there is only one authorative example in the docs.
2026-06-01 17:30:56 +00:00
FoxxMD 120e280fc8 docs: More upgrade guidance for 0.14.0 2026-06-01 15:22:38 +00:00
FoxxMD 6ae80fd881 feat(docs): Update colors for regular important admonition 2026-06-01 14:51:11 +00:00
FoxxMD be70e7074a fix(docs): Fix css for important admonition details important type 2026-06-01 14:35:02 +00:00
Matt Foxx 65841a8c6b Merge pull request #609 from HiiJax/fixMbIdCaps
fix(tealfm): trackMbid -> trackMbId
2026-06-01 08:40:14 -04:00
Jax 82374fc806 fix(tealfm): trackMbid -> trackMbId 2026-05-31 20:02:09 -04:00
FoxxMD 004400d7ea refactor: Replace jsondiffpatch-react with @pierre/diffs
Good ridance.
2026-05-30 20:02:20 +00:00
FoxxMD d54e169a14 fix for transformstep date 2026-05-30 19:05:36 +00:00
FoxxMD 31c35647dd feat(ui): Update artist rendering to use credits 2026-05-30 19:05:36 +00:00
FoxxMD 204ee159d6 fix(ui): Update JSX namespace to fix missing ambient in react 19 2026-05-30 19:05:36 +00:00
FoxxMD 4fe1f8ced9 chore(release): Bump for beta release 2026-05-30 15:12:25 +00:00
Matt Foxx c26e6f77f5 Merge pull request #608 from FoxxMD/nowPlayingGranular
refactor: Now Playing rewrite to handle realtime client updates
2026-05-30 10:59:40 -04:00
FoxxMD e2b59900e5 fix(listenbrainz): Fix artist credit mapping for minimum track data 2026-05-30 14:59:18 +00:00
FoxxMD c9cde11871 fix(tealfm): Missing function call to statusExpiresSoon 2026-05-29 14:45:42 +00:00
FoxxMD ea0c75ccf3 chore: Simplify gitignore pattern for db files 2026-05-29 14:40:57 +00:00
FoxxMD 13a64bd63a refactor(now playing): Improve now playing to generically handle clients that have real-time updates
* Break out player status checks and thresholds into separate functions
* Consolidate all should update functionality into shouldUpdatePlayingNow for easier testing
* Introduce realtime flag for teal/discord and check if clearing is possible/desired
  * Remove equivalent functionality in individual clients
* (tealfm): Correctly set max threshold using track duration
* (tealfm): Skip clearing update if close to/after expiration time
* (tealfm): Increase min threshold to avoid spamming pds updates for pauses/skip track
2026-05-29 14:40:45 +00:00
FoxxMD c3b23271d4 fix(now playing): Fix acessing undefined play when source player state is reported but without any data
598#issuecomment-4566553387
2026-05-28 17:48:05 +00:00
FoxxMD d047c600c2 feat(tealfm): Update lexicon defs with new mbid uri format
teal-fm/teal#102
2026-05-28 16:13:06 +00:00
FoxxMD b6cae4a538 fix(jellyfin): Handle string or object data for album props when parsing to play
#598#issuecomment-4564522030
2026-05-28 15:08:14 +00:00
FoxxMD 1eed48456c feat: Make artist name to credit function more robust
* artistNameToCredit can now handle partial ArtistCredit object
* Re-use artistNameToCredit for mapping in artistNameToCredits
2026-05-28 15:07:19 +00:00
FoxxMD 20834e812e feat: case-insensitive proxy handles spread/rest 2026-05-28 14:44:02 +00:00
FoxxMD d1e5b11598 chore(release): Bump version for release 2026-05-28 13:05:12 +00:00
FoxxMD c7af346daf docs(lastfm): Document 2 week scrobble window
#606
2026-05-28 12:31:28 +00:00
Matt Foxx 3975edeaf3 Merge pull request #603 from HiiJax/tealfmStatus
feat(tealfm): Add now playing support with fm.teal.alpha.actor.status
2026-05-27 20:43:01 -04:00
Jax 119c8d7fd7 fix(tealfm): avoid nested ternary operators in status expiry 2026-05-27 20:30:25 -04:00
Jax 3a96c28b2d fix(tealfm): status clearing, expiry, and state detection per review 2026-05-27 18:04:29 -04:00
Matt Foxx 6905853aa3 Merge pull request #604 from FoxxMD/listenRangeGuard
fix: Guard against old/bad cached listen range data
2026-05-27 15:52:17 -04:00
FoxxMD 3f1a952e44 fix: Guard against old/bad cached listen range data
#601
2026-05-27 19:25:17 +00:00
FoxxMD 405ee4f6d7 fix(scrobbler): Fix try-catch block so queued scrobble is always added, even if existing queued check fails 2026-05-27 19:24:21 +00:00
FoxxMD 34e0eaefd8 fix(scrobbler): Add migrated play to queue
* Utilize existing methods for added queued/dead scrobbled when migrating from cache
  * Using queueScrobble fixes migration not creating queued state
  * Using addDeadLetterScrobble reduces duplicated code in migration
* Drop listenranges to avoid bad cache data issue (potentially)
2026-05-27 19:19:24 +00:00
FoxxMD 6d4b617409 fix: Add missing sort order to failed/scrobbled api calls
#598#issuecomment-4490136917
2026-05-27 18:19:45 +00:00
Matt Foxx 4195bde081 Merge pull request #600 from nabijaczleweli/master
docs: u{p => t}most typo
2026-05-27 08:28:41 -04:00
Jax 925f3b916d feat(tealfm): Add now playing support with fm.teal.alpha.actor.status 2026-05-26 05:20:31 -04:00
наб 770621ba41 docs: u{p => t}most typo 2026-05-22 20:10:45 +02:00
FoxxMD a00e5d0dbc feat(database): Track component last ready and last active at 2026-05-15 17:21:22 +00:00
FoxxMD 0d6d803df3 feat(database): Implement database structures needed for historical plays 2026-05-15 17:03:48 +00:00
FoxxMD 396e4b922e docs: Overhaul kitchensink 2026-05-15 15:14:29 +00:00
FoxxMD 14ecb57210 fix(docs): Fix missing comma in discord config example 2026-05-15 15:14:12 +00:00
FoxxMD 14369836f6 feat(docs): Add more descriptive error logging for config file parsing 2026-05-15 15:13:52 +00:00
FoxxMD 70e5aaaad5 docs: update kitchensink with ids 2026-05-15 13:09:42 +00:00
FoxxMD 366e668c13 fix(docs): Fix json syntax in sample configs 2026-05-14 20:38:12 +00:00
FoxxMD d0e842ede3 docs: Update ENV configs with ID and name 2026-05-14 20:33:34 +00:00
FoxxMD a0c1f71162 docs: Update examples with id 2026-05-14 20:05:29 +00:00
FoxxMD 7ef159448e feat: Improved retention policy
* Add ENVs for compacting
* Default compacting all data types
* Add rention guidance to docs
2026-05-14 19:48:04 +00:00
FoxxMD b4e6ce6e78 chore(release): Bump the version beta 1 release 2026-05-14 17:40:37 +00:00
Matt Foxx abe75869b1 Merge pull request #588 from FoxxMD/database
0.14.0
2026-05-14 13:35:16 -04:00
FoxxMD 38d7a9cfce feat: Improve error type guards and ui rendering
* Use ErrorLike or ErrorIsh for error utilities, rather than requiring object be an Error instance
* Render error summary on dead scrobble page and have copy action include all error data
* serialize errors when sending through api
* fix error assignment for new dead scrobbles
2026-05-14 16:33:30 +00:00
FoxxMD 83a425a3d4 feat(database): Serialize errors with custom data type 2026-05-14 12:58:50 +00:00
FoxxMD 7ae727a8fe feat(cache): Improve scrobble migration
* Granular persistence of successfully migrated scrobbles
* Don't delete cache after processing
* reduce logging noise and improve wording
* update upgrade wording wrt cache migration
2026-05-14 12:54:29 +00:00
FoxxMD fe4b947d26 fix(koito): Use same now playing threshold as listenrbainz 2026-05-14 01:34:26 +00:00
FoxxMD c5cdc465f3 fix(lastfm): Remove scrobble duration when less than 30 seconds to bypass ignored response
Fixes #596
2026-05-14 00:21:04 +00:00
FoxxMD c86819b0b3 feat(database): Implement cached scrobble migration per-component 2026-05-13 21:00:33 +00:00
FoxxMD 5228d4894c refactor: Simplify init process by using abort controller to detect if init is occurring 2026-05-13 19:55:47 +00:00
FoxxMD e6709c442f feat(database): Implement (with patch) migration context
sandrinodimattia/sqlite-up#3
2026-05-13 15:10:48 -04:00
FoxxMD 0a594d5f83 test: Tighter integration with act 2026-05-13 11:41:29 -04:00
FoxxMD 49be95a4d1 fix(database): Add gitkeep for app migrations empty folder 2026-05-13 11:33:40 -04:00
FoxxMD fbf3af8474 feat(database): Implement app migrations 2026-05-13 14:48:57 +00:00
FoxxMD 146916bc6d feat: Enrich artist and albumartist mbids 2026-05-12 19:01:57 +00:00
FoxxMD a410721acf fix(now playing): Don't update now playing if minimum play information is not met 2026-05-12 18:10:41 +00:00
FoxxMD af5aec2ed3 port changes from pgllite branch
Lots of cleaned up methods and better framing if db backend ever becomes async again
2026-05-12 16:28:36 +00:00
FoxxMD 51b7b3fd40 test(database): Add 10k size stats 2026-05-12 14:52:15 +00:00
Matt Foxx c22867a9b1 Merge pull request #594 from philocalyst/database-latest
Updating everything to latest
2026-05-12 10:51:14 -04:00
FoxxMD f93c1fa4db revert: Remove vite optimize for ansi-to-react
Issue was instead solved by 1f199e28ef
2026-05-12 14:46:54 +00:00
FoxxMD 1f199e28ef fix(ui): Correct for bad ansi export 2026-05-12 14:44:11 +00:00
FoxxMD 811615dd06 fix(docs): Remove skipLibCheck and address React 19 namespace issues per package
* Update hast-util-to-jsx-runtime with npm override
* Re-export JSX as namespace for remaining packages with issues

May be addressed by future package updates or upgrading to docusaurus 3.10.x
2026-05-12 14:23:09 +00:00
𝑷𝒉𝒊𝒍𝒐𝒄𝒂𝒍𝒚𝒔𝒕 fc6ec840da vite: include ansi-to-react
for correct ESM module export
2026-05-12 09:35:27 -04:00
𝑷𝒉𝒊𝒍𝒐𝒄𝒂𝒍𝒚𝒔𝒕 eb2159de27 docsite: added skip lib check
to avoid the react 19 moving errors, until these packages update.
2026-05-12 09:34:13 -04:00
𝑷𝒉𝒊𝒍𝒐𝒄𝒂𝒍𝒚𝒔𝒕 d0a490b200 deps: fix the last conflict 2026-05-11 20:49:18 -04:00
𝑷𝒉𝒊𝒍𝒐𝒄𝒂𝒍𝒚𝒔𝒕 53870ac1f2 core: migrated code to new api surface 2026-05-11 20:40:52 -04:00
𝑷𝒉𝒊𝒍𝒐𝒄𝒂𝒍𝒚𝒔𝒕 d2f8717555 client: migrated code to new api surface 2026-05-11 20:40:42 -04:00
𝑷𝒉𝒊𝒍𝒐𝒄𝒂𝒍𝒚𝒔𝒕 756d9b84e1 deps: updated to latest across the board 2026-05-11 20:40:25 -04:00
FoxxMD a1ad250dcc feat: Improve cache testing and cleanup cache serialization
* Remove ListenProgress specific serialization tests and function since its not needed anymore
* postfix tmp dirs with test name hints for easier debugging
* try to prevent filecache from leaving files behind
2026-05-08 17:30:12 +00:00
FoxxMD f36fd16517 chore: Bump with-local-tmp-dir version 2026-05-08 17:28:47 +00:00
FoxxMD 28ade6ac28 fix: More improvements to dead scrobbler handling and rendering
* re-use dead scrobble removal method for clearing all
* temp fix for rendering queue errors in frontend
* properly decrement queue based on dead scrobble queue status
* display total dead on status card
2026-05-08 15:27:12 +00:00
FoxxMD fa1051b29a feat(client): Allow processing any dead scrobble that is not completed successfully 2026-05-08 15:22:45 +00:00
FoxxMD 3cdbfc337e feat: Implement generic play identifier repo method 2026-05-08 15:21:56 +00:00
FoxxMD 80474a96fe feat: Add dead scrobble delay configurable through debug env 2026-05-08 13:45:11 +00:00
FoxxMD 957db35c30 fix(ui): Gaurd against undefined Source in on failed scrobbled page
#588
2026-05-08 13:44:50 +00:00
FoxxMD 90f0bdb5ef fix(client): Fix dead to queued queueName constraint in the wrong part of the query
Was setting all failed states to dead queue when it should have been a where condition ON dead queue name

#588
2026-05-08 13:30:30 +00:00
FoxxMD 640d944b4c test: Add listenbrainz submit listens example requests for reference 2026-05-08 13:28:55 +00:00
FoxxMD c7fce06480 fix(listenbrainz): Maybe fix null artist_name
#588
2026-05-08 03:01:45 +00:00
FoxxMD 8cffd0d068 fix: Fix resolving config globally
#588
2026-05-08 02:57:22 +00:00
FoxxMD b8a9623def fix: Add neotraverse as production dependency 2026-05-07 20:48:23 +00:00
FoxxMD d922f37359 fix(client): Implement artistcredit conversion during cached scrobble migration 2026-05-07 20:40:44 +00:00
FoxxMD dcc53d1656 docs: Fix links and paths 2026-05-07 20:38:21 +00:00
FoxxMD 0cb20b83b4 feat: Add ID and name envs for all sources/clients 2026-05-07 20:08:29 +00:00
FoxxMD e814cf58fd docs: Add upgrade path for 0.14.0 2026-05-07 18:57:08 +00:00
FoxxMD f211a4a4c4 refactor(cache)!: Simplify cache config
* Reduce storage backend to valkey only (or inferred file for auth)
* Remove metadata and scrobble config options
* Simplify cache init with new config
* Add deprecation/warnings for cache ENVs
* Rewrite/simplify cache docs
2026-05-07 16:38:04 +00:00
FoxxMD 4d7162a1a4 docs: Add admonition 'important' type 2026-05-07 14:50:04 +00:00
FoxxMD a5926d71c1 chore: Bump drizzle to lastest beta 2026-05-07 12:47:16 +00:00
FoxxMD d95f323dc0 feat: Enrich listenbrainz and jellyfin source plays with artist mbids 2026-05-07 02:42:53 +00:00
FoxxMD 1b53d22e00 feat: Refactor artists as an object
Refactor from string to artist so we can support adding mbids etc. directly to artists

#425
2026-05-07 01:15:05 +00:00
FoxxMD 75c0230dae refactor(source): Move heartbeat responsibility into source class
* Will allow more flexibility in startup and stopping/silencing component by user (in the future)
* Remove unused tasks
2026-05-06 20:21:26 +00:00
FoxxMD 630edd7b3f feat(client): Make playing now scheduling part of heartbeat 2026-05-06 20:06:31 +00:00
FoxxMD 092cf907a2 refactor(client): Move heartbeat responsibility into client class
Will allow more flexibility in startup and stopping/silencing component by user (in the future)
2026-05-06 19:42:58 +00:00
FoxxMD 562b388e3e feat(now playing): Reduce logging noise
* Refactor should play methods to return result and reason, rather than always logging reason
* Combine reasons when logging to reduce log statements
* Demote "no update" logging to TRACE, promot "update" logging to VERBOSE
2026-05-06 18:16:42 +00:00
FoxxMD f788894494 fix(source): Remove superfluous interval logging 2026-05-06 18:15:35 +00:00
FoxxMD d0379e1bd6 fix: Simplify and fix getting next dead scrobble
* Use same kind of function behavior as scrobble queue to reduce cognitive load
* Pass retries to repo method to actually get queued dead scrobbles
2026-05-06 18:14:55 +00:00
FoxxMD 5eb967f61c test(database): Fix play fixture assignment of updatedAt 2026-05-06 16:12:28 +00:00
FoxxMD 0bf9d5e786 refactor(database): Replace relation select type with simpler built type 2026-05-06 16:04:54 +00:00
FoxxMD 102f9795f8 chore: Bump ts-essentials version 2026-05-06 16:03:50 +00:00
FoxxMD 7a7d7bb975 feat(database): Stub out jobs for later use
Creating the majority of it now, esp with jobId in plays table, will make later migrations/usage easier
2026-05-06 14:42:40 +00:00
FoxxMD 246e9ad7c5 chore(release): Bump version for release 2026-05-06 12:12:52 +00:00
FoxxMD d772c8c8cd test(database): Implement db size stats 2026-05-06 02:56:35 +00:00
FoxxMD 48b6b555c1 feat(source): Replace discovered function with existingPlay function
Normalizes the logic used for detected dupes/existing by using it for both sources and clients
2026-05-06 02:56:35 +00:00
FoxxMD 8be56457e2 remove debugging statement 2026-05-06 02:56:35 +00:00
FoxxMD d9a5aa1ce0 fix: Improved retention behavior
* Use new updatedAt column to determine if plays should be deleted
* Update plays on already discovered to keep them from being delted
* Fix various bugs and missed awaits in retention cleanup function
2026-05-06 02:56:35 +00:00
FoxxMD f6799955a0 fix: Fix parsing duration value from string 2026-05-06 02:56:35 +00:00
FoxxMD 077c3d33b5 fix(database): regenerate migrations with platformId removed 2026-05-06 02:56:35 +00:00
FoxxMD 524afb60a9 refactor: Remove platform-awareness for play discovery and database
multiplatform is still useful for memory players but is not useful for discovery and just complicates code paths.

there is no reason to discover based on platform as the Source is the smallest UoW anyway. If a play should be discovered (or not) it shouldn't matter what platform is was played on, it's all the same Source
2026-05-06 02:56:35 +00:00
FoxxMD 12ba99437c fix: Add discovered plays with platform based on multiplatform source prop 2026-05-06 02:56:35 +00:00
FoxxMD 8882e7ab87 chore: Update to drizzle rc1 2026-05-06 02:56:35 +00:00
FoxxMD 8de382f581 feat(database): Optimize queries for scrobble range ops 2026-05-06 02:56:35 +00:00
FoxxMD 691db9215c remove unused variable 2026-05-06 02:56:35 +00:00
FoxxMD 22c0916544 Fix counts for scrobbles/dead 2026-05-06 02:56:34 +00:00
FoxxMD cbe996db95 feat(database): Add query params for finding plays by queue 2026-05-06 02:56:34 +00:00
FoxxMD 8fd870b9ef Fix failed queueu updates 2026-05-06 02:56:34 +00:00
FoxxMD 272c3cc8be feat(database): Add migration path for cached queued scrobbles 2026-05-06 02:56:34 +00:00
FoxxMD 54da8b0add remove unused queue package 2026-05-06 02:56:34 +00:00
FoxxMD cfb4131d5d remove scrobbledPlays and prepare queue next query 2026-05-06 02:56:34 +00:00
FoxxMD b8494986d5 chore: Add sqlite browser vscode extension to devcontainer 2026-05-06 02:56:34 +00:00
FoxxMD f9f923041f the implementation continues 2026-05-06 02:56:34 +00:00
FoxxMD 5774be1d22 Implement api response transform to old structure 2026-05-06 02:56:34 +00:00
FoxxMD 4bc460f598 feat(database): Add relational model inferred type 2026-05-06 02:56:34 +00:00
FoxxMD 0f6aa56fe5 add repository api endpoint POC 2026-05-06 02:56:34 +00:00
FoxxMD 439f0e05aa fixes based on testing for client db impl 2026-05-06 02:56:34 +00:00
FoxxMD 952ddbdcc3 more client db impl 2026-05-06 02:56:34 +00:00
FoxxMD 765b13f910 test: Comment out scrobble caching tests
Not used any more with db
2026-05-06 02:56:34 +00:00
FoxxMD 47caf8de8c more scrobble db implementation 2026-05-06 02:56:34 +00:00
FoxxMD 3c3faf22fc more implementation for clients 2026-05-06 02:56:34 +00:00
FoxxMD f94538ea1f first pass on client database implementation
only refactored queue, need to do dead letter
2026-05-06 02:56:34 +00:00
FoxxMD e9b2990e15 partial scrobble queue database implementation 2026-05-06 02:56:34 +00:00
FoxxMD 3ef48547a7 feat(database): Add id awareness to plays and implement basic api GET for sources 2026-05-06 02:56:34 +00:00
FoxxMD 047de49ee6 feat(database): Initial Souce database usage implementation 2026-05-06 02:56:34 +00:00
FoxxMD 2a52d1e050 fix(spotify): Fix device id default should be only device constant, not platform 2026-05-06 02:56:34 +00:00
FoxxMD 8f049a089b feat(database): Implement discovered/scrobble count tracking 2026-05-06 02:56:34 +00:00
FoxxMD adf6b9ed58 feat(database): Implement basic repository 2026-05-06 02:56:34 +00:00
FoxxMD 59d1050b2b feat(database): Implement retention cleanup scheduled task 2026-05-06 02:56:34 +00:00
FoxxMD 561c62b426 fix(database): Unique constraint on uid + mode + type, not just uid 2026-05-06 02:56:34 +00:00
FoxxMD f38f10d2a0 feat(database): Implement retention cleanup 2026-05-06 02:56:34 +00:00
FoxxMD 7aa5595cc9 feat(database): Implement component hydration as component init stage 2026-05-06 02:56:34 +00:00
FoxxMD 46389fd81d feat(database): Add compacting config 2026-05-06 02:56:34 +00:00
FoxxMD c0384317b1 feat(database): Implement retention options and configuration parsing 2026-05-06 02:56:34 +00:00
FoxxMD 6e66cb06a9 refactor: Remove duplicated regex functions 2026-05-06 02:56:34 +00:00
FoxxMD cb1ff7d030 feat(database): Init and migrate database on startup 2026-05-06 02:56:34 +00:00
FoxxMD 3b5468499a feat(database): Use asyncstorage for query logging 2026-05-06 02:56:34 +00:00
FoxxMD c7361a8976 feat(database): Add full backup-and-migrate logic 2026-05-06 02:56:34 +00:00
FoxxMD 60a6ddbc41 feat(database): Implement drizzle logger 2026-05-06 02:56:34 +00:00
FoxxMD 92e027bfc4 feat(database): Implement finding purgable play ids 2026-05-06 02:56:34 +00:00
FoxxMD b388ca6106 feat(database): Cascade parent id to null on play deletes 2026-05-06 02:56:34 +00:00
FoxxMD 84b43d7c39 feat(database): Implement play deletes
* Implement repository method
* Test that deletes cascade to relations
2026-05-06 02:56:34 +00:00
FoxxMD 99ebb53fc6 chore: Remove unusued patch for kysely 2026-05-06 02:56:34 +00:00
FoxxMD cda33ba04f test(database): Add component query test 2026-05-06 02:56:34 +00:00
FoxxMD dda73cd96a feat(database): Implement query plays by date range 2026-05-06 02:56:34 +00:00
FoxxMD 5771fbf496 feat(database): Implement repository querying 2026-05-06 02:56:34 +00:00
FoxxMD e9d1c81380 chore: Add ts pretty errors to devcontainer extensions 2026-05-06 02:56:34 +00:00
FoxxMD d59cb2668d feat(database): Add basic repository and transaction support 2026-05-06 02:56:34 +00:00
FoxxMD 3c51149d9a feat(database): More database implementation
* add components table
* improve typing for json columns
* fix non-nullable columns
* implement basic entity generation functions
2026-05-06 02:56:34 +00:00
FoxxMD 40234e64b3 refactor(database): Use integer for primary key and make string id as vanity id 2026-05-06 02:56:34 +00:00
FoxxMD 2df8bfe6aa test(database): More migration tests 2026-05-06 02:56:34 +00:00
FoxxMD fec39b2e2e test(database): Craete pending migration and no-db test cases 2026-05-06 02:56:34 +00:00
FoxxMD 83f501df0d add FK For parent play 2026-05-06 02:56:34 +00:00
FoxxMD c40add7d70 feat(database): Initial database POC implementation
Using drizzle
2026-05-06 02:56:34 +00:00
FoxxMD 569c5a8690 fix(spotify): Fix stale state updated at timestamp 2026-05-06 02:56:21 +00:00
FoxxMD 11f7299c0e fix(transform): Fix using cache to return transformed play
Should be caching transformed data instead of play so that "old" plays aren't returned for repeated tracks
2026-05-06 02:40:58 +00:00
Matt Foxx 8a6ae698a1 Merge pull request #587 from FoxxMD/lastfmConnectTimeout
fix(lastfm): Increase connection test timeout for slow networks
2026-05-05 17:49:39 -04:00
FoxxMD d6ed03028d fix(lastfm): Increase connection test timeout for slow networks 2026-05-05 20:59:05 +00:00
FoxxMD 2818d1d275 chore: add lib folder and future db files to gitignore 2026-05-05 16:54:33 +00:00
FoxxMD 8127e4b6ce fix: Use correct gh pages link for replacement 2026-05-05 14:44:00 +00:00
FoxxMD 8e829a53b5 ci: Replace canonical bash command with js script that is more readable and maintainable 2026-05-05 14:39:09 +00:00
FoxxMD 1562f8bffc chore: Fix contributing link in PR template 2026-05-05 12:19:57 +00:00
FoxxMD e04514f6a1 chore(release): Bump version for release 2026-05-05 11:46:16 +00:00
FoxxMD 00e9755fb1 chore: Override rate-limit-threshold to use new version with reduced dependencies
Borewit/rate-limit-threshold#110
2026-05-05 11:46:16 +00:00
Matt Foxx 5ba4729f83 Merge pull request #585 from FoxxMD/webscrobblerPathFix
fix(webscrobbler): Convert express wildcard path to regex
2026-05-04 16:54:13 -04:00
FoxxMD e5df4f2752 docs: Remove extra dupe detection section from client overview
Direct to new dupe guidance page instead
2026-05-04 18:28:08 +00:00
FoxxMD d11db4cb8d docs: Add duplicate scrobble guidance
#582
2026-05-04 18:18:09 +00:00
FoxxMD 14f5f60c11 ci: add canonical search-replace reference comment 2026-05-04 18:15:49 +00:00
FoxxMD 4d7eadbd38 fix(webscrobbler): Convert express wildcard path to regex
New path wildcard from expressjs 5 doesn't seem to work. Use tried and try regex instead

Fixes #583
2026-05-04 14:01:02 +00:00
Matt Foxx 747b62289a Merge pull request #577 from FoxxMD/stalePlayerImprovement
feat: Improve stale player behavior
2026-05-04 09:05:54 -04:00
Matt Foxx 1eeb5e6b08 Merge pull request #580 from FoxxMD/lzEndpointRouteImprovements
Lz endpoint route improvements
2026-05-02 16:24:21 -04:00
FoxxMD ac01348266 docs: try to replace canonical urls for github.io with new site 2026-05-02 04:08:03 +00:00
FoxxMD 3028f83d47 fix(discord): Workaround activity minimum character limit
#578
2026-05-01 18:56:36 +00:00
FoxxMD a02d43acea feat(discord): Implement fallback to release group art if present
#578
2026-05-01 18:43:09 +00:00
FoxxMD c7679a0a62 docs: Fix missing backticks causing template errors on version equality 2026-05-01 16:56:01 +00:00
Gabe Farrell d11ac3d6ed chore: Remove references to KOITO_ALLOWED_HOSTS (#581)
* chore: update and correct references to KOITO_ALLOWED_HOSTS
* remove protocol from host
* make it clear env belongs to koito
2026-05-01 12:47:17 -04:00
Matt Foxx 8a09c91713 Merge pull request #565 from FoxxMD/lastfmCleanup
Lastfm cleanup
2026-05-01 12:39:19 -04:00
FoxxMD 81d24f1753 fix(transformer): try-catch cached steps and fallback to non-cache generation
#578
2026-05-01 15:14:35 +00:00
FoxxMD 5be12aab15 fix(cache): Explicitly define auth/metadata as memory when testing file caching 2026-05-01 15:14:11 +00:00
FoxxMD 47c600ed8d feat(endpointlz): Implement proper username handling for validate and now-playing routes 2026-05-01 14:07:43 +00:00
FoxxMD 5f84fefd5d feat(endpointlz): Add stubbed playing-now route to make some clients happy(er)
#579
2026-05-01 13:11:39 +00:00
FoxxMD a143aa4193 fix(endpointlz): Fix fallback route not returning a response
#579
2026-05-01 13:10:41 +00:00
FoxxMD 23a3dfa5d1 fix: Workaround for old play structure 2026-05-01 00:01:50 +00:00
Matt Foxx 3005d36db0 Merge pull request #575 from FoxxMD/mpdPosition
fix(mpd): Improve position tracking
2026-04-30 18:58:45 -04:00
FoxxMD ada9d70be9 docs(mpd): Add permission guidance 2026-04-30 22:54:57 +00:00
FoxxMD 9d839db2e1 feat(mpd): Rewrite with newer MPD client for better payload parsing #574
mpd-api was missing fields and had inconsistent data.
mpd-js is actually typed and returns better parsed data.
2026-04-30 22:50:09 +00:00
FoxxMD ca20b23fbc fix(now playing): Prefer fresher players
* Don't keep sticky now playing if the player has gone stale/orphaned
* When multiple players are present, prefer those that are not stale/orphaned

#480
2026-04-30 17:39:31 +00:00
FoxxMD 577cff3abf test(player): Fix incorrect variable used for advanced timestamp 2026-04-30 17:20:27 +00:00
FoxxMD c4786bdfe2 fix(player): Initialize player state in the past to prevent false positive on stale update check if update happens at the same time player is initialized 2026-04-30 17:19:48 +00:00
FoxxMD df0da7054c feat(player): Skip stale updates based on state timestamp and prevent dead players from being created from stale updates
#480
2026-04-30 16:39:03 +00:00
FoxxMD 272a336a22 feat(source): Add timestamps to play state to track player and play last updated, if present 2026-04-30 16:38:04 +00:00
Matt Foxx ec4a51074e Merge pull request #570 from FoxxMD/fixListenRange
Fix listen range
2026-04-22 13:27:32 -04:00
FoxxMD 5a4bcb2949 fix(discord): Include known spotify cdn for media providers #569 2026-04-22 13:46:38 +00:00
FoxxMD 77387c292b refactor: Replace fast-deep-equal with fast-equals
fast-deep-equal is abandoned and has bugs that are fixed in fast-equals

Potentially fixes #569
2026-04-22 13:43:14 +00:00
FoxxMD 4caf1c8cdb fix: Fix missing await on stagger mapper initial sleep 2026-04-22 13:40:29 +00:00
FoxxMD 981805aa96 fix: Simplify listenrange usage
* Use and return only plain PlayProgress on player state finish
  * Removes the need to serialize/deserialize ListenProgress class and compare/persist toad scheduler or timeout functions
* Potentially fixes timeout comparison stack error #569
2026-04-22 13:40:00 +00:00
FoxxMD 60e3242c44 fix: Check undefined on correct property
#567
2026-04-19 21:34:42 +00:00
FoxxMD e7e1417b0b ci: Add Cloudflare Pages hook trigger to docs deployment 2026-04-17 18:56:47 +00:00
FoxxMD bf765be174 docs: order BASE_SITE first to allow overriding other envs 2026-04-17 18:30:22 +00:00
FoxxMD e27c301932 docs: Add base site env detection for cloudflare pages 2026-04-17 18:22:45 +00:00
FoxxMD fc4606585d fix(lastfm): Fix total results reporting for librefm 2026-04-17 16:14:30 +00:00
FoxxMD fd80101a7a feat(lastfm): Add more logging to auth process and clean up host detection 2026-04-17 16:05:39 +00:00
FoxxMD 2cbc5542d1 chore(release): Bump version for release 2026-04-17 13:24:45 +00:00
Matt Foxx 6f15f15722 Merge pull request #563 from FoxxMD/middlewareFix
fix: Web endpoint fix
2026-04-17 09:22:25 -04:00
FoxxMD ff1d9248c6 fix: Add missing next() invocation
#561
2026-04-17 12:52:48 +00:00
FoxxMD 218ece8f5c fix(vite): Allow requests from anywhere during dev 2026-04-17 12:49:55 +00:00
FoxxMD 3adac7c6e0 docs: Improve updating guidance 2026-04-16 13:29:34 +00:00
FoxxMD 1c78da7985 chore(release): Bump verion for release 2026-04-16 12:26:39 +00:00
FoxxMD 457279465c ci: Add build date to image build workflow 2026-04-16 02:05:53 +00:00
FoxxMD d551c8563f feat(docker): Add proper opencontainer labels 2026-04-16 02:05:38 +00:00
FoxxMD 75bd4a04d6 fix(transform): Fix uninitialized logger 2026-04-15 20:34:40 +00:00
FoxxMD 339232c368 perf(transform): Defer logger creation until after it is determined a hook will be used 2026-04-15 18:40:21 +00:00
Matt Foxx 8741ff25ea Merge pull request #557 from Druidblack/master
update for Yandex music
2026-04-11 00:04:24 -04:00
Druidblack 8a952cb576 error correction at startup. 2026-04-09 22:32:19 +03:00
Druidblack eeb55aa02e added multiPlatform
added multiPlatform and support for receiving data from Yandex smart speakers
2026-04-09 22:31:18 +03:00
Druidblack 6a81fc1be2 Update ymbridge.json.example 2026-04-09 22:28:32 +03:00
FoxxMD a47e2a6242 docs: Update editUrl 2026-04-09 15:45:29 +00:00
FoxxMD dadaa6df35 ci: reduce dependabot npm updates to security only
Version updates are too big and unhelpful
2026-04-09 14:35:51 +00:00
FoxxMD fb19191209 ci: Update node version for sanity test 2026-04-09 14:08:58 +00:00
Matt Foxx 2f53a60da1 Merge pull request #548 from FoxxMD/express5
chore: Update to expressjs 5
2026-04-09 09:34:29 -04:00
FoxxMD ab2f397fab refactor: update express types related packages 2026-04-09 13:21:50 +00:00
FoxxMD db2dd8fb8b refactor: Refactor wildcard path usage for express5 2026-04-09 13:16:56 +00:00
FoxxMD 135439f509 fix(scrobbler): Fix stagger map generation variable usage 2026-04-09 13:16:33 +00:00
FoxxMD d743b849fe refactor: replace awaitjs/express with express usage 2026-04-09 13:04:47 +00:00
FoxxMD 9885768cad refactor: Install expressjs@5 2026-04-09 12:58:09 +00:00
FoxxMD c6e6bbb87b chore: Override awaitjs/express types to fix peer dependency conflict 2026-04-09 12:53:53 +00:00
FoxxMD bbc2351ebc ci: Fix npm groups to apply only by version/security
Some @types dev packages are tied to prod packages, cant really spearate them.
2026-04-09 12:30:52 +00:00
FoxxMD b547db9045 ci: group gha version updates 2026-04-09 12:25:09 +00:00
Matt Foxx 28c2e9873a Merge pull request #537 from FoxxMD/dependabot/github_actions/actions/download-artifact-8.0.1
chore(deps): bump actions/download-artifact from 4.3.0 to 8.0.1
2026-04-09 08:20:39 -04:00
Matt Foxx 6bcd3f9516 Merge pull request #536 from FoxxMD/dependabot/github_actions/actions/upload-artifact-7.0.0
chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.0
2026-04-09 08:16:49 -04:00
Matt Foxx 11b2632d02 Merge pull request #538 from FoxxMD/dependabot/github_actions/docker/metadata-action-6.0.0
chore(deps): bump docker/metadata-action from 5.9.0 to 6.0.0
2026-04-08 23:51:10 -04:00
Matt Foxx fb6dbe307d Merge pull request #539 from FoxxMD/dependabot/github_actions/marocchino/sticky-pull-request-comment-3.0.3
chore(deps): bump marocchino/sticky-pull-request-comment from 2.9.4 to 3.0.3
2026-04-08 23:50:13 -04:00
FoxxMD 2474b792c3 ci: try wildcard on github actions 2026-04-09 03:39:12 +00:00
FoxxMD 3007c949a0 ci: Group github action dependabot updates 2026-04-09 03:35:21 +00:00
dependabot[bot] 63533534df chore(deps): bump marocchino/sticky-pull-request-comment
Bumps [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment) from 2.9.4 to 3.0.3.
- [Release notes](https://github.com/marocchino/sticky-pull-request-comment/releases)
- [Commits](https://github.com/marocchino/sticky-pull-request-comment/compare/773744901bac0e8cbb5a0dc842800d45e9b2b405...d4d6b0936434b21bc8345ad45a440c5f7d2c40ff)

---
updated-dependencies:
- dependency-name: marocchino/sticky-pull-request-comment
  dependency-version: 3.0.3
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 03:32:57 +00:00
dependabot[bot] 5c03062976 chore(deps): bump docker/metadata-action from 5.9.0 to 6.0.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.9.0 to 6.0.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/318604b99e75e41977312d83839a89be02ca4893...030e881283bb7a6894de51c315a6bfe6a94e05cf)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 03:32:53 +00:00
dependabot[bot] dbe41fa5ab chore(deps): bump actions/download-artifact from 4.3.0 to 8.0.1
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 8.0.1.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/d3f86a106a0bac45b974a628896c90dbdf5c8093...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 03:32:49 +00:00
dependabot[bot] 5454f817e5 chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.0
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 03:32:44 +00:00
FoxxMD 8d8f8260b5 ci: Back to one object with multiple directories 2026-04-09 03:31:53 +00:00
FoxxMD 62bb00571f ci: Group dependabot updates 2026-04-09 03:12:32 +00:00
FoxxMD c10537d658 sync package-lock.json 2026-04-09 02:55:47 +00:00
FoxxMD e9ccc319e9 try to get dependabot to use a specific npm version 2026-04-09 02:55:02 +00:00
FoxxMD 54803c6ef9 feat(docker): Make colored console output the default
Can be turned off by setting COLORED_STD=false in any environment
2026-04-09 02:35:40 +00:00
FoxxMD a3d37a864a chore: Update tsx dependency 2026-04-09 02:34:48 +00:00
Matt Foxx 394570e5a3 Merge pull request #529 from FoxxMD/fontendDevPackages
refactor: Reduce docker image size by moving frontend packages to devDependencies
2026-04-08 22:33:37 -04:00
FoxxMD 2bbfdf424f refactor: further removal of frontend package to devDependencies 2026-04-09 02:20:01 +00:00
FoxxMD 9785ad6ba7 refactor: Remove unused react-dom imports 2026-04-09 02:19:20 +00:00
FoxxMD fe7d77c03d fix(docker): Ignore dist folder 2026-04-09 02:19:00 +00:00
FoxxMD 0e7aa92f5b refactor: Reduce docker image by moving frontend packages to devDependencies
They are bundled by vite/esbuild into /dist folder, shouldn't need to keep them in node_modules
2026-04-09 01:48:08 +00:00
FoxxMD 2ff80283b9 fix: Build vite-express config based on production env to avoid making vite fallback to development (somehow) 2026-04-09 01:27:22 +00:00
FoxxMD 4f34b1a055 feat(docker): use prune-mod to remove unneeded files in image 2026-04-08 20:58:18 +00:00
FoxxMD 4effdd6df5 refactor(docker): Improve image size by removing some icon folders 2026-04-08 20:39:56 +00:00
FoxxMD af3ce9dea7 fix(docker): Fix missing patches/tsconfig for docs on docker build 2026-04-08 20:39:56 +00:00
Matt Foxx f0c5cb524f Merge pull request #527 from FoxxMD/docusaurusSocialCardNew
docs: Generate social cards per page
2026-04-08 15:48:04 -04:00
FoxxMD 46883384b6 docs: Use netlify deploy url if present 2026-04-08 19:46:00 +00:00
FoxxMD 7bc5ab3d0f docs: Specify source for ambiguous components 2026-04-08 19:31:50 +00:00
FoxxMD fd15d15124 dcs: First pass at more descriptive social card text 2026-04-08 19:30:02 +00:00
FoxxMD 14da0795f1 docs: Finalize a working social card strategy
* Helper script to build a static font
* Move all image rendering code into own folder
* Simplify generated text to description OR title
* Use text-wrap balance to make it look prettier
* Add tagline and increase font sizes to fill card dimensions
2026-04-08 19:14:43 +00:00
FoxxMD 3faf0ee7f9 social cards working but need descriptions in each front matter 2026-04-07 15:13:23 +00:00
FoxxMD 78ddb15dcf almost working
svg still doesn't render
2026-04-07 14:14:25 +00:00
FoxxMD 760373c227 docs: Replace instances of foxxmd.github.io 2026-04-07 12:44:41 +00:00
FoxxMD 6bb7b17e97 docs: Update readme with new doc site base url 2026-04-07 12:39:41 +00:00
FoxxMD 231156d452 docs: fix base site env usage 2026-04-07 12:32:31 +00:00
FoxxMD d85628b4c9 docs: Add BASE_SITE env 2026-04-07 12:27:33 +00:00
FoxxMD db0e74aec3 feat(client): Strict ENV types 2026-04-06 20:10:25 +00:00
FoxxMD a918a96d34 feat(sources): Better type enforcement 2026-04-06 20:07:30 +00:00
FoxxMD bb51915085 feat: Increase transform play concurrency
Since MB rate limiting is done by api calient we can safely increase number of plays transformed without risking MB errors from rate limits
2026-04-06 19:12:19 +00:00
Matt Foxx 7c177dfe03 Merge pull request #521 from FoxxMD/processingOverhaul
refactor: Overhaul long-running processes
2026-04-06 15:11:11 -04:00
Matt Foxx cf5e7ca1fe Merge pull request #523 from Druidblack/master
feat: Add Yandex Music source
2026-04-06 14:58:11 -04:00
Druidblack fd43ff86c8 added NO_DEVICE and NO_USER 2026-04-06 21:36:21 +03:00
FoxxMD 194a0e78ff ci: Update checkout and setup-node versions due to node deprecation 2026-04-06 18:28:00 +00:00
FoxxMD 04027e87e7 ci: fix step if statement 2026-04-06 18:04:22 +00:00
FoxxMD a998060bca ci: Add docs repo dispatch 2026-04-06 18:01:10 +00:00
Druidblack 5b16e8857e Removed optional settings 2026-04-06 20:57:36 +03:00
FoxxMD c53ce7c517 docs: Update analytics 2026-04-06 17:03:43 +00:00
FoxxMD 7897dc9503 docs: Add Yandex Music Source docs 2026-04-06 15:04:56 +00:00
Matt Foxx 160ddac3e4 Merge pull request #524 from FoxxMD/docusaursUpdateAndFix
Docusaurs update and fix
2026-04-06 10:35:58 -04:00
FoxxMD 59b4f27294 fix dep changes in wrong file 2026-04-06 14:34:33 +00:00
FoxxMD 21f42bf45b try to trigger netlify 2026-04-06 14:28:08 +00:00
FoxxMD 3e8f170f9a chore(docs): Move markdown link warn into non-deprecated setting 2026-04-06 14:24:27 +00:00
FoxxMD 15fbed09a5 fix(docs): Override lodash to fix assignWith error
https://github.com/lodash/lodash/issues/6167#issuecomment-4172977775
2026-04-06 14:24:10 +00:00
FoxxMD 52b301e729 feat(docs): Update docusaurus to 3.9.2 2026-04-06 14:23:40 +00:00
FoxxMD 0bef197521 feat(yandex): Add env source config 2026-04-06 14:06:05 +00:00
FoxxMD f16750609a feat(yandex): Handle bridge errors as upstream with some response context 2026-04-06 13:58:43 +00:00
FoxxMD c39ef29597 fix: Add missing type to sourcestatusdata 2026-04-06 13:48:49 +00:00
FoxxMD 72639616b7 fix(jellyfin): Fix typo on devicesBlock env assignment #522 2026-04-06 12:53:04 +00:00
Druidblack effe870104 fix time track
fixed the calculation of the track playback if it has ended and the new ones have not started.
2026-04-05 20:56:18 +03:00
Druidblack ee753389f7 Add files via upload 2026-04-05 19:36:13 +03:00
Druidblack 5f4a5cb815 add yandex music 2026-04-05 19:35:00 +03:00
FoxxMD 0607aedf04 feat(musicbrainz): Handle rate limiting within api calls
Instead of using staggerMap with MB transformer settings, handle at api call level for each host
2026-04-02 21:23:26 +00:00
FoxxMD 1f165096b3 feat(client): make scrobble processing abortable 2026-04-02 19:42:59 +00:00
FoxxMD fb6f6a18c8 feat(source): Make discover abortable 2026-04-02 18:41:45 +00:00
FoxxMD 03f8b20704 refactor: Implement abortable source polling
Use abort-controller-x with signals to interrupt polling process

#483
2026-04-02 18:36:20 +00:00
FoxxMD c49cdba718 fix: Initialize plays in correct scope 2026-04-02 01:29:56 +00:00
FoxxMD de67879af5 test: Make loop stop wait time configurable so tests run faster/more stable 2026-04-01 17:10:59 +00:00
FoxxMD 9d0cf8f845 feat: Implement dispose methods for classes with schedulers and long running async tasks 2026-04-01 17:10:25 +00:00
Matt Foxx 8d9fd11c79 Merge pull request #519 from FoxxMD/nodeVersionBump
chore!: Bump node to 24
2026-04-01 11:30:57 -04:00
FoxxMD 745343c589 chore!: Bump node to 24
No breaking changes for MS but local installs will need to update node version
2026-04-01 15:23:40 +00:00
FoxxMD e5935c38da ci: try to force dependabot to use npm 11.12.1 2026-04-01 14:30:44 +00:00
FoxxMD cac13fa3da fix: Align dockefile and devcontainer node/npm versions to fix lockfile mismatch
Mismatch causes npm ci in docker build to error
2026-04-01 13:57:04 +00:00
FoxxMD ca4803713e chore: Update node/npm engine constraints in package.json 2026-04-01 13:16:49 +00:00
FoxxMD e53dd55ad8 chore: Remove unused testing libraries and fix storybook version
* Unusued libraries adding a ton of dependencies for functionality that is not used (yet)
* Need to fix storybook version because 10.3 is unstable
2026-04-01 12:59:08 +00:00
FoxxMD 1f2772353a fix: Fix circular dependency in error utils 2026-04-01 12:59:08 +00:00
Matt Foxx 78b48107a0 Merge pull request #517 from FoxxMD/dependabot/npm_and_yarn/npm_and_yarn-369bcfe21d
chore(deps): bump the npm_and_yarn group across 2 directories with 25 updates
2026-04-01 08:22:07 -04:00
dependabot[bot] bd00055ae5 chore(deps): bump the npm_and_yarn group across 2 directories with 25 updates
Bumps the npm_and_yarn group with 21 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [ajv](https://github.com/ajv-validator/ajv) | `8.17.1` | `8.18.0` |
| [ajv](https://github.com/ajv-validator/ajv) | `6.12.6` | `6.14.0` |
| [formidable](https://github.com/node-formidable/formidable) | `3.5.2` | `3.5.4` |
| [formidable](https://github.com/node-formidable/formidable) | `2.1.2` | `2.1.5` |
| [glob](https://github.com/isaacs/node-glob) | `11.0.0` | `11.1.0` |
| [glob](https://github.com/isaacs/node-glob) | `10.4.5` | `10.5.0` |
| [undici](https://github.com/nodejs/undici) | `6.22.0` | `6.24.1` |
| [undici](https://github.com/nodejs/undici) | `7.10.0` | `7.24.6` |
| [undici](https://github.com/nodejs/undici) | `6.21.3` | `6.24.1` |
| [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core) | `10.2.0` | `10.3.3` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `5.4.10` | `5.4.21` |
| [brace-expansion](https://github.com/juliangruber/brace-expansion) | `1.1.11` | `1.1.13` |
| [minimatch](https://github.com/isaacs/minimatch) | `3.1.2` | `3.1.5` |
| [picomatch](https://github.com/micromatch/picomatch) | `2.3.1` | `2.3.2` |
| [axios](https://github.com/axios/axios) | `1.11.0` | `1.14.0` |
| [qs](https://github.com/ljharb/qs) | `6.13.0` | `6.15.0` |
| [yaml](https://github.com/eemeli/yaml) | `1.10.2` | `1.10.3` |
| [flatted](https://github.com/WebReflection/flatted) | `3.3.3` | `3.4.2` |
| [immutable](https://github.com/immutable-js/immutable-js) | `5.1.4` | `5.1.5` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `4.1.0` | `4.1.1` |
| [jws](https://github.com/brianloveswords/node-jws) | `4.0.0` | `4.0.1` |
| [lodash](https://github.com/lodash/lodash) | `4.17.21` | `4.18.0` |
| [on-headers](https://github.com/jshttp/on-headers) | `1.0.2` | `1.1.0` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) | `6.27.0` | `6.30.3` |
| [rollup](https://github.com/rollup/rollup) | `4.24.3` | `4.60.1` |
| [tmp](https://github.com/raszi/node-tmp) | `0.0.33` | `0.2.5` |

Bumps the npm_and_yarn group with 13 updates in the /docsite directory:

| Package | From | To |
| --- | --- | --- |
| [undici](https://github.com/nodejs/undici) | `6.21.1` | `6.24.1` |
| [brace-expansion](https://github.com/juliangruber/brace-expansion) | `1.1.11` | `1.1.13` |
| [minimatch](https://github.com/isaacs/minimatch) | `3.1.2` | `3.1.5` |
| [picomatch](https://github.com/micromatch/picomatch) | `2.3.1` | `2.3.2` |
| [yaml](https://github.com/eemeli/yaml) | `2.8.2` | `2.8.3` |
| [immutable](https://github.com/immutable-js/immutable-js) | `5.1.4` | `5.1.5` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `3.14.1` | `3.14.2` |
| [lodash](https://github.com/lodash/lodash) | `4.17.21` | `4.18.0` |
| [mdast-util-to-hast](https://github.com/syntax-tree/mdast-util-to-hast) | `13.2.0` | `13.2.1` |
| [on-headers](https://github.com/jshttp/on-headers) | `1.0.2` | `1.1.0` |
| [node-forge](https://github.com/digitalbazaar/forge) | `1.3.1` | `1.4.0` |
| [svgo](https://github.com/svg/svgo) | `3.3.2` | `3.3.3` |
| [webpack](https://github.com/webpack/webpack) | `5.97.1` | `5.105.4` |



Updates `ajv` from 8.17.1 to 8.18.0
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v8.17.1...v8.18.0)

Updates `ajv` from 6.12.6 to 6.14.0
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v8.17.1...v8.18.0)

Updates `formidable` from 3.5.2 to 3.5.4
- [Release notes](https://github.com/node-formidable/formidable/releases)
- [Changelog](https://github.com/node-formidable/formidable/blob/master/CHANGELOG.md)
- [Commits](https://github.com/node-formidable/formidable/commits)

Updates `formidable` from 2.1.2 to 2.1.5
- [Release notes](https://github.com/node-formidable/formidable/releases)
- [Changelog](https://github.com/node-formidable/formidable/blob/master/CHANGELOG.md)
- [Commits](https://github.com/node-formidable/formidable/commits)

Updates `glob` from 11.0.0 to 11.1.0
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v11.0.0...v11.1.0)

Updates `glob` from 10.4.5 to 10.5.0
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v11.0.0...v11.1.0)

Updates `undici` from 6.22.0 to 6.24.1
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.22.0...v6.24.1)

Updates `undici` from 7.10.0 to 7.24.6
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.22.0...v6.24.1)

Updates `undici` from 6.21.3 to 6.24.1
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.22.0...v6.24.1)

Updates `storybook` from 10.2.0 to 10.3.3
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.3.3/code/core)

Updates `vite` from 5.4.10 to 5.4.21
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.21/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.21/packages/vite)

Updates `brace-expansion` from 1.1.11 to 1.1.13
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.13)

Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5)

Updates `picomatch` from 2.3.1 to 2.3.2
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

Updates `axios` from 1.11.0 to 1.14.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.11.0...v1.14.0)

Updates `qs` from 6.13.0 to 6.15.0
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.13.0...v6.15.0)

Updates `yaml` from 1.10.2 to 1.10.3
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](https://github.com/eemeli/yaml/compare/v1.10.2...v1.10.3)

Updates `flatted` from 3.3.3 to 3.4.2
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.2)

Updates `immutable` from 5.1.4 to 5.1.5
- [Release notes](https://github.com/immutable-js/immutable-js/releases)
- [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/immutable-js/immutable-js/compare/v5.1.4...v5.1.5)

Updates `js-yaml` from 4.1.0 to 4.1.1
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

Updates `jws` from 4.0.0 to 4.0.1
- [Release notes](https://github.com/brianloveswords/node-jws/releases)
- [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianloveswords/node-jws/compare/v4.0.0...v4.0.1)

Updates `lodash` from 4.17.21 to 4.18.0
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.18.0)

Updates `on-headers` from 1.0.2 to 1.1.0
- [Release notes](https://github.com/jshttp/on-headers/releases)
- [Changelog](https://github.com/jshttp/on-headers/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/on-headers/compare/v1.0.2...v1.1.0)

Updates `react-router` from 6.27.0 to 6.30.3
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/react-router@6.30.3/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router@6.30.3/packages/react-router)

Updates `rollup` from 4.24.3 to 4.60.1
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.24.3...v4.60.1)

Updates `tmp` from 0.0.33 to 0.2.5
- [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/raszi/node-tmp/compare/v0.0.33...v0.2.5)

Updates `undici` from 6.21.1 to 6.24.1
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.22.0...v6.24.1)

Updates `brace-expansion` from 1.1.11 to 1.1.13
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.13)

Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5)

Updates `picomatch` from 2.3.1 to 2.3.2
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

Updates `yaml` from 2.8.2 to 2.8.3
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](https://github.com/eemeli/yaml/compare/v1.10.2...v1.10.3)

Updates `immutable` from 5.1.4 to 5.1.5
- [Release notes](https://github.com/immutable-js/immutable-js/releases)
- [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/immutable-js/immutable-js/compare/v5.1.4...v5.1.5)

Updates `js-yaml` from 3.14.1 to 3.14.2
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

Updates `lodash` from 4.17.21 to 4.18.0
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.18.0)

Updates `mdast-util-to-hast` from 13.2.0 to 13.2.1
- [Release notes](https://github.com/syntax-tree/mdast-util-to-hast/releases)
- [Commits](https://github.com/syntax-tree/mdast-util-to-hast/compare/13.2.0...13.2.1)

Updates `on-headers` from 1.0.2 to 1.1.0
- [Release notes](https://github.com/jshttp/on-headers/releases)
- [Changelog](https://github.com/jshttp/on-headers/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/on-headers/compare/v1.0.2...v1.1.0)

Updates `node-forge` from 1.3.1 to 1.4.0
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.4.0)

Updates `svgo` from 3.3.2 to 3.3.3
- [Release notes](https://github.com/svg/svgo/releases)
- [Commits](https://github.com/svg/svgo/compare/v3.3.2...v3.3.3)

Updates `webpack` from 5.97.1 to 5.105.4
- [Release notes](https://github.com/webpack/webpack/releases)
- [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack/compare/v5.97.1...v5.105.4)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 8.18.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: ajv
  dependency-version: 6.14.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: formidable
  dependency-version: 3.5.4
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: formidable
  dependency-version: 2.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: glob
  dependency-version: 11.1.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: glob
  dependency-version: 10.5.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: undici
  dependency-version: 6.24.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: undici
  dependency-version: 7.24.6
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: undici
  dependency-version: 6.24.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: storybook
  dependency-version: 10.3.3
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: vite
  dependency-version: 5.4.21
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: brace-expansion
  dependency-version: 1.1.13
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: axios
  dependency-version: 1.14.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: qs
  dependency-version: 6.15.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: yaml
  dependency-version: 1.10.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: immutable
  dependency-version: 5.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: jws
  dependency-version: 4.0.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.18.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: on-headers
  dependency-version: 1.1.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: react-router
  dependency-version: 6.30.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: rollup
  dependency-version: 4.60.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: tmp
  dependency-version: 0.2.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: undici
  dependency-version: 6.24.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: brace-expansion
  dependency-version: 1.1.13
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: yaml
  dependency-version: 2.8.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: immutable
  dependency-version: 5.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: js-yaml
  dependency-version: 3.14.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.18.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: mdast-util-to-hast
  dependency-version: 13.2.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: on-headers
  dependency-version: 1.1.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: node-forge
  dependency-version: 1.4.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: svgo
  dependency-version: 3.3.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: webpack
  dependency-version: 5.105.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-31 20:31:04 +00:00
FoxxMD b174b23b3b fix: re-install missing dependencies introduced by dependabot 2026-03-31 20:07:34 +00:00
Matt Foxx 9e6319ee73 Configure Dependabot for npm and docker updates
Updated package ecosystems for Dependabot to include npm and docker.
2026-03-31 15:59:51 -04:00
Matt Foxx 6b5b3990cd Merge pull request #511 from FoxxMD/dependabot/npm_and_yarn/npm_and_yarn-6582722f31
chore(deps): bump the npm_and_yarn group across 2 directories with 2 updates
2026-03-31 15:53:42 -04:00
dependabot[bot] f2465f0f88 chore(deps): bump the npm_and_yarn group across 2 directories with 2 updates
Bumps the npm_and_yarn group with 1 update in the / directory: [express](https://github.com/expressjs/express).
Bumps the npm_and_yarn group with 2 updates in the /docsite directory: [express](https://github.com/expressjs/express) and [path-to-regexp](https://github.com/pillarjs/path-to-regexp).


Updates `express` from 4.21.1 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.1...v4.22.1)

Updates `path-to-regexp` from 0.1.10 to 0.1.13
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/v.0.1.13/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v0.1.12...v.0.1.13)

Updates `express` from 4.21.1 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.1...v4.22.1)

Updates `path-to-regexp` from 0.1.10 to 0.1.13
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/v.0.1.13/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v0.1.12...v.0.1.13)

Updates `express` from 4.21.2 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.1...v4.22.1)

Updates `path-to-regexp` from 0.1.12 to 0.1.13
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/v.0.1.13/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v0.1.12...v.0.1.13)

Updates `express` from 4.21.2 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.1...v4.22.1)

Updates `path-to-regexp` from 0.1.12 to 0.1.13
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/v.0.1.13/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v0.1.12...v.0.1.13)

---
updated-dependencies:
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: path-to-regexp
  dependency-version: 0.1.13
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: path-to-regexp
  dependency-version: 0.1.13
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: path-to-regexp
  dependency-version: 0.1.13
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: path-to-regexp
  dependency-version: 0.1.13
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-31 19:50:21 +00:00
FoxxMD c68ec8dbf6 chore: Remove unused nyc dependency 2026-03-31 19:46:03 +00:00
FoxxMD 6e1cdba58c chore(release): Bump version for release 2026-03-31 14:45:29 +00:00
FoxxMD df4bb27d3a docs: Add music assistant to readme 2026-03-31 14:44:43 +00:00
FoxxMD de7707b45a docs: Simplify installation
* Remove docker run
* Condense docker settings into tabs
2026-03-31 14:43:42 +00:00
FoxxMD c884b4776c docs: Add grafana dashboard 2026-03-31 14:06:19 +00:00
FoxxMD 0893b62f3b docs: Fix discord link on jellyfin page 2026-03-31 14:06:19 +00:00
FoxxMD 7d071c763d docs: Add more caching guidance 2026-03-31 14:06:19 +00:00
Matt Foxx 664395a0ee Merge pull request #508 from FoxxMD/cacheAusterity
feat: Reduce cache memory usage
2026-03-31 09:01:46 -04:00
FoxxMD 007d553d59 fix missed ttl for mb tests 2026-03-30 19:24:57 +00:00
FoxxMD 7c8c185c4c refactor: Remove ttl from mb api to ensure primary/secondary ttl is used correctly 2026-03-30 18:59:37 +00:00
FoxxMD 972eccd0bf cache init cleanup 2026-03-30 18:50:54 +00:00
Matt Foxx 034cfe7a8e Merge pull request #509 from FoxxMD/netlifyPreview
Netlify preview
2026-03-30 11:25:10 -04:00
FoxxMD 7a8cf7c004 feat: Skip fetching backlogged plays entirely if scrobbleBacklog=false 2026-03-29 23:50:55 +00:00
FoxxMD 30cdc9f553 docs: Add prometheus usage 2026-03-29 23:50:55 +00:00
Matt Foxx 3f19abb899 Merge pull request #506 from FoxxMD/musicAssistant
Music assistant
2026-03-29 19:30:50 -04:00
FoxxMD a601757759 docs: Add netlify badge to footer on preview docs 2026-03-28 22:16:02 +00:00
FoxxMD fe03bcd651 refactor: Refactor cache building to be able to specify both primary and secondary 2026-03-28 21:36:18 +00:00
FoxxMD 1f319cb9f6 fix: Use lifecycle invariant play for closest match 2026-03-28 02:01:14 +00:00
FoxxMD a0ac0f8e46 reduce step ttl to 2 minutes 2026-03-27 20:30:48 +00:00
FoxxMD 06945fda52 feat: Improve cache stats
* Remove vsize since its very inaccurate
* Use memory store `size` for count, if present
2026-03-27 20:30:32 +00:00
FoxxMD 306c4c858e fix: Only enable metrics collection for real runs 2026-03-27 18:51:00 +00:00
FoxxMD 81885632a0 feat: Add cache stats to prometheus metrics 2026-03-27 18:45:30 +00:00
FoxxMD 23467481c1 docs: Add prometheus usage 2026-03-27 17:47:15 +00:00
Matt Foxx e716de2160 Add Contributor Covenant Code of Conduct
This document outlines the Contributor Covenant Code of Conduct, including our pledge, standards, enforcement responsibilities, and guidelines for community behavior.
2026-03-27 13:15:33 -04:00
FoxxMD dda06a0873 add chunk array function 2026-03-27 16:08:47 +00:00
FoxxMD eca64d68e7 fix(musicbrainz): Catch recordings with no releases 2026-03-27 16:06:43 +00:00
Matt Foxx 1065643b23 Merge pull request #493 from FoxxMD/deadScrobbleImprovements
feat: Dead scrobble improvements
2026-03-26 08:58:31 -04:00
FoxxMD d92153f85f fix: Fix sleep time between consecutive dead scrobble attempts 2026-03-26 08:40:16 -04:00
FoxxMD 22d76c459a fix(scrobble): Improve ui/api experience for dead scrobble processing
* Return 200 when processing all, don't wait to finish to prevent response timeout
* Use event stream to update/remove/add dead scrobbles in ui

#489
2026-03-26 08:40:16 -04:00
FoxxMD ec87ab96d6 fix(scrobble): Improve dead scrobble iteration and logging
* Use filtered, processable scrobbles in for-loop to avoid any weird in-place array splice issues when iterating
* Add more logging with labels/ids to make logging more readable
* Move dead scrobble removal function closer blocks where it should happen
2026-03-26 08:40:13 -04:00
FoxxMD f62fe270fb feat(scrobble): Increase default dead letter retries from 1 to 3
#488
2026-03-26 08:36:54 -04:00
Matt Foxx 677474beed Merge pull request #504 from FoxxMD/transformStepCachingFix
fix: transform step usage and caching fix
2026-03-25 23:27:23 -04:00
FoxxMD cb9dd0fbc5 docs: Add Music Assistant to lz endpoint docs 2026-03-25 20:20:50 +00:00
FoxxMD 0685d4b06d feat(lzendpoint): Update json body parsing to support Music Assistant 2026-03-25 20:19:29 +00:00
FoxxMD 82c0a4faec fix: Refactor play tranforming to dogfood steps and fix caching #495
* Re-use lifecycle steps/patch to build diffs
* Break out step generation into own function to simplify logic
* Cache steps instead of play to avoid returning a cached play when data is the same #495
* Replace patch object/patching logic with json-diff-ts as its more robust and actually maintained
  * Reduces need to stringify everywhere due to lack of cloning in jsonpatchdiff
2026-03-25 18:48:47 +00:00
FoxxMD ccbd5e304a fix: Better handling when stage fails but should continue 2026-03-25 10:13:06 -04:00
FoxxMD 4f81a192fa Merge branch 'storybook' 2026-03-24 21:39:22 -04:00
FoxxMD 22cf95e58c feat(listenbrainz): Use upstream for backlogged 2026-03-25 01:37:54 +00:00
FoxxMD 358355c612 refactor: Move stagger config responsibility to transformer 2026-03-25 00:41:10 +00:00
FoxxMD c5f9600047 docs: Add duplicate scrobble detection explanation 2026-03-24 23:54:55 +00:00
Matt Foxx 703731e654 Merge pull request #501 from FoxxMD/storybook
More UI
2026-03-24 16:39:38 -04:00
FoxxMD 0dfa4c7aad fix(test): Fix expected plays for YTM interim plays 2026-03-24 20:23:47 +00:00
FoxxMD 68e473ec02 fix: Add stagger options as injected dependency to make tests faster 2026-03-24 20:21:14 +00:00
FoxxMD a8d20734aa fix: Fix wrong operation for maxRandomStagger 2026-03-24 20:20:37 +00:00
FoxxMD ebdb76cf6c fix: Fix type-erased meta property for json plays 2026-03-24 20:19:27 +00:00
FoxxMD e62e1ac2dd feat: Add seenAt to source/client play meta 2026-03-24 19:38:05 +00:00
FoxxMD e68b46f647 feat(ui): Implement play activity sortby seen/played 2026-03-24 19:15:54 +00:00
FoxxMD 7605cd3f1d virtualization is messy and plain accordian works better 2026-03-24 18:56:07 +00:00
FoxxMD 2735c283ce virtualized activity log 2026-03-24 17:47:51 +00:00
FoxxMD 0daaec81ca feat(ui): Add more info to play data 2026-03-24 01:22:39 +00:00
FoxxMD 2085df4406 feat(ui): Dynamic expand/collapse all 2026-03-24 00:16:57 +00:00
FoxxMD 9b8664d3a3 feat(ui): Condense timeline items into title using collapsible 2026-03-24 00:02:42 +00:00
FoxxMD e027a33e8d feat(ui): Play Data rows for better use of wide viewports 2026-03-23 18:56:50 +00:00
FoxxMD f04a19d34d feat(ui): Add flow and step state to timeline 2026-03-23 18:32:28 +00:00
FoxxMD 4b27671a91 feat: Add step and flow result to lifecycle 2026-03-23 18:32:12 +00:00
FoxxMD 5f4943e025 fix(ui): Fix keys 2026-03-20 20:47:38 +00:00
FoxxMD 66cdb94d57 feat(ui): Add lifecycle step story and fix diff rendering 2026-03-20 20:39:35 +00:00
FoxxMD 5ebb0e6a9c refactor: Separating functions so they are usuable by frontend storybook 2026-03-20 19:33:09 +00:00
FoxxMD dfb7f43c00 feat: Implement play with lifecycle fixture 2026-03-20 18:24:04 +00:00
FoxxMD ed85d35117 feat: Implement random object generator 2026-03-20 16:31:19 +00:00
FoxxMD 7d69e77ac6 Implement proper play conversion for frontend/backend testing
Convert to json-equivalent object, and back, without needing json stringify/parse
2026-03-20 15:22:53 +00:00
FoxxMD 03973d215b refactor: Fix JsonPlayObject to properly type dates 2026-03-20 14:00:17 +00:00
Matt Foxx 1b182d89cd Merge pull request #498 from FoxxMD/storybook
feat: Add storybook and initial ui design POC
2026-03-20 09:40:48 -04:00
FoxxMD 3d5c2c7450 fix: Remove schema-plugin types hint from docusaurus config 2026-03-20 13:31:51 +00:00
FoxxMD d6264dd994 chore: ignore storybook folders for docker image 2026-03-20 13:31:33 +00:00
FoxxMD 4c18123207 refactor: Move some utils into core folder 2026-03-20 13:29:23 +00:00
FoxxMD 71e7f41ea5 more ui improvements 2026-03-20 01:02:25 +00:00
FoxxMD 60cf5d1019 feat(ui): Hide text-heavy elements for small mobile 2026-03-19 21:11:11 +00:00
FoxxMD 3977057dfa more tweaks 2026-03-19 20:36:48 +00:00
FoxxMD 943bdc3e88 feat(ui): Improve play data 2026-03-19 20:23:15 +00:00
FoxxMD 44710048f4 feat(ui): Integrate timeline into activity detail 2026-03-19 19:48:22 +00:00
FoxxMD 9f9f5655b1 feat(ui): Implement scrobble action 2026-03-19 18:38:39 +00:00
FoxxMD e621811364 feat(ui): Implement duplicate match check 2026-03-19 18:10:26 +00:00
FoxxMD 685bc846e8 feat(ui): Implement transform steps 2026-03-19 17:36:02 +00:00
FoxxMD 3a9d58fae9 feat(ui): Implement error stack and more things 2026-03-19 02:07:09 +00:00
FoxxMD 33639c6e4c more improvements 2026-03-18 20:59:53 +00:00
FoxxMD 7c235e3179 feat(ui): Add PlayInfo to list 2026-03-18 20:29:39 +00:00
FoxxMD 559d749207 feat(ui): More activity log improvements 2026-03-18 20:12:01 +00:00
FoxxMD 53feae0f8c more imrovements 2026-03-18 19:04:51 +00:00
FoxxMD 0941ccc0ac improved list layout 2026-03-18 18:33:16 +00:00
FoxxMD 82ecd96ba4 Containerized playinfo 2026-03-18 18:19:38 +00:00
FoxxMD e118dc5db1 Better args default for stories 2026-03-18 18:19:27 +00:00
FoxxMD 1a23491ac2 feat(ui): Set max height for code block with scrolling 2026-03-18 17:56:38 +00:00
FoxxMD d916f167a5 feat(ui): Implement code block toggle for play info 2026-03-18 17:35:43 +00:00
FoxxMD 0102249549 feat(ui): Implement PlayInfo component 2026-03-18 16:44:17 +00:00
FoxxMD 2ca96dab42 Init storybook with chakra-ui 2026-03-18 10:25:20 -04:00
FoxxMD 345e60b7a3 chore(release): Bump version for release 2026-03-16 13:33:06 +00:00
Matt Foxx b9fb6c9d35 Merge pull request #487 from FoxxMD/jsonView
feat(docs): Implement rich config exploration and interaction
2026-03-13 15:00:29 -04:00
FoxxMD 5d0ccd8867 docs: re-nable AIO config display as read-only on mobile 2026-03-13 14:52:29 -04:00
FoxxMD b36f484f3b chore: Add netlify-specific build command 2026-03-13 14:52:29 -04:00
FoxxMD d2f7f986c7 Add gitkeep for schema folder 2026-03-13 14:52:29 -04:00
FoxxMD 9137d03b9f use genericonfiguration component for remaining client/sources 2026-03-13 14:52:29 -04:00
FoxxMD f6c0d13a8b feat(docs): Implement config example/structure guidance 2026-03-13 14:52:17 -04:00
FoxxMD c472b4e33a refactor: reorganized and consolidate source/client types 2026-03-13 14:52:17 -04:00
FoxxMD f6c3fc6b50 refactor(docs): replace docusaurus json-schema-plugin
* Use cf-json-schema-viz for schema viewer
* Use modern-react-json-editor for editing
2026-03-13 14:50:39 -04:00
FoxxMD 8ba146495e feat(jellyin): Add external URL guidance
#486
2026-03-12 14:00:59 +00:00
Matt Foxx 68c46fefb2 Merge pull request #471 from FoxxMD/componentPagination
feat: Implement pagination fetching for component listen data
2026-03-12 08:46:36 -04:00
Matt Foxx eddda41559 Merge pull request #473 from owendaprile/push-ovmumqzwvmqx
fix(plex): Also read MBIDs from `guid` field
2026-03-11 14:08:36 -04:00
FoxxMD 5945fdc2ef docs(spotify): Add premium account guidance
#485
2026-03-11 17:59:27 +00:00
FoxxMD d110dcbdcf fix(sources): Add a confidence signal to plays generated from authoratiative sources to avoid fuzzy matching repeats
https://github.com/FoxxMD/multi-scrobbler/issues/430#issuecomment-4035670777
2026-03-11 13:54:24 +00:00
Owen D'Aprile ebc0aa8a4e fix(plex): Also read MBIDs from guid field
Some items on Plex store the MBID in the `guid` field in the `Metadata`
response, not in the `Guid` field. This change checks the `guid` field
as a fallback if the `Guid` field is not set.
2026-03-10 20:24:25 -04:00
FoxxMD d4113b464a feat(scrobbler): Improved dupe detection
* Check queue before adding so that previously cached or re-discovered plays from a source are not added multiple times to the queue (should only be unique plays)
* Add timestamp heuristic to dupe matching -- if score is *close* to matching and timestamp is *exact* then nudge it into a match
2026-03-10 20:37:14 +00:00
FoxxMD 753dfe1fb3 feat: Implement better request retry logic
* Use p-retry to standard retry behavior
* Simplify/remove other own-rolled retry logic
* Fix superagent request instantiation
  * Requests are mutable, cannot be retried once executed. Need to make a new request for each retry
2026-03-10 19:47:42 +00:00
FoxxMD 013cccaac5 add more logging for discord now playing update logic 2026-03-10 16:43:49 +00:00
FoxxMD 504f8ffbeb refactor(source): Reduce logging noise for activity checks
Move most activity checks to TRACE log level to reduce noise at DEBUG level
2026-03-10 16:06:55 +00:00
FoxxMD 81d1eb2553 feat(ui): Default logs to trace 2026-03-10 15:33:54 +00:00
FoxxMD c9327b0e92 fix(lastfm): Default to not including now playing in history response
Scrobbler getScrobblesForTimeRange function isn't aware of the context and we only want now playing for the Source impl anyway.

Fixes not scrobbling play because it is also now playing which mathced existing scrobble logic.

https://github.com/FoxxMD/multi-scrobbler/issues/430#issuecomment-4031615361
2026-03-10 15:00:13 +00:00
FoxxMD 36aa236d82 use TRACE for cache file loading chunk logging 2026-03-09 19:44:58 +00:00
FoxxMD 3c37aa4449 fix(lastfm): Fix not returning nowPlaying scrobble 2026-03-09 18:39:33 +00:00
FoxxMD f1bf3cbe64 fix(nowPlaying): Scrobbler should report now playing if player state is known nowPlayingMode source
#477#issuecomment-4022857648
2026-03-09 18:39:11 +00:00
FoxxMD 17a9356040 fix: Handle historical scrobble fetch failure
* Don't cache error
* Handle error with logging and put scrobble into dead queue (or increment retries on dead)
2026-03-09 16:47:11 +00:00
FoxxMD 97c799bf2c refactor: Re-implement retry logic for LZ with fixed request init 2026-03-09 16:46:10 +00:00
FoxxMD 99c02daec7 fix(koito): Assign cursor to page param 2026-03-09 16:45:30 +00:00
FoxxMD 4cb792641d fix(pagination): Assign cursor on initial request and properly catch errors to add request parameter logging 2026-03-09 16:45:13 +00:00
FoxxMD fbc2950854 fix upstream scrobble tests 2026-03-06 20:47:04 +00:00
FoxxMD 08e0bdb437 feat(scrobbler): re-implement scrobble preload
Use a limit/maxFetch upper limit to return a bulk of scrobbles by count, rather than timerange, so that backlogged scrobbles are less likely to cause many fetches on first startup
2026-03-06 20:28:22 +00:00
FoxxMD 73dcab4de1 fix(scrobbler): Fix ttl for timerange cahe and missing awaits 2026-03-06 19:42:15 +00:00
FoxxMD 00594a14ed feat: Implement timerange consolidation 2026-03-06 19:41:54 +00:00
FoxxMD 52d5bab0f5 Implement noop logger 2026-03-06 19:40:50 +00:00
FoxxMD a41f4c56f7 feat(scrobbler): Implement play-dependent, arbitrary timerange fetching for duplicate checks
* Remove design bias towards "recent" scrobbles with limited timerange and complex shouldRefresh logic
* Replace with logic to fetch scrobbles from timeranges that are relevant to queued/dead scrobbles
  * timeranges are grouped by closely timestamped queued scrobbles
  * timeranges are cached based on staleAfter
2026-03-06 16:57:09 +00:00
Matt Foxx 8ea83962d6 Merge pull request #482 from FoxxMD/namedTransformFix
fix(transform): Fixes for user transform and transform selection
2026-03-06 08:15:34 -05:00
FoxxMD 9d97cc6e4c fix(transform): Fix transform for stage not using name for selection #481 2026-03-05 15:49:51 +00:00
FoxxMD 023579de9a refactor(atproto): Replace naive TID impl with @ewanc26/tid 2026-03-04 21:00:35 +00:00
FoxxMD 214d99f1c3 fix(lastfm): Check for singular scrobble response 2026-03-04 21:00:35 +00:00
FoxxMD d6fc6b9b10 debug for lastfm list type 2026-03-04 21:00:35 +00:00
FoxxMD cbdab93f92 refactor(tealfm): Replace TID package to avoid node-gyp dependency 2026-03-04 21:00:35 +00:00
FoxxMD abf37f0687 refactor(spotify): use listen timerange fetcher 2026-03-04 21:00:35 +00:00
FoxxMD e993a43399 refactor: Implement generic cursor iteration 2026-03-04 21:00:35 +00:00
FoxxMD bc79969fd0 refactor(maloja): use listen timerange fetcher 2026-03-04 21:00:35 +00:00
FoxxMD 801f9ed403 refactor(koito): Use listen timerange fetcher 2026-03-04 21:00:34 +00:00
FoxxMD 3d9f6f8f58 refactor(lastfm): Use listen timerange fetcher 2026-03-04 21:00:34 +00:00
FoxxMD c2676fb620 refactor(listenbrainz): Use listen timerange fetcher 2026-03-04 21:00:34 +00:00
FoxxMD cdb4ab23e9 refactor(listenbrainz)!: Remove Koito support
Koito functionality has diverged enough that it doesn't make sense to provide partial support via LZ components.

This also makes timerange pagination easier.
2026-03-04 21:00:33 +00:00
FoxxMD b3217f2d9c mostly implemented time range fetch utility 2026-03-04 20:59:52 +00:00
FoxxMD 7b61385ad5 implement time range scrobbles for teal 2026-03-04 20:59:52 +00:00
FoxxMD b5c86e74ad more pagination implementation 2026-03-04 20:59:51 +00:00
FoxxMD a3031a7eb9 Somewhat working
Stole pagination from FoxxMD/multi-scrobbler#390
2026-03-04 20:59:32 +00:00
FoxxMD 7c49a0535f fix typings 2026-03-04 20:36:35 +00:00
FoxxMD 797e5b0794 feat(scrobbler): Add dupe match debug information to lifecycle 2026-03-04 20:30:03 +00:00
FoxxMD bc6cd78c86 refactor: Implement alreadyScrobbled in base class
None of the child classes use a different implementation. DRY
2026-03-04 18:40:27 +00:00
FoxxMD 98a5b40be5 refactor: Use trace logging for defaults
* All logger use trace as minimum level
* Force app log stream to trace minimum so we always show all possible logs in dashboard
* Add trace level to dashboard
* Make dashboard start in debug logs for readability
2026-03-04 18:22:41 +00:00
FoxxMD 87c174fe0f chore: exclude schema folder from search 2026-03-04 15:52:49 +00:00
Matt Foxx 0cbb45e4ad Merge pull request #478 from FoxxMD/discordHangingStatus
fix(discord): Add hidden activity type
2026-03-04 10:41:11 -05:00
FoxxMD b11226af94 fix(discord): Don't throw on unknown activity type
This isn't used for filtering anymore so its not necessary to validate to a known activity
2026-03-04 15:40:14 +00:00
Matt Foxx 27dc5b5e19 Merge pull request #479 from FoxxMD/userTransformDefaults
fix(transform): Fix missing defaults assignment for stage config parsing
2026-03-04 08:12:58 -05:00
FoxxMD d892b83110 fix(transform): Fix user transform default value 2026-03-03 22:00:42 +00:00
FoxxMD c28984524a fix(transform): Fix missing defaults assignment for stage config parsing 2026-03-03 21:04:40 +00:00
FoxxMD 5d4fb63baa fix(discord): Add hidden activity type
Fixes #477
2026-03-03 13:50:14 +00:00
FoxxMD ca2574d1e5 Add comment pointing to JF source on MB ids 2026-03-02 15:45:43 +00:00
FoxxMD 758038e278 fix: Missed dependency bump 2026-02-27 16:57:24 +00:00
FoxxMD cb803b1a24 feat: Use lower minimum log level to prepare for logging cleanup 2026-02-27 16:51:30 +00:00
FoxxMD c985af5722 docs: Add discord to readme 2026-02-27 14:19:41 +00:00
FoxxMD 1ede54acbb docs: Fix broken links and anchors 2026-02-27 14:18:50 +00:00
FoxxMD a73ca6a95d feat(ui): Add service status page link to dashboard 2026-02-27 02:45:12 +00:00
FoxxMD 25f4095276 chore(release): Bump version 2026-02-26 20:37:22 +00:00
FoxxMD d242c133dd docs(faq): Add connection/dns guidance 2026-02-26 19:39:51 +00:00
FoxxMD da3e8044b7 docs: Add status page to monitoring section 2026-02-26 19:23:58 +00:00
FoxxMD b6d5939fbf chore: Add kasm service as extenable compose file for dev 2026-02-26 19:12:21 +00:00
FoxxMD d23ef88647 docs(discord): Clearer wording on user token usage 2026-02-26 17:21:48 +00:00
FoxxMD f374f130de fix(discord): Kasm improvements
* Fix permissions in compose example
* Better wording in advantages/disadvantages
2026-02-26 17:21:30 +00:00
FoxxMD b0c2c8611b docs(discord): Use named volume for kasmcord 2026-02-26 02:16:43 +00:00
FoxxMD 6f6f56ce64 docs(discord): Reorganize discord app container instructions and improve art examples 2026-02-26 02:06:21 +00:00
FoxxMD 4b28ec4b3a fix(discord): wrong protocol comparison 2026-02-25 21:14:12 +00:00
FoxxMD d189084c15 feat(discord): Implement retry for cover art api 2026-02-25 20:56:19 +00:00
FoxxMD 975d9540bc docs(discord): Update kasmcord with persistent config volume 2026-02-25 20:18:41 +00:00
FoxxMD 212bfba950 docs(discord): Add discord container instructions 2026-02-25 19:19:31 +00:00
FoxxMD 619e32cd83 feat(discord): Add more logging for cover art acquistion 2026-02-25 19:17:09 +00:00
FoxxMD ce9ff53ae1 feat(discord): Add debug log when no cover art found 2026-02-25 19:07:39 +00:00
FoxxMD d13fb33884 docs(discord): Improved discord app docs 2026-02-25 16:31:55 +00:00
FoxxMD 253e91250f fix(discord): Patch IPC client to catch socket error 2026-02-25 02:54:18 +00:00
FoxxMD b23668372b feat(discord): Correct position timestamp based on player last update time #468 2026-02-24 20:07:31 +00:00
FoxxMD 5b847c136e fix(discord): Don't queue scrobbles 2026-02-24 19:03:25 +00:00
FoxxMD 0d304a793d fix(scrobblers): Don't queue now playing data if scrobbler is not ready 2026-02-24 18:46:02 +00:00
FoxxMD 906e1a1a19 fix(discord): Stop scrobbler and set as auth failure on invalid client from IPC 2026-02-24 18:45:43 +00:00
FoxxMD 87f46f1e02 Improve failure mode handling for IPC discord
* Set auth failure on 4000 from server (invalid client id)
* Better logging for connection issues
* Don't fail on connect so we can keep retrying on MS activity
2026-02-24 18:31:46 +00:00
FoxxMD 56b4be1fe1 QoL features for discord-rpc library
* Add keepAlive to so close events actually happen
* DEBUG log human readable payload rather than hex
2026-02-24 18:28:37 +00:00
FoxxMD a08dcf05f1 refactor(discord): Remove activity filtering
https://github.com/FoxxMD/multi-scrobbler/issues/468#issuecomment-3952116123
2026-02-24 15:13:28 +00:00
FoxxMD 460882f6c1 fix(discord): wrong eqaulity for token check 2026-02-24 13:31:41 +00:00
FoxxMD 71fc94ba63 Missing category 2026-02-23 22:32:24 +00:00
FoxxMD b587d834bc docs: Add discord local/headless docs 2026-02-23 22:31:33 +00:00
FoxxMD 9b63e022ed Don't require media proxy for IPC 2026-02-23 21:15:37 +00:00
FoxxMD 324cbd76ee refator(discord): Move client init to build stage with more logging 2026-02-23 21:03:58 +00:00
FoxxMD ceab13f672 refactor(discord): Consolidate shared functionality 2026-02-23 20:47:22 +00:00
FoxxMD 10e17ed239 Initial IPC implementation 2026-02-23 20:15:21 +00:00
FoxxMD 4f84479513 fix: Fix labels for MS heartbeat task 2026-02-23 16:42:18 +00:00
FoxxMD 216ad4ed32 fix(discord): Stabalize heartbeat interval and logging
* Refactor sequence and gateway receive logging as labels
* Use timeout instead of interval for heartbeat to try to fix weird speedup
2026-02-23 16:42:18 +00:00
FoxxMD 85e4555322 fix(discord): Even more reconnect handling improvements
* Fix reconnect logic and ready state clearing
* Clearer and less noisy logging
* Delay clearing activities for convience on quick reconnect
2026-02-20 16:59:03 +00:00
FoxxMD a90e443a88 faster heartbeat for safety 2026-02-19 17:25:24 +00:00
FoxxMD a9c54b5f91 refactor(discord): More connection logic improvements
* Handle connect and auth separately so it can be restarted by scrobble heartbeat
* make ms-initiated reconnect use manual close/open since isosockets won't
* better error handling for auth/connection init stages
* send heartbeats even if not authed
2026-02-19 17:23:38 +00:00
FoxxMD 6d21435aab fix(discord): Use iso-websockets reconnect and workaround initial connection issues 2026-02-19 16:32:59 +00:00
FoxxMD 9c3bb11a66 more discord ws logging 2026-02-19 14:28:16 +00:00
FoxxMD d983080584 fix(discord): Fix config logging for artwork 2026-02-18 19:40:46 +00:00
FoxxMD 852b96009c docs cleanup 2026-02-18 18:13:54 +00:00
FoxxMD c82617d857 docs(discord): Update artwork guidance for cover art archive 2026-02-18 17:19:08 +00:00
FoxxMD 6f19256187 feat(discord): Use release mbid to get coverart if fallback would otherwise be used 2026-02-18 16:16:46 +00:00
FoxxMD 479ede334b fix(transform): Use temporally-invariant hash comparison
Fixes not using transform hashes due to user listening data on discover or for playing now data
2026-02-18 16:16:05 +00:00
FoxxMD e1349255de feat(scrobblers): Run preCompare transform hook on playing now data 2026-02-18 16:15:10 +00:00
FoxxMD 4a600dc01d Make art its own type 2026-02-18 15:27:09 +00:00
FoxxMD 315256ce96 feat(musicbrainz): Implement CoverArtArchive API 2026-02-18 15:25:14 +00:00
Matt Foxx bbead20723 Merge pull request #472 from FoxxMD/discordPresence
feat: Discord rich presence
2026-02-17 16:35:30 -05:00
FoxxMD bb77c1c0bb feat(discord): Use artwork url if its from a known domain 2026-02-17 21:28:53 +00:00
FoxxMD 2a2fb9ad55 refactor(discord): Update links and art
* Use pocike icon for placeholder art
* Use MS logo for small art with link to docs
* Use web link as track url, if available
* Use MB link as track or artist url
2026-02-17 21:05:26 +00:00
FoxxMD ea5b66cdae fix(discord): Fix ajv not liking defaultUrl string | false 2026-02-17 20:16:50 +00:00
FoxxMD 1a978c7ee3 fix: Fix config validation error source 2026-02-17 20:13:11 +00:00
FoxxMD cfd458f463 docs(discord): Improve artwork url guidance and application id 2026-02-17 20:12:49 +00:00
FoxxMD 61b8277822 feat(discord): Add actionable links for public URLs and musicbrainz
Add links to album art and/or small image if application id enabled
2026-02-17 19:05:17 +00:00
FoxxMD 53c8036e34 feat(discord): Add more presence configuration options 2026-02-16 21:08:23 +00:00
FoxxMD f5c8ce5109 more now playing fixes and improvements 2026-02-16 21:08:06 +00:00
FoxxMD 17b11f19a3 feat(nowplaying): Update now playing based on play presence AND player status 2026-02-16 17:26:34 +00:00
FoxxMD 2993279d78 feat(discord): Add platform specific now playing should update check 2026-02-15 18:36:27 +00:00
FoxxMD b95b7e3781 fix(discord): Add missing applicationId env and docs 2026-02-14 00:12:16 +00:00
FoxxMD c57200132e use discord.js deps in production build 2026-02-13 23:04:38 +00:00
FoxxMD f6d9921581 type fixes 2026-02-13 22:08:46 +00:00
FoxxMD 3aada673d5 feat(discord): Add album art functionality 2026-02-13 22:00:40 +00:00
FoxxMD 1456070044 fix(discord): Better error handling and reconnect logic 2026-02-13 20:42:23 +00:00
FoxxMD 883797a51d docs(discord): Add discord docs 2026-02-13 19:47:18 +00:00
FoxxMD 1b93512b0a feat(discord): artwork fallback and ENV config 2026-02-13 19:47:05 +00:00
FoxxMD 7c99262a79 feat(discord): Initial implementation #468 2026-02-13 18:39:33 +00:00
FoxxMD d10ecb88bb chore(release): Bump version 2026-02-12 13:31:36 +00:00
FoxxMD bb0f8e1a9a fix(spotify): Destructure external_ids from default object #470 2026-02-12 13:18:49 +00:00
FoxxMD 8be1ace9a1 chore(release): Bump version 2026-02-11 15:26:20 +00:00
FoxxMD 80d6879d2a chore: Update git-cliff workflow
* Add as dev dependency with npm script so it can be run anywhere project is installed
* Update config with newer template based on scopesorted
  * Add more scopes and give them pretty emojis
2026-02-11 15:24:54 +00:00
Matt Foxx 0b8dfaa5b5 Merge pull request #466 from FoxxMD/deezerImprovements
feat: Deezer family account and other improvements
2026-02-11 08:17:55 -05:00
Matt Foxx 3e25be1e9d Merge pull request #467 from FoxxMD/jellyfinUnknownLax
feat(jellyfin): More granular media type filtering
2026-02-11 08:17:35 -05:00
FoxxMD 4e550d14af fix(jellyfin): Fix options being required
The old jellyfin config had optional options which kept the new jf options required from *always* being required. Removing the old config revealed this bug.

Fixes #469
2026-02-10 20:06:06 +00:00
FoxxMD eab33559ca fix: allow musicvideo media type and use allowedMediaTypes for NowPlayingItem check 2026-02-10 19:39:35 +00:00
FoxxMD 83076a0770 docs: Update screenshot 2026-02-05 17:21:47 +00:00
FoxxMD db65b3140a docs: Remove erroneous ENV restriction 2026-02-05 00:43:17 +00:00
FoxxMD 70b703df8b docs: Wording and client order
* Make landing description more generalized.
* Put Koito as first client. Maloja is unmaintained and shouldn't be showcased.
2026-02-04 14:15:35 +00:00
FoxxMD 00070a1bd2 docs: Make compose default tab for installation 2026-02-04 13:44:13 +00:00
FoxxMD c7bf419ac4 chore: Remove unused dockerfile
alpine hasn't been used in awhile due to dns problems
2026-02-04 13:41:33 +00:00
FoxxMD 850f9f081a fix(jellyfin): Allow all media types when allowUnknown is true
Fixes #445
2026-02-03 18:51:28 +00:00
FoxxMD 1110b6b047 docs(deezer): Use config tabs 2026-02-03 17:41:18 +00:00
FoxxMD 3c99adc01c feat(deezer): Add family account monitoring #344 2026-02-03 17:26:05 +00:00
FoxxMD 55cec9a16f fix(deezer): Fix error list access #344 2026-02-03 16:04:30 +00:00
FoxxMD c36c7c6440 docs(plex): Add Musicbrainz stage guidance
#447
2026-02-03 15:48:39 +00:00
FoxxMD 7a4e0ea213 fix: Normalize state param for auth redirect URLs
Fixes #443
2026-02-03 15:07:34 +00:00
FoxxMD 5a7e1c0ae5 choer: Bump lastfm-ts-api version
scriptex/lastfm-ts-api#52
2026-02-03 13:40:22 +00:00
Matt Foxx 9c3b079620 Merge pull request #463 from Kernald/oci-source-label
chore(docker): Add source OCI labels
2026-01-31 11:43:26 -05:00
FoxxMD c75fff6833 fix: compatibility for old scrobbles #462 2026-01-31 11:40:14 -05:00
Marc Plano-Lesay 6adf2851ba chore(docker): Add source OCI labels
These labels are used, among other things, by Renovate to pull
changelogs/link to the upstream repository automatically
(https://docs.renovatebot.com/modules/datasource/docker/).
2026-01-31 11:06:08 +11:00
FoxxMD c6e1b9c629 chore: Fix links in issue templates 2026-01-30 10:17:08 -05:00
FoxxMD 09d7bad4a6 chore: Bump version for release 2026-01-30 15:01:47 +00:00
FoxxMD 4e0bc1552a fix(librefm): Relax response content-type
Patch package to fix response content type change from librefm until scriptex/lastfm-ts-api#52 is merged
2026-01-30 14:40:48 +00:00
Matt Foxx 205d626cd6 Merge pull request #460 from FoxxMD/playDiff
feat: Implement play diffing with inputs for debugging
2026-01-29 17:43:49 -05:00
FoxxMD dee2e5ecf8 docs: Add help docs and update github issue template with play debug data 2026-01-29 21:19:36 +00:00
FoxxMD 995f857b08 fix(plex): Do not use album artist MBID when existing artist or is VA #450 2026-01-29 18:58:22 +00:00
FoxxMD 073af2d3b4 fix(plex): Add missing brainz data to lifecycle original 2026-01-29 18:37:13 +00:00
FoxxMD 4b0eaff99c Add missing error capture to dead letter retry failures 2026-01-29 18:18:56 +00:00
FoxxMD 2aac56c97a feat(scrobblers): Serialize error correctly and add debug info to dead letter ui 2026-01-29 17:13:16 +00:00
FoxxMD 67f6880d32 feat(scrobblers): Refactor scrobbling functions to capture transactional data
Capture payload, response/body, errors, and warnings so we can store them in play lifecycle for future debugging
2026-01-29 16:34:25 +00:00
FoxxMD 1f2816e6fb Move debug icon to left side 2026-01-27 17:48:12 +00:00
FoxxMD 50565fe312 fix: Deep clone discovered plays
Fixes shared scrobble object overwriting lifecycle data for each scrobble client
2026-01-27 17:42:23 +00:00
FoxxMD 6332da52e6 Use ms play with scrobble payload for api response 2026-01-27 17:10:18 +00:00
FoxxMD fa06d65046 fix(maloja): Fix logging objects 2026-01-27 17:06:20 +00:00
FoxxMD 1ce27a2543 docs: Comment why compilations don't work for maloja 2026-01-27 17:05:01 +00:00
FoxxMD 406a4b3448 fix: add missing bug icon for copy action in scrobbled page 2026-01-26 20:23:48 +00:00
FoxxMD c0259ac409 feat: Add debug copy action to ui 2026-01-26 20:05:17 +00:00
FoxxMD d474ae24d3 feat: Use json diff to track play changes
* Store Source input and original play
* Store transformer hook results as diff patches alongside stage-specific arbitrary input data
  * Use jsondiffpatch console format to log stage diffs
* Store scrobble payload data
2026-01-26 19:13:03 +00:00
FoxxMD 62b06c0f56 refactor(sonos): Move device/group filters before track type checks to enable easier user workarounds
Device Name/GroupName is more likely to exist and less likely to cause issues than upnpclass and other things we are looking for to verify its a valid track.

User can block the erroring device to "fix" bad behavior.
2026-01-26 13:46:21 +00:00
FoxxMD af6851562c fix(sonos): Check for UpnpClass existing #398 2026-01-26 13:38:19 +00:00
FoxxMD cb62a6a659 fix(musicbrainz): Check for undefined status #458 2026-01-24 19:24:48 +00:00
Matt Foxx 7411f7324a Merge pull request #456 from FoxxMD/sonosStateHandle
fix(sonos): Gracefully handle failure when fetching device state #455
2026-01-23 13:33:54 -05:00
FoxxMD b3467e97b7 fix(sonos): Gracefully handle failure when fetching device state #455 2026-01-23 17:43:03 +00:00
FoxxMD 5b83e774e6 fix: TS typings for brainz meta and missed recording-track rename 2026-01-23 17:09:25 +00:00
FoxxMD 9cc2ca1010 docs: Refactor lastfm source instructions in quickstart guide to use ENV 2026-01-22 21:43:50 +00:00
FoxxMD 77aaefa3c3 docs: Update readme 2026-01-22 16:25:13 -05:00
FoxxMD 7a09950312 chore: Bump version for release 2026-01-22 20:17:07 +00:00
FoxxMD 2244eb4bf0 docs(sonos): Update admonitions 2026-01-22 20:10:23 +00:00
FoxxMD 5f9907adf7 chore: Cleanup dynamic import refactor 2026-01-22 14:49:57 +00:00
Matt Foxx 64eeae78a8 Merge pull request #448 from FoxxMD/mbTrack
feat(musicbrainz): Search by track MBID
2026-01-22 09:36:30 -05:00
Matt Foxx a053104b13 Merge pull request #451 from FoxxMD/lastfmDebug
feat(lastfm): Add response content logging
2026-01-22 09:34:26 -05:00
FoxxMD d2ea1adcb0 chore(lastfm): Use updated lastfm package
* Support timeout scriptex/lastfm-ts-api#50
* Error response debugging scriptex/lastfm-ts-api#51
2026-01-22 14:28:08 +00:00
Matt Foxx 20d86905c0 Merge pull request #439 from FoxxMD/sonos
Implement Sonos Source
2026-01-22 09:23:49 -05:00
FoxxMD 5fba6436ab refactor(sonos): Add missing sonos source dynamic usage 2026-01-22 13:51:54 +00:00
FoxxMD dea6d68228 feat(sonos): Better cleanup for for devices 2026-01-22 13:48:44 +00:00
FoxxMD 2ac9547f6a Use device invariant data for iterating devices
* Use invariant hash for seen state logging
  * Removes dependence on individual properties being available
* Drop player state if an existing existing player has the same play, rather than dropping by existing group
* Enable logging empty player for more debugging info

try to get device summary with for loop
2026-01-22 13:48:42 +00:00
FoxxMD 49529af813 feat(sonos): Add group/device filtering 2026-01-22 13:48:42 +00:00
FoxxMD 54eabf49f0 feat(sonos): Fix first media seen logging and add debug guidance to docs
add env gate to sonos test playground
2026-01-22 13:48:39 +00:00
FoxxMD 16ad50ca4d feat: Implement Sonos Source
disable debug test

Add mising type to source status data
2026-01-22 13:48:37 +00:00
Matt Foxx 49d09d0420 Merge pull request #453 from FoxxMD/memoryFix
refactor: Optimize production for memory usage
2026-01-22 08:31:14 -05:00
FoxxMD 50e613748f reactor: try dynamic import for components 2026-01-21 16:51:51 +00:00
FoxxMD 69d76d2d44 refactor: Use compiled json for schema in production
* Use dynamic import for schema based on environment
  * If production use pre-generated json to avoid loading vega generator -- big memory footprint reduction
  * If not production use vega so schema is always up to date
2026-01-21 16:24:58 +00:00
FoxxMD 65d9026f01 docs(tealfm): Update tealfm links 2026-01-21 13:16:21 +00:00
FoxxMD 5b6ad26b2e feat(lastfm): Add response content logging #449 2026-01-20 15:53:25 +00:00
FoxxMD 59a132e536 chore: Add config types to issue template 2026-01-19 21:35:08 +00:00
FoxxMD 9ec9de519e fix(musicbrainz): find correct release when release or track mbid is present 2026-01-19 21:08:10 +00:00
FoxxMD 54c631eb40 Fix missed track to recording rename 2026-01-19 18:24:59 +00:00
FoxxMD ef96241743 feat(musicbrainz): Search by track MBID using basicorids #447 2026-01-19 18:18:13 +00:00
FoxxMD 0b51c3a5fa refactor(musicbrainz): Rename recording mbid property to recording
So that introducing trackId isn't confusing
2026-01-19 18:09:29 +00:00
FoxxMD 9ccdd53bd8 feat: Implement ENV config for clients as sources
Source that are also clients did not have ENV config due to early design choices that are now irrelevant.

Implement ENV config for these source to make config easier for everyone.
2026-01-19 15:45:25 +00:00
Matt Foxx 8e6730a5ce Merge pull request #444 from FoxxMD/prometheus
feat: Add prometheus metrics #438
2026-01-18 18:02:24 -05:00
FoxxMD a2f4c3088a fix(prometheus): Set content type to plain text #438 2026-01-18 16:39:01 +00:00
FoxxMD ecb65a29c1 docs: Add prometheus usage 2026-01-16 21:16:55 +00:00
FoxxMD b4d8b9ad37 refactor: Add type label for prometheus metrics 2026-01-16 21:16:47 +00:00
FoxxMD d3cde0e373 feat: Add prometheus metrics #438 2026-01-16 21:03:23 +00:00
FoxxMD 28667067ca docs: Add missing default preset to quickstart MB instructions 2026-01-15 21:04:20 +00:00
FoxxMD c469ef02dd docs: Add librefm to repo readme 2026-01-15 15:50:20 +00:00
FoxxMD f48990e31f chore: Bump version for release 2026-01-15 15:39:55 +00:00
FoxxMD 2a0733968e fix: Fix koito spelling 2026-01-14 20:05:59 -05:00
FoxxMD cc7c90c012 docs: Fix styling on default details 2026-01-14 14:19:58 +00:00
FoxxMD 02a54ce8bc fix(librefm): Log warning for empty account rather than throwing
#401
2026-01-14 13:29:56 +00:00
Matt Foxx 25256321b2 Merge pull request #440 from FoxxMD/docComponents
Doc components
2026-01-13 15:42:43 -05:00
FoxxMD 370e3e90b0 docs: Details Admonotions for main configuration 2026-01-13 20:40:04 +00:00
FoxxMD c0c449ecc2 docs: Use AdmonitionDetails 2026-01-13 20:35:11 +00:00
FoxxMD 4f9cfcf46d docs: Re-style details and add custom admonition details component 2026-01-13 20:05:23 +00:00
Matt Foxx b05ff9814e feat: Librefm Source/Client (#436)
* feat(librefm): Implement librefm
* feat(librefm): Make api key/secret optional
* feat(librefm): Add LIBREFM_ENABLE env to allow enabling librefm with no other options
* feat(ui): Show client/source hint for all ambiguous components
2026-01-13 08:24:31 -05:00
Matt Foxx fa34e83474 Merge pull request #437 from jackwilsdon/add-undici
fix: add missing undici dependency
2026-01-12 11:07:00 -05:00
Jack Wilsdon 1c73dd5efa fix: add missing undici dependency 2026-01-11 22:22:28 +00:00
FoxxMD 8f66914dfb chore!: Remove deprecated Plex/Tautulli Sources 2026-01-08 19:00:56 +00:00
FoxxMD 424a764a9c chore!: Remove deprecated Jellyfin Source 2026-01-08 18:45:09 +00:00
FoxxMD 53ef315f50 feat(musicbrainz)!: Improve ENV presets
* Adds `fields` and `id` presets to give ENV users more flexibility
* BREAKING: Removes searchOrder from `sensible` so users must now use `default` with presets (other than `sensible`) to get default searchOrder methods added
2026-01-08 15:18:23 +00:00
FoxxMD 9e3c15c9e8 Improve logging for artist search method 2026-01-08 13:55:33 +00:00
FoxxMD 240fb2ca7d docs: Add read-only install instructions
Closes #429 thanks @drake7707
2026-01-08 13:33:42 +00:00
Matt Foxx 4657df2900 Merge pull request #433 from FoxxMD/musicbrainzSearchAgnostic
feat(musicbrainz)!: Add more control, and types, to api search execution
2026-01-08 08:14:53 -05:00
FoxxMD a3aa0b9988 docs: Improve MB docs 2026-01-07 22:50:01 +00:00
FoxxMD c33ed61220 fix(musicbrainz): Fix default assignment for searchOrder
Prevent undefined so in component transform options from causing defaults to override stage defaults
2026-01-07 22:50:01 +00:00
FoxxMD d7cf3f82ee fix(musicbrainz): Check for release data type before logging #434 2026-01-07 22:50:01 +00:00
FoxxMD 1ec492725c feat(musicbrainz): Implement field scoring 2026-01-07 22:49:57 +00:00
FoxxMD 03d9dc36ec fix: Remove cache assignment in child class 2026-01-07 22:47:22 +00:00
FoxxMD f0ffa1ad8a feat(transformer): Improved caching
* Cache full transform hooks and omit logging when cache hit
  * Big logging reduction for sources that return all plays (teal, lastfm, etc.)
* Implement new error type for stages to discriminate between expected prerequisite failures and true exceptions
  * Used to determine logging level and if hook should be cached
2026-01-07 22:47:22 +00:00
FoxxMD 528d269dde fix: Don't mutate original error when merging cause stack for logging 2026-01-07 22:47:22 +00:00
FoxxMD 5a642c4c06 fix some wording 2026-01-07 22:47:22 +00:00
FoxxMD 867f382cc0 fix type for env preset 2026-01-07 22:47:22 +00:00
FoxxMD 203411a875 docs(musicbrainz): Update search methods 2026-01-07 22:47:22 +00:00
FoxxMD 9833c6c7bb feat(musicbrainz): Implement basic-or-ids search 2026-01-07 22:47:22 +00:00
FoxxMDandgabe 4af0200161 feat(musicbrainz): add exclusive search by recording MBID
* adds mbidrecord search type

Co-authored-by: gabe <gabeklav@fastmail.com>
2026-01-07 22:47:22 +00:00
FoxxMD d27ec5f031 feat(musicbrainz)!: Replace fallback search with searchOrder for more search control
* search order and type of searches now determined by `searchOrder` instead of multiple `fallback*` options with hardcoded order
* Deprecate `fallback*` options
* Deprecate `fallbackArtistSearch` for `searchArtistMethod`
* Refactor ENV presets to use new options
2026-01-07 22:47:22 +00:00
Matt Foxx 9482b66846 Merge pull request #435 from FoxxMD/fixPreTransformClient
fix: Move preCompare transform hook for clients to the correct place …
2026-01-07 17:45:52 -05:00
FoxxMD dcf35a6930 more test fixes 2026-01-07 14:07:03 +00:00
FoxxMD e526fe79eb fix tests 2026-01-07 13:58:03 +00:00
FoxxMD ad61d29f08 fix: Move preCompare transform hook for clients to the correct place in lifecycle 2026-01-07 13:45:43 +00:00
Matt Foxx 2485267666 Merge pull request #426 from owendaprile/push-ursmqpqmrwns
feat(plex): Retrieve MusicBrainz IDs
2026-01-05 15:47:17 -05:00
FoxxMD 46f4fbe585 fix(endpointlz): Mark play as new from source
May fix scrobble clients not refreshing when scrobbling old/offline plays #430
2026-01-05 18:40:51 +00:00
FoxxMD a7a99eec05 feat(plex): Add reasonable timeout to cache calls 2026-01-05 18:15:26 +00:00
FoxxMD bad960d786 refactor(plex): Use existing cache and simplify failure result
* Use Keyv memory cache
* Return undefined instead of null to simplify assignment
* Throw error with cause for clearer logging
2026-01-05 18:10:32 +00:00
FoxxMD a3110dbddc fix(mpd): Add missing MPD envs to source building #432 2026-01-05 17:29:14 +00:00
FoxxMD 01c95d79c1 fix(musicbrainz): Simplify config parsing and log original ids
* simplify config building so new properties aren't accidentally not assigned
* add logPreMbid to defaults to make id search troubleshooting easier
2026-01-05 17:16:01 +00:00
FoxxMD 2b7cbc41f3 feat(musicbrainz): Improved missing mbid parsing and tests 2026-01-05 16:54:48 +00:00
FoxxMD 8bf1bffd70 fix(tealfm): Don't define brainz artist array if empty 2026-01-05 16:21:31 +00:00
FoxxMD df163a26de test(lastfm): Improve artist and mbid parsing
* Update scrobble types to more accurate represent what lastfm returns
* Add tests to check mbids and artists are parsed correctly
2026-01-05 15:29:48 +00:00
FoxxMD a98f8448d6 chore: Bump version for release 2025-12-31 20:47:17 +00:00
FoxxMD 541892a59e fix(musicbrainz): Don't assume duration is missing 2025-12-30 19:28:39 +00:00
FoxxMD 8dcb6528ac fix: Convert MB length to seconds
#423 #427
2025-12-28 16:03:01 +00:00
Owen D'Aprile 210f9a75ed feat(plex): Cache MusicBrainz IDs 2025-12-23 17:23:55 -05:00
Owen D'Aprile 50e3a3bbfe feat(plex): Retrieve MusicBrainz IDs 2025-12-23 17:23:49 -05:00
Matt Foxx 7dd238a48a Merge pull request #424 from SilverKnightKMA/patch-1
Rename 'unnamed-koito' to 'unnamed-rocksky'
2025-12-21 23:25:23 -05:00
Vũ Thanh Tùng 8a157947a6 Rename 'unnamed-koito' to 'unnamed-rocksky' 2025-12-22 10:54:51 +07:00
FoxxMD 5e309250f5 docs: Add valkey docker compose connection example 2025-12-18 16:48:19 +00:00
FoxxMD 0875aefacf feat(tealfm): Implement service filtering and parse isrc/music service from records 2025-12-17 16:34:48 +00:00
FoxxMD 083dcc494e refactor: Move ISRC to main play data
It's not a brainz-specific identifier
2025-12-17 16:09:45 +00:00
FoxxMD e5105b1bb2 chore: Bump version for release 2025-12-17 14:01:19 +00:00
FoxxMD e998a6d95a docs: Add debug mode logging hint 2025-12-17 14:00:16 +00:00
FoxxMD 98f045a70f docs: Improve general transform docs 2025-12-17 13:57:56 +00:00
FoxxMD 419f7cf657 docs(musicbrainz): Highlight ENV config 2025-12-17 13:45:49 +00:00
Matt Foxx 9bef0791c4 Merge pull request #421 from FoxxMD/secretsInterpolation
Secrets interpolation
2025-12-16 21:00:53 -05:00
FoxxMD 15d667f653 docs: Better warnings for ENV interpolation 2025-12-17 01:59:05 +00:00
FoxxMD 939ae6f892 docs: Add config interpolation docs 2025-12-17 01:52:07 +00:00
FoxxMD 0cd36e57d6 feat: Log as WARN if there are unmatched interpolation keys
#420
2025-12-17 01:30:52 +00:00
FoxxMD 5acb92e696 feat(musicbrainz): Search by ISRC before anything else
If ISRC is presents then it should be a guaranteed hit and match. Do a "pre" search using only ISRC before doing the normal field search.
2025-12-17 00:31:22 +00:00
FoxxMD 10a90c7d48 fix(musicbrainz): Add missing duration logic 2025-12-16 23:59:31 +00:00
FoxxMD f0c5686b4a fix: Parse non-interpolated json data as data 2025-12-16 23:53:38 +00:00
FoxxMD cae914b21b docs: Better language for mb quickstart section 2025-12-16 21:19:26 +00:00
Matt Foxx 344083a3a9 Merge pull request #419 from FoxxMD/spotifyBrainzMeta
feat: Add additional metadata from spotify and for listenbrainz submissions
2025-12-16 15:54:18 -05:00
FoxxMD 36ed40f628 feat: Implement secret interpolation from ENV
#420
2025-12-16 20:53:00 +00:00
FoxxMD c650c4a1e0 feat: Implement string interpolation from object values 2025-12-16 20:32:04 +00:00
FoxxMD f50c3b40d5 docs: Add musicbrainz step to quickstart 2025-12-16 19:29:06 +00:00
FoxxMD c1318f7efc feat: Add additional metadata from spotify and for listenbrainz submissions
* Parse irsc and track number from spotify data
* Add isrc and track number to listenbrainz submission
* Correct spotify ids for listenbrainz submission

#418
2025-12-16 18:18:30 +00:00
FoxxMD 615947b4d2 fix(transforms): Update types to allow json validation without type for user
#267
2025-12-16 16:36:47 +00:00
Matt Foxx 7c0a9fcd9a Merge pull request #417 from FoxxMD/improvedStageFlowControl
Improved stage flow control
2025-12-16 09:57:16 -05:00
FoxxMD 72572c9397 docs(transformers): Add Flow Control 2025-12-16 14:54:02 +00:00
FoxxMD 0e3874f35f chore: Update wording for disable web 2025-12-16 13:33:53 +00:00
FoxxMD db8a289517 feat(transformers): Log more transform stage detail for components 2025-12-16 13:33:53 +00:00
FoxxMD 698f0b91fc feat(transformers): Add onSkip flow control
* Don't use newtransform when nothing has been assigned
* Remove nanoid accidental commit
2025-12-16 13:33:23 +00:00
FoxxMD fb08a63e6f fix(musicbrainz): Throw errors on pre/post fetch so onFailure works as expected
#414
2025-12-15 18:37:26 +00:00
FoxxMD a320aba4da fix(transformer): Improve stage error logging
* Merge causes if a simple error exists in the stack, reduces stack logging noise
* Log top level message and print error instead of duplicating message in another error
* Fix adding transform history for failed-continue stage
2025-12-15 18:36:41 +00:00
FoxxMD 088e26ce4f feat(musicbrainz): Make fallback album search configurable #414 2025-12-13 22:23:41 +00:00
Matt Foxx e273159ecb Merge pull request #413 from FoxxMD/spotifyNonItem
fix(spotify): Don't report player state if spotify api doesn't return an item
2025-12-12 16:33:38 -05:00
FoxxMD f0ac53ffff fix(spotify): Don't report player state if spotify api doesn't return an item
It's not useful to the stateful player to return a player state without an item

#412
2025-12-12 21:14:09 +00:00
FoxxMD 4a364ce766 chore: Bump version for release 2025-12-12 13:59:33 +00:00
FoxxMD 6c4cd27aa0 fix(transformer): Don't try to build env transformer when no ENV exists 2025-12-12 13:36:51 +00:00
FoxxMD 861578a417 fix(musicbrainz): Wrong default argument for preRequest 2025-12-12 13:30:46 +00:00
FoxxMD 7f62aa79d0 docs(transforms): Add ENV Config quick example 2025-12-11 18:32:49 +00:00
FoxxMD 7223d51690 chore: Bump version for release 2025-12-11 16:52:28 +00:00
FoxxMD 7eabd7f4df fix(tealfm): Allow DID identifier 2025-12-11 16:51:47 +00:00
FoxxMD 88b81dcd12 docs(tranforms): Add default stage 2025-12-11 16:27:23 +00:00
FoxxMD 5d6b3d55cc feat(musicbrainz): Add configurable timeout 2025-12-11 16:00:10 +00:00
FoxxMD a5f4f1be6e docs: Add transform snippets to landing page 2025-12-11 15:35:48 +00:00
FoxxMD ac329cf538 docs(musicbrainz): Additional servers 2025-12-11 15:26:10 +00:00
FoxxMD fafd6a09a0 docs: Improve caching guidance 2025-12-11 15:16:28 +00:00
FoxxMD 759029107a fix(musicbrainz): Fix artist grouping
Remove parenthesis around AND making clause required
2025-12-11 14:08:34 +00:00
FoxxMD 802484c1bb feat(musicbrainz): Implement apikey header 2025-12-11 01:31:11 +00:00
FoxxMD 4dfb485c87 chore: Bump logging for bug fix 2025-12-11 01:21:18 +00:00
FoxxMD 57c1812547 fix(transformer): Fix missing else block when no transform history has occurred 2025-12-11 01:16:59 +00:00
FoxxMD c261699f3e feat(musicbrainz): Reduce retry limit with patched package 2025-12-11 01:16:39 +00:00
FoxxMD 039deca865 feat(musicbrainz): Implement host fallback if multiple are available 2025-12-10 16:20:31 +00:00
FoxxMD f8a18dd1ee test(musicbrainz): Add basic sanity test 2025-12-10 15:07:21 +00:00
FoxxMD de93fe166b refactor(musicbrainz): Move api init and caching closer to api client
* Move client init into MS api client for more control over options used
* Move caching into api call
* Cache URL using async storage
2025-12-10 14:43:29 +00:00
FoxxMD 1956484295 docs: More musicbrainz info 2025-12-09 17:10:56 +00:00
FoxxMD f76604aca5 docs: Add more musicbrainz stage info 2025-12-09 16:56:02 +00:00
FoxxMD 1f01d3e7be docs: Add more sources in quickstart 2025-12-09 16:49:29 +00:00
Matt Foxx eae1a84832 Merge pull request #406 from FoxxMD/musicbrainzTransform
Musicbrainz transformer
2025-12-08 14:09:30 -05:00
FoxxMD 17baebdbf2 feat(transformers): Implement applyng limited transform configs via ENV 2025-12-08 19:02:54 +00:00
FoxxMD 023bd74f12 docs(transformer): Add freetext search 2025-12-08 17:30:24 +00:00
FoxxMD 021ce4d03d test: freetext fallback 2025-12-08 17:08:56 +00:00
FoxxMD 761c0f79fb feat(transformer): Add freetext fallback search for musicbrainz api 2025-12-08 17:04:30 +00:00
FoxxMD 5e63936dda fix: if 2025-12-08 13:11:03 +00:00
FoxxMD a7134e2dae fix(transformer): Missing fallbacksearch assignment 2025-12-07 20:10:12 +00:00
FoxxMD 1289c53941 docs: Update musicbrainz and add additional parts to general transform docs 2025-12-05 20:54:52 +00:00
FoxxMD b4a36a42cd feat(transform): Always log transform diff if in debug mode 2025-12-05 20:48:37 +00:00
FoxxMD ea4d9b3764 fix(transformers): Add missing parts parsing 2025-12-05 19:25:38 +00:00
FoxxMD 5c2819a70c test(tranformer): Add longer timeout and fix logger used in musicbrainz suite 2025-12-05 19:20:31 +00:00
FoxxMD 83eb7a1b65 fix(transformer): Fix optional option object 2025-12-05 19:20:05 +00:00
FoxxMD 8976bb99f5 fix(transformer): Return stage name for proper diff logging 2025-12-05 19:19:50 +00:00
FoxxMD 40b5ef594a fix: revert lastfm debug code 2025-12-05 19:18:39 +00:00
FoxxMD 5c6e2b8cad feat(transformer): Add musicbrainz api url logging 2025-12-05 19:10:08 +00:00
FoxxMD 8083696469 feat(transform): Add proper support for meta and duration transform parts 2025-12-05 18:47:57 +00:00
FoxxMD c07b572abb feat(transformer): Allow fallback musicbrainz search to use aggressive native parsing 2025-12-05 18:30:11 +00:00
FoxxMD 0972a41962 feat(transformer): Try naive split on artist for additional search 2025-12-05 17:51:05 +00:00
FoxxMD aeae449abf test(transformer): Add working non-ascii example 2025-12-05 17:26:04 +00:00
FoxxMD fa6cc13c86 tests: Add edge case musicbrainz tests
Need to have MB_TEST=true in environment to run them
2025-12-05 17:09:24 +00:00
FoxxMD 3e57b006d2 fix(transformer): Escape lucene specia characters when searching musicbrainz
https://github.com/FoxxMD/multi-scrobbler/pull/406#issuecomment-3615254005
2025-12-05 16:32:41 +00:00
FoxxMD 949c1f9176 revert for netlify test 2025-12-04 20:42:58 +00:00
FoxxMD 2bcd0aa858 test commit for netlify 2025-12-04 20:38:57 +00:00
FoxxMD 8ba8a054a6 docs: Add musicbrainz stage 2025-12-04 20:03:02 +00:00
FoxxMD 08301d8664 mysteriously deleted interface? 2025-12-04 18:00:15 +00:00
FoxxMD c36ffa5ffd more bug fixes 2025-12-04 17:52:48 +00:00
FoxxMD 0d02215f71 More forgiving filter/comparison for maybe values 2025-12-04 17:42:58 +00:00
FoxxMD dadea4b90c feat(transformer): Implement country filter/priority for musicbrainz 2025-12-04 17:22:25 +00:00
FoxxMD 9c89142c47 feat: Improve album artist parsing for musicbrainz data
* Change meta to string array
* Compare artist ids
* Add transformer option to ignore various artists
2025-12-04 17:12:22 +00:00
FoxxMD e055e0bd53 feat(transform): Implement more exhaustive, human-readable transform diff 2025-12-04 17:11:15 +00:00
FoxxMD 14c8730435 Handle album artists 2025-12-04 02:54:34 +00:00
FoxxMD 1410e3a952 fix leftover method from refactor 2025-12-03 21:47:34 +00:00
FoxxMD 1e558de5e1 feat(transformer): Implement filtering and sorting of fetched musicbrainz recordings 2025-12-03 20:49:57 +00:00
FoxxMD dab2414a92 chore: Update musicbrainz-api to use ratelimit
Borewit/musicbrainz-api#1115
2025-12-03 19:12:07 +00:00
FoxxMD 03bb1e0552 fix: Use pmap for all bulk transformer 2025-12-03 17:04:58 +00:00
FoxxMD 1eab06c51d recfactor(transform): Use async hooks for logging to identify transform
Reduces logging noise
2025-12-03 17:04:42 +00:00
FoxxMD d217c91a30 Add musicbrainz-api patch for rate limit 2025-12-03 14:49:49 +00:00
FoxxMD b09cbb4bb5 feat(transformer): Implement staggered api calls to respect rate limit 2025-12-02 21:20:34 +00:00
FoxxMD d6d0ce515f fix score usage 2025-12-02 18:59:50 +00:00
FoxxMD db34c33c42 Fix name usage 2025-12-02 18:59:44 +00:00
FoxxMD 2024454f5b feat(transformers): More improvement to musicbrainz
* Implement multiple endpoints for API client with round robin load balancing
* Implement caching responses
* Add transformer options for search triggers
* Implement transformer checks based on search triggers and score
2025-12-02 18:32:50 +00:00
FoxxMD 3718def8b4 fix(transformer): Fix logging for delimiters 2025-12-01 21:59:38 +00:00
FoxxMD 094071b0ba feat: Implement initial musicbrainz api client 2025-12-01 21:58:32 +00:00
Matt Foxx ca8d397653 Merge pull request #404 from FoxxMD/transformProvider
feat: Implement transform pipeline providers
2025-12-01 13:10:44 -05:00
FoxxMD 6ac44397d0 docs: Refactor transformer docs with stages 2025-12-01 18:04:42 +00:00
FoxxMD d6c4d7cf25 refactor(transforms): Implement per-stage defaults with override 2025-12-01 15:16:24 +00:00
FoxxMD 04ae651b15 fix(plex): Fix library filter when media has no library 2025-11-29 21:06:00 +00:00
FoxxMD ef6e2b0f88 refactor(transformer): Add monolithic artist option and make artist string parsing optional 2025-11-29 05:06:26 +00:00
FoxxMD b7271ea4c2 feat(transformer): Allow configuring artist parsing string sources 2025-11-29 04:51:06 +00:00
FoxxMD b5e835a0c6 fix: Don't throw on nonimplemented notify for transformers 2025-11-29 04:36:17 +00:00
FoxxMD a7df5a8d30 feat: Add flow control to transforms and fix bugs 2025-11-28 23:18:09 +00:00
FoxxMD 883050e0b4 feat: Add native transformer options for delimiters and artist exceptions
#364
2025-11-28 23:18:09 +00:00
FoxxMD b6417ed780 Implement initial native transformer #364 2025-11-28 23:18:09 +00:00
FoxxMD affb16fc0e feat: Implement user transformer and refactor components to use async 2025-11-28 23:17:13 +00:00
FoxxMD 56409dd1d7 feat(transformer): Implement User Transformer class 2025-11-28 23:17:13 +00:00
FoxxMD 1af0193636 feat(transform): Implement abstract transformer
#365 #363 #364
2025-11-28 23:17:13 +00:00
FoxxMD 53e766318c refactor: Move abstract init into own abstract class
So that it can be used for transformer. Component (client/source) inherit from init class
2025-11-28 23:17:13 +00:00
FoxxMD c5269791af docs: Fix kitchensink links 2025-11-23 19:22:21 +00:00
FoxxMD fb5ffd053d fix(lastfm): Fix network error default value 2025-11-21 16:16:05 +00:00
Matt Foxx 0c04e7b79f Merge pull request #366 from FoxxMD/transformPipeline
feat: transform pipeline
2025-11-20 14:35:56 -05:00
FoxxMD dc5fab6f9a Refactor metadata stage so atomic parts are objects or booleans 2025-11-20 18:34:23 +00:00
FoxxMD 128c48947e feat(transforms): Allow for config with stage type
As long as it conforms to user stage type. Preserve backwards compatibility
2025-11-20 17:36:03 +00:00
FoxxMD 4cab02e88d fixed tests and isArray arg 2025-11-20 15:26:45 +00:00
FoxxMD a360687264 first attempt at folding in stages
Not working. Tests fail and compiler has errors.
2025-11-20 15:11:46 +00:00
FoxxMD 6a677b6fe1 refactor: Move transform typings to own file 2025-11-20 15:11:46 +00:00
FoxxMD 5c418d5618 chore(tealfm): Round duration for good measure 2025-11-19 17:25:51 +00:00
FoxxMD e6e782dec8 fix(rocksky): Round duration so value is an integer instead of float
#400
2025-11-19 14:44:04 +00:00
FoxxMD ab7d20d7d3 docs(rocksky): Add scrobbling guarantee disclaimer 2025-11-18 15:15:29 +00:00
FoxxMD ec4c2cdd56 fix(rocksky): Increase scrobble delay to respect PDS operation limits 2025-11-18 14:45:11 +00:00
FoxxMD 88d3e13b52 feat(rocksky): Use duration_ms instead of duation 2025-11-17 15:49:27 +00:00
FoxxMD 7bf70d1973 fix(rocksky): Use correct URL for auth validation 2025-11-17 15:48:16 +00:00
FoxxMD 8eae2dc69d chore: Bump version for release 2025-11-17 15:23:15 +00:00
FoxxMD aa44a08e9e fix(rocksky): Fix wrong property used for api auth header 2025-11-17 15:22:46 +00:00
FoxxMD 6071abca49 docs: Update rocksky link to main page rather than docs 2025-11-13 12:56:22 -05:00
FoxxMD 86a719ba4a docs: Add new clients to repo readme 2025-11-13 17:18:20 +00:00
FoxxMD 39b6f6e602 docs: Fix kitchensink link 2025-11-13 17:16:17 +00:00
FoxxMD bfce5dcc54 chore: Bump version for release 2025-11-13 17:14:36 +00:00
FoxxMD 18537e4e08 docs: Add subsonic guidance for lz scrobbling 2025-11-13 17:13:45 +00:00
FoxxMD 30db8712fc docs: Add redirects for old pages 2025-11-13 17:08:30 +00:00
Matt Foxx 1701a5e5f1 Merge pull request #397 from FoxxMD/lzParsingCleanup
refactor: Cleanup and consolidate listenbrainz listen parsing
2025-11-13 11:46:18 -05:00
FoxxMD 406c39b6b2 fix(tealfm): Fix scrobble play date context 2025-11-13 16:44:56 +00:00
FoxxMD ce7ad36db4 refactor(listenbrainz): Consolidate lz endpoint submit parsing into lz response parsing
Consolidtes logic for parsing lz listen data structure
2025-11-13 16:25:06 +00:00
FoxxMD fa4bf5ab10 refactor(listenbrainz): Move parsing functions out of static 2025-11-13 15:43:44 +00:00
FoxxMD 83d9af2aea fix(listenbrainz): Fix interfaces for submit/listen and consolidate 2025-11-13 15:36:17 +00:00
FoxxMD 433761525c fix(rocksky): Add scrobble to deadletter when ignored 2025-11-13 14:00:30 +00:00
FoxxMD f7a7a36d8b docs: Add robots 2025-11-12 16:59:36 +00:00
Matt Foxx 7e375f1531 Merge pull request #392 from FoxxMD/rocksky
feat(rocksky): Implement Rocksky Source/Client
2025-11-12 10:42:02 -05:00
FoxxMD 357397f225 chore: Add markdown extension to devcontainer 2025-11-12 15:36:14 +00:00
FoxxMD 78bf507226 docs: Update docs to include Rocksky Source and updated config 2025-11-12 15:35:39 +00:00
Matt Foxx f892851b60 Merge pull request #396 from FoxxMD/nowPlayingAccuracyImprovement
Now playing accuracy improvement
2025-11-12 10:10:16 -05:00
FoxxMD 4244ddb8c2 fix(listenbrainz): Use duration_ms if duration not provided 2025-11-11 19:54:34 +00:00
FoxxMD 3e67e9189f feat(listenbrainz): Add request body to logging for debugging 2025-11-11 19:50:14 +00:00
FoxxMD de1cbb2aae fix: Improve timing and update frequency to match scrobbler behavior
* Aggressively start Now Playing update (based on reported) but aggressibely end, based on stale/orphaned, so updates are early but not often
* Refactor update thresholds to use scrobble client behavior
  * LFM and LZ use track duration as "time visible" for Now Playing, don't re-update during that time period
  * Add thresholds to logging for easier troubleshooting

#395
2025-11-11 19:49:58 +00:00
FoxxMD db17455b2e fix: Revert accidental debug commit 2025-11-11 15:18:21 +00:00
FoxxMD a7729fbfa6 feat: Make ATProto handle transform usable by RockSky and teal.fm 2025-11-11 15:10:39 +00:00
FoxxMD 771fdc0686 chore: Regenerate schema with rebased results 2025-11-11 14:48:58 +00:00
FoxxMD 8cad2d4efd feat(rocksky): Implement Rocksky Source/Client 2025-11-11 14:47:59 +00:00
Matt Foxx a094a1aa65 Merge pull request #389 from FoxxMD/tealfm
feat: Implement teal.fm as source/client
2025-11-11 09:37:10 -05:00
Matt Foxx f2d45c5622 Merge pull request #386 from FoxxMD/GH-375/subsonicLoop
feat(subsonic): Add repeat detection
2025-11-10 13:15:50 -05:00
FoxxMD a429bccf07 fix(teal): Adding pds with env when it no longer exists 2025-11-07 22:44:02 +00:00
FoxxMD 04d950980d feat(tealfm): Massage handle for users who don't read docs 2025-11-07 22:41:30 +00:00
FoxxMD 7ec90b97d6 docs: Add tealfm to landing page 2025-11-07 22:30:38 +00:00
FoxxMD a4f989c5e4 feat(tealfm): Resolve pds from handle 2025-11-07 22:29:54 +00:00
FoxxMD da4fbd2f27 docs: Fix tealfm source link 2025-11-07 18:56:22 +00:00
FoxxMD b9e6f32500 chore: Update schema 2025-11-07 18:55:40 +00:00
FoxxMD 5c5c653c3b fix: Fix Source/Client data types 2025-11-07 18:55:27 +00:00
FoxxMD a9e7a4bf16 docs(tealfm): Add docs 2025-11-07 18:46:57 +00:00
FoxxMD 1b4baafa67 feat(teal): Change pds viewer web url 2025-11-07 17:35:00 +00:00
FoxxMD 794ef08aa2 feat(tealfm): Api improvements
* Implement PDS check for App auth clients
* Fix error logging for app loging
2025-11-07 17:31:16 +00:00
FoxxMD fa6ed323ff feat(tealfm): Add tealfm Source 2025-11-07 17:17:50 +00:00
FoxxMD 8110e8e9fa refactor(tealfm): Move common functionality to api client 2025-11-07 16:44:41 +00:00
FoxxMD 12a6eec740 test(tealfm): Add example config to pass config tests 2025-11-07 16:40:27 +00:00
FoxxMD 472021dd2c feat(tealfm): Add ENV config 2025-11-07 16:35:39 +00:00
FoxxMD ebb74d1b5c feat: Implement working tealfm client
* Add pds option
2025-11-07 16:31:41 +00:00
FoxxMD ea23a89101 refactor(tealfm): Implement abstract api client with concrete classes for different auth methods 2025-11-07 15:02:56 +00:00
FoxxMD 9062619d38 feat(tealfm): Implement app password auth 2025-11-07 14:51:31 +00:00
FoxxMD 3fb64be54f feat(tealfm): Initial oauth attempt 2025-11-06 17:22:06 +00:00
Matt Foxx 3e083b19f7 Merge pull request #382 from FoxxMD/GH-380/lzEndpoint
fix(endpointlz): Return expected OK response body
2025-11-05 13:22:47 -05:00
Matt Foxx e197c71bbb Merge pull request #388 from FoxxMD/ghWorkflowHarden
ci: Harden workflows using zizmor
2025-11-05 12:35:11 -05:00
FoxxMD 7b36d95dfc ci: Harden remaining workflows using zizmor
* Pin action digests
* Remove template injection where possible
2025-11-05 12:08:46 -05:00
FoxxMD 0427b6e945 try with double quotes 2025-11-05 11:48:00 -05:00
FoxxMD 326d9e58d7 ci: Use zizmor to fix and audit image publish action
* Pin actions to digest
* Replace template substitution with envs
2025-11-05 11:26:41 -05:00
FoxxMD 63c079f08e docs: Improve sources documentation 2025-11-04 19:18:46 +00:00
FoxxMD ff74fd7e4c docs: Update kitchensink 2025-11-04 19:04:17 +00:00
FoxxMD 680f862ee8 docs: Change installation to category doc link 2025-11-04 18:52:42 +00:00
FoxxMD abdd7f0b55 docs: Improved linking on config/landing and configuration type refinement 2025-11-04 18:49:16 +00:00
FoxxMD c017dd734b feat(subsonic): Add basic repeat detection based on listened duration
#375
2025-11-04 16:31:36 +00:00
Matt Foxx ad478adefd Merge pull request #385 from FoxxMD/depCleanup
refactor: frontend dependency cleanup
2025-11-04 10:40:35 -05:00
FoxxMD b11bd52963 chore(frontend): Update sass package and vite config to remove deprecation warnings 2025-11-04 14:36:22 +00:00
FoxxMD 538df6b6d0 refactor(frontend): Migrate tailwind config to v4 2025-11-04 14:17:51 +00:00
FoxxMD 819afcdb8a refactor(frontend): Update tailwind and move generation into vite
* Use vite tailwind plugin instead of postcss
* Update tailwind so it actually works with plugin
* Remove postcss
* Merge vite config into inline vite-express config
2025-11-04 13:55:31 +00:00
FoxxMD a5693f7c03 chore: Remove unused typedoc config 2025-11-04 13:35:02 +00:00
FoxxMD 22eb5b1168 docs: Add missing client flag for example json usage for clients
Fixes #383
2025-11-03 21:54:44 +00:00
FoxxMD 9402caa4ae docs(endpointlz): Add navidrome url setup instructions 2025-11-03 16:56:32 +00:00
FoxxMD 0aff56e891 feat(endpointlz): Add more logging for invalid routes 2025-11-03 16:10:44 +00:00
FoxxMD a5f6aaa7c0 feat(listenbrainz): Use end-of-string token and wildcard route to better log malformed LZ endpoint routes 2025-11-03 16:08:17 +00:00
FoxxMD 4ee503655c fix(endpointlz): Return expected OK response body
Fixes #380
2025-11-03 15:47:24 +00:00
FoxxMD e53a82782c docs: fix lastfm aio name 2025-11-01 03:50:20 +00:00
FoxxMD 020c6815ba docs: Fix readme links 2025-10-31 17:58:46 +00:00
FoxxMD 5281a92e81 docs: A word 2025-10-31 15:56:05 +00:00
Matt Foxx 8577eb44af Merge pull request #381 from tsirysndr/master
Fix typos in Rocksky documentation
2025-10-31 11:46:08 -04:00
Tsiry Sandratraina edd3cf25b5 Fix typos in Rocksky documentation 2025-10-31 17:24:29 +03:00
FoxxMD b17719c868 docs: Fix missing search index 2025-10-31 13:02:30 +00:00
FoxxMD 971ec9d4db feat(jellyfin): Add frontend url override as env #374 2025-10-30 20:20:10 +00:00
Matt Foxx 6607654e8a Merge pull request #379 from FoxxMD/docsRevamp
Docs revamp
2025-10-30 16:16:52 -04:00
FoxxMD 891e591ceb docs: Reorganize doc contents 2025-10-30 19:56:07 +00:00
FoxxMD 2540ed3945 docs: Add client own files 2025-10-30 18:52:59 +00:00
FoxxMD 7ac3f33cd4 docs: Move Source configs to own files 2025-10-30 18:35:58 +00:00
FoxxMD 9b91f6897e Add new Source overview using category 2025-10-30 17:06:39 +00:00
FoxxMD bc62b99401 docs: Add commonly used components to global scope 2025-10-30 17:06:22 +00:00
FoxxMD a5d1cea910 Add some snippers 2025-10-30 15:21:08 +00:00
FoxxMD 3e3473f6a8 chore: Ignore docusaurus build folders when searching 2025-10-30 15:19:14 +00:00
FoxxMD a0bdd15d15 docs: Move landing page to docs to simply url structure
Set docs as base for router so there isn't an additional docs in url
2025-10-30 15:19:01 +00:00
FoxxMD 920eb10c05 docs: Fix rocksky name/link typo 2025-10-30 09:30:14 -04:00
FoxxMD ae7a436758 chore: Bump version for release 2025-10-30 13:18:49 +00:00
FoxxMD 92d246b45a docs: Add rocksky to repo readme 2025-10-30 13:18:36 +00:00
Matt Foxx 0af480ac1a Merge pull request #377 from FoxxMD/GH-376/plexUrlParseFix
fix(plex): Use better url parsing method
2025-10-30 08:47:48 -04:00
Matt Foxx 9f52c2ec67 Merge pull request #369 from gabeklavans/fix/apprise-tags
fix: parse and use the tags in Apprise config
2025-10-29 11:33:05 -04:00
FoxxMD cfb278087e docs: Update listenbrainz json example to include url 2025-10-29 14:50:21 +00:00
FoxxMD 402b0d2cc7 docs: Add Rockysky setup instructions 2025-10-29 14:47:59 +00:00
FoxxMD 67c79f2eb7 fix(plex): Use better url parsing method
Fixes #376
2025-10-29 13:48:47 +00:00
FoxxMD d759b00c7e test: Add more tests for url parsing 2025-10-29 13:43:34 +00:00
Matt Foxx cac8163e58 Merge pull request #374 from wolffshots/feature/optionally-redirect-image-paths
feat(JellyfinApiSource): add option to override the Jellyfin base url
2025-10-24 09:16:21 -04:00
wolffshots 11dbdaf6cc chore(JellyfinApiSource): extract URL replacement to func and add tests 2025-10-23 17:53:51 +02:00
wolffshots ac6b04f492 feat(JellyfinApiSource): add option to override the Jellyfin base url used in the frontend 2025-10-23 17:22:57 +02:00
Matt Foxx 0790da2e0d feat(plex): Enable accepting self-signed certs #372 (#373)
* feat(plex): Enable accepting self-signed certs #372
* docs(plex): Add invalidcert param to plex example config
2025-10-21 09:10:38 -04:00
Matt Foxx dffb1c79ec Merge pull request #370 from h-wb/feat/add-source-as-lb-ms-name
feat(listenbrainz): add source as music service name
2025-10-08 08:27:01 -04:00
h-wb 46cc9f0b6e feat(listenbrainz): add source as music service name 2025-10-07 23:01:59 -04:00
gabe 140e9f0b20 fix(notification): parse and use the tags in Apprise config 2025-09-26 14:51:04 -04:00
FoxxMD 0fe5779c4b chore: Bump for release 2025-09-23 15:48:46 +00:00
FoxxMD 06b1475b63 chore: remove unused object-hash package 2025-09-23 15:48:21 +00:00
Matt Foxx 6bc415120d Merge pull request #359 from FoxxMD/objectHashReplace
fix: Update object hashing function
2025-09-23 11:43:13 -04:00
FoxxMD e061540e6b fix(jellyfin): Guard against undefined NowPlaying Path
#355
2025-09-18 14:15:20 +00:00
FoxxMD 38bf31a67f feat(lzendpoint): Accept artist and release artist names in submit payload
#360
2025-09-18 13:45:29 +00:00
Matt Foxx c8c3b4888f Merge pull request #343 from FoxxMD/caching
feat: Caching and persistent scrobble queues
2025-09-17 08:54:44 -04:00
FoxxMD 70bb30406a test: fix/workaround tests for new transformrule assumptions 2025-09-16 15:27:47 +00:00
FoxxMD d9e71f6770 fix: Do not use transform until after client is ready
Fixes #356
2025-09-16 15:16:27 +00:00
FoxxMD 7cee9f04cf fix: Update object hashing function
Might be a solution for #358
2025-09-15 17:37:30 +00:00
FoxxMD 0a673fd333 refactor: Decrease persist interval to 10 seconds
Faster interval means less likely user will update queue and exit MS before cache is saved
2025-09-11 19:14:01 +00:00
FoxxMD fd316a8e84 fix: Add full coverage for cached queue updating during client lifecycle 2025-09-11 19:14:01 +00:00
FoxxMD c1e1de2255 Increase file cache size to 2000
Should be ~700kb, full up. This should be a generous upper limit for number of scrobbles queued/dead at the same time.
2025-09-11 19:14:01 +00:00
FoxxMD 9bea31e1b2 docs: Add caching docs 2025-09-11 19:14:01 +00:00
FoxxMD 351edd8102 fix: Fix cache test missing awaits 2025-09-11 19:14:01 +00:00
FoxxMD 10dcb7f30d feat: Implement cache file streaming with progress logging
If cache files get large enough to cause noticeable delay it will be helpful to log progress
2025-09-11 19:14:01 +00:00
FoxxMD ffb41b4e30 test: Add scrobble client caching test 2025-09-11 19:14:01 +00:00
FoxxMD d78bc48e6f feat: Allow passing file cache options other than connection 2025-09-11 19:14:01 +00:00
FoxxMD b4154bb0d5 refactor: Move transient cache to exportable function 2025-09-11 19:14:01 +00:00
FoxxMD 48467b08d3 chore: Bump with-local-tmp-dir version
tmp dependency has been removed so previous buggy behavior(?) is gone
2025-09-11 19:14:01 +00:00
FoxxMD 682d507683 build: move net-interceptor to dev packages 2025-09-11 19:14:01 +00:00
FoxxMD 814e609efc fix: Add clone as runtime dependency 2025-09-11 19:14:01 +00:00
FoxxMD 652fa5a14c feat(cache): Improve data marshalling and cache init
* Use typeson for stringified data marshalling
* Use clone for in-memory serializing to preserve dayjs
* Refactor cache backend init into indepedent, testable functions
* Add `false` as cache provider type to allow disabling secondary cache
2025-09-11 19:14:01 +00:00
FoxxMD 39bc9cd410 build(vscode): Update devcontainer to use compose stack with valkey for caching integration 2025-09-11 19:14:01 +00:00
FoxxMD 63b6012488 feat(cache): Rehydrate dayjs data on cached scrobble parsing 2025-09-11 19:14:01 +00:00
FoxxMD 32e2aa6974 test: Setup transient di cache 2025-09-11 19:14:01 +00:00
FoxxMD 78f4767dd2 refactor: Refactor di cache to allow singleton or transient 2025-09-11 19:14:01 +00:00
FoxxMD 05a9ca15a9 refactor(cache): Update file cache name and gitignore 2025-09-11 19:14:01 +00:00
FoxxMD e2c8158aec feat: Log file cache save 2025-09-11 19:14:01 +00:00
FoxxMD 4eee6d4322 somewhat working scrobble caching 2025-09-11 19:14:01 +00:00
FoxxMD 56f5431dd9 chore: Update iti usage
* Update package to improve typing support/esm
* Remove dependency on sources/client/notifiers to prevent circular dependency
2025-09-11 19:14:01 +00:00
FoxxMD a00f94f9b1 feat: Implement caching backend
* Two-tier caching
  * primary is always in-memory LRU
  * secondary supports file and valkey
* Different caches for metadata and scrobbles
  * no file support for metadata (too big)
2025-09-11 19:14:01 +00:00
Matt Foxx df4fe87178 Merge pull request #351 from FoxxMD/ntfyToken
feat: Add Access Token auth for Ntfy webhook
2025-09-11 15:07:11 -04:00
Matt Foxx 89c39d2d25 Merge pull request #354 from FoxxMD/lastfmRecent
fix(lastfm): Full destructure recent response and log respon on error
2025-09-11 15:01:41 -04:00
FoxxMD b60422c26c fix: Try auth prefixed with Bearer 2025-09-11 18:57:30 +00:00
FoxxMD 59fce8271e feat: Add Access Token auth for Ntfy webhook 2025-09-11 18:57:30 +00:00
FoxxMD 506faf39dc fix(lastfm): Full destructure recent response and log respon on error
Maybe recenttracks/track does not exist for totally new accounts, though it should.

Guard against this and log response if something unexpected happens so we can troubleshoot

#353
2025-09-11 18:27:56 +00:00
Matt Foxx adf5401fff Merge pull request #347 from FoxxMD/ytm400
Youtube Music updates
2025-09-10 10:15:55 -04:00
FoxxMD dbf5cba7cb chore: Bump logging version
Fixes LOG_LEVEL non-output issue
2025-09-10 13:04:34 +00:00
FoxxMD b3a6beb8f4 docs(ytm): Add oauth warning 2025-09-10 12:57:42 +00:00
Matt Foxx 1291f60e62 Merge pull request #260 from FoxxMD/improvedArtistStringParsing
testing and improvements for artist string parsing
2025-09-10 08:47:50 -04:00
FoxxMD e86945355c fix: Add additional logging for ytm history request 2025-09-05 18:56:16 +00:00
FoxxMD 8dd9958b30 Use default scopes 2025-09-05 18:55:53 +00:00
FoxxMD 869c7dcfe1 fea(ytm): Allow user-defined oauth scopes 2025-09-02 13:07:46 +00:00
FoxxMD 7068da5fc2 test(ytm): Fix failing type assertion 2025-09-02 12:24:33 +00:00
FoxxMD 3704fba1f8 feat(ytm): Add debug logging #345 2025-09-02 12:18:21 +00:00
FoxxMD 6d99790f7d chore: Update ytm #345 2025-09-02 12:15:49 +00:00
Matt Foxx 3e7f1965e7 Merge pull request #341 from FoxxMD/nowPlayingPlayerUpdates
feat: Improve Player behavior for Sources only tracking Now Playing data
2025-08-27 11:23:24 -04:00
FoxxMD 87d05b7c75 fix(listenbrainz): Fix missing album/release_name for listenbrainz endpoint #342 2025-08-27 12:26:46 +00:00
FoxxMD aca23ed90d test: Update lz expected config count 2025-08-26 20:26:32 +00:00
FoxxMD a01c8e3f17 feat(ui): Add Now Playing behavior for ui Player
* show "Now Playing" instead of Unknown/Playing
* Don't show empty listened duration/percent
2025-08-26 20:22:12 +00:00
FoxxMD eba9bc1b6b feat(webscrobbler): Use Now Playing Player 2025-08-26 20:01:03 +00:00
FoxxMD 34be8add14 docs: Remove koito from listenbrainz example
Not really needed since koito has its own docs
2025-08-26 19:45:48 +00:00
FoxxMD bd44fa5609 feat: Change stale/orphan interval to match current play duration for Players that only track Now Playing data
#338
2025-08-26 19:40:18 +00:00
FoxxMD c81bdf608f fix(lastfm): Remove VA from album artist #340 2025-08-25 17:00:19 +00:00
FoxxMD e9e5987330 chore: Bump version for release 2025-08-20 13:23:16 +00:00
FoxxMD ce4b0f7aa7 docs: Add Maloja source to readme 2025-08-20 13:23:00 +00:00
Matt Foxx eb6e469dc9 Merge pull request #336 from FoxxMD/GH-295/malojaSource
feat: Add Maloja Source
2025-08-19 23:19:26 -04:00
FoxxMD 4f6fb4ffea fix(maloja): Remove null duration/length 2025-08-18 14:24:43 +00:00
FoxxMD 24df22781f fix: Don't removed undefined keys from nested objects
Don't want to break 3p libraries (dayjs)
2025-08-18 14:23:35 +00:00
FoxxMD 33fda80d0a feat: Improve artist string parsing
* Don't split artist with joiner when only one joiner is present
* Override naive parsing if metabrainz mapped artists fit with provided joiners
2025-08-07 19:32:51 +00:00
FoxxMD a3d8372f48 feat: More artist parsing improvements
* Use more context-aware list parsing with ampersands
* Ignore artists with slashes when wrapped by word-boundary
2025-08-07 13:23:10 +00:00
FoxxMD b5dbde66c4 WIP testing and improvements for artist astring parsing
* Implement faker data generation for artist string
* Add test suite for parsing different styles of artist strings
2025-08-07 13:23:10 +00:00
FoxxMD abf532c6bb feat(maloja): Add Maloja Source #295 2025-08-06 16:48:39 +00:00
FoxxMD 976c7c0e82 refactor(maloja)!: Modernize Maloja API usage
* Move API code into own class for reusability with future Source
* Remove Maloja V2 compatibility
* Throw on connection if server version is too old or unknown
2025-08-06 15:44:59 +00:00
FoxxMD 06b23d6287 docs: Update Spotify docs and usage due to Redirect URI changes
As of April 2025 Spotify no longer allows insecure redirect URIs which complicates initial Spotify setup.

* Improve spotify App creation instructions
* Add several approaches to creating a valid redirect URI
* Remove Spotify as the default Source example in docs due to complexity of Redirect URI requirements

Closes #330
2025-08-01 17:28:16 +00:00
FoxxMD 38a15d6426 chore: Bump version for release 2025-08-01 12:50:29 +00:00
FoxxMD c2c86033cb feat(listenbrainz): Add recording_mbid to submit payload for Koito compatibility
Koito should accept track_mbid but it only uses recording_mbid, so include that in payload.

#333
2025-07-31 16:40:21 +00:00
FoxxMD 72c94ca1e3 feat(listenbrainz): Include additional_info from LZ source Play if none parsed for MS play 2025-07-31 16:32:16 +00:00
FoxxMD bf6bd4be55 fix(listenbrainz): Parse MB metadata from LZ Source listens and set in Play
Had not updated LZ source to parse metadata into Play since adding brainz metadata to Play object

#333
2025-07-31 15:53:43 +00:00
FoxxMD 53f78b02fb chore: Bump for release 2025-07-28 13:59:17 +00:00
FoxxMD 6f5a8a7bc7 docs: Improve wording around Now Playing state 2025-07-28 13:46:46 +00:00
FoxxMD 0d5dd34597 docs: Remove koito mentions from LZ docs
Full Koito integration should be used! Removing mentions reduces ambiguity for new users.
2025-07-24 17:51:16 +00:00
FoxxMD a93ec8dd7e docs: Add clarifying callout for multi-use components 2025-07-24 17:51:16 +00:00
Matt Foxx 1e488b576c Merge pull request #317 from FoxxMD/GH-314/plexjsVersion
fix(Plex): Temporary plex validation fix
2025-07-21 08:50:40 -04:00
Matt Foxx d3d8eb40b5 Merge pull request #329 from FoxxMD/repeatPlayPersistence
Repeat play detection improvements
2025-07-21 08:50:17 -04:00
FoxxMD db54761422 fix: Add last played data and check for repeat on new Play #318 2025-07-17 15:45:18 +00:00
FoxxMD aa9f20f544 Fix formatting for hints 2025-07-17 15:44:35 +00:00
FoxxMD 60371f52f8 refactor: Move Play position closeness and duration comparisons to own functions
* Hint for logs returns for all conditions
* Add tests
2025-07-17 15:08:09 +00:00
FoxxMD 87394fbce7 Remove patch
Didn't work anyways
2025-07-17 13:24:30 +00:00
FoxxMD 72341ff1de fix(plex): Temporary fix for library response validation #314
Catches and ignores outdated validation from @lukehagar/plexjs if we can verify raw value contains the required objects

https://github.com/LukeHagar/plexjs/issues/35
2025-07-17 13:24:30 +00:00
FoxxMD 63cebf3784 fix(plex): Ignore library response validation
As temporary fix for #314
2025-07-17 13:24:30 +00:00
FoxxMD 60f3f05f67 fix(Plex): Bump plexjs version to fix response validation
#314
2025-07-17 13:24:30 +00:00
FoxxMD ce39065c80 docs: Fix social card image 2025-07-16 13:33:10 +00:00
FoxxMD 3f39e9efa1 docs: Update docusaurus to 3.8 2025-07-16 13:19:04 +00:00
Matt Foxx f37dbd75c6 Merge pull request #328 from FoxxMD/GH-318/repeatDetection
feat: Track if play is a repeat and use in duplicate scrobble detecti…
2025-07-15 15:40:39 -04:00
FoxxMD 47ad7a3b74 feat: Track if play is a repeat and use in duplicate scrobble detection #318
* Use MS Player to mark Play as a repeat if session repeat is detected
* Remove FUZZY temporal accuracy as acceptable for detecting duplicate if candidate play is marked as repeat
2025-07-15 19:23:49 +00:00
FoxxMD 91747c0682 docs: Add Source client config guidance #325 2025-07-15 15:48:13 +00:00
FoxxMD 80f8495f8e fix(plex): Fix regression with allowing non-music when using librariesAllow 2025-07-14 20:19:13 +00:00
Matt Foxx c6bb258bf4 Merge pull request #324 from FoxxMD/lzAlbumField
Lz album field
2025-07-14 12:48:14 -04:00
FoxxMD e70abc593c chore: Update readme Koito entries 2025-07-14 14:55:29 +00:00
FoxxMD 22d73c6a7f fix(lastfm): Fix lastfm providing empty string for non-defined album #323 2025-07-14 14:48:50 +00:00
FoxxMD 82afe4195c chore: Bump version for release 2025-07-14 14:12:23 +00:00
FoxxMD 5e9409ab66 feat(plex): Add libraries allow/block warning 2025-07-14 13:49:40 +00:00
FoxxMD e64854eb14 fix(plex): Strict comparison of libnrary names #326
* Fixes libraries containing partial allow/disallow names from being able to pass filter
* Fix not checking valid library types
2025-07-14 13:43:22 +00:00
FoxxMD 333f70bd7e docs: hide navbar on scroll 2025-07-11 17:58:50 +00:00
FoxxMD ace7d5efc9 docs: Fix anchor scrolling by specifying logo height 2025-07-11 17:56:13 +00:00
FoxxMD cd14f82753 docs: Move updating instructions to own page 2025-07-11 17:27:22 +00:00
FoxxMD aba718aef1 docs: Move docker install instructions before local 2025-07-11 17:05:24 +00:00
FoxxMD c87497071d docs: Add updating instructions 2025-07-11 17:04:02 +00:00
FoxxMD 2a35e7cf5c fix(listenbrainz): Fix sending undefined release_name in scrobble #323 2025-07-10 19:39:08 +00:00
FoxxMD 3b98036687 docs: Remove old FAQ entries 2025-07-10 16:37:56 +00:00
FoxxMD 3fc935b96d feat(listenbrainz): Add additional player/service meta info for LZ scrobbles #224 2025-07-10 15:52:51 +00:00
FoxxMD 7586f226ba feat(listenbrainz): Add submission_client #224 2025-07-10 14:34:01 +00:00
FoxxMD 1a0e600db5 docs: Sort Source/Clients alphabetically
* Sort on readme/landing page and in configuration docs
* Makes skimming docs easier
2025-07-10 14:22:19 +00:00
FoxxMD 1dba5a6c6f docs: Add Koito to overview summary 2025-07-10 13:15:45 +00:00
FoxxMD 3ec0652fbb docs: Update docker installation wording 2025-07-10 13:11:17 +00:00
Matt Foxx e71d5983a4 Merge pull request #322 from FoxxMD/koito
Implement Koito Client/Source
2025-07-10 07:50:50 -04:00
FoxxMD bb9b5fc5cd fix: superagent type error false positive 2025-07-09 16:30:15 +00:00
FoxxMD 89fde5a6fe chore(listenbrainz): Add guidance in logging to switch to Koito source/client 2025-07-09 16:19:47 +00:00
FoxxMD 24ff8f2b0f docs: Add Koito client/source docs 2025-07-09 16:17:47 +00:00
FoxxMD f103563cb7 feat(koito): Implement Koito Source 2025-07-09 15:40:13 +00:00
FoxxMD 1767268a48 fix: Only return interpolated album value if not undefined 2025-07-09 15:39:22 +00:00
FoxxMD 8ab2d61742 feat(koito): Implement Koito client 2025-07-09 15:04:19 +00:00
FoxxMD 132580af6f chore: Update superagent types 2025-07-09 15:04:01 +00:00
FoxxMD 375c0123c6 feat(koito): Add koito types/config 2025-07-09 13:12:15 +00:00
FoxxMD 769002412d docs: Remove flatpak install guidance 2025-07-08 20:34:16 +00:00
FoxxMD 7fa567c1e4 docs(mpris): Add remote socket guidance 2025-07-08 20:13:10 +00:00
FoxxMD 8dfc9a6d55 refactor(mpris): Remove socat service in favor of simplified dbus connection
Can connect to dbus over TCP socket using ENV which is much simpler.
2025-07-08 19:53:55 +00:00
FoxxMD 0efc85c516 feat(mpris): Better handling of socket error on connection check
Prevents a low-level emitted error from completely crashing MS
2025-07-08 19:51:57 +00:00
FoxxMD dbb8e3c5e0 feat(mpris): Add s6 finish script to prevent restart of socat 2025-07-08 19:36:08 +00:00
FoxxMD f4f1eed645 feat: Add socat service 2025-07-08 14:38:22 -04:00
FoxxMD 0a31f51567 docs: Update MPRIS instructions for docker 2025-07-08 17:25:28 +00:00
FoxxMD c255138a6e docs: Add Koito quickstart instructions 2025-07-08 14:36:10 +00:00
Matt Foxx 856a05a357 Merge pull request #320 from FoxxMD/symfoniumPlex
Fix symfonium reporting issues for plex
2025-07-08 08:27:53 -04:00
FoxxMD 18915167f4 feat: Add more logging to apprise errors #158 2025-07-07 17:44:17 +00:00
FoxxMD 34b0995d6b fix(plex): Increase max drift to 35 seconds to account for symfonium lag #271
Symfonium only reports position every 30 seconds vs. plex/plexamp 15 seconds. Increase max drift so MS doesn't falsely seek and reset play state.
2025-07-07 15:04:43 +00:00
FoxxMD 4e5f38378e feat: Add RT Player metrics to player logging 2025-07-07 15:03:30 +00:00
FoxxMD 5d2c9261ae chore: Bump version for release 2025-07-07 12:22:23 +00:00
FoxxMD e039d4512c ci: Add optional rybbit analytics to docs build 2025-07-07 12:20:16 +00:00
FoxxMD 51509a3531 ci: Add rybbit variables for gh actions 2025-07-03 17:51:38 +00:00
FoxxMD 8f032f2379 feat(listenbrainz): Allow now playing reporting for koito
Doesn't affect scrobbling and means if/when NP is actually supported it'll work automatically
2025-07-03 13:10:52 +00:00
FoxxMD ff11e26219 Clean up logging for Now Playing 2025-07-03 13:10:13 +00:00
FoxxMD f004aa4cfd feat(listenbrainz): Implement Now Playing functionality 2025-07-03 12:50:40 +00:00
FoxxMD 2104f2a99d fix(now playing): Catch update errors but only log
We don't need to stop the scrobbler for now playing issues since its not a critical function. Just log as warning.
2025-07-03 12:19:34 +00:00
Matt Foxx 389129aadf Merge pull request #316 from msparkles/feat/lastfm-nowplaying
feat: lastfm nowplaying
2025-07-02 16:59:21 -04:00
FoxxMD f885726ed1 docs: Add Now Playing and configuration 2025-07-02 20:50:03 +00:00
FoxxMD 3cc452323d feat: Allow Now Playing to be globally toggled by ENV 2025-07-02 20:42:12 +00:00
FoxxMD 780acb32d7 fix(scrobbler): Fix duplicate map keys causing delay in Now Playing update 2025-07-02 17:03:48 +00:00
FoxxMD bf5fdb95f4 test: Add Now Playing updating and scheduler tests 2025-07-02 17:03:26 +00:00
FoxxMD 7d7ccf53bb test: Add Now Playing filter/sorting tests 2025-07-02 16:03:09 +00:00
Matt Foxx 94837b7e03 feat(subsonic): Implement filtering plays by user (#319)
* feat(subsonic): Implement filtering plays by user #301
2025-07-02 08:15:44 -04:00
FoxxMD a9c1c7083d feat: Add config source to startup logging #309 2025-07-01 19:33:10 +00:00
FoxxMD 8dd6fc15cc docs: Improve example config rendering for ambiguous configs
* Filter examples based on client/source configuration
* Add `type` to all configs in AIO examples

Fixes #310
2025-07-01 18:30:24 +00:00
FoxxMD 32ca57fc65 feat: Implement Now Playing queue, scheduler, and source sorting
* Add queue for aggregating Now Playing updates
* Filter play based on 1. source priority and 2. player stickiness or deterministic order
* Use toad scheduler to processing NP queue
2025-07-01 16:18:15 +00:00
FoxxMD 9d748f26c0 feat: Pass source type-name to playingNow 2025-07-01 14:55:38 +00:00
FoxxMD 5af1454f36 feat: Add Now Playing user config
* Enable/disable now playing reporting
* WIP source filters for now playing
2025-06-30 16:12:11 +00:00
FoxxMD bf7a660633 feat: Add Now Playing as class configuration and implement rate limit intervals
* Define if scrobble client can update Now Playing based on class property, use this to filter now playing update
* Use thresholds to determine when/if Now Playing should be updated
* Set LastfmScrobbler as supported for Now Playing
2025-06-30 15:29:51 +00:00
Madeline Sparkles f0723f23e8 feat: lastfm now-playing scrobbling 2025-06-30 00:14:02 +02:00
Madeline Sparkles 36357135cb fix(docs): remove archaic JSDocs on ScrobbleClients.scrobble 2025-06-29 23:17:28 +02:00
FoxxMD 8be08a5c29 chore: Bump for release 2025-06-20 20:09:21 +00:00
Matt Foxx 9fe5b9b671 Merge pull request #312 from FoxxMD/lzEnrich
feat: Enrich Listenbrainz submit payload
2025-06-20 16:07:43 -04:00
FoxxMD 720c07b008 feat(listenbrainz): Include more ids/fields in submit additional_info #311 2025-06-20 16:43:01 +00:00
FoxxMD 7fdf93c5d3 feat(spotify): Add spotify meta ids to play 2025-06-20 16:42:04 +00:00
FoxxMD a0fd466bcf dev: Add ENV only launch config 2025-06-19 18:15:45 +00:00
FoxxMD 35d62c913a fix: Guard against undefined type in config.json #310 2025-06-19 18:12:57 +00:00
FoxxMD ede2d9f71a chore: Bump version for release 2025-06-19 16:22:39 +00:00
Matt Foxx acccc32813 Merge pull request #296 from FoxxMD/deezer-internal
feat: Implement Deezer Internal (ARL) Source
2025-06-17 20:41:08 -04:00
FoxxMD 69f73ff09f docs(deezer): Rewrite Deezer Source with ARL implementation
* Add ARL implementation docs and warnings
* Update json examples to include both types of deezer configs
2025-06-17 15:16:13 +00:00
FoxxMD 305f3c42ae fix(deezer): options are optional 2025-06-17 15:14:01 +00:00
FoxxMD d6ac4c34c5 feat: Implement better during/range temporal comparisons
* Refactor temporal comparisons to provide granular "during" thresholds
* Use duration for ignoring discovery with aggressive mode in Deezer #296
2025-06-17 10:10:34 -04:00
FoxxMD 9c6eeaafdb feat: Fuzzy diff threshold configurable
* Refactor fuzzy diff theshold to be configurable
* Configure aggressive fuzzy discovery for Deezer to be 40 seconds #296
2025-06-17 10:10:34 -04:00
FoxxMD 6bd841fea2 feat(deezer internal): Add fuzzy discovery ignore option
Allows user-configurable decision on whether to ignore fuzzy-matched discovered plays
2025-06-17 10:10:34 -04:00
FoxxMD e05c46e9ce fix(deezer official): Fix missing interval interface property 2025-06-17 10:10:34 -04:00
FoxxMD e94109dc75 feat: Implement Deezer Internal (ARL) Source 2025-06-17 10:10:34 -04:00
FoxxMD a68dea5193 chore: Bump version for release 2025-06-16 19:22:43 +00:00
FoxxMD b5d56b75d7 test(listenbrainz): Fix expected client count 2025-06-16 16:06:57 +00:00
FoxxMD c8daffb935 docs(listenbrainz): Add Koito compatibility and config example #300 2025-06-16 16:02:13 +00:00
FoxxMD 18a7f26c54 feat(listenbrainz): Implement limited support for Koito as Listenbrainz Source/Client #300
* Support Koito server detection via public route
  * Warns users of limited support on detection
* Implement play history retrival for Koito server
2025-06-16 15:49:39 +00:00
FoxxMD e7395e79a5 feat(listenbrainz): Detect /1/ version prefix on base URL
Remove /1/ from base URL to further normalize user URL and make config easier #300
2025-06-16 14:15:48 +00:00
FoxxMD 08ee6d379f fix(listenbrainz): Normalize URL and join parts correctly
* Normalize base URL to make user URL configuration easier/more robust
* Use joinPath for concetenating URL to avoid missing slashes #300
2025-06-16 14:04:15 +00:00
Matt Foxx 9c692539ce Merge pull request #298 from FoxxMD/jellyfin-musicbrainz
feat(jellyfin): Add musicbrainz metadata #297
2025-06-04 14:15:09 -04:00
FoxxMD 5cd5061f20 feat(jellyfin): Add musicbrainz metadata #297 2025-06-04 13:44:15 +00:00
FoxxMD 46bcf6d6a6 chore: Bump version for release 2025-05-29 13:20:34 +00:00
FoxxMD 4da931269c fix(plex): On Plex webhook routes filter plex sources to get webhook source only
#291
2025-05-27 17:31:34 +00:00
FoxxMD d19d40d479 test: Fix real time player not triggered during event loop
Running tests synchronously preventing rt player from advancing which cause each player update to be considered an overdrift
2025-05-27 17:07:30 +00:00
FoxxMD b3e1c7f660 chore: Update devcontainer to node 20 to match docker image 2025-05-27 17:05:50 +00:00
FoxxMD 1242a710df fix: Fix NaN and undefined initial states for rt player #292 2025-05-27 15:29:06 +00:00
FoxxMD b724eca9be docs: Add missing var for docs deploy 2025-04-23 15:04:20 +00:00
FoxxMD 376d4936cc docs: Add google site verification 2025-04-23 15:01:42 +00:00
FoxxMD a5da0573c5 docs: Remove flatpak installation method
See #287
2025-03-31 18:31:46 +00:00
FoxxMD 4694ce45a7 chore: Update flatpak description 2025-03-31 12:12:28 -04:00
FoxxMD 7c7d710cd3 fix(ui): Guard against null listenedDuration
Fixes #285
2025-03-28 08:21:04 -04:00
FoxxMD e2cd7e2991 chore: Bump version for release 2025-03-25 01:15:40 +00:00
FoxxMD 92d8eb8d6f chore: Update static config schema 2025-03-25 01:15:26 +00:00
FoxxMD d14e7d9b2e fix(lastfm): Remove duration for scrobble if value is 0 2025-03-25 01:09:31 +00:00
FoxxMD e4befae55a fix(lastfm): Fix endpoint regex to exclude auth callback url 2025-03-20 19:14:34 +00:00
FoxxMD 0e00b425b4 fix(icecast): rename old scrobble behavior variable 2025-03-20 16:27:30 +00:00
FoxxMD fcf6c8eb4c docs: Add some common source options 2025-03-20 16:23:01 +00:00
FoxxMD 242bacc1be feat(source): Optional position for non-positional sources
* Allow non-positional Sources to still report position (for display only)
* Refactor Azuracast to be non-positional due to reported position not always being accurate (azuracast approximates track length)
2025-03-20 15:40:31 +00:00
FoxxMD cbe28f97a0 feat(source): Improve "Should Scrobble" functionality
* Rename from manualListening to Should Scrobble to better describe functionality
* Move check to Source scrobble function to avoid short circuting Source player for no reason
* Add to Azuracast and make functionality more generic
2025-03-20 15:12:00 +00:00
FoxxMD 336972f586 fix(ui): Update status indicator for ingress sources 2025-03-20 14:13:48 +00:00
Matt Foxx 81edb31e7b Merge pull request #283 from FoxxMD/icecast
Icecast
2025-03-19 12:57:38 -04:00
FoxxMD dbde66ad77 docs: Add Icecast docs 2025-03-19 16:50:57 +00:00
FoxxMD efbf2da816 feat(icecast): Switch to metadata-only parsing 2025-03-19 16:34:19 +00:00
FoxxMD 38d1db2f3f feat: Implement Icecast Source MVP 2025-03-19 15:20:44 +00:00
Matt Foxx 265ae82663 Merge pull request #278 from FoxxMD/GH-263/azuracast
feat: Add Azuracast Source
2025-03-19 09:28:27 -04:00
FoxxMD 2bd2972af6 docs: Fix bad merge of azuracast/musiccast config 2025-03-19 13:22:52 +00:00
Matt Foxx 1bdf083e28 Merge branch 'master' into GH-263/azuracast 2025-03-19 09:17:44 -04:00
Matt Foxx 4c233fdded Merge pull request #279 from FoxxMD/GH-274/musiccast
feat(musiccast): Implement MusicCast Source
2025-03-19 08:42:40 -04:00
FoxxMD e0060fe3e5 feat: Add ENVs for default scrobble threshold for duration/percent
* SOURCE_SCROBBLE_DURATION env sets default duration
* SOURCE_SCROBBLE_PERCENT env sets default percent
2025-03-18 17:28:14 +00:00
FoxxMD 2adb3bd052 docs(musiccast): Add docs for Yahama MusicCast 2025-03-17 21:02:26 +00:00
FoxxMD 0dca49ab43 fix(player): Check for 0 duration before finalizing listen session with duration-based calculation 2025-03-17 20:40:06 +00:00
FoxxMD 6a71d4a495 fix(musiccast): Treat 0 total_total as undefined
Prevents some positional player logic from running on a functionally-useless value
2025-03-17 20:40:06 +00:00
FoxxMD 230ddf4a48 fix(source): Do not calculate polling interval decrease if duration does not exist 2025-03-17 20:40:06 +00:00
FoxxMD e4e1797ac5 fix(musiccast): Remove hardocded port for debugging 2025-03-17 20:40:06 +00:00
FoxxMD 1dd3185715 fix: Better handling of 0 duration tracks
* Check for zero duration before using progress bar in debug logging
* Adds tests for scrobble thresholds to make sure 0 duration is handled
2025-03-17 20:40:06 +00:00
FoxxMD 4fee231a7b test(musiccast): Add tests for basic connectivity 2025-03-17 20:36:15 +00:00
FoxxMD b5ead39792 feat(musiccast): Switch play info fetch order
net/usb is more likely to be used since it has more sources. Likely using it will reduce required fetches in most usage scenarios.
2025-03-17 20:36:15 +00:00
FoxxMD 190431b9d4 feat(musiccast): Implement MusicCast Source 2025-03-17 20:36:15 +00:00
FoxxMD 210fa35cb6 docs: Add Last.fm Endpoint source docs 2025-03-14 16:34:43 +00:00
FoxxMD 479af1cd5e docs: Add Listenbrainz Endpoint source docs 2025-03-14 16:29:48 +00:00
Matt Foxx c72831cd12 Merge pull request #281 from FoxxMD/normalScrobbleEndpoints
feat: Implement dummy endpoint Sources for Listenbrainz and Last.fm
2025-03-14 11:24:08 -04:00
FoxxMD f68a9493ce fix(listenbrainz): add dummy validate-token endpoint 2025-03-14 08:16:56 -04:00
Matt Foxx 78a93d0809 Merge pull request #256 from FoxxMD/configurablePlayerStale
feat(source): Stale/orphan scrobble and timestamp improvments
2025-03-13 15:26:46 -04:00
FoxxMD 3680ac8af1 feat(lastm): Implement MVP Lastfm endpoint source 2025-03-13 18:44:08 +00:00
FoxxMD e74ba52c47 fix(listenbrainz): Improved slug and normal lz endpoint detection 2025-03-13 16:53:25 +00:00
FoxxMD d3cd07c5c3 feat(listenbrainz): Implement MVP LZ endpoint source 2025-03-13 16:20:37 +00:00
FoxxMD 2b890d4704 refactor: Pass reportedTS for testing purposes 2025-03-13 11:06:26 -04:00
FoxxMD 47eead2a18 feat: Use timestamp for position MS change on RT player
Makes testing easier
2025-03-13 11:06:26 -04:00
FoxxMD 38ea3115f6 test: Add tests for scrobble behavior when cleaning up players 2025-03-13 11:06:26 -04:00
FoxxMD f11a2b5442 fix: Use last known position for final range when cleaning up stale RT player
Prevents listen duration from being reported as overdrift RT position due to lack of player updates
2025-03-13 11:06:26 -04:00
FoxxMD 818f67d6da feat(source): Add relative time since last activity to logging
Makes logs easier to read when looking for stale source/player
2025-03-13 11:06:26 -04:00
FoxxMD 84f353220d feat(source): Clear listening range on stale to prevent erroneous scrobble on resume
Clearing pre-stale listening range prevents any future resume (player becomes non-stale) from using old listening range to scrobble. Represents a physical "break" between listening sessions for the same song
2025-03-13 11:06:26 -04:00
FoxxMD 47541a449b feat: Use human-friendly timestamp for stale/ophan interva logging 2025-03-13 11:06:26 -04:00
FoxxMD 1a62edab37 feat(source): Add stale/orphaned intervals as user configurable 2025-03-13 11:06:26 -04:00
FoxxMD 5927450840 fix(ytm): Recover artist/album from YTM when not surfaced by youtube.js
Use flex_columns for parsing raw data when musicshelf when artist/album does not have an endpoint LuanRT/YouTube.js#381

Fixes #280
2025-03-13 10:40:47 -04:00
FoxxMD ec9bea70fd chore: Bump YTM dependency version 2025-03-13 10:37:53 -04:00
FoxxMD 2f9a45b1e4 fix: Filter components by name and check for undefined
Fixes #273
2025-03-12 19:16:32 +00:00
FoxxMD 3c649df2e9 docs(azuracast): Add azuracast Source docs 2025-03-11 16:41:42 +00:00
FoxxMD ab1766ca0a feat(azuracast): Add station name hint and fix labels 2025-03-11 16:10:38 +00:00
FoxxMD a42de78ad3 feat(azuracast): Implement manual listening 2025-03-11 16:06:46 +00:00
FoxxMD 81bde3a771 feat(azuracast): Add MVP azuracast source implementation 2025-03-11 15:21:07 +00:00
FoxxMD 982e6655ef chore: Add more log guidance on bug report 2025-02-14 17:51:17 +00:00
FoxxMD 44ce0cba3c feat(azuracast): Implement config and types 2025-02-03 16:53:39 +00:00
FoxxMD c1e1c69b5e fix: Missing optional period on vs. when parsing artist 2025-01-27 21:13:32 +00:00
FoxxMD 142defdd20 docs: Put delimited artist example in expander 2025-01-27 14:57:15 +00:00
FoxxMD aad9f2b4de docs: Add primary artist extraction examples for scrobble modification 2025-01-27 09:46:14 -05:00
FoxxMD 8e92407182 test: Add modification example for parsing a primary artist from delimited string 2025-01-27 09:36:15 -05:00
FoxxMD 94210e29d1 docs: Fix extra array in title modification example
Fixes #258
2025-01-27 09:16:34 -05:00
FoxxMD d2c6194314 ci: Add comments on PR SHA usage 2025-01-21 14:06:16 -05:00
FoxxMD 11ca7a724d try pull SHA directory for build
So that build summary details used SHA
2025-01-21 13:58:47 -05:00
FoxxMD 3057908074 fix(ci): Add context to build-push so it uses checked out PR ref 2025-01-21 13:28:45 -05:00
FoxxMD 6a9e538845 chore: Bump version for release 2025-01-21 15:04:38 +00:00
Matt Foxx 130538cd9a Merge pull request #255 from FoxxMD/GH-254/playCompletedOnCleanup
fix(spotify): Generate played object from cleanup with correct TS
2025-01-18 12:57:51 -05:00
FoxxMD 1486613744 fix(spotify): Generate played object from player cleanup with correct timestamp
Missing arg to pass to getPlayedObject to ensure the timestamp used for playDate is the same as normally discovered tracks. Without the arg two tracks played with the second being scrobbled on stale would cause the latter to have the same TS as the former

fixes #254
2025-01-17 18:55:35 +00:00
Matt Foxx f2516206c0 ci: Refactor OCI image workflows to use multi-runner for cross-arch builds (#246)
Replaces `build-push-action` buildx QEMU building for multiple `arch` with a multi-runner matrix that builds each image on native runners and combines digests before pushing to registries.

* Use arm public preview runner
* Refactor publish image workflow to use multi-runner
* Refactor PR workflow to use multi-runner
2025-01-17 09:35:11 -05:00
FoxxMD f8902e05a6 ci: Update sanity test to install/build concurrently 2025-01-16 16:15:00 -05:00
Matt Foxx c59b47c801 Merge pull request #252 from FoxxMD/paralellBuild
feat(docker): Paralellize npm install and build processes
2025-01-16 16:06:27 -05:00
FoxxMD 0e4845f2e2 feat(docker): Paralellize npm install and build processes 2025-01-16 20:48:05 +00:00
FoxxMD e2775cd9de chore(docker): Update node version and reduce npm verbosity
* Update to latest node 20.x minor version
* Remove `--verbose` and enable `--no-audit` for npm install to reduce install time
  * These were left over from debugging ARM builds from Feb 2024
2025-01-16 14:43:29 -05:00
Matt Foxx 816bec88c8 Merge pull request #251 from FoxxMD/docusaurus36
docs: Update to Docusaurs 3.6 to improve build times
2025-01-16 14:25:19 -05:00
FoxxMD d724bef4e4 docs: Update to Docusaurs 3.6 to improve build times 2025-01-16 14:07:47 -05:00
FoxxMD cac851f120 chore: Bump version for release 2025-01-15 15:16:26 +00:00
FoxxMD c1df74ee27 docs: Strikeout tautulli in readme 2025-01-15 15:16:01 +00:00
FoxxMD 0c7b51c622 docs: Update bug report template to correct debug mode link 2025-01-15 15:12:26 +00:00
FoxxMD 56ecad24d4 docs: Update kitchensink with newer jellyfin/plex examples 2025-01-15 15:09:38 +00:00
FoxxMD 6bb600648a docs: Add final deprecation notices for Plex/Tautull/Jellyfin legacy sources 2025-01-15 15:00:44 +00:00
FoxxMD fe2610c35a docs: Add debug mode information 2025-01-15 14:36:48 +00:00
FoxxMD 84bcbc9cea docs(ytm): Update docs with more debugging options 2025-01-15 14:02:50 +00:00
FoxxMD d741377e5a feat(ytm): Debug mode enables log diffs 2025-01-15 13:50:47 +00:00
Matt Foxx 1ea106970d Merge pull request #248 from FoxxMD/GH-227/ytmMusicalChairs
fix(ytm): Improve history handling
2025-01-15 08:27:55 -05:00
Matt Foxx a879b7aded Merge pull request #249 from FoxxMD/GH-223/plexPlatformCleanup
fix(plex): Improve handling of orphaned API sessions
2025-01-14 08:19:12 -05:00
FoxxMD 30ee000676 fix(plex): Refactor final range position to be configurable
* Keep default 3 seconds grace period
* Set grace period for plex to API viewoffset period (rtdrift) of 17 seconds #223
2025-01-09 18:42:09 +00:00
FoxxMD 703cf80d5a fix(source): Implement player cleanup with play discovery for stale platforms
* Do play cleanup during polling for new plays so that we can discover tracks from abandoned players
* Fixes missed scrobbles from Plex API when Source stops returning a session due to player queue end #223
2025-01-09 18:01:12 +00:00
FoxxMD 34289f0176 docs: defer script load 2025-01-03 19:24:51 +00:00
FoxxMD 8b8f32de02 feat(ytm): Use durations to generate play dates for interim tracks
#226
2025-01-03 18:28:55 +00:00
FoxxMD 095e5cc0d9 feat(ytm): Conservative skip detection
#226
2025-01-03 17:56:07 +00:00
FoxxMD 0c46c0a079 refactor(ytm): Clean up tests and history parsing functions 2025-01-03 16:25:33 +00:00
FoxxMD dd4b2ebb8c fix(ytm): Compare recent changed history to detect outdated responses
Store responses when history changes and then check if YTM returns an outdated response after previously returning new tracks.

#227
2025-01-02 19:03:38 +00:00
FoxxMD d30ee0c35a feat(source): Ensure delay on close-interval for scrobbling is less than interval 2025-01-02 18:29:34 +00:00
FoxxMD 484fb16bba fix(ytm): Use diff type to restrict valid history changes
* Diff type should always be prepend since we are checking for new tracks
  * Warn and log if another type is detected
* Warn if more than one track diffed for discovery
* Refactor and and make YTM history parsing testable

#227
2025-01-02 18:28:59 +00:00
FoxxMD f320e6cef0 feat: Include comment in play diff when present 2025-01-02 18:25:27 +00:00
FoxxMD ea2421bc6d chore: Bump plexjs version
Includes originalTitle spec addition so we can remove patch
2025-01-02 16:59:36 +00:00
FoxxMD f43c31fb9a docs: Add lnav config 2024-12-27 18:49:29 +00:00
FoxxMD 6825ad55e3 feat(ui): Disable minifiying frontend identifiers
No need to minify to save space since this is not a high-traffic site and preserving identifiers helps with debug issues
2024-12-27 18:49:16 +00:00
FoxxMD 92841f8bb3 fix: Default positional listen range to 0 position if none is provided
* doesn't make sense to use undefined as start. if we are providing a position it should be 0, if unknown

#245
2024-12-27 18:43:51 +00:00
FoxxMD 38e5e4c9a9 feat: Add init log message for debug mode status 2024-12-20 13:47:54 -05:00
FoxxMD 1bcfed05af feat: Log player state when using debug mode 2024-12-20 18:28:21 +00:00
FoxxMD e00ec4098a feat: Reduce polling log noise 2024-12-20 18:10:22 +00:00
FoxxMD 5d44953435 revert ts comment causing failing build 2024-12-20 17:46:04 +00:00
FoxxMD 80ad5a3518 feat: Fully implement use of DEBUG_MODE 2024-12-20 14:02:21 +00:00
FoxxMD b5683ba4b8 fix(jellyfin): Fix missing check for undefined play
#239
2024-12-17 20:53:54 +00:00
FoxxMD 884b3963d3 fix(plex): Use track artist from response data when album artist is present
* Fixes #241 by using the track artist as the primary artist when album artist is present
* Bug is reported in LukeHagar/plexjs#27 but will need be patched at runtime for the foreeable future due to npm packages not being published since September LukeHagar/plexjs#26
2024-12-16 20:11:50 +00:00
Matt Foxx 8de2296aaf Merge pull request #221 from FoxxMD/improveInitUsage
refactor: bubble init usage and errors to simplify recovery
2024-12-16 09:43:53 -05:00
Matt Foxx c1869f469c Merge pull request #240 from Fratt/fix-spotify-album-artists
fix(spotify): Album artists no longer missing
2024-12-16 09:34:29 -05:00
FoxxMD 86196b3122 test(spotify): Test album artist parsing 2024-12-16 14:31:10 +00:00
Fratt fd03e42240 fix(spotify): Album artists no longer missing 2024-12-14 13:08:00 +01:00
FoxxMD 3e230b0d68 fix(ui): Fix card header right-side alignment 2024-12-11 20:41:06 +00:00
FoxxMD 133d7f56e5 fix(ui): Wording for non-polling sources start/restart 2024-12-11 20:35:22 +00:00
FoxxMD 78d048ba62 fix: missing implemented methods for test class 2024-12-11 18:24:42 +00:00
FoxxMD 323004a730 feat: Implement start/restart/force init from UI regardless of status 2024-12-11 18:20:12 +00:00
FoxxMD 626bca9951 feat: Initialize usage refactored everywhere
* try-catch and bubble up depending on usage
* replace poll/monitor code on startup with scheduler task usage
* better notification messages with truncated cause chain
2024-12-11 17:30:08 +00:00
FoxxMD 3ae0d4ff45 feat: Add stage Error classes and cause chain for notification 2024-12-10 21:17:44 +00:00
FoxxMD 9d85df54e1 refactor: Normalize all testAuth implementation to throw on error 2024-12-10 20:56:31 +00:00
FoxxMD 0ff1c95fd1 TODO partial refactor of init usage to throw errors 2024-12-10 20:34:33 +00:00
FoxxMD b93274fd53 Merge remote-tracking branch 'origin/master' 2024-12-10 15:19:55 -05:00
FoxxMD 0f0d1d64f9 feat(jellyfin): More robust connection check and logging 2024-12-10 20:19:30 +00:00
FoxxMD d77e6c6f22 feat(jellyfin): Bump client major version 2024-12-10 20:19:10 +00:00
Matt Foxx 83ff5348c6 Merge pull request #216 from FoxxMD/GH-215/notifiersRelax
feat(notifications): Make init more granular and always complete init
2024-12-10 11:54:59 -05:00
FoxxMD 65012d40ed feat(notifications): Make init more granular and always complete init
* Notifications are not mission critical so its okay if they fail on init because service outage may be transient. Always init notification services and always attempt to push (we catch failures anyway)
* Parse more info from notification URL and test simple reachability of host/port to make troubleshooting easier

Fixes #215
2024-12-10 11:33:33 -05:00
FoxxMD feb02bfa85 docs(ytmusic): Clearer wording for troubleshooting content
Also increase non-erroneous diff logging from DEBUG to VERBOSE to raise signal a bit.
2024-12-10 15:55:20 +00:00
FoxxMD 276e51b8ea docs: Fix broken links 2024-12-10 15:40:15 +00:00
FoxxMD c83d77c02a docs: Fix bad transform links 2024-12-10 15:28:25 +00:00
FoxxMD 0cdb48a71a ci: Generate schema files for docsite in GH docs deploy workflow 2024-12-10 10:13:06 -05:00
FoxxMD 1556d7ac69 chore: Generate schema files during docker build for docsite 2024-12-10 10:08:02 -05:00
Matt Foxx 1e65abd962 Merge pull request #236 from FoxxMD/ytOauthRedux
feat(ytm): Re-implement auth with cookie and oauth
2024-12-10 09:16:14 -05:00
FoxxMD 9f11d799ac feat(source): Add experimental file logging 2024-12-09 18:44:43 +00:00
FoxxMD 5c0f419e7e feat(ytm): Implement ENV config 2024-12-06 19:28:32 +00:00
FoxxMD c33d42808a docs(ytmusic): Add new auth docs and update FAQ 2024-12-06 19:09:32 +00:00
FoxxMD e8716a45b2 feat(ytmusic): Custom redirectUri checks 2024-12-06 15:56:32 +00:00
FoxxMD 570dee30e3 fix(ytmusic): Add missing logging for redirect URI 2024-12-06 15:33:02 +00:00
FoxxMD 97222ed233 refactor(ytmusic): Improve auth handling for reauthentication 2024-12-06 15:18:07 +00:00
FoxxMD e2a7fff6f9 chore: Bump youtubei.js major version
* Fixes parsing warning for history response
2024-12-06 15:17:18 +00:00
FoxxMD efc8246a76 chore: Add docker-compose dev file and vscode task 2024-12-05 09:37:58 -05:00
FoxxMD b4a95e0cf9 fix(ytmusic): query string on redirect uri incorrectly encoded 2024-12-05 09:18:05 -05:00
FoxxMD c66d5d4627 docs: Improve schema generation and compatibility
* Patch generator to generate definition titles until vega/ts-json-schema-generator#2127 is resolved
* Add launch config for debugging schema generation
* Disallow topRef generation so docusarus json viewer works
* Write to docsite static assets on generation
2024-12-04 14:46:40 -05:00
FoxxMD 4de28e0390 feat(ytmusic): Add more innertube options to user configuration 2024-12-04 19:38:54 +00:00
FoxxMD f74721b366 fix(ytmusic): Fix missing api prefix for redirectUri 2024-12-04 15:04:36 +00:00
Matt Foxx 4fb16e7098 Merge pull request #232 from CodeWithMa/remove-deprecated-version
fix: remove deprecated version from docker-compose.yml
2024-12-03 16:35:46 -05:00
Matt Foxx a76c351206 Merge pull request #235 from CodeWithMa/fix_case
fix: fix WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match
2024-12-03 16:35:03 -05:00
FoxxMD 7faf94cfab feat(ytm): Re-implement auth with cookie and oauth
Youtube TV seems no longer have scope for reading history or account details?

Cookie may work and custom oauth seems most stable based on reporting from LuanRT/YouTube.js#803
2024-12-03 15:58:08 -05:00
Ma 3a1e29f682 fix: fix WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match 2024-11-28 15:57:17 +01:00
Ma 88cb287df8 fix: remove deprecated version from docker-compose.yml 2024-11-20 17:16:14 +01:00
dependabot[bot] eb26ee0cd4 Merge pull request #194 from FoxxMD/dependabot/npm_and_yarn/npm_and_yarn-ac4cac0c7a 2024-10-31 12:44:16 +00:00
dependabot[bot] 844833f348 chore(deps): bump the npm_and_yarn group across 2 directories with 3 updates
Bumps the npm_and_yarn group with 1 update in the / directory: [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js).
Bumps the npm_and_yarn group with 2 updates in the /docsite directory: [micromatch](https://github.com/micromatch/micromatch) and [webpack](https://github.com/webpack/webpack).


Updates `xml2js` from 0.6.0 to 0.6.1
- [Commits](https://github.com/Leonidas-from-XIV/node-xml2js/compare/0.6.0...0.6.1)

Updates `micromatch` from 4.0.7 to 4.0.8
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.7...4.0.8)

Updates `webpack` from 5.92.1 to 5.95.0
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.92.1...v5.95.0)

---
updated-dependencies:
- dependency-name: xml2js
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: micromatch
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: webpack
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-31 12:40:57 +00:00
FoxxMD 38b02cf771 Update dependencies 2024-10-31 12:38:04 +00:00
Matt Foxx 1706d5cab9 Merge pull request #203 from FoxxMD/GH-195/ytoauth
feat(youtube)!: Use oauth-based api library for better stability
2024-10-31 08:30:48 -04:00
Matt Foxx 640d2ff28b Merge pull request #219 from FoxxMD/GH-218/plexLocal
fix(plex): Handle plex local user
2024-10-30 13:42:55 -04:00
FoxxMD 312b6ce987 fix(plex): Handle plex local user
* Identify when session is for the local user (no user is logged in)
* Add Local User as default allowed when no usersAllow settings
* Allow user config to allow/block local user
* Update plex docs

Fixes #218
2024-10-30 16:44:51 +00:00
FoxxMD 489f70929e docs: Fix spelling mistake 2024-10-29 13:47:38 -04:00
FoxxMD 904ddfa5c6 docs(tautulli): Add deprecation notice and discussion link 2024-10-29 16:57:59 +00:00
FoxxMD 3ed6840607 feat: Improved filtering for platform players with multiple states
* Add session key dervied from source data to Play and PlayerState
* Discriminate states based on a session key, if possible
  * Log which states are being dropped based on session key (plex)
* Add session key to important logging (new player play, in UI for player info)
2024-10-29 14:59:55 +00:00
FoxxMD 93125dd7c8 feat: Reduce drop reason logging noise for jellyfin/plex API sources
Only log the first occurrence of a unique session drop so that subsequent drops don't make logging noisy
2024-10-28 18:33:52 +00:00
FoxxMD 34356c6c56 fix(youtube): Fix signout check 2024-10-28 18:03:10 +00:00
FoxxMD 05466fed2b feat(youtube): Add config option to always log diff 2024-10-28 18:03:10 +00:00
FoxxMD 535b818a22 fix(youtube): Implement bump-only list change detection
Should fix new way YTM orders recent history #195
2024-10-28 18:03:10 +00:00
FoxxMD e62e04dd14 feat(youtube)!: Use oauth-based api library for better stability
* Fixes #195 missing (404) history endpoint which only appear when using cookies
* Might fix #158 due to using a different authentication method
2024-10-28 18:03:10 +00:00
FoxxMD 61cd5fcf7b fix: Bump @foxxmd/logging to fix DST rolling file issue
#214
2024-10-28 18:02:04 +00:00
Matt Foxx f308f71b5d Merge pull request #212 from FoxxMD/playerStateCleanup
feat(player): Real time positional player state
2024-10-25 14:54:23 -04:00
FoxxMD c498bde1fd feat(ui): Show indeterminate state for non-positional players 2024-10-25 15:57:30 +00:00
FoxxMD 0c9b496137 feat(player): Implement real-time positional state tracking
* Introduce positional and non-positional data structures
  * Refactor state player into types of each
  * Refactor listen ranges and progress into types of each
* Implment (internal) real-time player and base positional player seeked/repeat on real-time drift instead of just reported position
* Refactor tests to use (emulated) real-time components
2024-10-24 20:37:41 +00:00
FoxxMD 9682d4f8f9 refactor(player): Cleaner player update signature 2024-10-24 14:53:30 +00:00
Matt Foxx da76945f5e Merge pull request #211 from FoxxMD/plexApi
feat(plex): Initial Plex API Source implementation
2024-10-24 09:45:17 -04:00
FoxxMD 51074a58f4 Add deprecation warning to plex webhook source 2024-10-24 13:41:10 +00:00
FoxxMD 3cc735b9c8 fix(plex): Refactor player state to allow for drift and tracking pause based on Source behavior
Plex only updates player position every 15 seconds (of played track) so player state needs to be adapted to not detect this as a pause or seek.

* Allow per-source drift allowed before triggering seek
* Allow per-source pause detection
2024-10-23 20:30:33 +00:00
FoxxMD b74f31c26d feat(plex): Implement album art for UI 2024-10-23 18:42:55 +00:00
FoxxMD 4a96cbfb0e docs(plex): Clean up api/webhook sections and add migration guide 2024-10-23 15:18:13 +00:00
FoxxMD 77a3c352b1 feat(plex): Implement workaround for getting plex token details
Ignore sdk validation error and get raw value in order to parse authenticated user
2024-10-23 10:59:36 -04:00
FoxxMD 598ae01082 feat(plex): Add track progress tracking to api source 2024-10-23 13:40:50 +00:00
FoxxMD 54e11899a0 Fix missing comma 2024-10-22 18:29:11 +00:00
FoxxMD dc4962ade1 feat(plex): Initial Plex API Source implementation 2024-10-22 18:21:28 +00:00
FoxxMD ccf317c06f docs: Fix Jellyfin API migration version 2024-10-17 10:40:54 -04:00
FoxxMD aff5717f19 fix(ui): Fix album art ordering 2024-10-16 16:26:23 +00:00
FoxxMD fa39209272 feat(ui): Implement album art for Jellyfin and Spotify 2024-10-16 16:09:24 +00:00
FoxxMD d63082a889 fix(ui): Skip lg breakpoint for cleaner interface 2024-10-16 16:09:05 +00:00
FoxxMD a28d46ecbe feat(ui): Add album art support in player 2024-10-16 16:08:41 +00:00
FoxxMD 3bc72ce881 feat(ui): Improve player ui when player is stopping 2024-10-16 13:56:05 +00:00
FoxxMD 314210117b fix(player): Fix missing calculated state on player stop 2024-10-16 13:55:35 +00:00
FoxxMD 57a8e48d3a fix(jellyfin): Fix memory player hanging on end of state
Was not passing stopped state due to undefined play but need to do this to let last play actually be scrobbled.

Refactor jellyfin session validation and types for MemorySource to correctly allow processing player state with no plays
2024-10-16 13:55:05 +00:00
FoxxMD 2d3ab86238 fix: Fix string splitting 2024-10-16 13:03:37 +00:00
FoxxMD b76edbf7de fix: Revert including platform for track dispay by default 2024-10-16 12:47:43 +00:00
Matt Foxx b2efc34b80 Merge pull request #210 from FoxxMD/GH-209/jellyfinCleanup
fix(jellyfin): Enforcing media type and session handling fixes
2024-10-15 14:36:56 -04:00
FoxxMD dee8d6bc61 chore(vscode): Add markdown extension to devcontainer 2024-10-15 17:42:04 +00:00
FoxxMD 3e5576481d feat(jellyfin): Support and enforce library collection type
* Default disallow any activity not from a library of collectionType 'music'
* Allow user config for allow/block by library name
* Allow user config for allowing additional library collection types
* Update docs and example config
2024-10-15 17:41:33 +00:00
FoxxMD ffd74aea6f docs: Enable parsing json5 for AIO examples 2024-10-15 17:39:49 +00:00
FoxxMD 145af33239 feat(jellyfin): More item type validation 2024-10-15 14:25:51 +00:00
FoxxMD 3851b2226a fix(jellyfin): Detect theme song extras play and discard
Fixes #209
2024-10-15 13:13:36 +00:00
FoxxMD bb132101b5 fix(jellyfin): Use correct id for tracking first-time seen media 2024-10-14 17:19:41 -04:00
FoxxMD 1e6251edfb ci: Fix sanity test checkout ref and shorten APP_VERSION sha usage 2024-10-14 13:07:12 -04:00
FoxxMD e251da9b8e test(jellyfin): Update valid activity tests 2024-10-14 15:42:54 +00:00
FoxxMD 335ee0cd60 fix(jellyfin): Set multi-platform in constructor 2024-10-14 11:15:59 -04:00
FoxxMD dc9f6c22ad feat(jellyfin): Add debug options for media data troubleshooting 2024-10-14 11:11:58 -04:00
FoxxMD 5568b54c99 fix(jellyfin): Enforce media type when determining session validity
Fixes #209 for erroneous scrobbling of video
2024-10-14 11:01:48 -04:00
FoxxMD e6e35e052a feat: Implement platform output when building track info 2024-10-14 11:01:11 -04:00
Matt Foxx 9c21db8172 Merge pull request #205 from FoxxMD/GH-200/jfPlayFormat
fix(jellyfin): Gaurd against undefined playback data
2024-10-11 15:57:57 -04:00
FoxxMD 77c9141d92 fix(jellyfin): Gaurd against active session without now playing data 2024-10-11 13:47:39 -04:00
FoxxMD 68e86f4f90 fix(jellyfin): Gaurd against undefined playback data
SDK types say AlbumArtists etc. should be defined but #200 shows that's not always the case, for some reason.

Check for undefined value on playback data that requires additional transformation to prevent errors.

Fixes #200
2024-10-11 13:47:39 -04:00
Matt Foxx 5e95f60461 Merge pull request #208 from FoxxMD/vegaSchema
fix: Replace typescript-json-schema with ts-json-schema-generator
2024-10-11 13:32:52 -04:00
FoxxMD 908d7d4177 fix: Replace typescript-json-schema with ts-json-schema-generator
Fixes a lot of headaches:

* vega is more up to date and extensible
  * no more hacky regex for reference names
  * complete control over parsing and formatting (const as enum)
  * does not duplicate typescript as dependency
  * should properly throw errors on schema generation instead of just logging to console
* move schema static files into programmatic creation instead of package scripts
* fix types being removed in prod which caused schema generation errors
2024-10-11 12:28:55 -04:00
FoxxMD de1a9c35ec fix: Add missing express types for prod dependencies
Required for ts-schema generator to correctly work since we use it in config definitions
2024-10-11 09:28:01 -04:00
FoxxMD f7fa9cd330 fix: Guard against ts-schema generation errors
* Check if generator is null and throw
* Check if schema is null before trying to validate, will make errors less cryptic
2024-10-11 09:27:12 -04:00
FoxxMD ee8b371850 fix: Missing tsconfig and other root files for some reason?? 2024-10-11 09:23:02 -04:00
FoxxMD 601228a369 fix: Fix boolean options in issue template forms 2024-10-10 15:12:24 -04:00
FoxxMD 5dcaefc460 chore: Rename config template 2024-10-10 15:06:21 -04:00
FoxxMD 026e94fc1b chore: Add issue template config 2024-10-10 15:05:24 -04:00
FoxxMD fd7c8467b4 chore: Add templates for feature request and new source/client 2024-10-10 15:03:31 -04:00
FoxxMD 06e651a844 chore: Migrate bug report template to form 2024-10-10 14:41:38 -04:00
FoxxMD 1b0e7a3dfd ci: Make test workflow reusable and add run sanity check
* Add sanity run steps to check for obvious errors when running in production
* Refactor test job to be reusable
2024-10-10 12:05:16 -04:00
FoxxMD abc5d1861a fix: Specify ts-json-schema as NON dev dep
Not enough to include it in both dependencies and devDependencies -- it needs to be NOT in devDependencies to prevent `npm ci --omit=dev` from purging it.
2024-10-10 12:02:06 -04:00
FoxxMD 4b8129fd19 fix: missing schema package in regular deps and freeze ts version 2024-10-10 11:36:23 -04:00
FoxxMD f610f385bd test: Try timeout in test instead of before() 2024-10-09 16:15:21 -04:00
FoxxMD 6994635fe4 test: Try another timeout and destroy scheduler 2024-10-09 16:13:15 -04:00
FoxxMD 61525e1351 test: Add long timeout to first config parse due to slow schema generation
Not a problem on my machine but causing timeout on github actions
2024-10-09 15:55:06 -04:00
FoxxMD a50070e133 ci: Add ACT run for just backend test 2024-10-09 15:51:58 -04:00
Matt Foxx db632424b1 Merge pull request #202 from FoxxMD/validateGranular
feat: Improve client/source schema validation generation and error handling
2024-10-09 12:52:47 -04:00
FoxxMD 6b92920f50 fix: Use silent logger for source config tests 2024-10-09 12:20:10 -04:00
FoxxMD a30d362695 fix: Fix error logging line numbers
Don't use ts-node for json-schema
2024-10-09 12:18:23 -04:00
FoxxMD d105e62f18 feat: Refactor validation errors to emit an event instead of throwing
* Prevents app from crashing due to only one thing going wrong
* Will be used for testing error handling in the future
2024-10-09 12:18:23 -04:00
FoxxMD d5ad796339 fix: Fix example configs so they pass validation tests
* Add missing sources to dual configs
* Fix slug type for webscrobbler example
2024-10-09 12:18:23 -04:00
FoxxMD c0aabefc72 test: Add tests for example configs and test parsing/validation
* Add suite for testing client/source parsing and validation
* Additionally, use example configs for two-birds-one-stone checking they are valid
* Refactor sources init as separate step from component building
2024-10-09 12:18:23 -04:00
FoxxMD 259d321f3d chore: Remove tests folder from tsconfig exclude to get autocomplete 2024-10-09 12:18:23 -04:00
FoxxMD d2375d92e6 test: Force mocha to exit 2024-10-09 12:18:23 -04:00
FoxxMD f8a63c5df1 fix: Add missing glob package 2024-10-09 12:18:23 -04:00
FoxxMD 5004d99473 chore: Add tmp testing folders to ignore files 2024-10-09 12:18:23 -04:00
FoxxMD 5b26cc73e8 feat: Improve client/source schema validation generation and error handling
* Use runtime-generated schemas
  * Ensures validated schemas always match code
  * Can use schemas for individual source/clients without having to generate files
* catch invididual validation errors and log instead of crashing
* refactor validation error output into chained error instead of as individual log statements to improve clarity
2024-10-09 12:18:23 -04:00
FoxxMD 72a4c4542b fix: Fix some source schemas to reflect documentation WRT optional properties 2024-10-09 12:18:23 -04:00
Matt Foxx fdaeb8f6b8 Merge pull request #201 from FoxxMD/GH-199/ytschema
fix(ytmusic): Allow authUser to be number or string
2024-10-09 08:28:25 -04:00
FoxxMD f2f550dae7 Update devcontainer usage with docusarus and docs 2024-10-08 19:53:50 +00:00
FoxxMD 6780d72296 Improve testing, linting, and node usage in devcontainer
* Swtch to devcontainer for node 18.x and remove terminal/launch settings for version (removes nvm dependency in container)
* Update eslint config to use proper config for include/ignore files
* Add spec for mocha and mocha test runner extension + settings
2024-10-08 19:33:47 +00:00
FoxxMD f1784f3c21 fix(ytmusic): Allow authUser to be number or string
Fixes #199
2024-10-07 10:38:55 -04:00
FoxxMD 22d17ba621 docs: Fix link typo for flatpak 2024-10-03 09:18:26 -04:00
FoxxMD 4b4cc1c438 docs: Update/fix docker-compose usage
* Remove bad direct links to non-docsite docker-compose and replace with inline file
* Fix quotes around base url ENV
* Simplify config volume mapping
2024-10-03 09:11:56 -04:00
FoxxMD 7aac664916 docs: Update jellyfin instructions in quickstart to use API Source 2024-10-03 08:55:36 -04:00
FoxxMD 12c4a014f2 fix(jellyfin): Fix tests not exiting 2024-09-30 13:43:15 -04:00
FoxxMD 1eada12714 fix(jellyfin): Fix naming in documentation for allow/disallow options
* Fix documentation and jellyfin example to match code
* Add tests for jellyfin api config parsing and valid activities
* Fix jellyin api ENV naming to match code
* Fix config parsing missing lowercase transform

Fixes #196
2024-09-30 11:07:43 -04:00
FoxxMD 5adb831136 Add multi-runner WIP tests to ACT
Would like to move to this to improve build time on GH Actions but its not working yet. Will also be good when GH Runners release arm nodes publicly.
2024-09-27 16:30:02 -04:00
FoxxMD 5b8a8a7449 ci: Refactor ACT for more thorough usage
* All required files in the same file by using .actrc
* Include example .secrets and .env
* Update README with usage
* Refactor actTest to make docker build steps optional with ENV
2024-09-27 11:41:38 -04:00
FoxxMD 005dae76ab chore: Bump version for release 2024-09-27 09:02:04 -04:00
FoxxMD cb2c7276dd docs: Add scrobble modification logging docs 2024-09-24 11:45:50 -04:00
FoxxMD 54fe61c51c docs: Add when condition docs and examples 2024-09-24 11:43:56 -04:00
FoxxMD bdf27ec421 fix: Freeze typescript to fix weird unused error directive problem 2024-09-23 09:49:31 -04:00
FoxxMD 3addd39fc5 chore(vscode): Add default built task 2024-09-23 09:49:10 -04:00
FoxxMD 19bf456e47 Fix version for yt-music-api 2024-09-23 08:39:46 -04:00
Matt Foxx 66bf889e9f Merge pull request #186 from FoxxMD/GH-185/condition
feat(modifications): Implement "when" conditions
2024-09-23 08:34:53 -04:00
FoxxMD 09ea158734 Update lock file after rebase 2024-09-23 08:34:09 -04:00
FoxxMD 88c1b553e3 feat(modifications): Refactor hooks to accept an array of parts
* Hook can be single object part or array of parts
* All arrays are processed

#185
2024-09-23 08:32:40 -04:00
FoxxMD 1d1fd1b54d feat(modifications): Implement "when" conditions for scrobble modifications
Enable using multiple "when" conditions of regex matching to determine if a hook or individual part-rules should run

#185
2024-09-23 08:32:37 -04:00
FoxxMD 9d3267b1fc Add dockerignore entries for vscode 2024-09-23 08:29:47 -04:00
FoxxMD 22a04adde0 docker: Update dockerfile to ignore devcontainer and vscode settings 2024-09-20 12:33:23 -04:00
FoxxMD 1dba90ceb5 docs: Update development docs for VSCode usage 2024-09-20 12:31:34 -04:00
FoxxMD 4e9794d574 feat: Add VSCode devcontainer 2024-09-20 12:17:37 -04:00
FoxxMD 23a747d3a9 feat: Add VSCode native dev settings
* Add settings.json to ensure terminal runs with correct node version
* Add launch settings for debugging individual files, whole app, and mocha tests
2024-09-20 11:57:37 -04:00
FoxxMD 4678c35453 Merge remote-tracking branch 'origin/master' 2024-09-19 12:56:03 -04:00
FoxxMD c153e53c5b feat: Improve upstream scrobble refresh logic and caching controls
* Add refreshMinInterval to prevent hammering upstream services
* Refactor refresh logic to be simpler and account for backlogged tracks
* (test): Improve play generation utils for testing
* (test): Refactor testing for upstream scrobble refreshing to use more actual scrobbler class behavior
2024-09-19 12:55:50 -04:00
FoxxMD e20ee09bbb chore: Update faker to official release 2024-09-19 12:53:00 -04:00
Matt Foxx 619687472d Merge pull request #192 from FoxxMD/GH-191/plex-formdata-fix
fix(plex): Refactor plex webhook formdata parsing to be more defensive
2024-09-17 08:51:18 -04:00
FoxxMD b74f23f6d1 fix: Don't use es module in vite config because of gross esm/cjs reasons 2024-09-13 17:07:32 -04:00
FoxxMD d073b4c402 fix: Strip wrapping quotes from base url
Compensates for scenarios where a user accidentally encloses value in quotes when it shouldn't be

fixes #187
2024-09-13 16:51:02 -04:00
FoxxMD 258883d88b test: Add missing version prop for test components 2024-09-13 16:49:37 -04:00
FoxxMD 29c8d6236a fix(plex): Refactor plex webhook formdata parsing to be more defensive
* Move file parsing to own function
* Add some typings to file parsing to help with development (typings are bad)
* Defensively check structure of formdata for nested arrays since Plex seems to waffle on how it sends data (fixes #191)
* Add logging for all files found to help with future end-user debugging
2024-09-13 13:54:50 -04:00
FoxxMD a1443594f7 docs: Fix youtube music identifier
Closes #190
2024-09-12 08:46:49 -04:00
Matt Foxx ac2e9570e5 Merge pull request #189 from jackwilsdon/fix-docs-link
docs: fix link
2024-09-11 15:00:04 -04:00
FoxxMD 983b1c67ac fix: Bump @foxxmd/logging version to fix read-only system issues 2024-09-11 14:48:27 -04:00
Jack Wilsdon 764493f5c9 docs: fix link 2024-09-11 19:35:39 +01:00
Matt Foxx d7981e7cc0 Merge pull request #188 from jackwilsdon/fix-local-docs
fix: local documentation
2024-09-11 08:33:03 -04:00
Jack Wilsdon 11fbe97325 fix: local documentation
express-static prefers directories over files when using the extensions
option, meaning an extensionless route will always route to the
directory instead of the file (expressjs/serve-static#138).
2024-09-10 21:09:09 +01:00
Matt Foxx 3f37a63439 Merge pull request #182 from FoxxMD/dependabot/npm_and_yarn/npm_and_yarn-cccb3c3a64
chore(deps): bump the npm_and_yarn group across 2 directories with 7 updates
2024-08-30 11:03:09 -04:00
dependabot[bot] ee78b95617 chore(deps): bump the npm_and_yarn group across 2 directories with 7 updates
Bumps the npm_and_yarn group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [formidable](https://github.com/node-formidable/formidable) | `2.1.2` | `3.5.1` |
| [@types/formidable](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/formidable) | `2.0.6` | `3.4.5` |
| [ntfy](https://github.com/ffflorian/node-packages) | `1.5.4` | `1.6.2` |
| [postcss](https://github.com/postcss/postcss) | `8.4.38` | `8.4.41` |
| [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) | `0.5.0` | `0.6.0` |
| [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) | `7.24.7` | `7.25.6` |

Bumps the npm_and_yarn group with 2 updates in the /docsite directory: [postcss](https://github.com/postcss/postcss) and [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse).


Updates `formidable` from 2.1.2 to 3.5.1
- [Release notes](https://github.com/node-formidable/formidable/releases)
- [Changelog](https://github.com/node-formidable/formidable/blob/master/CHANGELOG.md)
- [Commits](https://github.com/node-formidable/formidable/commits/v3.5.1)

Updates `@types/formidable` from 2.0.6 to 3.4.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/formidable)

Updates `ntfy` from 1.5.4 to 1.6.2
- [Commits](https://github.com/ffflorian/node-packages/compare/ntfy@1.5.4...ntfy@1.6.2)

Updates `postcss` from 8.4.38 to 8.4.41
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.38...8.4.41)

Updates `xml2js` from 0.5.0 to 0.6.0
- [Commits](https://github.com/Leonidas-from-XIV/node-xml2js/compare/0.5.0...0.6.0)

Updates `@babel/traverse` from 7.24.7 to 7.25.6
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.6/packages/babel-traverse)

Updates `axios` from 1.7.2 to 1.7.4
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.2...v1.7.4)

Updates `postcss` from 8.4.39 to 8.4.41
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.38...8.4.41)

Updates `@babel/traverse` from 7.24.7 to 7.25.6
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.6/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: formidable
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: "@types/formidable"
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: ntfy
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: postcss
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: xml2js
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: "@babel/traverse"
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: axios
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: postcss
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: "@babel/traverse"
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-30 14:55:40 +00:00
FoxxMD d7091f8a8e chore(ci): Add dependabot PR test gh action 2024-08-30 10:53:09 -04:00
FoxxMD 4b5cdade77 chore(ci): Disable alpine builds for PR image 2024-08-30 10:37:21 -04:00
FoxxMD cb67d1ae40 chore!: Fix latest/tag for images and disable alpine builds
* Ensure pre-release tags don't also get latest tag
* Disable alpine builds
  * Only increases testing and build complexity and there has been no feedback from users about needing it
2024-08-30 10:26:23 -04:00
FoxxMD 676af4a2bf Merge branch 'develop' 2024-08-30 09:54:24 -04:00
FoxxMD 0feb02babe chore: Refactor git/dev workflow to use master as unstable branch
* Aligns with "normal" default branch usage better, allows dependabot to actually run
* Change image publishing to push tagged images as 'latest' and master images as `edge`
2024-08-30 09:53:52 -04:00
FoxxMD 90c481b12b Merge remote-tracking branch 'origin/develop' into develop 2024-08-30 09:23:02 -04:00
FoxxMD 59fed488ba feat(jellyfin): Update schema 2024-08-30 09:22:52 -04:00
Matt Foxx 8431e7b6b2 Merge pull request #172 from FoxxMD/jellyfinApi
feat: Refactor Jellyfin source to use Jellyfin API
2024-08-30 09:13:56 -04:00
FoxxMD be30cdd540 feat(jellyfin): Implement partial WS client for future use 2024-08-29 15:16:49 -04:00
FoxxMD 54927ed77c fix(jellyfin): Map AlbumArtist Name property 2024-08-29 11:30:59 -04:00
FoxxMD 97f974d931 update vlc source building after rebase 2024-08-29 11:29:41 -04:00
FoxxMD 0de2cc0922 feat(jellyfin)!: Refactor Jellyfin source to use Jellyfin API
* Implement new jellyfin source using JF typescript api client library for communication
  * Use either API Key or username/password
* Implement real-time scrobble monitoring
* Implement feature parity filters from old jellyfin source (users) and add devices filters
* Refactor documentation for new configuration with api and add migration steps for webhook users
* Add deprecation warning to jellyfin webhook source
2024-08-29 11:28:27 -04:00
FoxxMD e80ad81f05 Merge branch 'develop' 2024-08-28 09:35:28 -04:00
FoxxMD a3960421d7 chore: Bump version for release 2024-08-28 09:35:13 -04:00
FoxxMD 2f2eeeb13a docs(youtube): Add FAQ entries for YTM auth and scrobble issues 2024-08-28 09:32:46 -04:00
Matt Foxx eeb026abf0 Merge pull request #163 from FoxxMD/ytMusicDebug
Improve YTM experience
2024-08-28 09:11:38 -04:00
FoxxMD 0fed96f59c Merge branch 'develop' 2024-08-28 09:07:12 -04:00
Matt Foxx 8369939135 Merge pull request #181 from FoxxMD/malojaDuplicateHandling
fix(maloja): Improve handling for Maloja warnings-as-errors
2024-08-27 16:54:11 -04:00
FoxxMD 08056a650f fix: Actually store recent scrobbles
Refresh scrobbles refactor missed actually storing scrobbles on refresh
2024-08-27 09:40:30 -04:00
FoxxMD 5b53b7490c fix(maloja): Improve handling for Maloja warnings-as-errors
* Fixes incorrect handling for duplicate scrobble error from Maloja 3.2.2 #180
* More defensive Maloja scrobble parsing
2024-08-26 11:09:49 -04:00
Matt Foxx ce95c3ae8c Merge pull request #179 from FoxxMD/vlc
Implement VLC as Source
2024-08-26 10:55:01 -04:00
FoxxMD 5e0c4e3e77 docs(vlc): Some fixes for VLC docs
tags <> in code block in details causes parsing error
2024-08-23 09:00:14 -04:00
FoxxMD 10bf48df40 docs(vlc): Add VLC docs 2024-08-22 17:30:37 -04:00
FoxxMD ae935798f3 chore: Update schema 2024-08-22 16:44:15 -04:00
FoxxMD bf71f8cf86 feat(vlc): Use regex from configuration to extract metadata from filenames 2024-08-22 16:44:08 -04:00
FoxxMD 4206696f0d feat(vlc): Better metadata parsing 2024-08-22 15:07:47 -04:00
FoxxMD 2903662f8b feat: Implement POC vlc Source #177 2024-08-22 13:11:12 -04:00
FoxxMD 469847e4b7 feat(youtube): Use just-validated history as recently played on new plays #156
Rather than generating our own just use the known "good" history we just compared against to see if this improves consistency.
2024-08-21 13:14:38 -04:00
FoxxMD d7a86b0401 feat(youtube): Increase level of auth update logging when configured to output changes #158
Increasing to INFO makes the signal better for long-running MS processes instead of requiring logging all of DEBUG
2024-08-21 13:14:38 -04:00
FoxxMD 4fdd346c00 Merge branch 'refs/heads/develop' 2024-08-20 09:18:01 -04:00
FoxxMD 4f26b63ab1 chore: Bump version for release 2024-08-20 09:17:28 -04:00
FoxxMD 0fed91302c chore(ci): Update untagged package schedule to run once a week
Doesn't need to run every day.
2024-08-19 11:55:47 -04:00
FoxxMD 831cefd9a7 docs(deezer): Deprecate due to discontinued API support
Deprecate Source with warning message and update docs. #175
2024-08-19 11:25:11 -04:00
FoxxMD 114a3dda8b feat(ui): Add timestamp to recent pages #167 2024-07-26 10:07:25 -04:00
FoxxMD 55ddd2c5a0 docs: Mention data modification in readme 2024-07-26 09:38:18 -04:00
FoxxMD 1d276186f8 feat: Implement removing field if field is an empty string after transforming 2024-07-26 09:30:58 -04:00
FoxxMD fb3886b981 docs: Modification improvements 2024-07-26 09:19:11 -04:00
FoxxMD 2bed7be654 docs: Fix compare example 2024-07-25 17:47:57 -04:00
FoxxMD 5c460ad747 docs: Add Play Transform docs 2024-07-25 17:28:49 -04:00
FoxxMD 32220d7509 feat: Implement play transforms in source/client logic 2024-07-25 16:16:58 -04:00
FoxxMD b0265001f8 feat: Improve logging for play transforms
* Use a proper child logger and error messages on catch
* Log full play string before => after instead of just parts
2024-07-25 15:12:39 -04:00
FoxxMD 9ede4634cb test: Use faker 9.0RC for more plausible artist/album names in generated data 2024-07-25 15:04:37 -04:00
FoxxMD 0e008ecd5c feat: Add album option to play string building function 2024-07-25 15:03:39 -04:00
FoxxMD 2ae82fdd9e feat: Implement common play transform functionality 2024-07-25 13:43:34 -04:00
Matt Foxx 3b430b95ed Merge pull request #174 from FoxxMD/issue-173-scrobbler-improvement
Enable more agressive scrobble checking behavior
2024-07-25 09:18:07 -04:00
FoxxMD e907892c4a refactor(scrobbler): Change refresh force to user-configurable staleness time
Use refreshStaleAfter to force refresh to user can configure the time.

Allows more nuanced refreshing behavior as well as always refresh (0 seconds)
2024-07-24 12:06:20 -04:00
FoxxMD d9cd3764b9 refactor(scrobbler): Consolidate refresh logic and add more logging
* Move recentScrobbles and generic refresh logic into abstract class
* New abstract function for scrobbler children to implement to get scrobbler-specific play lists on refresh
* Implement shouldRefereshScrobble with logging for better insight into why or why not a scrobbler refreshed upstream scrobbles
2024-07-24 11:20:09 -04:00
FoxxMD 9c2bf05a24 refactor(listenbrainz): Simplify scrobble api calls and logging 2024-07-24 10:31:37 -04:00
FoxxMD 91e52c4c5d feat(musikcube): Provide more error logging and example config
* Update iso-websockets to fix typing exports and get node network error from WS error
* Add url example to config
2024-07-23 12:11:19 -04:00
FoxxMD b41d7f539f feat(scrobble): Enable forcing existing scrobbles refresh on every scrobble #173 2024-07-23 10:48:35 -04:00
FoxxMD 9735b980d7 fix(tests): Do not re-use scrobbler between tests 2024-07-19 14:44:39 -04:00
FoxxMD 706483ed06 feat: On polling error retry check source is initialized and reinitialize if not 2024-07-19 14:36:50 -04:00
FoxxMD 7760776a5f feat(mpd): Use idle event to wake up from polling early 2024-07-19 14:36:27 -04:00
FoxxMD 8b9a7893d3 feat(mpd): Implement MPD Source MVP 2024-07-19 12:10:51 -04:00
FoxxMD 729250a2cc Merge branch 'refs/heads/develop' 2024-07-18 14:18:39 -04:00
FoxxMD f14203f85e docs: More improvements to configuration docs 2024-07-18 11:14:40 -04:00
FoxxMD 60e880f7f2 Merge branch 'refs/heads/develop'
# Conflicts:
#	docsite/docs/configuration/configuration.md
2024-07-17 12:47:23 -04:00
FoxxMD 16cef0ae65 chore: Bump versions for release 2024-07-17 12:46:18 -04:00
FoxxMD 12ff1f421e docs: Use relative paths for volume mounting 2024-07-17 11:46:00 -04:00
FoxxMD 61c33da2b0 docs: Fix quickstart link 2024-07-17 11:39:41 -04:00
FoxxMD 8b0c7205b7 docs: Add quick start guide 2024-07-17 11:33:56 -04:00
FoxxMD b02c96ada8 docs: Parse and render config examples from repository 2024-07-17 09:51:44 -04:00
FoxxMD 52b20e4c8e docs: Update kitchensink code block titles 2024-07-16 15:37:09 -04:00
FoxxMD a94ac8284f docs: refactor installation for docusaurus 2024-07-16 15:28:09 -04:00
FoxxMD ee399136a9 docs: Lean 100% into docusaurus documentation
Since docs are now generated alongside builds and hosted on the app server there is no longer a barrier to using docusaurus docs as the main documentation presentation. Any user looking for docs can use the GH Pages hosted site or a "versioned" docs site hosted on their MS app. Due to this we can fully commit to docusaurus and take advantage of MDX layouts to simplify docs.

* Replace env/file configs headings in configuration with MDX tabs to make reading easier
* Remove superfluous TOCs
* Replace internal links in repo readme with links to docsite
2024-07-16 14:11:14 -04:00
FoxxMD ab54422acf docs: Replace manual notes with admonitions 2024-07-16 11:58:09 -04:00
FoxxMD d56c5720eb docs(flatpak): Fix typo in docs website link 2024-07-16 11:46:13 -04:00
FoxxMD 040de4b000 docs(flatpak): Implement bash setup script and move flatpak instructions to docsite
* setup.sh takes care of building generated sources for project/docsite and building flatpak app
* Modify flatpak manifest to include two generated sources files and build docsite files
* Update flatpak docs with script usage and generated sources changes, move to docusauraus doc site
2024-07-16 11:34:15 -04:00
FoxxMD 815a774e3d docs(fix): Fix broken links/anchors 2024-07-15 14:24:00 -04:00
FoxxMD b2e7f58e14 docs(fix): Add missing docsite build steps to alpine docker variant 2024-07-15 13:50:37 -04:00
FoxxMD 8d124a20ac docs(fix): Update package scripts to use npx to invoke docusarus 2024-07-15 13:44:07 -04:00
FoxxMD d1a4a54d2a docs: Implement self-hosted docs
* Add npm scripts for installing/building docusaurus from main project
* Set base url based on ENV
* Build docsite in docker image
* Add link to doc in dashboard and link to github
* Update nodejs install instructions to include doc build command
* Update GH pages workflow to use correct base url
* Add hint page to main app when docs are not built
2024-07-15 13:26:57 -04:00
FoxxMD 049bb06762 docs: Make docs site more prominent in readme 2024-07-12 16:55:48 -04:00
FoxxMD e5dd473981 Merge branch 'refs/heads/develop' 2024-07-12 14:39:53 -04:00
FoxxMD ca5cc3bb30 docs(feat): Add TOC to dev docs and links in readme 2024-07-12 14:37:52 -04:00
FoxxMD 444d75c803 docs(feat): Add architecture overview, common dev structures, and dev guidance for Sources 2024-07-12 14:31:11 -04:00
FoxxMD ccda3a6098 Merge branch 'refs/heads/develop' 2024-07-09 16:06:05 -04:00
FoxxMD ce1c70a4e1 ci: Ignore flatpak and docsite for image deploy 2024-07-09 16:05:15 -04:00
FoxxMD 5fcfa979c5 docs: Improve TOC for docusaurus and github
* Use lower headers so docusaurs sidebar TOC is more accurate
* Specify header levels for config/FAQ to make sidebar more concise
* Wrap inline TOC in details block -- so docusaurs users don't have to see it twice but its still available to github viewers
2024-07-09 15:56:44 -04:00
FoxxMD ec4d609ba1 docs: Update docusaurs playground schema for MS to latest 2024-07-09 15:55:07 -04:00
FoxxMD b42278a372 docs: Update docusaurus to v3 2024-07-09 15:54:45 -04:00
FoxxMD 1f96035ba9 Merge branch 'refs/heads/develop' 2024-07-09 10:25:29 -04:00
FoxxMD 332edb5dca chore: Bump flatpak release history 2024-07-09 10:25:17 -04:00
FoxxMD c5681d31eb Merge branch 'refs/heads/develop' 2024-07-09 09:53:03 -04:00
FoxxMD 685d70c639 chore: Bump version for release 2024-07-09 09:51:43 -04:00
FoxxMD 848878bc5e docs: Update screenshot 2024-07-09 09:51:33 -04:00
FoxxMD 088d063d38 fix: use correct ordering for version priority 2024-07-05 11:26:23 -04:00
FoxxMD 4e493db987 refactor: Use @foxxmd/get-version to render app version 2024-07-05 10:42:41 -04:00
FoxxMD 6d017d4b27 chore(ci): Update setup-node to v4 to squash node deprecation warnings 2024-07-03 10:11:52 -04:00
FoxxMD a34066d650 fix(docker): Typo in Dockerfile name 2024-07-03 10:09:24 -04:00
FoxxMD 0e34d63c84 feat(docker)!: Use debian image as default
Sporadic DNS issues with alpine have caused a number of issues #160 #126 #134

Use debian as default since it has been proven to be stable. The image size increase is worth squashing these issues.
2024-07-03 10:07:35 -04:00
FoxxMD 9dca8ebfa0 fix(chromecast): Add missing avahi-utils package for debian image 2024-07-03 09:55:58 -04:00
FoxxMD c908aea1ae ci: Better package cleanup and manual triggers 2024-06-26 16:39:42 -04:00
FoxxMD c7a58bbce6 ci: Add package cleanup 2024-06-26 16:26:30 -04:00
FoxxMD b26f303479 ci: remove test workflow 2024-06-26 15:52:52 -04:00
FoxxMD 13d64d2ce2 ci: Implement gated automated PR building
Only checkout/build PR branches if labelled first
2024-06-26 15:44:12 -04:00
FoxxMD ddb7fb3d6e ci: Use checked out repo to get git info rather than GH variables 2024-06-26 14:05:33 -04:00
FoxxMD 457967bfb2 Pass default APP_VERSION env as build arg 2024-06-26 13:23:45 -04:00
FoxxMD 734742ecbe Add APP_VERSION parsing to github actions 2024-06-26 12:37:09 -04:00
FoxxMD 26dab3870a Simplify version info on frontend by using api endpoint 2024-06-26 12:37:08 -04:00
FoxxMD ca9acbb089 Add git versioning check on backend 2024-06-26 12:37:08 -04:00
FoxxMD f78d6fec1d fix(youtube): Catch auth issues that occur during polling #158 2024-06-26 12:37:08 -04:00
FoxxMD bafb852545 feat(youtube): Use full-fat list diffing to watch for new plays #156
* Use superdiff to diff PlayObject lists and detect changes as well as append/prepend scenarios
* Replace YTM recently played logic with list diffing, only accept prepend-validated lists
  * On non-prepend scenarios replace existing recently played and log human readable diff
2024-06-26 12:37:08 -04:00
FoxxMD a755db45b9 fix: Fix ntfy imports 2024-06-26 12:37:08 -04:00
FoxxMD b9715f2159 chore: update dependencies 2024-06-26 12:37:07 -04:00
FoxxMD e90dbaf691 chore: npm audit fixes 2024-06-26 12:37:07 -04:00
FoxxMD 08ac55f718 fix(webscrobbler): Fix formatting of slug url in logs 2024-06-26 12:37:07 -04:00
FoxxMD 5bf831e236 feat(youtube): Sync cookies with those returned from YTM responses #158
* Patch youtube-music-ts-api to use updated cookies from response and provide a callback on update
* Implement currentCreds/build init data and read from MS-updated creds if available
* Write to currentCreds when ytm-ts-api invokes auth update callback and optionally log what parts changed based on config options
2024-06-26 12:37:07 -04:00
FoxxMD 1905804f2a fix(webscrobbler): Add preflight route #157 2024-06-26 12:37:07 -04:00
FoxxMD afc931ac8c docs: Use vars instead of secrets 2024-06-26 12:37:07 -04:00
FoxxMD 9fb032e030 docs: Add scripting on deploy for plausible analytics 2024-06-26 12:37:07 -04:00
FoxxMD 09b0c96263 feat(youtube): Surface library history playlist and raw recently played for debugging #156 2024-06-26 12:37:06 -04:00
FoxxMD 7c66816023 Implement musikcube source 2024-06-26 12:35:13 -04:00
FoxxMD 3e7e5df5de fix: Missed package-lock.json commit 2024-06-05 11:01:12 -04:00
FoxxMD 1c84a74034 fix(vite): Use default base string if no other path detected
* Update Vite dep
* Use inlineViteConfig for vite-express middleware and detect correct base string
* Refactor vite.config.ts to detect correct base string
2024-06-05 10:58:52 -04:00
FoxxMD 09969dd9d7 fix(spotify): Convert URL to string for redirectUri 2024-06-05 10:21:18 -04:00
FoxxMD 63b57e1113 docs: Clarify BASE_URL usage and add more examples #155 2024-06-04 15:51:30 -04:00
FoxxMD 585677e515 fix: Refactor Base URL normalization to cover more cases #155
* Move code into testable function
* Fix port erasure when url uses standard port but it is explicitly specified
* Simplify building default url and fix using undefined mainPort variable
* Fix port erasure when https protocol is explicitly specified
* Refactor localUrl usage as URL instead of string
  * Implement pathname joining on URL to make handling trailing/leading slashes take place in nodejs lib
* Implements tests for URL building/manipulation
2024-06-04 15:44:28 -04:00
FoxxMD 57f2b5f7e5 feat: Update normalize-url to prevent port erasure #155 2024-06-04 15:39:47 -04:00
FoxxMD 3597735556 feat(client): Implement initial refresh count and config control #153
* Refresh recent scrobbles with a higher limit after initialization (maximum supported by api call)
* Implement controlling count in client config
2024-05-16 15:22:24 -04:00
FoxxMD 2442cf2286 refactor: Move all init logic into common abstract base class 2024-05-16 15:01:07 -04:00
FoxxMD 97438e13d2 refactor(client): Use same init logic as source 2024-05-16 14:50:26 -04:00
FoxxMD 57dff9d122 feat!(source): Increase backlog limit defaults and add config control #153
* Increase default backlog limits to maximum pagination supported by each source
* Add scrobbleBacklogCount config property so user can explicitly set # of tracks to backlog
2024-05-16 13:43:44 -04:00
FoxxMD 963fc792a0 fix: Fix clientDefaults interface 2024-05-10 12:53:04 -04:00
FoxxMD 35a6418f38 docs!: Update schema 2024-05-10 12:48:08 -04:00
FoxxMD 3c0b951132 refactor(config)!: Move common options out of client config and into new option property 2024-05-10 12:44:16 -04:00
FoxxMD 3dc9e7d8b4 refactor(config)!: Move remaining common options out of source data and into options
* Move logPayload and logFilterFailure to options
* Disallow use of "options" property in common data
2024-05-10 12:38:09 -04:00
FoxxMD ab372b8357 refactor(config)!: Move source retry config to options 2024-05-10 12:07:39 -04:00
FoxxMD c79f04581f refactor(config)!: Move scrobble thresholds to options 2024-05-10 12:01:45 -04:00
FoxxMD 0dcd049453 Merge branch 'refs/heads/develop' 2024-04-11 09:39:08 -04:00
FoxxMD 7170b09586 chore: Bump version for release 2024-04-11 09:38:55 -04:00
FoxxMD 3d893b126f refactor(logging): Balance debug/verbose level logging pt.1
* Move some debug => verbose for non-repeating logs that are relevant to state, notifications, and scrobbling
* Move some verbose => debug that were repeating and making verbose level noisy
2024-04-10 11:25:27 -04:00
FoxxMD fb73b8b106 feat(mpris): Less noisy error handling
* Convert DBus non-standard thrown error data to regular Errors
* Only warn about position errors if error message is unexpected
2024-04-10 10:57:02 -04:00
FoxxMD cede77e3fa refactor: Remove pony-cause dependency
Use built-in error cause and adapt helper functions from pony-cause so we can remove a dependency
2024-04-10 10:56:04 -04:00
FoxxMD 0572d6a308 refactor(logging): Reduce noise for polling interval logging 2024-04-10 10:19:58 -04:00
FoxxMD 5967e3df46 feat: Implement notifications via Apprise 2024-04-05 12:07:41 -04:00
FoxxMD 6b1ee83654 docs: Add config section and config example for disabling web server #150 2024-04-04 09:35:27 -04:00
FoxxMD 0af1496a0f chore: Update proxies 2024-04-04 09:30:42 -04:00
FoxxMD 52b08efd88 feat: Implement option for disabling web server #150
If a user does not need the dashboard or has security concerns about ingress and cannot control their hosting environment this enables reducing attack surface.

Closes #150
2024-04-04 09:30:33 -04:00
FoxxMD 7a3e4e56e2 chore: Remove some unused packages 2024-04-02 10:15:41 -04:00
FoxxMD abe6638f66 refactor: Use updated logger to reduce log file path logic complexity 2024-03-28 12:28:56 -04:00
FoxxMD eb62c2cea9 refactor: optimize imports
* Remove unused imports
* Normalize spaces in curly braces
* Sort by module (npm packages, then relative imports)
2024-03-28 09:20:46 -04:00
FoxxMD 7e6eddce3e refactor: Reduce usage of ErrorWithCause
Error Cause (https://github.com/tc39/proposal-error-cause) was finalized and introduced in ES2022 so we don't need to ponyfill this anymore. Still using the helpful helper functions thought.
2024-03-28 09:20:45 -04:00
FoxxMD bc517e0cb0 Merge branch 'develop' 2024-03-26 09:37:03 -04:00
FoxxMD 41900b0048 chore: Bump version for release 2024-03-26 09:36:37 -04:00
FoxxMD 9ea71b931c fix(flatpak): Fix missing package.json needed to run as esm module 2024-03-26 09:04:31 -04:00
FoxxMD 64f222b5b7 fix: Add binary alias(?) to pass appstream guidelines
flathub/io.github.foxxmd.multiscrobbler#14
2024-03-25 09:49:01 -04:00
FoxxMD 6c27406803 fix: Fix colored output being applied to file logging 2024-03-21 17:08:14 -04:00
FoxxMD 2f51e7ad99 feat: Enable colorizing docker log output 2024-03-21 16:29:33 -04:00
FoxxMD d86dd63236 fix: Fix log name to match existing logs names 2024-03-21 15:50:43 -04:00
FoxxMD f794133915 fix: Fix missing parent logger 2024-03-21 15:33:06 -04:00
FoxxMD c7d2e7acc2 feat(ui): Use ansi-to-react for log coloring
Vastly simplifies log formatting on the dashboard
2024-03-21 15:33:06 -04:00
FoxxMD 2dde3840c6 refactor(logging): Replace winston with @foxxmd/logging 2024-03-21 15:33:06 -04:00
FoxxMD 4675847fec fix(flatpak): Reduce summary length 2024-03-11 16:14:45 -04:00
FoxxMD 830d1a2243 fix(flatpak): Add missing developer name
https://github.com/flathub/io.github.foxxmd.multiscrobbler/pull/13#issuecomment-1949888692
2024-03-06 10:10:13 -05:00
FoxxMD 8a43f0ded5 test arm64 building for debian docker image using updated node version #126
Using latest LTS (20) seems to have fixed TLS timeout/connection reset issue seen when trying to `npm ci` on LTS 18
2024-02-19 15:32:24 -05:00
FoxxMD af24e0ffbe chore(docker): Remove unused dependencies 2024-02-19 15:09:55 -05:00
FoxxMD d3a70bf2c1 fix: Add comment for future typed linting 2024-02-19 13:24:53 -05:00
FoxxMD a62fe705f9 fix: Fix lint errors 2024-02-19 13:02:28 -05:00
FoxxMD 1c6407238c feat: Add initial linting config 2024-02-19 12:27:34 -05:00
FoxxMD ec897b185c fix: Fix logger used for tests to always be 'noop'
Cleans up logging output during tests
2024-02-19 10:50:10 -05:00
FoxxMD 69e15b3797 fix: Refactor static arrow function class fields to normal functions #143
Something about using arrow function form for static class methods causes node debugger to crash.

Closes #143
2024-02-19 10:38:59 -05:00
FoxxMD dae4af070f chore: Bump mocha version 2024-02-15 13:01:22 -05:00
FoxxMD beaf0f3bfd chore(!): Upgrade Node to LTS for --import support
So that we can use tsx with official --import rather than requiring (old-style) which doesn't work with string-sameness esm for some reason

https://github.com/mochajs/mocha/issues/5002
https://github.com/mochajs/mocha-examples/pull/76
2024-02-15 12:40:02 -05:00
FoxxMD 8057982184 chore: Upgrade string-sameness
* Removes dependency on unmaintained dice coeffecient library
* New version is esm-only library
2024-02-15 12:27:59 -05:00
FoxxMD 9a5a808780 fix: Remove alt single quote when normalizing strings 2024-02-15 12:05:50 -05:00
FoxxMD d2d5f4a705 chore: Remove more unused packages 2024-02-15 10:10:01 -05:00
FoxxMD 4aa875660f chore: Remove unused es6-error package 2024-02-15 09:25:32 -05:00
FoxxMD 5ab8f00aeb Fix microsecond conversion 2024-02-15 09:23:26 -05:00
FoxxMD 1e1b5f56ce refactor: Replace dbus-next with dbus-ts #142 2024-02-14 16:32:38 -05:00
FoxxMD 49b9ee96f3 fix: Fix ts schema generation import issue
Changing tsconfig resolution caused generation to generate new (bad?) import lines. Replacing with regex from https://github.com/YousefED/typescript-json-schema/issues/582 returned ref/definitions to normal
2024-02-14 09:47:00 -05:00
FoxxMD aef7716634 fix(webscrobbler): Fix missing wildcard to match slug route #137
Closes #137
2024-02-14 09:45:14 -05:00
FoxxMD 57f2e1d500 feat: Log more URL when route is unknown 2024-02-14 09:44:47 -05:00
FoxxMD 41c696992a feat: Add legacy fallback options for subsonic communication #136
* Add config options for using legacy authentication and ignoring TLS cert errors
* Fallback to legacy auth if subsonic error code 41 is detected
2024-02-13 15:59:17 -05:00
FoxxMD f231d4e1e4 ci: Implement test checks for PRs and image publishing 2024-02-08 13:07:13 -05:00
FoxxMD 0efbe41b7e test: Use tsx through mocha config 2024-02-08 12:14:11 -05:00
FoxxMD be9675bb10 fix: Handle when no existing scrobble match with score greater than 0 #130
https://github.com/FoxxMD/multi-scrobbler/issues/130#issuecomment-1934452275
2024-02-08 11:51:00 -05:00
FoxxMD 4e45d35925 test: Add test that handles no existing scrobble match with score greater than 0 #130
Detects track string error thrown reported via https://github.com/FoxxMD/multi-scrobbler/issues/130#issuecomment-1934452275
2024-02-08 11:47:58 -05:00
FoxxMD a5e293554c Merge branch 'develop' 2024-02-06 09:28:35 -05:00
FoxxMD c76d4822fe docs: Fix which host debian image is available for 2024-02-06 09:28:22 -05:00
FoxxMD 0f8fd5cc0e chore: Forgot to bump version in lock file 2024-02-06 09:28:02 -05:00
FoxxMD 8b27890254 Merge branch 'develop' 2024-02-05 11:53:18 -05:00
FoxxMD 8747c8375e chore: Bump version 2024-02-05 11:52:47 -05:00
FoxxMD 50f27c110c Merge branch 'develop' 2024-02-05 11:47:40 -05:00
FoxxMD c1f8997c01 feat: Implement remaining recently played endpoints 2024-02-05 11:40:06 -05:00
FoxxMD 12ed767961 ci: Bump action versions to fix node deprecations 2024-02-05 10:47:58 -05:00
FoxxMD 335808217b docs: Add debian docker image network workaround to docs #126 #134 2024-02-05 10:38:15 -05:00
FoxxMD b5bb7024fc docs: Add workarounds for rollup issues and flatpak disclaimer 2024-02-05 10:28:40 -05:00
FoxxMD ac2806dc66 fix(frontend): Fix scss division deprecation warnings 2024-02-05 10:14:11 -05:00
FoxxMD 9d149dab49 Try to use direct node binary distribution #126 2024-02-02 12:55:58 -05:00
FoxxMD 451404c0f9 Disable arm64 debian builds and document issues in dockerfile #126 2024-02-02 11:05:09 -05:00
FoxxMD a3f1f077ce Revert fancy default negation
Doesn't work
2024-02-01 12:18:30 -05:00
FoxxMD dcd13833ae Ignore secrets files 2024-02-01 12:16:03 -05:00
FoxxMD 78b732b75c Update metadata-action version 2024-02-01 11:55:57 -05:00
FoxxMD 3152933937 chore: Add matrix for building debian flavor tag 2024-02-01 11:54:40 -05:00
FoxxMD 6c6126bb27 chore: make container image build tags agnostic to default branch name 2024-02-01 11:48:15 -05:00
FoxxMD ad13b7687d feat: Implement debian-based image #126 2024-02-01 11:39:05 -05:00
FoxxMD 633e366e82 feat: Improved logging for last.fm api network errors #115 2024-01-31 15:52:25 -05:00
FoxxMD 69b1786859 fix: Add patch-package as postinstall script so packages actually get patched 2024-01-31 14:09:31 -05:00
FoxxMD 41839a961a chore: Ignore apple cert extensions 2024-01-31 14:09:06 -05:00
FoxxMD ccb50c64bb fix(lastfm): Patch lfm library to actually implement a request timeout #134 2024-01-31 13:15:20 -05:00
FoxxMD d88ac1b424 feat(source): Start implementing recent from API 2024-01-31 12:36:35 -05:00
FoxxMD c807611e55 fix: Revert debug statement 2024-01-31 11:51:20 -05:00
FoxxMD 155ec1403e feat(sources): Improve Source of Truth usage and presentation to user #134
* Refactor SOT to be a type (may have more in the future)
* Set player stale/orphan interval based on SOT type
* Add note in log when initializing MemorySource which does not use player as SOT
* Add tooltip to UI player when it is not SOT
2024-01-31 11:46:22 -05:00
FoxxMD ecde657c3e feat(lastfm): Implement nowPlaying lfm api call 2024-01-31 10:01:12 -05:00
FoxxMD 6aa8374f25 feat: Add debug logging for user api requests 2024-01-31 09:30:58 -05:00
FoxxMD c2f01473fd fix(scrobbler): Fix erasing non-english characters #121 2024-01-30 14:47:19 -05:00
FoxxMD 41e607c995 refactor(scrobbler): Use simpler method for handling queued scrobbles #130 2024-01-30 13:40:52 -05:00
FoxxMD fee754f15f feat(chrome): Used improved library 2024-01-30 13:24:09 -05:00
FoxxMD d62d18232d chore: Remove some unused packages 2024-01-30 10:30:33 -05:00
FoxxMD a1acab0fed Merge branch 'develop' 2024-01-29 10:35:27 -05:00
FoxxMD d39a7099c7 docs(cast): Add disclaimer about status of source support 2024-01-29 10:34:13 -05:00
FoxxMD 7b2c4f99f3 chore: Bump version for release 2024-01-29 10:33:57 -05:00
FoxxMD b941ff08dc Merge branch 'develop' 2024-01-29 10:25:06 -05:00
FoxxMD 210a74c75f chore: Bump version for release 2024-01-29 10:24:50 -05:00
FoxxMD eafce71cd0 chore(flatpak): Update flatpak release version 2024-01-29 10:24:08 -05:00
FoxxMD d5777b501d chore(flatpak): Update flatpak manifest to work with new app structure 2024-01-29 10:21:44 -05:00
FoxxMD dd60e5eb21 fix(flatpak): Fix missing destination when building locally 2024-01-29 09:49:33 -05:00
FoxxMD c57dbf23e1 chore(maloja): Deprecate support for versions below 3.0.0 2024-01-26 10:31:23 -05:00
FoxxMD cb52adb4de feat: Log when heartbeat tasks start 2024-01-26 10:17:17 -05:00
FoxxMD a75b0fc549 feat(chrome): Reduce device rejection logging noise
Change device rejection log to verbose if we've seen the blacklisted device before
2024-01-26 10:12:20 -05:00
FoxxMD 1a546b72d2 docs(chrome): Add more google cast configuration docs and update TOCs 2024-01-26 09:55:50 -05:00
FoxxMD fd13d268d0 fix(chrome): Typo 2024-01-25 16:47:10 -05:00
FoxxMD 5837fc11a5 fix: Better handling of uncaught exceptions and rejections 2024-01-25 10:54:44 -05:00
FoxxMD efdbbe40e8 fix(chromecast): Remove debugging interval 2024-01-25 09:52:39 -05:00
FoxxMD 5103cf1c12 feat(chromecast): Catch buffering media 2024-01-25 09:50:23 -05:00
FoxxMD e855a3de7d feat(chromecast): Try to connect all discovered interfaces in the event one fails 2024-01-25 09:43:15 -05:00
FoxxMD b90e38d595 fix(chromecast): Fix black/white app name variable assign 2024-01-25 09:15:53 -05:00
FoxxMD 1864f39be0 fix(chromecast): Fix unknown play tracking 2024-01-25 09:11:44 -05:00
FoxxMD 89e80b6f8b fix(chromecast): Debounce avahi discovery 2024-01-24 14:47:15 -05:00
FoxxMD 564295ee64 feat(spotify): Prepare for future spotify lib migration by writing completing credential data
Migrating to @spotify/spotify-web-api-ts-sdk requires that the credentials we provide have valid expires_in/expires data and grant type. Make this migration easier by writing that data now so users upgrading later most likely do not need to re-authenticate.
2024-01-23 15:10:33 -05:00
FoxxMD 61c7f26007 fix: Fix where retries are checked 2024-01-23 11:37:51 -05:00
FoxxMD 54b9ece5b6 fix: Fix when to check connection
Since all sources can now control if they need to check connection or not do not restrict to just those that can poll
2024-01-23 11:27:54 -05:00
FoxxMD 335136561a fix(chromecast): Better handling of client offline events
* Actually remove device if it fails after X retries
* Properly close controllers/platform/client to prevent uncaught errors from castv2
* Move manually configured devices to device discovery function so they can be reconnected on heartbeat (if previously removed)
2024-01-23 10:45:12 -05:00
FoxxMD 56f1cacd07 fix: Fix return values for source init startup 2024-01-23 09:41:40 -05:00
FoxxMD 558e358d0b fix: Fix default import usage 2024-01-22 13:25:31 -05:00
FoxxMD 290e6eecc4 fix: Fix import missing extension 2024-01-22 13:25:17 -05:00
FoxxMD f512f55782 feat(deezer): Fix credentials check during build data stage 2024-01-22 13:21:00 -05:00
FoxxMD ad6eba58d2 feat: improve data init stage log wording 2024-01-22 13:13:29 -05:00
FoxxMD b675aee8ff fix: Fix status text based on initialization OK values 2024-01-22 13:10:12 -05:00
FoxxMD c29ea9c89c fix: Fix status indicator color based on status text 2024-01-22 13:09:43 -05:00
FoxxMD 50016a31a8 fix: Fix isReady logic 2024-01-22 13:09:32 -05:00
FoxxMD 1cecffc30f feat(subsonic): Improve error/response parsing and report errors correcetly on startup #129
* Implement interfaces for response shape and getters for data
* Parse version data from response and use ping endpoint to return info on connection test
* Fix throwing auth/connection errors to include actual cause along with more human-friendly parsed error info
2024-01-22 12:00:53 -05:00
FoxxMD 833273c19d feat: Improve discovery for network exceptions in error causes 2024-01-22 12:00:50 -05:00
FoxxMD 35603d0caf chore: update ChromecastSource to comply with new initialization flow 2024-01-22 12:00:47 -05:00
FoxxMD de1377afdd fix: actually throw auth failure so initialization fails correctly 2024-01-22 12:00:43 -05:00
FoxxMD a22ddd10cc Merge branch 'develop' into sourceInitializeRefactor
# Conflicts:
#	src/backend/scrobblers/LastfmScrobbler.ts
#	src/backend/sources/DeezerSource.ts
#	src/backend/sources/MopidySource.ts
#	src/backend/sources/SpotifySource.ts
#	src/backend/sources/SubsonicSource.ts
#	src/backend/tasks/heartbeatSources.ts
2024-01-22 11:59:59 -05:00
FoxxMD 280add7107 Prepare for reverse proxy usage #125
Not working correctly yet but no BC for regular, non suburl, usage
2024-01-19 11:40:15 -05:00
FoxxMD b34abcab56 Update index.html 2024-01-19 11:05:34 -05:00
FoxxMD 788b26949e Fix uncaught Vite startup errors 2024-01-19 11:00:09 -05:00
FoxxMD c11da3df3d Working dockerfile 2024-01-18 16:59:45 -05:00
FoxxMD 0d68fea0eb Working app version indicator 2024-01-18 16:41:35 -05:00
FoxxMD c98672bcef Simplify port usage 2024-01-18 15:23:56 -05:00
FoxxMD bb0c079757 Cleanup package.json 2024-01-18 15:23:47 -05:00
FoxxMD 891144546e Simplify (and fix) test tooling for new esm stuff 2024-01-18 15:06:25 -05:00
FoxxMD 86611d764d Cleanup 2024-01-18 14:36:28 -05:00
FoxxMD e604268004 It works! 2024-01-18 14:18:08 -05:00
FoxxMD 396c3da277 Convert all relative backend endings to js 2024-01-18 13:58:31 -05:00
FoxxMD 0591b90089 somewhat working esm conversion 2024-01-18 13:15:06 -05:00
FoxxMD 6763be53ac Use vite-express to migrate from CRA
TODO convert backend to esmodule?
2024-01-18 11:52:13 -05:00
FoxxMD aee23f7550 fix(chrome): Remove device if it fails to refresh after 6 retries 2024-01-17 10:11:53 -05:00
FoxxMD 57b5528d43 docs(chrome): Update device connection instructions 2024-01-16 11:40:19 -05:00
FoxxMD bd8cf18a1a feat(chrome): refactor mdns discovery to run on source heartbeat as well as startup 2024-01-16 11:29:43 -05:00
FoxxMD 84acdd901a refactor: Move mdns discovery into own functions
May be useful for other sources...
2024-01-16 11:10:49 -05:00
FoxxMD e213a95996 fix(chrome): Refactor error handling for client and mdns libraries to catch errors properly 2024-01-16 09:52:41 -05:00
FoxxMD 78cd2eecf9 feat(chrome): Allow manual device connections 2024-01-15 16:11:33 -05:00
FoxxMD ebfeea1087 feat(chrome): Implement user filtering media by type 2024-01-15 16:02:10 -05:00
FoxxMD ddca623792 Fix error causing schema to generate 2024-01-15 16:01:36 -05:00
FoxxMD f0da35d115 docs: Add local source reference to flatpak manifest 2024-01-15 14:18:29 -05:00
FoxxMD 10eb355f92 chore(chromecast): Switch to scoped chromecast-client to fix flatpak source generation limitation 2024-01-15 14:18:14 -05:00
FoxxMD 85702c534a feat(maloja): Improve error handling
* Build error causes based on known error response types and expected maloja error body
* Only retry requests if error is network-related
* Set upstream error as NOT showstopping if we find expected error structure and status is less than 500
* Better maloja error parsing and logging
2024-01-15 12:45:01 -05:00
FoxxMD e2dfe317a9 feat(chrome): Improve mdns discovery for docker
* Switch to lower-level mdns library for more control during debugging
* Use avahi-browse with host avahi-daemon to circumvent musl (alpline) issues with mdns resolution https://johnsiu.com/blog/alpine-linux/
2024-01-12 17:00:05 -05:00
FoxxMD 7008ae8672 feat(chrome): Handle applications with transportId context
* Add transportId shortname to logger label for better differentiation of "per session" apps
* Fix handling of MS player deletion when pruning apps by checking for other valid apps before deletion
2024-01-12 13:26:53 -05:00
FoxxMD 10d9fa3581 feat(chrome): Improved app logging
Use child winston logger for better readability
2024-01-12 12:58:14 -05:00
FoxxMD 2b85927739 feat(chrome): Don't use bad media data as a play
* Check media data for missing artist or track and skip play if either is missing
* Remove player if bad data for 60 seconds
2024-01-12 12:31:35 -05:00
FoxxMD 8c402238ed feat(chrome): Add user debugging 2024-01-12 11:38:52 -05:00
FoxxMD 758770d278 refactor(chrome): Use forked chromecast-client lib
* Instead of patching using forked lib with validation fixes and improvements
* Print raw data if validation error is found
2024-01-12 11:12:21 -05:00
FoxxMD ee7ebb159b fix(chrome): Fix ENV names 2024-01-12 10:14:31 -05:00
FoxxMD f47a66060f refactor(chrome): Proper package patch for optional/nullish validation fixes
https://github.com/dantaylor3/chromecast-client/pull/14
2024-01-12 10:14:17 -05:00
FoxxMD 8929a630ed docs: chromecast docs and schema 2024-01-11 15:25:06 -05:00
FoxxMD 077f5d7547 feat: Improve chromecast handling 2024-01-11 14:51:52 -05:00
FoxxMD 369ad42946 feat: Add initial Chromecast source 2024-01-10 16:43:34 -05:00
FoxxMD 5ab6b85b30 refactor(source): Implement more granular initialization
* Break up initialize into build data => check connection => check auth
* Implement stub methods in AbstractSource with default return for steps
* Refactor existing initialize overrides into steps for each source
2024-01-05 13:19:34 -05:00
774 changed files with 121608 additions and 48890 deletions
+25
View File
@@ -0,0 +1,25 @@
version: '3.7'
services:
# Update this to the name of the service you want to work with in your docker-compose.yml file
multi-scrobbler:
# Uncomment if you want to override the service's Dockerfile to one in the .devcontainer
# folder. Note that the path of the Dockerfile and context is relative to the *primary*
# docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile"
# array). The sample below assumes your primary file is in the root of your project.
#
# build:
# context: .
# dockerfile: .devcontainer/Dockerfile
image: mcr.microsoft.com/devcontainers/javascript-node:24-bookworm
volumes:
# Update this to wherever you want VS Code to mount the folder of your project
- ..:/workspaces:cached
command: sleep infinity
valkey:
image: valkey/valkey
env_file:
- path: ./.env
required: false
+50
View File
@@ -0,0 +1,50 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "Node.js",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"dockerComposeFile": [
"compose.yml"
// uncomment to add kasm/discord service
//"../deploy/docker-compose.discord.yml"
],
"service": "multi-scrobbler",
"workspaceFolder": "/workspaces",
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [9078,3000],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": ".devcontainer/postCreate.sh",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"hbenl.vscode-mocha-test-adapter",
"dbaeumer.vscode-eslint",
"unifiedjs.vscode-mdx",
"bradlc.vscode-tailwindcss",
"TakumiI.markdowntable",
"YoavBls.pretty-ts-errors",
"bowlerr.sqlite-intelliview-vscode"
]
}
},
"portsAttributes": {
"3000": {
"label": "Docusaurus"
},
"9078": {
"label": "App"
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
echo 'Adding node_modules to path'
echo 'export PATH=/workspaces/node_modules/.bin:/workspaces/docsite/node_modules/.bin:$PATH' >> /home/node/.bashrc
echo 'Updating npm...'
npm install -g npm@11.12.1
echo 'Installing concurrently...'
npm install -g concurrently
echo 'If you have freshly cloned this project or node_modules folder does not exist then you should run "npm run install:parallel" now'
+14 -1
View File
@@ -2,6 +2,7 @@
node_modules
npm-debug.log
Dockerfile
*.Dockerfile
.dockerignore
.gitignore
.github
@@ -10,13 +11,25 @@ Dockerfile
.idea
config/*.json
config/*.bak
config/*.p8
/docs
dist
/logs
.flatpak-builder
flatpak/generated-sources.json
**/generated-sources.*
flatpak/.flatpak-builder
docsite/build
docsite/node_modules
docsite/.docusaurus
docsite/.cache-loader
build
*.secrets
.devcontainer
.vscode
**/act/*
tmp-*
.env
*.env
.storybook
.stories
**/lexicons/**/*.json
+95
View File
@@ -0,0 +1,95 @@
name: Bug Report
description: Report a reproducible problem
title: "bug: "
labels: ["bug"]
body:
- type: checkboxes
attributes:
label: Please check existing knowledge before opening an issue
options:
- label: I have [read the Help docs](https://foxxmd.github.io/multi-scrobbler/help/)
required: true
- label: I have [checked the FAQ](https://foxxmd.github.io/multi-scrobbler/FAQ/) and [documentation](https://foxxmd.github.io/multi-scrobbler/configuration/)
required: true
- label: I have [searched through existing issues](https://github.com/FoxxMD/multi-scrobbler/issues?q=sort%3Aupdated-desc) and [discussions.](https://github.com/FoxxMD/multi-scrobbler/discussions)
required: true
- type: markdown
attributes:
value: |
If this a how-do-I question, troublehooting, or generally **not** a bug/error with multi-scrobbler please consider [**starting a discussion**](https://github.com/FoxxMD/multi-scrobbler/discussions) instead of opening an issue.
- type: textarea
id: what-happened
attributes:
label: Describe the Bug
description: Describe what you expected to happen and what happened instead. Please provide as much detail as possible.
placeholder: The app should have scrobbled from Spotify but instead it crashed with an error about undefined properties, etc...
validations:
required: true
- type: checkboxes
attributes:
label: What configuration types are you using for multi-scrobbler? Check all that apply.
options:
- label: "[Environmental Variables (ENV)](https://foxxmd.github.io/multi-scrobbler/configuration/?configType=env#configuration-types)"
required: false
- label: "[Individual](https://foxxmd.github.io/multi-scrobbler/configuration/?configType=file#configuration-types) Config Files"
required: false
- label: "[All-In-One](https://foxxmd.github.io/multi-scrobbler/configuration/?configType=aio#configuration-types) Config File"
required: false
- type: dropdown
id: platform
attributes:
label: Platform
description: What platform are you running multi-scrobbler on?
options:
- Docker
- Local (NodeJS)
- Flatpak
default: 0
validations:
required: true
- type: textarea
attributes:
label: Versions
description: What version of multi-scrobbler and issue-related sources/clients are running?
placeholder: |
- multi-scrobbler: 0.8.3 on docker
- maloja 3.1.4
- jellyfin 10.8.9
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs
description: |
Please copy and paste any/all relevant from the DEBUG level log output.
Even if your issue does not seem to be shown in the logs you should still add as much detail as possible, a _lack_ of issues in logs may be a good hint during debugging.
Your logs will be automatically formatted into code. Do not use fenced code blocks (backticks).
If possible reproduce the issue with [**Debug Mode** enabled](https://foxxmd.github.io/multi-scrobbler/configuration#debug-mode).
render: shell
placeholder: |
[2025-02-14 12:47:57.170 -0500] VERBOSE: [Init] Config Dir ENV: undefined -> Resolved: CWD/config
[2025-02-14 12:47:57.236 -0500] INFO : [Init] Debug Mode: NO
[2025-02-14 12:47:57.258 -0500] INFO : [Init] Version: master
[2025-02-14 12:47:57.259 -0500] INFO : [Init] Generating schema definitions...
[2025-02-14 12:47:59.148 -0500] DEBUG : [App] [Scrobblers] [Maloja - default] Found 100 recent scrobbles
- type: textarea
id: playDebug
attributes:
label: Play Debug Data
description: |
If relevent, please copy and paste all [**Debug Data**](https://foxxmd.github.io/multi-scrobbler/help#copy-play-debug-data) related to the Plays you are having issues with.
Your data will be automatically formatted into code. Do not use fenced code blocks (backticks) in the text area below.
render: shell
placeholder: |
{
"input": {
"addedAt": 1690250024,
"art": "/library/metadata/186983/art/1698213665",
"duration": 243983,
"grandparentArt": "/library/metadata/186983/art/1698213665",
...
- type: textarea
attributes:
label: Additional Context
description: Add any other context about the problem here.
@@ -0,0 +1,31 @@
name: Feature Request
description: Suggest a new feature or functionality
title: "feat: "
labels: ["enhancement"]
body:
- type: checkboxes
attributes:
label: Please check existing knowledge before opening an issue
options:
- label: I have checked the [documentation](https://foxxmd.github.io/multi-scrobbler/configuration/)
required: true
- label: I have [searched through existing issues](https://github.com/FoxxMD/multi-scrobbler/issues?q=sort%3Aupdated-desc) and [discussions.](https://github.com/FoxxMD/multi-scrobbler/discussions)
required: true
- type: textarea
attributes:
label: Describe the new functionality
description: Please describe the feature or functionality you want multi-scrobbler to have. Use as much detail as possible about the exact behavior you wish to see.
validations:
required: true
- type: textarea
attributes:
label: Configuration Example
description: |
If the functionality involves changes to configuration files please provide an example here
render: json5
- type: checkboxes
attributes:
label: Will you help implement it?
options:
- label: I am willing to contribute code towards completing this feature
- label: I am willing to help test preview builds for this feature
@@ -0,0 +1,75 @@
name: Request a new Source or Client
description: Request a new Source or Client to be implemented
title: "feat: "
labels: ["enhancement"]
body:
- type: checkboxes
attributes:
label: Please check existing knowledge before opening an issue
options:
- label: I have checked the [documentation](https://foxxmd.github.io/multi-scrobbler/configuration/)
required: true
- label: I have [searched through existing issues](https://github.com/FoxxMD/multi-scrobbler/issues?q=sort%3Aupdated-desc) and [discussions.](https://github.com/FoxxMD/multi-scrobbler/discussions)
required: true
- type: dropdown
attributes:
label: What Type?
description: Is this a Source or a Client?
options:
- Source
- Client
default: 1
validations:
required: true
- type: input
attributes:
label: Name
description: "What is the name of the new service/software?"
placeholder: "My Cool Player"
validations:
required: true
- type: input
attributes:
label: Website
description: "Website for the service/software. Preferably a github repo or other source-code homepage"
validations:
required: true
- type: dropdown
attributes:
label: API Available?
description: Does the service have an API or other protocol that multi-scrobbler can use to communicate? **Without this the likelyhood of implementation is very low.**
options:
- 'Yes'
- 'No'
default: 1
validations:
required: true
- type: dropdown
attributes:
label: Free To Use?
description: Is this service/software freely available or does it require purchasing/subscription?
options:
- 'Yes'
- 'No'
default: 1
validations:
required: true
- type: dropdown
attributes:
label: Willing to finance development?
description: If the software is **non-free** are you will to provide a paid account/subscription to multi-scrobbler developer's in order to facilitate development/testing?
options:
- 'Yes'
- 'No'
validations:
required: false
- type: checkboxes
attributes:
label: Will you help implement it?
options:
- label: I am willing to contribute code towards completing this feature
- label: I am willing to help test preview builds for this feature
- type: textarea
attributes:
label: Additional Context
description: Add any other context about the new Source/Client here
-40
View File
@@ -1,40 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
[Please check the FAQ](https://github.com/FoxxMD/multi-scrobbler/blob/master/docsite/docs/FAQ.md) before submitting a bug report.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Logs**
If possible reproduce the issue with [debug logging ON](https://github.com/FoxxMD/multi-scrobbler/blob/master/docsite/docs/FAQ.md#turn-on-debug-logging)
```
Copy and paste as much log data as possible related to this issue here.
```
**Versions (please complete the following information):**
Provide version information for any related sources/clients.
- multi-scrobbler: [e.g. 0.4.0 on docker]
- maloja [e.g. 3.1.4]
- jellyfin [e.g. 10.8.9]
**Additional context**
Add any other context about the problem here.
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+5
View File
@@ -0,0 +1,5 @@
--directory ../../
--env-file .github/act/.env
--secret-file .github/act/.secrets
--artifact-server-path out
#--action-offline-mode
+5
View File
@@ -0,0 +1,5 @@
NO_DOCKER_BUILD=true
#https://github.com/nektos/act/issues/329#issuecomment-1905955589
ACTIONS_RUNTIME_URL=http://YOUR_HOST_IP:8082/
ACTIONS_RUNTIME_TOKEN=foo
ACTIONS_CACHE_URL=http://YOUR_HOST_IP:8082/
+3
View File
@@ -0,0 +1,3 @@
DOCKER_PASSWORD=
DOCKER_USERNAME=
GITHUB_TOKEN=
+53
View File
@@ -0,0 +1,53 @@
Testing GH Actions with ACT
Need to have credentials in a [`.secrets` file](https://nektosact.com/usage/index.html#secrets), copy and rename [`.secrets.example`](./secrets.example) to `.secrets`, then fill out blank fields. Required for docker/metadata-action to read...something. Fails with `Parameter token or opts.auth is required` if they are not supplied.
An ENV file can also be made by copy and renaming [`.env.example`](./env.example). Set `NO_DOCKER_BUILD=true` if you only want to test APP_VERSION and docker tags output.
If running a full docker build for multi-runner workflows you will need to create an [artifact server](https://github.com/nektos/act/issues/329#issuecomment-1905955589) for ACT to work:
```shell
docker pull ghcr.io/jefuller/artifact-server:latest
docker run -d --name artifact-server -p 8082:8080 --add-host host.docker.internal:host-gateway -e AUTH_KEY=foo ghcr.io/jefuller/artifact-server:latest
```
Run the following **from this directory** to make use of `.actrc` and proper working directory.
### Test Branch Test Suite
```shell
act -W '.github/act/testSuite.yml' -e '.github/act/actBranchEvent.json'
```
### Test Branch Push
```shell
act -W '.github/act/actTest.yml' -e '.github/act/actBranchEvent.json'
```
### Test Tag (Release) Push
```shell
act -W '.github/act/actTest.yml' -e '.github/act/actTagEvent.json'
```
### Test Tag (Pre-Release) Push
```shell
act -W '.github/act/actTest.yml' -e '.github/act/actTagPreEvent.json'
```
### Test Multi-Runner Push (WIP)
```shell
act -W '.github/act/multiRunnerTest.yml' -e '.github/act/actBranchEvent.json'
```
### Test Multi-Runner Bake Push (WIP)
```shell
act -W '.github/act/multiRunnerBakeTest.yml' -e '.github/act/actBranchEvent.json'
```
+4
View File
@@ -0,0 +1,4 @@
{
"ref": "refs/heads/master",
"sha": "14d5eb3313110f2cfd1aa8fe9c229c21901c1eeb"
}
+164
View File
@@ -0,0 +1,164 @@
{
"action": "synchronize",
"number": 210,
"pull_request": {
"url": "https://api.github.com/repos/FoxxMD/multi-scrobbler/pulls/210",
"id": 2123337348,
"node_id": "PR_kwDOEpP-x85-j46E",
"number": 210,
"state": "open",
"locked": false,
"merge_commit_sha": "349bea1f4580b9e61aa22446eae73f8b1225bbb7",
"labels": [
{
"id": 2494982061,
"node_id": "MDU6TGFiZWwyNDk0OTgyMDYx",
"url": "https://api.github.com/repos/FoxxMD/multi-scrobbler/labels/bug",
"name": "bug",
"color": "d73a4a",
"default": true,
"description": "Something isn't working"
},
{
"id": 7131135993,
"node_id": "LA_kwDOEpP-x88AAAABqQx_-Q",
"url": "https://api.github.com/repos/FoxxMD/multi-scrobbler/labels/safe%20to%20test",
"name": "safe to test",
"color": "D4C5F9",
"default": false,
"description": "trusted to build image"
}
],
"milestone": null,
"draft": false,
"head": {
"label": "FoxxMD:GH-209/jellyfinCleanup",
"ref": "GH-209/jellyfinCleanup",
"sha": "e251da9b8eecfcb3aba8756393e5075d0092794b",
"user": {
"login": "FoxxMD",
"id": 4663766,
"node_id": "MDQ6VXNlcjQ2NjM3NjY=",
"avatar_url": "https://avatars.githubusercontent.com/u/4663766?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/FoxxMD",
"html_url": "https://github.com/FoxxMD",
"followers_url": "https://api.github.com/users/FoxxMD/followers",
"following_url": "https://api.github.com/users/FoxxMD/following{/other_user}",
"gists_url": "https://api.github.com/users/FoxxMD/gists{/gist_id}",
"starred_url": "https://api.github.com/users/FoxxMD/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/FoxxMD/subscriptions",
"organizations_url": "https://api.github.com/users/FoxxMD/orgs",
"repos_url": "https://api.github.com/users/FoxxMD/repos",
"events_url": "https://api.github.com/users/FoxxMD/events{/privacy}",
"received_events_url": "https://api.github.com/users/FoxxMD/received_events",
"type": "User",
"site_admin": false
},
"repo": {
"id": 311688903,
"node_id": "MDEwOlJlcG9zaXRvcnkzMTE2ODg5MDM=",
"name": "multi-scrobbler",
"full_name": "FoxxMD/multi-scrobbler",
"private": false,
"owner": {
"login": "FoxxMD",
"id": 4663766,
"node_id": "MDQ6VXNlcjQ2NjM3NjY=",
"avatar_url": "https://avatars.githubusercontent.com/u/4663766?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/FoxxMD",
"html_url": "https://github.com/FoxxMD",
"followers_url": "https://api.github.com/users/FoxxMD/followers",
"following_url": "https://api.github.com/users/FoxxMD/following{/other_user}",
"gists_url": "https://api.github.com/users/FoxxMD/gists{/gist_id}",
"starred_url": "https://api.github.com/users/FoxxMD/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/FoxxMD/subscriptions",
"organizations_url": "https://api.github.com/users/FoxxMD/orgs",
"repos_url": "https://api.github.com/users/FoxxMD/repos",
"events_url": "https://api.github.com/users/FoxxMD/events{/privacy}",
"received_events_url": "https://api.github.com/users/FoxxMD/received_events",
"type": "User",
"site_admin": false
},
"html_url": "https://github.com/FoxxMD/multi-scrobbler",
"description": "Scrobble plays from multiple sources to multiple clients",
"fork": false,
"created_at": "2020-11-10T14:45:38Z",
"updated_at": "2024-10-14T09:21:37Z",
"pushed_at": "2024-10-14T15:43:00Z",
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"visibility": "public",
"forks": 16,
"open_issues": 19,
"watchers": 369,
"default_branch": "master",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": false,
"delete_branch_on_merge": false,
"allow_update_branch": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE"
}
},
"base": {
"label": "FoxxMD:master",
"ref": "master",
"sha": "9c21db8172b6beff9d321e831e9353bf17e92a37",
"repo": {
"id": 311688903,
"node_id": "MDEwOlJlcG9zaXRvcnkzMTE2ODg5MDM=",
"name": "multi-scrobbler",
"full_name": "FoxxMD/multi-scrobbler",
"private": false,
"fork": false,
"created_at": "2020-11-10T14:45:38Z",
"updated_at": "2024-10-14T09:21:37Z",
"pushed_at": "2024-10-14T15:43:00Z",
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"visibility": "public",
"forks": 16,
"open_issues": 19,
"watchers": 369,
"default_branch": "master",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": false,
"delete_branch_on_merge": false,
"allow_update_branch": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE"
}
},
"author_association": "OWNER",
"auto_merge": null,
"active_lock_reason": null,
"merged": false,
"mergeable": null,
"rebaseable": null,
"mergeable_state": "unknown",
"merged_by": null,
"comments": 0,
"review_comments": 0,
"maintainer_can_modify": false,
"commits": 5,
"additions": 84,
"deletions": 28,
"changed_files": 5
},
"before": "335ee0cd601f5a82e36643c812507b2b53e7daf0",
"after": "e251da9b8eecfcb3aba8756393e5075d0092794b"
}
+8
View File
@@ -0,0 +1,8 @@
{
"ref": "refs/tags/0.8.4",
"ref_name": "0.8.4",
"before": "0000000000000000000000000000000000000000",
"after": "005dae76ab51799d3d55112738e301cb1af0dafd",
"sha": "005dae76ab51799d3d55112738e301cb1af0dafd",
"base_ref": "refs/heads/master"
}
+8
View File
@@ -0,0 +1,8 @@
{
"ref": "refs/tags/0.8.5-gh-runner",
"ref_name": "0.8.5-gh-runner",
"before": "0000000000000000000000000000000000000000",
"after": "005dae76ab51799d3d55112738e301cb1af0dafd",
"sha": "005dae76ab51799d3d55112738e301cb1af0dafd",
"base_ref": "refs/heads/master"
}
+105
View File
@@ -0,0 +1,105 @@
name: Publish Docker image to Dockerhub
on:
workflow_dispatch:
push:
branches:
- 'master'
tags:
- '*.*.*'
# don't trigger if just updating docs
paths-ignore:
- 'README.md'
- '.github/**'
- 'flatpak/**'
# use release instead of tags once version is correctly parsed
# https://github.com/docker/metadata-action/issues/422
# https://github.com/docker/metadata-action/issues/240
# release:
# types: [ published ]
jobs:
push_to_registry:
name: Build and push container images
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Debug
run: echo $JSON
env:
JSON: ${{ toJSON(github) }}
- name: Set git state to ENV
id: vars
# https://dev.to/hectorleiva/github-actions-and-creating-a-short-sha-hash-8b7
# short sha available under env.COMMIT_SHORT_SHA
run: |
calculatedSha=$(git rev-parse --short HEAD)
branchName=$(git rev-parse --abbrev-ref HEAD)
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
echo "COMMIT_BRANCH=$branchName" >> $GITHUB_ENV
- name: Check App Version
env:
# use release instead of tags once version is correctly parsed
#APP_VERSION: ${{ github.event.release.tag_name }}
# https://github.com/actions/runner/issues/409#issuecomment-752775072
# https://stackoverflow.com/a/69919067/1469797
APP_VERSION: ${{ contains(github.ref, 'refs/tags/') && github.ref_name || format('{0}-{1}', env.COMMIT_BRANCH, env.COMMIT_SHORT_SHA ) }}
run: |
echo $APP_VERSION
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
# generate Docker tags based on the following events/attributes
# https://github.com/docker/metadata-action/issues/247#issuecomment-1511259674 for NOT is default branch, eventually
tags: |
type=edge
# maybe re-enable branch-named tags in the futures
#type=ref,event=branch,enable=${{ !endsWith(github.ref, 'master') }}
# tag non-prelease as latest -- has a higher priority than regular tag so it shows first in registries
type=match,pattern=\d.\d.\d$,priority=901
# tag all semver (include pre-release)
type=semver,pattern={{version}}
# flavor: |
# latest=false
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
id: qemu
if: ${{ !env.NO_DOCKER_BUILD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
if: ${{ steps.qemu.outcome == 'success' }}
continue-on-error: true
- name: Build and push Docker image
if: ${{ steps.qemu.outcome == 'success' }}
env:
# use release instead of tags once version is correctly parsed
#APP_VERSION: ${{ github.event.release.tag_name }}
# https://github.com/actions/runner/issues/409#issuecomment-752775072
# https://stackoverflow.com/a/69919067/1469797
APP_VERSION: ${{ contains(github.ref, 'refs/tags/') && github.ref_name || format('{0}-{1}', env.COMMIT_BRANCH, env.COMMIT_SHORT_SHA ) }}
uses: docker/build-push-action@v5
with:
context: .
# https://github.com/docker/build-push-action/issues/1026#issue-2041857786
build-args: |
APP_BUILD_VERSION=${{env.APP_VERSION}}
push: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
+30
View File
@@ -0,0 +1,30 @@
variable "DEFAULT_TAG" {
default = "multi-scrobbler:local"
}
// Special target: https://github.com/docker/metadata-action#bake-definition
target "docker-metadata-action" {
tags = ["${DEFAULT_TAG}"]
}
// Default target if none specified
group "default" {
targets = ["image-local"]
}
target "image" {
inherits = ["docker-metadata-action"]
}
target "image-local" {
inherits = ["image"]
output = ["type=docker"]
}
target "image-all" {
inherits = ["image"]
platforms = [
"linux/amd64",
"linux/arm64"
]
}
+233
View File
@@ -0,0 +1,233 @@
# Based on https://docs.docker.com/build/ci/github-actions/multi-platform/#with-bake (https://github.com/docker/build-push-action/issues/671#issuecomment-1609106171)
# with example from here https://github.com/crazy-max/docker-linguist/blob/master/.github/workflows/build.yml that uses caching
#
# may have to use this to enable pushing to multiple registries? https://github.com/docker/build-push-action/discussions/1067#discussioncomment-8677682
name: build
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
- 'master'
tags:
- '*.*.*'
paths-ignore:
- 'README.md'
- '.github/**'
- 'flatpak/**'
env:
DOCKERHUB_SLUG: foxxmd/multi-scrobbler
GHCR_SLUG: ghcr.io/foxxmd/multi-scrobbler
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.platforms.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v4
- name: Set short git commit SHA
id: appvars
# https://dev.to/hectorleiva/github-actions-and-creating-a-short-sha-hash-8b7
# short sha available under env.COMMIT_SHORT_SHA
run: |
calculatedSha=$(git rev-parse --short HEAD)
branchName=$(git rev-parse --abbrev-ref HEAD)
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
echo "COMMIT_BRANCH=$branchName" >> $GITHUB_ENV
- name: Get App Version
id: appversion
env:
# use release instead of tags once version is correctly parsed
#APP_VERSION: ${{ github.event.release.tag_name }}
# https://github.com/actions/runner/issues/409#issuecomment-752775072
# https://stackoverflow.com/a/69919067/1469797
APP_VERSION: ${{ contains(github.ref, 'refs/tags/') && github.ref_name || format('{0}-{1}', env.COMMIT_BRANCH, env.COMMIT_SHORT_SHA ) }}
run: |
echo appversion=$APP_VERSION >>${GITHUB_OUTPUT}
-
name: Create matrix
id: platforms
run: |
echo "matrix=$(docker buildx bake --file ./docker-bake.hcl image-all --print | jq -cr '.target."image-all".platforms')" >>${GITHUB_OUTPUT}
-
name: Show matrix
run: |
echo ${{ steps.platforms.outputs.matrix }}
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.GHCR_SLUG }}
tags: |
type=edge
# maybe re-enable branch-named tags in the futures
#type=ref,event=branch,enable=${{ !endsWith(github.ref, 'master') }}
# tag non-prelease as latest -- has a higher priority than regular tag so it shows first in registries
type=match,pattern=\d.\d.\d$,priority=901
# tag all semver (include pre-release)
type=semver,pattern={{version}}
labels: |
org.opencontainers.image.title=Multi-Scrobbler
org.opencontainers.image.description=Scrobble from many sources to many clients
org.opencontainers.image.vendor=FoxxMD
-
name: Rename meta bake definition file
run: |
mv "${{ steps.meta.outputs.bake-file }}" "/tmp/bake-meta.json"
-
name: Upload meta bake definition
uses: actions/upload-artifact@v3
with:
name: bake-meta
path: /tmp/bake-meta.json
if-no-files-found: error
retention-days: 1
build:
runs-on: ubuntu-latest
needs:
- prepare
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps:
-
name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
-
name: Checkout
uses: actions/checkout@v4
-
name: Test App Version Transfer
run: |
echo "App Version in Build ${{ needs.prepare.appversion.outputs.appversion }}"
-
name: Download meta bake definition
uses: actions/download-artifact@v3
with:
name: bake-meta
path: /tmp
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
buildkitd-flags: "--debug"
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
-
name: Login to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build
id: bake
uses: docker/bake-action@v5
with:
files: |
./.github/act/docker-bake.hcl
/tmp/bake-meta.json
targets: image
set: |
*.args.APP_BUILD_VERSION=${{ needs.prepare.appversion.outputs.appversion }}
*.tags=
*.platform=${{ matrix.platform }}
*.cache-from=type=gha,scope=build-${{ env.PLATFORM_PAIR }}
*.cache-to=type=gha,scope=build-${{ env.PLATFORM_PAIR }}
*.output=type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
-
name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ fromJSON(steps.bake.outputs.metadata).image['containerimage.digest'] }}"
touch "/tmp/digests/${digest#sha256:}"
-
name: Upload digest
uses: actions/upload-artifact@v3
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
needs:
- build
steps:
-
name: Download meta bake definition
uses: actions/download-artifact@v3
with:
name: bake-meta
path: /tmp
-
name: Download digests
uses: actions/download-artifact@v3
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
-
name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("${{ env.DOCKERHUB_SLUG }}")) | "-t " + .) | join(" ")' /tmp/bake-meta.json) \
$(printf '${{ env.DOCKERHUB_SLUG }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("${{ env.GHCR_SLUG }}")) | "-t " + .) | join(" ")' /tmp/bake-meta.json) \
$(printf '${{ env.GHCR_SLUG }}@sha256:%s ' *)
-
name: Inspect image
run: |
tag=$(jq -r '.target."docker-metadata-action".args.DOCKER_META_VERSION' /tmp/bake-meta.json)
docker buildx imagetools inspect ${{ env.DOCKERHUB_SLUG }}:${tag}
docker buildx imagetools inspect ${{ env.GHCR_SLUG }}:${tag}
+198
View File
@@ -0,0 +1,198 @@
# Based on https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
name: build
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
- 'master'
tags:
- '*.*.*'
paths-ignore:
- 'README.md'
- '.github/**'
- 'flatpak/**'
env:
DOCKERHUB_SLUG: foxxmd/multi-scrobbler
GHCR_SLUG: ghcr.io/foxxmd/multi-scrobbler
jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Check out the repo
uses: actions/checkout@v5
- name: Set short git commit SHA
id: appvars
# https://dev.to/hectorleiva/github-actions-and-creating-a-short-sha-hash-8b7
# short sha available under env.COMMIT_SHORT_SHA
run: |
calculatedSha=$(git rev-parse --short HEAD)
branchName=$(git rev-parse --abbrev-ref HEAD)
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
echo "COMMIT_BRANCH=$branchName" >> $GITHUB_ENV
- name: Get App Version
id: appversion
env:
# use release instead of tags once version is correctly parsed
#APP_VERSION: ${{ github.event.release.tag_name }}
# https://github.com/actions/runner/issues/409#issuecomment-752775072
# https://stackoverflow.com/a/69919067/1469797
APP_VERSION: ${{ contains(github.ref, 'refs/tags/') && github.ref_name || format('{0}-{1}', env.COMMIT_BRANCH, env.COMMIT_SHORT_SHA ) }}
run: |
echo appversion=$APP_VERSION >>${GITHUB_OUTPUT}
# - name: Extract metadata (tags, labels) for Docker
# id: meta
# uses: docker/metadata-action@v5
# with:
# images: |
# ${{ env.DOCKERHUB_SLUG }}
# ${{ env.GHCR_SLUG }}
# labels: |
# org.opencontainers.image.title=Multi-Scrobbler
# org.opencontainers.image.description=Scrobble from many sources to many clients
# org.opencontainers.image.vendor=FoxxMD
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# https://github.com/docker/build-push-action/issues/671#issuecomment-1619353328
# for caching
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
build-args: |
APP_BUILD_VERSION=${{steps.appversion.outputs.appversion}}
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
#tags: ${{ steps.meta.outputs.tags }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=true
#cache-from: type=gha,scope=build-${{ env.PLATFORM_PAIR }}
#cache-to: type=gha,scope=build-${{ env.PLATFORM_PAIR }}
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
needs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.GHCR_SLUG }}
# generate Docker tags based on the following events/attributes
# https://github.com/docker/metadata-action/issues/247#issuecomment-1511259674 for NOT is default branch, eventually
tags: |
type=edge
# maybe re-enable branch-named tags in the futures
type=ref,event=branch,enable=${{ !endsWith(github.ref, 'master') }}
# tag non-prelease as latest -- has a higher priority than regular tag so it shows first in registries
type=match,pattern=\d.\d.\d$,priority=901
# tag all semver (include pre-release)
type=semver,pattern={{version}}
# flavor: |
# latest=false
labels: |
org.opencontainers.image.title=Multi-Scrobbler
org.opencontainers.image.description=Scrobble from many sources to many clients
org.opencontainers.image.vendor=FoxxMD
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.DOCKERHUB_SLUG }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.GHCR_SLUG }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }}
docker buildx imagetools inspect ${{ env.GHCR_SLUG }}:${{ steps.meta.outputs.version }}
+10
View File
@@ -0,0 +1,10 @@
name: PR Workflow
on:
push:
branches:
- 'master'
jobs:
test:
uses: ./.github/workflows/testAndSanity.yml
+37
View File
@@ -0,0 +1,37 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
groups:
sec-updates:
applies-to: "security-updates"
patterns:
- "*"
directories:
- "/"
- "/docsite"
schedule:
interval: "weekly"
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `root` directory
directory: "/"
# Check for updates once a week
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
groups:
sec-updates:
applies-to: "security-updates"
patterns:
- "*"
version-updates:
applies-to: "version-updates"
patterns:
- "*"
schedule:
interval: "weekly"
+1 -2
View File
@@ -1,7 +1,6 @@
## Checklist before requesting a review
- [ ] **I am opening this PR for the [`develop` branch](https://github.com/FoxxMD/multi-scrobbler/tree/develop) and NOT `master`.**
- [ ] I have read the [contributing guidelines.](../CONTRIBUTING.md)
- [ ] I have read the [contributing guidelines.](../blob/master/CONTRIBUTING.md)
## Type of change
+16
View File
@@ -0,0 +1,16 @@
name: Test Dependabot PR
on:
pull_request_target:
types:
- synchronize
- reopened
- opened
branches:
- 'master'
jobs:
test:
name: Tests / Build / Sanity Run
if: github.actor == 'dependabot[bot]'
uses: ./.github/workflows/testAndSanity.yml
+46 -8
View File
@@ -1,9 +1,9 @@
name: Deploy to GitHub Pages
on:
push:
branches:
- master
workflow_dispatch:
release:
types: [released]
# Review gh actions docs if you want to further define triggers, paths, etc
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
@@ -12,23 +12,40 @@ jobs:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
node-version: 18
persist-credentials: false
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #6.3.0
with:
node-version: 24
cache: npm
- name: Install dependencies
- name: Install app dev dependencies
run: npm ci
- name: Generate schema files
run: npm run schema
- name: Install docusaurus dependencies
run: npm ci
working-directory: ./docsite
- name: Build website
env:
RY_ANALYTICS: ${{ vars.RY_ANALYTICS }}
RY_ANALYTICS_SITEID: ${{ vars.RY_ANALYTICS_SITEID }}
GSITEVERIFICATION: ${{ vars.GSITEVERIFICATION }}
DOCS_BASE: '/multi-scrobbler'
run: npm run build
working-directory: ./docsite
- name: Replace canonical
working-directory: ./docsite
run: node --experimental-strip-types canonical-replace.ts ./build
# Popular action to deploy to GitHub Pages:
# Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e #4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# Build output to publish to the `gh-pages` branch:
@@ -40,3 +57,24 @@ jobs:
# You can swap them out with your own user credentials.
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com
- name: Trigger dependent build
if: ${{ vars.DOCS_REPO != ''}}
run: |
# Trigger builds in dependent repositories
curl -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.DOCS_DISPATCH_TOKEN }}" \
"https://api.github.com/repos/${{ vars.DOCS_REPO }}/dispatches" \
-d "{
\"event_type\": \"release\",
\"client_payload\": {
\"commit\": \"${{ github.sha }}\"
}
}"
- name: Trigger CF Pages build
if: ${{ vars.CF_PAGES == 'true' }}
run: |
# trigger CF pages hook deployment
curl -d "" \
"${{ secrets.CF_PAGES_HOOK }}"
@@ -0,0 +1,21 @@
name: Delete Untagged Packages
on:
schedule:
- cron: '30 1 * * 0'
workflow_run:
workflows: ["Publish Docker image to Dockerhub"]
types:
- completed
workflow_dispatch:
jobs:
delete-untagged:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: dataaxiom/ghcr-cleanup-action@cd0cdb900b5dbf3a6f2cc869f0dbb0b8211f50c4 #1.0.16
with:
token: ${{ secrets.GITHUB_TOKEN }}
# maybe set up for PR close later
# https://github.com/dataaxiom/ghcr-cleanup-action?tab=readme-ov-file#delete-image-when-pull-request-is-closed
+238
View File
@@ -0,0 +1,238 @@
name: PR Workflow
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.head.sha }}
cancel-in-progress: true
on:
pull_request_target:
types:
- labeled
- synchronize
- reopened
- opened
branches:
- 'master'
jobs:
test:
if: contains(github.event.pull_request.labels.*.name, 'safe to test')
uses: ./.github/workflows/testAndSanity.yml
with:
ref: ${{ github.event.pull_request.head.sha }}
build-snapshot:
name: Build OCI snapshot
needs: test
if: contains(github.event.pull_request.labels.*.name, 'safe to test')
runs-on: ${{ matrix.os }}
permissions:
packages: write
contents: read
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
arch: amd64
platform: linux/amd64
- os: ubuntu-24.04-arm
arch: arm64
platform: linux/arm64
steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
# list all registries to push to and join all non-empty with comma
# https://unix.stackexchange.com/a/693165/116849
# https://stackoverflow.com/a/9429887/1469797
strings=("${VARS_DOCKERHUB_SLUG}" "${VARS_GHCR_SLUG}")
for i in ${!strings[@]}; do [[ -z ${strings[i]} ]] && unset strings[i]; done
joined_string=$(IFS=, ; echo "${strings[*]}")
echo "REGISTRIES_JOINED=$joined_string" >> $GITHUB_ENV
date=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "BUILD_DATE=$date" >> $GITHUB_ENV
env:
VARS_DOCKERHUB_SLUG: ${{ vars.DOCKERHUB_SLUG }}
VARS_GHCR_SLUG: ${{vars.GHCR_SLUG}}
# do not use here!
# instead we can specify repo#sha in build-push-action so we only deal with foreign SHA for actually building image
# - uses: actions/checkout@v4
# with:
# ref: ${{ github.event.pull_request.head.sha }}
- name: Set short git commit SHA
run: |
short=$(echo "${{ github.event.pull_request.head.sha }}" | head -c7)
echo "COMMIT_SHORT_SHA=$short" >> $GITHUB_ENV
- name: Get App Version
id: appversion
env:
APP_VERSION: ${{ format('pr{0}-{1}', github.event.number, env.COMMIT_SHORT_SHA ) }}
run: |
echo appversion=$APP_VERSION >>${GITHUB_OUTPUT}
- name: Login to Docker Hub
if: ${{ vars.DOCKERHUB_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
if: ${{ vars.GHCR_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# metadata extract for docker labels/image names is done in merge job
- name: Set up Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1
# https://github.com/docker/build-push-action/issues/671#issuecomment-1619353328
# for caching
- name: Build and push by digest
id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
with:
# specify foreign repo#sha from PR that is used to build image
context: ${{github.event.pull_request.head.repo.clone_url}}#${{github.event.pull_request.head.sha}}
build-args: |
APP_BUILD_VERSION=${{steps.appversion.outputs.appversion}}
BUILD_DATE=${{ env.BUILD_DATE }}
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=${{ env.REGISTRIES_JOINED }}",push-by-digest=true,name-canonical=true,push=true
#cache-from: type=gha,scope=build-${{ env.PLATFORM_PAIR }}
#cache-to: type=gha,scope=build-${{ env.PLATFORM_PAIR }}
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #7.0.0
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
release-snapshot:
name: Merge OCI Images and Push
if: ${{ vars.DOCKERHUB_SLUG != '' || vars.GHCR_SLUG != '' }}
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
needs:
- build-snapshot
- test
steps:
- name: Download digests
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #8.0.1
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Login to Docker Hub
if: ${{ vars.DOCKERHUB_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
if: ${{ vars.GHCR_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435
- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf #6.0.0
with:
images: |
${{ vars.DOCKERHUB_SLUG }}
${{ vars.GHCR_SLUG }}
# generate Docker tags based on the following events/attributes
# https://github.com/docker/metadata-action/issues/247#issuecomment-1511259674 for NOT is default branch, eventually
tags: |
type=ref,event=pr
flavor: |
latest=false
labels: |
org.opencontainers.image.title=Multi-Scrobbler
org.opencontainers.image.description=Scrobble from many sources to many clients
org.opencontainers.image.vendor=FoxxMD
- name: Create manifest list and push dockerhub
if: ${{ vars.DOCKERHUB_SLUG != '' }}
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "${VARS_DOCKERHUB_SLUG}@sha256:%s " *)
env:
VARS_DOCKERHUB_SLUG: ${{ vars.DOCKERHUB_SLUG }}
- name: Create manifest list and push gchr
if: ${{ vars.GHCR_SLUG != '' }}
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "${VARS_GHCR_SLUG}@sha256:%s " *)
env:
VARS_GHCR_SLUG: ${{ vars.GHCR_SLUG }}
- name: Inspect image dockerhub
if: ${{ vars.DOCKERHUB_SLUG != '' }}
run: |
docker buildx imagetools inspect ${VARS_DOCKERHUB_SLUG}:${STEPS_META_OUTPUTS_VERSION}
env:
VARS_DOCKERHUB_SLUG: ${{ vars.DOCKERHUB_SLUG }}
STEPS_META_OUTPUTS_VERSION: ${{ steps.meta.outputs.version }}
- name: Inspect image ghcr
if: ${{ vars.GHCR_SLUG != '' }}
run: |
docker buildx imagetools inspect ${VARS_GHCR_SLUG}:${STEPS_META_OUTPUTS_VERSION}
env:
VARS_GHCR_SLUG: ${{ vars.GHCR_SLUG }}
STEPS_META_OUTPUTS_VERSION: ${{ steps.meta.outputs.version }}
combine-and-comment:
name: Leave comment
runs-on: ubuntu-latest
needs: release-snapshot
if: contains(github.event.pull_request.labels.*.name, 'safe to test')
steps:
- name: Create comment
uses: marocchino/sticky-pull-request-comment@d4d6b0936434b21bc8345ad45a440c5f7d2c40ff #3.0.3
with:
recreate: true
header: "pr-release"
message: |
#### :package: A new release has been made for this pull request.
To play around with this PR, pull an image:
* `foxxmd/multi-scrobbler:pr-${{ github.event.number }}`
Images are available for x86_64 and ARM64.
> Latest commit: ${{ github.event.pull_request.head.sha }}
+214 -35
View File
@@ -1,69 +1,248 @@
# Based on https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
name: Publish Docker image to Dockerhub
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
push:
branches:
- 'master'
- 'develop'
tags:
- '*.*.*'
# don't trigger if just updating docs
paths-ignore:
- '**.md'
- 'README.md'
- '.github/**'
- 'flatpak/**'
# use release instead of tags once version is correctly parsed
# https://github.com/docker/metadata-action/issues/422
# https://github.com/docker/metadata-action/issues/240
# release:
# types: [ published ]
# define in GH Repository -> Actions -> Variables (or act .variables) to enable pushing to registries
# -- will only push to registries that are defined
# EX
# DOCKERHUB_SLUG=foxxmd/multi-scrobbler
# GHCR_SLUG=ghcr.io/foxxmd/multi-scrobbler
jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
test:
if: github.event_name != 'pull_request'
uses: ./.github/workflows/testAndSanity.yml
build:
name: Build OCI Images
if: ${{ github.event_name != 'pull_request' && (vars.DOCKERHUB_SLUG != '' || vars.GHCR_SLUG != '') }}
needs: test
runs-on: ${{ matrix.os }}
permissions:
packages: write
contents: read
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
arch: amd64
platform: linux/amd64
- os: ubuntu-24.04-arm
arch: arm64
platform: linux/arm64
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
# list all registries to push to and join all non-empty with comma
# https://unix.stackexchange.com/a/693165/116849
# https://stackoverflow.com/a/9429887/1469797
strings=("${VARS_DOCKERHUB_SLUG}" "${VARS_GHCR_SLUG}")
for i in ${!strings[@]}; do [[ -z ${strings[i]} ]] && unset strings[i]; done
joined_string=$(IFS=, ; echo "${strings[*]}")
echo "REGISTRIES_JOINED=$joined_string" >> $GITHUB_ENV
date=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "BUILD_DATE=$date" >> $GITHUB_ENV
env:
VARS_DOCKERHUB_SLUG: ${{ vars.DOCKERHUB_SLUG }}
VARS_GHCR_SLUG: ${{vars.GHCR_SLUG}}
- name: Check out the repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Set short git commit SHA
id: appvars
# https://dev.to/hectorleiva/github-actions-and-creating-a-short-sha-hash-8b7
# short sha available under env.COMMIT_SHORT_SHA
run: |
calculatedSha=$(git rev-parse --short HEAD)
branchName=$(git rev-parse --abbrev-ref HEAD)
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
echo "COMMIT_BRANCH=$branchName" >> $GITHUB_ENV
- name: Get App Version
id: appversion
env:
# use release instead of tags once version is correctly parsed
#APP_VERSION: ${{ github.event.release.tag_name }}
# https://github.com/actions/runner/issues/409#issuecomment-752775072
# https://stackoverflow.com/a/69919067/1469797
APP_VERSION: ${{ contains(github.ref, 'refs/tags/') && github.ref_name || format('{0}-{1}', env.COMMIT_BRANCH, env.COMMIT_SHORT_SHA ) }}
run: |
echo appversion=$APP_VERSION >>${GITHUB_OUTPUT}
- name: Login to Docker Hub
if: ${{ github.event_name != 'pull_request' && vars.DOCKERHUB_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
if: ${{ github.event_name != 'pull_request' && vars.GHCR_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
# metadata extract for docker labels/image names is done in merge job
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1
# https://github.com/docker/build-push-action/issues/671#issuecomment-1619353328
# for caching
- name: Build and push by digest
id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
with:
build-args: |
APP_BUILD_VERSION=${{steps.appversion.outputs.appversion}}
BUILD_DATE=${{ env.BUILD_DATE }}
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=${{ env.REGISTRIES_JOINED }}",push-by-digest=true,name-canonical=true,push=true
#cache-from: type=gha,scope=build-${{ env.PLATFORM_PAIR }}
#cache-to: type=gha,scope=build-${{ env.PLATFORM_PAIR }}
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${VARS_DIGEST}"
touch "/tmp/digests/${digest#sha256:}"
env:
VARS_DIGEST: ${{ steps.build.outputs.digest }}
- name: Upload digest
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #7.0.0
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
name: Merge OCI Images and Push
if: ${{ github.event_name != 'pull_request' && (vars.DOCKERHUB_SLUG != '' || vars.GHCR_SLUG != '') }}
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
needs:
- build
- test
steps:
- name: Download digests
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #8.0.1
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Login to Docker Hub
if: ${{ github.event_name != 'pull_request' && vars.DOCKERHUB_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
if: ${{ github.event_name != 'pull_request' && vars.GHCR_SLUG != '' }}
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435
- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf #6.0.0
with:
images: |
foxxmd/multi-scrobbler
ghcr.io/foxxmd/multi-scrobbler
${{ vars.DOCKERHUB_SLUG }}
${{ vars.GHCR_SLUG }}
# generate Docker tags based on the following events/attributes
# https://github.com/docker/metadata-action/issues/247#issuecomment-1511259674 for NOT is default branch, eventually
tags: |
type=raw,value=latest,enable=${{ endsWith(github.ref, 'master') }}
type=edge
# push with branch name as tag if not master/main
type=ref,event=branch,enable=${{ !endsWith(github.ref, 'master') }}
# tag non-prelease as latest -- has a higher priority than regular tag so it shows first in registries
type=match,pattern=\d.\d.\d$,priority=901
# tag all semver (include pre-release)
type=semver,pattern={{version}}
flavor: |
latest=false
# flavor: |
# latest=false
labels: |
org.opencontainers.image.title=Multi-Scrobbler
org.opencontainers.image.description=Scrobble from many sources to many clients
org.opencontainers.image.vendor=FoxxMD
- name: Create manifest list and push dockerhub
if: ${{ vars.DOCKERHUB_SLUG != '' }}
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "${VARS_DOCKERHUB_SLUG}@sha256:%s " *)
env:
VARS_DOCKERHUB_SLUG: ${{ vars.DOCKERHUB_SLUG }}
- name: Create manifest list and push gchr
if: ${{ vars.GHCR_SLUG != '' }}
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "${VARS_GHCR_SLUG}@sha256:%s " *)
env:
VARS_GHCR_SLUG: ${{ vars.GHCR_SLUG }}
- name: Inspect image dockerhub
if: ${{ vars.DOCKERHUB_SLUG != '' }}
run: |
docker buildx imagetools inspect ${VARS_DOCKERHUB_SLUG}:${STEPS_META_OUTPUTS_VERSION}
env:
VARS_DOCKERHUB_SLUG: ${{ vars.DOCKERHUB_SLUG }}
STEPS_META_OUTPUTS_VERSION: ${{ steps.meta.outputs.version }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: ${{ github.event_name != 'pull_request' && !env.ACT}}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
- name: Inspect image ghcr
if: ${{ vars.GHCR_SLUG != '' }}
run: |
docker buildx imagetools inspect ${VARS_GHCR_SLUG}:${STEPS_META_OUTPUTS_VERSION}
env:
VARS_GHCR_SLUG: ${{ vars.GHCR_SLUG }}
STEPS_META_OUTPUTS_VERSION: ${{ steps.meta.outputs.version }}
+71
View File
@@ -0,0 +1,71 @@
name: Tests and Sanity Run
on:
workflow_call:
inputs:
node-version:
description: "Node version"
required: false
default: '24.x'
type: string
ref:
description: "Ref to checkout"
required: false
type: string
jobs:
test:
name: Tests / Build / Sanity Run
runs-on: ubuntu-latest
steps:
- name: Check out the repo (gha)
if: ${{ !env.ACT }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
ref: ${{ inputs.ref }}
persist-credentials: false
- name: Check out the repo (act)
if: ${{ env.ACT }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Use Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #6.3.0
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- name: Install concurrently
run: npm install -g concurrently
- name: Install dev dependencies
run: npm run install:parallel
- name: Test Backend
run: npm run test
- name: Build
run: npm run build:parallel
# remove modules that might include dev stuff
# so that in the next step we are sure that prod-only runs work correctly
- name: Install Prod Deps
run: |
rm -rf node_modules && \
rm -rf docsite/node_modules && \
NODE_ENV=production npm ci --omit=dev
# run app for 10 seconds as sanity check to see if it errors for any reason
# easy testcase for missing packages and init errors
- name: Sanity Run
run: |
set +e
export NODE_ENV=production
timeout --preserve-status 10s node src/backend/index.ts
exitcode="$?"
if [[ "$exitcode" -eq 143 ]] || [[ "$exitcode" -eq 137 ]]; then
echo "App stayed up long enough and exited with expected status"
exit 0
else
echo "App exited with unexpected code $exitcode"
exit "$exitcode"
fi
+30
View File
@@ -73,6 +73,7 @@ web_modules/
# dotenv environment variables file
.env
.env.test
*.env
# parcel-bundler cache (https://parceljs.org/)
.cache
@@ -118,15 +119,44 @@ dist
.pnp.*
config/*.json
config/mscache
config/yti-*
config/*.cache
*.txt
!robots.txt
.idea/
src/**/**.js
src/**/**.js.map
src/backend/common/schema/*.json
!src/backend/common/schema/aio-client.json
!src/backend/common/schema/aio-source.json
!src/backend/common/schema/aio.json
!src/backend/common/schema/client.json
!src/backend/common/schema/source.json
docsite/static/schemas/*.json
*.bak
*.p8
.flatpak-builder
flatpak/generated-sources.json
*.secrets
build
!setupProxy.js
**/generated-sources.*
.github/act/out
tmp-*
*storybook.log
storybook-static
*.db
*.db*
**/lexicons/**/*.json
bun.lock
.DS_Store
**/.DS_Store
+28
View File
@@ -0,0 +1,28 @@
{
"$schema": "https://lnav.org/schemas/format-v1.schema.json",
"error_log": {
"title": "Multi-Scrobbler Log",
"description": "Logs from Multi Scrobbler",
"regex": {
"std": {
"pattern": "^\\[(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?)(?:.*?)\\] (?<level>[A-Z]*) : (?<body>.*)"
}
},
"level-field": "level",
"level": {
"info": "^(?i)(?:info)$",
"debug": "^(?i)(?:debug)$",
"error": "^(?i)(error)$",
"warning": "^(?i)(warn)$",
"trace": "^(?i)verbose$",
"critical": "^(?i)(?:crit|Cr)$",
"fatal": "^(?i)(?:alert|fatal|panic|Al|Em)$"
},
"sample": [
{
"line": "[2024-12-26 01:58:48.261 -0500] DEBUG : [App] [Sources] [Jellyfin - unnamed] Last activity was at 01:58:48-05:00 | Next check in 10.00s | No new tracks discovered",
"level": "debug"
}
]
}
}
+7 -2
View File
@@ -1,4 +1,9 @@
{
"require": ["./register.js", "source-map-support/register"],
"reporter": "dot"
"reporter": "dot",
"extension": "ts",
"spec": "./src/backend/tests/**/*.test.ts",
"file": [
"./src/backend/tests/setup.ts"
],
"exit": true
}
+1 -1
View File
@@ -1 +1 @@
v18.16.0
v24.14.0
-24
View File
@@ -1,24 +0,0 @@
{
"extends": "@istanbuljs/nyc-config-typescript",
"exclude": [
"node_modules/",
"**/src/backend/common/schema/**",
"**/src/backend/tests/**",
"register.js",
"**/src/server/**/*.d.ts",
"**/src/client/**"
],
"include": [
"**/src/backend/**/*.ts",
"**/src/**/backend/*.js",
"**/src/**/backend/*.js.map"
],
"extension": [
".ts"
],
"reporter": [
"text-summary",
"html"
],
"report-dir": "./coverage"
}
+47
View File
@@ -0,0 +1,47 @@
import { defineMain } from "@storybook/react-vite/node";
import { mergeConfig } from "vite";
export default defineMain({
"stories": [
"../src/**/*.mdx",
"../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
],
"addons": [
"@chromatic-com/storybook",
// "@storybook/addon-vitest",
"@storybook/addon-a11y",
"@storybook/addon-docs",
'storybook-addon-remix-react-router'
// "@storybook/addon-onboarding"
],
features: {
// https://github.com/storybookjs/storybook/discussions/33279
sidebarOnboardingChecklist: false,
},
staticDirs: ['../public'],
"framework": "@storybook/react-vite",
viteFinal: async (config) => {
return mergeConfig(config, {
optimizeDeps: {
include: ["@storybook/addon-docs"],
},
plugins: [
{
name: "fix-mdx-react-shim",
enforce: "pre",
resolveId(source: any) {
if (
source.startsWith("file://") &&
source.includes("mdx-react-shim.js")
) {
// Convert file:///... path to normal filesystem path for Vite
return new URL(source).pathname;
}
return null;
},
},
],
});
},
});
+6
View File
@@ -0,0 +1,6 @@
import { addons } from 'storybook/manager-api';
import { themes } from 'storybook/theming';
addons.setConfig({
theme: themes.normal,
});
+37
View File
@@ -0,0 +1,37 @@
import addonDocs from "@storybook/addon-docs";
import addonA11y from "@storybook/addon-a11y";
import { definePreview } from "@storybook/react-vite";
import { themes } from 'storybook/theming';
import { initialize, mswLoader, getWorker } from 'msw-storybook-addon';
// https://github.com/mswjs/msw-storybook-addon/issues/82#issuecomment-3894302575
try {
getWorker();
} catch (_) {
initialize();
}
export default definePreview({
loaders: [mswLoader],
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
a11y: {
// 'todo' - show a11y violations in the test UI only
// 'error' - fail CI on a11y violations
// 'off' - skip a11y checks entirely
test: 'todo'
},
docs: {
theme: themes.normal,
},
},
addons: [addonA11y(), addonDocs()]
});
+6
View File
@@ -0,0 +1,6 @@
{
"recommendations": [
"sanjulaganepola.github-local-actions",
"github.vscode-github-actions"
]
}
+139
View File
@@ -0,0 +1,139 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Zod Conversion",
"type": "node",
"request": "launch",
// Debug app in VSCode
"program": "${workspaceFolder}/ts-zod.ts",
"args": [
"${file}"
],
"runtimeExecutable": "node",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"skipFiles": [
"<node_internals>/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
},
{
"name": "Run Canonical Replace",
"program": "${workspaceFolder}/docsite/canonical-replace.ts",
"runtimeArgs": ["--experimental-strip-types"],
"args": [
"${workspaceFolder}/docsite/build"
],
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
{
"name": "dev",
"type": "node",
"request": "launch",
// Debug app in VSCode
"program": "${workspaceFolder}/src/backend/index.ts",
"runtimeExecutable": "node",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"skipFiles": [
"<node_internals>/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
},
{
"name": "dev (ENV Only)",
"type": "node",
"request": "launch",
// Debug app in VSCode
"program": "${workspaceFolder}/src/backend/index.ts",
"runtimeExecutable": "node",
"console": "integratedTerminal",
"envFile": "${workspaceFolder}/.env",
"env": {
"CONFIG_DIR": "./not-real"
},
"internalConsoleOptions": "neverOpen",
"skipFiles": [
"<node_internals>/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
},
{
"name": "schema",
"type": "node",
"request": "launch",
// Debug app in VSCode
"program": "${workspaceFolder}/src/backend/utils/SchemaDocsStaticUtils.ts",
"runtimeExecutable": "node",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"skipFiles": [
"<node_internals>/**",
// Ignore all dependencies (optional)
//"${workspaceFolder}/node_modules/**",
],
"resolveSourceMapLocations": [
"${workspaceFolder}/src/**/*",
"${workspaceFolder}/node_modules/**/*"
]
},
{
"args": [
"-u",
"bdd",
"--timeout",
"999999",
"--reporter",
"spec",
"--colors",
"--config",
"${workspaceRoot}/.mocharc.json",
"--recursive",
"${workspaceFolder}/src/backend/tests/**/*.test.ts"
],
"runtimeExecutable": "node",
"internalConsoleOptions": "openOnSessionStart",
"name": "Mocha Tests",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"request": "launch",
"skipFiles": [
"<node_internals>/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
"type": "node"
},
{
"args": [
"-u",
"bdd",
"--timeout",
"999999",
"--reporter",
"spec",
"--colors",
"--config", "${workspaceRoot}/.mocharc.json",
"${file}"
],
"runtimeExecutable": "node",
"internalConsoleOptions": "openOnSessionStart",
"name": "Mocha Test on File",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"request": "launch",
"skipFiles": [
"<node_internals>/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
"type": "node"
}
]
}
+18
View File
@@ -0,0 +1,18 @@
{
"mochaExplorer.timeout": 1200000,
"mochaExplorer.exit": true,
"search.exclude": {
"**/.docusaurus": true,
"**/build": true,
"**/schema": true
},
"tailwindCSS.files.exclude": [
"docsite/**"
],
"files.associations": {
"*.css": "tailwindcss",
"**/config/*.json": "jsonc"
},
"tailwindCSS.experimental.configFile": "src/client/index.css",
}
+37
View File
@@ -0,0 +1,37 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "src/backend/tsconfig.json",
"problemMatcher": [
"$tsc"
],
"group": {
"kind": "build",
"isDefault": true
},
"label": "tsc: build - src/backend/tsconfig.json"
},
{
"type": "shell",
"label": "compose-up-dev",
"command": "docker-compose -f docker-compose.dev.yml up",
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"type": "shell",
"label": "compose-build-dev",
"command": "docker-compose -f docker-compose.dev.yml build",
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
}
]
}
+128
View File
@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
coc@foxxmd.dev.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+1 -2
View File
@@ -2,7 +2,6 @@
Please follow these guidelines when contributing code to this repository:
* The PR **must be for the [`develop` branch.](https://github.com/FoxxMD/multi-scrobbler/tree/develop)** The `master` branch is for releases only.
* Use [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/#summary) format when creating commits.
* Preferably, please use a [feature branch](https://stackoverflow.com/a/39586780/1469797) instead of committing directly to `develop`.
* Preferably, please use a [feature branch](https://stackoverflow.com/a/39586780/1469797) instead of committing directly to `master`.
* Ensure that if your code is covered by [an existing test](./src/backend/tests) that you have updated the test accordingly
+101 -44
View File
@@ -1,83 +1,140 @@
FROM lsiobase/alpine:3.18 as base
FROM ghcr.io/linuxserver/baseimage-debian:bookworm AS base
ENV TZ=Etc/GMT
ENV NODE_VERSION=24.14.0
# borrowing openssl header removal trick from offical docker-node
# https://github.com/nodejs/docker-node/blob/main/18/bookworm-slim/Dockerfile#L8
RUN \
ARCH= OPENSSL_ARCH= && dpkgArch="$(dpkg --print-architecture)" \
&& case "${dpkgArch##*-}" in \
amd64) ARCH='x64' OPENSSL_ARCH='linux-x86_64';; \
ppc64el) ARCH='ppc64le' OPENSSL_ARCH='linux-ppc64le';; \
s390x) ARCH='s390x' OPENSSL_ARCH='linux*-s390x';; \
arm64) ARCH='arm64' OPENSSL_ARCH='linux-aarch64';; \
armhf) ARCH='armv7l' OPENSSL_ARCH='linux-armv4';; \
i386) ARCH='x86' OPENSSL_ARCH='linux-elf';; \
*) echo "unsupported architecture"; exit 1 ;; \
esac && \
set -ex && \
echo "**** install build packages ****" && \
apk add --no-cache \
alpine-base \
git \
nodejs \
npm \
#yarn \
openssh && \
apt-get update && \
apt-get install --no-install-recommends -y \
#ca-certificates \
xz-utils \
avahi-utils \
curl && \
echo "**** Fetch and install node****" && \
# get node/npm directly from nodejs dist \
# https://github.com/nodejs/docker-node/blob/main/18/bookworm-slim/Dockerfile#L41
curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz" && \
tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr --strip-components=1 --no-same-owner && \
rm "node-v$NODE_VERSION-linux-$ARCH.tar.xz" && \
ln -s /usr/bin/node /usr/bin/nodejs && \
npm update -g npm && \
echo "**** cleanup ****" && \
rm -rf \
/root/.cache \
/tmp/*
# https://github.com/nodejs/docker-node/blob/main/18/bookworm-slim/Dockerfile#L49
# Remove unused OpenSSL headers to save ~34MB
# (does not affect arm64 issue below)
find /usr/include/node/openssl/archs -mindepth 1 -maxdepth 1 ! -name "$OPENSSL_ARCH" -exec rm -rf {} \; && \
apt-get purge --auto-remove -y perl xz-utils && \
apt-get autoclean && \
apt-get autoremove && \
rm -rf \
/config/.cache \
/root/cache \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/*
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "Node: $(node -v)\nNPM: $(npm -v)"
RUN npm install -g concurrently
ARG data_dir=/config
VOLUME $data_dir
ENV CONFIG_DIR=$data_dir
ENV DATA_DIR=$data_dir
COPY docker/root/ /
RUN npm install -g patch-package \
&& chown -R root:root /usr/local/lib/node_modules/patch-package
COPY docker/root /
WORKDIR /app
FROM base as build
FROM base AS build
# would very much like to use YARN for dependency management but its got show-stopping bad design for prod dependencies
# https://github.com/yarnpkg/yarn/issues/6323 -- always downloads devDependencies -- and im not about to migrate to v2 since alpine doesn't support it yet
# copy dep/TS config and install dev dependencies
#COPY --chown=abc:abc package.json tsconfig.json yarn.lock ./
COPY --chown=abc:abc package*.json tsconfig.json ./
COPY --chown=abc:abc patches ./patches
COPY --chown=abc:abc docsite/patches ./docsite/patches
COPY --chown=abc:abc docsite/package*.json docsite/tsconfig* ./docsite/
# for debugging, so the build fails faster when timing out (arm64)
#RUN npm config set fetch-retries 1 && \
# npm config set fetch-retry-mintimeout 5000 && \
# npm config set fetch-retry-maxtimeout 5000
RUN npm install \
&& chown -R root:root node_modules
#RUN yarn install
# https://www.npmjs.com/package/tls-test
# used to test that the OS supports downloading packages over HTTPS with TLS 1.2 enforced
# -- this always succeeds but a good sanity check
#RUN npm install -g https://tls-test.npmjs.com/tls-test-1.0.0.tgz
# This FAILED for node < 20 when building arm64 but not amd64 (and alpine-based Dockerfile has no issues building arm64)
# see https://github.com/FoxxMD/multi-scrobbler/issues/126
RUN npm run install:parallel \
&& chown -R root:root node_modules \
&& chown -R root:root docsite/node_modules
COPY --chown=abc:abc . /app
# need to set before build so server/client build is optimized and has constants (if needed)
ENV NODE_ENV=production
RUN npm run build && rm -rf node_modules
#RUN yarn run build && rm -rf node_modules
RUN npm run build:parallel && rm -rf node_modules && rm -rf docsite/node_modules
FROM base as app
FROM base AS app
#COPY --chown=abc:abc package.json yarn.lock ./
COPY --chown=abc:abc package*.json ./
COPY --chown=abc:abc *.json *.js *.ts index.html ./
COPY --chown=abc:abc patches ./patches
COPY --from=build --chown=abc:abc /app/build /app/build
COPY --from=base /usr/local/bin /usr/local/bin
COPY --from=base /usr/local/lib /usr/local/lib
# frontend build from vite/esbuild
COPY --from=build --chown=abc:abc /app/dist /app/dist
# backend
COPY --from=build --chown=abc:abc /app/src/backend /app/src/backend
COPY --from=build --chown=abc:abc /app/src/core /app/src/core
# docusaurus docs
COPY --from=build --chown=abc:abc /app/docsite /app/docsite
COPY --from=base /usr/bin /usr/bin
COPY --from=base /usr/lib /usr/lib
ENV NODE_ENV=production
ENV IS_DOCKER=true
#
#RUN yarn global add patch-package \
# && yarn install --production=true \
# && yarn global remove patch-package \
# && yarn cache clean --mirror \
# && chown abc:abc node_modules \
# && rm -rf node_modules/ts-node \
# && rm -rf node_modules/typescript
ENV COLORED_STD=true
RUN npm install --omit=dev \
# https://stackoverflow.com/a/63640896/1469797
ARG APP_BUILD_VERSION
ENV APP_VERSION=$APP_BUILD_VERSION
RUN npm ci --omit=dev --no-audit \
&& npm cache clean --force \
&& chown -R abc:abc node_modules \
&& rm -rf node_modules/ts-node \
&& rm -rf node_modules/typescript \
&& rm -rf node_modules/@types
## peerDependency of validbot and can(?) be removed for production
&& rm -r node_modules/typescript \
&& npx @usex/prune-mod -w \
&& rm -rf /root/.cache
ARG BUILD_DATE=0
LABEL org.opencontainers.image.version="$APP_BUILD_VERSION" \
org.opencontainers.image.source="https://github.com/FoxxMD/multi-scrobbler" \
org.opencontainers.image.documentation="https://docs.multi-scrobbler.app" \
org.opencontainers.image.description="Scrobble from multiple sources to multiple clients" \
org.opencontainers.image.title="Multi-Scrobbler" \
org.opencontainers.image.licenses="MIT" \
org.opencontainers.image.authors="FoxxMD" \
org.opencontainers.image.created="$BUILD_DATE" \
org.opencontainers.image.url="https://docs.multi-scrobbler.app" \
maintainer="FoxxMD" \
build_version="$APP_BUILD_VERSION"
ARG webPort=9078
ENV PORT=$webPort
+67 -31
View File
@@ -3,37 +3,67 @@
[![Latest Release](https://img.shields.io/github/v/release/foxxmd/multi-scrobbler)](https://github.com/FoxxMD/multi-scrobbler/releases)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Docker Pulls](https://img.shields.io/docker/pulls/foxxmd/multi-scrobbler)](https://hub.docker.com/r/foxxmd/multi-scrobbler)
[![Docs](https://img.shields.io/badge/Read%20The%20Docs-1082c2)](https://docs.multi-scrobbler.app/)
<img src="/assets/icon.png" align="right"
alt="multi-scrobbler logo" width="180" height="180">
A javascript app to scrobble music you listened to, to [Maloja](https://github.com/krateng/maloja), [Last.fm](https://www.last.fm), and [ListenBrainz](https://listenbrainz.org)
A dockerized app that monitors your music listening activity from *everywhere* and scrobbles it *anywhere*.
* Supports scrobbling from many **Sources**
* [Spotify](/docsite/docs/configuration/configuration.md#spotify)
* [Plex](/docsite/docs/configuration/configuration.md#plex) or [Tautulli](/docsite/docs/configuration/configuration.md#tautulli)
* [Subsonic-compatible APIs](/docsite/docs/configuration/configuration.md#subsonic) (like [Airsonic](https://airsonic.github.io/) and [Navidrome](https://www.navidrome.org/))
* [Jellyfin](/docsite/docs/configuration/configuration.md#jellyfin)
* [WebScrobbler](/docsite/docs/configuration/configuration.md#webscrobbler)
* [Youtube Music](/docsite/docs/configuration/configuration.md#youtube-music)
* [Last.fm](/docsite/docs/configuration/configuration.md#lastfm-source)
* [ListenBrainz](/docsite/docs/configuration/configuration.md#listenbrainz--source-)
* [Deezer](/docsite/docs/configuration/configuration.md#deezer)
* [MPRIS (Linux Desktop)](/docsite/docs/configuration/configuration.md#mpris)
* [Mopidy](/docsite/docs/configuration/configuration.md#mopidy)
* [JRiver](/docsite/docs/configuration/configuration.md#jriver)
* [Kodi](/docsite/docs/configuration/configuration.md#kodi)
* Supports scrobbling to many **Clients**
* [Maloja](/docsite/docs/configuration/configuration.md#maloja)
* [Last.fm](/docsite/docs/configuration/configuration.md#lastfm)
* [ListenBrainz](/docsite/docs/configuration/configuration.md#listenbrainz)
* Monitor status of Sources and Clients using [webhooks (Gotify or Ntfy)](/docsite/docs/configuration/configuration.md#webhook-configurations) or [healthcheck endpoint](/docsite/docs/configuration/configuration.md#health-endpoint)
* Supports scrobbling from many [**Sources**](https://docs.multi-scrobbler.app/configuration/sources)
* [Apple Music](https://docs.multi-scrobbler.app/configuration/sources/applemusic/?configType=file)
* [Azuracast](https://docs.multi-scrobbler.app/configuration/sources/azuracast)
* [Deezer](https://docs.multi-scrobbler.app/configuration/sources/deezer)
* [Google Cast (Chromecast)](https://docs.multi-scrobbler.app/configuration/sources/google-cast)
* [Icecast](https://docs.multi-scrobbler.app/configuration/sources/icecast)
* [Jellyfin](https://docs.multi-scrobbler.app/configuration/sources/jellyfin)
* [JRiver](https://docs.multi-scrobbler.app/configuration/sources/jriver)
* [Kodi](https://docs.multi-scrobbler.app/configuration/sources/kodi)
* [Koito](https://docs.multi-scrobbler.app/configuration/sources/koito-source)
* [Last.fm](https://docs.multi-scrobbler.app/configuration/sources/lastfm-source)
* [Last.fm (Endpoint)](https://docs.multi-scrobbler.app/configuration/sources/lastfm-endpoint)
* [Libre.fm](https://docs.multi-scrobbler.app/configuration/sources/librefm-source)
* [ListenBrainz](https://docs.multi-scrobbler.app/configuration/sources/listenbrainz-source)
* [ListenBrainz (Endpoint)](https://docs.multi-scrobbler.app/configuration/sources/listenbrainz-endpoint)
* [Maloja](https://docs.multi-scrobbler.app/configuration/sources/maloja)
* [Mopidy](https://docs.multi-scrobbler.app/configuration/sources/mopidy)
* [MPD (Music Player Daemon)](https://docs.multi-scrobbler.app/configuration/sources/mpd)
* [MPRIS (Linux Desktop)](https://docs.multi-scrobbler.app/configuration/sources/mpris)
* [Musikcube](https://docs.multi-scrobbler.app/configuration/sources/musikcube)
* [Music Assistant](https://docs.multi-scrobbler.app/configuration/sources/listenbrainz-endpoint#music-assistant)
* [Plex](https://docs.multi-scrobbler.app/configuration/sources/plex)
* [Rocksky](https://docs.multi-scrobbler.app/configuration/sources/rocksky-source)
* [Sonos](https://docs.multi-scrobbler.app/configuration/sources/sonos)
* [Spotify](https://docs.multi-scrobbler.app/configuration/sources/spotify)
* [Subsonic-compatible APIs](https://docs.multi-scrobbler.app/configuration/sources/subsonic) (like [Airsonic](https://airsonic.github.io/) and [Navidrome](https://www.navidrome.org/))
* [teal.fm](https://docs.multi-scrobbler.app/configuration/sources/tealfm-source)
* [WebScrobbler](https://docs.multi-scrobbler.app/configuration/sources/webscrobbler)
* [VLC](https://docs.multi-scrobbler.app/configuration/sources/vlc)
* [Yamaha MusicCast](https://docs.multi-scrobbler.app/configuration/sources/yamaha-musiccast)
* [Youtube Music](https://docs.multi-scrobbler.app/configuration/sources/youtube-music)
* Supports scrobbling to many [**Clients**](https://docs.multi-scrobbler.app/configuration/clients)
* [Discord](https://docs.multi-scrobbler.app/configuration/clients/discord) (Now Playing)
* [Koito](https://docs.multi-scrobbler.app/configuration/clients/koito)
* [Last.fm](https://docs.multi-scrobbler.app/configuration/clients/lastfm)
* [Libre.fm](https://docs.multi-scrobbler.app/configuration/clients/librefm)
* [ListenBrainz](https://docs.multi-scrobbler.app/configuration/clients/listenbrainz)
* [Maloja](https://docs.multi-scrobbler.app/configuration/clients/maloja)
* [Rocksky](https://docs.multi-scrobbler.app/configuration/clients/rocksky)
* [teal.fm](https://docs.multi-scrobbler.app/configuration/clients/tealfm)
* Monitor status of Sources and Clients using [webhooks (Gotify, Ntfy, Apprise)](https://docs.multi-scrobbler.app/configuration#webhook-configurations), [healthcheck endpoints](https://docs.multi-scrobbler.app/configuration#health-endpoint), or [prometheus metrics](https://docs.multi-scrobbler.app/configuration/#prometheus).
* Supports [Now Playing](https://docs.multi-scrobbler.app/configuration/clients#now-playing) for scrobble Clients
* Supports configuring for single or multiple users (scrobbling for your friends and family!)
* Web server interface for stats, basic control, and detailed logs
* Graceful network and client failure handling (queued scrobbles that auto-retry)
* Smart handling of credentials (persistent, authorization through app)
* Easy configuration through ENVs or JSON
* Install using [Docker images for x86/ARM](/docsite/docs/installation/installation.md#docker), [flatpak](/docsite/docs/installation/installation.md#flatpak), or [locally with NodeJS](/docsite/docs/installation/installation.md#nodejs)
* Easy configuration through [ENVs or JSON](ttps://foxxmd.github.io/multi-scrobbler/configuration#configuration-types)
* Modify data before scrobbling with [regular expression or search patterns](https://docs.multi-scrobbler.app/configuration/transforms)
* Install using [Docker images for x86/ARM](https://docs.multi-scrobbler.app/installation#docker) or [locally with NodeJS](https://docs.multi-scrobbler.app/installation#nodejs)
[**Quick Start Guide**](https://docs.multi-scrobbler.app//quickstart)
<img src="/docsite/static/img/status-ui.png" width="800">
**Why should I use this over a browser extension and/or mobile app scrobbler?**
@@ -44,17 +74,15 @@ A javascript app to scrobble music you listened to, to [Maloja](https://github.c
**But I already scrobble my music to Last.fm/ListenBrainz, is multi-scrobbler for me?**
Yes! You can use [Last.fm as a **Source**](/docsite/docs/configuration/configuration.md#lastfm--source-) or [Listenbrainz as a **Source**](/docsite/docs/configuration/configuration.md#listenbrainz--source-) to forward scrobbles from your profile to any other Client! That way you can keep your current scrobble setup as-is but still get the benefit of capturing your data to a self-hosted location.
<img src="/assets/status-ui.png" width="800">
Yes! You can use [Last.fm as a **Source**](https://docs.multi-scrobbler.app/configuration/sources/lastfm-source) or [Listenbrainz as a **Source**](https://docs.multi-scrobbler.app/configuration/sources/listenbrainz-source) to forward scrobbles from your profile to any other Client! That way you can keep your current scrobble setup as-is but still get the benefit of capturing your data to a self-hosted location.
## How Does multi-scrobbler (MS) Work?
You set up configurations for one or more **Sources** and one or more **Clients**. MS monitors all of your configured **Sources**. When new tracks are played by a Source it grabs that information and then sends it (scrobbles it) to all **Clients** that Source is configured to scrobble to.
You set up [configurations](https://docs.multi-scrobbler.app/configuration) for one or more [**Sources**](https://docs.multi-scrobbler.app/configuration/sources) and one or more [**Clients**](https://docs.multi-scrobbler.app/configuration/clients). MS monitors all of your configured **Sources**. When new tracks are played by a Source MS grabs that information and then sends it (scrobbles it) to all **Clients** that Source is configured to forward to.
### Source
A **Source** is a data source that contains information about tracks you are playing like a music player or platform. Examples are **Spotify, Jellyfin, Plex, Youtube Music, Airsonic**, etc...
A [**Source**](https://docs.multi-scrobbler.app/configuration/sources) is a data source that contains information about music you are playing or have listened to, such as: a desktop player, web music player, or cloud music service. Examples are **Spotify, Jellyfin, Plex, Youtube Music, Navidrome**, etc...
Source configurations consist of:
@@ -64,20 +92,24 @@ Source configurations consist of:
### Client
A **Client** is an application that stores the historical information about what songs you have played (scrobbles). Examples are **Maloja, Last.fm, Listenbrainz**...
A [**Client**](https://docs.multi-scrobbler.app/configuration/clients) is an application that stores the historical information about what music you have played (scrobbles). Examples are **Koito, Last.fm, Listenbrainz**...
Client configurations consist of:
* A friendly name.
* Any data needed to communicate or authenticate with the Client.
## Quick Start
[See the **Quick Start Guide**](https://docs.multi-scrobbler.app/quickstart)
## Installation
[See the **Installation** documentation](/docsite/docs/installation/installation.md)
[See the **Installation** documentation](https://docs.multi-scrobbler.app/installation)
## Configuration
[See the **Configuration** documentation](/docsite/docs/configuration/configuration.md)
[See the **Configuration** documentation](https://docs.multi-scrobbler.app/configuration)
## Usage
@@ -92,7 +124,11 @@ On first startup you may need to authorize Spotify and/or Last.fm by visiting th
## Help/FAQ
Having issues with connections or configuration? Check the [FAQ](/docsite/docs/FAQ.md) before creating an issue!
Having issues with connections or configuration? Check the [FAQ](https://docs.multi-scrobbler.app/FAQ) before creating an issue!
## Development
[Detailed architecture and development guides for Sources/Clients](https://docs.multi-scrobbler.app/development/dev-common)
## License
+1
View File
@@ -0,0 +1 @@
* Attribution for [`default-artwork.png`](/assets/default-artwork.png): https://www.flaticon.com/free-icon/music_15795471
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 KiB

+42 -29
View File
@@ -1,18 +1,20 @@
# configuration file for git-cliff (0.1.0)
# git-cliff ~ configuration file
# https://git-cliff.org/docs/configuration
[changelog]
# changelog header
# A Tera template to be rendered as the changelog's header.
# See https://keats.github.io/tera/docs/#introduction
header = """
# Changelog
# Changelog\n
All notable changes to this project will be documented in this file.\n
"""
# template for the changelog body
# https://tera.netlify.app/docs/#introduction
# A Tera template to be rendered for each release in the changelog.
# See https://keats.github.io/tera/docs/#introduction
body = """
{% if version %}\
## [{{ version | replace(from="v", to="") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
## {{ version | trim_start_matches(pat="v") }} - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [unreleased]
## Unreleased
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
@@ -24,6 +26,7 @@ body = """
{% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}}
{%- endif -%}
{%- endfor -%}
{% raw %}\n{% endraw %}\
{%- for commit in commits %}
{%- if commit.scope -%}
{% else -%}
@@ -33,35 +36,45 @@ body = """
{% endif -%}
{% endif -%}
{% endfor -%}
{% endfor %}
{% raw %}\n{% endraw %}\
{% endfor %}\n
"""
# remove the leading and trailing whitespaces from the template
trim = true
# changelog footer
# A Tera template to be rendered as the changelog's footer.
# See https://keats.github.io/tera/docs/#introduction
footer = """
<!-- generated by git-cliff -->
"""
# Remove leading and trailing whitespaces from the changelog's body.
trim = true
[git]
# allow only conventional commits
# https://www.conventionalcommits.org
# Parse commits according to the conventional commits specification.
# See https://www.conventionalcommits.org
conventional_commits = true
# regex for parsing and grouping commits
# Exclude commits that do not match the conventional commits specification.
filter_unconventional = true
# An array of regex based parsers for extracting data from the commit message.
# Assigns commits to groups.
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
commit_parsers = [
{ message = "^feat", group = "Features"},
{ message = "^fix", group = "Bug Fixes"},
{ message = "^doc", group = "Documentation"},
{ message = "^perf", group = "Performance"},
{ message = "^refactor", group = "Refactor"},
{ message = "^style", group = "Styling"},
{ message = "^test", group = "Testing"},
{ message = "^chore\\(release\\): prepare for", skip = true},
{ message = "^chore", group = "Miscellaneous Tasks"},
{ body = ".*security", group = "Security"},
{ message = "^feat", group = "⛰️ Features" },
{ message = "^fix", group = "🐛 Bug Fixes" },
{ message = "^doc", group = "📚 Documentation" },
{ message = "^perf", group = "Performance" },
{ message = "^refactor", group = "🚜 Refactor" },
{ message = "^style", group = "💅 Styling" },
{ message = "^test", group = "🧪 Testing" },
{ message = "^ci", group = "🧑‍🍳 Continuous Integration" },
{ message = "^build", group = "🐋 Build" },
{ message = "^chore\\(release\\)", skip = true },
{ message = "^chore", group = "⚙️ Miscellaneous Tasks" },
{ body = ".*security", group = "🛡️ Security" },
]
# filter out the commits that are not matched by commit parsers
# Exclude commits that are not matched by any commit parser.
filter_commits = false
# glob pattern for matching git tags
tag_pattern = "[0-9]*"
# regex for skipping tags
skip_tags = "v0.1.0-beta.1"
# Order releases topologically instead of chronologically.
topo_order = false
# Order of commits in each group/release within the changelog.
# Allowed values: newest, oldest
sort_commits = "oldest"
-217
View File
@@ -1,217 +0,0 @@
import {API, Collection, FileInfo, Options} from 'jscodeshift';
import path from 'path';
import fs from 'fs';
export type TransformFrom = 'none' | 'any' | string;
export type TransformTo = 'none' | 'any' | string;
export type ImportTypes = 'any' | 'relative' | 'alias';
const base = process.cwd();
export default function transformer(
file: FileInfo,
{ jscodeshift: j }: API,
options: Options,
) {
const tf = options.transformFrom as string | undefined;
if(tf === undefined) {
throw new Error(`arg '--transformFrom' must be defined.`);
}
const transformFrom = tf.split(',').map(x => x.toLocaleLowerCase()) as TransformFrom[];
const tfIsAny = transformFrom.includes('any');
const tt = options.transformTo as string | undefined;
if(tt === undefined) {
throw new Error(`arg '--transformTo' must be defined.`);
}
const transformTo = tt.split(',').map(x => x.toLocaleLowerCase()) as TransformTo[];
if(transformTo.length > 1 && transformFrom.length !== transformTo.length) {
throw new Error('When more than one Transform To is specified then number of Transform From arguments must match');
}
const itypes = options.importTypes as string | undefined;
if(itypes === undefined) {
throw new Error(`arg '--importTypes' must be defined.`);
}
const importTypes = itypes.split(',').map(x => x.toLocaleLowerCase()) as ImportTypes[];
const importsIsAny = importTypes.includes('any');
const fileDir = path.dirname(path.join(base, file.path));
const processingFilePath = file.path;
console.log(`Processing => ${processingFilePath}`);
let source: Collection<any>;
try {
source = j(file.source);
} catch (e) {
console.error(`Failed to parse ${processingFilePath}, will skip`);
console.error(e);
}
const imports = source.find(j.ImportDeclaration)
imports.forEach((x) => {
const importPath = x.value.source.value as string;
const importPathPrefix = `${importPath.padEnd(60, ' ')} =>`;
const pathInfo = path.parse(importPath);
const hasNoExt = pathInfo.ext === '';
let filenameFromDir: string;
if(tfIsAny || (hasNoExt && transformFrom.includes('none')) || (transformFrom.includes(pathInfo.ext.replace('.', '').toLocaleLowerCase()))) {
const pathFull = path.join(fileDir, importPath);
const dir = path.dirname(pathFull);
const normalExt = pathInfo.ext.replace('.', '');
let isRelative: boolean | undefined;
let dirExists: boolean | undefined;
let fileExists: boolean | undefined;
try {
// is dir path real?
fs.realpathSync(dir);
dirExists = true;
} catch (e) {
isRelative = false;
dirExists = false;
}
if(isRelative === undefined) {
// if extension is none we need to check for any file in dir with this name
if(hasNoExt) {
const dirFiles = fs.readdirSync(dir)
filenameFromDir = dirFiles.find(x => path.parse(x).name === pathInfo.name);
if(filenameFromDir !== undefined) {
fileExists = false;
isRelative = false;
} else {
fileExists = true;
isRelative = true;
}
} else {
try {
// does a file exist?
fs.realpathSync(pathFull);
isRelative = true;
} catch (e) {
isRelative = false;
fileExists = false;
}
}
}
if(!importsIsAny) {
if(!isRelative && !importTypes.includes('alias')) {
console.log(`${importPathPrefix} Import looks like an alias ${dirExists ? '(dir exists, file does not)' : '(dir does not exist)'} but import types does specify alias`);
return;
} else if(isRelative && !importTypes.includes('relative')) {
console.log(`${pathFull} => Import is relative but import types does not specify relative`);
return;
}
}
// determine transformTo
// if there is only one TO then use it
let derivedTT: undefined | string = transformTo.length === 1 ? transformTo[0] : undefined;
if(derivedTT === undefined) {
// otherwise we find the TO by using the same index as the matching FROM extension type
const tfIndex = transformFrom.findIndex((x) => {
if(x === 'any') {
return true;
}
if(x === 'none' && hasNoExt) {
return true;
}
if(x === normalExt) {
return true;
}
});
if(tfIndex === -1) {
console.warn(`${importPathPrefix} did not match a Transform From type. Will not transform`);
return;
}
derivedTT = transformTo[tfIndex];
}
let transformPrefix = ` --> ${hasNoExt ? '(None)' : normalExt} TO ${derivedTT} <--`;
let transformedImport: string;
switch(derivedTT) {
case 'none':
if(hasNoExt) {
console.log(`${importPathPrefix} ${transformPrefix} => Import already has no extension, nothing to do`);
return;
}
transformedImport = combineDirFile(pathInfo.dir, pathInfo.name); // path.join(pathInfo.root, pathInfo.dir, pathInfo.name);
break;
case 'any':
if(hasNoExt && filenameFromDir) {
transformedImport = filenameFromDir;
} else {
const otherFilename = fs.readdirSync(dir).find(x => {
const pinfo = path.parse(x);
return pinfo.name === pathInfo.name && pinfo.ext !== pathInfo.ext;
});
if(otherFilename === undefined) {
console.warn(`${importPathPrefix} ${transformPrefix} => Could not find another file in directory that had same name but different extension. Will not transform.`);
return;
}
transformedImport = combineDirFile(pathInfo.dir, otherFilename); // path.join(pathInfo.root, dir, otherFilename);
transformPrefix = `${transformPrefix} (${path.parse(otherFilename).ext})`
}
break;
default:
transformedImport = combineDirFile(pathInfo.dir, `.${derivedTT}`); // path.join(pathInfo.root, dir, pathInfo.name, `.${derivedTT}`);
break;
}
console.log(`${importPathPrefix} ${transformPrefix} => Replacing with ${transformedImport}`);
j(x).replaceWith(
j.importDeclaration(
x.node.specifiers,
j.stringLiteral(transformedImport)
)
);
} else {
console.log(`${importPathPrefix} Import did not match transformFrom ('${tf}')`);
return;
}
});
/**
* Early exit condition
* -----
* It is often good practice to exit early and return the original source file
* if it does not contain code relevant to the codemod.
* See this page for more information:
* https://codeshiftcommunity.github.io/CodeshiftCommunity/docs/your-first-codemod#output
*/
// if (/* Some condition here */ true) {
// return file.source;
// }
/**
* Codemod logic goes here 👇
* -----
* This is where the core logic for your codemod will go,
* consider grouping specific actions into 'motions' and running them in sequence
*
* See this page for more information:
* https://codeshiftcommunity.github.io/CodeshiftCommunity/docs/authoring#motions
*/
//source.findVariableDeclarators('foo').renameTo('bar');
/**
* Return your modified AST here 👇
* -----
* This is where your modified AST will be transformed back into a string
* and written back to the file.
*/
return source.toSource(options.printOptions);
}
const combineDirFile = (dir: string, file: string) => {
if(dir === '') {
return file;
}
return `${dir}${path.sep}${file}`;
}
+1 -1
View File
@@ -8,5 +8,5 @@ These are **NOT** exhaustive examples. You should consult the **configuration**
Documentation at
* [internal docs](../docsite/docs/configuration/configuration.md)
* [internal docs](../docsite/docs/configuration/configuration.mdx)
* External Link: https://foxxmd.github.io/multi-scrobbler/docs/configuration
+29
View File
@@ -0,0 +1,29 @@
[
{
"id": "myAppleMusic",
"name": "My Apple Music",
"enable": true,
"clients": [],
"data": {
// either key or token needs to be provided
"key": {
"id": "2HPSNJZ88N",
"teamId": "SN6YASW8G4",
"p8": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEG...-----END PRIVATE KEY-----"
},
"token": "your-jwt-token-here",
"mediaUserToken": "your-media-user-token-here",
// optional: Origin header for API requests (required when using a browser token)
"origin": "https://music.apple.com",
// optional: polling interval in seconds (default 60)
"interval": 60
},
"options": {
"logDiff": true,
"recoverUnchangedTopHistory": true,
"normalizeAlbum": true
}
}
]
+14
View File
@@ -0,0 +1,14 @@
[
{
"type": "azuracast",
"enable": true,
"name": "Cool Station",
"id": "myAzura",
"data": {
"url": "ws://192.168.0.101",
"station": "my-station-name",
"monitorWhenLive": true,
"monitorWhenListeners": 1
}
}
]
+12
View File
@@ -0,0 +1,12 @@
[
{
"name": "My Cast",
"id": "myCast",
"data": {
"blacklistedDevices": [],
"whitelistedDevices": [],
"blacklistedApps": [],
"whitelistedApps": []
}
}
]
+11 -10
View File
@@ -1,18 +1,17 @@
{
"debugMode": false,
"disableWeb": false,
"sourceDefaults": {
"maxPollRetries": 1,
"maxRequestRetries": 1,
"retryMultiplier": 1.5,
"logPayload": false,
"logFilterFailure": "warn",
"logPlayerState": false,
"scrobbleThresholds": {
"duration": 30,
"percent": 50
},
"options": {
"logPayload": false,
"logFilterFailure": "warn",
"logPlayerState": false
}
"maxPollRetries": 1,
"maxRequestRetries": 1,
"retryMultiplier": 1.5
},
"clientDefaults": {
"maxRequestRetries": 1,
@@ -23,7 +22,8 @@
"type": "spotify",
"enable": true,
"clients": ["myConfig"],
"name": "mySpotifySource",
"name": "Cool Spotify Name",
"id": "mySpotifyId",
"data": {
"clientId": "a89cba1569901a0671d5a9875fed4be1",
"clientSecret": "ec42e09d5ae0ee0f0816ca151008412a",
@@ -35,7 +35,8 @@
{
"type": "maloja",
"enable": true,
"name": "myConfig",
"name": "Foxx Maloja",
"id": "myMalojaId",
"data": {
"url": "http://localhost:42010",
"apiKey": "myMalojaKey"
+13
View File
@@ -0,0 +1,13 @@
[
{
"name": "DeezerOfficalDeprecated",
"enable": true,
"clients": [],
"data": {
"clientId": "a89cba1569901a0671d5a9875fed4be1",
"clientSecret": "ec42e09d5ae0ee0f0816ca151008412a",
"redirectUri": "http://localhost:9078/deezer/callback",
"interval": 60
}
}
]
+3 -5
View File
@@ -1,13 +1,11 @@
[
{
"name": "FoxxMDeezer",
"name": "Family Account",
"id": "myDeezerId",
"enable": true,
"clients": [],
"data": {
"clientId": "a89cba1569901a0671d5a9875fed4be1",
"clientSecret": "ec42e09d5ae0ee0f0816ca151008412a",
"redirectUri": "http://localhost:9078/deezer/callback",
"interval": 60
"arl": "UOsRPjT3U5Dhaaup3xQ30DWFoSgqugdSYzL3QE743waaVy2eur2ckyJcZ4RV123Q3PsbKXkLwA6ahc9XmEfev6BtfSP8LujE3JswWRQogZCDUOwVzWO5sAig",
}
}
]
+12
View File
@@ -0,0 +1,12 @@
[
{
"name": "Desktop",
"enable": true,
"id": "myDiscordLocal",
"data": {
"applicationId": "8190211179716453570",
"ipcLocations": ["192.168.0.105:6655"]
}
}
]
+11
View File
@@ -0,0 +1,11 @@
[
{
"name": "Discord",
"enable": true,
"id": "myDiscordRemote",
"data": {
"token": "Ma7XBvzRERK3gQdkX4dkb3OQ.6aaGmJ.rvFiiVrzG4VXHHL3LyhZYhpWdG3Ph_if9aKz5E",
"applicationId": "8190211179716453570"
}
}
]
+10
View File
@@ -0,0 +1,10 @@
[
{
"name": "LFM For App",
"enable": true,
"id": "myLfmApp",
"data": {
"slug": "mySlug"
}
}
]
+10
View File
@@ -0,0 +1,10 @@
[
{
"name": "LZ for Navidrome",
"id": "myLzNavidrome",
"enable": true,
"data": {
"token": "myToken"
}
}
]
+11
View File
@@ -0,0 +1,11 @@
[
{
"name": "Station 1",
"enable": true,
"id": "myIceStation1",
"data": {
"url": "http://myIcecast.com/radio"
}
}
]
+18 -5
View File
@@ -1,15 +1,28 @@
[
{
"name": "MyJellyfin",
"name": "Cool JF Server",
"enable": true,
"id": "myJellyfin",
"clients": [],
"data": {
"users": ["FoxxMD"],
"servers": ["myServer","anotherServer"]
"url": "http://localhost:8096",
"user": "FoxxMD",
"apiKey": "c9fae8756fbf481ebd9c5bb56bd6540c",
// everything below is optional
"usersAllow": ["FoxxMD","SomeOtherUser"],
"usersBlock": ["AnotherUser"],
"devicesAllow": ["firefox"],
"devicesBlock": ["google-home"],
"librariesAllow": ["GoodMusic"],
"librariesBlock": ["BadMusic"],
"additionalAllowedLibraryTypes": ["musicvideos"],
"allowMediaTypes": ["audio"],
"frontendUrlOverride": "https://myJellyfinExternal.tld"
},
"options": {
"logPayload": false,
"logFilterFailure": "warn"
"logPayload": true,
"logFilterFailure": "debug"
}
}
]
+2 -1
View File
@@ -1,6 +1,7 @@
[
{
"name": "MyJriver",
"name": "My JRiver Server",
"id": "myRiver",
"enable": true,
"data": {
"url": "0.0.0.0",
+2 -1
View File
@@ -1,6 +1,7 @@
[
{
"name": "MyKodi",
"name": "My Kodi Server",
"id": "myKodi",
"enable": true,
"data": {
"url": "http://localhost:8080/jsonrpc",
+22
View File
@@ -0,0 +1,22 @@
[
{
"name": "Koito Client A",
"id": "myKoitoClient",
"configureAs": "client",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "admin",
"url": "http://192.168.0.100:4110"
}
},
{
"name": "Koito Source B",
"id": "myKoitoSource",
"configureAs": "source",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "admin",
"url": "http://192.168.0.100:4110"
}
}
]
+13 -1
View File
@@ -1,6 +1,7 @@
[
{
"name": "myLastFm",
"name": "Foxx LFM Client",
"id": "myLastFmClient",
"enable": true,
"configureAs": "client",
"data": {
@@ -8,5 +9,16 @@
"secret": "ec42e09d5ae0ee0f0816ca151008412a",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
},
{
"name": "Foxx LFM Source",
"id": "myLastFmSource",
"enable": true,
"configureAs": "source",
"data": {
"apiKey": "a89cba1569901a0671d5a9875fed4be1",
"secret": "ec42e09d5ae0ee0f0816ca151008412a",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
}
]
+24
View File
@@ -0,0 +1,24 @@
[
{
"name": "Foxx Libre Client",
"id": "myLibreFmClient",
"enable": true,
"configureAs": "client",
"data": {
"apiKey": "anything",
"secret": "anything",
"redirectUri": "http://localhost:9078/librefm/callback"
}
},
{
"name": "Foxx Libre Source",
"id": "myLibreFmSource",
"enable": true,
"configureAs": "source",
"data": {
"apiKey": "anything",
"secret": "anything",
"redirectUri": "http://localhost:9078/librefm/callback"
}
}
]
+15 -2
View File
@@ -1,11 +1,24 @@
[
{
"name": "brainz",
"name": "Foxx LZ Client",
"id": "brainzClient",
"enable": true,
"configureAs": "client",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "FoxxMD"
"username": "FoxxMD",
"url": "https://api.listenbrainz.org"
}
},
{
"name": "Foxx LZ Source",
"id": "brainzSource",
"enable": true,
"configureAs": "source",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "FoxxMD",
"url": "https://api.listenbrainz.org"
}
}
]
+13 -1
View File
@@ -1,7 +1,19 @@
[
{
"name": "myMaloja",
"name": "Maloja Client",
"id": "myMalojaClient",
"enable": true,
"configureAs": "client",
"data": {
"url": "http://localhost:42010",
"apiKey": "myMalojaKey"
}
},
{
"name": "Maloja Source",
"id": "myMalojaSource",
"enable": true,
"configureAs": "source",
"data": {
"url": "http://localhost:42010",
"apiKey": "myMalojaKey"
+2 -1
View File
@@ -1,6 +1,7 @@
[
{
"name": "MyMopidy",
"name": "Mopidy Desktop",
"id": "MyMopidy",
"enable": true,
"data": {
"url": "localhost",
+14
View File
@@ -0,0 +1,14 @@
[
{
"enable": true,
"id": "myMPD",
"name": "Desktop",
"data": {
"url": "192.168.0.100:6600",
"password": "MY_PASSWORD"
},
"options": {
"disableDiscovery": false
}
}
]
+2 -1
View File
@@ -1,6 +1,7 @@
[
{
"name": "ubuntu",
"name": "Desktop",
"id": "myMprisUbuntu",
"enable": true,
"data": {
"whitelist": ["vlc", "mpd"],
+10
View File
@@ -0,0 +1,10 @@
[
{
"name": "Livingroom Reciever",
"id": "myYamaha",
"enable": true,
"data": {
"url": "192.168.0.101"
}
}
]
+12
View File
@@ -0,0 +1,12 @@
[
{
"type": "musikcube",
"enable": true,
"name": "Desktop",
"id": "myMusikcube",
"data": {
"url": "ws://localhost:7905",
"password": "MY_PASSWORD"
}
}
]
+15 -7
View File
@@ -1,15 +1,23 @@
[
{
"name": "MyPlex",
"name": "Foxx Plex",
"id": "MyPlexApi",
"enable": true,
"clients": [],
"data": {
"user": ["username@gmail.com","anotherUser@gmail.com"],
"libraries": ["music","my podcasts"],
"servers": ["myServer","anotherServer"],
"options": {
"logFilterFailure": "warn"
"token": "1234",
"url": "http://192.168.0.120:32400",
"usersAllow": ["FoxxMD","SomeOtherUser"],
"usersBlock": ["AnotherUser"],
"devicesAllow": ["firefox"],
"devicesBlock": ["google-home"],
"librariesAllow": ["GoodMusic"],
"librariesBlock": ["BadMusic"]
},
"options": {
"logPayload": true,
"logFilterFailure": "debug",
"ignoreInvalidCert": false
}
}
}
]
+20
View File
@@ -0,0 +1,20 @@
[
{
"id": "myRockskyClient",
"name": "FoxxMD Rocksky Client",
"configureAs": "client",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkaWQiOiJkaWQ6cGxjOng0NjVwZmtyeW5zaDZ...",
"handle": "alice.bsky.social"
}
},
{
"id": "myRockskySource",
"name": "FoxxMD Rocksky Source",
"configureAs": "source",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkaWQiOiJkaWQ6cGxjOng0NjVwZmtyeW5zaDZ...",
"handle": "alice.bsky.social"
}
}
]
+14
View File
@@ -0,0 +1,14 @@
[
{
"enable": true,
"id": "MySonos",
"name": "Boom 2",
"data": {
"host": "192.168.0.150",
"devicesAllow": ["move","beam"],
"devicesBlock": ["roam"],
"groupsAllow": ["family"],
"groupsBlock": ["bedroom"]
}
}
]
+2 -1
View File
@@ -1,6 +1,7 @@
[
{
"name": "MySpotify",
"id": "MySpotify",
"name": "Foxx Spotify",
"enable": true,
"clients": [],
"data": {
+5 -2
View File
@@ -1,11 +1,14 @@
[
{
"name": "MySubsonic",
"id": "mySubsonic",
"name": "Airsonic Server",
"enable": true,
"data": {
"url": "http://localhost:4040/airsonic",
"user": "yourUser",
"password": "yourPassword"
"password": "yourPassword",
"usersAllow": ["yourUser"],
"detectStaleNowPlayingFromMinutesAgo": true
}
}
]
-15
View File
@@ -1,15 +0,0 @@
[
{
"name": "MyTautuilli",
"enable": true,
"clients": [],
"data": {
"user": ["username@gmail.com","anotherUser@gmail.com"],
"libraries": ["music","my podcasts"],
"servers": ["myServer","anotherServer"],
"options": {
"logFilterFailure": "warn"
}
}
}
]
+24
View File
@@ -0,0 +1,24 @@
[
{
"id": "myTealClient",
"name": "Foxx Teal Client",
"configureAs": "client",
"data": {
"identifier": "alice.bsky.social",
"appPassword": "twog-phu7-4dhe-y4j3"
}
},
{
"id": "myTealSource",
"name": "Foxx Teal Source",
"configureAs": "source",
"data": {
"identifier": "alice.bsky.social",
"appPassword": "twog-phu7-4dhe-y4j3",
// everything below is optional
"serviceAllow": ["plyr"],
"serviceDeny": ["last.fm"]
}
}
]
+11
View File
@@ -0,0 +1,11 @@
[
{
"enable": true,
"id": "myVlc",
"name": "Desktop",
"data": {
"url": "localhost:8080",
"password": "changeme"
}
}
]
+3 -2
View File
@@ -1,8 +1,9 @@
[
{
"name": "MyWebScrobbler",
"id": "MyWebScrobbler",
"name": "Firefox Laptop",
"data": {
"slug": null,
"slug": "MyOptionalSlug",
"whitelist": [],
"blacklist": []
}
+12
View File
@@ -0,0 +1,12 @@
[
{
"id": "myYandex",
"name": "Yandex Music",
"type": "ymbridge",
"data": {
"url": "http://192.168.1.161:9980",
"apiKey": "change-me",
"interval": 3
}
}
]
+12 -3
View File
@@ -1,11 +1,20 @@
[
{
"name": "MyYTMusic",
"id": "myYtMusic",
"name": "Foxx YT Music",
"enable": true,
"clients": [],
"data": {
"cookie": "VISITOR_INFO1_LIVE=jMDXz2_L8rY; __Secure-3PAPISID=3AxsXpSXGqOInSDn1jEKn; DEVICE_INFO=ChxOekU0TmTBpjek5EWZ0G; YSC=7gZdl3Zdl3; SID=TwhNsaZRXYTAtXxzGyu6rZdpg2HvGROeW8J4Ym_FhkhoZMUYEQ.; __Secure-1PSID=TwhNOsaZRXYTyRBe4rxAtXRIKsIEtk_Qot2VLBNfHQrQ.; __Secure-3PSID=ZRXYTAtXRIKsIEtk_Qot2yRBerZdpg2HvvZRXYTAtXRIKsIEtk_Qot2yRBerkuZICFQ.; HSID=A1UMmELW79; SSID=AKhomOs; APISID=IlHHmuzkPdQzZZDhHn3; SAPISID=3AxsXpy0u75Qb/n1jEKn; __Secure-1PAPISID=3AxsXpQb/AkSDn1jEKn; LOGIN_INFO=AFmP6vFpyVCZZAIgDwbkhWMBBhluaIWAPP:QUQ314UW5NWMjNmd2ZUJnYnJsakdIMjZoaE5zVVMjNmd2ZZUiHRlb3ZlV3ZIcUVyRVIMjNmdjNmd2ZZUivYlNqX2ZNZUiHdUNFNFdaYmJIW1NkJRX3hqdlU2YnFESkFuSS1uTldnZVRmLXNjWFc5OUJuR3dTd3JsZGZYa2EtZFQ2a0k2Ry1KQQ==; PREF=volume=26; SIDCC=AFvI_94PxXwls-ndqpGfPgFX3FWj80y_94PxXwls-ndqfSh15sP; __Secure-1PSIDCC=AFvIBnUbRr96I96UCIp2U4T8HRVk2B0HfKzhzxwsiP; __Secure-3PSIDCC=AFvIB3bINuUN0ETDR9gO91wpwWIVmpGki3BxT3bINuUN0ETDR9gO91wCH",
"authUser": "0"
"cookie": "__Secure-1PSIDTS=sidts-CjEB3EgAEvCd-......",
// either cookie or id/secret needs to be provided
"clientId": "891098404....apps.googleusercontent.com",
"clientSecret": "GOCS..."
// optional
//"redirectUri": "http://my.custom.tld/api/ytmusic/callback?name=MyYTMusic"
},
"options": {
"logDiff": true
}
}
]
+26
View File
@@ -0,0 +1,26 @@
services:
multi-scrobbler:
volumes:
- kasm_run:/run
kasmcord:
container_name: kasmcord
image: kasmweb/discord:1.14.0
ports:
# VNC port to use in web browser
- 6901:6901
shm_size: 512m
environment:
# set a password for VNC access
VNC_PW: ${KASM_PW:-hunter2}
XDG_RUNTIME_DIR: /run/user/1000
volumes:
- kasm_run:/run/user/1000
- kasm_config:/home/kasm-user/.config
user: "0"
entrypoint: sh -c "chmod 700 /run/user/1000 && chown -R kasm-user:kasm-user /run/user/1000 && chown -R kasm-user:kasm-user /home/kasm-user/.config && su kasm-user -c '/dockerstartup/kasm_default_profile.sh /dockerstartup/vnc_startup.sh /dockerstartup/kasm_startup.sh'"
volumes:
kasm_run:
name: kasm_run
kasm_config:
name: kasm_config
+31
View File
@@ -0,0 +1,31 @@
version: '3.7'
services:
multi-scrobbler:
build:
context: .
args:
BUILD_DATE: "${BUILD_DATE}"
env_file:
- path: ./.env
required: false
#environment:
#- TZ=Etc/GMT # Specify timezone from TZ Database name found here https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
#- SPOTIFY_CLIENT_ID=
#- SPOTIFY_CLIENT_SECRET=
#- SPOTIFY_REDIRECT_URI=http://multi-scrobbler-host-IP:9078/callback ## Need to be whitelisted in Spotify dashboard and is used for creating the connection first time
#- MALOJA_URL=http://maloja:42010
#- MALOJA_API_KEY=
#- PUID=1000 # required if running docker on linux host, see main README Docker setup instructions
#- PGID=1000 # required if running docker on linux host, see main README Docker setup instructions
# set if using a source/client with redirect URI that you have not explicitly set and MS is NOT running on the same machine that you will view the dashboard from
# EX: You will view MS dashboard at 'http://192.168.0.101:9078' -> set BASE_URL=http://192.168.0.101:9078
#- BASE_URL=http://MyHostIP:9078
volumes:
- "./config:/config"
#networks:
# - (optional to add container to the same bridge network that maloja is inside to be able to use docker internal networking & dns to resolve and connect to maloja URL via http://maloja:port)
ports:
- 9078:9078 # first port is the HOST port multi-scrobbler will serve UI and API on
restart: unless-stopped
+4 -6
View File
@@ -1,14 +1,12 @@
version: '3.7'
services:
multi-scrobbler:
image: foxxmd/multi-scrobbler
container_name: multi-scrobbler
environment:
- TZ=Etc/GMT # Specify timezone from TZ Database name found here https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
#- SPOTIFY_CLIENT_ID=
#- SPOTIFY_CLIENT_SECRET=
#- SPOTIFY_REDIRECT_URI=http://multi-scrobbler-host-IP:9078/callback ## Need to be whitelisted in Spotify dashboard and is used for creating the connection first time
#- JELLYFIN_APIKEY=
#- JELLYFIN_URL=
#- JELLYFIN_USER=
#- MALOJA_URL=http://maloja:42010
#- MALOJA_API_KEY=
#- PUID=1000 # required if running docker on linux host, see main README Docker setup instructions
@@ -18,7 +16,7 @@ services:
# EX: You will view MS dashboard at 'http://192.168.0.101:9078' -> set BASE_URL=http://192.168.0.101:9078
#- BASE_URL=http://MyHostIP:9078
volumes:
- /path_on_host/multi-scrobbler-config:/config
- "./config:/config"
#networks:
# - (optional to add container to the same bridge network that maloja is inside to be able to use docker internal networking & dns to resolve and connect to maloja URL via http://maloja:port)
ports:
@@ -1,33 +1,19 @@
#!/usr/bin/with-contenv bash
# used https://github.com/linuxserver/docker-plex as a template
POPULATE_EXAMPLES=false
echo "-------------------------------------"
echo -e "Setting up multi-scrobbler config directory based on CONFIG_DIR env: ${CONFIG_DIR}\n"
echo -e "Verifying multi-scrobbler directory permissions based on CONFIG_DIR env: ${CONFIG_DIR} and DATA_DIR env: ${DATA_DIR}\n"
# make config folder if it does not exist
if [ ! -d "${CONFIG_DIR}" ]; then
echo "Directory does not exist! Creating..."
POPULATE_EXAMPLES=true
mkdir -p "${CONFIG_DIR}"
else
if [ "$(ls -A ${CONFIG_DIR})" ]; then
echo "Directory is not empty, not creating examples."
else
POPULATE_EXAMPLES=true
fi
if [ -d "${CONFIG_DIR}" ]; then
echo "chown'ing config directory to ensure correct permissions."
chown -R abc:abc "${CONFIG_DIR}"
echo "Done!"
fi
# add example configs
if [ "$POPULATE_EXAMPLES" = true ]; then
echo "Directory is empty, adding examples..."
cp -r /app/config/. "${CONFIG_DIR}"/
if [ -d "${DATA_DIR}" ]; then
echo "chown'ing data directory to ensure correct permissions."
chown -R abc:abc "${DATA_DIR}"
echo "Done!"
fi
# permissions
echo "chown'ing directory to ensure correct permissions."
chown -R abc:abc "${CONFIG_DIR}"
echo "Done!"
echo -e "-------------------------------------\n"
@@ -4,6 +4,7 @@
# NODE_ARGS can be passed by ENV in docker command like "docker run foxxmd/multi-scrobbler -e NODE_ARGS=--optimize_for_size"
echo -e "\nmulti-scrobbler is starting!"
export NODE_ENV=production
cd /app || exit
exec \
s6-setuidgid abc /usr/bin/node $NODE_ARGS /app/build/server.js
s6-setuidgid abc /usr/bin/node $NODE_ARGS /app/src/backend/index.ts
+1
View File
@@ -18,3 +18,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lib
-3
View File
@@ -1,3 +0,0 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};
+42
View File
@@ -0,0 +1,42 @@
import fs from 'node:fs/promises';
import path from 'node:path';
var args = process.argv.slice(2);
const linkRegex = new RegExp(/<link data-rh="true" rel="\w+"\shref="(https:\/\/foxxmd\.github\.io\/multi-scrobbler)/g,);
const replacement = process.env.CANONICAL_HREF ?? 'https://docs.multi-scrobbler.app';
/**
* Replace canonical and alternative <link> nodes with the "real" domain of the site
* so that SEO (google) chooses the correct domain when showing search results
*
*/
(async function () {
if(replacement === undefined || replacement === '') {
console.warn('No replacement value found in process.env.CANONICAL_HREF');
return;
}
const buildDir = path.resolve(args[0]);
console.log(`Reading dir recursively ${buildDir}`);
const files = (await fs.readdir(buildDir, { recursive: true })).filter(x => x.includes('.html'));
console.log(`Found ${files.length} files with .html extensions`);
let modifications = 0;
await Promise.all(files.map(async (x) => {
const filePath = path.resolve(path.join(buildDir, x));
//console.log(`Replacing at ${filePath}`);
await fs.writeFile(filePath, (await fs.readFile(filePath)).toString().replace(linkRegex, (match, capture, offset, string, groups) => {
// this may not be fully accurate since we're mutating concurrently/async
// but its a good enough signal for logging to tell if replacements happened
modifications++;
return match.replace(capture, replacement);
}));
}));
console.log(`Done with ${modifications} replacements`);
}());
+183 -95
View File
@@ -1,119 +1,54 @@
* [Connection Issues](#connection-issues)
* [Plex/Tautulli/Jellyfin don't connect](#plextautullijellyfin-dont-connect)
* [Jellyfin has warnings about undefined or missing data](#jellyfin-has-warnings-about-undefined-or-missing-data)
* [Jellyfin has warnings about missing headers](#jellyfin-has-warnings-about-missing-headers)
* [Spotify/Deezer/LastFM won't authenticate](#spotifydeezerlastfm-wont-authenticate)
* [Configuration Issues](#configuration-issues)
* [Config could not be parsed](#config-could-not-be-parsed)
* [Scrobbling Issues](#scrobbling-issues)
* [Last.fm does not scrobble tracks with multiple artists correctly](#lastfm-does-not-scrobble-tracks-with-multiple-artists-correctly)
* [Jellyfin does not scrobble tracks with multiple artists correctly](#jellyfin-does-not-scrobble-tracks-with-multiple-artists-correctly)
---
toc_min_heading_level: 2
toc_max_heading_level: 5
title: FAQ
---
# Connection Issues
## Connection Issues
## Plex/Tautulli/Jellyfin don't connect
### Webscrobbler/Listenbrainz Endpoint doesn't connect {#ingress-connection}
These three [sources](/#source) are **ingress-based** which means that multi-scrobbler waits for the Plex/Tautulli/Jellyfin server to contact multi-scrobbler, as opposed to multi-scrobbler contacting the server.
These sources are **ingress-based** which means that multi-scrobbler waits for the Webscrobbler extension or app using Listenbrainz Endpoint to contact multi-scrobbler, as opposed to multi-scrobbler contacting them.
multi-scrobbler will log information about any server that connects to it for these three services. In the logs it looks something like this:
multi-scrobbler will log information about any server that connects to it for these services. In the logs it looks something like this:
```
2023-02-22T10:55:56-05:00 info : [Ingress - Plex ] Received request from a new remote address: ::ffff:192.168.0.140 (UA: PlexMediaServer/1.24.5.5173-8dcc73a59)
2023-02-22T10:55:56-05:00 info : [Ingress - Plex ] ::ffff:192.168.0.140 (UA: PlexMediaServer/1.24.5.5173-8dcc73a59) Received valid data from server examplePlex for the first time.
2023-02-22T10:55:56-05:00 warn : [Plex Request ] Received valid Plex webhook payload but no Plex sources are configured
[2025-07-10 12:32:21.417 -0400] INFO : [App] [API] [Ingress] [WebScrobbler] [Ingress] [WebScrobbler] Received request from a new remote address: ::ffff:127.0.0.1 (192.168.0.100) (UA: Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0)
[2025-07-10 12:32:21.418 -0400] INFO : [App] [API] [Ingress] [WebScrobbler] [Ingress] [WebScrobbler] ::ffff:127.0.0.1 (192.168.0.100) (UA: Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0) Received data for API URL slug '(none)' for the first time.
```
It also logs if a server tries to connect to a URL that it does not recognize:
```
2023-02-22T11:16:12-05:00 debug : [App ] Server received POST request from ::ffff:192.168.0.140 (UA: PlexMediaServer/1.24.5.5173-8dcc73a59) to unknown route: /plkex
2023-02-22T11:16:12-05:00 debug : [App ] Server received POST request from ::ffff:192.168.0.100 (UA: PlexMediaServer/1.24.5.5173-8dcc73a59) to unknown route: /plkex
```
**So, if you do not see either of these in your logs then Plex/Tautulli/Jellyfin is not able to connect to your multi-scrobbler instance at all.**
**So, if you do not see either of these in your logs then the Source is not able to connect to your multi-scrobbler instance at all.**
This is not something multi-scrobbler can fix and means you have an issue in your network.
### Troubleshooting
#### Troubleshooting
Check or try all these steps before submitting an issue:
#### Turn on Debug Logging
##### Turn on Debug Logging
First, turn on **debug** logging for multi-scrobbler by setting the environmental variable `LOG_LEVEL=debug`:
First, turn on **debug** logging for multi-scrobbler by setting the environmental variable `DEBUG_MODE=true`. Then, check the output for any additional information.
* using node `LOG_LEVEL=debug ... node src/index.js`
* using docker `docker run -e LOG_LEVEL=debug ... foxxmd/multi-scrobbler`
##### Check Host name and URL
Check the output for any additional information.
The URLs examples in the [configuration](/configuration#base-url) documentation assume you are running Webscrobbler/LFM Endpoint on the same server as multi-scrobbler. If these are not the same machine then you need to determine the IP address or domain name that multi-scrobbler is reachable at and use that instead of `localhost` when configuring these sources. **This is likely the same host name that you would use to access the web interface for multi-scrobbler.**
#### Check Host name and URL
EX `http://localhost:9078/api/webscrobbler` -> `http://192.168.0.140:9078/api/webscrobbler`
The URLs examples in the [configuration](configuration/configuration.md) documentation assume you are running Plex/Tautulli/Jellyfin on the same server as multi-scrobbler. If these are not the same machine then you need to determine the IP address or domain name that multi-scrobbler is reachable at and use that instead of `localhost` when configuring these sources. **This is likely the same host name that you would use to access the web interface for multi-scrobbler.**
EX `http://localhost:9078/plex` -> `http://192.168.0.140:9078/plex`
#### Check Firewall and Port Forwarding
##### Check Firewall and Port Forwarding
If the machine multi-scrobbler is running on has a firewall ensure that port **9078** is open. Or if it is in another network entirely make sure your router is forwarding this port and it is open to the correct machine.
#### Check Source Service Logs
##### Check Source Service Logs
Plex/Tautulli/Jellyfin all have logs that will log if they cannot connect to multi-scrobbler. Check these for further information.
###### Webscrobbler
##### Plex
See [Debugging the extension](https://github.com/web-scrobbler/web-scrobbler/wiki/Debug-the-extension) to get logs which should have information about failed requests.
Settings -> Manage -> Console
##### Tautulli
Check the command-line output of the application or docker logs.
##### Jellyfin
Administration -> Dashboard -> Advanced -> Logs
## Jellyfin has warnings about undefined or missing data
Make sure you have
* [Configured the webhook plugin correctly](configuration/configuration.md#jellyfin)
* Checked the **Send All Properties(ignores template)** option in the webhook settings and **Saved**
multi-scrobbler is known to work on Jellyfin `10.8.9` with Webhook version `11.0.0.0`.
You can verify the payload sent from the webhook by modifying your jellyfin configuration to include `logPayload: true` which will output the raw payload to DEBUG level logging:
```json
[
{
"name": "MyJellyfin",
"clients": [],
"data": {
"users": ["FoxxMD"],
"options": {
"logPayload": true
}
}
}
]
```
If your issue persists and you open an Issue for it please include the raw payload logs in your report.
## Jellyfin has warnings about missing headers
If you experience issues trying to scrobble with Jellyfin and find this in your MS logs
```
[API] Jellyfin is not sending a request with valid headers...
```
A workaround that may fix this:
* In Webhook settings:
* [In the webhook you have already configured...](configuration/configuration.md#jellyfin)
* Add Request Header...
* **Key:** `Content-Type`
* **Value:** `application/json`
* Then Save
## Spotify/Deezer/LastFM won't authenticate
### Spotify/Deezer/LastFM won't authenticate
Ensure any **client id** or **secrets** are correct in your configuration.
@@ -126,9 +61,46 @@ If multi-scrobbler is not running on the same machine your browser is on then th
EX `http://localhost:9078/lastfm/callback` -> `http://192.168.0.220:9078/lastfm/callback`
# Configuration Issues
### I get errors with `ECONNRESET` `ETIMEDOUT` `ENOTFOUND` `EAI_AGAIN`
## Config could not be parsed
These are errors indicating a network issue is occuring between you and the Source/Client.
* `ECONNRESET` means the upstream service unexpectedly closed the connection
* `ETIMEDOUT` means the upstream service did not respond to a request MS
* `ENOTFOUND` means that MS could not find a DNS record for the domain of the upstream service
* `EAI_AGAIN` means that a DNS server did not respond to MS's request to lookup the record for a domain
`ECONNRESET` and timeout issues can occur when you have a poor connection or if the upstream service is overloaded or is generally not behaving well. This is a common occurrence for Listenbrainz/Musicbrainz related requests.
Please check the [Upstream Services Status Page](https://status.multi-scrobbler.app) to independently verify if the service is misbehaving. If the service is up and has good uptime then the issue may be in your network.
`ENOTFOUND` and `EAI_AGAIN` and generally caused by DNS caching (stale records) or misbehaving DNS servers. Though this can happen at the upstream service's end, it is *usually* an issue in your network. If you run a Pihole, AdGaurd, or other DNS solution try flushing the cache for the mishaving domain and check that your DNS application is working correctly.
### Youtube Music fails after some time
If you see errors in multi-scrobbler for YTM that contain **401** or **403** like
```
Error: Could not send the specified request to browse. Status code: 401
```
then YTM has invalidated your authentication.
First, ensure you are NOT using [YoutubeTV authentication.](/configuration/sources/youtube-music?ytmAuth=ytt#ytm-auth) If you completed authentication by entering a "User Code" you are using YoutubeTV which has stopped working. You should reauthenticate using **Cookies** or **Custom OAuth.**
#### When using OAuth Client Authentication
Refresh your authentication by using the **(Re)authenticate** link from MS's web dashboard.
#### When using Cookies Authentication
The library MS uses relies on scraping the YTM site by using cookies from your actual browser to pretend it is a browser. It does its best to keep these up to date but since this is not an official way to access the service YTM may invalidate your access _to the authenticated session_ at any time. How this is triggered is unknown and not something multi-scrobbler can control. You can help limit the chance of your session being invalidated by [getting the cookie from an Incognito/Private Session](https://github.com/LuanRT/YouTube.js/issues/803#issuecomment-2504032666) and then immediately closing the browser afterwards.
To re-authenticate MS [follow the YTM instructions to retrieve a new set of cookies for multi-scrobbler](/configuration/sources/youtube-music?ytmAuth=cookie#ytm-auth) and then restart MS to potentially resolve the problem.
## Configuration Issues
### Config could not be parsed
If you see something like this in your logs:
@@ -140,14 +112,130 @@ If you see something like this in your logs:
It means the JSON in your configuration file is not valid. Copy and paste your configuration into a site like [JSONLint](https://jsonlint.com/) to find out where errors you have and fix them.
# Scrobbling Issues
## Scrobbling Issues
## Last.fm does not scrobble tracks with multiple artists correctly
### How do I prevent duplicate scrobbles?
Multi-scrobbler has a [robust duplicate scrobble detection system](/configuration/duplicates#how-duplicates-are-detected) that should handle this for you in the majority of usecases. If you have a [simple setup without any circular dependencies](/configuration/duplicates#valid-configs) then you are already protected against duplicates.
If your scenario is more complex or you have a service(s) acting as **both** a **Client** and **Source** you should refer to the [**Duplicate Scrobble Guidance**](/configuration/duplicates#valid-configs) page to determine if you can avoid a configuration that may result in duplicate scrobbles.
### Last.fm does not scrobble tracks with multiple artists correctly
This is a limitation of the [Last.fm API](https://www.last.fm/api/show/track.scrobble) where the **artist** field is only one string and Last.fm does not recognize (play well) with "combined" artists.
Multi-scrobbler works the same was the official Spotify-Last.fm integration works -- it only scrobbles the **first** artist on a multi-artist track.
## Jellyfin does not scrobble tracks with multiple artists correctly
### Google Cast track information is missing/incorrect or MS player has weird times
This is a limitation caused by the [Jellyfin webhook plugin](https://github.com/FoxxMD/multi-scrobbler/issues/70#issuecomment-1443804712) only sending the first artist to multi-scrobbler. This issues needs to be [fixed upstream on the Jellyfin webhook repository.](https://github.com/jellyfin/jellyfin-plugin-webhook/issues/166)
The Google Cast integration relies on a few common fields in the data it receives from your casting device. Every platform that can cast (Spotify, Pandora, etc...) *should* use these fields the same but there are slight differences between their implementations that may confuse multi-scrobbler. Specific platforms may also return more information in non-common fields that are undocumented.
To diagnose these issues you [**must enable payload logging**](/configuration/sources/google-cast#cast-troubleshooting) for your google cast Source, run MS, and then include logs with this output from that run. Without the raw data logged from your cast device it will be nearly impossible to resolve your issue.
### Google Cast device does not track media
It is likely the app playing on the cast device is incorrectly reporting the media type as **not music**.
MS logs will tell you what type the media is reported as with lines like:
```
My Artist - Example Track has 'unknown' media type and allowUnknownMedia=false, will not track
```
Refer to [Allow Unknown Media Type](/configuration/sources/google-cast#allow-unknown-media-type) section to fix this
```
My Artist - Example Track has 'movie' media type so will not track
```
Refer to [Force Media Tracking](/configuration/sources/google-cast#forcing-media-tracking) section to fix this
### VLC is not scrobbling fields correctly
Before reporting an issue turn on metadata logging in the MS VLC configuration, [see the VLC documentation.](/configuration/sources/vlc#vlc-information-reporting)
### Youtube Music misses or duplicates scrobbles
<details>
<summary>How MS detects YTM history</summary>
In order for multi-scrobbler to accurately determine if a song has been scrobbled it needs **a source of truth.** For YTM this is a "history" list scraped from the YTM website. Unfortunately, the data in this list can be (often) inconsistent which makes it hard for multi-scrobbler to "trust" that it is correct and determine when/if new scrobbles occur. This inconsistency is not something multi-scrobbler can control -- it is a side-effect of having to use an unofficial method to access YTM (scraping).
To compensate for this multi-scrobbler resets when it considers this list the "source of truth" based on if the list changes in an inconsistent way between consecutive checks. New scrobbles can only be detected when this list is "OK" as a source of truth for N+1 checks. Therefore, any new tracks that appear when the list is inconsistent will be ignored.
Duplicate scrobbles can also occur if the change between two checks is technically consistent. For instance, if you listen to a track twice in some period, separated by other music, YTM will sometimes "remove" the track from the earlier time (further down in your history) and "re-add" it at the top of the history.
</details>
#### Reporting YTM scrobble issues
If you experience scrobble detection issues you can help improve MS's YTM heureistic by providing thorough feedback as [an issue.](https://github.com/FoxxMD/multi-scrobbler/issues/new?assignees=&labels=bug&projects=&template=01-bug-report.yml&title=bug%3A+) **Please do the following to provide the most useful report:**
##### Turn on Change Detection
In your YTM configuration (`ytmusic.json`) add `logDiff` under `options` like this:
```json
{
"type": "ytmusic",
"name": "MyYTM",
"data": { ... },
"options": {
"logDiff": true
}
}
```
or set either ENVs:
* `YTM_LOG_DIFF=true`
* [`DEBUG_MODE=true`](/configuration#debug-mode)
This will cause MS to log YTM history changes similar to this:
```
[Ytmusic - MyYTM] Changes from last seen list:
1. (tuhe1CpHRxY) KNOWER - Im The President --- undefined => Moved - Originally at 6
2. (Mtg8V6Xa2nc) Vulfpeck - Romanian Drinking Song --- Schvitz => Moved - Originally at 1
3. (rxbCaiyYSXM) Nightmares On Wax - You Wish --- In A Space Outta Sound => Moved - Originally at 2
4. (tMt_YXr90AM) Gorillaz - O Green World --- undefined => Moved - Originally at 3
...
```
Which are essential to troubleshooting this behavior.
##### Turn on File Logging
Optionally, if your logs are busy due to many other sources, you can log **only** YTM logs to a file. Turn this on with the `logToFile` config option:
```json
{
"type": "ytmusic",
"name": "MyYTM",
"data": { ... },
"options": {
"logDiff": true,
"logToFile": true
}
}
```
This will cause MS to write YTM logs to a file in your `logs` folder named `ytmusic-MyYTM.log` (based on your source name).
##### Provide Detail and Context
Provide a detailed account of how you were using YTM when the issue occurred, including things like:
* the platform listening on (desktop, mobile, 3rd party client, etc...)
* any changes in platform
* > I switched from desktop to listening on my phone...
* how you were listening to music
* > I was playing an album start to finish
* > I listened to two songs in a row, then browsed for a new song in library by artist, then went back to a song in the queue...
Explain the expected behavior (it should have scrobbled songs x, y, then z) and what actually happened (it scrobbled songs x, then y, then x again, then z)
Provide ALL logs from the time when the issue occurred including logs from BEFORE (ideally 2-3 minutes of logs) and AFTER the issue.
+3 -3
View File
@@ -1,8 +1,8 @@
{
"label": "Configuration",
"position": 2,
"position": 5,
"link": {
"type": "generated-index",
"description": "Configuring Multi-Scrobbler and examples"
"type": "doc",
"id": "configuration/configuration"
}
}
@@ -0,0 +1,177 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="configType" queryString>
<TabItem value="file" label="File">
Using [File Config](/configuration/?configType=file#configuration-types)
```json5 title="CONFIG_DIR/jellyin.json"
[
{
"id": "fredJf",
"name": "Freds Jellyfin",
"clients": ["fredLFM"],
"data": {
"url": "https://jellyfin.fred.com",
"user": "Fred",
"apiKey": "c9fae8756fbf481ebd9c5bb56bd6540c"
}
},
{
"id": "maryJf",
"name": "Marys Jellyfin",
"clients": ["maryLFM"],
"data": {
"url": "https://jellyfin.mary.com",
"user": "Mary",
"apiKey": "26fe9c5dc6374542adc4f4d5e8352838"
}
}
]
```
```json5 title="CONFIG_DIR/plex.json"
[
{
"id": "foxxPlex",
"name": "Foxx Plex",
"clients": ["foxxKoi"],
"data": {
"token": "JtRnwQWD__XMJF8sT3jc",
"url": "192.168.0.233:32400"
}
}
]
```
```json5 title="CONFIG_DIR/lastfm.json"
[
{
"id": "maryLFM",
"name": "Marys Lastfm",
"configureAs": "client",
"data": {
"apiKey": "maryApiKey",
"secret": "marySecret",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
},
{
"id": "fredLFM",
"name": "Freds Lastfm",
"configureAs": "client",
"data": {
"apiKey": "fredApiKey",
"secret": "fredSecret",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
}
]
```
```json5 title="CONFIG_DIR/koito.json"
[
{
"id": "foxxKoi",
"name": "Foxx Koito",
"configureAs": "client",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "admin",
"url": "http://192.168.0.100:4110"
}
}
]
```
</TabItem>
<TabItem value="aio" label="AIO">
Using [AIO Config](/configuration/?configType=aio#configuration-types)
```json5 title="CONFIG_DIR/config.json"
{
"sources": [
{
"type": "jellyfin",
"id": "fredJf",
"name": "Freds Jellyfin",
"clients": [
"fredLFM"
],
"data": {
"url": "https://jellyfin.fred.com",
"user": "Fred",
"apiKey": "c9fae8756fbf481ebd9c5bb56bd6540c"
}
},
{
"type": "jellyfin",
"id": "maryJf",
"name": "Marys Jellyfin",
"clients": [
"maryLFM"
],
"data": {
"url": "https://jellyfin.mary.com",
"user": "Mary",
"apiKey": "26fe9c5dc6374542adc4f4d5e8352838"
}
},
{
"type": "plex",
"id": "foxxPlex",
"name": "Foxx Plex",
"clients": [
"foxxKoi"
],
"data": {
"token": "JtRnwQWD__XMJF8sT3jc",
"url": "192.168.0.233:32400",
"usersallow": [
"foxx"
]
}
}
],
"clients": [
{
"type": "lastfm",
"id": "maryLFM",
"name": "Marys Lastfm",
"configureAs": "client",
"data": {
"apiKey": "maryApiKey",
"secret": "marySecret",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
},
{
"type": "lastfm",
"id": "fredLFM",
"name": "Freds Lastfm",
"configureAs": "client",
"data": {
"apiKey": "fredApiKey",
"secret": "fredSecret",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
},
{
"type": "koito",
"id": "foxxKoi",
"name": "Foxx Koito",
"configureAs": "client",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "admin",
"url": "http://192.168.0.100:4110"
}
}
]
}
```
</TabItem>
</Tabs>
@@ -0,0 +1,196 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs groupId="configType" queryString>
<TabItem value="env" label="ENV">
Using [ENV Config](/configuration/?configType=env#configuration-types)
```yaml title="compose.yaml"
services:
multi-scrobbler:
image: foxxmd/multi-scrobbler
container_name: multi-scrobbler
environment:
- TZ=Etc/GMT # Specify timezone from TZ Database name found here https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# spotify
- SPOTIFY_ID=foxxSpotify
- SPOTIFY_CLIENT_ID=H2UvGv8okrFlv2OUoc1lAtK7Xe5EGDgs
- SPOTIFY_CLIENT_SECRET=HvoFE5Ce2hdblNE6vaFBEx6dRVcDdo43
- SPOTIFY_REDIRECT_URI=https://multiscrobbler.example.com/callback
# navidrome listenbrainz endpoint
- LZE_ID=myLzNavidrome
- LZE_TOKEN=myToken
# plex
- PLEX_ID=foxxPlex
- PLEX_URL=192.168.0.233:32400
- PLEX_TOKEN=JtRnwQWD__XMJF8sT3jc
- PLEX_USERS_ALLOW=foxx
- PLEX_LIBRARIES_ALLOW=oldies
# lastfm
- LASTFM_ID=myLFM
- LASTFM_API_KEY=myApiKey
- LASTFM_SECRET=mySecret
- LASTFM_REDIRECT_URI=https://multiscrobbler.example.com/lastfm/callback
# koito
- KOITO_ID=foxxKoi
- KOITO_TOKEN=029b081ba-9156-4pe7-88e5-3be671f5ea2b
- KOITO_USER=admin
- KOITO_URL=http://192.168.0.100:4110
volumes:
- "./config:/config"
ports:
- "9078:9078"
restart: unless-stopped
```
</TabItem>
<TabItem value="file" label="File">
Using [File Config](/configuration/?configType=file#configuration-types)
```json5 title="CONFIG_DIR/spotify.json"
[
{
"id": "foxxSpotify",
"name": "Foxx Spotify",
"data": {
"clientId": "a89cba1569901a0671d5a9875fed4be1",
"clientSecret": "ec42e09d5ae0ee0f0816ca151008412a",
"redirectUri": "http://localhost:9078/callback",
"interval": 60
}
}
]
```
```json5 title="CONFIG_DIR/endpointlz.json"
[
{
"id": "myLzNavidrome",
"name": "LZ for Navidrome",
"data": {
"token": "myToken"
}
}
]
```
```json5 title="CONFIG_DIR/plex.json"
[
{
"id": "foxxPlex",
"name": "Foxx Plex",
"data": {
"token": "JtRnwQWD__XMJF8sT3jc",
"url": "192.168.0.233:32400",
"usersallow": ["foxx"],
"librariesAllow": ["oldies"],
}
}
]
```
```json5 title="CONFIG_DIR/lastfm.json"
[
{
"id": "myLFM",
"name": "Old Lastfm",
"configureAs": "client",
"data": {
"apiKey": "myApiKey",
"secret": "mySecret",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
}
]
```
```json5 title="CONFIG_DIR/koito.json"
[
{
"id": "foxxKoi",
"name": "Foxx Koito",
"configureAs": "client",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "admin",
"url": "http://192.168.0.100:4110"
}
}
]
```
</TabItem>
<TabItem value="aio" label="AIO">
Using [AIO Config](/configuration/?configType=aio#configuration-types)
```json5 title="CONFIG_DIR/config.json"
{
"sources": [
{
"type": "spotify",
"id": "foxxSpotify",
"name": "Foxx Spotify",
"data": {
"clientId": "a89cba1569901a0671d5a9875fed4be1",
"clientSecret": "ec42e09d5ae0ee0f0816ca151008412a",
"redirectUri": "http://localhost:9078/callback",
"interval": 60
}
},
{
"type": "endpointlz",
"name": "LZ for Navidrome",
"id": "myLzNavidrome",
"data": {
"token": "myToken"
}
},
{
"type": "plex",
"id": "foxxPlex",
"name": "Foxx Plex",
"data": {
"token": "JtRnwQWD__XMJF8sT3jc",
"url": "192.168.0.233:32400",
"usersallow": ["foxx"],
"librariesAllow": ["oldies"]
}
}
],
"clients": [
{
"type": "lastfm",
"id": "myLFM",
"name": "Old Lastfm",
"configureAs": "client",
"data": {
"apiKey": "myApiKey",
"secret": "mySecret",
"redirectUri": "http://localhost:9078/lastfm/callback"
}
},
{
"type": "koito",
"id": "foxxKoi",
"name": "Foxx Koito",
"configureAs": "client",
"data": {
"token": "029b081ba-9156-4pe7-88e5-3be671f5ea2b",
"username": "admin",
"url": "http://192.168.0.100:4110"
}
}
]
}
```
</TabItem>
</Tabs>

Some files were not shown because too many files have changed in this diff Show More