UNPKG

@mieweb/wikigdrive

Version:

Google Drive to MarkDown synchronization

190 lines (189 loc) 7.59 kB
import "../../_dnt.polyfills.js"; import process from 'node:process'; import { EventEmitter } from 'node:events'; import minimist from 'minimist'; import dotenv from 'dotenv'; import { addTelemetry } from '../telemetry.js'; import { createLogger } from '../utils/logger/logger.js'; import { ContainerEngine } from '../ContainerEngine.js'; import { GoogleApiContainer } from '../containers/google_api/GoogleApiContainer.js'; import { FileContentService } from '../utils/FileContentService.js'; import { loadRunningInstance } from '../containers/server/loadRunningInstance.js'; import { FolderRegistryContainer } from '../containers/folder_registry/FolderRegistryContainer.js'; import { JobManagerContainer } from '../containers/job/JobManagerContainer.js'; import { WatchChangesContainer } from '../containers/changes/WatchChangesContainer.js'; import { ServerContainer } from '../containers/server/ServerContainer.js'; import { getAuthConfig } from './getAuthConfig.js'; import { usage } from './usage.js'; const __filename = globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).filename; const __dirname = globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).dirname; process.env.GIT_SHA = process.env.GIT_SHA || 'dev'; export class MainService { constructor(params) { Object.defineProperty(this, "params", { enumerable: true, configurable: true, writable: true, value: params }); Object.defineProperty(this, "eventBus", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "logger", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "containerEngine", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "mainFileService", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "authConfig", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.eventBus = new EventEmitter(); this.eventBus.setMaxListeners(0); if (params.debug.indexOf('main') > -1) { this.attachDebug(); } this.logger = createLogger(this.params.workdir, this.eventBus); } attachDebug() { const eventNames = {}; this.eventBus.on('newListener', (event) => { if (eventNames[event]) return; eventNames[event] = event; this.eventBus.on(event, () => { this.logger.debug('OnEvent', event); }); }); } async init() { this.mainFileService = new FileContentService(this.params.workdir || '/data'); await this.mainFileService.mkdir('/'); this.authConfig = await getAuthConfig(this.params, this.mainFileService); if (this.params.share_email) { this.authConfig.share_email = this.params.share_email; } this.containerEngine = new ContainerEngine(this.logger, this.mainFileService); this.eventBus.on('panic:invalid_grant', () => { // if (configService) { // await configService.saveGoogleAuth(null); // await configService.flushData(); // } process.exit(1); }); this.eventBus.on('panic', (error) => { throw error; /* this.logger.error(error.stack ? error.stack : error.message); console.error(error.message); process.exit(1); */ }); } async cmdServer() { const instance = await loadRunningInstance(); if (instance) { this.logger.error('WikiGDrive server already running, PID: ' + instance.pid); process.exit(1); } if (!this.params.disable_google_watch) { const changesContainer = new WatchChangesContainer({ name: 'watch_changes', share_email: this.params.share_email }); await changesContainer.mount(await this.mainFileService); await this.containerEngine.registerContainer(changesContainer); await changesContainer.run(); } const port = parseInt(this.params.args[1]) || 3000; const serverContainer = new ServerContainer({ name: 'server', share_email: this.params.share_email }, port); await serverContainer.mount(await this.mainFileService); await this.containerEngine.registerContainer(serverContainer); await serverContainer.run(); const containerEnginePromise = this.containerEngine.run(); containerEnginePromise.then(() => { }); await new Promise(resolve => { this.eventBus.on('end', resolve); }); } async start() { const apiContainer = new GoogleApiContainer({ name: 'google_api' }, this.authConfig); await apiContainer.mount(await this.mainFileService); await this.containerEngine.registerContainer(apiContainer); await apiContainer.run(); const folderRegistryContainer = new FolderRegistryContainer({ name: 'folder_registry' }); await folderRegistryContainer.mount(await this.mainFileService); await this.containerEngine.registerContainer(folderRegistryContainer); await folderRegistryContainer.run(); const jobManagerContainer = new JobManagerContainer({ name: 'job_manager' }); await jobManagerContainer.mount(await this.mainFileService); await this.containerEngine.registerContainer(jobManagerContainer); await jobManagerContainer.run(); await this.cmdServer(); await this.containerEngine.flushData(); } } async function main() { const argv = minimist(process.argv.slice(2)); if (argv._.length < 1 || argv.h || argv.help) { await usage(__filename); process.exit(0); } // PWD is null on Windows, so we can set it here process.env.PWD = process.cwd(); const params = { args: argv._.slice(1), // drive: argv['drive'], workdir: argv['workdir'] || process.env.VOLUME_DATA || '/data', client_id: argv['client_id'] || process.env.CLIENT_ID, client_secret: argv['client_secret'] || process.env.CLIENT_SECRET, // link_mode: argv['link_mode'] || 'mdURLs', debug: (argv['debug'] || '').split(',').map(str => str.toLocaleString().trim()), service_account: argv['service_account'] || null, share_email: argv['share_email'] || process.env.SHARE_EMAIL || null, server_port: +argv['server_port'], disable_google_watch: !!argv['disable_google_watch'] }; const mainService = new MainService(params); try { await mainService.init(); } catch (err) { await usage(__filename); console.error(err); process.exit(1); } return await mainService.start(); } dotenv.config(); await addTelemetry(process.env.ZIPKIN_SERVICE || 'wikigdrive', __dirname); try { await main(); process.exit(0); } catch (err) { if (err.isUsageError) { console.error(err.message); await usage(__filename); } else { console.error(err); } process.exit(1); }