-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmakeGDriveFolderBackup.mjs
134 lines (114 loc) · 4.85 KB
/
makeGDriveFolderBackup.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import fs from 'fs';
import path from 'path';
import {promisify} from 'util';
import google from 'googleapis';
import withExponentialBackoff from './withExponentialBackoff.mjs';
const GOOGLE_DRIVE_FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';
const GOOGLE_DOC_MIME_TYPE = 'application/vnd.google-apps.document';
const GOOGLE_SPREADSHEET_MIME_TYPE = 'application/vnd.google-apps.spreadsheet';
const GOOGLE_DRAWING_MIME_TYPE = 'application/vnd.google-apps.drawing';
const GOOGLE_PRESENTATION_MIME_TYPE = 'application/vnd.google-apps.presentation';
const GOOGLE_SCRIPT_MIME_TYPE = 'application/vnd.google-apps.script';
const mkdir = promisify(fs.mkdir);
const unlink = promisify(fs.unlink);
const drive = google.drive('v3');
const list = promisify(drive.files.list);
function listFolderFiles(auth, folderId) {
return list({ auth, q: `'${folderId}' in parents` })
}
function exportToFile(auth, fileId, filename, mimeType){
return new Promise((resolve, reject) => {
var dest = fs.createWriteStream(filename);
drive.files.export({ auth, fileId, mimeType }, (err) => {
if(err){
reject(err);
}
})
.on('end', resolve)
.on('error', e => {
unlink(filename)
.then(() => reject(e))
.catch(() => reject(e));
})
.pipe(dest);
});
}
function downloadToFile(auth, fileId, filename){
return new Promise((resolve, reject) => {
var dest = fs.createWriteStream(filename);
drive.files.get({ auth, fileId, alt: 'media' }, (err) => {
if(err){
reject(err);
}
})
.on('end', resolve)
.on('error', e => {
unlink(filename)
.then(() => reject(e))
.catch(() => reject(e));
})
.pipe(dest);
});
}
const listFolderFilesWithBackoffAndRetry = withExponentialBackoff(listFolderFiles);
const exportToFileWithBackoffAndRetry = withExponentialBackoff(exportToFile);
const downloadToFileWithBackoffAndRetry = withExponentialBackoff(downloadToFile);
export default function makeGDriveFolderBackup(auth, gDriveFolderId, dirPath = './tmp'){
// verify the dir exists
// verify it's a git repo; make it so if not https://github.com/dtc-innovation/garagiste/issues/3
return listFolderFilesWithBackoffAndRetry(auth, gDriveFolderId)
.then(({files}) => {
return Promise.all(
files.map(f => {
const localFilename = path.join(
dirPath,
f.name.replace(new RegExp(path.sep, 'g'), '_')
)
console.log('Start', f.name, dirPath);
(() => {
switch(f.mimeType){
case GOOGLE_DRIVE_FOLDER_MIME_TYPE: {
return mkdir(localFilename, {recursive: true})
.then(() => makeGDriveFolderBackup(auth, f.id, localFilename) )
}
case GOOGLE_DOC_MIME_TYPE: {
return exportToFileWithBackoffAndRetry(
auth, f.id, `${localFilename}.odt`, 'application/vnd.oasis.opendocument.text'
)
}
case GOOGLE_SPREADSHEET_MIME_TYPE: {
return exportToFileWithBackoffAndRetry(
auth, f.id, `${localFilename}.ods`, 'application/x-vnd.oasis.opendocument.spreadsheet'
)
}
case GOOGLE_DRAWING_MIME_TYPE: {
return exportToFileWithBackoffAndRetry(
auth, f.id, `${localFilename}.svg`, 'image/svg+xml'
)
}
case GOOGLE_PRESENTATION_MIME_TYPE: {
return exportToFileWithBackoffAndRetry(
auth, f.id, `${localFilename}.odp`, 'application/vnd.oasis.opendocument.presentation'
)
}
case GOOGLE_SCRIPT_MIME_TYPE: {
return exportToFileWithBackoffAndRetry(
auth, f.id, `${localFilename}.json`, 'application/vnd.google-apps.script+json'
)
}
default: {
return downloadToFileWithBackoffAndRetry(auth, f.id, localFilename)
}
}
})()
.then(ret => {
console.log('End', f.name, dirPath);
return ret;
})
.catch(e => {
console.error('Error', f.name, dirPath, e);
})
})
)
})
}