From a63a2c6dc5bb60937c7bbe384f97e519b4d8ce57 Mon Sep 17 00:00:00 2001 From: Manuel Ruwe Date: Sun, 18 Dec 2022 19:21:33 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Code=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.controller.spec.ts | 22 ------------------- src/app.controller.ts | 12 ---------- src/app.module.ts | 8 +++---- src/app.service.ts | 9 -------- src/clients/jellyfin/jellyfin.module.ts | 9 +------- src/clients/jellyfin/jellyfin.service.ts | 9 ++++++-- .../jellyfin.stream.builder.service.ts | 20 +++++++++++------ .../jellyfin/jellyfin.websocket.service.ts | 10 ++++++++- src/commands/pause.command.ts | 14 ++---------- src/commands/play.comands.ts | 2 +- src/commands/playlist.command.ts | 2 +- src/playback/playback.service.ts | 2 +- 12 files changed, 38 insertions(+), 81 deletions(-) delete mode 100644 src/app.controller.spec.ts delete mode 100644 src/app.controller.ts delete mode 100644 src/app.service.ts diff --git a/src/app.controller.spec.ts b/src/app.controller.spec.ts deleted file mode 100644 index d22f389..0000000 --- a/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/src/app.controller.ts b/src/app.controller.ts deleted file mode 100644 index cce879e..0000000 --- a/src/app.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { AppService } from './app.service'; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getHello(): string { - return this.appService.getHello(); - } -} diff --git a/src/app.module.ts b/src/app.module.ts index a8015a1..3490c27 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -5,12 +5,10 @@ import { DiscordModule } from '@discord-nestjs/core'; import { ConfigModule } from '@nestjs/config'; import { EventEmitterModule } from '@nestjs/event-emitter'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; +import { DiscordConfigService } from './clients/discord/discord.config.service'; import { DiscordClientModule } from './clients/discord/discord.module'; import { JellyfinClientModule } from './clients/jellyfin/jellyfin.module'; import { CommandModule } from './commands/command.module'; -import { DiscordConfigService } from './clients/discord/discord.config.service'; import { PlaybackModule } from './playback/playback.module'; @Module({ @@ -33,7 +31,7 @@ import { PlaybackModule } from './playback/playback.module'; JellyfinClientModule, PlaybackModule, ], - controllers: [AppController], - providers: [AppService], + controllers: [], + providers: [], }) export class AppModule {} diff --git a/src/app.service.ts b/src/app.service.ts deleted file mode 100644 index c699f07..0000000 --- a/src/app.service.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AppService { - constructor() {} - getHello(): string { - return 'Hello World!'; - } -} diff --git a/src/clients/jellyfin/jellyfin.module.ts b/src/clients/jellyfin/jellyfin.module.ts index 40e8818..ab59e96 100644 --- a/src/clients/jellyfin/jellyfin.module.ts +++ b/src/clients/jellyfin/jellyfin.module.ts @@ -20,10 +20,7 @@ import { JellyinWebsocketService } from './jellyfin.websocket.service'; ], }) export class JellyfinClientModule implements OnModuleInit, OnModuleDestroy { - constructor( - private jellyfinService: JellyfinService, - private readonly jellyfinWebsocketService: JellyinWebsocketService, - ) {} + constructor(private jellyfinService: JellyfinService) {} onModuleDestroy() { this.jellyfinService.destroy(); @@ -32,9 +29,5 @@ export class JellyfinClientModule implements OnModuleInit, OnModuleDestroy { onModuleInit() { this.jellyfinService.init(); this.jellyfinService.authenticate(); - - setTimeout(() => { - this.jellyfinWebsocketService.openSocket(); - }, 5000); } } diff --git a/src/clients/jellyfin/jellyfin.service.ts b/src/clients/jellyfin/jellyfin.service.ts index 5bcfa21..fdab370 100644 --- a/src/clients/jellyfin/jellyfin.service.ts +++ b/src/clients/jellyfin/jellyfin.service.ts @@ -4,6 +4,7 @@ import { Api, Jellyfin } from '@jellyfin/sdk'; import { Constants } from '../../utils/constants'; import { SystemApi } from '@jellyfin/sdk/lib/generated-client/api/system-api'; import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; +import { EventEmitter2 } from '@nestjs/event-emitter'; @Injectable() export class JellyfinService { @@ -13,6 +14,8 @@ export class JellyfinService { private systemApi: SystemApi; private userId: string; + constructor(private readonly eventEmitter: EventEmitter2) {} + init() { this.jellyfin = new Jellyfin({ clientInfo: { @@ -20,8 +23,8 @@ export class JellyfinService { version: Constants.Metadata.Version, }, deviceInfo: { - id: 'test', - name: 'test', + id: 'jellyfin-discord-bot', + name: 'Jellyfin Discord Bot', }, }); @@ -49,6 +52,8 @@ export class JellyfinService { this.userId = response.data.SessionInfo.UserId; this.systemApi = getSystemApi(this.api); + + this.eventEmitter.emit('clients.jellyfin.ready'); }) .catch((test) => { this.logger.error(test); diff --git a/src/clients/jellyfin/jellyfin.stream.builder.service.ts b/src/clients/jellyfin/jellyfin.stream.builder.service.ts index 41741de..f8d6e8b 100644 --- a/src/clients/jellyfin/jellyfin.stream.builder.service.ts +++ b/src/clients/jellyfin/jellyfin.stream.builder.service.ts @@ -16,14 +16,20 @@ export class JellyfinStreamBuilderService { const accessToken = this.jellyfinService.getApi().accessToken; - const url = encodeURI( - `${ - api.basePath - }/Audio/${jellyfinItemId}/universal?UserId=${this.jellyfinService.getUserId()}&DeviceId=${ - this.jellyfinService.getJellyfin().clientInfo.name - }&MaxStreamingBitrate=${bitrate}&Container=ogg,opus&AudioCodec=opus&TranscodingContainer=ts&TranscodingProtocol=hls&api_key=${accessToken}`, + const uri = new URL(api.basePath); + uri.pathname = `/Audio/${jellyfinItemId}/universal`; + uri.searchParams.set('UserId', this.jellyfinService.getUserId()); + uri.searchParams.set( + 'DeviceId', + this.jellyfinService.getJellyfin().clientInfo.name, ); + uri.searchParams.set('MaxStreamingBitrate', `${bitrate}`); + uri.searchParams.set('Container', 'ogg,opus'); + uri.searchParams.set('AudioCodec', 'opus'); + uri.searchParams.set('TranscodingContainer', 'ts'); + uri.searchParams.set('TranscodingProtocol', 'hls'); + uri.searchParams.set('api_key', accessToken); - return url; + return uri.toString(); } } diff --git a/src/clients/jellyfin/jellyfin.websocket.service.ts b/src/clients/jellyfin/jellyfin.websocket.service.ts index b7c447d..e99ef76 100644 --- a/src/clients/jellyfin/jellyfin.websocket.service.ts +++ b/src/clients/jellyfin/jellyfin.websocket.service.ts @@ -2,12 +2,20 @@ import { Injectable } from '@nestjs/common'; import { JellyfinService } from './jellyfin.service'; import { getPlaystateApi } from '@jellyfin/sdk/lib/utils/api/playstate-api'; +import { OnEvent } from '@nestjs/event-emitter'; @Injectable() export class JellyinWebsocketService { constructor(private readonly jellyfinClientManager: JellyfinService) {} - async openSocket() { + @OnEvent('clients.jellyfin.ready') + handleJellyfinBotReady() { + console.log('ready!'); + + this.openSocket(); + } + + private async openSocket() { const systemApi = getPlaystateApi(this.jellyfinClientManager.getApi()); // TODO: Write socket playstate api to report playback progress diff --git a/src/commands/pause.command.ts b/src/commands/pause.command.ts index 6626ad8..3fc4e61 100644 --- a/src/commands/pause.command.ts +++ b/src/commands/pause.command.ts @@ -19,22 +19,12 @@ export class PausePlaybackCommand implements DiscordCommand { handler( commandInteraction: CommandInteraction, ): string | InteractionReplyOptions { - const newStatus = this.discordVoiceService.togglePaused(); - - if (newStatus) { - return { - embeds: [ - this.discordMessageService.buildMessage({ - title: 'Paused', - }), - ], - }; - } + const shouldBePaused = this.discordVoiceService.togglePaused(); return { embeds: [ this.discordMessageService.buildMessage({ - title: 'Unpaused', + title: shouldBePaused ? 'Paused' : 'Unpaused', }), ], }; diff --git a/src/commands/play.comands.ts b/src/commands/play.comands.ts index dbead9e..a2f0a2a 100644 --- a/src/commands/play.comands.ts +++ b/src/commands/play.comands.ts @@ -245,7 +245,7 @@ export class PlayItemCommand const milliseconds = jellyfinPlayable.RunTimeTicks / 10000; - return this.playbackService.eneuqueTrack({ + return this.playbackService.enqueueTrack({ jellyfinId: jellyfinPlayable.Id, name: jellyfinPlayable.Name, durationInMilliseconds: milliseconds, diff --git a/src/commands/playlist.command.ts b/src/commands/playlist.command.ts index 138db8c..46e7e1d 100644 --- a/src/commands/playlist.command.ts +++ b/src/commands/playlist.command.ts @@ -43,7 +43,7 @@ export class PlaylistCommand implements DiscordCommand { let point = this.getListPoint(isCurrent, index); point += `**${trimStringToFixedLength(track.track.name, 30)}**`; - if (isCurrent === true) { + if (isCurrent) { point += ' :loud_sound:'; } diff --git a/src/playback/playback.service.ts b/src/playback/playback.service.ts index beb4034..9d341b4 100644 --- a/src/playback/playback.service.ts +++ b/src/playback/playback.service.ts @@ -64,7 +64,7 @@ export class PlaybackService { return true; } - eneuqueTrack(track: Track) { + enqueueTrack(track: Track) { const uuid = uuidv4(); const emptyBefore = this.playlist.tracks.length === 0;