playlist subscription functionality

This commit is contained in:
raiper34
2024-07-21 16:44:50 +02:00
parent 57da7c7410
commit c365d8be90
8 changed files with 76 additions and 13 deletions
@@ -1,4 +1,4 @@
import {Body, Controller, Delete, Get, Param, Post} from '@nestjs/common';
import {Body, Controller, Delete, Get, Param, Post, Put} from '@nestjs/common';
import {PlaylistService} from "./playlist.service";
import {PlaylistModel} from "./playlist.model";
@@ -20,6 +20,11 @@ export class PlaylistController {
await this.service.create(playlist);
}
@Put(':id')
update(@Param('id') id: number, @Body() playlist: Partial<PlaylistModel>): Promise<void> {
return this.service.update(id, playlist);
}
@Delete(':id')
remove(@Param('id') id: number): Promise<void> {
return this.service.remove(id);
@@ -16,6 +16,9 @@ export class PlaylistEntity {
@Column({ nullable: true })
error?: string;
@Column({default: false})
active?: boolean;
@Column({default: () => Date.now()})
createdAt?: number;
@@ -5,4 +5,5 @@ export interface PlaylistModel {
tracks?: any[]; //todo fix it
error?: string;
createdAt?: number;
active?: boolean;
}
+44 -8
View File
@@ -10,6 +10,7 @@ import {resolve} from "path";
import {ConfigService} from "@nestjs/config";
import {EnviromentEnum} from "../enviroment.enum";
import * as fs from 'fs';
import {Interval} from "@nestjs/schedule";
const fetch = require('isomorphic-unfetch');
const { getData, getPreview, getTracks, getDetails } = require('spotify-url-info')(fetch);
@@ -26,8 +27,8 @@ export class PlaylistService {
private readonly configService: ConfigService,
) {}
findAll(): Promise<PlaylistEntity[]> {
return this.repository.find({relations: {tracks: true}});
findAll(relations: Record<string, boolean> = {tracks: true}, where?: Partial<PlaylistEntity>): Promise<PlaylistEntity[]> {
return this.repository.find({where, relations});
}
findOne(id: number): Promise<PlaylistEntity | null> {
@@ -48,10 +49,8 @@ export class PlaylistService {
} catch (err) {
playlist2Save = {...playlist, error: String(err)};
}
const savedPlaylist = await this.repository.save(playlist2Save);
this.io.emit('playlistNew', savedPlaylist);
const folderName = resolve(__dirname, '..',this.configService.get<string>(EnviromentEnum.DOWNLOADS_PATH), savedPlaylist.name);
!fs.existsSync(folderName) && fs.mkdirSync(folderName);
const savedPlaylist = await this.save(playlist2Save);
this.createPlaylistFolderStructure(savedPlaylist.name);
for(let track of details?.tracks ?? []) {
await this.trackService.create({
artist: track.artist,
@@ -61,9 +60,16 @@ export class PlaylistService {
}
}
async update(id: number, playlist: PlaylistEntity): Promise<void> {
async save(playlist: PlaylistEntity): Promise<PlaylistEntity> {
const savedPlaylist = await this.repository.save(playlist);
this.io.emit('playlistNew', savedPlaylist);
return savedPlaylist;
}
async update(id: number, playlist: Partial<PlaylistEntity>): Promise<void> {
await this.repository.update(id, playlist);
this.io.emit('trackPlaylist', playlist);
const dbPlaylist = await this.findOne(id);
this.io.emit('playlistUpdate', dbPlaylist);
}
async retryFailedOfPlaylist(id: number): Promise<void> {
@@ -74,4 +80,34 @@ export class PlaylistService {
}
}
}
private createPlaylistFolderStructure(playlistName): void {
const folderName = resolve(__dirname, '..',this.configService.get<string>(EnviromentEnum.DOWNLOADS_PATH), playlistName);
!fs.existsSync(folderName) && fs.mkdirSync(folderName);
}
@Interval(3600000)
async checkActivePlaylists(): Promise<void> {
const activePlaylists = await this.findAll({}, {active: true});
for (let playlist of activePlaylists) {
let details;
try {
details = await getDetails(playlist.spotifyUrl);
} catch (err) {
await this.update(playlist.id, {...playlist, error: String(err)});
}
this.createPlaylistFolderStructure(playlist.name);
for(let track of details?.tracks ?? []) {
const track2Save = {
artist: track.artist,
song: track.name,
spotifyUrl: track.previewUrl,
}
const isExist = !!(await this.trackService.findAll({...track2Save, playlist: {id: playlist.id}})).length;
if(!isExist) {
await this.trackService.create(track2Save, playlist);
}
}
}
}
}
+2 -2
View File
@@ -28,7 +28,7 @@ export class TrackService {
private readonly configService: ConfigService,
) {}
findAll(where?: Partial<TrackEntity>, relations: string[] = []): Promise<TrackEntity[]> {
findAll(where?: {[key: string]: any}, relations: Record<string, boolean> = {}): Promise<TrackEntity[]> {
return this.repository.find({where, relations});
}
@@ -82,7 +82,7 @@ export class TrackService {
@Interval(1000)
async download() {
const queuedTracks = await this.findAll({status: TrackStatusEnum.Queued}, ['playlist']);
const queuedTracks = await this.findAll({status: TrackStatusEnum.Queued}, {playlist: true});
for (let track of queuedTracks) {
await this.update(track.id, {...track, status: TrackStatusEnum.Downloading});
}