UNPKG

@mieweb/wikigdrive

Version:

Google Drive to MarkDown synchronization

140 lines (139 loc) 4.85 kB
import { Container } from '../../ContainerEngine.js'; import { GoogleDriveServiceError } from '../../google/driveFetch.js'; const __filename = globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).filename; export class FolderRegistryContainer extends Container { constructor(params) { super(params); Object.defineProperty(this, "params", { enumerable: true, configurable: true, writable: true, value: params }); Object.defineProperty(this, "logger", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "folders", { enumerable: true, configurable: true, writable: true, value: void 0 }); } async init(engine) { await super.init(engine); this.logger = engine.logger.child({ filename: __filename }); this.folders = await this.filesService.readJson('folders.json') || {}; try { await this.refreshDrives(); } catch (err) { this.logger.error(err.stack ? err.stack : err.message); } } async refreshDrives() { if (!this.engine.hasContainer('google_api')) { this.logger.warn('Not authenticated to Google API. Skipping drives refresh.'); return; } this.logger.info('refreshDrives'); const oldDrives = Object.values(await this.getFolders()); const apiContainer = this.engine.getContainer('google_api'); try { const drives = await apiContainer.listDrives(); for (const newDrive of drives) { if (!oldDrives.find(oldDrive => oldDrive.id === newDrive.id)) { try { await this.registerFolder(newDrive.id); } catch (err) { this.logger.error(err.stack ? err.stack : err.message); } } } for (const oldDrive of oldDrives) { if (!drives.find(newDrive => newDrive.id === oldDrive.id)) { await this.unregisterFolder(oldDrive.id); } } } catch (err) { if (401 === err?.status) { this.logger.warn('Not authenticated to Google API. Skipping drives refresh.'); return; } throw err; } } async registerFolder(folderId) { if (this.folders[folderId]) { return this.folders[folderId]; } const apiContainer = this.engine.getContainer('google_api'); const folder = await apiContainer.getDrive(folderId); if (!folder) { throw new GoogleDriveServiceError('Drive not shared with wikigdrive', { isQuotaError: false, status: 404 }); } this.folders[folderId] = { id: folder.id, name: folder.name, driveId: folder.id, }; this.engine.emit(folderId, 'drive:register', this.folders[folderId]); await this.flushData(); return Object.assign({}, folder, { new: true }); } async unregisterFolder(folderId) { if (this.folders[folderId]) { this.logger.info('Unregistered folder: ' + folderId); delete this.folders[folderId]; await this.flushData(); this.engine.emit(folderId, 'drive:unregister', this.folders[folderId]); } } getFolders() { return this.folders; } async pruneFolder(folderId) { await this.unregisterFolder(folderId); await this.filesService.remove(folderId); await this.filesService.remove(folderId + '_transform'); } async pruneTransformFolder(folderId) { await this.filesService.remove(folderId + '_transform'); } async pruneGitFolder(folderId) { await this.filesService.remove(folderId + '_transform/.git'); } async flushData() { await this.filesService.writeJson('folders.json', this.folders); } async run() { setInterval(async () => { try { await this.refreshDrives(); } catch (err) { this.logger.error(err.stack ? err.stack : err.message); } }, 60 * 1000); } // eslint-disable-next-line @typescript-eslint/no-empty-function async destroy() { } async rename(folderId, name) { if (this.folders[folderId]) { this.folders[folderId].name = name; await this.flushData(); } } hasFolder(folderId) { return !!this.folders[folderId]; } }