Ver Fonte

Merge pull request #1652 from stephentuso/drive-dropbox-pagination

companion: return nextPagePath for drive/dropbox
Ifedapo .A. Olarewaju há 5 anos atrás
pai
commit
324ba3d066

+ 18 - 7
packages/@uppy/companion/src/server/provider/drive/adapter.js

@@ -1,3 +1,5 @@
+const querystring = require('querystring')
+
 exports.getUsername = (data) => {
   for (const item of data.files) {
     if (item.ownedByMe) {
@@ -20,7 +22,11 @@ exports.getItemSize = (item) => {
 
 exports.getItemIcon = (item) => {
   if (item.kind === 'drive#teamDrive') {
-    return item.backgroundImageLink + '=w16-h16-n'
+    const size = '=w16-h16-n'
+    const sizeParamRegex = /=[-whncsp0-9]*$/
+    return item.backgroundImageLink.match(sizeParamRegex)
+      ? item.backgroundImageLink.replace(sizeParamRegex, size)
+      : `${item.backgroundImageLink}${size}`
   }
 
   if (item.thumbnailLink) {
@@ -50,12 +56,6 @@ exports.getItemId = (item) => {
 }
 
 exports.getItemRequestPath = (item) => {
-  // If it's from a Team Drive, add the Team Drive ID as a query param.
-  // The server needs the Team Drive ID to list files in a Team Drive folder.
-  if (item.teamDriveId) {
-    return item.id + `?teamDriveId=${item.teamDriveId}`
-  }
-
   return item.id
 }
 
@@ -70,3 +70,14 @@ exports.getItemThumbnailUrl = (item) => {
 exports.isTeamDrive = (item) => {
   return item.kind === 'drive#teamDrive'
 }
+
+exports.getNextPagePath = (data, currentQuery, currentPath) => {
+  if (!data.nextPageToken) {
+    return null
+  }
+  const query = {
+    ...currentQuery,
+    cursor: data.nextPageToken
+  }
+  return `${currentPath}?${querystring.stringify(query)}`
+}

+ 78 - 68
packages/@uppy/companion/src/server/provider/drive/index.js

@@ -24,66 +24,74 @@ class Drive {
   list (options, done) {
     const directory = options.directory || 'root'
     const query = options.query || {}
-    const teamDrive = query.teamDrive
-    let listDone = false
-    let teamDrivesDone = false
-    let teamDrives
-    let listResponse
-    let reqErr
-    const finishReq = () => {
-      if (reqErr || listResponse.statusCode !== 200) {
-        const err = this._error(reqErr, listResponse)
-        logger.error(err, 'provider.drive.list.error')
-        done(err)
-      } else {
-        done(null, this.adaptData(listResponse.body, teamDrives ? teamDrives.body : null, options.uppy))
-      }
+
+    let teamDrivesPromise = Promise.resolve(undefined)
+
+    const shouldListTeamDrives = directory === 'root' && !query.cursor
+    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.cursor,
+      q: `'${directory}' in parents and trashed=false`,
+      includeItemsFromAllDrives: true,
+      supportsAllDrives: true
     }
 
-    if (directory === 'root') {
-      // fetch a list of all Team Drives which the user can access.
+    const filesPromise = new Promise((resolve, reject) => {
       this.client
         .query()
-        .get('teamdrives')
-        .where({ fields: TEAM_DRIVE_FIELDS })
+        .get('files')
+        .where(where)
         .auth(options.token)
         .request((err, resp) => {
           if (err) {
-            logger.error(err, 'provider.drive.teamDrive.error')
-          }
-          teamDrivesDone = true
-          teamDrives = resp
-          if (listDone) {
-            finishReq()
+            reject(err)
+            return
           }
+          resolve(resp)
         })
-    }
+    })
 
-    let where = {
-      fields: DRIVE_FILES_FIELDS,
-      q: `'${directory}' in parents and trashed=false`
-    }
-    if (teamDrive) {
-      // Team Drives require several extra parameters in order to work.
-      where.supportsTeamDrives = true
-      where.includeTeamDriveItems = true
-      where.teamDriveId = directory
-      where.corpora = 'teamDrive'
-    }
+    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
+          }
 
-    this.client
-      .query()
-      .get('files')
-      .where(where)
-      .auth(options.token)
-      .request((err, resp) => {
-        listDone = true
-        listResponse = resp
-        reqErr = err
-        if (teamDrivesDone || directory !== 'root') {
-          finishReq()
+          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) {
@@ -132,30 +140,32 @@ class Drive {
     })
   }
 
-  adaptData (res, teamDrivesResp, uppy) {
-    const data = { username: adapter.getUsername(res), items: [] }
+  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 || [] : []
-    items.concat(teamDrives).forEach((item) => {
-      data.items.push({
-        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)
-        }
-      })
-    })
 
-    data.nextPagePath = null
+    const adaptedItems = teamDrives.concat(items).map(adaptItem)
 
-    return data
+    return {
+      username: adapter.getUsername(res),
+      items: adaptedItems,
+      nextPagePath: adapter.getNextPagePath(res, query, directory)
+    }
   }
 
   _error (err, resp) {

+ 9 - 0
packages/@uppy/companion/src/server/provider/dropbox/adapter.js

@@ -1,4 +1,5 @@
 const mime = require('mime-types')
+const querystring = require('querystring')
 
 exports.getUsername = (data) => {
   return data.user_email
@@ -43,3 +44,11 @@ exports.getItemModifiedDate = (item) => {
 exports.getItemThumbnailUrl = (item) => {
   return `/dropbox/thumbnail/${exports.getItemRequestPath(item)}`
 }
+
+exports.getNextPagePath = (data) => {
+  if (!data.has_more) {
+    return null
+  }
+  const query = { cursor: data.cursor }
+  return `?${querystring.stringify(query)}`
+}

+ 13 - 1
packages/@uppy/companion/src/server/provider/dropbox/index.js

@@ -79,6 +79,18 @@ class DropBox {
   }
 
   stats ({ directory, query, token }, done) {
+    if (query.cursor) {
+      this.client
+        .post('files/list_folder/continue')
+        .options({ version: '2' })
+        .auth(token)
+        .json({
+          cursor: query.cursor
+        })
+        .request(done)
+      return
+    }
+
     this.client
       .post('files/list_folder')
       .options({ version: '2' })
@@ -169,7 +181,7 @@ class DropBox {
       })
     })
 
-    data.nextPagePath = null
+    data.nextPagePath = adapter.getNextPagePath(res)
 
     return data
   }

+ 3 - 2
packages/@uppy/companion/src/server/provider/instagram/adapter.js

@@ -67,8 +67,9 @@ exports.getItemThumbnailUrl = (item) => {
   return item.images ? item.images.thumbnail.url : null
 }
 
-exports.getNextPagePath = (items) => {
+exports.getNextPagePath = (data) => {
+  const items = exports.getItemSubList(data)
   if (items.length) {
-    return `recent?max_id=${exports.getItemId(items[items.length - 1])}`
+    return `recent?cursor=${exports.getItemId(items[items.length - 1])}`
   }
 }

+ 3 - 2
packages/@uppy/companion/src/server/provider/instagram/index.js

@@ -16,7 +16,8 @@ class Instagram {
   }
 
   list ({ directory = 'recent', token, query = {} }, done) {
-    const qs = query.max_id ? { max_id: query.max_id } : {}
+    const cursor = query.cursor || query.max_id
+    const qs = cursor ? { max_id: cursor } : {}
     this.client
       .select(`users/self/media/${directory}`)
       .qs(qs)
@@ -142,7 +143,7 @@ class Instagram {
       })
     })
 
-    data.nextPagePath = adapter.getNextPagePath(items)
+    data.nextPagePath = adapter.getNextPagePath(res)
     return data
   }