private async Task <IGoogleDriveFile> DoCopyFolderAsync(IGoogleDriveFolder from, IGoogleDriveFolder toFolder, string newName, PauseToken pt, CancellationToken ct, IProgress <GoogleDriveProgress> progress, GoogleDriveProgress progressPayload)
        {
            await pt.WaitWhilePausedAsync().ConfigureAwait(false);

            var name = newName.HasValue() ? newName : from.Name;
            var getOrCreateFolder = await GetOrCreateFolderAsync(name, toFolder, ct, progress, progressPayload).ConfigureAwait(false);

            var fromFolderCopy = getOrCreateFolder.Folder;

            if (fromFolderCopy.IsChildrenCopied.GetValueOrDefault())
            {
                progressPayload.Status = string.Format("Folder '{0}' is already copied", fromFolderCopy.Name);
                progress.TryReport(() => progressPayload);
                return(fromFolderCopy);
            }

            await pt.WaitWhilePausedAsync().ConfigureAwait(false);

            progressPayload.Status = string.Format("Loading files under source folder '{0}'", from.Name);
            progress.TryReport(() => progressPayload);
            var childFiles = await DoGetChildFilesAsync(from, null, ct, null).ConfigureAwait(false);

            IReadOnlyCollection <IGoogleDriveFile> childFilesOfCopy = null;

            if (!getOrCreateFolder.IsNew)
            {
                progressPayload.Status = string.Format("Loading files under target folder '{0}'", fromFolderCopy.Name);
                progress.TryReport(() => progressPayload);
                childFilesOfCopy = await DoGetChildFilesAsync(fromFolderCopy, null, ct, null).ConfigureAwait(false);
            }

            var hasErrors = false;

            foreach (var file in childFiles)
            {
                await pt.WaitWhilePausedAsync().ConfigureAwait(false);

                if (!ct.IsCancellationRequested)
                {
                    ////Check existing in memory here instead of letting DoCopyFileAsync to check the file existence by using name to check the target folder - that often throws 400 ApiException.
                    var existing = childFilesOfCopy != null?childFilesOfCopy.FirstOrDefault(i => i.Name == file.Name && i.Size == file.Size) : null;

                    if (existing == null || file is IGoogleDriveFolder)
                    {
                        try
                        {
                            await DoCopyAsync(file, fromFolderCopy, null, pt, ct, progress, progressPayload).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("Error copy file {0} - {1}", from.Name, ex);
                            hasErrors = true;
                        }
                    }
                    else
                    {
                        progressPayload.Count++;
                        progressPayload.Current = existing;
                        progressPayload.Status  = string.Format("Found file '{0}' in folder '{1}'...", file.Name, fromFolderCopy.Name);
                        progress.TryReport(() => progressPayload);
                    }
                }
            }

            if (!hasErrors)
            {
                await UpdateChildrenCopiedAsync(fromFolderCopy, ct).ConfigureAwait(false);
            }

            return(fromFolderCopy);
        }
        private async Task <IGoogleDriveFile> DoCopyFileAsync(IGoogleDriveFile from, IGoogleDriveFolder toFolder, string newName, PauseToken pt, CancellationToken ct, IProgress <GoogleDriveProgress> progress, GoogleDriveProgress progressPayload)
        {
            var driveService = await GetDriveServiceAsync().ConfigureAwait(false);

            progressPayload.Count++;
            progressPayload.Current = from;
            progressPayload.Status  = string.Format("Copying file '{0}' to folder '{1}'...", from.Name, toFolder.Name);
            progress.TryReport(() => progressPayload);

            await pt.WaitWhilePausedAsync().ConfigureAwait(false);

            var toFile = new File {
                Parents = new List <string> {
                    toFolder.Id
                }, Name = newName
            };
            var copyRequest = driveService.Files.Copy(toFile, from.Id);

            copyRequest.SupportsTeamDrives = true;
            var resp = await copyRequest.ExecuteAsync(ct).ConfigureAwait(false);

            var result = new GoogleDriveFile(resp, toFolder);

            RaiseFileCreated(result);
            return(result);
        }
 public Task <IGoogleDriveFile> CopyAsync(IGoogleDriveFile from, IGoogleDriveFolder toFolder, string newName = null, PauseToken pt = default(PauseToken), CancellationToken ct = default(CancellationToken), IProgress <GoogleDriveProgress> progress = null, GoogleDriveProgress progressPayload = null)
 {
     return(Task.Run(async() =>
     {
         var payload = progressPayload ?? new GoogleDriveProgress();
         var result = await DoCopyAsync(from, toFolder, newName, pt, ct, progress, payload).ConfigureAwait(false);
         progress.TryReport(() => payload);
         return result;
     }, ct));
 }
        public Task <IGoogleDriveFile> DoCopyAsync(IGoogleDriveFile from, IGoogleDriveFolder toFolder, string newName, PauseToken pt, CancellationToken ct, IProgress <GoogleDriveProgress> progress, GoogleDriveProgress progressPayload)
        {
            var folder = from as IGoogleDriveFolder;

            return(folder != null
        ? DoCopyFolderAsync(folder, toFolder, newName, pt, ct, progress, progressPayload)
        : DoCopyFileAsync(from, toFolder, newName, pt, ct, progress, progressPayload));
        }
Exemple #5
0
        private async Task <GetOrCreateFolder> GetOrCreateFolderAsync(string name, IGoogleDriveFolder parent,
                                                                      CancellationToken ct, IProgress <GoogleDriveProgress> progress = null, GoogleDriveProgress progressPayload = null)
        {
            GetOrCreateFolder result;
            var folder = await GetFileAsync <IGoogleDriveFolder>(name, parent, ct, null).ConfigureAwait(false);

            if (folder != null)
            {
                result = new GetOrCreateFolder(folder, false);
                if (progressPayload != null)
                {
                    progressPayload.Status = string.Format("Found folder '{0}' under {1}...", name, parent.Name);
                }
            }
            else
            {
                folder = await DoCreateFolderAsync(name, parent, ct, null).ConfigureAwait(false);

                result = new GetOrCreateFolder(folder, true);
                if (progressPayload != null)
                {
                    progressPayload.Status = string.Format("Creating folder '{0}' under {1}...", name, parent.Name);
                }
            }

            if (progressPayload != null)
            {
                progressPayload.Count++;
                progressPayload.Current = folder;
                progress.TryReport(() => progressPayload);
            }

            return(result);
        }