From 3740087044e43edb95cd39e84ed56c1d060b2197 Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Fri, 17 May 2019 17:44:23 +0100
Subject: [PATCH] Get tools to build

---
 src/bot.ts                   |  3 +--
 src/discordas.ts             |  2 +-
 tools/addRoomsToDirectory.ts | 43 ++++++---------------------------
 tools/adminme.ts             | 32 +++++++++---------------
 tools/chanfix.ts             | 34 +++++---------------------
 tools/ghostfix.ts            | 47 +++---------------------------------
 tools/toolshelper.ts         | 36 +++++++++++++++++++++++++++
 tsconfig.json                |  2 +-
 8 files changed, 69 insertions(+), 130 deletions(-)
 create mode 100644 tools/toolshelper.ts

diff --git a/src/bot.ts b/src/bot.ts
index 214d1d0..4eb8ee9 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -84,7 +84,6 @@ export class DiscordBot {
     private channelLocks: { [channelId: string]: {p: Promise<{}>, i: NodeJS.Timeout|null} };
 
     constructor(
-        private botUserId: string,
         private config: DiscordBridgeConfig,
         private bridge: Appservice,
         private store: DiscordStore,
@@ -123,7 +122,7 @@ export class DiscordBot {
     }
 
     get BotUserId(): string {
-        return this.botUserId;
+        return this.bridge.botUserId;
     }
 
     get RoomHandler(): MatrixRoomHandler {
diff --git a/src/discordas.ts b/src/discordas.ts
index 51e6b4e..9d72fba 100644
--- a/src/discordas.ts
+++ b/src/discordas.ts
@@ -156,7 +156,7 @@ async function run() {
         process.exit(1);
     }
 
-    const discordbot = new DiscordBot(appservice.botUserId, config, appservice, store);
+    const discordbot = new DiscordBot(config, appservice, store);
     const roomhandler = discordbot.RoomHandler;
     const eventProcessor = discordbot.MxEventProcessor;
 
diff --git a/tools/addRoomsToDirectory.ts b/tools/addRoomsToDirectory.ts
index 6b0c056..5b2f184 100644
--- a/tools/addRoomsToDirectory.ts
+++ b/tools/addRoomsToDirectory.ts
@@ -19,14 +19,11 @@ limitations under the License.
  * Allows you to become an admin for a room the bot is in control of.
  */
 
-import * as yaml from "js-yaml";
-import * as fs from "fs";
 import * as args from "command-line-args";
 import * as usage from "command-line-usage";
-import { DiscordBridgeConfig } from "../src/config";
 import { Log } from "../src/log";
 import { Util } from "../src/util";
-import { DiscordStore } from "../src/store";
+import { ToolsHelper } from "./toolshelper";
 const log = new Log("AddRoomsToDirectory");
 const optionDefinitions = [
     {
@@ -44,10 +41,10 @@ const optionDefinitions = [
         typeLabel: "<config.yaml>",
     },
     {
-        alias: "s",
+        alias: "r",
         defaultValue: "room-store.db",
-        description: "The location of the room store.",
-        name: "store",
+        description: "The location of the registration file.",
+        name: "reg",
         type: String,
     },
 ];
@@ -68,50 +65,26 @@ if (options.help) {
     ]));
     process.exit(0);
 }
-const yamlConfig = yaml.safeLoad(fs.readFileSync("./discord-registration.yaml", "utf8"));
-const registration = AppServiceRegistration.fromObject(yamlConfig);
-const config: DiscordBridgeConfig = yaml.safeLoad(fs.readFileSync(options.config, "utf8")) as DiscordBridgeConfig;
 
-if (registration === null) {
-    throw new Error("Failed to parse registration file");
-}
-
-const clientFactory = new ClientFactory({
-    appServiceUserId: `@${registration.sender_localpart}:${config.bridge.domain}`,
-    token: registration.as_token,
-    url: config.bridge.homeserverUrl,
-});
-
-const bridge = new Bridge({
-    controller: {
-        onEvent: () => { },
-    },
-    domain: "rubbish",
-    homeserverUrl: true,
-    registration: true,
-});
-
-const discordstore = new DiscordStore(config.database ? config.database.filename : "discord.db");
+const {store, appservice} = ToolsHelper.getToolDependencies(options.config, options.reg);
 
 async function run() {
     try {
-        await discordstore.init();
+        await store!.init();
     } catch (e) {
         log.error(`Failed to load database`, e);
     }
-    let rooms = await discordstore.roomStore.getEntriesByRemoteRoomData({
+    let rooms = await store!.roomStore.getEntriesByRemoteRoomData({
         discord_type: "text",
     });
     rooms = rooms.filter((r) => r.remote && r.remote.get("plumbed") !== true );
-    const client = clientFactory.getClientAs();
     log.info(`Got ${rooms.length} rooms to set`);
     try {
         await Util.AsyncForEach(rooms, async (room) => {
             const guild = room.remote.get("discord_guild");
             const roomId = room.matrix.getId();
             try {
-                await client.setRoomDirectoryVisibilityAppService(
-                    guild,
+                await appservice.botIntent.underlyingClient.setDirectoryVisibility(
                     roomId,
                     "public",
                 );
diff --git a/tools/adminme.ts b/tools/adminme.ts
index 4ee728b..eaf4f0d 100644
--- a/tools/adminme.ts
+++ b/tools/adminme.ts
@@ -16,14 +16,12 @@ limitations under the License.
 
 /* tslint:disable:no-console */
 /**
- * Allows you to become an admin for a room the bot is in control of.
+ * Allows you to become an admin for a room that the bot is in control of.
  */
 
-import * as yaml from "js-yaml";
-import * as fs from "fs";
 import * as args from "command-line-args";
 import * as usage from "command-line-usage";
-import { DiscordBridgeConfig } from "../src/config";
+import { ToolsHelper } from "./toolshelper";
 
 const optionDefinitions = [
     {
@@ -89,25 +87,19 @@ if (!options.userid) {
     process.exit(1);
 }
 
-const yamlConfig = yaml.safeLoad(fs.readFileSync("discord-registration.yaml", "utf8"));
-const registration = AppServiceRegistration.fromObject(yamlConfig);
-const config: DiscordBridgeConfig = yaml.safeLoad(fs.readFileSync(options.config, "utf8")) as DiscordBridgeConfig;
-
-if (registration === null) {
-    throw new Error("Failed to parse registration file");
-}
-
-const clientFactory = new ClientFactory({
-    appServiceUserId: `@${registration.sender_localpart}:${config.bridge.domain}`,
-    token: registration.as_token,
-    url: config.bridge.homeserverUrl,
-});
-const client = clientFactory.getClientAs();
-const intent = new Intent(client, client, {registered: true});
+const {appservice} = ToolsHelper.getToolDependencies(options.config, options.reg, false);
 
 async function run() {
     try {
-        await intent.setPowerLevel(options.roomid, options.userid, options.power);
+        const powerLevels = (await appservice.botIntent.underlyingClient.getRoomStateEvent(
+            options.roomId, "m.room.power_levels", "",
+        )).content;
+
+        powerLevels.users[options.userid] = options.power;
+
+        await appservice.botIntent.underlyingClient.sendStateEvent(
+            options.roomid, "m.room.power_levels", "", powerLevels,
+        );
         console.log("Power levels set");
         process.exit(0);
     } catch (err) {
diff --git a/tools/chanfix.ts b/tools/chanfix.ts
index 407fc8e..a4fa45f 100644
--- a/tools/chanfix.ts
+++ b/tools/chanfix.ts
@@ -14,16 +14,12 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-import * as yaml from "js-yaml";
-import * as fs from "fs";
 import * as args from "command-line-args";
 import * as usage from "command-line-usage";
-import { DiscordBridgeConfig } from "../src/config";
 import { DiscordBot } from "../src/bot";
-import { DiscordStore } from "../src/store";
 import { Log } from "../src/log";
 import { Util } from "../src/util";
-import { Appservice } from "matrix-bot-sdk";
+import { ToolsHelper } from "./toolshelper";
 
 const log = new Log("ChanFix");
 
@@ -62,34 +58,16 @@ if (options.help) {
     process.exit(0);
 }
 
-const registration = yaml.safeLoad(fs.readFileSync("./discord-registration.yaml", "utf8"));
-const config = new DiscordBridgeConfig();
-config.ApplyConfig(yaml.safeLoad(fs.readFileSync(options.config, "utf8")) as DiscordBridgeConfig);
-
-if (registration === null) {
-    throw new Error("Failed to parse registration file");
-}
-
-const botUserId = `@${registration.sender_localpart}:${config.bridge.domain}`;
-
-const bridge = new Appservice({
-    registration,
-    port: 0,
-    bindAddress: "",
-    homeserverUrl: config.bridge.homeserverUrl,
-    homeserverName: config.bridge.domain,
-});
-
 async function run() {
-    const store = new DiscordStore(config.database);
-    await store.init();
-    const discordbot = new DiscordBot(botUserId, config, bridge, store);
+    const {store, appservice, config} = ToolsHelper.getToolDependencies(options.config);
+    await store!.init();
+    const discordbot = new DiscordBot(config, appservice, store!);
     await discordbot.init();
     await discordbot.ClientFactory.init();
     const client = await discordbot.ClientFactory.getClient();
 
     // first set update_icon to true if needed
-    const mxRoomEntries = await store.roomStore.getEntriesByRemoteRoomData({
+    const mxRoomEntries = await store!.roomStore.getEntriesByRemoteRoomData({
         update_name: true,
         update_topic: true,
     });
@@ -104,7 +82,7 @@ async function run() {
             return; // skipping because something was set manually
         }
         entry.remote!.set("update_icon", true);
-        promiseList.push(store.roomStore.upsertEntry(entry));
+        promiseList.push(store!.roomStore.upsertEntry(entry));
     });
     await Promise.all(promiseList);
 
diff --git a/tools/ghostfix.ts b/tools/ghostfix.ts
index 9ce61d6..f8e9d6c 100644
--- a/tools/ghostfix.ts
+++ b/tools/ghostfix.ts
@@ -14,16 +14,12 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-import { AppServiceRegistration, ClientFactory, Bridge } from "matrix-appservice-bridge";
-import * as yaml from "js-yaml";
-import * as fs from "fs";
 import * as args from "command-line-args";
 import * as usage from "command-line-usage";
-import { DiscordBridgeConfig } from "../src/config";
 import { Log } from "../src/log";
 import { Util } from "../src/util";
 import { DiscordBot } from "../src/bot";
-import { DiscordStore } from "../src/store";
+import { ToolsHelper } from "./toolshelper";
 
 const log = new Log("GhostFix");
 
@@ -73,46 +69,11 @@ if (options.help) {
     process.exit(0);
 }
 
-const yamlConfig = yaml.safeLoad(fs.readFileSync("./discord-registration.yaml", "utf8"));
-const registration = AppServiceRegistration.fromObject(yamlConfig);
-const config = new DiscordBridgeConfig();
-config.ApplyConfig(yaml.safeLoad(fs.readFileSync(options.config, "utf8")) as DiscordBridgeConfig);
-
-if (registration === null) {
-    throw new Error("Failed to parse registration file");
-}
-
-const botUserId = `@${registration.sender_localpart}:${config.bridge.domain}`;
-const clientFactory = new ClientFactory({
-    appServiceUserId: botUserId,
-    token: registration.as_token,
-    url: config.bridge.homeserverUrl,
-});
-
-const bridge = new Bridge({
-    clientFactory,
-    controller: {
-        onEvent: () => { },
-    },
-    domain: config.bridge.domain,
-    homeserverUrl: config.bridge.homeserverUrl,
-    intentOptions: {
-        clients: {
-            dontJoin: true, // handled manually
-      },
-    },
-    registration,
-    roomStore: config.database.roomStorePath,
-    userStore: config.database.userStorePath,
-});
-
 async function run() {
-    await bridge.loadDatabases();
-    const store = new DiscordStore(config.database);
-    await store.init(undefined, bridge.getRoomStore());
-    const discordbot = new DiscordBot(botUserId, config, bridge, store);
+    const {store, appservice, config} = ToolsHelper.getToolDependencies(options.config);
+    await store!.init();
+    const discordbot = new DiscordBot(config, appservice, store!);
     await discordbot.init();
-    bridge._clientFactory = clientFactory;
     const client = await discordbot.ClientFactory.getClient();
 
     const promiseList: Promise<void>[] = [];
diff --git a/tools/toolshelper.ts b/tools/toolshelper.ts
new file mode 100644
index 0000000..1d55842
--- /dev/null
+++ b/tools/toolshelper.ts
@@ -0,0 +1,36 @@
+import { DiscordBridgeConfig } from "../src/config";
+import { Appservice } from "matrix-bot-sdk";
+import { DiscordStore } from "../src/store";
+import * as yaml from "js-yaml";
+import * as fs from "fs";
+
+export class ToolsHelper {
+    public static getToolDependencies(
+        configFile: string, regFile: string = "./discord-registration.yaml", needsStore: boolean = true): {
+        store: DiscordStore|null,
+        appservice: Appservice,
+        config: DiscordBridgeConfig,
+    } {
+        const registration = yaml.safeLoad(fs.readFileSync(regFile, "utf8"));
+        const config: DiscordBridgeConfig = yaml.safeLoad(fs.readFileSync(configFile, "utf8")) as DiscordBridgeConfig;
+
+        if (registration === null) {
+            throw Error("Failed to parse registration file");
+        }
+
+        const appservice = new Appservice({
+            bindAddress: "notathing",
+            homeserverName: config.bridge.domain,
+            homeserverUrl: config.bridge.homeserverUrl,
+            port: 0,
+            registration,
+        });
+
+        const store = needsStore ? new DiscordStore(config.database ? config.database.filename : "discord.db") : null;
+        return {
+            appservice,
+            config,
+            store,
+        };
+    }
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index e6dad2a..2da4349 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,6 +12,6 @@
     "compileOnSave": true,
     "include": [
         "src/**/*",
-        "test/**/*",
+        "tools/**/*",
     ]
 }
-- 
GitLab