Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
FoxxMD committed Jan 10, 2024
2 parents af037ee + a6ddc2b commit 4bd996e
Show file tree
Hide file tree
Showing 44 changed files with 1,205 additions and 452 deletions.
20 changes: 20 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## 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)

## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## Describe your changes



## Issue number and link, if applicable

8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Creating a Pull Request

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`.
* Ensure that if your code is covered by [an existing test](./src/backend/tests) that you have updated the test accordingly
2 changes: 1 addition & 1 deletion config/webscrobbler.json.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[
{
"name": "MyWebScrobbler",
"slug": null,
"data": {
"slug": null,
"whitelist": [],
"blacklist": []
}
Expand Down
44 changes: 24 additions & 20 deletions docsite/docs/configuration/configuration.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions flatpak/io.github.foxxmd.multiscrobbler.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
</screenshot>
</screenshots>
<releases>
<release version="0.6.3" date="2024-01-10"/>
<release version="0.6.2" date="2023-11-29"/>
<release version="0.6.1" date="2023-10-24"/>
<release version="0.6.0" date="2023-10-04"/>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "multi-scrobbler",
"version": "0.6.2",
"version": "0.6.3",
"description": "scrobble plays from multiple sources to multiple clients",
"scripts": {
"schema": "npm run -s schema-aio & npm run -s schema-source & npm run -s schema-client & npm run -s schema-aiosource & npm run -s schema-aioclient",
Expand All @@ -12,7 +12,7 @@
"typedoc": "typedoc",
"circular": "madge --circular --extensions ts src/index.ts",
"test": "react-scripts test",
"test:backend": "mocha --extension ts --reporter spec --recursive src/backend/tests/scrobbler/**/*.test.ts",
"test:backend": "mocha --extension ts --reporter spec --recursive src/backend/tests/**/*.test.ts",
"eject": "react-scripts eject",
"dev": "concurrently -p name -c \"yellow,magenta,blue\" -n \"webpack-server,nodemon-server,CRA\" \"npm run dev:server:webpack\" \"npm run dev:server:nodemon\" \"npm run dev:client\"",
"dev:client": "BROWSER=none REACT_APP_VERSION=$npm_package_version react-scripts start",
Expand Down
4 changes: 3 additions & 1 deletion register.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ tsNode.register({
project: './src/backend/tsconfig.json'
});

process.env.CONSOLE_LEVEL = parseBool(process.env.DEBUG_MODE) ? undefined : 'false';
if(!parseBool(process.env.DEBUG_MODE)) {
process.env.CONSOLE_LEVEL = 'false';
}
process.env.FILE_LEVEL = 'false';
9 changes: 8 additions & 1 deletion src/backend/common/schema/aio.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,8 +1335,15 @@
"LogOptions": {
"properties": {
"console": {
"$ref": "#/definitions/LogLevel",
"description": "Specify the minimum log level streamed to the console (or docker container)",
"enum": [
"debug",
"error",
false,
"info",
"verbose",
"warn"
],
"title": "console"
},
"file": {
Expand Down
10 changes: 6 additions & 4 deletions src/backend/common/vendor/LastfmApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {DEFAULT_RETRY_MULTIPLIER, FormatPlayObjectOptions} from "../infrastructu
import { LastfmData } from "../infrastructure/config/client/lastfm";
import { PlayObject } from "../../../core/Atomic";
import {isNodeNetworkException} from "../errors/NodeErrors";
import {nonEmptyStringOrDefault, splitByFirstFound} from "../../../core/StringUtils";
import {source} from "common-tags";

const badErrors = [
'api key suspended',
Expand Down Expand Up @@ -61,7 +63,7 @@ export default class LastfmApiClient extends AbstractApiClient {
mbid,
} = obj;
// arbitrary decision yikes
let artistStrings = artists !== undefined ? artists.split(',') : [artistName];
let artistStrings = splitByFirstFound(artists, [','], [artistName]);
return {
data: {
artists: [...new Set(artistStrings)] as string[],
Expand All @@ -71,9 +73,9 @@ export default class LastfmApiClient extends AbstractApiClient {
playDate: time !== undefined ? dayjs.unix(time) : undefined,
meta: {
brainz: {
album: albumMbid === '' ? undefined : albumMbid,
artist: artistMbid === '' ? undefined : artistMbid,
track: mbid === '' ? undefined : mbid
album: nonEmptyStringOrDefault<undefined>(albumMbid),
artist: splitByFirstFound<undefined>(artistMbid, [',',';'], undefined),
track: nonEmptyStringOrDefault<undefined>(mbid)
}
}
},
Expand Down
39 changes: 37 additions & 2 deletions src/backend/common/vendor/ListenbrainzApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
parseTrackCredits,
uniqueNormalizedStrArr
} from "../../utils/StringUtils";
import {UpstreamError} from "../errors/UpstreamError";
import {getScrobbleTsSOCDate} from "../../utils/TimeUtils";


export interface ArtistMBIDMapping {
Expand Down Expand Up @@ -137,7 +139,40 @@ export class ListenbrainzApiClient extends AbstractApiClient {
} catch (e) {
const {
message,
err,
status,
response: {
body = undefined,
text = undefined,
} = {}
} = e;
// TODO check err for network exception
if(status !== undefined) {
const msgParts = [`(HTTP Status ${status})`];
// if the response is 400 then its likely there was an issue with the data we sent rather than an error with the service
let showStopper = status !== 400;
if(body !== undefined) {
if(typeof body === 'object') {
if('code' in body) {
msgParts.push(`Code ${body.code}`);
}
if('error' in body) {
msgParts.push(`Error => ${body.error}`);
}
if('message' in body) {
msgParts.push(`Message => ${body.error}`);
}
// if('track_metadata' in body) {
// msgParts.push(`Track Metadata => ${JSON.stringify(body.track_metadata)}`);
// }
} else if(typeof body === 'string') {
msgParts.push(`Response => ${body}`);
}
} else if (text !== undefined) {
msgParts.push(`Response => ${text}`);
}
throw new UpstreamError(`Listenbrainz API Request Failed => ${msgParts.join(' | ')}`, {cause: e, showStopper});
}
throw e;
}
}
Expand Down Expand Up @@ -241,15 +276,15 @@ export class ListenbrainzApiClient extends AbstractApiClient {
}
} = play;
return {
listened_at: (playDate ?? dayjs()).unix(),
listened_at: getScrobbleTsSOCDate(play).unix(),
track_metadata: {
artist_name: artists[0],
track_name: track,
release_name: album,
additional_info: {
duration: play.data.duration !== undefined ? Math.round(duration) : undefined,
track_mbid: brainz.track,
artist_mbids: brainz.artist !== undefined ? [brainz.artist] : undefined,
artist_mbids: brainz.artist,
release_mbid: brainz.album,
release_group_mbid: brainz.releaseGroup
}
Expand Down
35 changes: 10 additions & 25 deletions src/backend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const configDir = process.env.CONFIG_DIR || path.resolve(projectDir, `./config`)
initServer(logger, output);

if(process.env.IS_LOCAL === 'true') {
logger.info('multi-scrobbler can be run as a background service! See: https://github.com/FoxxMD/multi-scrobbler/blob/develop/docs/service.md');
logger.info('multi-scrobbler can be run as a background service! See: https://foxxmd.github.io/multi-scrobbler/docs/installation/service');
}

if(appConfigFail !== undefined) {
Expand All @@ -98,6 +98,11 @@ const configDir = process.env.CONFIG_DIR || path.resolve(projectDir, `./config`)
await scrobbleClients.buildClientsFromConfig(notifiers);
if (scrobbleClients.clients.length === 0) {
logger.warn('No scrobble clients were configured!')
} else {
logger.info('Starting scrobble clients...');
}
for(const client of scrobbleClients.clients) {
await client.initScrobbleMonitoring();
}

const scrobbleSources = root.get('sources');//new ScrobbleSources(localUrl, configDir);
Expand All @@ -116,30 +121,10 @@ const configDir = process.env.CONFIG_DIR || path.resolve(projectDir, `./config`)
let anyNotReady = false;
for (const source of scrobbleSources.sources.filter(x => x.canPoll === true)) {
await sleep(1500); // stagger polling by 1.5 seconds so that log messages for each source don't get mixed up
switch (source.type) {
case 'spotify':
if ((source as SpotifySource).spotifyApi !== undefined) {
if ((source as SpotifySource).spotifyApi.getAccessToken() === undefined) {
anyNotReady = true;
} else {
(source as SpotifySource).poll();
}
}
break;
case 'lastfm':
if(source.initialized === true) {
source.poll();
}
break;
default:
if (source.poll !== undefined) {
source.poll();
}
}
}
for(const client of scrobbleClients.clients) {
if((await client.isReady())) {
client.initScrobbleMonitoring();
if(source.isReady()) {
source.poll();
} else {
anyNotReady = true;
}
}
if (anyNotReady) {
Expand Down
Loading

0 comments on commit 4bd996e

Please sign in to comment.