Many refactors

This commit is contained in:
Will Hunt 2021-11-22 11:29:01 +00:00
parent 4e0fddfa32
commit 80dda1ca1a
6 changed files with 51 additions and 58 deletions

View File

@ -1,4 +1,3 @@
// eslint-disable-next-line no-undef
module.exports = { module.exports = {
root: true, root: true,
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',

View File

@ -5,7 +5,6 @@ import { BridgeConfig, parseRegistrationFile } from "../Config/Config";
import { Webhooks } from "../Webhooks"; import { Webhooks } from "../Webhooks";
import { MatrixSender } from "../MatrixSender"; import { MatrixSender } from "../MatrixSender";
import { UserNotificationWatcher } from "../Notifications/UserNotificationWatcher"; import { UserNotificationWatcher } from "../Notifications/UserNotificationWatcher";
LogWrapper.configureLogging("debug"); LogWrapper.configureLogging("debug");
const log = new LogWrapper("App"); const log = new LogWrapper("App");

View File

@ -156,11 +156,11 @@ export class ConnectionManager {
return connections; return connections;
} }
public getConnectionsForGithubIssue(org: string, repo: string, issueNumber: number): (GitHubIssueConnection|GitLabRepoConnection)[] { public getConnectionsForGithubIssue(org: string, repo: string, issueNumber: number): (GitHubIssueConnection|GitHubRepoConnection)[] {
org = org.toLowerCase(); org = org.toLowerCase();
repo = repo.toLowerCase(); repo = repo.toLowerCase();
return this.connections.filter((c) => (c instanceof GitHubIssueConnection && c.org === org && c.repo === repo && c.issueNumber === issueNumber) || return this.connections.filter((c) => (c instanceof GitHubIssueConnection && c.org === org && c.repo === repo && c.issueNumber === issueNumber) ||
(c instanceof GitHubRepoConnection && c.org === org && c.repo === repo)) as (GitHubIssueConnection|GitLabRepoConnection)[]; (c instanceof GitHubRepoConnection && c.org === org && c.repo === repo)) as (GitHubIssueConnection|GitHubRepoConnection)[];
} }
public getConnectionsForGithubRepo(org: string, repo: string): GitHubRepoConnection[] { public getConnectionsForGithubRepo(org: string, repo: string): GitHubRepoConnection[] {

View File

@ -1,20 +1,20 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/ban-ts-comment */
import { IConnection } from "./IConnection";
import { Appservice } from "matrix-bot-sdk"; import { Appservice } from "matrix-bot-sdk";
import { MatrixMessageContent, MatrixEvent, MatrixReactionContent } from "../MatrixEvent";
import markdown from "markdown-it";
import { UserTokenStore } from "../UserTokenStore";
import LogWrapper from "../LogWrapper";
import { CommentProcessor } from "../CommentProcessor";
import { Octokit } from "@octokit/rest";
import { MessageSenderClient } from "../MatrixSender";
import { FormatUtil } from "../FormatUtil";
import axios from "axios";
import { BotCommands, handleCommand, botCommand, compileBotCommands } from "../BotCommands"; import { BotCommands, handleCommand, botCommand, compileBotCommands } from "../BotCommands";
import { ReposGetResponseData } from "../Github/Types"; import { CommentProcessor } from "../CommentProcessor";
import { IssuesOpenedEvent, IssuesEditedEvent, PullRequestOpenedEvent, PullRequestClosedEvent, PullRequestReadyForReviewEvent, PullRequestReviewSubmittedEvent, ReleaseCreatedEvent } from "@octokit/webhooks-types"; import { FormatUtil } from "../FormatUtil";
import emoji from "node-emoji"; import { IConnection } from "./IConnection";
import { IssuesOpenedEvent, IssuesReopenedEvent, IssuesEditedEvent, PullRequestOpenedEvent, IssuesClosedEvent, PullRequestClosedEvent, PullRequestReadyForReviewEvent, PullRequestReviewSubmittedEvent, ReleaseCreatedEvent } from "@octokit/webhooks-types";
import { MatrixMessageContent, MatrixEvent, MatrixReactionContent } from "../MatrixEvent";
import { MessageSenderClient } from "../MatrixSender";
import { NotLoggedInError } from "../errors"; import { NotLoggedInError } from "../errors";
import { Octokit } from "@octokit/rest";
import { ReposGetResponseData } from "../Github/Types";
import { UserTokenStore } from "../UserTokenStore";
import axios from "axios";
import emoji from "node-emoji";
import LogWrapper from "../LogWrapper";
import markdown from "markdown-it";
const log = new LogWrapper("GitHubRepoConnection"); const log = new LogWrapper("GitHubRepoConnection");
const md = new markdown(); const md = new markdown();
@ -300,7 +300,7 @@ export class GitHubRepoConnection implements IConnection {
}); });
} }
public async onIssueStateChange(event: IssuesEditedEvent) { public async onIssueStateChange(event: IssuesEditedEvent|IssuesReopenedEvent|IssuesClosedEvent) {
if (this.shouldSkipHook('issue.changed', 'issue')) { if (this.shouldSkipHook('issue.changed', 'issue')) {
return; return;
} }

View File

@ -31,31 +31,51 @@ import LogWrapper from "./LogWrapper";
const log = new LogWrapper("GithubBridge"); const log = new LogWrapper("GithubBridge");
export class GithubBridge { export class GithubBridge {
private readonly as: Appservice;
private readonly storage: IBridgeStorageProvider;
private readonly messageClient: MessageSenderClient;
private readonly queue: MessageQueue;
private readonly commentProcessor: CommentProcessor;
private readonly notifProcessor: NotificationProcessor;
private readonly tokenStore: UserTokenStore;
private connectionManager?: ConnectionManager; private connectionManager?: ConnectionManager;
private github?: GithubInstance; private github?: GithubInstance;
private as!: Appservice;
private encryptedMatrixClient?: MatrixClient; private encryptedMatrixClient?: MatrixClient;
private adminRooms: Map<string, AdminRoom> = new Map(); private adminRooms: Map<string, AdminRoom> = new Map();
private commentProcessor!: CommentProcessor; private widgetApi: BridgeWidgetApi = new BridgeWidgetApi(this.adminRooms);
private notifProcessor!: NotificationProcessor;
private queue!: MessageQueue;
private tokenStore!: UserTokenStore;
private messageClient!: MessageSenderClient;
private widgetApi!: BridgeWidgetApi;
private ready = false; private ready = false;
constructor(private config: BridgeConfig, private registration: IAppserviceRegistration) { } constructor(private config: BridgeConfig, private registration: IAppserviceRegistration) {
if (this.config.queue.host && this.config.queue.port) {
log.info(`Initialising Redis storage (on ${this.config.queue.host}:${this.config.queue.port})`);
this.storage = new RedisStorageProvider(this.config.queue.host, this.config.queue.port);
} else {
log.info('Initialising memory storage');
this.storage = new MemoryStorageProvider();
}
this.as = new Appservice({
homeserverName: this.config.bridge.domain,
homeserverUrl: this.config.bridge.url,
port: this.config.bridge.port,
bindAddress: this.config.bridge.bindAddress,
registration: this.registration,
storage: this.storage,
});
this.queue = createMessageQueue(this.config);
this.messageClient = new MessageSenderClient(this.queue);
this.commentProcessor = new CommentProcessor(this.as, this.config.bridge.mediaUrl || this.config.bridge.url);
this.notifProcessor = new NotificationProcessor(this.storage, this.messageClient);
this.tokenStore = new UserTokenStore(this.config.passFile || "./passkey.pem", this.as.botIntent);
}
public stop() { public stop() {
this.as.stop(); this.as.stop();
if(this.queue.stop) this.queue.stop(); if (this.queue.stop) this.queue.stop();
} }
public async start() { public async start() {
log.info('Starting up'); log.info('Starting up');
this.queue = createMessageQueue(this.config);
this.messageClient = new MessageSenderClient(this.queue);
if (!this.config.github && !this.config.gitlab) { if (!this.config.github && !this.config.gitlab) {
log.error("You haven't configured support for GitHub or GitLab!"); log.error("You haven't configured support for GitHub or GitLab!");
@ -67,27 +87,6 @@ export class GithubBridge {
await this.github.start(); await this.github.start();
} }
let storage: IBridgeStorageProvider;
if (this.config.queue.host && this.config.queue.port) {
log.info(`Initialising Redis storage (on ${this.config.queue.host}:${this.config.queue.port})`);
storage = new RedisStorageProvider(this.config.queue.host, this.config.queue.port);
} else {
log.info('Initialising memory storage');
storage = new MemoryStorageProvider();
}
this.notifProcessor = new NotificationProcessor(storage, this.messageClient);
this.as = new Appservice({
homeserverName: this.config.bridge.domain,
homeserverUrl: this.config.bridge.url,
port: this.config.bridge.port,
bindAddress: this.config.bridge.bindAddress,
registration: this.registration,
storage,
});
this.as.expressAppInstance.get("/live", (_, res) => res.send({ok: true})); this.as.expressAppInstance.get("/live", (_, res) => res.send({ok: true}));
this.as.expressAppInstance.get("/ready", (_, res) => res.status(this.ready ? 200 : 500).send({ready: this.ready})); this.as.expressAppInstance.get("/ready", (_, res) => res.status(this.ready ? 200 : 500).send({ready: this.ready}));
@ -95,7 +94,7 @@ export class GithubBridge {
log.info(`Loading pantalaimon client`); log.info(`Loading pantalaimon client`);
const pan = new PantalaimonClient( const pan = new PantalaimonClient(
this.config.bridge.pantalaimon.url, this.config.bridge.pantalaimon.url,
storage, this.storage,
); );
this.encryptedMatrixClient = await pan.createClientWithCredentials( this.encryptedMatrixClient = await pan.createClientWithCredentials(
this.config.bridge.pantalaimon.username, this.config.bridge.pantalaimon.username,
@ -109,11 +108,7 @@ export class GithubBridge {
log.info(`Pan client is syncing`); log.info(`Pan client is syncing`);
} }
this.widgetApi = new BridgeWidgetApi(this.adminRooms);
this.commentProcessor = new CommentProcessor(this.as, this.config.bridge.mediaUrl || this.config.bridge.url);
this.tokenStore = new UserTokenStore(this.config.passFile || "./passkey.pem", this.as.botIntent);
await this.tokenStore.load(); await this.tokenStore.load();
const connManager = this.connectionManager = new ConnectionManager(this.as, const connManager = this.connectionManager = new ConnectionManager(this.as,
this.config, this.tokenStore, this.commentProcessor, this.messageClient, this.github); this.config, this.tokenStore, this.commentProcessor, this.messageClient, this.github);
@ -219,8 +214,9 @@ export class GithubBridge {
const connections = connManager.getConnectionsForGithubIssue(owner, repository.name, issue.number); const connections = connManager.getConnectionsForGithubIssue(owner, repository.name, issue.number);
connections.map(async (c) => { connections.map(async (c) => {
try { try {
if (c instanceof GitHubIssueConnection || c instanceof GitHubRepoConnection) if (c.onIssueStateChange) {
await c.onIssueStateChange(data); await c.onIssueStateChange(data);
}
} catch (ex) { } catch (ex) {
log.warn(`Connection ${c.toString()} failed to handle github.issues.reopened:`, ex); log.warn(`Connection ${c.toString()} failed to handle github.issues.reopened:`, ex);
} }
@ -228,7 +224,7 @@ export class GithubBridge {
}); });
this.queue.on<GitHubWebhookTypes.IssuesEditedEvent>("github.issues.edited", async ({ data }) => { this.queue.on<GitHubWebhookTypes.IssuesEditedEvent>("github.issues.edited", async ({ data }) => {
const { repository, issue, owner } = validateRepoIssue(data); const { repository, owner } = validateRepoIssue(data);
const connections = connManager.getConnectionsForGithubRepo(owner, repository.name); const connections = connManager.getConnectionsForGithubRepo(owner, repository.name);
connections.map(async (c) => { connections.map(async (c) => {
try { try {

View File

@ -5,7 +5,6 @@ const mq = createMessageQueue({
queue: { queue: {
monolithic: true, monolithic: true,
}, },
// tslint:disable-next-line: no-any
} as any); } as any);
describe("MessageQueueTest", () => { describe("MessageQueueTest", () => {