示例#1
0
        private async Task <SyncResults> SyncFiles(SyncResultsBuilder resultsBuilder)
        {
            _logger.LogInformation($"Sync files starting - {_filesToDownload.Count} files to be downloaded");

            // To increase the download speed we will download multiple files at once in pages
            var page = GetNextDownloadPage();

            while (page.downloads != null && page.downloads.Any())
            {
                _logger.LogInformation($"Starting download for {page.downloads.Count()} files");
                var downloaders = new List <Task>();
                foreach (var download in page.downloads)
                {
                    downloaders.Add(Task.Run(() =>
                    {
                        DownloadFile(download, resultsBuilder);
                    }));
                }
                await Task.WhenAll(downloaders);

                page = GetNextDownloadPage(page.nextPage);
            }

            return(resultsBuilder.Build());
        }
示例#2
0
        public SyncResults(SyncResultsBuilder builder)
        {
            SuccessfulDownloads = builder.SuccessfulDownloads.AsReadOnly();
            ErroredFiles        = builder.ErroredFiles.AsReadOnly();

            TotalDownloads = SuccessfulDownloads.Count + ErroredFiles.Count;
        }
示例#3
0
        public async Task Go()
        {
            StartTime = DateTime.Now;
            Authorize();
            CreateService();
            SanatizeDestinationPath();
            // Start finding files to sync and track progress
            // First call to FindFilesToSync should include the top level folder Id from config

            var resultsBuilder = new SyncResultsBuilder();

            FindFilesToSync(resultsBuilder, Config.GoogleDriveFolderId);
            var results = await SyncFiles(resultsBuilder);

            // Once finished display a summary of the results
            EndTime = DateTime.Now;
            DisplayResults(results);
        }
示例#4
0
        private void CheckForLocalFile(GFile gFile, SyncResultsBuilder results)
        {
            var fullPath = GetFileFolderPath(gFile);

            _logger.LogInformation($"New File \"{fullPath}\"");

            var localPath    = Path.Combine(Config.DestinationPath, fullPath);
            var downloadFile = new DownloadableFile(gFile, localPath);

            try
            {
                if (LFile.Exists(localPath))
                {
                    _logger.LogInformation("   File exists");
                    if (Config.ForceDownloads)
                    {
                        _logger.LogInformation($"   Force downloads enabled, will download to: {localPath}");
                        _filesToDownload.Add(downloadFile);
                        return;
                    }

                    var lFileInfo = new FileInfo(localPath);
                    if (lFileInfo.LastWriteTimeUtc <= (gFile.ModifiedTime ?? gFile.CreatedTime))
                    {
                        _logger.LogInformation($"   Google file is newer, will download to: {localPath}");
                        _filesToDownload.Add(downloadFile);
                    }
                }
                else
                {
                    // File doesn't exist, download it
                    _logger.LogInformation($"   File does not exist, downloading to: {localPath}");
                    _filesToDownload.Add(downloadFile);
                }
            }
            catch (Exception exception)
            {
                var error = downloadFile.ToErroredFile(exception);
                results.ErroredFiles.Add(error);
            }
        }
示例#5
0
        private void FindFilesToSync(SyncResultsBuilder results, string folderId)
        {
            if (string.IsNullOrWhiteSpace(folderId))
            {
                return;
            }

            _logger.LogInformation($"Finding files in folder with id {folderId}");
            var filePage = GetNextGoogleFilePage(folderId, null);

            while (filePage?.Files != null && filePage.Files.Count > 0)
            {
                // Loop the files in this page
                foreach (var gFile in filePage.Files)
                {
                    // If this is a folder ignore it as we can't "sync" a folder (but it will be created later when we get the full path)
                    // save it to the file cache for reference later when getting parent path
                    if (gFile.MimeType == SyncConstants.FolderMimeType)
                    {
                        _fileCache.TryAdd(gFile.Id, gFile);
                        // Recusrively call FileFilesToSync agains the folder we just found to get the files in this folder
                        FindFilesToSync(results, gFile.Id);
                        continue;
                    }
                    // Non-folder files should be checked against the local destination for downloading
                    CheckForLocalFile(gFile, results);
                }

                // Get the next page or stop the loop
                if (string.IsNullOrWhiteSpace(filePage.NextPageToken))
                {
                    filePage = null;
                }
                else
                {
                    filePage = GetNextGoogleFilePage(folderId, filePage.NextPageToken);
                }
            }
        }
示例#6
0
        private void DownloadFile(DownloadableFile download, SyncResultsBuilder results)
        {
            _logger.LogInformation($"[dl: {download.GFile.Name}] download starting at {download.Destination}");
            var sanitizedDestination = SanatizePath(download.Destination);

            if (sanitizedDestination != download.Destination)
            {
                _logger.LogError($"[dl: {download.GFile.Name}] Warning: Invalid Destination path.  Will use \"{sanitizedDestination}\" instead");
            }
            // Create the directorys (if they dont exist) to avoid exception when making file
            var folderPath = Path.GetDirectoryName(sanitizedDestination);

            Directory.CreateDirectory(folderPath);
            // Create the file in a temp location to avoid overwriting the file and corrupting if the download is broken
            var tempFile = sanitizedDestination + ".temp";

            try
            {
                using (var stream = new FileStream(tempFile, FileMode.Create))
                {
                    var request = _service.Files.Get(download.GFile.Id);
                    // Add a handler which will be notified on progress changes.
                    // It will notify on each chunk download and when the
                    // download is completed or failed.
                    request.MediaDownloader.ProgressChanged +=
                        (IDownloadProgress progress) =>
                    {
                        switch (progress.Status)
                        {
                        case DownloadStatus.Downloading:
                        {
                            string percent;
                            if (download.GFile.Size.HasValue)
                            {
                                percent = $"{((100 * progress.BytesDownloaded) / download.GFile.Size.Value)}%";
                            }
                            else
                            {
                                percent = "...";
                            }

                            _logger.LogInformation($"[dl: {download.GFile.Name}] {percent}");
                            break;
                        }

                        case DownloadStatus.Completed:
                        {
                            _logger.LogInformation($"[dl: {download.GFile.Name}] Download complete.");
                            results.SuccessfulDownloads.Add(download);
                            break;
                        }

                        case DownloadStatus.Failed:
                        {
                            _logger.LogError($"[dl: {download.GFile.Name}] Download failed.  Exception: {progress.Exception.Message}");
                            results.ErroredFiles.Add(download.ToErroredFile(progress.Exception));
                            break;
                        }
                        }
                    };
                    request.DownloadWithStatus(stream);
                    stream.Dispose();
                    // Finished downloading, delete the original and rename the temp to the original
                    LFile.Delete(sanitizedDestination);
                    LFile.Move(tempFile, sanitizedDestination);
                }
            }
            catch (Exception exception)
            {
                _logger.LogError($"[dl: {download?.GFile?.Name}] Download failed.  Exception: {exception.Message}");
                _logger.LogError(exception.Message);
                if (download?.GFile != null)
                {
                    var errorFile = download.ToErroredFile(exception);
                    results.ErroredFiles.Add(errorFile);
                }
            }
        }