Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic report encoding #831

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions Source/FikaAmazonAPI/ReportGeneration/ProductsReport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace FikaAmazonAPI.ReportGeneration
public class ProductsReport
{
public List<ProductsRow> Data { get; set; } = new List<ProductsRow>();
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<ProductsRow> values = new List<ProductsRow>();
foreach (var row in table.Rows)
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions Source/FikaAmazonAPI/Services/ReportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ private async Task<string> GetFileAsync(ReportDocument reportDocument, Cancellat

cancellationToken.ThrowIfCancellationRequested();

FileTransform.SetFileEncoding(tempFilePath);

return tempFilePath;
}
catch (OperationCanceledException)
Expand Down
111 changes: 111 additions & 0 deletions Source/FikaAmazonAPI/Utils/EncodingDetector.cs
Original file line number Diff line number Diff line change
@@ -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
}
}
}
26 changes: 26 additions & 0 deletions Source/FikaAmazonAPI/Utils/EncodingHelper.cs
Original file line number Diff line number Diff line change
@@ -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
};
}
}
}
11 changes: 9 additions & 2 deletions Source/FikaAmazonAPI/Utils/FileTransform.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -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);
Expand All @@ -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));
}

}
}
Loading