From 1dbdd0a36641181a0ac576ec75c0300228bd0142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 11 Oct 2019 16:05:14 +0200 Subject: [PATCH] ElectronPlatform: Add support for a event index using Seshat. --- electron_app/package.json | 8 +- electron_app/src/electron-main.js | 116 ++++++++++++++++++++++++ package.json | 4 +- src/vector/platform/ElectronPlatform.js | 44 +++++++++ 4 files changed, 170 insertions(+), 2 deletions(-) diff --git a/electron_app/package.json b/electron_app/package.json index f7a70bce61..7986b1fd03 100644 --- a/electron_app/package.json +++ b/electron_app/package.json @@ -5,11 +5,17 @@ "version": "1.4.2", "description": "A feature-rich client for Matrix.org", "author": "New Vector Ltd.", + "scripts": { + "build": "electron-build-env --electron 6.0.3 neon build seshat-node --release", + "postinstall": "yarn build" + }, "dependencies": { "auto-launch": "^5.0.1", "electron-store": "^2.0.0", "electron-window-state": "^4.1.0", "minimist": "^1.2.0", - "png-to-ico": "^1.0.2" + "png-to-ico": "^1.0.2", + "make-dir": "^3.0.0", + "seshat-node": "^0.2.0" } } diff --git a/electron_app/src/electron-main.js b/electron_app/src/electron-main.js index f061acd5f9..81647fe31c 100644 --- a/electron_app/src/electron-main.js +++ b/electron_app/src/electron-main.js @@ -39,6 +39,8 @@ const { migrateFromOldOrigin } = require('./originMigrator'); const windowStateKeeper = require('electron-window-state'); const Store = require('electron-store'); +const seshat = require('seshat-node'); +const makeDir = require('make-dir'); if (argv["help"]) { console.log("Options:"); @@ -82,8 +84,12 @@ try { // Could not load local config, this is expected in most cases. } + +const eventStorePath = path.join(app.getPath('userData'), 'EventStore'); const store = new Store({ name: "electron-config" }); +let eventIndex = null; + let mainWindow = null; global.appQuitting = false; global.minimizeToTray = store.get('minimizeToTray', true); @@ -149,6 +155,17 @@ autoUpdater.on('update-downloaded', (ev, releaseNotes, releaseName, releaseDate, ipcMain.on('ipcCall', async function(ev, payload) { if (!mainWindow) return; + const send_error = (id, e) => { + const error = { + message: e.message + } + + mainWindow.webContents.send('ipcReply', { + id:id, + error: error + }); + } + const args = payload.args || []; let ret; @@ -200,6 +217,105 @@ ipcMain.on('ipcCall', async function(ev, payload) { case 'getConfig': ret = vectorConfig; break; + + case 'initEventIndex': + if (args[0] && eventIndex === null) { + let p = path.normalize(path.join(eventStorePath, args[0])); + try { + await makeDir(p); + eventIndex = new seshat(p); + console.log("Initialized event store"); + } catch (e) { + send_error(payload.id, e); + return; + } + } + break; + + case 'deleteEventIndex': + await eventIndex.delete(); + eventIndex = null; + + case 'isEventIndexEmpty': + if (eventIndex === null) ret = true; + else ret = await eventIndex.isEmpty(); + break; + + case 'addEventToIndex': + try { + eventIndex.addEvent(args[0], args[1]); + } catch (e) { + send_error(payload.id, e); + return; + } + break; + + case 'commitLiveEvents': + try { + ret = await eventIndex.commit(); + } catch (e) { + send_error(payload.id, e); + return; + } + break; + + case 'searchEventIndex': + try { + ret = await eventIndex.search(args[0]); + } catch (e) { + send_error(payload.id, e); + return; + } + break; + + case 'addHistoricEvents': + if (eventIndex === null) ret = false; + else { + try { + ret = await eventIndex.addHistoricEvents( + args[0], args[1], args[2]); + } catch (e) { + send_error(payload.id, e); + return; + } + } + break; + + case 'removeCrawlerCheckpoint': + if (eventIndex === null) ret = false; + else { + try { + ret = await eventIndex.removeCrawlerCheckpoint(args[0]); + } catch (e) { + send_error(payload.id, e); + return; + } + } + break; + + case 'addCrawlerCheckpoint': + if (eventIndex === null) ret = false; + else { + try { + ret = await eventIndex.addCrawlerCheckpoint(args[0]); + } catch (e) { + send_error(payload.id, e); + return; + } + } + break; + + case 'loadCheckpoints': + if (eventIndex === null) ret = []; + else { + try { + ret = await eventIndex.loadCheckpoints(); + } catch (e) { + ret = []; + } + } + break; + default: mainWindow.webContents.send('ipcReply', { id: payload.id, diff --git a/package.json b/package.json index bd05b090df..0026891285 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,9 @@ "source-map-loader": "^0.2.4", "webpack": "^4.23.1", "webpack-cli": "^3.1.2", - "webpack-dev-server": "^3.1.11" + "webpack-dev-server": "^3.1.11", + "electron-build-env": "^0.2.0", + "neon-cli": "^0.3.1" }, "build": { "appId": "im.riot.app", diff --git a/src/vector/platform/ElectronPlatform.js b/src/vector/platform/ElectronPlatform.js index 8b01f86417..e50f287f1a 100644 --- a/src/vector/platform/ElectronPlatform.js +++ b/src/vector/platform/ElectronPlatform.js @@ -293,4 +293,48 @@ export default class ElectronPlatform extends VectorBasePlatform { callbacks.resolve(payload.reply); } } + + async initEventIndex(user_id: string): void { + return this._ipcCall('initEventIndex', user_id); + } + + supportsEventIndexing(): boolean { + return true + } + + async addEventToIndex(ev: {}, profile: {}) { + return this._ipcCall('addEventToIndex', ev, profile); + } + + async isEventIndexEmpty(): Promise { + return this._ipcCall('isEventIndexEmpty'); + } + + async commitLiveEvents(): Promise<{}> { + return this._ipcCall('commitLiveEvents'); + } + + async searchEventIndex(term: string): Promise<{}> { + return this._ipcCall('searchEventIndex', term); + } + + async addHistoricEvents(events: string, checkpoint = null, oldCheckpoint = null): Promise<{}> { + return this._ipcCall('addHistoricEvents', events, checkpoint, oldCheckpoint); + } + + async addCrawlerCheckpoint(checkpoint: {}): Promise<{}> { + return this._ipcCall('addCrawlerCheckpoint', checkpoint); + } + + async removeCrawlerCheckpoint(checkpoint: {}): Promise<{}> { + return this._ipcCall('removeCrawlerCheckpoint', checkpoint); + } + + async loadCheckpoints(checkpoint: {}): Promise<[{}]> { + return this._ipcCall('loadCheckpoints'); + } + + async deleteEventIndex(): Promise<> { + return this._ipcCall('deleteEventIndex'); + } }