mirror of
https://github.com/FoxxMD/multi-scrobbler.git
synced 2026-10-19 07:13:55 +00:00
fix remaining erasure issues
This commit is contained in:
parent
69b19da6aa
commit
77de2a7526
4 changed files with 35 additions and 36 deletions
|
|
@ -1,13 +1,12 @@
|
|||
import { findCauseByFunc } from "../../utils/ErrorUtils.js";
|
||||
import { isArbitraryObject } from "../infrastructure/Atomic.js";
|
||||
import ErrnoException = NodeJS.ErrnoException;
|
||||
|
||||
export type NodeNetworkErrorCode = 'ENOTFOUND' | 'ETIMEDOUT' | 'EAI_AGAIN' | 'ECONNRESET' | 'ECONNREFUSED' | 'ERRADDRINUSE' | 'EADDRNOTAVAIL' | 'ECONNABORTED' | 'EHOSTUNREACH';
|
||||
export const NETWORK_ERROR_CODES: NodeNetworkErrorCode[] = ['ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN', 'ECONNRESET', 'ECONNREFUSED', 'ERRADDRINUSE', 'EADDRNOTAVAIL', 'ECONNABORTED', 'EHOSTUNREACH'];
|
||||
|
||||
export const NETWORK_ERROR_FAILURE_CODES: NodeNetworkErrorCode[] = ['ENOTFOUND', 'EAI_AGAIN', 'ECONNRESET', 'ECONNREFUSED', 'ERRADDRINUSE', 'EADDRNOTAVAIL', 'ECONNABORTED', 'EHOSTUNREACH'];
|
||||
|
||||
export const isErrnoException = (error: unknown): error is ErrnoException => {
|
||||
export const isErrnoException = (error: unknown): error is NodeJS.ErrnoException => {
|
||||
return isArbitraryObject(error) &&
|
||||
error instanceof Error &&
|
||||
(typeof error.errno === "number" || typeof error.errno === "undefined") &&
|
||||
|
|
@ -16,7 +15,7 @@ export const isErrnoException = (error: unknown): error is ErrnoException => {
|
|||
(typeof error.syscall === "string" || typeof error.syscall === "undefined");
|
||||
}
|
||||
|
||||
export interface NodeNetworkException extends ErrnoException {
|
||||
export interface NodeNetworkException extends NodeJS.ErrnoException {
|
||||
code: NodeNetworkErrorCode
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { type Logger } from '@foxxmd/logging';
|
||||
import { Dayjs, type ManipulateType } from "dayjs";
|
||||
import type { Logger } from '@foxxmd/logging';
|
||||
import type { Dayjs, ManipulateType } from "dayjs";
|
||||
import { type Request, type Response } from "express";
|
||||
import { type NextFunction, type ParamsDictionary, type Query } from "express-serve-static-core";
|
||||
import type { NextFunction, ParamsDictionary, Query } from "express-serve-static-core";
|
||||
import { FixedSizeList } from 'fixed-size-list';
|
||||
import { type ErrorLike, isPlayObject, type PlayMeta, type PlayObject, type PlayObjectMinimal, type UnixTimestamp } from "../../../core/Atomic.js";
|
||||
import TupleMap from "../TupleMap.js";
|
||||
import { MusicBrainzApi } from 'musicbrainz-api';
|
||||
import { type SourceType } from './config/source/sources.js';
|
||||
import type { SourceType } from './config/source/sources.js';
|
||||
import { type ClientType, clientTypes } from './config/client/clients.js';
|
||||
import assert, { AssertionError } from 'assert';
|
||||
import assert from 'assert';
|
||||
|
||||
export const lowGranularitySources: SourceType[] = ['subsonic', 'ytmusic'];
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,12 @@ import { readJson } from '../utils/DataUtils.js';
|
|||
import { findCauseByFunc } from "../utils/ErrorUtils.js";
|
||||
import { joinedUrl } from "../utils/NetworkUtils.js";
|
||||
import { type RecentlyPlayedOptions } from "./AbstractSource.js";
|
||||
import AlbumObjectSimplified = SpotifyApi.AlbumObjectSimplified;
|
||||
import ArtistObjectSimplified = SpotifyApi.ArtistObjectSimplified;
|
||||
import CurrentlyPlayingObject = SpotifyApi.CurrentlyPlayingObject;
|
||||
import PlayHistoryObject = SpotifyApi.PlayHistoryObject;
|
||||
import TrackObjectFull = SpotifyApi.TrackObjectFull;
|
||||
import UserDevice = SpotifyApi.UserDevice;
|
||||
// import SpotifyApi.AlbumObjectSimplified = SpotifyApi.SpotifyApi.AlbumObjectSimplified;
|
||||
// import SpotifyApi.ArtistObjectSimplified = SpotifyApi.SpotifyApi.ArtistObjectSimplified;
|
||||
// import SpotifyApi.CurrentlyPlayingObject = SpotifyApi.SpotifyApi.CurrentlyPlayingObject;
|
||||
// import SpotifyApi.PlayHistoryObject = SpotifyApi.SpotifyApi.PlayHistoryObject;
|
||||
// import SpotifyApi.TrackObjectFull = SpotifyApi.SpotifyApi.TrackObjectFull;
|
||||
// import SpotifyApi.UserDevice = SpotifyApi.SpotifyApi.UserDevice;
|
||||
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";
|
||||
import { baseFormatPlayObj } from "../utils/PlayTransformUtils.js";
|
||||
import { createGetScrobblesForTimeRangeFunc } from "../utils/ListenFetchUtils.js";
|
||||
|
|
@ -81,14 +81,14 @@ export default class SpotifySource extends MemoryPositionalSource implements Pag
|
|||
this.getScrobblesForTimeRange = createGetScrobblesForTimeRangeFunc(this, this.logger);
|
||||
}
|
||||
|
||||
static formatPlayObj(obj: PlayHistoryObject | CurrentlyPlayingObject, options: FormatPlayObjectOptions = {}): PlayObject {
|
||||
static formatPlayObj(obj: SpotifyApi.PlayHistoryObject | SpotifyApi.CurrentlyPlayingObject, options: FormatPlayObjectOptions = {}): PlayObject {
|
||||
|
||||
const {
|
||||
newFromSource = false
|
||||
} = options;
|
||||
|
||||
let artists: ArtistObjectSimplified[];
|
||||
let album: AlbumObjectSimplified;
|
||||
let artists: SpotifyApi.ArtistObjectSimplified[];
|
||||
let album: SpotifyApi.AlbumObjectSimplified;
|
||||
let name: string;
|
||||
let duration_ms: number;
|
||||
let played_at: Dayjs;
|
||||
|
|
@ -165,11 +165,11 @@ export default class SpotifySource extends MemoryPositionalSource implements Pag
|
|||
isrc
|
||||
} = {},
|
||||
track_number
|
||||
} = item as TrackObjectFull;
|
||||
} = item as SpotifyApi.TrackObjectFull;
|
||||
|
||||
delete (obj.item as TrackObjectFull).available_markets;
|
||||
if((obj.item as TrackObjectFull).album !== undefined) {
|
||||
delete (obj.item as TrackObjectFull).album.available_markets;
|
||||
delete (obj.item as SpotifyApi.TrackObjectFull).available_markets;
|
||||
if((obj.item as SpotifyApi.TrackObjectFull).album !== undefined) {
|
||||
delete (obj.item as SpotifyApi.TrackObjectFull).album.available_markets;
|
||||
}
|
||||
|
||||
scrobbleTsSOC = SCROBBLE_TS_SOC_START;
|
||||
|
|
@ -196,7 +196,7 @@ export default class SpotifySource extends MemoryPositionalSource implements Pag
|
|||
images = []
|
||||
} = album || {};
|
||||
|
||||
let actualAlbumArtists: ArtistObjectSimplified[] = [];
|
||||
let actualAlbumArtists: SpotifyApi.ArtistObjectSimplified[] = [];
|
||||
if ((artists.length !== albumArtists.length) || !artists.every(artist => albumArtists.some(albumArtist => artist.id === albumArtist.id))) {
|
||||
// only include album artists if they are not the EXACT same as the track artists
|
||||
// ...if they aren't the exact same then include all artists, even if they are duplicates of track artists
|
||||
|
|
@ -438,7 +438,7 @@ export default class SpotifySource extends MemoryPositionalSource implements Pag
|
|||
const result = await this.callApi<ReturnType<typeof this.spotifyApi.getMyRecentlyPlayedTracks>>((api: SpotifyWebApi) => api.getMyRecentlyPlayedTracks(options));
|
||||
|
||||
let more = true;
|
||||
let plays = result.body.items.map((x: PlayHistoryObject) => SpotifySource.formatPlayObj(x)).sort(sortByOldestPlayDate);
|
||||
let plays = result.body.items.map((x: SpotifyApi.PlayHistoryObject) => SpotifySource.formatPlayObj(x)).sort(sortByOldestPlayDate);
|
||||
|
||||
if(to !== undefined) {
|
||||
const toDate = dayjs.unix(to);
|
||||
|
|
@ -455,7 +455,7 @@ export default class SpotifySource extends MemoryPositionalSource implements Pag
|
|||
}
|
||||
|
||||
return {
|
||||
data: result.body.items.map((x: PlayHistoryObject) => SpotifySource.formatPlayObj(x)).sort(sortByOldestPlayDate),
|
||||
data: result.body.items.map((x: SpotifyApi.PlayHistoryObject) => SpotifySource.formatPlayObj(x)).sort(sortByOldestPlayDate),
|
||||
meta: {
|
||||
...params,
|
||||
total: result.body.total,
|
||||
|
|
@ -493,7 +493,7 @@ export default class SpotifySource extends MemoryPositionalSource implements Pag
|
|||
return undefined;
|
||||
}
|
||||
|
||||
getCurrentPlaybackState = async (logError = true): Promise<{device?: UserDevice, playerState?: PlayerStateData}> => {
|
||||
getCurrentPlaybackState = async (logError = true): Promise<{device?: SpotifyApi.UserDevice, playerState?: PlayerStateData}> => {
|
||||
try {
|
||||
const funcState = (api: SpotifyWebApi) => api.getMyCurrentPlaybackState();
|
||||
const res = await this.callApi<ReturnType<typeof this.spotifyApi.getMyCurrentPlaybackState>>(funcState);
|
||||
|
|
@ -634,9 +634,9 @@ export default class SpotifySource extends MemoryPositionalSource implements Pag
|
|||
protected getBackloggedPlays = async (options: RecentlyPlayedOptions = {}) => await this.getPlayHistory({formatted: true, ...options})
|
||||
}
|
||||
|
||||
const asPlayHistoryObject = (obj: object): obj is PlayHistoryObject => 'played_at' in obj
|
||||
const asPlayHistoryObject = (obj: object): obj is SpotifyApi.PlayHistoryObject => 'played_at' in obj
|
||||
|
||||
const asCurrentlyPlayingObject = (obj: object): obj is CurrentlyPlayingObject => 'is_playing' in obj
|
||||
const asCurrentlyPlayingObject = (obj: object): obj is SpotifyApi.CurrentlyPlayingObject => 'is_playing' in obj
|
||||
|
||||
const hasApiPermissionError = (e: Error): boolean => findCauseByFunc(e, (err) => err.message.includes('Permissions missing')) !== undefined
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { type LogDataPretty, type LogLevel } from "@foxxmd/logging";
|
||||
import { Dayjs } from "dayjs";
|
||||
import { type AdditionalTrackInfoResponse } from "../backend/common/vendor/listenbrainz/interfaces.js";
|
||||
import type { DeepOmit, Merge, RequiredKeys, StrictOmit } from "ts-essentials";
|
||||
import { type ErrorObject } from "serialize-error";
|
||||
import { type PlayPlatformIdStr } from "../backend/common/infrastructure/Atomic.js";
|
||||
import { type FlowControlTerm, type TransformHook } from "../backend/common/infrastructure/Transform.js";
|
||||
import { type Changeset } from "json-diff-ts";
|
||||
import {type IParseBaseOptions } from 'qs';
|
||||
import type { LogDataPretty, LogLevel } from "@foxxmd/logging";
|
||||
import type { Dayjs } from "dayjs";
|
||||
import type { AdditionalTrackInfoResponse } from "../backend/common/vendor/listenbrainz/interfaces.js";
|
||||
import type { Merge, RequiredKeys, StrictOmit } from "ts-essentials";
|
||||
import type { ErrorObject } from "serialize-error";
|
||||
import type { PlayPlatformIdStr } from "../backend/common/infrastructure/Atomic.js";
|
||||
import type { FlowControlTerm, TransformHook } from "../backend/common/infrastructure/Transform.js";
|
||||
import type { Changeset } from "json-diff-ts";
|
||||
import type { IParseBaseOptions } from 'qs';
|
||||
|
||||
export type ComponentTypeClient = 'client';
|
||||
export const COMPONENT_TYPE_CLIENT: ComponentTypeClient = 'client';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue