mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
start playlists management
This commit is contained in:
+2
-1
@@ -17,6 +17,7 @@ import { WindowManagerService } from './services/window-manager.service';
|
||||
import { DeepLinkService } from './services/deep-link.service';
|
||||
import { AppWindow } from 'shared/models/window-manager/app-window.model';
|
||||
import { LocalMapsManagerService } from './services/additional-content/local-maps-manager.service';
|
||||
import { LocalPlaylistsManagerService } from './services/additional-content/local-playlists-manager.service';
|
||||
|
||||
export const PRELOAD_PATH = app.isPackaged ? path.join(__dirname, 'preload.js') : path.join(__dirname, '../../.erb/dll/preload.js')
|
||||
|
||||
@@ -57,7 +58,7 @@ const createWindow = async (window: AppWindow = "launcher.html") => {
|
||||
|
||||
const initServicesMustBeInitialized = () => {
|
||||
LocalMapsManagerService.getInstance();
|
||||
// Playlist
|
||||
LocalPlaylistsManagerService.getInstance();
|
||||
// Model
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import path from "path";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
import { Observable } from "rxjs";
|
||||
import { BSVersion } from "shared/bs-version.interface";
|
||||
import { BsvPlaylist, BsvPlaylistPage } from "shared/models/maps/beat-saver.model";
|
||||
import { BSLocalVersionService } from "../bs-local-version.service";
|
||||
import { RequestService } from "../request.service";
|
||||
import { UtilsService } from "../utils.service";
|
||||
import { LocalMapsManagerService } from "./local-maps-manager.service";
|
||||
|
||||
export class LocalPlaylistsManagerService {
|
||||
|
||||
private static instance: LocalPlaylistsManagerService
|
||||
|
||||
public static getInstance(): LocalPlaylistsManagerService {
|
||||
if (!LocalPlaylistsManagerService.instance) { LocalPlaylistsManagerService.instance = new LocalPlaylistsManagerService(); }
|
||||
return LocalPlaylistsManagerService.instance;
|
||||
}
|
||||
|
||||
private readonly PLAYLISTS_FOLDER = "Playlists";
|
||||
private readonly DEEP_LINKS = {
|
||||
BeatSaver: "bsplaylist",
|
||||
};
|
||||
|
||||
|
||||
private readonly versions: BSLocalVersionService;
|
||||
private readonly maps: LocalMapsManagerService;
|
||||
public readonly utils: UtilsService;
|
||||
public readonly request: RequestService;
|
||||
|
||||
private constructor(){
|
||||
this.maps = LocalMapsManagerService.getInstance();
|
||||
this.versions = BSLocalVersionService.getInstance();
|
||||
this.utils = UtilsService.getInstance();
|
||||
this.request = RequestService.getInstance();
|
||||
}
|
||||
|
||||
private getPlaylistIdFromDownloadUrl(url: string): string{
|
||||
const splited = url.split("/")
|
||||
const idIndex = splited.indexOf("id");
|
||||
return splited[idIndex + 1];
|
||||
}
|
||||
|
||||
private async downloadPlaylistFile(playlist: BsvPlaylist, version: BSVersion): Promise<string>{
|
||||
|
||||
const versionFolder = await this.versions.getVersionPath(version);
|
||||
const bpListUrl = playlist.downloadURL;
|
||||
|
||||
const bsListDest = path.join(versionFolder, this.PLAYLISTS_FOLDER, path.basename(bpListUrl));
|
||||
|
||||
return this.request.downloadFile(bpListUrl, bsListDest);
|
||||
|
||||
}
|
||||
|
||||
public downloadPlaylist(playlistPage: BsvPlaylistPage, version: BSVersion): Observable<string[]>{
|
||||
|
||||
const res = new BehaviorSubject<string[]>([]);
|
||||
|
||||
const observer = async () => {
|
||||
try{
|
||||
const bpListPath = await this.downloadPlaylistFile(playlistPage.playlist, version);
|
||||
|
||||
for(const map of playlistPage.maps){
|
||||
const mapPath = await this.maps.downloadMap(map.map, version);
|
||||
res.next([...res.value, mapPath]);
|
||||
}
|
||||
|
||||
res.next([...res.value, bpListPath]);
|
||||
res.complete();
|
||||
}
|
||||
catch(e){
|
||||
res.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
observer();
|
||||
return res.asObservable();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ApiResult } from "renderer/models/api/api.model";
|
||||
import { BsvMapDetail } from "shared/models/maps";
|
||||
import { MapFilter, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
|
||||
import { BsvPlaylistPage, MapFilter, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
|
||||
import fetch from "node-fetch"
|
||||
|
||||
export class BeatSaverApiService {
|
||||
@@ -121,4 +121,14 @@ export class BeatSaverApiService {
|
||||
|
||||
}
|
||||
|
||||
public async getPlaylistDetails(id: number): Promise<ApiResult<BsvPlaylistPage>>{
|
||||
|
||||
const res = await fetch(`${this.bsaverApiUrl}/playlists/id/${id}`);
|
||||
|
||||
const data = await res.json() as BsvPlaylistPage;
|
||||
|
||||
return {status: res.status, data};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import { splitIntoChunk } from "../../../helpers/array-tools";
|
||||
import { BsvMapDetail } from "shared/models/maps";
|
||||
import { SearchParams } from "shared/models/maps/beat-saver.model";
|
||||
import { BsvPlaylist, BsvPlaylistPage, SearchParams } from "shared/models/maps/beat-saver.model";
|
||||
import { BeatSaverApiService } from "./beat-saver-api.service";
|
||||
import { red } from "tailwindcss/colors";
|
||||
|
||||
export class BeatSaverService {
|
||||
|
||||
@@ -65,6 +66,13 @@ export class BeatSaverService {
|
||||
|
||||
}
|
||||
|
||||
public async getPlaylistPage(id: number): Promise<BsvPlaylistPage>{
|
||||
|
||||
const res = await this.bsaverApi.getPlaylistDetails(id);
|
||||
return res.data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -183,4 +183,46 @@ export interface SearchParams {
|
||||
includeEmpty?: boolean
|
||||
}
|
||||
|
||||
export type SearchOrder = "Latest"|"Relevance"|"Rating"|"Curated";
|
||||
export type SearchOrder = "Latest"|"Relevance"|"Rating"|"Curated";
|
||||
|
||||
export interface BsvMapDetailWithOrder {
|
||||
map: BsvMapDetail,
|
||||
order: number
|
||||
}
|
||||
|
||||
export interface BsvPlaylist {
|
||||
createdAt: BsvInstant,
|
||||
curatedAt: BsvInstant,
|
||||
curator: BsvUserDetail,
|
||||
deletedAt: BsvInstant,
|
||||
description: string,
|
||||
downloadURL: string,
|
||||
name: string,
|
||||
owner: BsvUserDetail,
|
||||
playlistId: number,
|
||||
playlistImage: string,
|
||||
playlistImage512: string,
|
||||
public: boolean,
|
||||
songsChangedAt: BsvInstant,
|
||||
stats: BsvPlaylistStats,
|
||||
updatedAt: BsvInstant,
|
||||
}
|
||||
|
||||
export interface BsvPlaylistStats {
|
||||
avgScore: number,
|
||||
downVotes: number,
|
||||
mapperCount: number,
|
||||
maxNps: number,
|
||||
maxNpsTwoDP: number,
|
||||
minNps: number,
|
||||
minNpsTwoDP: number,
|
||||
scoreOneDP: number,
|
||||
totalDuration: number,
|
||||
totalMaps: number,
|
||||
upVotes: number
|
||||
}
|
||||
|
||||
export interface BsvPlaylistPage {
|
||||
maps: BsvMapDetailWithOrder[],
|
||||
playlist: BsvPlaylist
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user