diff --git a/services/request/.env.example b/services/request/.env.example index 8db03d8..fdc7ff7 100644 --- a/services/request/.env.example +++ b/services/request/.env.example @@ -1,7 +1,17 @@ +# Keys --------------------------------------------------------------------------------------------- + # Application key to sign stuff APP_KEY_FILE = /run/secrets/app_key -# Database credentials +# Discord bot token +DISCORD_BOT_KEY_FILE = /run/secrets/discord_bot_key + +# TVDB API key +TVDB_KEY_FILE = /run/secrets/tvdb_key +TVDB_PIN = + +# Database ----------------------------------------------------------------------------------------- + DB_TYPE = mysql DB_HOST = database DB_PORT = 3306 @@ -16,6 +26,3 @@ TORRENT_CLIENT_IPC_SOCKET = /tmp/torrent_client.sock # Web server port WEBSERVER_PORT = 3200 - -# Discord bot token -DISCORD_BOT_TOKEN = diff --git a/services/request/src/server/Application.ts b/services/request/src/server/Application.ts index 2a9f4fd..2fff703 100644 --- a/services/request/src/server/Application.ts +++ b/services/request/src/server/Application.ts @@ -1,17 +1,19 @@ -import DiscordBot from "./services/DiscordBot"; +import services from "./services"; import Service from "./services/Service"; -import TorrentClientIpc from "./services/TorrentClientIpc"; -import WebServer from "./services/WebServer"; import { User, RegisterToken } from "./database/entities"; -import Database from "./services/Database"; +import assert from "assert"; -let instance: Application; +interface ServiceMap { + [name: string]: Service +} /** * The main application class */ export default class Application { + private static __instance: Application; + /** * The application key used for signing stuff */ @@ -20,56 +22,40 @@ export default class Application /** * All available services */ - protected services: Service[]; - - /** - * The database service - */ - protected database!: Database; - - /** - * The discord bot service - */ - protected discord!: DiscordBot; - - /** - * The webserver service - */ - protected web!: WebServer; - - /** - * The torrent client service - */ - protected torrent!: TorrentClientIpc; + protected services: ServiceMap = {}; /** * Return the current application instance */ public static instance() { - return instance; + return this.__instance; } /** * Create a new application instance */ public constructor(appKey: string) { - instance = this; + Application.__instance = this; this.APP_KEY = appKey; - this.services = [ - this.database = new Database(this), - // this.discord = new DiscordBot(this), - this.web = new WebServer(this), - // this.torrent = new TorrentClientIpc(this) - ] + for (let ServiceClass of Object.values(services)) { + this.installService(ServiceClass); + } + } - // this.torrent.logging = false; + /** + * Install a service into the application + */ + protected installService(ServiceClass: new (app: Application) => Service) { + let service = new ServiceClass(this); + this.services[service.name] = service; } /** * Boot the application and all of the services */ protected async boot() { - return Promise.all(this.services.map(service => service.boot())); + let services = Object.values(this.services); + return Promise.all(services.map(service => service.boot())); } /** @@ -91,7 +77,8 @@ export default class Application * Shutdown the application */ protected shutdown() { - return Promise.all(this.services.map(service => service.shutdown())); + let services = Object.values(this.services); + return Promise.all(services.map(service => service.shutdown())); } /** @@ -100,7 +87,9 @@ export default class Application public async start() { await this.boot(); await this.initialize(); - this.services.forEach(service => service.start()); + for (let service of Object.values(this.services)) { + service.start(); + } } /** @@ -110,4 +99,21 @@ export default class Application await this.shutdown(); process.exit(code); } + + // Access -------------------------------------------------------------------------------------- + + /** + * Get all available services + */ + public serviceList() { + return Object.keys(this.services); + } + + /** + * Get an application service instance + */ + public service(serviceName: string) { + assert(serviceName in this.services); + return this.services[serviceName]; + } } diff --git a/services/request/src/server/services/Service.ts b/services/request/src/server/services/Service.ts index 04cfffb..61c0d2a 100644 --- a/services/request/src/server/services/Service.ts +++ b/services/request/src/server/services/Service.ts @@ -2,7 +2,10 @@ import Application from "../Application"; export default abstract class Service { - private readonly __name: string; + /** + * The name of the service + */ + public readonly name: string; /** * The application instance @@ -19,7 +22,7 @@ export default abstract class Service */ public constructor(name: string, app: Application) { this.app = app; - this.__name = name; + this.name = name; } // Required Service Implementation ------------------------------------------------------------- @@ -44,12 +47,12 @@ export default abstract class Service }; /** - * Log to the console + * Service-specific logging */ - protected log(...args: any[]) { + public log(...args: any[]) { if (!this.logging) { return; } - console.log(`[${this.__name}]:`, ...args); + console.log(`[${this.name}]:`, ...args); } } diff --git a/services/request/src/server/services/TvDb.ts b/services/request/src/server/services/TvDb.ts index e69de29..1ac8b99 100644 --- a/services/request/src/server/services/TvDb.ts +++ b/services/request/src/server/services/TvDb.ts @@ -0,0 +1,34 @@ +import { readFile } from "fs/promises"; +import Application from "@server/Application"; +import TVDB from "tvdb-v4"; +import Service from "./Service"; + +export default class TvDb extends Service +{ + /** + * The active TVDB instance + */ + protected tvdb!: TVDB; + + /** + * Create a new TvDb service instance + */ + public constructor(app: Application) { + super("TVDB", app); + this.tvdb; + } + + /** + * Boot the service + */ + public async boot() { + let apiKey = await readFile(process.env["TVDB_KEY_FILE"]); + } + + /** + * Shutdown the service + */ + public async shutdown() { + + } +} diff --git a/services/request/src/server/services/index.ts b/services/request/src/server/services/index.ts new file mode 100644 index 0000000..e232f54 --- /dev/null +++ b/services/request/src/server/services/index.ts @@ -0,0 +1,15 @@ +import Database from "./Database"; +import DiscordBot from "./DiscordBot"; +import MovieSearch from "./MovieSearch"; +import TorrentClientIpc from "./TorrentClientIpc"; +import TvDb from "./TvDb"; +import WebServer from "./WebServer"; + +export default { + Database, + // DiscordBot, + MovieSearch, + // TorrentClientIpc, + TvDb, + WebServer +}