From 4dfae48095b254d895deb7a1a345c2ed30295f35 Mon Sep 17 00:00:00 2001 From: YPermitin Date: Thu, 6 Jul 2023 17:41:57 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8=20=D0=B4=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B8=D0=B1=D1=83=D1=82=D0=B8=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=A4=D0=98=D0=90=D0=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлено тестовое приложение для загрузки дистрибутива ФИАС - Улучшен вспомогательный класс работы с API ФИАС * Оптимизировано обращение через HTTP-клиент * Добавлена возможность многопоточной загрузки данных * Реализована обработка события изменения прогреса загрузки файла - Выделен список файлов дистрибутивов для загрузки - Добавлены вспомогательные методы получения URL и загрузки файла по типу файла дистрибутива - Загрузка файлов и другие HTTP-запросы теперь выполняются с "User Agent" от имени обычного браузера - Удалены неиспользуемые элементы решения и проектов - Очистка кода - Расширены тесты в части загрузки файлов дистрибутивов --- .../Program.cs | 47 +++++++++ ....FIASToolSet.DistributionDownloader.csproj | 14 +++ .../API/APIHelper.cs | 88 +++++++++++------ .../API/IAPIHelper.cs | 5 +- .../Enums/DistributionFileType.cs | 16 ++++ .../GeneralResources.Designer.cs | 54 +++++++++++ .../GeneralResources.resx | 24 +++++ .../DownloadDistributionFileEventArgs.cs | 20 ++++ ...istributionFileProgressChangedEventType.cs | 10 ++ .../Models/FIASDistributionInfo.cs | 95 ++++++++++++++++++- ...tin.FIASToolSet.DistributionBrowser.csproj | 20 ++++ .../YPermitin.FIASToolSet.Loader.xml | 32 ++++++- .../ZipHelper.cs | 23 +++++ .../YPermitin.FIASToolSet.Storage.Core.csproj | 4 - .../FIASDistributionBrowserTests.cs | 24 +++++ YPermitin.FIASToolSet.sln | 9 ++ 16 files changed, 441 insertions(+), 44 deletions(-) create mode 100644 Apps/YPermitin.FIASToolSet.DistributionDownloader/Program.cs create mode 100644 Apps/YPermitin.FIASToolSet.DistributionDownloader/YPermitin.FIASToolSet.DistributionDownloader.csproj create mode 100644 Libs/YPermitin.FIASToolSet.DistributionBrowser/Enums/DistributionFileType.cs create mode 100644 Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.Designer.cs create mode 100644 Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.resx create mode 100644 Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileEventArgs.cs create mode 100644 Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileProgressChangedEventType.cs create mode 100644 Libs/YPermitin.FIASToolSet.DistributionBrowser/ZipHelper.cs diff --git a/Apps/YPermitin.FIASToolSet.DistributionDownloader/Program.cs b/Apps/YPermitin.FIASToolSet.DistributionDownloader/Program.cs new file mode 100644 index 0000000..060f1aa --- /dev/null +++ b/Apps/YPermitin.FIASToolSet.DistributionDownloader/Program.cs @@ -0,0 +1,47 @@ +// See https://aka.ms/new-console-template for more information + +using YPermitin.FIASToolSet.DistributionBrowser; +using YPermitin.FIASToolSet.DistributionBrowser.Enums; +using YPermitin.FIASToolSet.DistributionBrowser.Models; + +Console.WriteLine("Тестовая загрузка полного дистрибутива ФИАС."); + +IFIASDistributionBrowser loader = new FIASDistributionBrowser(); +var lastInfo = await loader.GetLastDistributionInfo(); +var xmlFullUrl = lastInfo?.GetUrlByFileType(DistributionFileType.GARFIASXmlComplete); + +var tempFileToDownload = Path.Combine( + Path.GetTempPath(), + "FIAS_FULL.zip"); + +DateTime downloadStarted = DateTime.UtcNow; +DateTime lastProgressShow = DateTime.MinValue; +double lastProgressPercentage = 0; +await lastInfo?.DownloadDistributionByFileTypeAsync( + DistributionFileType.GARFIASXmlComplete, + tempFileToDownload, + (args) => + { + double progress = Math.Round(args.ProgressPercentage, 2); + + double progressChanged = lastProgressPercentage - progress; + + var showProgressTimeLeft = DateTime.UtcNow - lastProgressShow; + if (args.State != DownloadDistributionFileProgressChangedEventType.Downloading + || showProgressTimeLeft.TotalSeconds > 10 + || progressChanged >= 1) + { + var downloadDuration = DateTime.UtcNow - downloadStarted; + Console.WriteLine($"[{DateTime.UtcNow}] {args.State}. Progress: {progress} %. Seconds left: {downloadDuration.TotalSeconds}"); + if (args.ErrorInfo != null) + { + Console.WriteLine(args.ErrorInfo.GetBaseException().Message); + } + + lastProgressPercentage = progress; + lastProgressShow = DateTime.UtcNow; + } + }); + +Console.WriteLine("Для выхода нажмите любую клавишу..."); +Console.ReadKey(); \ No newline at end of file diff --git a/Apps/YPermitin.FIASToolSet.DistributionDownloader/YPermitin.FIASToolSet.DistributionDownloader.csproj b/Apps/YPermitin.FIASToolSet.DistributionDownloader/YPermitin.FIASToolSet.DistributionDownloader.csproj new file mode 100644 index 0000000..202e7ec --- /dev/null +++ b/Apps/YPermitin.FIASToolSet.DistributionDownloader/YPermitin.FIASToolSet.DistributionDownloader.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/APIHelper.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/APIHelper.cs index e6c3633..2520837 100644 --- a/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/APIHelper.cs +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/APIHelper.cs @@ -1,52 +1,80 @@ using System; -using System.IO; using System.Net.Http; using System.Threading.Tasks; +using Downloader; +using YPermitin.FIASToolSet.DistributionBrowser.Models; namespace YPermitin.FIASToolSet.DistributionBrowser.API { internal class APIHelper : IAPIHelper { - private readonly HttpClient _apiClient; - - - public APIHelper() + private static readonly string DefaultUserAgent = GeneralResources.DefaultUserAgent; + private static readonly HttpClient APIClient; + private static readonly DownloadConfiguration DownloaderConfiguration = new DownloadConfiguration() { - _apiClient = new HttpClient(); + ChunkCount = 8, + ParallelDownload = true, + RequestConfiguration = new RequestConfiguration() + { + UserAgent = DefaultUserAgent + } + }; + static APIHelper() + { + APIClient = new HttpClient(); + APIClient.DefaultRequestHeaders + .UserAgent.TryParseAdd(DefaultUserAgent); } - + /// /// Загрузка файла по URL и сохранение его в файловой системе /// /// URL файла /// Путь для сохранения + /// Событие с информацией о прогрессе загрузки файла /// Асинхронная операция - public async Task DownloadFileAsync(Uri uriFile, string savePath) + public async Task DownloadFileAsync(Uri uriFile, string savePath, + Action onDownloadFileProgressChangedEvent = null) { - using (HttpResponseMessage response = _apiClient.GetAsync(uriFile, HttpCompletionOption.ResponseHeadersRead).Result) + var downloader = new DownloadService(DownloaderConfiguration); + downloader.DownloadStarted += (sender, args) => { - response.EnsureSuccessStatusCode(); - - await using (Stream contentStream = await response.Content.ReadAsStreamAsync(), fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) + var eventArgs = new DownloadDistributionFileProgressChangedEventArgs( + state: DownloadDistributionFileProgressChangedEventType.Started, + progressPercentage: 0); + onDownloadFileProgressChangedEvent?.Invoke(eventArgs); + }; + downloader.DownloadProgressChanged += (sender, args) => + { + var eventArgs = new DownloadDistributionFileProgressChangedEventArgs( + state: DownloadDistributionFileProgressChangedEventType.Downloading, + progressPercentage: args.ProgressPercentage); + onDownloadFileProgressChangedEvent?.Invoke(eventArgs); + }; + downloader.DownloadFileCompleted += (sender, args) => + { + DownloadDistributionFileProgressChangedEventType state; + Exception errorInfo = null; + + if (args.Cancelled) + state = DownloadDistributionFileProgressChangedEventType.Canceled; + else if (args.Error != null) { - var buffer = new byte[8192]; - var isMoreToRead = true; - - do - { - var read = await contentStream.ReadAsync(buffer, 0, buffer.Length); - if (read == 0) - { - isMoreToRead = false; - } - else - { - await fileStream.WriteAsync(buffer, 0, read); - } - } - while (isMoreToRead); + state = DownloadDistributionFileProgressChangedEventType.Failure; + errorInfo = args.Error; } - } + else + { + state = DownloadDistributionFileProgressChangedEventType.Compleated; + } + + var eventArgs = new DownloadDistributionFileProgressChangedEventArgs( + state: state, + progressPercentage: 100, + errorInfo: errorInfo); + onDownloadFileProgressChangedEvent?.Invoke(eventArgs); + }; + await downloader.DownloadFileTaskAsync(uriFile.AbsoluteUri, savePath); } /// @@ -56,7 +84,7 @@ public async Task DownloadFileAsync(Uri uriFile, string savePath) /// Строкове содержимое данных по URL public async Task GetContentAsStringAsync(Uri uri) { - var response = await _apiClient.GetAsync(uri); + var response = await APIClient.GetAsync(uri); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/IAPIHelper.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/IAPIHelper.cs index e3fe7f5..294a24a 100644 --- a/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/IAPIHelper.cs +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/API/IAPIHelper.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using YPermitin.FIASToolSet.DistributionBrowser.Models; namespace YPermitin.FIASToolSet.DistributionBrowser.API { @@ -10,8 +11,10 @@ internal interface IAPIHelper /// /// URL файла /// Путь для сохранения + /// Событие с информацией о прогрессе загрузки файла /// Асинхронная операция - Task DownloadFileAsync(Uri uriFile, string savePath); + Task DownloadFileAsync(Uri uriFile, string savePath, + Action onDownloadFileProgressChangedEvent = null); /// /// Получение содержимого по URL diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/Enums/DistributionFileType.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Enums/DistributionFileType.cs new file mode 100644 index 0000000..a22cb42 --- /dev/null +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Enums/DistributionFileType.cs @@ -0,0 +1,16 @@ +namespace YPermitin.FIASToolSet.DistributionBrowser.Enums; + +/// +/// Типы файлов дистрибутива ФИАС для загрузки +/// +public enum DistributionFileType +{ + FIASDbfComplete, + FIASDbfDelta, + FIASXmlComplete, + FIASXmlDelta, + GARFIASXmlComplete, + GARFIASXmlDelta, + KLADR4ArjComplete, + KLADR47zComplete +} \ No newline at end of file diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.Designer.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.Designer.cs new file mode 100644 index 0000000..7f970bd --- /dev/null +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.Designer.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace YPermitin.FIASToolSet.DistributionBrowser { + using System; + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class GeneralResources { + + private static System.Resources.ResourceManager resourceMan; + + private static System.Globalization.CultureInfo resourceCulture; + + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal GeneralResources() { + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Resources.ResourceManager ResourceManager { + get { + if (object.Equals(null, resourceMan)) { + System.Resources.ResourceManager temp = new System.Resources.ResourceManager("YPermitin.FIASToolSet.DistributionBrowser.GeneralResources", typeof(GeneralResources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static string DefaultUserAgent { + get { + return ResourceManager.GetString("DefaultUserAgent", resourceCulture); + } + } + } +} diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.resx b/Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.resx new file mode 100644 index 0000000..af612d7 --- /dev/null +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/GeneralResources.resx @@ -0,0 +1,24 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 YaBrowser/23.5.1.800 Yowser/2.5 Safari/537.36 + + \ No newline at end of file diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileEventArgs.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileEventArgs.cs new file mode 100644 index 0000000..ec0d3f1 --- /dev/null +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileEventArgs.cs @@ -0,0 +1,20 @@ +using System; + +namespace YPermitin.FIASToolSet.DistributionBrowser.Models; + +public class DownloadDistributionFileProgressChangedEventArgs +{ + public DownloadDistributionFileProgressChangedEventType State { get; } + public double ProgressPercentage { get; } + public Exception ErrorInfo { get; } + + public DownloadDistributionFileProgressChangedEventArgs( + DownloadDistributionFileProgressChangedEventType state, + double progressPercentage, + Exception errorInfo = null) + { + ProgressPercentage = progressPercentage; + State = state; + ErrorInfo = errorInfo; + } +} \ No newline at end of file diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileProgressChangedEventType.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileProgressChangedEventType.cs new file mode 100644 index 0000000..f3ae75a --- /dev/null +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/DownloadDistributionFileProgressChangedEventType.cs @@ -0,0 +1,10 @@ +namespace YPermitin.FIASToolSet.DistributionBrowser.Models; + +public enum DownloadDistributionFileProgressChangedEventType +{ + Started, + Downloading, + Compleated, + Failure, + Canceled +} \ No newline at end of file diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/FIASDistributionInfo.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/FIASDistributionInfo.cs index 39985f6..9bb08b7 100644 --- a/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/FIASDistributionInfo.cs +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/Models/FIASDistributionInfo.cs @@ -2,6 +2,7 @@ using System.IO; using System.Threading.Tasks; using YPermitin.FIASToolSet.DistributionBrowser.API; +using YPermitin.FIASToolSet.DistributionBrowser.Enums; namespace YPermitin.FIASToolSet.DistributionBrowser.Models { @@ -45,6 +46,86 @@ public sealed class FIASDistributionInfo /// public DistributionFileFormatInfo KLADR4Arj { get; } + /// + /// Получение адреса файла для скачивания по типу + /// + /// Тип файла дистрибутива + /// Адрес для скачивания файла дистрибутива + public Uri GetUrlByFileType(DistributionFileType fileType) + { + Uri fileUrl = null; + + switch (fileType) + { + case DistributionFileType.FIASDbfComplete: + fileUrl = FIASDbf.Complete; + break; + case DistributionFileType.FIASDbfDelta: + fileUrl = FIASDbf.Delta; + break; + case DistributionFileType.FIASXmlComplete: + fileUrl = FIASXml.Complete; + break; + case DistributionFileType.FIASXmlDelta: + fileUrl = FIASXml.Delta; + break; + case DistributionFileType.GARFIASXmlComplete: + fileUrl = GARFIASXml.Complete; + break; + case DistributionFileType.GARFIASXmlDelta: + fileUrl = GARFIASXml.Delta; + break; + case DistributionFileType.KLADR47zComplete: + fileUrl = KLADR47z.Complete; + break; + case DistributionFileType.KLADR4ArjComplete: + fileUrl = KLADR4Arj.Complete; + break; + } + + return fileUrl; + } + + /// + /// Скачивание файла дистрибутивая по типу + /// + /// Тип файла дистрибутива + /// Путь для сохранрения файла + /// Событие с информацией о прогрессе загрузки файла + public async Task DownloadDistributionByFileTypeAsync( + DistributionFileType fileType, + string pathToSaveFile, + Action onDownloadFileProgressChangedEvent = null) + { + switch (fileType) + { + case DistributionFileType.FIASDbfComplete: + await FIASDbf.SaveCompleteFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + case DistributionFileType.FIASDbfDelta: + await FIASDbf.SaveDeltaFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + case DistributionFileType.FIASXmlComplete: + await FIASXml.SaveCompleteFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + case DistributionFileType.FIASXmlDelta: + await FIASXml.SaveDeltaFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + case DistributionFileType.KLADR4ArjComplete: + await KLADR4Arj.SaveCompleteFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + case DistributionFileType.KLADR47zComplete: + await KLADR47z.SaveDeltaFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + case DistributionFileType.GARFIASXmlComplete: + await GARFIASXml.SaveCompleteFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + case DistributionFileType.GARFIASXmlDelta: + await GARFIASXml.SaveDeltaFileAsync(pathToSaveFile, onDownloadFileProgressChangedEvent); + break; + } + } + /// /// Файлы дистрибутива КЛАДР 4 в формате 7Z /// @@ -113,8 +194,10 @@ internal DistributionFileFormatInfo(IAPIHelper apiHelper, Uri complete, Uri delt /// Сохранение полного дистрибутива в указанный файл /// /// Путь к файлу для сохранения + /// Событие с информацией о прогрессе загрузки файла /// Асинхронная операция - public async Task SaveCompleteFileAsync(string fileToSave) + public async Task SaveCompleteFileAsync(string fileToSave, + Action onDownloadFileProgressChangedEvent = null) { FileInfo fileToSaveInfo = new FileInfo(fileToSave); if (fileToSaveInfo.Directory != null) @@ -122,8 +205,8 @@ public async Task SaveCompleteFileAsync(string fileToSave) if (!fileToSaveInfo.Directory.Exists) fileToSaveInfo.Directory.Create(); } - - await _apiHelper.DownloadFileAsync(Complete, fileToSave); + + await _apiHelper.DownloadFileAsync(Complete, fileToSave, onDownloadFileProgressChangedEvent); } /// @@ -142,8 +225,10 @@ public async Task LastDistributionInfoExists() /// Сохранение дистрибутива с изменениями в указанный файл /// /// Путь к файлу для сохранения + /// Событие с информацией о прогрессе загрузки файла /// Асинхронная операция - public async Task SaveDeltaFileAsync(string fileToSave) + public async Task SaveDeltaFileAsync(string fileToSave, + Action onDownloadFileProgressChangedEvent = null) { FileInfo fileToSaveInfo = new FileInfo(fileToSave); if (fileToSaveInfo.Directory != null) @@ -152,7 +237,7 @@ public async Task SaveDeltaFileAsync(string fileToSave) fileToSaveInfo.Directory.Create(); } - await _apiHelper.DownloadFileAsync(Delta, fileToSave); + await _apiHelper.DownloadFileAsync(Delta, fileToSave, onDownloadFileProgressChangedEvent); } /// diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.DistributionBrowser.csproj b/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.DistributionBrowser.csproj index a384bd3..21a2c35 100644 --- a/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.DistributionBrowser.csproj +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.DistributionBrowser.csproj @@ -16,6 +16,7 @@ + @@ -25,4 +26,23 @@ + + + + + + + ResXFileCodeGenerator + GeneralResources.Designer.cs + + + + + + True + True + GeneralResources.resx + + + diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.Loader.xml b/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.Loader.xml index 2dabe07..ebcfac0 100644 --- a/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.Loader.xml +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/YPermitin.FIASToolSet.Loader.xml @@ -4,12 +4,13 @@ YPermitin.FIASToolSet.DistributionBrowser - + Загрузка файла по URL и сохранение его в файловой системе URL файла Путь для сохранения + Событие с информацией о прогрессе загрузки файла Асинхронная операция @@ -26,12 +27,13 @@ URL файла Истина - файл сущестует и Ложь в противном случае - + Загрузка файла по URL и сохранение его в файловой системе URL файла Путь для сохранения + Событие с информацией о прогрессе загрузки файла Асинхронная операция @@ -48,6 +50,11 @@ URL файла Истина - файл сущестует и Ложь в противном случае + + + Типы файлов дистрибутива ФИАС для загрузки + + Объект работы с дистрибутивами ФИАС разных форматов и типов @@ -122,6 +129,21 @@ Файлы дистрибутива КЛАДР 4 в формате ARJ + + + Получение адреса файла для скачивания по типу + + Тип файла дистрибутива + Адрес для скачивания файла дистрибутива + + + + Скачивание файла дистрибутивая по типу + + Тип файла дистрибутива + Путь для сохранрения файла + Событие с информацией о прогрессе загрузки файла + Файлы дистрибутива КЛАДР 4 в формате 7Z @@ -142,11 +164,12 @@ URL дельта версии дистрибутива - + Сохранение полного дистрибутива в указанный файл Путь к файлу для сохранения + Событие с информацией о прогрессе загрузки файла Асинхронная операция @@ -155,11 +178,12 @@ Истина - существует и Ложь в противном случае - + Сохранение дистрибутива с изменениями в указанный файл Путь к файлу для сохранения + Событие с информацией о прогрессе загрузки файла Асинхронная операция diff --git a/Libs/YPermitin.FIASToolSet.DistributionBrowser/ZipHelper.cs b/Libs/YPermitin.FIASToolSet.DistributionBrowser/ZipHelper.cs new file mode 100644 index 0000000..43e30c1 --- /dev/null +++ b/Libs/YPermitin.FIASToolSet.DistributionBrowser/ZipHelper.cs @@ -0,0 +1,23 @@ +using System.IO; +using System.IO.Compression; + +namespace YPermitin.FIASToolSet.DistributionBrowser; + +public static class ZipHelper +{ + public static bool IsZipValid(string path) + { + try + { + using (var zipFile = ZipFile.OpenRead(path)) + { + var entries = zipFile.Entries; + return true; + } + } + catch (InvalidDataException) + { + return false; + } + } +} \ No newline at end of file diff --git a/Libs/YPermitin.FIASToolSet.Storage.Core/YPermitin.FIASToolSet.Storage.Core.csproj b/Libs/YPermitin.FIASToolSet.Storage.Core/YPermitin.FIASToolSet.Storage.Core.csproj index 34da672..82a067e 100644 --- a/Libs/YPermitin.FIASToolSet.Storage.Core/YPermitin.FIASToolSet.Storage.Core.csproj +++ b/Libs/YPermitin.FIASToolSet.Storage.Core/YPermitin.FIASToolSet.Storage.Core.csproj @@ -22,8 +22,4 @@ - - - - diff --git a/Tests/YPermitin.FIASToolSet.DistributionBrowser.Tests/FIASDistributionBrowserTests.cs b/Tests/YPermitin.FIASToolSet.DistributionBrowser.Tests/FIASDistributionBrowserTests.cs index 8459710..55183ea 100644 --- a/Tests/YPermitin.FIASToolSet.DistributionBrowser.Tests/FIASDistributionBrowserTests.cs +++ b/Tests/YPermitin.FIASToolSet.DistributionBrowser.Tests/FIASDistributionBrowserTests.cs @@ -1,3 +1,5 @@ +using YPermitin.FIASToolSet.DistributionBrowser.Enums; + namespace YPermitin.FIASToolSet.DistributionBrowser.Tests { public class FIASDistributionBrowserTests @@ -28,5 +30,27 @@ public async Task GetAllDistributionInfoTest() Assert.NotNull(allInfo); Assert.True(allInfo.Count > 0); } + + [Fact] + public async Task DownloadLastGarXmlDeltaDistribution() + { + IFIASDistributionBrowser loader = new FIASDistributionBrowser(); + var lastInfo = await loader.GetLastDistributionInfo(); + + var tempFileToDownload = Path.Combine( + Path.GetTempPath(), + "FIAS_FULL.zip"); + + if (lastInfo != null) + { + await lastInfo.DownloadDistributionByFileTypeAsync( + DistributionFileType.GARFIASXmlDelta, + tempFileToDownload); + } + + Assert.NotNull(lastInfo); + Assert.True(File.Exists(tempFileToDownload)); + Assert.True(ZipHelper.IsZipValid(tempFileToDownload)); + } } } diff --git a/YPermitin.FIASToolSet.sln b/YPermitin.FIASToolSet.sln index efa5de3..1f33cbd 100644 --- a/YPermitin.FIASToolSet.sln +++ b/YPermitin.FIASToolSet.sln @@ -31,6 +31,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YPermitin.FIASToolSet.Stora EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YPermitin.FIASToolSet.Storage.SQLServer", "Libs\YPermitin.FIASToolSet.Storage.SQLServer\YPermitin.FIASToolSet.Storage.SQLServer.csproj", "{7C8AF72D-8645-4B5D-B1E5-FC3C405FEC46}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{FAA25495-423B-44E1-B49B-7DB6DB993664}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YPermitin.FIASToolSet.DistributionDownloader", "Apps\YPermitin.FIASToolSet.DistributionDownloader\YPermitin.FIASToolSet.DistributionDownloader.csproj", "{C3B585DE-1E5C-43D0-B9FE-EEA1B5673DDD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -69,6 +73,10 @@ Global {7C8AF72D-8645-4B5D-B1E5-FC3C405FEC46}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C8AF72D-8645-4B5D-B1E5-FC3C405FEC46}.Release|Any CPU.ActiveCfg = Release|Any CPU {7C8AF72D-8645-4B5D-B1E5-FC3C405FEC46}.Release|Any CPU.Build.0 = Release|Any CPU + {C3B585DE-1E5C-43D0-B9FE-EEA1B5673DDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3B585DE-1E5C-43D0-B9FE-EEA1B5673DDD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3B585DE-1E5C-43D0-B9FE-EEA1B5673DDD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3B585DE-1E5C-43D0-B9FE-EEA1B5673DDD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -82,6 +90,7 @@ Global {E1E77459-3721-4581-B00F-13708A31DDB4} = {068FF229-56E5-4718-83EF-1D863CBE8F71} {0A3BF334-1F90-4A14-B50F-D757956380C8} = {068FF229-56E5-4718-83EF-1D863CBE8F71} {7C8AF72D-8645-4B5D-B1E5-FC3C405FEC46} = {068FF229-56E5-4718-83EF-1D863CBE8F71} + {C3B585DE-1E5C-43D0-B9FE-EEA1B5673DDD} = {FAA25495-423B-44E1-B49B-7DB6DB993664} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E8FCAA60-A495-45A3-95C8-405142F3203A}