mirror of
https://github.com/apricote/Listory.git
synced 2026-01-13 21:21:02 +00:00
chore(deps): bump all (#294)
This commit is contained in:
parent
1979d924c9
commit
38cf2ff549
69 changed files with 4681 additions and 3804 deletions
|
|
@ -2,12 +2,12 @@ import { createJob } from "@apricote/nest-pg-boss";
|
|||
|
||||
export type ICrawlerSupervisorJob = {};
|
||||
export const CrawlerSupervisorJob = createJob<ICrawlerSupervisorJob>(
|
||||
"spotify-crawler-supervisor"
|
||||
"spotify-crawler-supervisor",
|
||||
);
|
||||
|
||||
export type IUpdateSpotifyLibraryJob = {};
|
||||
export const UpdateSpotifyLibraryJob = createJob<IUpdateSpotifyLibraryJob>(
|
||||
"update-spotify-library"
|
||||
"update-spotify-library",
|
||||
);
|
||||
|
||||
export type IImportSpotifyJob = { userID: string };
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export class SchedulerService implements OnApplicationBootstrap {
|
|||
@ImportSpotifyJob.Inject()
|
||||
private readonly importSpotifyJobService: JobService<IImportSpotifyJob>,
|
||||
@UpdateSpotifyLibraryJob.Inject()
|
||||
private readonly updateSpotifyLibraryJobService: JobService<IUpdateSpotifyLibraryJob>
|
||||
private readonly updateSpotifyLibraryJobService: JobService<IUpdateSpotifyLibraryJob>,
|
||||
) {}
|
||||
|
||||
async onApplicationBootstrap() {
|
||||
|
|
@ -65,9 +65,9 @@ export class SchedulerService implements OnApplicationBootstrap {
|
|||
{ userID: user.id },
|
||||
{},
|
||||
pollRate,
|
||||
user.id
|
||||
user.id,
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ import {
|
|||
import { HttpService } from "@nestjs/axios";
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { Counter, Histogram } from "@opentelemetry/api-metrics";
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
import type { InternalAxiosRequestConfig } from "axios";
|
||||
import { MetricService } from "nestjs-otel";
|
||||
import { UrlValueParserService } from "../../../open-telemetry/url-value-parser.service";
|
||||
|
||||
const SPOTIFY_API_METRICS_CONFIG_KEY = Symbol("kSpotifyApiMetricsInterceptor");
|
||||
|
||||
// Merging our custom properties with the base config
|
||||
interface SpotifyApiMetricsConfig extends AxiosRequestConfig {
|
||||
interface SpotifyApiMetricsConfig extends InternalAxiosRequestConfig {
|
||||
[SPOTIFY_API_METRICS_CONFIG_KEY]: {
|
||||
startTime: number;
|
||||
};
|
||||
|
|
@ -28,13 +28,13 @@ export class MetricsInterceptor extends AxiosInterceptor<SpotifyApiMetricsConfig
|
|||
constructor(
|
||||
httpService: HttpService,
|
||||
metricService: MetricService,
|
||||
private readonly urlValueParserService: UrlValueParserService
|
||||
private readonly urlValueParserService: UrlValueParserService,
|
||||
) {
|
||||
super(httpService);
|
||||
|
||||
this.responseCounter = metricService.getCounter(
|
||||
"listory_spotify_api_http_response",
|
||||
{ description: "Total number of HTTP responses from Spotify API" }
|
||||
{ description: "Total number of HTTP responses from Spotify API" },
|
||||
);
|
||||
|
||||
this.requestHistogram = metricService.getHistogram(
|
||||
|
|
@ -43,7 +43,7 @@ export class MetricsInterceptor extends AxiosInterceptor<SpotifyApiMetricsConfig
|
|||
description:
|
||||
"HTTP latency value recorder in seconds for requests made to Spotify API",
|
||||
unit: "seconds",
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ export class MetricsInterceptor extends AxiosInterceptor<SpotifyApiMetricsConfig
|
|||
status: response.status.toString(),
|
||||
path: this.urlValueParserService.replacePathValues(
|
||||
response.config.url,
|
||||
"<id>"
|
||||
"<id>",
|
||||
),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ export class SpotifyApiService {
|
|||
{
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
params: parameters,
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return history.data.items;
|
||||
|
|
@ -34,12 +34,12 @@ export class SpotifyApiService {
|
|||
|
||||
async getArtist(
|
||||
accessToken: string,
|
||||
spotifyID: string
|
||||
spotifyID: string,
|
||||
): Promise<ArtistObject> {
|
||||
const artist = await firstValueFrom(
|
||||
this.httpService.get<ArtistObject>(`v1/artists/${spotifyID}`, {
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return artist.data;
|
||||
|
|
@ -47,7 +47,7 @@ export class SpotifyApiService {
|
|||
|
||||
async getArtists(
|
||||
accessToken: string,
|
||||
spotifyIDs: string[]
|
||||
spotifyIDs: string[],
|
||||
): Promise<ArtistObject[]> {
|
||||
const artist = await firstValueFrom(
|
||||
this.httpService.get<{ artists: ArtistObject[] }>(`v1/artists`, {
|
||||
|
|
@ -55,7 +55,7 @@ export class SpotifyApiService {
|
|||
params: {
|
||||
ids: spotifyIDs.join(","),
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return artist.data.artists;
|
||||
|
|
@ -65,14 +65,14 @@ export class SpotifyApiService {
|
|||
const album = await firstValueFrom(
|
||||
this.httpService.get<AlbumObject>(`v1/albums/${spotifyID}`, {
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
})
|
||||
}),
|
||||
);
|
||||
return album.data;
|
||||
}
|
||||
|
||||
async getAlbums(
|
||||
accessToken: string,
|
||||
spotifyIDs: string[]
|
||||
spotifyIDs: string[],
|
||||
): Promise<AlbumObject[]> {
|
||||
const album = await firstValueFrom(
|
||||
this.httpService.get<{ albums: AlbumObject[] }>(`v1/albums`, {
|
||||
|
|
@ -80,7 +80,7 @@ export class SpotifyApiService {
|
|||
params: {
|
||||
ids: spotifyIDs.join(","),
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
return album.data.albums;
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ export class SpotifyApiService {
|
|||
const track = await firstValueFrom(
|
||||
this.httpService.get<TrackObject>(`v1/tracks/${spotifyID}`, {
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return track.data;
|
||||
|
|
@ -97,7 +97,7 @@ export class SpotifyApiService {
|
|||
|
||||
async getTracks(
|
||||
accessToken: string,
|
||||
spotifyIDs: string[]
|
||||
spotifyIDs: string[],
|
||||
): Promise<TrackObject[]> {
|
||||
const track = await firstValueFrom(
|
||||
this.httpService.get<{ tracks: TrackObject[] }>(`v1/tracks`, {
|
||||
|
|
@ -105,7 +105,7 @@ export class SpotifyApiService {
|
|||
params: {
|
||||
ids: spotifyIDs.join(","),
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return track.data.tracks;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export class SpotifyAuthService {
|
|||
|
||||
constructor(
|
||||
private readonly httpService: HttpService,
|
||||
config: ConfigService
|
||||
config: ConfigService,
|
||||
) {
|
||||
this.clientID = config.get<string>("SPOTIFY_CLIENT_ID");
|
||||
this.clientSecret = config.get<string>("SPOTIFY_CLIENT_SECRET");
|
||||
|
|
@ -27,8 +27,8 @@ export class SpotifyAuthService {
|
|||
username: this.clientID,
|
||||
password: this.clientSecret,
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return response.data.access_token;
|
||||
|
|
@ -44,8 +44,8 @@ export class SpotifyAuthService {
|
|||
username: this.clientID,
|
||||
password: this.clientSecret,
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return response.data.access_token;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export class SpotifyService {
|
|||
private readonly listensService: ListensService,
|
||||
private readonly musicLibraryService: MusicLibraryService,
|
||||
private readonly spotifyApi: SpotifyApiService,
|
||||
private readonly spotifyAuth: SpotifyAuthService
|
||||
private readonly spotifyAuth: SpotifyAuthService,
|
||||
) {}
|
||||
|
||||
@Span()
|
||||
|
|
@ -82,7 +82,7 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async crawlListensForUser(
|
||||
user: User,
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<void> {
|
||||
this.logger.debug({ userId: user.id }, `Crawling recently played tracks`);
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ export class SpotifyService {
|
|||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
try {
|
||||
const accessToken = await this.spotifyAuth.refreshAccessToken(
|
||||
user.spotify
|
||||
user.spotify,
|
||||
);
|
||||
await this.usersService.updateSpotifyConnection(user, {
|
||||
...user.spotify,
|
||||
|
|
@ -103,7 +103,7 @@ export class SpotifyService {
|
|||
} catch (errFromAuth) {
|
||||
this.logger.error(
|
||||
{ userId: user.id },
|
||||
`Refreshing access token failed for user "${user.id}": ${errFromAuth}`
|
||||
`Refreshing access token failed for user "${user.id}": ${errFromAuth}`,
|
||||
);
|
||||
throw errFromAuth;
|
||||
}
|
||||
|
|
@ -112,7 +112,7 @@ export class SpotifyService {
|
|||
}
|
||||
|
||||
this.logger.error(
|
||||
`Unexpected error while fetching recently played tracks: ${err}`
|
||||
`Unexpected error while fetching recently played tracks: ${err}`,
|
||||
);
|
||||
throw err;
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ export class SpotifyService {
|
|||
}
|
||||
|
||||
const tracks = await this.importTracks(
|
||||
uniq(playHistory.map((history) => history.track.id))
|
||||
uniq(playHistory.map((history) => history.track.id)),
|
||||
);
|
||||
|
||||
const listenData = playHistory.map((history) => ({
|
||||
|
|
@ -140,15 +140,15 @@ export class SpotifyService {
|
|||
listen.track.name
|
||||
}" by ${listen.track.artists
|
||||
?.map((artist) => `"${artist.name}"`)
|
||||
.join(", ")}`
|
||||
)
|
||||
.join(", ")}`,
|
||||
),
|
||||
);
|
||||
|
||||
const newestPlayTime = new Date(
|
||||
playHistory
|
||||
.map((history) => history.played_at)
|
||||
.sort()
|
||||
.pop()
|
||||
.pop(),
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -181,7 +181,7 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async importTrack(
|
||||
spotifyID: string,
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<Track> {
|
||||
const track = await this.musicLibraryService.findTrack({
|
||||
spotify: { id: spotifyID },
|
||||
|
|
@ -195,7 +195,7 @@ export class SpotifyService {
|
|||
try {
|
||||
spotifyTrack = await this.spotifyApi.getTrack(
|
||||
this.appAccessToken,
|
||||
spotifyID
|
||||
spotifyID,
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
|
|
@ -211,8 +211,8 @@ export class SpotifyService {
|
|||
this.importAlbum(spotifyTrack.album.id),
|
||||
Promise.all(
|
||||
spotifyTrack.artists.map(({ id: artistID }) =>
|
||||
this.importArtist(artistID)
|
||||
)
|
||||
this.importArtist(artistID),
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
|
|
@ -232,15 +232,15 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async importTracks(
|
||||
spotifyIDs: string[],
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<Track[]> {
|
||||
const tracks = await this.musicLibraryService.findTracks(
|
||||
spotifyIDs.map((id) => ({ spotify: { id } }))
|
||||
spotifyIDs.map((id) => ({ spotify: { id } })),
|
||||
);
|
||||
|
||||
// Get missing ids
|
||||
const missingIDs = spotifyIDs.filter(
|
||||
(id) => !tracks.some((track) => track.spotify.id === id)
|
||||
(id) => !tracks.some((track) => track.spotify.id === id),
|
||||
);
|
||||
|
||||
// No need to make spotify api request if all data is available locally
|
||||
|
|
@ -256,11 +256,11 @@ export class SpotifyService {
|
|||
chunk(missingIDs, SPOTIFY_BULK_MAX_IDS).map(async (ids) => {
|
||||
const batchTracks = await this.spotifyApi.getTracks(
|
||||
this.appAccessToken,
|
||||
ids
|
||||
ids,
|
||||
);
|
||||
|
||||
spotifyTracks.push(...batchTracks);
|
||||
})
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
|
|
@ -279,24 +279,24 @@ export class SpotifyService {
|
|||
const artists = await this.importArtists(
|
||||
uniq(
|
||||
spotifyTracks.flatMap((track) =>
|
||||
track.artists.map((artist) => artist.id)
|
||||
)
|
||||
)
|
||||
track.artists.map((artist) => artist.id),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const albums = await this.importAlbums(
|
||||
uniq(spotifyTracks.map((track) => track.album.id))
|
||||
uniq(spotifyTracks.map((track) => track.album.id)),
|
||||
);
|
||||
|
||||
// Find the right albums & artists for each spotify track & create db entry
|
||||
const newTracks = await this.musicLibraryService.createTracks(
|
||||
spotifyTracks.map((spotifyTrack) => {
|
||||
const trackAlbum = albums.find(
|
||||
(album) => spotifyTrack.album.id === album.spotify.id
|
||||
(album) => spotifyTrack.album.id === album.spotify.id,
|
||||
);
|
||||
|
||||
const trackArtists = spotifyTrack.artists.map((trackArtist) =>
|
||||
artists.find((artist) => trackArtist.id == artist.spotify.id)
|
||||
artists.find((artist) => trackArtist.id == artist.spotify.id),
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
@ -310,7 +310,7 @@ export class SpotifyService {
|
|||
href: spotifyTrack.href,
|
||||
},
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
// Return new & existing tracks
|
||||
|
|
@ -320,7 +320,7 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async importAlbum(
|
||||
spotifyID: string,
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<Album> {
|
||||
const album = await this.musicLibraryService.findAlbum({
|
||||
spotify: { id: spotifyID },
|
||||
|
|
@ -334,7 +334,7 @@ export class SpotifyService {
|
|||
try {
|
||||
spotifyAlbum = await this.spotifyApi.getAlbum(
|
||||
this.appAccessToken,
|
||||
spotifyID
|
||||
spotifyID,
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
|
|
@ -348,8 +348,8 @@ export class SpotifyService {
|
|||
|
||||
const artists = await Promise.all(
|
||||
spotifyAlbum.artists.map(({ id: artistID }) =>
|
||||
this.importArtist(artistID)
|
||||
)
|
||||
this.importArtist(artistID),
|
||||
),
|
||||
);
|
||||
|
||||
return this.musicLibraryService.createAlbum({
|
||||
|
|
@ -367,15 +367,15 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async importAlbums(
|
||||
spotifyIDs: string[],
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<Album[]> {
|
||||
const albums = await this.musicLibraryService.findAlbums(
|
||||
spotifyIDs.map((id) => ({ spotify: { id } }))
|
||||
spotifyIDs.map((id) => ({ spotify: { id } })),
|
||||
);
|
||||
|
||||
// Get missing ids
|
||||
const missingIDs = spotifyIDs.filter(
|
||||
(id) => !albums.some((album) => album.spotify.id === id)
|
||||
(id) => !albums.some((album) => album.spotify.id === id),
|
||||
);
|
||||
|
||||
// No need to make spotify api request if all data is available locally
|
||||
|
|
@ -391,11 +391,11 @@ export class SpotifyService {
|
|||
chunk(missingIDs, SPOTIFY_BULK_ALBUMS_MAX_IDS).map(async (ids) => {
|
||||
const batchAlbums = await this.spotifyApi.getAlbums(
|
||||
this.appAccessToken,
|
||||
ids
|
||||
ids,
|
||||
);
|
||||
|
||||
spotifyAlbums.push(...batchAlbums);
|
||||
})
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
|
|
@ -410,16 +410,16 @@ export class SpotifyService {
|
|||
const artists = await this.importArtists(
|
||||
uniq(
|
||||
spotifyAlbums.flatMap((album) =>
|
||||
album.artists.map((artist) => artist.id)
|
||||
)
|
||||
)
|
||||
album.artists.map((artist) => artist.id),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Find the right albums & artists for each spotify track & create db entry
|
||||
const newAlbums = await this.musicLibraryService.createAlbums(
|
||||
spotifyAlbums.map((spotifyAlbum) => {
|
||||
const albumArtists = spotifyAlbum.artists.map((albumArtist) =>
|
||||
artists.find((artist) => albumArtist.id == artist.spotify.id)
|
||||
artists.find((artist) => albumArtist.id == artist.spotify.id),
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
@ -432,7 +432,7 @@ export class SpotifyService {
|
|||
href: spotifyAlbum.href,
|
||||
},
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return [...albums, ...newAlbums];
|
||||
|
|
@ -441,7 +441,7 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async importArtist(
|
||||
spotifyID: string,
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<Artist> {
|
||||
const artist = await this.musicLibraryService.findArtist({
|
||||
spotify: { id: spotifyID },
|
||||
|
|
@ -455,7 +455,7 @@ export class SpotifyService {
|
|||
try {
|
||||
spotifyArtist = await this.spotifyApi.getArtist(
|
||||
this.appAccessToken,
|
||||
spotifyID
|
||||
spotifyID,
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
|
|
@ -468,7 +468,7 @@ export class SpotifyService {
|
|||
}
|
||||
|
||||
const genres = await Promise.all(
|
||||
spotifyArtist.genres.map((genreName) => this.importGenre(genreName))
|
||||
spotifyArtist.genres.map((genreName) => this.importGenre(genreName)),
|
||||
);
|
||||
|
||||
return this.musicLibraryService.createArtist({
|
||||
|
|
@ -486,15 +486,15 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async importArtists(
|
||||
spotifyIDs: string[],
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<Artist[]> {
|
||||
const artists = await this.musicLibraryService.findArtists(
|
||||
spotifyIDs.map((id) => ({ spotify: { id } }))
|
||||
spotifyIDs.map((id) => ({ spotify: { id } })),
|
||||
);
|
||||
|
||||
// Get missing ids
|
||||
const missingIDs = spotifyIDs.filter(
|
||||
(id) => !artists.some((artist) => artist.spotify.id === id)
|
||||
(id) => !artists.some((artist) => artist.spotify.id === id),
|
||||
);
|
||||
|
||||
// No need to make spotify api request if all data is available locally
|
||||
|
|
@ -510,11 +510,11 @@ export class SpotifyService {
|
|||
chunk(missingIDs, SPOTIFY_BULK_MAX_IDS).map(async (ids) => {
|
||||
const batchArtists = await this.spotifyApi.getArtists(
|
||||
this.appAccessToken,
|
||||
ids
|
||||
ids,
|
||||
);
|
||||
|
||||
spotifyArtists.push(...batchArtists);
|
||||
})
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
|
|
@ -527,14 +527,14 @@ export class SpotifyService {
|
|||
}
|
||||
|
||||
const genres = await this.importGenres(
|
||||
uniq(spotifyArtists.flatMap((artist) => artist.genres))
|
||||
uniq(spotifyArtists.flatMap((artist) => artist.genres)),
|
||||
);
|
||||
|
||||
// Find the right genres for each spotify artist & create db entry
|
||||
const newArtists = await this.musicLibraryService.createArtists(
|
||||
spotifyArtists.map((spotifyArtist) => {
|
||||
const artistGenres = spotifyArtist.genres.map((artistGenre) =>
|
||||
genres.find((genre) => artistGenre == genre.name)
|
||||
genres.find((genre) => artistGenre == genre.name),
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
@ -547,7 +547,7 @@ export class SpotifyService {
|
|||
href: spotifyArtist.href,
|
||||
},
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return [...artists, ...newArtists];
|
||||
|
|
@ -556,7 +556,7 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async updateArtist(
|
||||
spotifyID: string,
|
||||
retryOnExpiredToken: boolean = true
|
||||
retryOnExpiredToken: boolean = true,
|
||||
): Promise<Artist> {
|
||||
const artist = await this.importArtist(spotifyID, retryOnExpiredToken);
|
||||
|
||||
|
|
@ -565,7 +565,7 @@ export class SpotifyService {
|
|||
try {
|
||||
spotifyArtist = await this.spotifyApi.getArtist(
|
||||
this.appAccessToken,
|
||||
spotifyID
|
||||
spotifyID,
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.response && err.response.status === 401 && retryOnExpiredToken) {
|
||||
|
|
@ -578,7 +578,7 @@ export class SpotifyService {
|
|||
}
|
||||
|
||||
const genres = await Promise.all(
|
||||
spotifyArtist.genres.map((genreName) => this.importGenre(genreName))
|
||||
spotifyArtist.genres.map((genreName) => this.importGenre(genreName)),
|
||||
);
|
||||
|
||||
await this.musicLibraryService.updateArtist({
|
||||
|
|
@ -609,12 +609,12 @@ export class SpotifyService {
|
|||
@Span()
|
||||
async importGenres(names: string[]): Promise<Genre[]> {
|
||||
const genres = await this.musicLibraryService.findGenres(
|
||||
names.map((name) => ({ name }))
|
||||
names.map((name) => ({ name })),
|
||||
);
|
||||
|
||||
// Get missing genres
|
||||
const missingGenres = names.filter(
|
||||
(name) => !genres.some((genre) => genre.name === name)
|
||||
(name) => !genres.some((genre) => genre.name === name),
|
||||
);
|
||||
|
||||
// No need to create genres if all data is available locally
|
||||
|
|
@ -623,7 +623,7 @@ export class SpotifyService {
|
|||
}
|
||||
|
||||
const newGenres = await this.musicLibraryService.createGenres(
|
||||
missingGenres.map((name) => ({ name }))
|
||||
missingGenres.map((name) => ({ name })),
|
||||
);
|
||||
|
||||
return [...genres, ...newGenres];
|
||||
|
|
@ -646,7 +646,7 @@ export class SpotifyService {
|
|||
resolve();
|
||||
} catch (err) {
|
||||
this.logger.warn(
|
||||
`Error while refreshing spotify app access token ${err}`
|
||||
`Error while refreshing spotify app access token ${err}`,
|
||||
);
|
||||
|
||||
reject(err);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue