mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature-107] Advancement on playlists feature
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import { LocalBPList } from "shared/models/playlists/local-playlist.models";
|
||||
import { LocalPlaylistsManagerService } from "../services/additional-content/local-playlists-manager.service";
|
||||
import { IpcService } from "../services/ipc.service";
|
||||
import { of } from "rxjs";
|
||||
import { mergeMap, of } from "rxjs";
|
||||
import { BPList } from "shared/models/playlists/playlist.interface";
|
||||
import path from "path";
|
||||
import { pathToFileURL } from "url";
|
||||
import { LocalMapsManagerService } from "../services/additional-content/maps/local-maps-manager.service";
|
||||
import { Progression } from "main/helpers/fs.helpers";
|
||||
|
||||
const ipc = IpcService.getInstance();
|
||||
|
||||
@@ -61,5 +62,12 @@ ipc.on("get-version-playlists-details", (args, reply) => {
|
||||
|
||||
ipc.on("delete-playlist", (args, reply) => {
|
||||
const playlists = LocalPlaylistsManagerService.getInstance();
|
||||
reply(playlists.deletePlaylist(args));
|
||||
const maps = LocalMapsManagerService.getInstance();
|
||||
reply(playlists.deletePlaylistFile(args.bpList).pipe(mergeMap(() => {
|
||||
if(args.deleteMaps){
|
||||
console.log("ALALALZELALZELAZELA");
|
||||
return maps.deleteMapsFromHashs(args.version, args.bpList.songs.map(s => s.hash));
|
||||
}
|
||||
return of({ current: 0, total: 0 } as Progression);
|
||||
})));
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ import { SongCacheService } from "./maps/song-cache.service";
|
||||
import { InstallationLocationService } from "../installation-location.service";
|
||||
import sanitize from "sanitize-filename";
|
||||
import { isValidUrl } from "shared/helpers/url.helpers";
|
||||
import { allSettled } from "shared/helpers/promise.helpers";
|
||||
|
||||
export class LocalPlaylistsManagerService {
|
||||
private static instance: LocalPlaylistsManagerService;
|
||||
@@ -284,34 +285,8 @@ export class LocalPlaylistsManagerService {
|
||||
|
||||
}
|
||||
|
||||
public deletePlaylist(opt: {path: string, deleteMaps?: boolean}): Observable<Progression>{
|
||||
|
||||
return new Observable<Progression>(obs => {
|
||||
(async () => {
|
||||
|
||||
const bpList = await this.readPlaylistFromSource(opt.path);
|
||||
|
||||
const progress: Progression = { current: 0, total: opt.deleteMaps ? bpList.songs.length + 1 : 1};
|
||||
|
||||
if(opt.deleteMaps){
|
||||
const mapsHashs = bpList.songs.map(s => ({ hash: s.hash }));
|
||||
await lastValueFrom(this.maps.deleteMaps(mapsHashs).pipe(
|
||||
tap({
|
||||
next: () => {
|
||||
progress.current += 1
|
||||
obs.next(progress);
|
||||
},
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
await unlinkPath(opt.path);
|
||||
progress.current += 1;
|
||||
obs.next(progress);
|
||||
})()
|
||||
.catch(err => obs.error(err))
|
||||
.finally(() => obs.complete());
|
||||
});
|
||||
public deletePlaylistFile(bpList: LocalBPList): Observable<void>{
|
||||
return from(unlinkPath(bpList.path));
|
||||
}
|
||||
|
||||
public oneClickInstallPlaylist(bpListUrl: string): Observable<Progression<DownloadPlaylistProgressionData>> {
|
||||
|
||||
@@ -26,6 +26,7 @@ import { SongCacheService } from "./song-cache.service";
|
||||
import { IpcService } from "../../ipc.service";
|
||||
import { pathToFileURL } from "url";
|
||||
import { sToMs } from "../../../../shared/helpers/time.helpers";
|
||||
import { FieldRequired } from "shared/helpers/type.helpers";
|
||||
|
||||
export class LocalMapsManagerService {
|
||||
private static instance: LocalMapsManagerService;
|
||||
@@ -236,7 +237,7 @@ export class LocalMapsManagerService {
|
||||
return this.linker.unlinkFolder(versionMapsPath, { keepContents: keepMaps, intermediateFolder: LocalMapsManagerService.SHARED_MAPS_FOLDER });
|
||||
}
|
||||
|
||||
public deleteMaps(maps: Partial<BsmLocalMap>[]): Observable<DeleteMapsProgress> {
|
||||
public deleteMaps(maps: FieldRequired<BsmLocalMap, "path">[]): Observable<DeleteMapsProgress> {
|
||||
return new Observable<DeleteMapsProgress>(observer => {
|
||||
const progress: DeleteMapsProgress = { total: maps.length, deleted: 0 };
|
||||
|
||||
@@ -244,17 +245,13 @@ export class LocalMapsManagerService {
|
||||
for (const map of maps) {
|
||||
let mapPath = map.path;
|
||||
|
||||
if (!mapPath) {
|
||||
const mapInfo = map.hash ? this.songCache.getMapInfoFromHash(map.hash) : null;
|
||||
mapPath = mapInfo?.path;
|
||||
}
|
||||
|
||||
if (mapPath && pathExistsSync(mapPath)) {
|
||||
if (pathExistsSync(mapPath)) {
|
||||
await deleteFolder(mapPath);
|
||||
this.songCache.deleteMapInfoFromDirname(path.basename(mapPath));
|
||||
progress.deleted++;
|
||||
observer.next(progress);
|
||||
}
|
||||
|
||||
observer.next(progress);
|
||||
}
|
||||
})()
|
||||
.catch(e => observer.error(e))
|
||||
@@ -262,6 +259,53 @@ export class LocalMapsManagerService {
|
||||
});
|
||||
}
|
||||
|
||||
public deleteMapsFromHashs(version: BSVersion, hashs: string[]): Observable<Progression> {
|
||||
return new Observable<Progression>(observer => {
|
||||
const progress: Progression = { total: hashs.length, current: 0 };
|
||||
|
||||
(async () => {
|
||||
const versionMapsPath = await this.getMapsFolderPath(version);
|
||||
const mapsPaths = await getFoldersInFolder(versionMapsPath);
|
||||
|
||||
for (const mapPath of mapsPaths) {
|
||||
const mapInfo = await this.loadMapInfoFromPath(mapPath);
|
||||
if (hashs.includes(mapInfo.hash)) {
|
||||
await deleteFolder(mapPath);
|
||||
this.songCache.deleteMapInfoFromDirname(path.basename(mapPath));
|
||||
progress.current++;
|
||||
}
|
||||
|
||||
observer.next(progress);
|
||||
}
|
||||
})()
|
||||
.catch(e => observer.error(e))
|
||||
.finally(() => observer.complete());
|
||||
});
|
||||
}
|
||||
|
||||
public async getMapInfoFromHash(hash: string, version: BSVersion): Promise<BsmLocalMap> {
|
||||
const versionMapsPath = await this.getMapsFolderPath(version);
|
||||
const mapInfo = this.songCache.getMapInfoFromHash(hash);
|
||||
|
||||
const cachedMapPath = path.join(versionMapsPath, mapInfo.dirname);
|
||||
|
||||
if(pathExistsSync(cachedMapPath)){
|
||||
return this.loadMapInfoFromPath(cachedMapPath);
|
||||
}
|
||||
|
||||
// if not in cache, search in the folder
|
||||
const mapsPaths = await getFoldersInFolder(versionMapsPath);
|
||||
|
||||
for (const mapPath of mapsPaths) {
|
||||
const mapInfo = await this.loadMapInfoFromPath(mapPath);
|
||||
if (mapInfo.hash === hash) {
|
||||
return mapInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public async downloadMap(map: BsvMapDetail, version?: BSVersion): Promise<BsmLocalMap> {
|
||||
if (!map.versions.at(0).hash) {
|
||||
|
||||
@@ -26,9 +26,9 @@ export class SongCacheService {
|
||||
return this.rawInfosCache.get(dirname);
|
||||
}
|
||||
|
||||
public getMapInfoFromHash(hash: string): { path: string, info: CachedRawInfoWithHash } | undefined {
|
||||
public getMapInfoFromHash(hash: string): { dirname: string, info: CachedRawInfoWithHash } | undefined {
|
||||
const res = Object.entries(this.rawInfosCache.cache).find(([, info]) => info.hash === hash);
|
||||
return res ? { path: res[0], info: res[1] } : undefined;
|
||||
return res ? { dirname: res[0], info: res[1] } : undefined;
|
||||
}
|
||||
|
||||
public setMapInfoFromDirname(dirname: string, info: CachedRawInfoWithHash): void {
|
||||
|
||||
Reference in New Issue
Block a user