@mieweb/wikigdrive
Version:
Google Drive to MarkDown synchronization
259 lines (226 loc) • 8.22 kB
text/typescript
import winston from 'winston';
import {GoogleDriveService} from '../../google/GoogleDriveService.ts';
import {FileContentService} from '../../utils/FileContentService.ts';
import {INITIAL_RETRIES, QueueTask} from './QueueTask.ts';
import {TaskFetchDiagram} from './TaskFetchDiagram.ts';
import {TaskFetchDocument} from './TaskFetchDocument.ts';
import {TaskFetchBinary} from './TaskFetchBinary.ts';
import {TaskFetchAsset} from './TaskFetchAsset.ts';
import {MimeTypes, SimpleFile} from '../../model/GoogleFile.ts';
import {FileId} from '../../model/model.ts';
import {HasAccessToken} from '../../google/AuthClient.ts';
import {StopWatch} from '../../utils/StopWatch.ts';
interface Filters {
filterFoldersIds: FileId[];
filterFilesIds: FileId[];
}
export class TaskFetchFolder extends QueueTask {
private useGoogleMarkdowns = false;
constructor(protected logger: winston.Logger,
private googleDriveService: GoogleDriveService,
private auth: HasAccessToken,
private fileService: FileContentService,
private file: SimpleFile,
private forceDownloadFilters = false,
private filters: Filters) {
super(logger);
}
setUseGoogleMarkdowns(value: boolean) {
this.useGoogleMarkdowns = value;
}
async run(): Promise<QueueTask[]> {
if (this.filters.filterFoldersIds.length > 0) {
if (this.filters.filterFoldersIds.indexOf(this.file.id) === -1) {
return [];
}
}
const stopWatch = new StopWatch();
if (this.retries < INITIAL_RETRIES) {
await new Promise(resolve => setTimeout(resolve, 1000));
this.logger.info('Listening (retry): ' + this.file.id);
} else {
this.logger.info('Listening: ' + this.file.id);
}
// const rootFolderId = urlToFolderId(this.drive_config['drive']);
const tasks: QueueTask[] = [];
const file = await this.googleDriveService.getFile(this.auth, this.file.id);
if (file.mimeType === MimeTypes.FOLDER_MIME) {
const oldFiles = await this.fileService.readJson('.folder-files.json') || [];
await this.fileService.writeJson('.folder.json', file);
const files = await this.googleDriveService.listFiles(this.auth, { folderId: this.file.id });
await this.deleteUnused(files);
const filesToSave = [];
for (const file of files) {
const oldFile = oldFiles.find(oldFile => oldFile.id === file.id);
if (this.filters.filterFilesIds.length > 0) {
if (this.filters.filterFilesIds.indexOf(file.id) === -1 && this.filters.filterFoldersIds.indexOf(file.id) === -1) {
if (oldFile) {
filesToSave.push(oldFile);
}
continue;
}
}
filesToSave.push(file);
/*
const oldFile = oldFiles.find(oldFile => oldFile.id === file.id);
if (modifiedTime && oldFile.modifiedTime !== file.modifiedTime) {
const localFiles = await this.fileService.list();
for (const localFile of localFiles) {
if (localFile.startsWith(oldFile.id)) {
await this.fileService.remove(localFile);
}
}
}
*/
const forceDownload = this.forceDownloadFilters || oldFile?.modifiedTime !== file.modifiedTime;
switch (file.mimeType) {
case MimeTypes.FOLDER_MIME:
{
const task = new TaskFetchFolder(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService.getSubFileService(file.id),
file,
this.forceDownloadFilters,
this.filters
);
task.setUseGoogleMarkdowns(this.useGoogleMarkdowns);
tasks.push(task);
}
break;
case MimeTypes.DRAWING_MIME:
tasks.push(new TaskFetchDiagram(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload
));
break;
case MimeTypes.DOCUMENT_MIME:
if (!this.useGoogleMarkdowns) {
tasks.push(new TaskFetchDocument(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload
));
} else {
tasks.push(new TaskFetchBinary(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
MimeTypes.MARKDOWN, 'md'
));
}
break;
case MimeTypes.SPREADSHEET_MIME:
tasks.push(new TaskFetchBinary(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsx'
));
tasks.push(new TaskFetchBinary(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
'text/csv', 'csv'
));
break;
case MimeTypes.PRESENTATION_MIME:
tasks.push(new TaskFetchBinary(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pptx'
));
tasks.push(new TaskFetchBinary(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
'application/pdf', 'pdf'
));
break;
case MimeTypes.FORM_MIME:
tasks.push(new TaskFetchBinary(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
'application/zip', 'zip'
));
break;
case MimeTypes.APPS_SCRIPT:
tasks.push(new TaskFetchBinary(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
'application/vnd.google-apps.script+json', 'gs'
));
break;
case MimeTypes.SHORTCUT:
break;
default:
tasks.push(new TaskFetchAsset(
this.logger,
this.googleDriveService,
this.auth,
await this.fileService,
file,
forceDownload,
));
break;
}
}
await this.fileService.writeJson('.folder-files.json', filesToSave);
}
const timeString = stopWatch.toString(1000);
if (timeString) {
this.logger.info('Slow listening: ' + this.file.id + ' ' + timeString);
}
return tasks;
}
private async deleteUnused(files: SimpleFile[]): Promise<void> {
const localFiles = await this.fileService.list();
for (const localFile of localFiles) {
if (localFile === '.logs') continue;
if (localFile === '.jobs.json') continue;
if (localFile === '.changes.json') continue;
if (localFile === '.private') continue;
if (localFile === '.folder.json') continue;
if (localFile === '.folder-files.json') continue;
if (localFile === '.rendered_preview_time') continue;
if (localFile === '.user_config.json') continue;
const presentFile = files.find(file => localFile.startsWith(file.id));
if (presentFile) {
continue;
}
await this.fileService.remove(localFile);
}
}
}