diff --git a/README.md b/README.md index 5b1c064d..4fc9a20c 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,14 @@ Please see [here](https://github.com/abuzuhri/Amazon-SP-API-CSharp/blob/main/Sou >> >> ***This is not required and will operate normally without the ProxyAddress being set.*** + +### Configuration using Docker - Linux +You need to add windows-1252 encoding +```csharp + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); +``` + + ### Order List, For more orders sample please check [Here](https://github.com/abuzuhri/Amazon-SP-API-CSharp/blob/main/Source/FikaAmazonAPI.SampleCode/ReportsSample.cs). ```CSharp ParameterOrderList serachOrderList = new ParameterOrderList(); diff --git a/Source/FikaAmazonAPI/ReportGeneration/ProductsReport.cs b/Source/FikaAmazonAPI/ReportGeneration/ProductsReport.cs index 251d368e..f9c44b1f 100644 --- a/Source/FikaAmazonAPI/ReportGeneration/ProductsReport.cs +++ b/Source/FikaAmazonAPI/ReportGeneration/ProductsReport.cs @@ -7,12 +7,12 @@ namespace FikaAmazonAPI.ReportGeneration public class ProductsReport { public List Data { get; set; } = new List(); - public ProductsReport(string path, Encoding encoding = default) + public ProductsReport(string path) { if (string.IsNullOrEmpty(path)) return; - var table = Table.ConvertFromCSV(path, encoding: encoding); + var table = Table.ConvertFromCSV(path); List values = new List(); foreach (var row in table.Rows) diff --git a/Source/FikaAmazonAPI/ReportGeneration/ReportDataTable/Table.cs b/Source/FikaAmazonAPI/ReportGeneration/ReportDataTable/Table.cs index af638d1f..eed8a797 100644 --- a/Source/FikaAmazonAPI/ReportGeneration/ReportDataTable/Table.cs +++ b/Source/FikaAmazonAPI/ReportGeneration/ReportDataTable/Table.cs @@ -1,9 +1,11 @@ -using System; +using FikaAmazonAPI.Utils; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; namespace FikaAmazonAPI.ReportGeneration.ReportDataTable { @@ -48,13 +50,12 @@ public Table(params string[] header) this.header = header; } - public static Table ConvertFromCSV(string path, char separator = '\t', Encoding encoding = default) + public static Table ConvertFromCSV(string path, char separator = '\t') { - var lines = File.ReadAllLines(path, encoding ?? Encoding.UTF8); + var lines = File.ReadAllLines(path, EncodingHelper.GetEncodingFromCulture(Thread.CurrentThread.CurrentCulture)); var table = new Table(lines.First().Split(separator)); - lines.Skip(1).ToList().ForEach(a => ConvertFromCSVAddRow(table, a, separator)); return table; } diff --git a/Source/FikaAmazonAPI/Services/ReportService.cs b/Source/FikaAmazonAPI/Services/ReportService.cs index ac528900..55f84f0b 100644 --- a/Source/FikaAmazonAPI/Services/ReportService.cs +++ b/Source/FikaAmazonAPI/Services/ReportService.cs @@ -247,6 +247,8 @@ private async Task GetFileAsync(ReportDocument reportDocument, Cancellat cancellationToken.ThrowIfCancellationRequested(); + FileTransform.SetFileEncoding(tempFilePath); + return tempFilePath; } catch (OperationCanceledException) diff --git a/Source/FikaAmazonAPI/Utils/EncodingDetector.cs b/Source/FikaAmazonAPI/Utils/EncodingDetector.cs new file mode 100644 index 00000000..f546e46f --- /dev/null +++ b/Source/FikaAmazonAPI/Utils/EncodingDetector.cs @@ -0,0 +1,111 @@ +using System; +using System.IO; +using System.Linq; +using System.Text; + +namespace FikaAmazonAPI.Utils +{ + public class EncodingDetector + { + private static readonly Encoding[] CommonEncodings = { + Encoding.UTF8, Encoding.Unicode, Encoding.BigEndianUnicode, + Encoding.UTF32, Encoding.ASCII, Encoding.GetEncoding("ISO-8859-1") + }; + + public static Encoding DetectEncoding(string filePath, int sampleSize = 4096) + { + byte[] buffer = File.ReadAllBytes(filePath); + return DetectEncoding(buffer, sampleSize); + } + + public static Encoding DetectEncoding(byte[] buffer, int sampleSize = 4096) + { + if (buffer == null || buffer.Length == 0) + throw new ArgumentException("Buffer is empty"); + + // Schritt 1: Prüfe auf BOM + Encoding bomEncoding = CheckBOM(buffer); + if (bomEncoding != null) + return bomEncoding; + + // Schritt 2: Prüfe auf UTF-8 + if (IsUTF8(buffer)) + return Encoding.UTF8; + + // Schritt 3: Prüfe auf bekannte Encodings durch Heuristik + return HeuristicDetection(buffer); + } + + private static Encoding CheckBOM(byte[] buffer) + { + if (buffer.Length >= 3 && buffer[0] == 0xEF && buffer[1] == 0xBB && buffer[2] == 0xBF) + return Encoding.UTF8; // UTF-8 mit BOM + + if (buffer.Length >= 2 && buffer[0] == 0xFF && buffer[1] == 0xFE) + return Encoding.Unicode; // UTF-16 LE + + if (buffer.Length >= 2 && buffer[0] == 0xFE && buffer[1] == 0xFF) + return Encoding.BigEndianUnicode; // UTF-16 BE + + if (buffer.Length >= 4 && buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0xFE && buffer[3] == 0xFF) + return Encoding.UTF32; // UTF-32 BE + + if (buffer.Length >= 4 && buffer[0] == 0xFF && buffer[1] == 0xFE && buffer[2] == 0x00 && buffer[3] == 0x00) + return Encoding.UTF32; // UTF-32 LE + + return null; + } + + private static bool IsUTF8(byte[] buffer) + { + int i = 0; + while (i < buffer.Length) + { + if (buffer[i] <= 0x7F) + { + i++; + continue; + } + + if (buffer[i] >= 0xC2 && buffer[i] <= 0xDF) + { + if (i + 1 < buffer.Length && (buffer[i + 1] & 0xC0) == 0x80) + { + i += 2; + continue; + } + } + else if (buffer[i] >= 0xE0 && buffer[i] <= 0xEF) + { + if (i + 2 < buffer.Length && (buffer[i + 1] & 0xC0) == 0x80 && (buffer[i + 2] & 0xC0) == 0x80) + { + i += 3; + continue; + } + } + else if (buffer[i] >= 0xF0 && buffer[i] <= 0xF4) + { + if (i + 3 < buffer.Length && (buffer[i + 1] & 0xC0) == 0x80 && (buffer[i + 2] & 0xC0) == 0x80 && (buffer[i + 3] & 0xC0) == 0x80) + { + i += 4; + continue; + } + } + + return false; + } + return true; + } + + private static Encoding HeuristicDetection(byte[] buffer) + { + int asciiCount = buffer.Count(b => b <= 127); + int extendedCount = buffer.Length - asciiCount; + + if (extendedCount == 0) + return Encoding.ASCII; // ASCII-Dateien enthalten keine Sonderzeichen + + return Encoding.GetEncoding("ISO-8859-1"); // Latin-1 als Fallback für ANSI + } + } +} diff --git a/Source/FikaAmazonAPI/Utils/EncodingHelper.cs b/Source/FikaAmazonAPI/Utils/EncodingHelper.cs new file mode 100644 index 00000000..1b214607 --- /dev/null +++ b/Source/FikaAmazonAPI/Utils/EncodingHelper.cs @@ -0,0 +1,26 @@ +using System.Globalization; +using System.Text; + +namespace FikaAmazonAPI.Utils +{ + public static class EncodingHelper + { + public static Encoding GetEncodingFromCulture(CultureInfo culture) + { + string cultureName = culture.Name.ToLower(); + + return cultureName switch + { + "en-us" => Encoding.GetEncoding("Windows-1252"), // Westeuropa (ANSI) + "de-de" => Encoding.GetEncoding("Windows-1252"), // Westeuropa (ANSI) + "fr-fr" => Encoding.GetEncoding("Windows-1252"), // Westeuropa (ANSI) + "ja-jp" => Encoding.GetEncoding("shift_jis"), // Japanisch + "zh-cn" => Encoding.GetEncoding("gb2312"), // Vereinfachtes Chinesisch + "ru-ru" => Encoding.GetEncoding("Windows-1251"), // Kyrillisch + "ko-kr" => Encoding.GetEncoding("ks_c_5601-1987"), // Koreanisch + "ar-sa" => Encoding.GetEncoding("Windows-1256"), // Arabisch + _ => Encoding.UTF8 // Standard als Fallback + }; + } + } +} diff --git a/Source/FikaAmazonAPI/Utils/FileTransform.cs b/Source/FikaAmazonAPI/Utils/FileTransform.cs index 3b0ea3e2..8d1a2b48 100644 --- a/Source/FikaAmazonAPI/Utils/FileTransform.cs +++ b/Source/FikaAmazonAPI/Utils/FileTransform.cs @@ -1,7 +1,10 @@ using System; +using System.Globalization; using System.IO; using System.IO.Compression; using System.Security.Cryptography; +using System.Text; +using System.Threading; namespace FikaAmazonAPI.Utils { @@ -31,8 +34,6 @@ public static string DecryptString(byte[] key, byte[] iv, byte[] cipherText) } - - public static string Decompress(string fileName) { FileInfo fileInfo = new FileInfo(fileName); @@ -54,6 +55,12 @@ public static string Decompress(string fileName) } } + public static void SetFileEncoding(string filePath) + { + var detectedEncoding = EncodingDetector.DetectEncoding(filePath); + string content = File.ReadAllText(filePath, detectedEncoding); + File.WriteAllText(filePath, content, EncodingHelper.GetEncodingFromCulture(Thread.CurrentThread.CurrentCulture)); + } } }