示例#1
0
        public async Task<FilterUpdateResult> UpdateFilterAsync(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress<ProgressModel> progress)
        {
            var filterPath = CacheProvider.FilterPath;

            // Update qBittorrent config
            var qBittorrentIniPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "qBittorrent", "qBittorrent.ini");

            if (File.Exists(qBittorrentIniPath))
            {
                Trace.TraceInformation("Pointing qBittorrent to " + filterPath);
                Trace.TraceInformation("Updating qBittorrent configuration: " + qBittorrentIniPath);

                try
                {
                    WriteIniSetting("Preferences", @"IPFilter\Enabled", "true", qBittorrentIniPath);
                    WriteIniSetting("Preferences", @"IPFilter\File", filterPath.Replace("\\", "/"), qBittorrentIniPath);
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("Couldn't update qBittorrent configuration: " + ex);
                }
            }
            
            return new FilterUpdateResult { FilterTimestamp = filter.FilterTimestamp };
        }
示例#2
0
        public async Task <FilterDownloadResult> GetAsync(FilterDownloadResult filter)
        {
            var file = new FileInfo(filterPath);

            if (!file.Exists)
            {
                return(null);
            }

            // Find the Etag
            var etagFile = new FileInfo(file.FullName + ".etag");

            if (!etagFile.Exists)
            {
                return(null);
            }

            var result = new FilterDownloadResult
            {
                FilterTimestamp = file.LastWriteTimeUtc,
                Etag            = EntityTagHeaderValue.Parse(File.ReadAllText(etagFile.FullName)),
                Stream          = new MemoryStream((int)file.Length)
            };

            using (var stream = file.OpenRead())
            {
                await stream.CopyToAsync(result.Stream);
            }

            result.Length = result.Stream.Length;

            return(result);
        }
示例#3
0
        async Task <MemoryStream> Decompress(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            using (var stream = filter.Stream)
            {
                var result = new MemoryStream();

                stream.Seek(0, SeekOrigin.Begin);

                cancellationToken.ThrowIfCancellationRequested();

                switch (filter.CompressionFormat)
                {
                case CompressionFormat.GZip:
                    using (var gzipFile = new GZipStream(stream, CompressionMode.Decompress))
                    {
                        var buffer = new byte[1024 * 64];
                        int bytesRead;
                        while ((bytesRead = await gzipFile.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                            result.Write(buffer, 0, bytesRead);
                            progress.Report(new ProgressModel(UpdateState.Decompressing, "Decompressing...", -1));
                        }
                    }
                    break;

                case CompressionFormat.Zip:

                    using (var zipFile = new ZipArchive(stream, ZipArchiveMode.Read))
                    {
                        progress.Report(new ProgressModel(UpdateState.Decompressing, "Decompressing...", -1));

                        if (zipFile.Entries.Count == 0)
                        {
                            throw new IOException("There are no entries in the zip file.");
                        }
                        if (zipFile.Entries.Count > 1)
                        {
                            throw new IOException("There is more than one file in the zip file. This application will need to be updated to support this.");
                        }

                        var entry = zipFile.Entries.First();

                        using (var entryStream = entry.Open())
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                            await entryStream.CopyToAsync(result);
                        }
                    }
                    break;

                default:
                    await stream.CopyToAsync(result);

                    break;
                }

                return(result);
            }
        }
示例#4
0
        public async Task SetAsync(FilterDownloadResult filter)
        {
            try
            {
                if (filter == null || filter.Exception != null) return;

                var file = new FileInfo(filterPath);

                if (file.Directory != null && !file.Directory.Exists)
                {
                    file.Directory.Create();
                }

                Trace.TraceInformation("Writing cached ipfilter to " + filterPath);
                filter.Stream.Seek(0, SeekOrigin.Begin);
                using (var cacheFile = File.Open(filterPath, FileMode.Create, FileAccess.Write,FileShare.Read))
                {
                    await filter.Stream.CopyToAsync(cacheFile);
                }

                if (filter.FilterTimestamp != null)
                {
                    file.LastWriteTimeUtc = filter.FilterTimestamp.Value.UtcDateTime;
                }
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Couldn't write the cached ipfilter: " + ex.Message);
            }
        }
示例#5
0
        public Task <FilterUpdateResult> UpdateFilterAsync(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            var filterPath = CacheProvider.FilterPath;

            // Update qBittorrent config
            var qBittorrentIniPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "qBittorrent", "qBittorrent.ini");

            if (File.Exists(qBittorrentIniPath))
            {
                Trace.TraceInformation("Pointing qBittorrent to " + filterPath);
                Trace.TraceInformation("Updating qBittorrent configuration: " + qBittorrentIniPath);

                try
                {
                    WriteIniSetting("Preferences", @"IPFilter\Enabled", "true", qBittorrentIniPath);
                    WriteIniSetting("Preferences", @"IPFilter\File", filterPath.Replace("\\", "/"), qBittorrentIniPath);
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("Couldn't update qBittorrent configuration: " + ex);
                }
            }

            return(Task.FromResult(new FilterUpdateResult {
                FilterTimestamp = filter.FilterTimestamp
            }));
        }
示例#6
0
        public async Task SetAsync(FilterDownloadResult filter)
        {
            try
            {
                if (filter == null || filter.Exception != null)
                {
                    return;
                }

                var file = new FileInfo(filterPath);

                if (file.Directory != null && !file.Directory.Exists)
                {
                    file.Directory.Create();
                }

                Trace.TraceInformation("Writing cached ipfilter to " + filterPath);
                filter.Stream.Seek(0, SeekOrigin.Begin);
                using (var cacheFile = File.Open(filterPath, FileMode.Create, FileAccess.Write, FileShare.Read))
                {
                    await filter.Stream.CopyToAsync(cacheFile);
                }

                if (filter.FilterTimestamp != null)
                {
                    file.LastWriteTimeUtc = filter.FilterTimestamp.Value.UtcDateTime;
                }
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Couldn't write the cached ipfilter: " + ex.Message);
            }
        }
示例#7
0
        public async Task <FilterUpdateResult> UpdateFilterAsync(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            var basePath        = Environment.GetFolderPath(configFolder, Environment.SpecialFolderOption.Create);
            var destinationPath = Path.Combine(basePath, FolderName, "config", "ipfilter.dat");

            Trace.TraceInformation("Writing filter to " + destinationPath);
            using var destination = File.Open(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None);
            using var writer      = new EmuleWriter(destination);
            await writer.Write(filter.Entries, progress);

            return(new FilterUpdateResult {
                FilterTimestamp = filter.FilterTimestamp
            });
        }
示例#8
0
        public async Task <FilterUpdateResult> UpdateFilterAsync(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            var roamingPath     = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create);
            var destinationPath = Path.Combine(roamingPath, "deluge", "ipfilter.dat");

            Trace.TraceInformation("Writing filter to " + destinationPath);
            using (var destination = File.Open(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (var writer = new P2pWriter(destination))
                {
                    await writer.Write(filter.Entries, progress);
                }

            return(new FilterUpdateResult {
                FilterTimestamp = filter.FilterTimestamp
            });
        }
示例#9
0
        public async Task <FilterUpdateResult> UpdateFilterAsync(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            var localPath            = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.Create);
            var destinationPath      = Path.Combine(localPath, FolderName, "filter", "ipfilter.dat");
            var destinationDirectory = Path.GetDirectoryName(destinationPath);

            if (destinationDirectory != null && !Directory.Exists(destinationDirectory))
            {
                Directory.CreateDirectory(destinationDirectory);
            }

            Trace.TraceInformation("Writing filter to " + destinationPath);
            using (var destination = File.Open(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None))
                using (var writer = new P2pWriter(destination))
                {
                    await writer.Write(filter.Entries, progress);
                }

            // Update qBittorrent config
            var qBittorrentIniPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), FolderName, "qBittorrent.ini");

            if (File.Exists(qBittorrentIniPath))
            {
                Trace.TraceInformation("Pointing qBittorrent to " + destinationPath);
                Trace.TraceInformation("Updating qBittorrent configuration: " + qBittorrentIniPath);

                try
                {
                    WriteIniSetting("Preferences", @"IPFilter\Enabled", "true", qBittorrentIniPath);
                    WriteIniSetting("Preferences", @"IPFilter\File", destinationPath.Replace("\\", "/"), qBittorrentIniPath);
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("Couldn't update qBittorrent configuration: " + ex);
                }
            }

            return(new FilterUpdateResult {
                FilterTimestamp = filter.FilterTimestamp
            });
        }
示例#10
0
        public async Task<FilterDownloadResult> GetAsync(FilterDownloadResult filter)
        {
            var file = new FileInfo(filterPath);

            if (!file.Exists) return null;

            var result = new FilterDownloadResult();

            result.FilterTimestamp = file.LastWriteTimeUtc;

            result.Stream = new MemoryStream((int) file.Length);

            using (var stream = file.OpenRead())
            {
                await stream.CopyToAsync(result.Stream);
            }

            result.Length = result.Stream.Length;

            return result;
        }
示例#11
0
        public async Task<FilterDownloadResult> GetAsync(FilterDownloadResult filter)
        {
            var file = new FileInfo(filterPath);

            if (!file.Exists) return null;

            var result = new FilterDownloadResult();

            result.FilterTimestamp = file.LastWriteTimeUtc;

            result.Stream = new MemoryStream((int) file.Length);

            using (var stream = file.OpenRead())
            {
                await stream.CopyToAsync(result.Stream);
            }

            result.Length = result.Stream.Length;

            return result;
        }
示例#12
0
        public async Task<FilterUpdateResult> UpdateFilterAsync(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress<ProgressModel> progress)
        {
            var roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create);
            var destinationPath = Path.Combine(roamingPath, FolderName, "ipfilter.dat");

            Trace.TraceInformation("Writing filter to " + destinationPath);
            using (var destination = File.Open(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                filter.Stream.WriteTo(destination);
            }

            return new FilterUpdateResult { FilterTimestamp = filter.FilterTimestamp };

            // TODO: Check if IP Filter is enabled in µTorrent
//            string settingsPath = Environment.ExpandEnvironmentVariables(@"%APPDATA%\uTorrent\settings.dat");
//            var settings = File.ReadAllText(settingsPath);
//            if (settings.Contains("15:ipfilter.enablei0e"))
//            {
//                MessageBox.Show("You haven't enabled IP Filtering in µTorrent! Go to http://ipfilter.codeplex.com/ for help.", "IP filtering not enabled", MessageBoxButton.OK);
//            }
        }
示例#13
0
        public async Task <FilterUpdateResult> UpdateFilterAsync(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            var roamingPath     = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create);
            var destinationPath = Path.Combine(roamingPath, FolderName, "ipfilter.dat");

            Trace.TraceInformation("Writing filter to " + destinationPath);
            using (var destination = File.Open(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                filter.Stream.WriteTo(destination);
            }

            return(new FilterUpdateResult {
                FilterTimestamp = filter.FilterTimestamp
            });

            // TODO: Check if IP Filter is enabled in µTorrent
//            string settingsPath = Environment.ExpandEnvironmentVariables(@"%APPDATA%\uTorrent\settings.dat");
//            var settings = File.ReadAllText(settingsPath);
//            if (settings.Contains("15:ipfilter.enablei0e"))
//            {
//                MessageBox.Show("You haven't enabled IP Filtering in µTorrent! Go to http://ipfilter.codeplex.com/ for help.", "IP filtering not enabled", MessageBoxButton.OK);
//            }
        }
示例#14
0
        async Task <MemoryStream> Decompress(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            using (var stream = filter.Stream)
            {
                var result = new MemoryStream();

                stream.Seek(0, SeekOrigin.Begin);

                cancellationToken.ThrowIfCancellationRequested();

                switch (filter.CompressionFormat)
                {
                case CompressionFormat.GZip:
                    using (var gzipFile = new GZipStream(stream, CompressionMode.Decompress))
                    {
                        var buffer = new byte[1024 * 64];
                        int bytesRead;
                        while ((bytesRead = await gzipFile.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                            result.Write(buffer, 0, bytesRead);
                            progress.Report(new ProgressModel(UpdateState.Decompressing, "Decompressing...", -1));
                        }
                    }
                    break;

                case CompressionFormat.Zip:

                    EventHandler <ReadProgressEventArgs> reportProgress = (sender, args) =>
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        if (args.EventType != ZipProgressEventType.Extracting_EntryBytesWritten)
                        {
                            return;
                        }
                        var percentage = (int)Math.Floor((double)args.BytesTransferred / args.TotalBytesToTransfer * 100);
                        progress.Report(new ProgressModel(UpdateState.Decompressing, "Unzipping...", percentage));
                    };

                    using (var zipFile = ZipFile.Read(stream, reportProgress))
                    {
                        if (zipFile.Entries.Count == 0)
                        {
                            throw new ZipException("There are no entries in the zip file.");
                        }
                        if (zipFile.Entries.Count > 1)
                        {
                            throw new ZipException("There is more than one file in the zip file. This application will need to be updated to support this.");
                        }

                        var entry = zipFile.Entries.First();

                        entry.Extract(result);
                    }
                    break;

                default:
                    await stream.CopyToAsync(result);

                    break;
                }

                return(result);
            }
        }
示例#15
0
        public async Task <FilterDownloadResult> DownloadFilter(Uri uri, CancellationToken cancellationToken, IProgress <ProgressModel> progress)
        {
            var result = new FilterDownloadResult();

            try
            {
                if (uri == null)
                {
                    var provider = Mirrors.First();
                    uri = new Uri(provider.GetUrlForMirror());
                }

                result.Uri = uri.ToString();

                using (var handler = new WebRequestHandler())
                {
                    handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

                    Trace.TraceInformation("Downloading filter from " + result.Uri);

                    using (var httpClient = new HttpClient(handler))
                        using (var response = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
                        {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                return(null);
                            }

                            if (!response.IsSuccessStatusCode)
                            {
                                throw new HttpRequestException((int)response.StatusCode + ": " + response.ReasonPhrase);
                            }

                            result.FilterTimestamp = response.Content.Headers.LastModified;
                            result.Etag            = response.Headers.ETag;
                            result.Length          = response.Content.Headers.ContentLength;

                            Trace.TraceInformation("Online filter's timestamp is " + result.FilterTimestamp);
                            Trace.TraceInformation("ETag: '{0}'", result.Etag);

                            // Check if the cached filter is already up to date.
                            if (cache != null && Config.Default.settings.cache.isEnabled && result.Etag != null && !result.Etag.IsWeak)
                            {
                                var cacheResult = await cache.GetAsync(result);

                                if (cacheResult != null && cacheResult.Length > 0)
                                {
                                    Trace.TraceInformation("Found cached ipfilter with timestamp of " + cacheResult.FilterTimestamp);
                                    if (cacheResult.FilterTimestamp >= result.FilterTimestamp && cacheResult.Etag != null && !cacheResult.Etag.IsWeak && cacheResult.Etag.Tag == result.Etag.Tag)
                                    {
                                        Trace.TraceInformation("Using the cached ipfilter as it's the same or newer than the online filter.");
                                        return(cacheResult);
                                    }
                                }
                            }


                            double lengthInMb = !result.Length.HasValue ? -1 : (double)result.Length.Value / 1024 / 1024;

                            double bytesDownloaded = 0;

                            using (var stream = await response.Content.ReadAsStreamAsync())
                            {
                                var buffer = new byte[65535 * 4];

                                result.Stream = new MemoryStream((int)(result.Length ?? buffer.Length));

                                int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

                                result.CompressionFormat = DetectCompressionFormat(buffer, response.Content.Headers.ContentType);

                                // We only want to report the percentage when it increments by at least 1
                                var currentPercentage = -1;

                                while (bytesRead != 0)
                                {
                                    await result.Stream.WriteAsync(buffer, 0, bytesRead, cancellationToken);

                                    bytesDownloaded += bytesRead;

                                    if (result.Length.HasValue)
                                    {
                                        double downloadedMegs = bytesDownloaded / 1024 / 1024;
                                        var    percent        = (int)Math.Floor((bytesDownloaded / result.Length.Value) * 100);
                                        if (percent > currentPercentage)
                                        {
                                            var status = string.Format(CultureInfo.CurrentUICulture, "Downloaded {0:F2} MB of {1:F2} MB", downloadedMegs, lengthInMb);
                                            progress.Report(new ProgressModel(UpdateState.Downloading, status, percent));
                                        }

                                        currentPercentage = percent;
                                    }

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

                                    bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
                                }
                            }
                        }
                }

                // Decompress if necessary
                if (result.CompressionFormat != CompressionFormat.None)
                {
                    result.Stream = await Decompress(result, cancellationToken, progress);
                }
            }
            catch (Exception ex)
            {
                result.Exception = ex;
                return(result);
            }

            // Write to cache
            if (cache != null)
            {
                await cache.SetAsync(result);
            }

            return(result);
        }
示例#16
0
        async Task<MemoryStream> Decompress(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress<ProgressModel> progress)
        {
            using (var stream = filter.Stream)
            {
                var result = new MemoryStream();

                stream.Seek(0, SeekOrigin.Begin);

                cancellationToken.ThrowIfCancellationRequested();

                switch (filter.CompressionFormat)
                {
                    case CompressionFormat.GZip:
                        using(var gzipFile = new GZipStream(stream, CompressionMode.Decompress))
                        {
                            var buffer = new byte[1024 * 64];
                            int bytesRead;
                            while ((bytesRead = await gzipFile.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
                            {
                                cancellationToken.ThrowIfCancellationRequested();
                                result.Write(buffer, 0, bytesRead);
                                progress.Report(new ProgressModel(UpdateState.Decompressing, "Decompressing...", -1));
                            }
                        }
                        break;

                    case CompressionFormat.Zip:

                        EventHandler<ReadProgressEventArgs> reportProgress = (sender, args) =>
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                            if (args.EventType != ZipProgressEventType.Extracting_EntryBytesWritten) return;
                            var percentage = (int)Math.Floor( (double)args.BytesTransferred / args.TotalBytesToTransfer * 100);
                            progress.Report(new ProgressModel(UpdateState.Decompressing, "Unzipping...", percentage));
                        };

                        using (var zipFile = ZipFile.Read(stream, reportProgress))
                        {
                            if (zipFile.Entries.Count == 0) throw new ZipException("There are no entries in the zip file.");
                            if (zipFile.Entries.Count > 1) throw new ZipException("There is more than one file in the zip file. This application will need to be updated to support this.");

                            var entry = zipFile.Entries.First();

                            entry.Extract(result);
                        }
                        break;

                    default:
                        await stream.CopyToAsync(result);
                        break;
                }

                return result;
            }
        }
示例#17
0
        public async Task<FilterDownloadResult> DownloadFilter(Uri uri, CancellationToken cancellationToken, IProgress<ProgressModel> progress)
        {
            var result = new FilterDownloadResult();

            try
            {
                
                if (uri == null)
                {
                    var provider = Mirrors.First();
                    var mirror = provider.GetMirrors().First();
                    uri = new Uri(provider.GetUrlForMirror(mirror));
                }

                result.Uri = uri.ToString();

                using (var handler = new WebRequestHandler())
                {
                    handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

                    Trace.TraceInformation("Downloading filter from " + result.Uri);

                    using (var httpClient = new HttpClient(handler))
                    using (var response = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
                    {
                        if (cancellationToken.IsCancellationRequested) return null;

                        result.FilterTimestamp = response.Content.Headers.LastModified ?? response.Headers.Date;
                        result.Etag = response.Headers.ETag;

                        Trace.TraceInformation("Online filter's timestamp is " + result.FilterTimestamp);
                        Trace.TraceInformation("ETag: '{0}'", result.Etag);


                        // Check if the cached filter is already up to date.
                        if (cache != null && !Settings.Default.DisableCache)
                        {
                            var cacheResult = await cache.GetAsync(result);

                            if (cacheResult != null && cacheResult.Length > 0)
                            {
                                Trace.TraceInformation("Found cached ipfilter with timestamp of " + cacheResult.FilterTimestamp);
                                if (cacheResult.FilterTimestamp >= result.FilterTimestamp)
                                {
                                    Trace.TraceInformation("Using the cached ipfilter as it's the same or newer than the online filter.");
                                    return cacheResult;
                                }
                            }
                        }
                        
                        result.Length = response.Content.Headers.ContentLength;

                        double lengthInMb = !result.Length.HasValue ? -1 : (double) result.Length.Value / 1024 / 1024;

                        double bytesDownloaded = 0;

                        using (var stream = await response.Content.ReadAsStreamAsync())
                        {
                            var buffer = new byte[65535 * 4];

                            result.Stream = new MemoryStream((int) (result.Length ?? buffer.Length));

                            int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

                            result.CompressionFormat = DetectCompressionFormat(buffer, response.Content.Headers.ContentType);

                            while (bytesRead != 0)
                            {
                                await result.Stream.WriteAsync(buffer, 0, bytesRead, cancellationToken);
                                bytesDownloaded += bytesRead;

                                if (result.Length.HasValue)
                                {
                                    double downloadedMegs = bytesDownloaded / 1024 / 1024;
                                    var percent = (int)Math.Floor((bytesDownloaded / result.Length.Value) * 100);
                                    
                                    var status = string.Format(CultureInfo.CurrentUICulture, "Downloaded {0:F2} MB of {1:F2} MB", downloadedMegs, lengthInMb);

                                    progress.Report(new ProgressModel(UpdateState.Downloading, status, percent));
                                }

                                if (cancellationToken.IsCancellationRequested) return null;

                                bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
                            }
                        }
                    }
                }

                // Decompress if necessary
                if (result.CompressionFormat != CompressionFormat.None)
                {
                    result.Stream = await Decompress(result, cancellationToken, progress);
                }
            }
            catch (Exception ex)
            {
                result.Exception = ex;
                return result;
            }

            // Write to cache
            if (cache != null)
            {
                await cache.SetAsync(result);
            }

            return result;
        }
示例#18
0
        async Task<MemoryStream> Decompress(FilterDownloadResult filter, CancellationToken cancellationToken, IProgress<ProgressModel> progress)
        {
            using (var stream = filter.Stream)
            {
                var result = new MemoryStream();

                stream.Seek(0, SeekOrigin.Begin);

                cancellationToken.ThrowIfCancellationRequested();

                switch (filter.CompressionFormat)
                {
                    case CompressionFormat.GZip:
                        using(var gzipFile = new GZipStream(stream, CompressionMode.Decompress))
                        {
                            var buffer = new byte[1024 * 64];
                            int bytesRead;
                            while ((bytesRead = await gzipFile.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
                            {
                                cancellationToken.ThrowIfCancellationRequested();
                                result.Write(buffer, 0, bytesRead);
                                progress.Report(new ProgressModel(UpdateState.Decompressing, "Decompressing...", -1));
                            }
                        }
                        break;

                    case CompressionFormat.Zip:

                        using (var zipFile = new ZipArchive(stream,ZipArchiveMode.Read))
                        {
                            progress.Report(new ProgressModel(UpdateState.Decompressing, "Decompressing...", -1));
                            
                            if (zipFile.Entries.Count == 0) throw new IOException("There are no entries in the zip file.");
                            if (zipFile.Entries.Count > 1) throw new IOException("There is more than one file in the zip file. This application will need to be updated to support this.");

                            var entry = zipFile.Entries.First();

                            using (var entryStream = entry.Open())
                            {
                                cancellationToken.ThrowIfCancellationRequested();
                                await entryStream.CopyToAsync(result);
                            }
                        }
                        break;

                    default:
                        await stream.CopyToAsync(result);
                        break;
                }

                return result;
            }
        }