< Summary

Information
Class: Services.ParserServices.CsvUrlParser
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ParserServices/CsvUrlParser.cs
Line coverage
5%
Covered lines: 3
Uncovered lines: 56
Coverable lines: 59
Total lines: 112
Line coverage: 5%
Branch coverage
0%
Covered branches: 0
Total branches: 16
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ReadFileFromUrl()0%272160%
ReadCsv(...)100%210%
ReadExcel(...)100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ParserServices/CsvUrlParser.cs

#LineLine coverage
 1using System.Data;
 2using System.Globalization;
 3using System.Net.Http;
 4using CsvHelper;
 5using CsvHelper.Configuration;
 6using ExcelDataReader;
 7using Newtonsoft.Json;
 8using Newtonsoft.Json.Linq;
 9using Services.ApiServices.OzonApi;
 10
 11namespace Services.ParserServices
 12{
 13    public class CsvUrlParser
 14    {
 15        private readonly IHttpClientFactory _httpClientFactory;
 16
 4417        public CsvUrlParser(IHttpClientFactory httpClientFactory)
 18        {
 4419            _httpClientFactory = httpClientFactory;
 4420        }
 21
 22        public async Task<JArray> ReadFileFromUrl(string fileUrl)
 23        {
 024            if (string.IsNullOrEmpty(fileUrl))
 025                throw new ArgumentException("Ссылка на файл не была передана");
 26
 27            try
 28            {
 029                using var httpClient = _httpClientFactory.CreateClient();
 030                using var response = await OzonReportDownloadHelper.GetWithRetryAsync(httpClient, fileUrl);
 31
 032                if (!response.IsSuccessStatusCode)
 033                    throw new ArgumentException($"Не удалось получить файл. Код состояния: {response.StatusCode}");
 34
 035                var stream = await response.Content.ReadAsStreamAsync();
 036                var contentType = response.Content.Headers.ContentType?.MediaType;
 37
 38                // Определяем расширение файла из URL
 039                var fileExtension = Path.GetExtension(fileUrl)?.ToLowerInvariant();
 40
 41                // XLSX - проверяем как по content-type, так и по расширению файла
 042                if (contentType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ||
 043                    fileExtension == ".xlsx")
 44                {
 045                    return ReadExcel(stream);
 46                }
 47
 48                // Также можно добавить проверку на старый формат Excel
 049                if (contentType == "application/vnd.ms-excel" ||
 050                    fileExtension == ".xls")
 51                {
 052                    return ReadExcel(stream); // или отдельный метод для старого формата
 53                }
 54
 55                // CSV (по умолчанию)
 056                return ReadCsv(stream);
 57            }
 058            catch (Exception ex)
 59            {
 060                throw new ArgumentException($"Произошла ошибка при чтении файла: {ex.Message} -> {fileUrl}");
 61            }
 062        }
 63        private JArray ReadCsv(Stream stream)
 64        {
 065            using var reader = new StreamReader(stream);
 066            using var csv = new CsvReader(reader, new CsvConfiguration(CultureInfo.InvariantCulture)
 067            {
 068                Delimiter = ";",
 069                HasHeaderRecord = true,
 070                BadDataFound = null,
 071                MissingFieldFound = null,
 072                IgnoreBlankLines = true
 073            });
 74
 075            var records = csv.GetRecords<dynamic>().ToList();
 076            return JArray.FromObject(records);
 077        }
 78
 79        private JArray ReadExcel(Stream stream)
 80        {
 081            System.Text.Encoding.RegisterProvider(
 082                System.Text.CodePagesEncodingProvider.Instance);
 83
 084            using var reader = ExcelReaderFactory.CreateReader(stream);
 85
 086            var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration
 087            {
 088                ConfigureDataTable = _ => new ExcelDataTableConfiguration
 089                {
 090                    UseHeaderRow = true,
 091                    ReadHeaderRow = rowReader =>
 092                    {
 093                        rowReader.Read(); // ❌ первая строка (пропускаем)
 094                    }
 095                }
 096            });
 97
 098            var table = dataSet.Tables[0];
 99
 0100            var rows = table.AsEnumerable()
 0101                .Select(row =>
 0102                    table.Columns.Cast<DataColumn>()
 0103                        .ToDictionary(
 0104                            col => col.ColumnName,
 0105                            col => row[col]
 0106                        )
 0107                );
 108
 0109            return JArray.FromObject(rows);
 0110        }
 111    }
 112}