mirror of
https://github.com/FoxxMD/multi-scrobbler.git
synced 2026-10-19 07:13:55 +00:00
Merge pull request #754 from FoxxMD/deezerExtraInfo
Some checks are pending
Publish Docker image to Dockerhub / test (push) Waiting to run
Publish Docker image to Dockerhub / Build OCI Images (push) Blocked by required conditions
Publish Docker image to Dockerhub / Build OCI Images-1 (push) Blocked by required conditions
Publish Docker image to Dockerhub / Merge OCI Images and Push (push) Blocked by required conditions
Some checks are pending
Publish Docker image to Dockerhub / test (push) Waiting to run
Publish Docker image to Dockerhub / Build OCI Images (push) Blocked by required conditions
Publish Docker image to Dockerhub / Build OCI Images-1 (push) Blocked by required conditions
Publish Docker image to Dockerhub / Merge OCI Images and Push (push) Blocked by required conditions
feat(deezer): Add additional data to deezer plays
This commit is contained in:
commit
aab24819a2
3 changed files with 28 additions and 8 deletions
|
|
@ -5,4 +5,5 @@
|
|||
| `DEEZER_ENABLE` | boolean | true | Should this component be used? |
|
||||
| _**`DEEZER_ARL`**_ | string | | ARL retrieved from Deezer response header |
|
||||
| `DEEZER_ACCOUNT_ID` | string | | The ID (USER_ID) of the linked account to monitor. |
|
||||
| `DEEZER_USER_AGENT` | string | Mozilla/5.0 (X11; Linux i686; rv:135.0) Gecko/20100101 Firefox/135.0 | User agent |
|
||||
| `DEEZER_USER_AGENT` | string | Mozilla/5.0 (X11; Linux i686; rv:135.0) Gecko/20100101 Firefox/135.0 | User agent |
|
||||
| `DEEZER_TRACK_VARIANT` | boolean | false | |
|
||||
|
|
@ -2,6 +2,7 @@ import * as z from "zod";
|
|||
import type {Second} from "../../../../../core/Atomic.ts";
|
||||
import {pollingOptionsSchema} from "../common.ts";
|
||||
import {commonSourceConfigSchema, commonSourceDataSchema, commonSourceOptionsSchema, type EnvSourceSchema} from "./index.ts";
|
||||
import { envMetaNormalize } from "../../../../utils/ZodUtils.ts";
|
||||
|
||||
export const deezerDataSchema = z.object({
|
||||
...commonSourceDataSchema.shape,
|
||||
|
|
@ -80,7 +81,9 @@ export const deezerInternalDataSchema = z.object({
|
|||
export type DeezerInternalData = z.infer<typeof deezerInternalDataSchema>;
|
||||
|
||||
export const deezerInternalSourceOptionsSchema = z.object({
|
||||
...commonSourceOptionsSchema.shape,
|
||||
variant: z.boolean().optional().meta({
|
||||
description: 'Add the reported title variant, like `(Remastered)`, to the title name.',
|
||||
}),
|
||||
/**
|
||||
* Set the heuristic level of duplicate/repeated track pruning from listening history.
|
||||
*
|
||||
|
|
@ -90,6 +93,7 @@ export const deezerInternalSourceOptionsSchema = z.object({
|
|||
* * `aggressive` => above AND check for plays during previous play times that occurred during the track (50% +/- duration plus playedAt date)
|
||||
*/
|
||||
fuzzyDiscoveryIgnore: z.union([z.boolean(), z.literal('aggressive')]).optional(),
|
||||
...commonSourceOptionsSchema.shape,
|
||||
});
|
||||
|
||||
export type DeezerInternalSourceOptions = z.infer<typeof deezerInternalSourceOptionsSchema>;
|
||||
|
|
@ -116,7 +120,8 @@ export type DeezerCompatConfig = z.infer<typeof deezerCompatConfigSchema>;
|
|||
const envDataSchema = z.object({
|
||||
DEEZER_ARL: deezerInternalDataSchema.shape.arl,
|
||||
DEEZER_ACCOUNT_ID: deezerInternalDataSchema.shape.accountId,
|
||||
DEEZER_USER_AGENT: deezerInternalDataSchema.shape.userAgent
|
||||
DEEZER_USER_AGENT: deezerInternalDataSchema.shape.userAgent,
|
||||
DEEZER_TRACK_VARIANT: z.stringbool().optional().meta(envMetaNormalize(deezerInternalSourceOptionsSchema.shape.variant.meta()))
|
||||
});
|
||||
|
||||
export const envSchemas: EnvSourceSchema<typeof envDataSchema, DeezerInternalSourceConfig> = {
|
||||
|
|
@ -154,6 +159,12 @@ export interface DeezerInternalTrackData {
|
|||
SNG_TITLE: string
|
||||
/** Time listened to track in seconds */
|
||||
DURATION: Second
|
||||
/** The variant of the Song Title
|
||||
*
|
||||
* @example (Remastered)
|
||||
*/
|
||||
VERSION?: string
|
||||
ISRC?: string
|
||||
|
||||
__TYPE__: 'song' | string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { withAlbumArt } from "../../core/MusicMetadata.ts";
|
||||
import { isrcMeta, withAlbumArt } from "../../core/MusicMetadata.ts";
|
||||
import dayjs from "dayjs";
|
||||
import type EventEmitter from "events";
|
||||
import type { Request } from 'superagent';
|
||||
|
|
@ -7,7 +7,7 @@ import { COMPONENT_AUTH_TYPE, type ComponentAuthType, PARSED_FROM, type PlayMatc
|
|||
import { DEFAULT_RETRY_MULTIPLIER, type FormatPlayObjectOptions, type InternalConfig } from "../common/infrastructure/Atomic.ts";
|
||||
import type {DeezerInternalSourceConfig, DeezerInternalTrackData} from "../common/infrastructure/config/source/deezer.ts";
|
||||
import { TRANSFORM_HOOK } from "../../core/Transform.ts";
|
||||
import { parseRetryAfterSecsFromObj, playObjDataMatch, sleep, sortByOldestPlayDate} from "../utils.ts";
|
||||
import { getNonEmptyString, parseRetryAfterSecsFromObj, playObjDataMatch, sleep, sortByOldestPlayDate} from "../utils.ts";
|
||||
import type {RecentlyPlayedOptions} from "./AbstractSource.ts";
|
||||
import { CookieJar } from 'tough-cookie';
|
||||
import { MixedCookieAgent } from 'http-cookie-agent/http';
|
||||
|
|
@ -114,13 +114,21 @@ export default class DeezerInternalSource extends MemorySource {
|
|||
this.agent = request.agent().use((req) => req.agent(mixedAgent));
|
||||
}
|
||||
|
||||
static formatPlayObj(obj: DeezerInternalTrackData, options: FormatPlayObjectOptions = {}): PlayObject {
|
||||
static formatPlayObj(obj: DeezerInternalTrackData, options: FormatPlayObjectOptions & {variant?: boolean} = {}): PlayObject {
|
||||
const {newFromSource = false} = options;
|
||||
const trackParts: string[] = [obj.SNG_TITLE];
|
||||
if(options.variant === true) {
|
||||
const v = getNonEmptyString(obj.VERSION);
|
||||
if(v !== undefined) {
|
||||
trackParts.push(v);
|
||||
}
|
||||
}
|
||||
|
||||
const play: PlayObjectMinimal = {
|
||||
data: {
|
||||
artists: namesToCredits([obj.ART_NAME]),
|
||||
album: nameToCredit(obj.ALB_TITLE),
|
||||
track: nameToCredit(obj.SNG_TITLE),
|
||||
track: nameToCredit(trackParts.join(' '), isrcMeta(getNonEmptyString(obj.ISRC))),
|
||||
duration: obj.DURATION,
|
||||
playDate: dayjs(obj.TS * 1000),
|
||||
},
|
||||
|
|
@ -244,7 +252,7 @@ export default class DeezerInternalSource extends MemorySource {
|
|||
this.logger.debug(`Ignoring ${nonSong.length} entries in history with types of ${nonSongTypes.join(',')}`);
|
||||
}
|
||||
return resp.results.data.filter(x => x.__TYPE__ === 'song').map(x => {
|
||||
const play = DeezerInternalSource.formatPlayObj(x);
|
||||
const play = DeezerInternalSource.formatPlayObj(x, {variant: this.config.options?.variant});
|
||||
play.meta.parsedFrom = PARSED_FROM.history;
|
||||
return play;
|
||||
}).sort(sortByOldestPlayDate);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue