Esempio n. 1
0
        private async Task <string> DownloadCoreAsync(ManagedDownload download, Task <Stream> stream, long?length, string contentHash, CancellationToken cancellation)
        {
            await this.setupTask.ConfigureAwait(false);

            Stream writeStream;

            try {
                writeStream = await this.storage.GetWriteStreamAsync(download.ContentId, contentHash).ConfigureAwait(false);
            } catch (Exception ex) {
                Trace.WriteLine("Error opening write stream: " + ex);
                download.State = DownloadState.LocalError;
                return(null);
            }

            Stream readStream;

            try {
                readStream = await stream.ConfigureAwait(false);
            } catch (Exception ex) {
                Trace.WriteLine("Error downloading: " + ex);
                download.State = DownloadState.DownloadError;
                return(null);
            }

            ConcurrentQueue <(byte[] buffer, int len)> chunks = new ();

            var  errorCancel = new CancellationTokenSource();
            Task read        = DownloadAsync(chunks, download, readStream, errorCancel, cancellation);
            Task write       = WriteAsync(chunks, length, download, writeStream, errorCancel, cancellation);

            try {
                await Task.WhenAll(read, write);
            } catch (AggregateException aex) {
                if (aex.InnerException is OperationCanceledException)
                {
                    return(null);
                }

                throw;
            }

            try {
                SHA256 hasher = SHA256.Create();
                byte[] hash;
                using (Stream localReadStream = await this.storage.GetStreamAsync(download.ContentId).ConfigureAwait(false))
                    hash = hasher.ComputeHash(localReadStream);

                if (download.State == DownloadState.InProgress)
                {
                    download.State = DownloadState.Completed;
                }

                return(BitConverter.ToString(hash).Replace("-", String.Empty));
            } catch (Exception ex) {
                Trace.WriteLine("Error hashing: " + ex);
                download.State = DownloadState.LocalError;
                return(null);
            }
        }
Esempio n. 2
0
        public static async Task ImportAsync(IReadOnlyList <IStorageItem> items, IProgress <double> progress = null)
        {
            items = GetImportableItems(items);

            AggregateProgress total = (progress != null) ? new AggregateProgress(progress) : null;

            ISyncService sync = await App.Services.GetServiceAsync <ISyncService> ().ConfigureAwait(false);

            DownloadManager downloads = await App.Services.GetServiceAsync <DownloadManager> ().ConfigureAwait(false);

            List <Task> importTasks = new List <Task> ();

            foreach (IStorageItem item in items)
            {
                var node = total?.CreateProgressNode();
                if (item is IStorageFolder folder)
                {
                    var children = await folder.GetItemsAsync();

                    importTasks.Add(ImportAsync(children, node));
                }
                else if (item is IStorageFile file)
                {
                    Task <FileSample> import   = null;
                    ManagedDownload   download = null;

                    Func <CancellationToken, IProgress <double>, Task <FileSample> > importGetter = async(cancel, progress) => {
                        import = ImportAsync(file, sync, progress, cancel);
                        FileSample sample = null;
                        try {
                            sample = await import;
                            if (download != null)
                            {
                                download.State = DownloadState.Completed;
                            }
                        } catch {
                            if (download != null)
                            {
                                download.State = DownloadState.LocalError;
                            }
                        }

                        return(sample);
                    };
                    download = downloads.QueueImport(file.Name, importGetter);
                    importTasks.Add(import);
                }
            }

            total?.FinishDiscovery();
            await Task.WhenAll(importTasks);
        }
Esempio n. 3
0
        private async Task <string> DownloadCoreAsync(ManagedDownload download, Uri uri, string contentHash, CancellationToken cancellation)
        {
            Task <Stream> stream;
            long?         len;

            HttpClient client = new HttpClient();

            try {
                HttpResponseMessage result = await client.GetAsync(uri).ConfigureAwait(false);

                len    = result.Content.Headers.ContentLength;
                stream = result.Content.ReadAsStreamAsync();
            } catch (Exception ex) {
                download.State = DownloadState.DownloadError;
                Trace.WriteLine("Error downloading: " + ex);
                return(null);
            }

            return(await DownloadCoreAsync(download, stream, len, contentHash, cancellation));
        }
Esempio n. 4
0
        public ManagedDownload QueueImport(string name, Func <CancellationToken, IProgress <double>, Task <FileSample> > getImportTask)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException($"'{nameof (name)}' cannot be null or whitespace.", nameof(name));
            }
            if (getImportTask is null)
            {
                throw new ArgumentNullException(nameof(getImportTask));
            }

            var source = new CancellationTokenSource();

            var download = new ManagedDownload(name);

            download.Task = SampleToHashTask(getImportTask(source.Token, download));
            lock (this.downloads)
                this.downloads.Add(download);

            DownloadsChanged?.Invoke(this, EventArgs.Empty);
            return(download);
        }
Esempio n. 5
0
        public ManagedDownload QueueDownload(string id, string name, Task <Stream> stream, long length, string contentHash = null, IProgress <double> progress = null, CancellationToken cancellation = default)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException($"'{nameof (name)}' cannot be null or whitespace", nameof(name));
            }
            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentException($"'{nameof (id)}' cannot be null or whitespace", nameof(id));
            }
            if (stream is null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var download = new ManagedDownload(id, name);

            download.Task = DownloadCoreAsync(download, stream, length, contentHash, cancellation);
            lock (this.downloads)
                this.downloads.Add(download);

            DownloadsChanged?.Invoke(this, EventArgs.Empty);
            return(download);
        }
Esempio n. 6
0
        public async Task EnsurePresentAsync(FileSample sample, IProgress <double> progress = null, CancellationToken cancellationToken = default)
        {
            if (sample is null)
            {
                throw new ArgumentNullException(nameof(sample));
            }

            if (await this.storage.GetIsPresentAsync(sample.Id, sample.ContentHash))
            {
                progress?.Report(1);
                return;
            }

            if (!this.settings.DownloadInBackground)
            {
                Task <bool> downloadQuestionTask;
                if (this.downloadInBackground != null)
                {
                    downloadQuestionTask = this.downloadInBackground;
                }
                else
                {
                    lock (this.settings) {
                        if (this.downloadInBackground == null)
                        {
                            // TODO: Localize
                            var prompt = new PromptMessage("Download missing files", "Some of the files for these elements are missing. Would you like to download them now?", "Download");
                            Messenger.Default.Send(prompt);
                            this.downloadInBackground = prompt.Result;
                            downloadQuestionTask      = this.downloadInBackground;
                        }
                        else
                        {
                            downloadQuestionTask = this.downloadInBackground;
                        }
                    }
                }

                if (!await downloadQuestionTask)
                {
                    progress?.Report(1);
                    return;
                }
            }

            IContentProviderService[] providers = await this.services.GetServicesAsync <IContentProviderService> ().ConfigureAwait(false);

            IContentProviderService handler = providers.FirstOrDefault(c => c.CanAcquire(sample));

            ManagedDownload download = null;

            if (handler != null)
            {
                string id = handler.GetEntryIdFromUrl(sample.SourceUrl);
                if (id != null)
                {
                    ContentEntry entry = await handler.GetEntryAsync(id, cancellationToken);

                    download = QueueDownload(sample.Id, sample.Name, handler.DownloadEntryAsync(id), entry.Size, sample.ContentHash, progress, cancellationToken);
                }
            }

            if (download == null)
            {
                if (!Uri.TryCreate(sample.SourceUrl, UriKind.Absolute, out Uri uri))
                {
                    progress?.Report(1);
                    throw new ArgumentException();
                }

                if (uri.IsFile)
                {
                    if (await this.storage.GetIsPresentAsync(uri))
                    {
                        progress?.Report(1);
                        return;
                    }
                    else
                    {
                        progress?.Report(1);
                        throw new FileNotFoundException();
                    }
                }

                download = QueueDownload(sample.Id, sample.Name, new Uri(sample.SourceUrl), sample.ContentHash, progress, cancellationToken);
            }

            await download.Task;
        }