Ejemplo n.º 1
0
        internal async Task <byte[]> ReadHttpResponseStreamAsync(HttpResponseMessage httpResponse, long?length, CancellationToken ct, bool saveToFile = false, string filename = null, string folderPath = null)
        {
            return(await Task.Run(async() =>
            {
                // Were we already canceled?
                ct.ThrowIfCancellationRequested();
                using (StreamReader sr = new StreamReader(await httpResponse.Content.ReadAsStreamAsync()))
                {
                    DownloadMetric metric = new DownloadMetric(length);
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    OnDownloadStart?.Invoke(metric);
                    if (!saveToFile)
                    {
                        return FromReaderToStream(sr, new MemoryStream((int)length), ref metric, ref stopwatch, ref length, ct);
                    }
                    else
                    {
                        filename = ToRelativeFilePath(httpResponse.RequestMessage.RequestUri, filename, folderPath);

                        return FromReaderToStream(sr, File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite),
                                                  ref metric, ref stopwatch, ref length, ct);
                    }
                }
            }, ct));
        }
Ejemplo n.º 2
0
        public void QueueDownload(UriString url, string targetDirectory, string filename = null, int retryCount = 0)
        {
            var download = new DownloadTask(TaskManager, url, targetDirectory, filename, retryCount, Token);

            download.OnStart += t => OnDownloadStart?.Invoke(((DownloadTask)t).Url);
            download.OnEnd   += (t, res, s, ex) => {
                if (s)
                {
                    OnDownloadComplete?.Invoke(((DownloadTask)t).Url, res);
                }
                else
                {
                    OnDownloadFailed?.Invoke(((DownloadTask)t).Url, ex);
                }
            };
            // queue after hooking up events so OnDownload* gets called first
            Queue(download);
        }
Ejemplo n.º 3
0
        public void QueueDownload(UriString url, NPath targetDirectory)
        {
            var download = new DownloadTask(Token, fileSystem, url, targetDirectory);

            download.OnStart += t => OnDownloadStart?.Invoke(((DownloadTask)t).Url);
            download.OnEnd   += (t, res, s, ex) =>
            {
                if (s)
                {
                    OnDownloadComplete?.Invoke(((DownloadTask)t).Url, res);
                }
                else
                {
                    OnDownloadFailed?.Invoke(((DownloadTask)t).Url, ex);
                }
            };
            // queue after hooking up events so OnDownload* gets called first
            Queue(download);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// From a provided REST API endpoint download a mod.
        /// </summary>
        public async Task DownloadMod(string url)
        {
            Downloading = true;
            string modZipPath;
            string modImagePath;
            string modExtractPath;
            string modString = string.Empty;

            using (WebClient wc = new WebClient()) {
                dynamic Data = new OnDownloadCompleteArgs();
                OnDownloadStart?.Invoke(this, Data);


                wc.DownloadProgressChanged += WCDownloadPercentChanged;
                try {
                    modString = await wc.DownloadStringTaskAsync(url);
                } catch (WebException ex) {
                    Data.ErrorMessage = ex.Message;
                    OnDownloadComplete?.Invoke(this, Data);
                    return;
                }
                JsonObject json = JsonObject.Parse(modString);
                // Let's make sure the slug doesn't have weird stuff.
                json["slug"] = string.Join(" ", json["slug"].Split(Path.GetInvalidFileNameChars().Concat(Path.GetInvalidPathChars()).ToArray()));
                if (json["compatible"] != "Yes")
                {
                    Data.ErrorMessage = Helpers._("Error.NotCompatible");
                    OnDownloadComplete?.Invoke(this, Data);
                    return;
                }
                m = new Mod(
                    json["id"],
                    json.ArrayObjects("title") [0]["rendered"],
                    DateTime.ParseExact(json["modified"].Replace("T", " "), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
                    json.ArrayObjects("content") [0]["rendered"],
                    json["author_name"],
                    url,
                    json["File"],
                    json["slug"],
                    json["slug"] + ".jpg"
                    );
                modZipPath     = zipPath + m.Slug + ".zip";
                modExtractPath = Mod.InstallPath + m.Slug + "\\";
                modImagePath   = Mod.ImagePath + m.Thumbnail;

                // Cleanup previous versions and files.
                Delete(m.Slug);
                if (File.Exists(modZipPath))
                {
                    File.Delete(modZipPath);
                }
                if (Directory.Exists(modExtractPath))
                {
                    Directory.Delete(modExtractPath, true);
                }
                if (File.Exists(modImagePath))
                {
                    File.Delete(modImagePath);
                }

                // And start downloading stuff.
                try {
                    await wc.DownloadFileTaskAsync(new System.Uri(json["image"]), modImagePath);
                } catch (WebException we) {
                    Data.ErrorMessage = we.Message;
                    OnDownloadComplete?.Invoke(this, Data);
                    return;
                }
                try {
                    await wc.DownloadFileTaskAsync(new System.Uri(m.File), modZipPath);
                } catch (WebException we) {
                    Data.ErrorMessage = we.Message;
                    OnDownloadComplete?.Invoke(this, Data);
                    return;
                }
                UnpackMod(modZipPath, modExtractPath);
                AvailableMods.Add(m);
                Data.Success = true;
                OnDownloadComplete?.Invoke(this, Data);
                UpdateSettings();
            }
            Downloading = false;
        }
Ejemplo n.º 5
0
        private async Task ProcessDownloadAsync(Uri uri, string filename, CancellationToken ct)
        {
            try
            {
                dynamic request = null;

                #region Get file size

                if (uri.Scheme == Uri.UriSchemeHttp)
                {
                    request          = WebRequest.Create(uri) as HttpWebRequest;
                    request !.Method = WebRequestMethods.Http.Head;
                }
                else if (uri.Scheme == Uri.UriSchemeFtp)
                {
                    request          = WebRequest.Create(uri) as FtpWebRequest;
                    request !.Method = WebRequestMethods.Ftp.GetFileSize;
                }

                var metric = new DownloaderMetric
                {
                    FileName = Path.GetFileName(filename)
                };

                using (var response = await request !.GetResponseAsync())
                {
                    metric.TotalBytes = response.ContentLength;
                }

                #endregion

                // Set start download position
                long startPos = 0;
                var  fi       = new FileInfo(filename);
                if (fi.Exists)
                {
                    if (metric.TotalBytes > fi.Length)
                    {
                        metric.DownloadedBytes = startPos = fi.Length - 1024;
                    }
                    else if (metric.TotalBytes == fi.Length)
                    {
                        return;
                    }
                }

                #region Read Content Stream Asynchronously

                if (uri.Scheme == Uri.UriSchemeHttp)
                {
                    request          = WebRequest.Create(uri) as HttpWebRequest;
                    request          = (HttpWebRequest)request;
                    request !.Method = WebRequestMethods.Http.Get;
                    request.AddRange(startPos, metric.TotalBytes);
                }
                else if (uri.Scheme == Uri.UriSchemeFtp)
                {
                    request               = WebRequest.Create(uri) as FtpWebRequest;
                    request !.Method      = WebRequestMethods.Ftp.DownloadFile;
                    request.ContentOffset = startPos;
                }

                var stopwatch = new Stopwatch();
                stopwatch.Start();
                if (!Directory.Exists(Path.GetDirectoryName(filename)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(filename) !);
                }
                var fileStream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite)
                {
                    Position = metric.DownloadedBytes
                };
                await Task.Run(async() =>
                {
                    if (ct.IsCancellationRequested)
                    {
                        return;
                    }

                    using var streamReader = new StreamReader((await request.GetResponseAsync()).GetResponseStream());
                    OnDownloadStart?.Invoke(metric);
                    FromReaderToFile(streamReader, fileStream, ref metric, ref stopwatch, ct);
                    OnDownloadCompleted?.Invoke(metric);
                }, ct);

                #endregion
            }
            catch (OperationCanceledException)
            {
                const string msg = "Download cancelled by user";
                OnError?.Invoke(new DownloaderClientException(msg));
            }
            catch (Exception ex)
            {
                const string msg = "An unexpected error occurred.";
                OnError?.Invoke(
                    new DownloaderClientException($"{msg}\n\nDownload failed. See inner exception for details.", ex));
            }
        }
Ejemplo n.º 6
0
        private async void DownloadWithUrl(string _url)
        {
            var _filePath = new Uri(_url).AbsolutePath;
            var _name     = Path.GetFileName(_filePath);
            var _dir      = $"./downloads/{Path.GetDirectoryName(_filePath)}";

            var _path = $"{_dir}/{_name}";

            if (!Directory.Exists(_dir))
            {
                Directory.CreateDirectory(_dir);
            }

            if (File.Exists(_path))
            {
                OnDownloadComplete?.Invoke(this, new DownloadResultEventArg
                {
                    FileName = _name,
                    Success  = true,
                    Url      = _url,
                    Contains = true
                });
            }
            else
            {
                try
                {
                    OnDownloadStart?.Invoke(this, new DownloadResultEventArg
                    {
                        FileName = _name,
                        Success  = true,
                        Url      = _url
                    });

                    HttpWebRequest webRequest = WebRequest.CreateHttp(_url);
                    webRequest.UserAgent = "Half-Life 2";
                    webRequest.Referer   = "hl2://31.186.251.23:27016";

                    using (WebResponse _request = webRequest.GetResponse())
                        using (Stream _stream = _request.GetResponseStream())
                            using (FileStream _file = File.Create(_path))
                                await _stream.CopyToAsync(_file);

                    OnDownloadComplete?.Invoke(this, new DownloadResultEventArg
                    {
                        FileName = _name,
                        Success  = true,
                        Url      = _url
                    });
                }
                catch (Exception ex)
                {
                    //WebException _ex = ex as WebException;

                    if (_retryCount++ < 3)
                    {
                        File.Delete(_path);
                        DownloadWithUrl(_url);
                    }
                    else
                    {
                        _retryCount = 0;

                        OnDownloadComplete?.Invoke(this, new DownloadResultEventArg
                        {
                            FileName  = _name,
                            Success   = false,
                            Url       = _url,
                            Exception = ex
                        });
                    }
                }
            }
        }
Ejemplo n.º 7
0
        internal async Task <byte[]> ProcessDownloadAsync(Uri uri, Stream output, CancellationToken ct)
        {
            byte[] vs = Array.Empty <byte>();
            try
            {
                #region Get file size
                DownloadTrace?.Invoke("Getting file size...");
                WebRequest webRequest = WebRequest.Create(uri);
                webRequest.Method = "HEAD";
                Stopwatch      watch = new Stopwatch();
                DownloadMetric m     = new DownloadMetric();
                long?          bytes;
                watch.Start();
                using (WebResponse webResponse = webRequest.GetResponse())
                {
                    bytes = long.Parse(webResponse.Headers.Get("Content-Length"));
                    DownloadTrace?.Invoke($"File size: {bytes.Value.HumanizeBytes(2)}");
                    m.TotalBytes  = bytes.Value;
                    m.ElapsedTime = watch.Elapsed;
                }

                /*__________________________________________________________________________________
                 |                                                                                |
                 |  .NET runtime has a 2GB size limit for objects.                                |
                 |  ----------------------------------------------                                |
                 |  To adhere to this restriction, this module ONLY allows downloading files      |
                 |  less than 1GB. If the file is greater than 1GB, call DownloadToFile method    |
                 |  instead which downloads the file directly to disk or allow this application   |
                 |  to automatically save the file to disk for you.                               |
                 |  ----------------------------------------------                                |
                 |  1 GB = 1,000,000,000 (1 Billion Bytes).                                       |
                 |                                                                                |
                 *|________________________________________________________________________________|*/
                if (bytes == null)
                {
                    bytes = _maxDowloadSize;
                }
                else
                {
                    if (bytes.Value > _maxDowloadSize)
                    {
                        bytes = _maxDowloadSize;
                    }
                }
                #endregion

                #region Read Content Stream Asynchronously
                long?l = bytes;
                DownloadTrace?.Invoke("Download about to begin.");
                DownloadTrace.Invoke("On your marks...");
                HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest;
                req.Method = "GET";
                req.AddRange(0, bytes.Value);
                vs = await Task.Run(async() =>
                {
                    // Check if operation is already canceled?
                    ct.ThrowIfCancellationRequested();

                    using (StreamReader sr = new StreamReader((await req.GetResponseAsync()).GetResponseStream()))
                    {
                        DownloadTrace.Invoke("Download started!");
                        OnDownloadStart?.Invoke(m);
                        var a = FromReaderToStream(sr, output, ref m, ref watch, ref l, ct);
                        DownloadCompleted?.Invoke(m, null);
                        return(a);
                    }
                }, ct);

                #endregion
            }
            catch (OperationCanceledException)
            {
                string msg = "Download cancelled by user";
                DownloadTrace.Invoke(msg);
                OnError?.Invoke(new DownloadClientException(msg));
            }
            catch (Exception ex)
            {
                string msg = "An unexpected error occured.";
                DownloadTrace?.Invoke(msg);
                OnError?.Invoke(new DownloadClientException($"{msg}\n\nDownload failed. See inner exception for details.", ex));
            }
            return(vs);
        }