Exemple #1
0
        public IDisposable SetDownloadProgress([CanBeNull] IProgress <AsyncProgressEntry> progress, long?suggestedTotal = null, Action callback = null)
        {
            var s = Stopwatch.StartNew();

            void Handler(object sender, DownloadProgressChangedEventArgs args)
            {
                if (s.Elapsed.TotalMilliseconds < 20)
                {
                    return;
                }

                callback?.Invoke();
                s.Restart();

                var total = args.TotalBytesToReceive;

                if (total == -1 && suggestedTotal != null && suggestedTotal > 0)
                {
                    total = Math.Max(suggestedTotal.Value, args.BytesReceived);
                }

                progress?.Report(AsyncProgressEntry.CreateDownloading(args.BytesReceived, total));
            }

            DownloadProgressChanged += Handler;
            return(new ActionAsDisposable(() => {
                DownloadProgressChanged -= Handler;
            }));
        }
Exemple #2
0
        public static async Task <string> LoadAsyncTo(string argument,
                                                      FlexibleLoaderGetPreferredDestinationCallback getPreferredDestination, [CanBeNull] FlexibleLoaderReportDestinationCallback reportDestination,
                                                      Action <FlexibleLoaderMetaInformation> reportMetaInformation = null, Func <bool> checkIfPaused = null,
                                                      IProgress <AsyncProgressEntry> progress = null, CancellationToken cancellation = default)
        {
            progress?.Report(AsyncProgressEntry.FromStringIndetermitate("Finding fitting loader…"));
            var loader = await CreateLoaderAsync(argument, cancellation) ?? throw new OperationCanceledException();

            try {
                using (var order = KillerOrder.Create(new CookieAwareWebClient(), TimeSpan.FromMinutes(10))) {
                    var client = order.Victim;

                    if (_proxy != null)
                    {
                        client.Proxy = _proxy;
                    }

                    progress?.Report(AsyncProgressEntry.Indetermitate);

                    cancellation.ThrowIfCancellationRequested();
                    cancellation.Register(client.CancelAsync);

                    if (!await loader.PrepareAsync(client, cancellation))
                    {
                        throw new InformativeException("Can’t load file", "Loader preparation failed.");
                    }

                    cancellation.ThrowIfCancellationRequested();
                    reportMetaInformation?.Invoke(FlexibleLoaderMetaInformation.FromLoader(loader));

                    var initialProgressCallback = true;
                    var reportStopwatch         = Stopwatch.StartNew();
                    var progressStopwatch       = new AsyncProgressBytesStopwatch();

                    if (loader.UsesClientToDownload)
                    {
                        client.DownloadProgressChanged += (sender, args) => {
                            if (initialProgressCallback)
                            {
                                reportMetaInformation?.Invoke(FlexibleLoaderMetaInformation.FromLoader(loader));
                                initialProgressCallback = false;
                            }

                            if (reportStopwatch.Elapsed.TotalMilliseconds < 20)
                            {
                                return;
                            }
                            order.Delay();
                            reportStopwatch.Restart();
                            progress?.Report(AsyncProgressEntry.CreateDownloading(args.BytesReceived, args.TotalBytesToReceive == -1 &&
                                                                                  loader.TotalSize.HasValue ? Math.Max(loader.TotalSize.Value, args.BytesReceived) : args.TotalBytesToReceive,
                                                                                  progressStopwatch));
                        };
                    }

                    var loaded = await loader.DownloadAsync(client, getPreferredDestination, reportDestination, checkIfPaused,
                                                            loader.UsesClientToDownload?null : new Progress <long>(p => {
                        if (initialProgressCallback)
                        {
                            reportMetaInformation?.Invoke(FlexibleLoaderMetaInformation.FromLoader(loader));
                            initialProgressCallback = false;
                        }

                        if (reportStopwatch.Elapsed.TotalMilliseconds < 20)
                        {
                            return;
                        }
                        order.Delay();
                        reportStopwatch.Restart();
                        progress?.Report(loader.TotalSize.HasValue ? AsyncProgressEntry.CreateDownloading(p, loader.TotalSize.Value, progressStopwatch)
                                        : new AsyncProgressEntry(string.Format(UiStrings.Progress_Downloading, p.ToReadableSize(1)), null));
                    }), cancellation);

                    cancellation.ThrowIfCancellationRequested();
                    Logging.Write("Loaded: " + loaded);
                    return(loaded);
                }
            } catch (Exception e) when(cancellation.IsCancellationRequested || e.IsCancelled())
            {
                Logging.Warning("Cancelled");
                throw new OperationCanceledException();
            } catch (Exception e) {
                Logging.Warning(e);
                throw;
            }
        }
Exemple #3
0
        public static async Task <string> LoadAsyncTo(string argument, string destination, IProgress <AsyncProgressEntry> progress = null,
                                                      Action <FlexibleLoaderMetaInformation> metaInformationCallback = null, CancellationToken cancellation = default(CancellationToken))
        {
            var loader = CreateLoader(argument);

            try {
                using (var order = KillerOrder.Create(new CookieAwareWebClient {
                    Headers =
                    {
                        [HttpRequestHeader.UserAgent] = CmApiProvider.UserAgent
                    }
                }, TimeSpan.FromMinutes(10))) {
                    var client = order.Victim;

                    if (_proxy != null)
                    {
                        client.Proxy = _proxy;
                    }

                    progress?.Report(AsyncProgressEntry.Indetermitate);

                    cancellation.ThrowIfCancellationRequested();
                    cancellation.Register(client.CancelAsync);

                    if (!await loader.PrepareAsync(client, cancellation))
                    {
                        throw new InformativeException("Can’t load file", "Loader preparation failed.");
                    }

                    cancellation.ThrowIfCancellationRequested();
                    metaInformationCallback?.Invoke(new FlexibleLoaderMetaInformation(loader.TotalSize, loader.FileName, loader.Version));

                    var s = Stopwatch.StartNew();
                    if (loader.UsesClientToDownload)
                    {
                        client.DownloadProgressChanged += (sender, args) => {
                            if (s.Elapsed.TotalMilliseconds > 20)
                            {
                                order.Delay();
                                s.Restart();
                            }
                            else
                            {
                                return;
                            }

                            var total = args.TotalBytesToReceive;
                            if (total == -1 && loader.TotalSize != -1)
                            {
                                total = Math.Max(loader.TotalSize, args.BytesReceived);
                            }

                            progress?.Report(AsyncProgressEntry.CreateDownloading(args.BytesReceived, total));
                        };
                    }

                    await loader.DownloadAsync(client, destination, loader.UsesClientToDownload?null : new Progress <double>(p => {
                        if (s.Elapsed.TotalMilliseconds > 20)
                        {
                            order.Delay();
                            s.Restart();
                        }
                        else
                        {
                            return;
                        }

                        var total = loader.TotalSize;
                        progress?.Report(total == -1 ?
                                         new AsyncProgressEntry("Loading…", p) :
                                         AsyncProgressEntry.CreateDownloading((long)(p * total), total));
                    }), cancellation);

                    cancellation.ThrowIfCancellationRequested();
                }
            } catch (Exception) when(cancellation.IsCancellationRequested)
            {
                throw new OperationCanceledException();
            }

            return(destination);
        }
Exemple #4
0
        public static async Task <string> LoadAsyncTo(string argument, string destination, IProgress <AsyncProgressEntry> progress = null,
                                                      CancellationToken cancellation = default(CancellationToken))
        {
            var loader = CreateLoader(argument);

            try {
                // TODO: Timeout?
                using (var client = new CookieAwareWebClient {
                    Headers =
                    {
                        [HttpRequestHeader.UserAgent] = CmApiProvider.UserAgent
                    }
                }) {
                    progress?.Report(AsyncProgressEntry.Indetermitate);

                    cancellation.ThrowIfCancellationRequested();
                    cancellation.Register(client.CancelAsync);

                    if (!await loader.PrepareAsync(client, cancellation) ||
                        cancellation.IsCancellationRequested)
                    {
                        return(null);
                    }

                    var skipEvent = 0;
                    client.DownloadProgressChanged += (sender, args) => {
                        if (++skipEvent > 50)
                        {
                            skipEvent = 0;
                        }
                        else
                        {
                            return;
                        }

                        var total = args.TotalBytesToReceive;
                        if (total == -1 && loader.TotalSize != -1)
                        {
                            total = Math.Max(loader.TotalSize, args.BytesReceived);
                        }

                        // ReSharper disable once AccessToDisposedClosure
                        progress?.Report(AsyncProgressEntry.CreateDownloading(args.BytesReceived, total));
                    };

                    await loader.DownloadAsync(client, destination, cancellation);

                    if (cancellation.IsCancellationRequested)
                    {
                        return(null);
                    }

                    Logging.Debug("Loaded: " + destination);
                }

                return(destination);
            } catch (TaskCanceledException) {
                return(null);
            } catch (Exception e) {
                NonfatalError.Notify(ToolsStrings.Common_CannotDownloadFile, ToolsStrings.Common_CannotDownloadFile_Commentary, e);
                return(null);
            }
        }