@mieweb/wikigdrive
Version:
Google Drive to MarkDown synchronization
140 lines (139 loc) • 4.85 kB
JavaScript
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];
}
}