Release Jarri Spooty Workspace v3.0.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "backend",
|
||||
"version": "2.4.2",
|
||||
"version": "3.0.0",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -14,6 +14,7 @@ import { BullModule } from '@nestjs/bullmq';
|
||||
import { APP_GUARD } from '@nestjs/core';
|
||||
import { AuthGuard } from './shared/auth.guard';
|
||||
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
|
||||
import { ArchiveModule } from './archive/archive.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -79,6 +80,7 @@ import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
|
||||
}),
|
||||
TrackModule,
|
||||
PlaylistModule,
|
||||
ArchiveModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { ArchiveListingDto, ArchiveService } from './archive.service';
|
||||
|
||||
@Controller('archive')
|
||||
export class ArchiveController {
|
||||
constructor(private readonly archiveService: ArchiveService) {}
|
||||
|
||||
@Get()
|
||||
list(): Promise<ArchiveListingDto> {
|
||||
return this.archiveService.list();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
import { ArchiveController } from './archive.controller';
|
||||
import { ArchiveService } from './archive.service';
|
||||
|
||||
@Module({
|
||||
imports: [SharedModule],
|
||||
controllers: [ArchiveController],
|
||||
providers: [ArchiveService],
|
||||
})
|
||||
export class ArchiveModule {}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { promises as fs } from 'fs';
|
||||
import { relative, resolve } from 'path';
|
||||
import { UtilsService } from '../shared/utils.service';
|
||||
|
||||
export interface ArchiveFileDto {
|
||||
name: string;
|
||||
path: string;
|
||||
sizeBytes: number;
|
||||
modifiedAt: number;
|
||||
}
|
||||
|
||||
export interface ArchiveListingDto {
|
||||
root: string;
|
||||
files: ArchiveFileDto[];
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class ArchiveService {
|
||||
constructor(private readonly utilsService: UtilsService) {}
|
||||
|
||||
async list(): Promise<ArchiveListingDto> {
|
||||
const root = this.utilsService.getRootDownloadsPath();
|
||||
const files = await this.listFiles(root, root);
|
||||
|
||||
return {
|
||||
root,
|
||||
files: files.sort((a, b) => b.modifiedAt - a.modifiedAt),
|
||||
};
|
||||
}
|
||||
|
||||
private async listFiles(root: string, currentPath: string): Promise<ArchiveFileDto[]> {
|
||||
const entries = await fs.readdir(currentPath, { withFileTypes: true });
|
||||
const files: ArchiveFileDto[] = [];
|
||||
|
||||
for (const entry of entries) {
|
||||
const entryPath = this.utilsService.ensureInsideDownloadsRoot(
|
||||
resolve(currentPath, entry.name),
|
||||
);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
files.push(...await this.listFiles(root, entryPath));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry.isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const stat = await fs.stat(entryPath);
|
||||
|
||||
files.push({
|
||||
name: entry.name,
|
||||
path: relative(root, entryPath).split(/[\\/]+/).join('/'),
|
||||
sizeBytes: stat.size,
|
||||
modifiedAt: stat.mtimeMs,
|
||||
});
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,10 @@ enum WsTrackOperation {
|
||||
Delete = 'trackDelete',
|
||||
}
|
||||
|
||||
type ClientTrack = Omit<Partial<TrackEntity>, 'rejectedYoutubeUrls'> & {
|
||||
rejectedYoutubeUrls?: string[];
|
||||
};
|
||||
|
||||
@WebSocketGateway()
|
||||
@Injectable()
|
||||
export class TrackService {
|
||||
@@ -56,13 +60,14 @@ export class TrackService {
|
||||
this.io.emit(WsTrackOperation.Delete, { id });
|
||||
}
|
||||
|
||||
private toClientTrack(track: TrackEntity): Partial<TrackEntity> {
|
||||
private toClientTrack(track: TrackEntity): ClientTrack {
|
||||
return {
|
||||
id: track.id,
|
||||
artist: track.artist,
|
||||
name: track.name,
|
||||
spotifyUrl: track.spotifyUrl,
|
||||
youtubeUrl: track.youtubeUrl,
|
||||
rejectedYoutubeUrls: this.parseRejectedYoutubeUrls(track),
|
||||
downloadAttemptCount: track.downloadAttemptCount,
|
||||
status: track.status,
|
||||
error: track.error,
|
||||
|
||||
Reference in New Issue
Block a user