/// <summary> /// Looks for the files located at the provided path. /// </summary> /// <param name="path">File's path in Google Drive. Add front slash to find all files in a folder.</param> /// <param name="appData">Whether to use the AppData space instead of the drive root.</param> /// <param name="fields">Required fields for the list request. To request file's fields, use 'files(id, name, mimeType, ...)'.</param> /// <param name="mimeType">File's MIME type.</param> /// <param name="trashed">Whether to include trashed files.</param> public static async System.Threading.Tasks.Task <List <Data.File> > FindFilesByPathAsync(string path, bool appData = false, List <string> fields = null, string mime = null, bool trashed = false) { var result = new List <Data.File>(); var fileName = Path.GetFileName(path); var parentIds = await ValidatePath(path, appData); if (parentIds == null) { return(result); } var parentQueries = parentIds.Select(parentId => $"'{parentId}' in parents"); var query = $"({string.Join(" or ", parentQueries)}) and trashed = {trashed}"; if (!string.IsNullOrWhiteSpace(fileName)) { query += $" and name = '{fileName}'"; } if (!string.IsNullOrWhiteSpace(mime)) { query += $" and mimeType = '{mime}'"; } if (fields == null) { fields = new List <string>(); } fields.Add("nextPageToken, files(id)"); string pageToken = null; do { var listRequest = GoogleDriveFiles.List(query, fields, appData ? AppDataSpace : DriveSpace, pageToken); var fileList = await listRequest.Send(); if (fileList?.Files?.Count > 0) { result.AddRange(fileList.Files); } pageToken = fileList?.NextPageToken; listRequest.Dispose(); } while (pageToken != null); return(result); }
/// <summary> /// Creates a new (or update existsing) <see cref="Data.File"/> at the provided path. /// Will also create any missing folders at the provided path. /// </summary> /// <param name="file">Metadata for the created (updated) file.</param> /// <param name="path">Created file's path (including file name).</param> /// <param name="appData">Whether to use the AppData space instead of the drive root.</param> /// <param name="forceUploadContent">Whether to always upload <see cref="Data.File.Content"/>, even when checksum of the content is equal to the one kept on drive.</param> /// <param name="uploadMimeType">When the uploaded content differs from the target type (Eg when uploading plain text to create a google document), specify the uploaded content MIME type here.</param> /// <returns>ID of the created (updated) file. Null if failed.</returns> public static async System.Threading.Tasks.Task <string> CreateOrUpdateFileAtPathAsync(Data.File file, string path, bool appData = false, bool forceUploadContent = false, string uploadMimeType = null) { var fileName = Path.GetFileName(path); if (string.IsNullOrWhiteSpace(fileName)) { return(null); } if (string.IsNullOrWhiteSpace(file.Name)) { file.Name = fileName; } // Just modify the file if already exists. var files = await FindFilesByPathAsync(path, appData, new List <string> { "files(md5Checksum)" }, file.MimeType); if (files.Count > 0) { if (files.Count > 1) { Debug.LogWarning($"UnityGoogleDrive: Multiple '{path}' files found while attempting to modify the file. Operation will modify only the first found file."); } if (!forceUploadContent && file.Content != null && CalculateMD5Checksum(file.Content) == files[0].Md5Checksum) { file.Content = null; } using (var updateRequest = GoogleDriveFiles.Update(files[0].Id, file, uploadMimeType)) { updateRequest.Fields = new List <string> { "id" }; var updatedFile = await updateRequest.Send(); return(updatedFile.Id); } } // Check if all the folders in the path exist. var parentIds = await ValidatePath(path, appData); if (parentIds == null) { parentIds = new HashSet <string>(); } if (parentIds.Count > 1) { Debug.LogWarning($"UnityGoogleDrive: Multiple '{Path.GetDirectoryName(path)}' pathes found while attempting to create a file. Operation will create a file at the first found path."); } // Some of the folders are missing; create them. if (parentIds.Count == 0) { var parentId = appData ? AppDataAlias : RootAlias; path = Path.GetDirectoryName(path).Replace('\\', '/'); var parentNames = path.Split('/').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); for (int i = 0; i < parentNames.Length; i++) { using (var listRequest = new GoogleDriveFiles.ListRequest()) { listRequest.Fields = new List <string> { "files(id)" }; listRequest.Spaces = appData ? AppDataAlias : DriveSpace; listRequest.Q = $"'{parentId}' in parents and name = '{parentNames[i]}' and mimeType = '{FolderMimeType}' and trashed = false"; await listRequest.Send(); if (listRequest == null || listRequest.IsError) { return(null); } // Next folder at the current level is missing; create it. if (listRequest.ResponseData.Files == null || listRequest.ResponseData.Files.Count == 0) { var folder = new Data.File { Name = parentNames[i], MimeType = FolderMimeType, Parents = new List <string> { parentId } }; using (var createRequest = GoogleDriveFiles.Create(folder)) { createRequest.Fields = new List <string> { "id" }; var createdFolder = await createRequest.Send(); parentId = createdFolder.Id; continue; } } // Next folder exists; use it's ID and travers higher. else { parentId = listRequest.ResponseData.Files[0].Id; } } } parentIds.Add(parentId); } // Create the file. file.Parents = new List <string> { parentIds.First() }; using (var createRequest = GoogleDriveFiles.Create(file, uploadMimeType)) { createRequest.Fields = new List <string> { "id" }; var createdFile = await createRequest.Send(); return(createdFile?.Id); } }