@@ -27,6 +27,14 @@ import (
2727
2828// do others that not defined in Driver interface
2929
30+ // Google Drive API field constants
31+ const (
32+ // File list query fields
33+ FilesListFields = "files(id,name,mimeType,size,modifiedTime,createdTime,thumbnailLink,shortcutDetails,md5Checksum,sha1Checksum,sha256Checksum),nextPageToken"
34+ // Single file query fields
35+ FileInfoFields = "id,name,mimeType,size,md5Checksum,sha1Checksum,sha256Checksum"
36+ )
37+
3038type googleDriveServiceAccount struct {
3139 // Type string `json:"type"`
3240 // ProjectID string `json:"project_id"`
@@ -235,7 +243,7 @@ func (d *GoogleDrive) getFiles(id string) ([]File, error) {
235243 }
236244 query := map [string ]string {
237245 "orderBy" : orderBy ,
238- "fields" : "files(id,name,mimeType,size,modifiedTime,createdTime,thumbnailLink,shortcutDetails,md5Checksum,sha1Checksum,sha256Checksum),nextPageToken" ,
246+ "fields" : FilesListFields ,
239247 "pageSize" : "1000" ,
240248 "q" : fmt .Sprintf ("'%s' in parents and trashed = false" , id ),
241249 //"includeItemsFromAllDrives": "true",
@@ -249,11 +257,82 @@ func (d *GoogleDrive) getFiles(id string) ([]File, error) {
249257 return nil , err
250258 }
251259 pageToken = resp .NextPageToken
260+
261+ // Batch process shortcuts, API calls only for file shortcuts
262+ shortcutTargetIds := make ([]string , 0 )
263+ shortcutIndices := make ([]int , 0 )
264+
265+ // Collect target IDs of all file shortcuts (skip folder shortcuts)
266+ for i := range resp .Files {
267+ if resp .Files [i ].MimeType == "application/vnd.google-apps.shortcut" &&
268+ resp .Files [i ].ShortcutDetails .TargetId != "" &&
269+ resp .Files [i ].ShortcutDetails .TargetMimeType != "application/vnd.google-apps.folder" {
270+ shortcutTargetIds = append (shortcutTargetIds , resp .Files [i ].ShortcutDetails .TargetId )
271+ shortcutIndices = append (shortcutIndices , i )
272+ }
273+ }
274+
275+ // Batch get target file info (only for file shortcuts)
276+ if len (shortcutTargetIds ) > 0 {
277+ targetFiles := d .batchGetTargetFilesInfo (shortcutTargetIds )
278+ // Update shortcut file info
279+ for j , targetId := range shortcutTargetIds {
280+ if targetFile , exists := targetFiles [targetId ]; exists {
281+ fileIndex := shortcutIndices [j ]
282+ if targetFile .Size != "" {
283+ resp .Files [fileIndex ].Size = targetFile .Size
284+ }
285+ if targetFile .MD5Checksum != "" {
286+ resp .Files [fileIndex ].MD5Checksum = targetFile .MD5Checksum
287+ }
288+ if targetFile .SHA1Checksum != "" {
289+ resp .Files [fileIndex ].SHA1Checksum = targetFile .SHA1Checksum
290+ }
291+ if targetFile .SHA256Checksum != "" {
292+ resp .Files [fileIndex ].SHA256Checksum = targetFile .SHA256Checksum
293+ }
294+ }
295+ }
296+ }
297+
252298 res = append (res , resp .Files ... )
253299 }
254300 return res , nil
255301}
256302
303+ // getTargetFileInfo gets target file details for shortcuts
304+ func (d * GoogleDrive ) getTargetFileInfo (targetId string ) (File , error ) {
305+ var targetFile File
306+ url := fmt .Sprintf ("https://www.googleapis.com/drive/v3/files/%s" , targetId )
307+ query := map [string ]string {
308+ "fields" : FileInfoFields ,
309+ }
310+ _ , err := d .request (url , http .MethodGet , func (req * resty.Request ) {
311+ req .SetQueryParams (query )
312+ }, & targetFile )
313+ if err != nil {
314+ return File {}, err
315+ }
316+ return targetFile , nil
317+ }
318+
319+ // batchGetTargetFilesInfo batch gets target file info, sequential processing to avoid concurrency complexity
320+ func (d * GoogleDrive ) batchGetTargetFilesInfo (targetIds []string ) map [string ]File {
321+ if len (targetIds ) == 0 {
322+ return make (map [string ]File )
323+ }
324+
325+ result := make (map [string ]File )
326+ // Sequential processing to avoid concurrency complexity
327+ for _ , targetId := range targetIds {
328+ file , err := d .getTargetFileInfo (targetId )
329+ if err == nil {
330+ result [targetId ] = file
331+ }
332+ }
333+ return result
334+ }
335+
257336func (d * GoogleDrive ) chunkUpload (ctx context.Context , file model.FileStreamer , url string , up driver.UpdateProgress ) error {
258337 defaultChunkSize := d .ChunkSize * 1024 * 1024
259338 ss , err := stream .NewStreamSectionReader (file , int (defaultChunkSize ), & up )
0 commit comments