From f0afa8740ddfbf9e308ec7f2d33c951ae2066567 Mon Sep 17 00:00:00 2001 From: Amaury Date: Fri, 25 Jun 2021 16:29:04 +0200 Subject: [PATCH] Reformat --- src/discordParser.ts | 226 ++++++++++++++++++------------------ src/implementableApi.ts | 44 +++---- src/index.ts | 4 +- src/logWriter.ts | 57 +++++---- src/peertubeRequester.ts | 243 +++++++++++++++++++-------------------- src/router.ts | 94 ++++++++------- 6 files changed, 328 insertions(+), 340 deletions(-) diff --git a/src/discordParser.ts b/src/discordParser.ts index 1a838ba..d2f5e27 100644 --- a/src/discordParser.ts +++ b/src/discordParser.ts @@ -1,139 +1,135 @@ -import { Client, Message, TextChannel } from 'discord.js'; -import { ImplementableApi } from './implementableApi'; +import { Client, Message, TextChannel } from "discord.js"; +import { ImplementableApi } from "./implementableApi"; -import { once as eventsOnce } from 'events'; +import { once as eventsOnce } from "events"; namespace DiscordParser { - export type Config = ImplementableApi.Config & { - token: string; - channelsId: { - idChannelYtb: string; - idChannelPeerTube: string; - }; - keyWord: string; + export type Config = ImplementableApi.Config & { + token: string; + channelsId: { + idChannelYtb: string; + idChannelPeerTube: string; }; + keyWord: string; + }; - export type ConstructorPattern = ImplementableApi.Config & { - botPrefix: string; - channels: { - ChannelYtb: TextChannel; - ChannelPeerTube: TextChannel; - }; - client: Client; + export type ConstructorPattern = ImplementableApi.Config & { + botPrefix: string; + channels: { + ChannelYtb: TextChannel; + ChannelPeerTube: TextChannel; }; + client: Client; + }; } type ChannelsType = { - ChannelYtb: TextChannel; - ChannelPeerTube: TextChannel; + ChannelYtb: TextChannel; + ChannelPeerTube: TextChannel; }; -type TBaseDiscordMessageType = ('addListener' | 'newEntriesNotify') & - ImplementableApi.TBaseMessageType; +type TBaseDiscordMessageType = ("addListener" | "newEntriesNotify") & + ImplementableApi.TBaseMessageType; class DiscordParser< - T extends TBaseDiscordMessageType + T extends TBaseDiscordMessageType > extends ImplementableApi { - readonly botPrefix: string; - readonly channels: { - [key: string]: TextChannel; - ChannelYtb: TextChannel; - ChannelPeerTube: TextChannel; + readonly botPrefix: string; + readonly channels: { + [key: string]: TextChannel; + ChannelYtb: TextChannel; + ChannelPeerTube: TextChannel; + }; + readonly client: Client; + + constructor(readonly config: DiscordParser.ConstructorPattern) { + super(config); + this.botPrefix = config.botPrefix; + this.channels = config.channels; + this.client = config.client; + this.settingEvents(); + } + + static async instanciate( + config: DiscordParser.Config + ): Promise> { + const client = new Client(); + client.login(config.token); + await eventsOnce(client, "ready"); + const channels: ChannelsType = { + ChannelPeerTube: this.getTextChannel( + client, + config.channelsId.idChannelPeerTube + ), + ChannelYtb: this.getTextChannel(client, config.channelsId.idChannelYtb), }; - readonly client: Client; - constructor(readonly config: DiscordParser.ConstructorPattern) { - super(config); - this.botPrefix = config.botPrefix; - this.channels = config.channels; - this.client = config.client; - this.settingEvents(); + return new DiscordParser({ + name: config.name, + channels: channels, + client: client, + botPrefix: config.keyWord, + }); + } + + private static getTextChannel(client: Client, id: string): TextChannel { + const channel = client.channels.resolve(id); + if (!channel || !(channel instanceof TextChannel)) + throw "Bad token or bad channel id. Be careful, the channel must be a TextChannel"; + return channel; + } + + public receivedMessage(message: ImplementableApi.Message) { + switch (message.type) { + case "newEntriesNotify": + this.sendMsgYtb( + `New YouTubes entries received :\n${message.rawContent.items.map( + (item: any) => + `Author : ${item.author}\nTitle: ${item.title}\nlink: ${item.link}` + )}` + ); + default: + break; } + } - static async instanciate( - config: DiscordParser.Config - ): Promise> { - const client = new Client(); - client.login(config.token); - await eventsOnce(client, 'ready'); - const channels: ChannelsType = { - ChannelPeerTube: this.getTextChannel( - client, - config.channelsId.idChannelPeerTube - ), - ChannelYtb: this.getTextChannel( - client, - config.channelsId.idChannelYtb - ), - }; + private async sendMsgYtb(message: string) { + const resolvedChannel = await this.channels; + resolvedChannel.ChannelYtb.send(message); + } + private async sendMsgPeerTube(message: string) { + const resolvedChannel = await this.channels; + resolvedChannel.ChannelPeerTube.send(message); + } - return new DiscordParser({ - name: config.name, - channels: channels, - client: client, - botPrefix: config.keyWord, - }); - } + private settingEvents(): void { + this.client.on("message", (message: Message) => { + const resolvedChannel = this.channels; + let id_arr: string[] = []; + for (const key in this.channels) id_arr.push(resolvedChannel[key].id); - private static getTextChannel(client: Client, id: string): TextChannel { - const channel = client.channels.resolve(id); - if (!channel || !(channel instanceof TextChannel)) - throw 'Bad token or bad channel id. Be careful, the channel must be a TextChannel'; - return channel; - } - - public receivedMessage(message: ImplementableApi.Message) { - switch (message.type) { - case 'newEntriesNotify': - this.sendMsgYtb( - `New YouTubes entries received :\n${message.rawContent.items.map( - (item: any) => - `Author : ${item.author}\nTitle: ${item.title}\nlink: ${item.link}` - )}` - ); - default: - break; + if (this.channels) + if (id_arr.includes(message.channel.id)) { + const msg_splitted = message.content.split(" "); + if (msg_splitted[0] === this.botPrefix) { + switch (msg_splitted[1]) { + case "add": + const send_message: ImplementableApi.Message = + { + rawContent: { + address: msg_splitted[2], + user: message.author.toString(), + date: message.createdAt.toUTCString(), + }, + type: "addListener", + }; + message.channel.send("Ceci est un feedback"); + this.emit("addListener", send_message); + } + } } - } - - private async sendMsgYtb(message: string) { - const resolvedChannel = await this.channels; - resolvedChannel.ChannelYtb.send(message); - } - private async sendMsgPeerTube(message: string) { - const resolvedChannel = await this.channels; - resolvedChannel.ChannelPeerTube.send(message); - } - - private settingEvents(): void { - this.client.on('message', (message: Message) => { - const resolvedChannel = this.channels; - let id_arr: string[] = []; - for (const key in this.channels) - id_arr.push(resolvedChannel[key].id); - - if (this.channels) - if (id_arr.includes(message.channel.id)) { - const msg_splitted = message.content.split(' '); - if (msg_splitted[0] === this.botPrefix) { - switch (msg_splitted[1]) { - case 'add': - const send_message: ImplementableApi.Message = - { - rawContent: { - address: msg_splitted[2], - user: message.author.toString(), - date: message.createdAt.toUTCString(), - }, - type: 'addListener', - }; - message.channel.send('Ceci est un feedback'); - this.emit('addListener', send_message); - } - } - } - }); - } + }); + } } export { DiscordParser }; diff --git a/src/implementableApi.ts b/src/implementableApi.ts index b010959..72ddf20 100644 --- a/src/implementableApi.ts +++ b/src/implementableApi.ts @@ -1,34 +1,34 @@ -import EventEmitter from 'events'; +import EventEmitter from "events"; namespace ImplementableApi { - export type Config = { - name: string; - }; + export type Config = { + name: string; + }; - /** - * [optional] idListener is the way to identificate the listener who's the src of the newEntries - * the type field permit to know which type of message it is - * rawContent field is the string content of the message - */ - export type Message = { - idListener?: number; - type: T | 'logging'; - rawContent: any; - }; - export type TBaseMessageType = string; + /** + * [optional] idListener is the way to identificate the listener who's the src of the newEntries + * the type field permit to know which type of message it is + * rawContent field is the string content of the message + */ + export type Message = { + idListener?: number; + type: T | "logging"; + rawContent: any; + }; + export type TBaseMessageType = string; } abstract class ImplementableApi< - T extends ImplementableApi.TBaseMessageType + T extends ImplementableApi.TBaseMessageType > extends EventEmitter { - readonly name: string; + readonly name: string; - constructor(readonly config: ImplementableApi.Config) { - super(); - this.name = config.name; - } + constructor(readonly config: ImplementableApi.Config) { + super(); + this.name = config.name; + } - public abstract receivedMessage(message: ImplementableApi.Message): void; + public abstract receivedMessage(message: ImplementableApi.Message): void; } export { ImplementableApi }; diff --git a/src/index.ts b/src/index.ts index 71ec4ff..bde6373 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ // export * as Router from "./router" -export {Router} from "./router" +export { Router } from "./router"; -export {ImplementableApi} from "./implementableApi" \ No newline at end of file +export { ImplementableApi } from "./implementableApi"; diff --git a/src/logWriter.ts b/src/logWriter.ts index 9d94695..8a55bbf 100644 --- a/src/logWriter.ts +++ b/src/logWriter.ts @@ -1,46 +1,43 @@ -import { ImplementableApi } from './implementableApi'; +import { ImplementableApi } from "./implementableApi"; -import pino, { Logger } from 'pino'; +import pino, { Logger } from "pino"; namespace LogWriter { - export type Config = ImplementableApi.Config & { - path: string; - }; + export type Config = ImplementableApi.Config & { + path: string; + }; } /** * check nodejs buffer et throttle */ class LogWriter extends ImplementableApi { - readonly path: string; - readonly logger: Logger; + readonly path: string; + readonly logger: Logger; - constructor(readonly config: LogWriter.Config) { - super(config); - this.path = config.path; + constructor(readonly config: LogWriter.Config) { + super(config); + this.path = config.path; - this.logger = pino(pino.destination({ dest: config.path })); - } + this.logger = pino(pino.destination({ dest: config.path })); + } - private writeMsg(message: string): void; - private writeMsg(message: ImplementableApi.Message): void; - private writeMsg(message: ImplementableApi.Message | string) { - if (typeof message !== 'string') - message = `[${message.type}] ${ - typeof message.rawContent === 'string' - ? message.rawContent - : JSON.stringify(message.rawContent) - } ${ - message.idListener ?? - `( listener_id : ${message.idListener} )\n` - }`; + private writeMsg(message: string): void; + private writeMsg(message: ImplementableApi.Message): void; + private writeMsg(message: ImplementableApi.Message | string) { + if (typeof message !== "string") + message = `[${message.type}] ${ + typeof message.rawContent === "string" + ? message.rawContent + : JSON.stringify(message.rawContent) + } ${message.idListener ?? `( listener_id : ${message.idListener} )\n`}`; - // const str = `[${new Date().toISOString()}] ${message}\n`; - this.logger.info(message); - } + // const str = `[${new Date().toISOString()}] ${message}\n`; + this.logger.info(message); + } - public receivedMessage(message: ImplementableApi.Message) { - this.writeMsg(message); - } + public receivedMessage(message: ImplementableApi.Message) { + this.writeMsg(message); + } } export { LogWriter }; diff --git a/src/peertubeRequester.ts b/src/peertubeRequester.ts index 43d7878..aa3bfd7 100644 --- a/src/peertubeRequester.ts +++ b/src/peertubeRequester.ts @@ -1,157 +1,154 @@ -import { ImplementableApi } from './implementableApi'; +import { ImplementableApi } from "./implementableApi"; // Api request lib -import fetch, { FetchError, Headers } from 'node-fetch'; -import { URLSearchParams } from 'url'; -import FormData from 'form-data'; -import dedent from 'ts-dedent'; +import fetch, { FetchError, Headers } from "node-fetch"; +import { URLSearchParams } from "url"; +import FormData from "form-data"; +import dedent from "ts-dedent"; namespace PeerTubeRequester { - export type Config = ImplementableApi.Config & { - domain_name: string; - username: string; - password: string; - }; + export type Config = ImplementableApi.Config & { + domain_name: string; + username: string; + password: string; + }; } type UploadInstruction = { - [key: string]: string; - channelId: string; - targetUrl: string; + [key: string]: string; + channelId: string; + targetUrl: string; }; type ClientToken = { - client_id: string; - client_secret: string; - grant_type: 'password'; - response_type: 'code'; - username: string; - password: string; + client_id: string; + client_secret: string; + grant_type: "password"; + response_type: "code"; + username: string; + password: string; }; type UserToken = { - access_token: string; - token_type: string; - expires_in: string; - refresh_token: string; + access_token: string; + token_type: string; + expires_in: string; + refresh_token: string; }; class PeerTubeRequester extends ImplementableApi { - readonly domain_name: string; - readonly username: string; - readonly password: string; + readonly domain_name: string; + readonly username: string; + readonly password: string; - constructor(readonly config: PeerTubeRequester.Config) { - super(config); - this.domain_name = config.domain_name; - this.username = config.username; - this.password = config.password; + constructor(readonly config: PeerTubeRequester.Config) { + super(config); + this.domain_name = config.domain_name; + this.username = config.username; + this.password = config.password; + } + + public async receivedMessage( + message: ImplementableApi.Message + ): Promise { + switch (message.type) { + case "newEntriesNotify": + await this.newEntriesNotify(message); + break; + default: + break; } + } - public async receivedMessage( - message: ImplementableApi.Message - ): Promise { - switch (message.type) { - case 'newEntriesNotify': - await this.newEntriesNotify(message); - break; - default: - break; - } - } - - private async newEntriesNotify( - message: ImplementableApi.Message - ): Promise { - // parse content - const items = message.rawContent['items']; - if (Array.isArray(items)) - for (const item of items) { - const media_group = item['media:group']; - const args: UploadInstruction = { - channelId: '848', // to do binding avec les idDeChaines Skeptikom - targetUrl: item.link, - }; - await this.apiRequest(args); - } - } - - private async apiRequest(message: UploadInstruction): Promise { - let response = await fetch( - `https://${this.domain_name}/api/v1/oauth-clients/local` - ); - if (!response.ok) { - throw new Error(response.statusText); // CRASH - } - const { client_id, client_secret } = await response.json(); - - const client_info: { [key: string]: string } = { - client_id, - client_secret, - grant_type: 'password', - response_type: 'code', - username: this.username, - password: this.password, + private async newEntriesNotify( + message: ImplementableApi.Message + ): Promise { + // parse content + const items = message.rawContent["items"]; + if (Array.isArray(items)) + for (const item of items) { + const media_group = item["media:group"]; + const args: UploadInstruction = { + channelId: "848", // to do binding avec les idDeChaines Skeptikom + targetUrl: item.link, }; + await this.apiRequest(args); + } + } - let myParams = new URLSearchParams(); - for (const key in client_info) myParams.append(key, client_info[key]); + private async apiRequest(message: UploadInstruction): Promise { + let response = await fetch( + `https://${this.domain_name}/api/v1/oauth-clients/local` + ); + if (!response.ok) { + throw new Error(response.statusText); // CRASH + } + const { client_id, client_secret } = await response.json(); - response = await fetch( - `https://${this.domain_name}/api/v1/users/token`, - { - method: 'post', - body: myParams, - } - ); - if (!response.ok) { - throw new Error(response.statusText); // CRASH - } - const { access_token } = await response.json(); + const client_info: { [key: string]: string } = { + client_id, + client_secret, + grant_type: "password", + response_type: "code", + username: this.username, + password: this.password, + }; - // Upload - const myUploadForm = new URLSearchParams(); - const myHeader = new Headers(); - myHeader.append('Authorization', `Bearer ${access_token}`); - for (const key in message) myUploadForm.append(key, message[key]); + let myParams = new URLSearchParams(); + for (const key in client_info) myParams.append(key, client_info[key]); - response = await fetch( - `https://${this.domain_name}/api/v1/videos/imports`, - { - method: 'post', - headers: myHeader, - body: myUploadForm, - } - ); + response = await fetch(`https://${this.domain_name}/api/v1/users/token`, { + method: "post", + body: myParams, + }); + if (!response.ok) { + throw new Error(response.statusText); // CRASH + } + const { access_token } = await response.json(); - if (!response.ok) { - switch (response.status) { - case 400: - throw new Error( - dedent`Your target URL was not accepted by the API.\ + // Upload + const myUploadForm = new URLSearchParams(); + const myHeader = new Headers(); + myHeader.append("Authorization", `Bearer ${access_token}`); + for (const key in message) myUploadForm.append(key, message[key]); + + response = await fetch( + `https://${this.domain_name}/api/v1/videos/imports`, + { + method: "post", + headers: myHeader, + body: myUploadForm, + } + ); + + if (!response.ok) { + switch (response.status) { + case 400: + throw new Error( + dedent`Your target URL was not accepted by the API.\ Actualy it's : ${message.targetUrl} ${response.statusText}` - ); - break; - case 403: - throw new Error(response.statusText); - break; - case 409: - throw new Error( - dedent`Oops, your instance had not allowed the HTTPS import.\ + ); + break; + case 403: + throw new Error(response.statusText); + break; + case 409: + throw new Error( + dedent`Oops, your instance had not allowed the HTTPS import.\ Contact your administrator. ${response.statusText}` - ); - break; - default: - throw new Error( - dedent`Oh, you resolved an undocumented issues.\ + ); + break; + default: + throw new Error( + dedent`Oh, you resolved an undocumented issues.\ Please report this on the git if you have the time. ERROR: ${response.statusText}` - ); - break; - } - } + ); + break; + } } + } } export { PeerTubeRequester }; diff --git a/src/router.ts b/src/router.ts index d4ce724..28c9b51 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,66 +1,64 @@ -import { ImplementableApi } from './implementableApi'; +import { ImplementableApi } from "./implementableApi"; -import EventEmitter from 'events'; +import EventEmitter from "events"; namespace Router { - export type EventsType = { - name: string; - type: 'emit' | 'received'; - }; - export type InternalConfig = { - events: EventsType[]; - }; + export type EventsType = { + name: string; + type: "emit" | "received"; + }; + export type InternalConfig = { + events: EventsType[]; + }; } class Router< - MessageType extends ImplementableApi.TBaseMessageType + MessageType extends ImplementableApi.TBaseMessageType > extends EventEmitter { - api_array: { [key: string]: ImplementableApi } = {}; - events: Router.EventsType[]; + api_array: { [key: string]: ImplementableApi } = {}; + events: Router.EventsType[]; - constructor(readonly config: Router.EventsType[]) { - super(); - this.events = config; - } + constructor(readonly config: Router.EventsType[]) { + super(); + this.events = config; + } - public injectDependency(api: ImplementableApi): void { - if (api.name in this.api_array) - throw `The api name '${api.name}' is already take`; - this.api_array[api.name] = api; + public injectDependency(api: ImplementableApi): void { + if (api.name in this.api_array) + throw `The api name '${api.name}' is already take`; + this.api_array[api.name] = api; - this.setEvents(api); + this.setEvents(api); + this.receivedMessage({ + rawContent: `The dependency \`${api.name}\` was well injected into the router`, + type: "logging", + }); + } + + private setEvents(api: ImplementableApi) { + for (const event of this.events.filter((ev) => ev.type === "received")) { + api.on(event.name, (obj: ImplementableApi.Message) => { this.receivedMessage({ - rawContent: `The dependency \`${api.name}\` was well injected into the router`, - type: 'logging', + type: "logging", + rawContent: `A message of type \`${obj.type}\` was emited by \`${api.name}\` with the event \`${event.name}\``, }); + this.emit(event.name, obj); + }); } + } - private setEvents(api: ImplementableApi) { - for (const event of this.events.filter( - (ev) => ev.type === 'received' - )) { - api.on(event.name, (obj: ImplementableApi.Message) => { - this.receivedMessage({ - type: 'logging', - rawContent: `A message of type \`${obj.type}\` was emited by \`${api.name}\` with the event \`${event.name}\``, - }); - this.emit(event.name, obj); - }); - } - } - - public receivedMessage(message: ImplementableApi.Message) { - this.redirectMessage({ - rawContent: `A message of type \`${message.type}\` was received`, - type: 'logging', - }); - this.redirectMessage(message); - } - private redirectMessage(message: ImplementableApi.Message) { - for (const api in this.api_array) - this.api_array[api].receivedMessage(message); - } + public receivedMessage(message: ImplementableApi.Message) { + this.redirectMessage({ + rawContent: `A message of type \`${message.type}\` was received`, + type: "logging", + }); + this.redirectMessage(message); + } + private redirectMessage(message: ImplementableApi.Message) { + for (const api in this.api_array) + this.api_array[api].receivedMessage(message); + } } export { Router };