generated from uwu/neptune-template
-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate MusicBrainz data into unified class
- Loading branch information
Showing
12 changed files
with
160 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { actions } from "@neptune"; | ||
import { ItemId, TrackItem, Album } from "neptune-types/tidal"; | ||
import { interceptPromise } from "../interceptPromise"; | ||
import { MusicBrainz } from "../musicbrainzApi"; | ||
import { Recording } from "../musicbrainzApi/types/Recording"; | ||
import { Release } from "../musicbrainzApi/types/UPCData"; | ||
import { TrackItemCache } from "./TrackItemCache"; | ||
import { undefinedError } from "../undefinedError"; | ||
|
||
export class ExtendedTrackItem { | ||
public readonly trackId: ItemId; | ||
private _trackItem?: TrackItem; | ||
private _album?: Album; | ||
private _recording?: Recording; | ||
private _releaseAlbum?: Release; | ||
|
||
private static readonly _cache: Record<ItemId, ExtendedTrackItem> = {}; | ||
|
||
private constructor(trackId: ItemId) { | ||
this.trackId = trackId; | ||
} | ||
|
||
public static get(trackId: ItemId) { | ||
if (trackId === undefined) return undefined; | ||
return this._cache[trackId] ?? (this._cache[trackId] = new this(trackId)); | ||
} | ||
|
||
public trackItem(): TrackItem | undefined { | ||
if (this._trackItem !== undefined) return this._trackItem; | ||
|
||
return (this._trackItem = TrackItemCache.get(this.trackId)); | ||
} | ||
public async album(): Promise<Album | undefined> { | ||
if (this._album !== undefined) return this._album; | ||
|
||
actions.content.loadAlbum({ albumId: this.trackItem()?.album?.id! }); | ||
return (this._album = await interceptPromise(["content/LOAD_ALBUM_SUCCESS"], []).then((res) => <Album>res?.[0].album)); | ||
} | ||
public async recording(): Promise<Recording | undefined> { | ||
if (this._recording !== undefined) return this._recording; | ||
|
||
this._recording = await MusicBrainz.getRecording(this.trackItem()?.isrc).catch(undefinedError); | ||
if (this._recording !== undefined) return this._recording; | ||
|
||
const trackItem = this.trackItem(); | ||
if (trackItem === undefined) return undefined; | ||
|
||
const album = await this.album(); | ||
const albumRelease = await MusicBrainz.getAlbumRelease(album?.id).catch(undefinedError); | ||
|
||
const volumeNumber = (trackItem.volumeNumber ?? 1) - 1; | ||
const trackNumber = (trackItem.trackNumber ?? 1) - 1; | ||
|
||
return (this._recording = albumRelease?.media?.[volumeNumber]?.tracks?.[trackNumber]?.recording); | ||
} | ||
public async releaseAlbum() { | ||
if (this._releaseAlbum !== undefined) return this._releaseAlbum; | ||
|
||
const album = await this.album(); | ||
const upcData = await MusicBrainz.getUPCData(album?.upc).catch(undefinedError); | ||
|
||
return (this._releaseAlbum = upcData?.releases?.[0]); | ||
} | ||
|
||
public async everything() { | ||
return { | ||
trackItem: this.trackItem(), | ||
album: await this.album(), | ||
releaseAlbum: await this.releaseAlbum(), | ||
recording: await this.recording(), | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,22 @@ | ||
import { store } from "@neptune"; | ||
import { TrackItem, MediaItem } from "neptune-types/tidal"; | ||
|
||
import { TrackItem, MediaItem, ItemId } from "neptune-types/tidal"; | ||
import { undefinedError } from "../undefinedError"; | ||
export class TrackItemCache { | ||
private static readonly _cache: Map<string, TrackItem> = new Map<string, TrackItem>(); | ||
public static get(trackId: number | string | undefined) { | ||
private static readonly _cache: Record<ItemId, TrackItem> = {}; | ||
public static get(trackId?: ItemId) { | ||
if (trackId === undefined) return undefined; | ||
trackId = trackId.toString(); | ||
let mediaItem = TrackItemCache._cache.get(trackId); | ||
|
||
let mediaItem = this._cache[trackId]; | ||
if (mediaItem !== undefined) return mediaItem; | ||
|
||
const mediaItems: Record<number, MediaItem> = store.getState().content.mediaItems; | ||
for (const itemId in mediaItems) { | ||
const item = mediaItems[itemId]?.item; | ||
if (item?.contentType !== "track") continue; | ||
TrackItemCache._cache.set(itemId, item); | ||
this._cache[itemId] = item; | ||
} | ||
mediaItem = TrackItemCache._cache.get(trackId); | ||
|
||
mediaItem = this._cache[trackId]; | ||
if (mediaItem !== undefined) return mediaItem; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { MediaItem } from "neptune-types/tidal"; | ||
import { requestStream, rejectNotOk, toJson } from "../fetch"; | ||
import type { ISRCData } from "./types/ISRCData"; | ||
import type { ReleaseData } from "./types/ReleaseData"; | ||
import type { UPCData, Release } from "./types/UPCData"; | ||
|
||
const _jsonCache: Record<string, unknown> = {}; | ||
const fetchCachedJson = async <T>(url: string): Promise<T> => | ||
<T>_jsonCache[url] ?? | ||
(_jsonCache[url] = requestStream(url) | ||
.then(rejectNotOk) | ||
.then(toJson<T>)); | ||
|
||
export class MusicBrainz { | ||
public static async getRecording(isrc?: string) { | ||
if (isrc === undefined) return undefined; | ||
const isrcData = await fetchCachedJson<ISRCData>(`https://musicbrainz.org/ws/2/isrc/${isrc}?fmt=json`); | ||
return isrcData?.recordings?.[0]; | ||
} | ||
public static async getUPCData(upc?: string) { | ||
if (upc === undefined) return undefined; | ||
return fetchCachedJson<UPCData>(`https://musicbrainz.org/ws/2/release/?query=barcode:${upc}&fmt=json`); | ||
} | ||
public static async getAlbumRelease(albumId?: number) { | ||
if (albumId === undefined) return undefined; | ||
return fetchCachedJson<ReleaseData>(`https://musicbrainz.org/ws/2/release/${albumId}?inc=recordings+isrcs&fmt=json`); | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,5 @@ export interface Recording { | |
id?: string; | ||
disambiguation?: string; | ||
video?: boolean; | ||
isrcs?: string[]; | ||
} |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export const undefinedError = (err: Error) => { | ||
console.error(err); | ||
return undefined; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters