playlist subscription functionality
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user