123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- const request = require('request')
- // @ts-ignore
- const purest = require('purest')({ request })
- const logger = require('../../logger')
- const adapter = require('./adapter')
- const AuthError = require('../error')
- const DRIVE_FILE_FIELDS = 'kind,id,name,mimeType,ownedByMe,permissions(role,emailAddress),size,modifiedTime,iconLink,thumbnailLink,teamDriveId'
- const DRIVE_FILES_FIELDS = `kind,nextPageToken,incompleteSearch,files(${DRIVE_FILE_FIELDS})`
- const TEAM_DRIVE_FIELDS = 'teamDrives(kind,id,name,backgroundImageLink)'
- class Drive {
- constructor (options) {
- this.authProvider = options.provider = Drive.authProvider
- options.alias = 'drive'
- options.version = 'v3'
- this.client = purest(options)
- }
- static get authProvider () {
- return 'google'
- }
- list (options, done) {
- const directory = options.directory || 'root'
- const query = options.query || {}
- let teamDrivesPromise = Promise.resolve(undefined)
- const shouldListTeamDrives = directory === 'root' && !query.nextPageToken
- if (shouldListTeamDrives) {
- teamDrivesPromise = new Promise((resolve) => {
- this.client
- .query()
- .get('teamdrives')
- .where({ fields: TEAM_DRIVE_FIELDS })
- .auth(options.token)
- .request((err, resp) => {
- if (err) {
- logger.error(err, 'provider.drive.teamDrive.error')
- return
- }
- resolve(resp)
- })
- })
- }
- let where = {
- fields: DRIVE_FILES_FIELDS,
- pageToken: query.nextPageToken,
- q: `'${directory}' in parents and trashed=false`,
- includeItemsFromAllDrives: true,
- supportsAllDrives: true
- }
- const filesPromise = new Promise((resolve, reject) => {
- this.client
- .query()
- .get('files')
- .where(where)
- .auth(options.token)
- .request((err, resp) => {
- if (err) {
- reject(err)
- return
- }
- resolve(resp)
- })
- })
- Promise.all([teamDrivesPromise, filesPromise])
- .then(
- ([teamDrives, filesResponse]) => {
- if (filesResponse.statusCode !== 200) {
- const err = this._error(null, filesResponse)
- logger.error(err, 'provider.drive.list.error')
- done(err)
- return
- }
- const returnData = this.adaptData(
- filesResponse.body,
- teamDrives && teamDrives.body,
- options.uppy,
- directory,
- query
- )
- done(null, returnData)
- },
- (reqErr) => {
- logger.error(reqErr, 'provider.drive.list.error')
- done(reqErr)
- }
- )
- }
- stats ({ id, token }, done) {
- return this.client
- .query()
- .get(`files/${id}`)
- .where({ fields: DRIVE_FILE_FIELDS, supportsTeamDrives: true })
- .auth(token)
- .request(done)
- }
- download ({ id, token }, onData) {
- return this.client
- .query()
- .get(`files/${id}`)
- .where({ alt: 'media', supportsTeamDrives: true })
- .auth(token)
- .request()
- .on('data', onData)
- .on('end', () => onData(null))
- .on('error', (err) => {
- logger.error(err, 'provider.drive.download.error')
- })
- }
- thumbnail ({ id, token }, done) {
- return this.stats({ id, token }, (err, resp, body) => {
- if (err || resp.statusCode !== 200) {
- err = this._error(err, resp)
- logger.error(err, 'provider.drive.thumbnail.error')
- return done(err)
- }
- done(null, body.thumbnailLink ? request(body.thumbnailLink) : null)
- })
- }
- size ({ id, token }, done) {
- return this.stats({ id, token }, (err, resp, body) => {
- if (err || resp.statusCode !== 200) {
- err = this._error(err, resp)
- logger.error(err, 'provider.drive.size.error')
- return done(err)
- }
- done(null, parseInt(body.size))
- })
- }
- adaptData (res, teamDrivesResp, uppy, directory, query) {
- const adaptItem = (item) => ({
- isFolder: adapter.isFolder(item),
- icon: adapter.getItemIcon(item),
- name: adapter.getItemName(item),
- mimeType: adapter.getMimeType(item),
- id: adapter.getItemId(item),
- thumbnail: uppy.buildURL(adapter.getItemThumbnailUrl(item), true),
- requestPath: adapter.getItemRequestPath(item),
- modifiedDate: adapter.getItemModifiedDate(item),
- size: adapter.getItemSize(item),
- custom: {
- isTeamDrive: adapter.isTeamDrive(item)
- }
- })
- const items = adapter.getItemSubList(res)
- const teamDrives = teamDrivesResp ? teamDrivesResp.teamDrives || [] : []
- const adaptedItems = teamDrives.concat(items).map(adaptItem)
- return {
- username: adapter.getUsername(res),
- items: adaptedItems,
- nextPagePath: adapter.getNextPagePath(res, query, directory)
- }
- }
- _error (err, resp) {
- if (resp) {
- const errMsg = `request to ${this.authProvider} returned ${resp.statusCode}`
- return resp.statusCode === 401 ? new AuthError() : new Error(errMsg)
- }
- return err
- }
- }
- module.exports = Drive
|