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 void SetEmptyFolder(IGoogleDriveFolder folder) { if (folder != null) { EmptyFolderContainer.Select(folder.Id); } }
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); }
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); } }
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)); }
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); }
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); }
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); } }
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)); }
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); }
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(); } }
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); }
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); }
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); }