playlist folder structure in downloads
This commit is contained in:
@@ -4,10 +4,12 @@ import {PlaylistEntity} from "./playlist.entity";
|
|||||||
import {PlaylistService} from "./playlist.service";
|
import {PlaylistService} from "./playlist.service";
|
||||||
import {PlaylistController} from "./playlist.controller";
|
import {PlaylistController} from "./playlist.controller";
|
||||||
import {TrackModule} from "../track/track.module";
|
import {TrackModule} from "../track/track.module";
|
||||||
|
import {ConfigModule} from "@nestjs/config";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([PlaylistEntity]),
|
TypeOrmModule.forFeature([PlaylistEntity]),
|
||||||
|
ConfigModule,
|
||||||
TrackModule,
|
TrackModule,
|
||||||
],
|
],
|
||||||
providers: [PlaylistService],
|
providers: [PlaylistService],
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ import {TrackService} from "../track/track.service";
|
|||||||
import {WebSocketGateway, WebSocketServer} from "@nestjs/websockets";
|
import {WebSocketGateway, WebSocketServer} from "@nestjs/websockets";
|
||||||
import {Server} from "socket.io";
|
import {Server} from "socket.io";
|
||||||
import {TrackStatusEnum} from "../track/track.model";
|
import {TrackStatusEnum} from "../track/track.model";
|
||||||
|
import {resolve} from "path";
|
||||||
|
import {ConfigService} from "@nestjs/config";
|
||||||
|
import {EnviromentEnum} from "../enviroment.enum";
|
||||||
|
import * as fs from 'fs';
|
||||||
const fetch = require('isomorphic-unfetch');
|
const fetch = require('isomorphic-unfetch');
|
||||||
const { getData, getPreview, getTracks, getDetails } = require('spotify-url-info')(fetch);
|
const { getData, getPreview, getTracks, getDetails } = require('spotify-url-info')(fetch);
|
||||||
|
|
||||||
@@ -20,6 +23,7 @@ export class PlaylistService {
|
|||||||
@InjectRepository(PlaylistEntity)
|
@InjectRepository(PlaylistEntity)
|
||||||
private repository: Repository<PlaylistEntity>,
|
private repository: Repository<PlaylistEntity>,
|
||||||
private readonly trackService: TrackService,
|
private readonly trackService: TrackService,
|
||||||
|
private readonly configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
findAll(): Promise<PlaylistEntity[]> {
|
findAll(): Promise<PlaylistEntity[]> {
|
||||||
@@ -46,6 +50,8 @@ export class PlaylistService {
|
|||||||
}
|
}
|
||||||
const savedPlaylist = await this.repository.save(playlist2Save);
|
const savedPlaylist = await this.repository.save(playlist2Save);
|
||||||
this.io.emit('playlistNew', savedPlaylist);
|
this.io.emit('playlistNew', savedPlaylist);
|
||||||
|
const folderName = resolve(__dirname, '..',this.configService.get<string>(EnviromentEnum.DOWNLOADS_PATH), savedPlaylist.name);
|
||||||
|
!fs.existsSync(folderName) && fs.mkdirSync(folderName);
|
||||||
for(let track of details?.tracks ?? []) {
|
for(let track of details?.tracks ?? []) {
|
||||||
await this.trackService.create({
|
await this.trackService.create({
|
||||||
artist: track.artist,
|
artist: track.artist,
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ export class TrackService {
|
|||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
findAll(criteria?: Partial<TrackEntity>): Promise<TrackEntity[]> {
|
findAll(where?: Partial<TrackEntity>, relations: string[] = []): Promise<TrackEntity[]> {
|
||||||
return this.repository.find({where: criteria});
|
return this.repository.find({where, relations});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllByPlaylist(id: number): Promise<TrackEntity[]> {
|
getAllByPlaylist(id: number): Promise<TrackEntity[]> {
|
||||||
@@ -82,14 +82,14 @@ export class TrackService {
|
|||||||
|
|
||||||
@Interval(1000)
|
@Interval(1000)
|
||||||
async download() {
|
async download() {
|
||||||
const queuedTracks = await this.findAll({status: TrackStatusEnum.Queued});
|
const queuedTracks = await this.findAll({status: TrackStatusEnum.Queued}, ['playlist']);
|
||||||
for (let track of queuedTracks) {
|
for (let track of queuedTracks) {
|
||||||
await this.update(track.id, {...track, status: TrackStatusEnum.Downloading});
|
await this.update(track.id, {...track, status: TrackStatusEnum.Downloading});
|
||||||
}
|
}
|
||||||
for(let track of queuedTracks) {
|
for(let track of queuedTracks) {
|
||||||
let error: string;
|
let error: string;
|
||||||
try {
|
try {
|
||||||
await this.youtubeDownload(track);
|
await this.youtubeDownload(track, track.playlist.name);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
error = String(err);
|
error = String(err);
|
||||||
@@ -103,7 +103,7 @@ export class TrackService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private youtubeDownload(track: TrackEntity): Promise<void> {
|
private youtubeDownload(track: TrackEntity, playlistName: string): Promise<void> {
|
||||||
return new Promise((res, reject) => {
|
return new Promise((res, reject) => {
|
||||||
const audio = ytdl(track.youtubeUrl, {quality: "highestaudio", filter: "audioonly"})
|
const audio = ytdl(track.youtubeUrl, {quality: "highestaudio", filter: "audioonly"})
|
||||||
.on('error', (err) => reject(err));
|
.on('error', (err) => reject(err));
|
||||||
@@ -114,7 +114,7 @@ export class TrackService {
|
|||||||
.pipe(
|
.pipe(
|
||||||
fs.createWriteStream(
|
fs.createWriteStream(
|
||||||
resolve(
|
resolve(
|
||||||
__dirname, '..', this.configService.get<string>(EnviromentEnum.DOWNLOADS_PATH),
|
__dirname, '..', this.configService.get<string>(EnviromentEnum.DOWNLOADS_PATH), playlistName,
|
||||||
`${track.artist} - ${track.song.replace('/', '')}.${this.configService.get<string>(EnviromentEnum.FORMAT)}`
|
`${track.artist} - ${track.song.replace('/', '')}.${this.configService.get<string>(EnviromentEnum.FORMAT)}`
|
||||||
)
|
)
|
||||||
).on('finish', () => res()).on('error', (err) => reject(err))
|
).on('finish', () => res()).on('error', (err) => reject(err))
|
||||||
|
|||||||
Reference in New Issue
Block a user