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);
        }
Пример #2
0
 public void SetEmptyFolder(IGoogleDriveFolder folder)
 {
     if (folder != null)
     {
         EmptyFolderContainer.Select(folder.Id);
     }
 }
Пример #3
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);
        }
Пример #4
0
        private async Task <IGoogleDriveFolder> DoCreateFolderAsync(string name, IGoogleDriveFolder parent, CancellationToken ct = default(CancellationToken), IProgress <string> progress = null)
        {
            progress.TryReport("Creating folder '{0}' under folder '{1}'...", name, parent.Name);
            var driveService = await GetDriveServiceAsync().ConfigureAwait(false);

            try
            {
                var folder = new File {
                    Name = name, MimeType = MimeType.Folder, Parents = new List <string> {
                        parent.Id
                    }
                };
                var createRequest = driveService.Files.Create(folder);
                createRequest.SupportsTeamDrives = true;
                var resp = await createRequest.ExecuteAsync(ct).ConfigureAwait(false);

                var result = new GoogleDriveFolder(resp, parent, _ => DoGetChildFilesAsync(_, null, ct, progress));
                RaiseFileCreated(result);
                return(result);
            }
            catch (Exception ex)
            {
                Logger.Error("Error creating folder {0} - {1}", name, ex);
                return(null);
            }
        }
Пример #5
0
        private async Task <IGoogleDriveFile> DoGetGoogleDriveFileAsync(string id, IGoogleDriveFolder parent, CancellationToken ct, IProgress <string> progress)
        {
            var f = await DoGetFileAsync(id, ct, progress).ConfigureAwait(false);

            var result = CreateDriveFile(f, parent, ct, progress);

            return(result);
        }
        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));
        }
 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));
 }
Пример #8
0
        private Task <IReadOnlyCollection <IGoogleDriveFile> > DoGetChildFilesAsync(IGoogleDriveFolder parent, string query, CancellationToken ct, IProgress <string> progress)
        {
            var tcs = new TaskCompletionSource <IReadOnlyCollection <IGoogleDriveFile> >();

            Task.Run(() =>
            {
                var result   = new List <IGoogleDriveFile>();
                var observer = new Subject <IReadOnlyCollection <IGoogleDriveFile> >();
                observer.Subscribe(files => result.AddRange(files), () => tcs.TrySetResult(result));
                return(QueryObservableChildFilesAsync(observer, parent, query, ct, progress));
            }, ct);

            return(tcs.Task);
        }
Пример #9
0
        private static IGoogleDriveFolder GetRootFolder(this IGoogleDriveFolder folder)
        {
            var p = folder;

            while (p != null)
            {
                if (p.File is IGoogleRootFile)
                {
                    return(p);
                }

                p = (IGoogleDriveFolder)p.Parent;
            }

            return(null);
        }
        private async Task <T> GetFileAsync <T>(string name, IGoogleDriveFolder toFolder, CancellationToken ct, IProgress <string> progress) where T : class, IGoogleDriveFile
        {
            var query = string.Format(CommonQueries.LiveFileFormat + " and name = '{1}'", toFolder.Id, NormalizeName(name));
            var files = await DoGetGoogleDriveFilesAsync(toFolder, query, ct, progress).ConfigureAwait(false);

            if (files.Count == 1)
            {
                return(files.First() as T);
            }

            if (files.Count > 1)
            {
                throw new ArgumentException(string.Format("More than one files found in folder '{0}', name: {1}", toFolder, name));
            }

            return(null);
        }
Пример #11
0
        protected override async Task <ITreeNodeContainer> CreateRootNodeAsync()
        {
            var root          = new GoogleDriveRoot();
            var myDriveFolder = await _gService.GetMyDriveAsync();

            var myDrive           = new GoogleMyDrive(myDriveFolder.File);
            var teamDrive         = new GoogleTeamDrive();
            var activityDrive     = new GoogleActivityDrive();
            var adhocDrive        = new GoogleAdhocDrive();
            var searchResultDrive = new GoogleSearchResultDrive();

            _rootFolder         = new GoogleDriveFolder(root, null, GetRootsAsync);
            _myDriveFolder      = new GoogleDriveFolder(myDrive, _rootFolder, GetFilesAsync);
            _teamDriveFolder    = new GoogleDriveFolder(teamDrive, _rootFolder, GetTeamDrivesAsync);
            _activityFolder     = new GoogleDriveFolder(activityDrive, _rootFolder, GetActivityFilesAsync);
            _adhocFolder        = new GoogleDriveFolder(adhocDrive, _rootFolder, GetAdhocFilesAsync);
            _searchResultFolder = new GoogleDriveFolder(searchResultDrive, _rootFolder, GetSearchResultAsync);
            return(new TreeNodeContainer(_rootFolder, null, this));
        }
        private async Task UpdateChildrenCopiedAsync(IGoogleDriveFolder folder, CancellationToken ct)
        {
            var driveService = await GetDriveServiceAsync().ConfigureAwait(false);

            try
            {
                var appProperties = new Dictionary <string, string> {
                    { "ChildrenCopied", "True" }
                };
                var updateFolder = new File {
                    MimeType = MimeType.Folder, AppProperties = appProperties
                };
                var updateRequest = driveService.Files.Update(updateFolder, folder.Id);
                updateRequest.SupportsTeamDrives = true;
                await updateRequest.ExecuteAsync(ct).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Logger.Error("Fail to update AppProperties for folder {0} - {1}", folder, ex);
            }
        }
Пример #13
0
        public async Task <bool> SelectAsync(IGoogleDriveFolder toSelect)
        {
            var node        = _rootNode;
            var folderStack = new Stack <IGoogleDriveFolder>(toSelect.FolderToRoot());

            folderStack.Pop();
            while (folderStack.Count > 0)
            {
                await node.LoadChildrenAsync().ConfigureAwait(true);

                var folder    = folderStack.Pop();
                var childNode = node.Children.FirstOrDefault(i => folder.Id == i.DataItem.CastTo <IGoogleDriveFolder>().Id);
                if (childNode != null)
                {
                    node = (TreeNodeContainer)childNode;
                }
            }

            SelectedItem = node;
            return(node != null);
        }
 public Task <IGoogleDriveFolder> CreateFolderAsync(string name, IGoogleDriveFolder parent, CancellationToken ct = default(CancellationToken), IProgress <string> progress = null)
 {
     return(Task.Run(() => DoCreateFolderAsync(name, parent, ct, progress), ct));
 }
Пример #15
0
        private async Task <IReadOnlyCollection <IGoogleDriveFile> > DoGetActivityFilesAsync(IGoogleDriveFolder parent, CancellationToken ct = default(CancellationToken), IProgress <string> progress = null)
        {
            var driveService = await GetDriveServiceAsync().ConfigureAwait(false);

            var result    = new List <IGoogleDriveFile>();
            var pageToken = await GetStartPageTokenAsync().ConfigureAwait(false);

            while (pageToken != null)
            {
                var request = driveService.Changes.List(pageToken);
                request.Spaces = "drive";
                request.IncludeTeamDriveItems = true;
                request.IncludeCorpusRemovals = true;
                request.IncludeRemoved        = true;
                request.SupportsTeamDrives    = true;
                var changes = await request.ExecuteAsync(ct).ConfigureAwait(false);

                var fileIds      = changes.Changes.Where(c => c.File != null).Select(c => c.FileId).ToArray();
                var changedFiles = new List <IGoogleDriveFile>();
                foreach (var id in fileIds)
                {
                    try
                    {
                        var file = await DoGetGoogleDriveFileAsync(id, parent, ct, progress).ConfigureAwait(false);

                        if (!file.OwnedByMe)
                        {
                            changedFiles.Add(file);
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Info("Error loading file info " + id + " - " + ex);
                    }
                }
                Logger.Info("Found " + changedFiles.Count + " file changes");
                result.AddRange(changedFiles);

                if (changes.NewStartPageToken != null)
                {
                    // Last page, save this token for the next polling interval
                    StartPageToken = changes.NewStartPageToken;
                    break;
                }
                pageToken = changes.NextPageToken;
                break;
            }

            return(result);
        }
Пример #16
0
 public Task <IReadOnlyCollection <IGoogleDriveFile> > GetActivityFilesAsync(IGoogleDriveFolder parent, CancellationToken ct = default(CancellationToken), IProgress <string> progress = null)
 {
     return(Task.Run(() => DoGetActivityFilesAsync(parent, ct, progress), ct));
 }
 public GoogleDriveFolderOperations(IGoogleDriveFolder folder, Action <IGoogleDriveFolderOperations> navigateToAction)
 {
     _folder           = folder;
     _navigateToAction = navigateToAction;
     NavigateToCommand = new DelegateCommand <IGoogleDriveFolderOperations>(HandleNavigateTo);
 }
        private async Task DoQueryObservableEmptyFoldersAsync(IObserver <IGoogleDriveFolder> observer, IGoogleDriveFolder parent, string query, int level, CancellationToken ct, IProgress <string> progress)
        {
            var driveService = await GetDriveServiceAsync().ConfigureAwait(false);

            string pageToken = null;

            if (ct != default(CancellationToken))
            {
                ct.Register(() => pageToken = null);
            }

            try
            {
                do
                {
                    var q = level == 0
            ? string.Format(CommonQueries.LiveFolderFormat, parent.Id)
            : string.Format(CommonQueries.LiveFileFormat, parent.Id);

                    if (query.HasValue())
                    {
                        q = q + " and " + query;
                    }

                    var request = driveService.GetListRequest(q, pageToken);
                    var resp    = await request.ExecuteAsync(ct).ConfigureAwait(false);

                    if (!ct.IsCancellationRequested)
                    {
                        var files = resp.Files;
                        if (files != null && files.Count > 0)
                        {
                            var newLevel = level + 1;
                            foreach (var f in files.Where(i => i.MimeType == MimeType.Folder))
                            {
                                var folder = (IGoogleDriveFolder)CreateDriveFile(f, parent, ct, progress);
                                await DoQueryObservableEmptyFoldersAsync(observer, folder, query, newLevel, ct, progress);
                            }
                        }
                        else
                        {
                            progress.TryReport("Found empty folder " + parent);
                            observer.OnNext(parent);
                        }

                        pageToken = resp.NextPageToken;
                    }
                } while (pageToken != null && !ct.IsCancellationRequested);
            }
            catch (Exception ex)
            {
                observer.OnError(ex);
                return;
            }

            if (level == 0)
            {
                observer.OnCompleted();
            }
        }
Пример #19
0
 private TreeNodeContainer CreateRootNode()
 {
     _rootFolder = new GoogleDriveFolder(_rootFile, null, f => _gService.GetChildFilesAsync(f, progress: BusyStatusReceiver));
     return(new TreeNodeContainer(_rootFolder, null, this));
 }
        public IObservable <IReadOnlyCollection <IGoogleDriveFolder> > GetEmptyFoldersObservable(IGoogleDriveFolder parent, string query = null, CancellationToken ct = default(CancellationToken),
                                                                                                 IProgress <string> progress             = null)
        {
            var childFilesSubject = new Subject <IReadOnlyCollection <IGoogleDriveFolder> >();

            Task.Run(() => QueryEmptyFoldersAsync(childFilesSubject, parent, query, ct, progress), ct);

            return(childFilesSubject);
        }
Пример #21
0
 public Task <IGoogleDriveFile> GetFileAsync(string id, IGoogleDriveFolder parent, CancellationToken ct = default(CancellationToken), IProgress <string> progress = null)
 {
     return(Task.Run(() => DoGetGoogleDriveFileAsync(id, parent, ct, progress), ct));
 }
        private async Task QueryObservableChildFilesAsync(IObserver <IReadOnlyCollection <IGoogleDriveFile> > observer, IGoogleDriveFolder parent, string query, CancellationToken ct, IProgress <string> progress)
        {
            var q = string.Format(CommonQueries.LiveFileFormat, parent.Id);

            if (query.HasValue())
            {
                q = q + " and " + query;
            }

            Action <IList <File> > handleNext = lf =>
            {
                var gFiles = lf.Select(f => CreateDriveFile(f, parent, ct, progress)).ToArray();
                observer.OnNext(gFiles);
            };

            var sub = new Subject <IList <File> >();

            sub.Subscribe(handleNext, observer.OnError, observer.OnCompleted, ct);
            await QueryObservableFilesAsync(sub, q, ct, progress);
        }
 public Task <IDictionary <IGoogleDriveFile, int> > RecursiveGetChildFilesAsync(IGoogleDriveFolder parent, int start, string filenameQuery = null, CancellationToken ct = default(CancellationToken), IProgress <string> progress = null)
 {
     return(Task.Run(async() =>
     {
         var items = await DoRecursiveGetChildFilesAsync(parent, start, filenameQuery, ct, progress).ConfigureAwait(false);
         return (IDictionary <IGoogleDriveFile, int>)items.ToDictionary(i => i.Item1, i => i.Item2);
     }, ct));
 }
 private IGoogleDriveFile CreateDriveFile(File f, IGoogleDriveFolder parent, CancellationToken ct, IProgress <string> progress)
 {
     return(f.IsFolder() ? (IGoogleDriveFile) new GoogleDriveFolder(f, parent, _ => DoGetChildFilesAsync(_, null, ct, progress)) : new GoogleDriveFile(f, parent));
 }
        private async Task <IReadOnlyCollection <Tuple <IGoogleDriveFile, int> > > DoRecursiveGetChildFilesAsync(IGoogleDriveFolder parent, string query, int start, string filenameQuery, CancellationToken ct, IProgress <string> progress)
        {
            var newQuery = query;

            if (filenameQuery.HasValue())
            {
                var fileOrFolder = CommonQueries.IsFolder + " or ((" + filenameQuery + ") and " + CommonQueries.IsNotFolder + ")";
                newQuery = newQuery + " and (" + fileOrFolder + ")";
            }

            var files = await DoGetFilesAsync(newQuery, ct, progress).ConfigureAwait(false);

            var gFiles = files.Select(f => CreateDriveFile(f, parent, ct, null)).ToArray();

            var result = new List <Tuple <IGoogleDriveFile, int> >();

            foreach (var file in gFiles)
            {
                if (file is IGoogleDriveFolder)
                {
                    var children = await DoRecursiveGetChildFilesAsync(file, start, filenameQuery, ct, progress).ConfigureAwait(false);

                    start += children.Count;
                    result.AddRange(children);
                }
                else
                {
                    result.Add(Tuple.Create(file, start++));
                }
            }
            return(result);
        }
Пример #26
0
 public GetOrCreateFolder(IGoogleDriveFolder folder, bool isNew)
 {
     Folder = folder;
     IsNew  = isNew;
 }
        private async Task <IReadOnlyCollection <IGoogleDriveFile> > DoGetGoogleDriveFilesAsync(IGoogleDriveFolder parent, string query, CancellationToken ct, IProgress <string> progress)
        {
            var files = await DoGetFilesAsync(query, ct, progress).ConfigureAwait(false);

            var result = files.Select(f => CreateDriveFile(f, parent, ct, progress)).ToArray();

            return(result);
        }
        private async Task QueryEmptyFoldersAsync(IObserver <IReadOnlyCollection <IGoogleDriveFolder> > observer, IGoogleDriveFolder parent, string query, CancellationToken ct, IProgress <string> progress)
        {
            var resultSub = new Subject <IList <IGoogleDriveFolder> >();

            Action <IGoogleDriveFolder> handleNext = f => observer.OnNext(new[] { f });

            var sub = new Subject <IGoogleDriveFolder>();

            sub.Subscribe(handleNext, resultSub.OnError, resultSub.OnCompleted);
            await DoQueryObservableEmptyFoldersAsync(sub, parent, query, 0, ct, progress);
        }
        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 <IReadOnlyCollection <IGoogleDriveFile> > DoGetTeamDrivesAsync(IGoogleDriveFolder parent, CancellationToken ct, IProgress <string> progress)
        {
            var driveService = await GetDriveServiceAsync().ConfigureAwait(false);

            var teamDrives = driveService.Teamdrives.List();
            var t          = await teamDrives.ExecuteAsync(ct);

            var teamDriveFolders = t.TeamDrives.Select(i => new GoogleTeamDriveFolder(i, parent, _ => DoGetChildFilesAsync(_, null, ct, progress))).ToArray();

            return(teamDriveFolders);
        }