Esempio n. 1
0
 IEnumerator GetImages()
 {
     foreach (var result in results)
     {
         GoogleDriveFiles.DownloadTextureRequest request;
         request = GoogleDriveFiles.DownloadTexture(result.Key);
         request.Send().OnDone += ImageRequested;
         yield return(requestFilled);
     }
 }
Esempio n. 2
0
 private void ListFiles(string nextPageToken = null)
 {
     request        = GoogleDriveFiles.List();
     request.Fields = new List <string> {
         "nextPageToken, files(id, name, size, createdTime)"
     };
     request.PageSize = ResultsPerPage;
     //if (!string.IsNullOrEmpty(query))
     //    request.Q = string.Format("name contains '{0}'", query);
     request.Q = string.Format("name contains '{0}' or name contains '{1}' or name contains '{2}'", ".png", ".jpg", ".jpeg");
     if (!string.IsNullOrEmpty(nextPageToken))
     {
         request.PageToken = nextPageToken;
     }
     request.Send().OnDone += BuildResults;
 }
Esempio n. 3
0
    private IEnumerator GetFileByPathRoutine(string filePath)
    {
        // A folder in Google Drive is actually a file with the MIME type 'application/vnd.google-apps.folder'.
        // Hierarchy relationship is implemented via File's 'Parents' property. To get the actual file using it's path
        // we have to find ID of the file's parent folder, and for this we need IDs of all the folders in the chain.
        // Thus, we need to traverse the entire hierarchy chain using List requests.
        // More info about the Google Drive folders: https://developers.google.com/drive/v3/web/folder.

        var fileName    = filePath.Contains("/") ? filePath.GetAfter("/") : filePath;
        var parentNames = filePath.Contains("/") ? filePath.GetBeforeLast("/").Split('/') : null;

        // Resolving folder IDs one by one to find ID of the file's parent folder.
        var parendId = "root"; // 'root' is alias ID for the root folder in Google Drive.

        if (parentNames != null)
        {
            for (int i = 0; i < parentNames.Length; i++)
            {
                request        = new GoogleDriveFiles.ListRequest();
                request.Fields = new List <string> {
                    "files(id)"
                };
                request.Q = string.Format("'{0}' in parents and name = '{1}' and mimeType = 'application/vnd.google-apps.folder' and trashed = false",
                                          parendId, parentNames[i]);

                yield return(request.Send());

                if (request.IsError || request.ResponseData.Files == null || request.ResponseData.Files.Count == 0)
                {
                    result = string.Format("Failed to retrieve '{0}' part of '{1}' file path.", parentNames[i], filePath);
                    yield break;
                }

                if (request.ResponseData.Files.Count > 1)
                {
                    Debug.LogWarning(string.Format("Multiple '{0}' folders been found.", parentNames[i]));
                }

                parendId = request.ResponseData.Files[0].Id;
            }
        }

        // Searching the file.
        request        = new GoogleDriveFiles.ListRequest();
        request.Fields = new List <string> {
            "files(id, size, modifiedTime)"
        };
        request.Q = string.Format("'{0}' in parents and name = '{1}'", parendId, fileName);

        yield return(request.Send());

        if (request.IsError || request.ResponseData.Files == null || request.ResponseData.Files.Count == 0)
        {
            result = string.Format("Failed to retrieve '{0}' file.", filePath);
            yield break;
        }

        if (request.ResponseData.Files.Count > 1)
        {
            Debug.LogWarning(string.Format("Multiple '{0}' files been found.", filePath));
        }

        var file = request.ResponseData.Files[0];

        result = string.Format("ID: {0} Size: {1:0.00}MB Modified: {2:dd.MM.yyyy HH:MM:ss}",
                               file.Id, file.Size * .000001f, file.CreatedTime);
    }
    /// <summary>
    /// Traverses the entire path and returns ID of the top-level folder(s) (if found), null otherwise.
    /// </summary>
    /// <param name="path">Path to validate.</param>
    /// <param name="appData">Whether to use the AppData space instead of the drive root.</param>
    /// <param name="parentId">ID of the parent folder, when path starts not from the root level.</param>
    /// <returns>ID of the final folders in the path; null if the path is not valid.</returns>
    public static async System.Threading.Tasks.Task <HashSet <string> > ValidatePath(string path, bool appData, string parentId = null)
    {
        if (parentId == null)
        {
            parentId = appData ? AppDataAlias : RootAlias;
        }
        if (string.IsNullOrWhiteSpace(path))
        {
            return new HashSet <string> {
                       parentId
            }
        }
        ;
        path = Path.GetDirectoryName(path).Replace('\\', '/');
        if (string.IsNullOrWhiteSpace(path) || path.Trim() == "/" || path.Trim() == "\\")
        {
            return new HashSet <string> {
                       parentId
            }
        }
        ;
        var parentNames = path.Split('/').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
        var result      = new HashSet <string>();

        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.PageSize = 1000; // Assume we can't have more than 1K folders with equal names at the same level and skip the pagination.
                listRequest.Q        = $"'{parentId}' in parents and name = '{parentNames[i]}' and mimeType = '{FolderMimeType}' and trashed = false";

                await listRequest.Send();

                if (listRequest == null || listRequest.IsError || listRequest.ResponseData.Files == null || listRequest.ResponseData.Files.Count == 0)
                {
                    return(null);
                }

                // When at the top level, add all the folder's IDs.
                if (i + 1 == parentNames.Length)
                {
                    result.UnionWith(listRequest.ResponseData.Files.Select(f => f.Id)); break;
                }

                // Multiple folders with equal names found at the same level (but not top), travers them recursively.
                if (listRequest.ResponseData.Files.Count > 1)
                {
                    var nextPath = string.Join("/", parentNames.Skip(i + 1)) + "/";
                    foreach (var folder in listRequest.ResponseData.Files)
                    {
                        var topFolderIds = await ValidatePath(nextPath, appData, folder.Id);

                        if (topFolderIds != null)
                        {
                            result.UnionWith(topFolderIds);
                        }
                    }
                    break;
                } // Only one folder found, use it's ID to travers higher.
                else
                {
                    parentId = listRequest.ResponseData.Files[0].Id;
                }
            }
        }

        return(result.Count == 0 ? null : 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(UnityGoogleDrive.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 UnityGoogleDrive.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);
        }
    }