Ability to enable/disable reporting of now playing and scrobbling

This commit is contained in:
simojenki
2021-07-08 16:48:02 +10:00
parent f7a1b3f52c
commit 9823665601
4 changed files with 104 additions and 26 deletions

View File

@@ -95,6 +95,8 @@ BONOB_SONOS_SERVICE_NAME | bonob | service name for sonos
BONOB_SONOS_SERVICE_ID | 246 | service id for sonos BONOB_SONOS_SERVICE_ID | 246 | service id for sonos
BONOB_NAVIDROME_URL | http://$(hostname):4533 | URL for navidrome BONOB_NAVIDROME_URL | http://$(hostname):4533 | URL for navidrome
BONOB_NAVIDROME_CUSTOM_CLIENTS | undefined | Comma delimeted mime types for custom navidrome clients when streaming. ie. "audio/flac,audio/ogg" would use client = 'bonob+audio/flac' for flacs, and 'bonob+audio/ogg' for oggs. BONOB_NAVIDROME_CUSTOM_CLIENTS | undefined | Comma delimeted mime types for custom navidrome clients when streaming. ie. "audio/flac,audio/ogg" would use client = 'bonob+audio/flac' for flacs, and 'bonob+audio/ogg' for oggs.
BONOB_SCROBBLE_TRACKS | true | Whether to scrobble the playing of a track if it has been played for >30s
BONOB_REPORT_NOW_PLAYING | true | Whether to report a track as now playing
## Initialising service within sonos app ## Initialising service within sonos app

View File

@@ -4,12 +4,13 @@ import { appendMimeTypeToClientFor, DEFAULT, Navidrome } from "./navidrome";
import encryption from "./encryption"; import encryption from "./encryption";
import { InMemoryAccessTokens, sha256 } from "./access_tokens"; import { InMemoryAccessTokens, sha256 } from "./access_tokens";
import { InMemoryLinkCodes } from "./link_codes"; import { InMemoryLinkCodes } from "./link_codes";
import config from "./config"; import readConfig from "./config";
import sonos, { bonobService } from "./sonos"; import sonos, { bonobService } from "./sonos";
import { MusicService } from "./music_service";
logger.info( const config = readConfig();
`Starting bonob with config ${JSON.stringify(config)}`
); logger.info(`Starting bonob with config ${JSON.stringify(config)}`);
const bonob = bonobService( const bonob = bonobService(
config.sonos.serviceName, config.sonos.serviceName,
@@ -20,17 +21,45 @@ const bonob = bonobService(
const sonosSystem = sonos(config.sonos.deviceDiscovery, config.sonos.seedHost); const sonosSystem = sonos(config.sonos.deviceDiscovery, config.sonos.seedHost);
const streamUserAgent = config.navidrome.customClientsFor ? appendMimeTypeToClientFor(config.navidrome.customClientsFor.split(",")) : DEFAULT; const streamUserAgent = config.navidrome.customClientsFor
? appendMimeTypeToClientFor(config.navidrome.customClientsFor.split(","))
: DEFAULT;
const navidrome = new Navidrome(
config.navidrome.url,
encryption(config.secret),
streamUserAgent
);
const featureFlagAwareMusicService: MusicService = {
generateToken: navidrome.generateToken,
login: (authToken: string) =>
navidrome.login(authToken).then((library) => {
return {
...library,
scrobble: (id: string) => {
if (config.scrobbleTracks) return library.scrobble(id);
else {
logger.info("Track Scrobbling not enabled")
return Promise.resolve(false);
}
},
nowPlaying: (id: string) => {
if (config.reportNowPlaying) return library.nowPlaying(id);
else {
logger.info("Reporting track now playing not enabled");
return Promise.resolve(false);
}
},
};
}),
};
const app = server( const app = server(
sonosSystem, sonosSystem,
bonob, bonob,
config.webAddress, config.webAddress,
new Navidrome( featureFlagAwareMusicService,
config.navidrome.url,
encryption(config.secret),
streamUserAgent
),
new InMemoryLinkCodes(), new InMemoryLinkCodes(),
new InMemoryAccessTokens(sha256(config.secret)) new InMemoryAccessTokens(sha256(config.secret))
); );

View File

@@ -1,30 +1,36 @@
import { hostname } from "os"; import { hostname } from "os";
import logger from "./logger"; import logger from "./logger";
const port = +(process.env["BONOB_PORT"] || 4534); export default function () {
const webAddress = const port = +(process.env["BONOB_PORT"] || 4534);
const webAddress =
process.env["BONOB_WEB_ADDRESS"] || `http://${hostname()}:${port}`; process.env["BONOB_WEB_ADDRESS"] || `http://${hostname()}:${port}`;
if (webAddress.match("localhost")) { if (webAddress.match("localhost")) {
logger.error("BONOB_WEB_ADDRESS containing localhost is almost certainly incorrect, sonos devices will not be able to communicate with bonob using localhost, please specify either public IP or DNS entry"); logger.error(
"BONOB_WEB_ADDRESS containing localhost is almost certainly incorrect, sonos devices will not be able to communicate with bonob using localhost, please specify either public IP or DNS entry"
);
process.exit(1); process.exit(1);
} }
export default { return {
port, port,
webAddress, webAddress,
secret: process.env["BONOB_SECRET"] || "bonob", secret: process.env["BONOB_SECRET"] || "bonob",
sonos: { sonos: {
serviceName: process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob", serviceName: process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob",
deviceDiscovery: (process.env["BONOB_SONOS_DEVICE_DISCOVERY"] || "true") == "true", deviceDiscovery:
(process.env["BONOB_SONOS_DEVICE_DISCOVERY"] || "true") == "true",
seedHost: process.env["BONOB_SONOS_SEED_HOST"], seedHost: process.env["BONOB_SONOS_SEED_HOST"],
autoRegister: process.env["BONOB_SONOS_AUTO_REGISTER"] == "true", autoRegister: process.env["BONOB_SONOS_AUTO_REGISTER"] == "true",
sid: Number(process.env["BONOS_SONOS_SERVICE_ID"] || "246") sid: Number(process.env["BONOS_SONOS_SERVICE_ID"] || "246"),
}, },
navidrome: { navidrome: {
url: process.env["BONOB_NAVIDROME_URL"] || `http://${hostname()}:4533`, url: process.env["BONOB_NAVIDROME_URL"] || `http://${hostname()}:4533`,
customClientsFor: process.env["BONOB_NAVIDROME_CUSTOM_CLIENTS"] || undefined, customClientsFor:
} process.env["BONOB_NAVIDROME_CUSTOM_CLIENTS"] || undefined,
},
scrobbleTracks: (process.env["BONOB_SCROBBLE_TRACKS"] || "true") == "true",
reportNowPlaying: (process.env["BONOB_REPORT_NOW_PLAYING"] || "true") == "true",
};
} }

41
tests/config.test.ts Normal file
View File

@@ -0,0 +1,41 @@
import config from "../src/config";
describe("config", () => {
const OLD_ENV = process.env;
beforeEach(() => {
jest.resetModules();
process.env = { ...OLD_ENV };
});
afterEach(() => {
process.env = OLD_ENV;
});
function describeBooleanConfigValue(name : string, envVar: string) {
describe(name, () => {
function expecting({
value,
expected,
}: {
value: string;
expected: boolean;
}) {
describe(`when value is ${value}`, () => {
it(`should be ${expected}`, () => {
process.env[envVar] = value;
expect((config() as any)[name]).toEqual(expected);
});
});
}
expecting({ value: "", expected: true });
expecting({ value: "true", expected: true });
expecting({ value: "false", expected: false });
expecting({ value: "foo", expected: false });
});
};
describeBooleanConfigValue("scrobbleTracks", "BONOB_SCROBBLE_TRACKS");
describeBooleanConfigValue("reportNowPlaying", "BONOB_REPORT_NOW_PLAYING");
});