-
Notifications
You must be signed in to change notification settings - Fork 148
Expand file tree
/
Copy pathsearch.js
More file actions
108 lines (83 loc) · 2.9 KB
/
search.js
File metadata and controls
108 lines (83 loc) · 2.9 KB
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
'use strict'
const {google} = require('googleapis')
const {getAuth} = require('./auth')
const list = require('./list')
const log = require('./logger')
const driveId = process.env.DRIVE_ID
exports.run = async (query, driveType = 'team') => {
const authClient = await getAuth()
let folderIds
const drive = google.drive({version: 'v3', auth: authClient})
if (driveType === 'folder') {
folderIds = await getAllFolders({drive})
}
const files = await fullSearch({drive, query, folderIds, driveType})
.catch((err) => {
log.error(`Error when searching for ${query}, ${err}`)
throw err
})
const fileMetas = files
.map((file) => { return list.getMeta(file.id) || {} })
.filter(({path, tags}) => (path || '').split('/')[1] !== 'trash' && !(tags || []).includes('hidden'))
return fileMetas
}
async function fullSearch({drive, query, folderIds, results = [], nextPageToken: pageToken, driveType}) {
const options = getOptions(query, folderIds, driveType)
if (pageToken) {
options.pageToken = pageToken
}
const {data} = await drive.files.list(options)
const {files, nextPageToken} = data
const total = results.concat(files)
if (nextPageToken) {
return fullSearch({drive, query, results: total, nextPageToken, folderIds, driveType})
}
return total
}
// Grab all folders in directory to search through in shared drive
async function getAllFolders({nextPageToken: pageToken, drive, parentIds = [driveId], foldersSoFar = []} = {}) {
const options = {
...list.commonListOptions.folder,
q: `(${parentIds.map((id) => `'${id}' in parents`).join(' or ')}) AND mimeType = 'application/vnd.google-apps.folder'`,
fields: 'files(id,name,mimeType,parents)'
}
if (pageToken) {
options.pageToken = pageToken
}
const {data} = await drive.files.list(options)
const {files, nextPageToken} = data
const combined = foldersSoFar.concat(files)
if (nextPageToken) {
return getAllFolders({
nextPageToken,
foldersSoFar: combined,
drive
})
}
const folders = combined.filter((item) => parentIds.includes(item.parents[0]))
if (folders.length > 0) {
return getAllFolders({
foldersSoFar: combined,
drive,
parentIds: folders.map((folder) => folder.id)
})
}
return combined.map((folder) => folder.id)
}
function getOptions(query, folderIds, driveType) {
const fields = '*'
if (driveType === 'folder') {
const parents = folderIds.map((id) => `'${id}' in parents`).join(' or ')
return {
...list.commonListOptions.folder,
q: `(${parents}) AND fullText contains ${JSON.stringify(query)} AND mimeType != 'application/vnd.google-apps.folder' AND trashed = false`,
fields
}
}
return {
...list.commonListOptions.team,
q: `fullText contains ${JSON.stringify(query)} AND mimeType != 'application/vnd.google-apps.folder' AND trashed = false`,
teamDriveId: driveId,
fields
}
}