diff --git a/AutomaticMailPrinter/App.config b/AutomaticMailPrinter/App.config
index 05e2f90..5de3a19 100644
--- a/AutomaticMailPrinter/App.config
+++ b/AutomaticMailPrinter/App.config
@@ -11,12 +11,28 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AutomaticMailPrinter/AutomaticMailPrinter.csproj b/AutomaticMailPrinter/AutomaticMailPrinter.csproj
index e76e147..f6b2034 100644
--- a/AutomaticMailPrinter/AutomaticMailPrinter.csproj
+++ b/AutomaticMailPrinter/AutomaticMailPrinter.csproj
@@ -1,17 +1,7 @@
-
-
-
+
- Debug
- AnyCPU
- {EBE756A9-E6C7-45D7-9575-769607F15C2F}
+ net48
WinExe
- AutomaticMailPrinter
- AutomaticMailPrinter
- v4.8
- 512
- true
- true
false
publish\
true
@@ -27,25 +17,9 @@
1.0.0.%2a
false
true
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
+ true
+ true
+ false
icon.ico
@@ -57,78 +31,13 @@
app.manifest
-
- ..\packages\Portable.BouncyCastle.1.9.0\lib\net40\BouncyCastle.Crypto.dll
-
-
- ..\packages\MailKit.3.4.1\lib\net48\MailKit.dll
-
-
- ..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0-rc.2.22472.3\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll
-
-
- ..\packages\MimeKit.3.4.1\lib\net48\MimeKit.dll
-
-
-
- ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
-
-
-
- ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll
-
-
-
- ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
-
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.7.0.0-preview.2.22152.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll
-
-
- ..\packages\System.Text.Encoding.CodePages.7.0.0-rc.2.22472.3\lib\net462\System.Text.Encoding.CodePages.dll
-
-
- ..\packages\System.Text.Encodings.Web.7.0.0-rc.2.22472.3\lib\net462\System.Text.Encodings.Web.dll
-
-
- ..\packages\System.Text.Json.7.0.0-rc.2.22472.3\lib\net462\System.Text.Json.dll
-
-
- ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
-
-
- ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
- True
- True
- Resources.de.resx
-
-
-
-
-
+
Always
@@ -165,10 +74,10 @@
Always
-
+
Always
-
+
Always
@@ -185,14 +94,21 @@
-
- PublicResXFileCodeGenerator
- Resources.de.Designer.cs
-
-
- PublicResXFileCodeGenerator
- Resources.Designer.cs
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/AutomaticMailPrinter/Program.cs b/AutomaticMailPrinter/Program.cs
index 4f4460e..00cb7b5 100644
--- a/AutomaticMailPrinter/Program.cs
+++ b/AutomaticMailPrinter/Program.cs
@@ -9,6 +9,7 @@
using System.Linq;
using System.Threading;
using System.Windows.Forms;
+using MimeKit;
namespace AutomaticMailPrinter
{
@@ -18,9 +19,11 @@ internal class Program
private static readonly Mutex AppMutex = new Mutex(false, "c75adf4e-765c-4529-bf7a-90dd76cd386a");
private static string ImapServer, MailAddress, Password, PrinterName;
+
public static string WebHookUrl { get; private set; }
private static string[] Filter = new string[0];
private static int ImapPort;
+ private static bool PrintPdfAttachments = false;
private static ImapClient client = new ImapClient();
private static IMailFolder inbox;
@@ -39,29 +42,46 @@ static void Main(string[] args)
int intervalInSecods = 60;
try
{
- string configPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json");
- var configDocument = System.Text.Json.JsonSerializer.Deserialize(System.IO.File.ReadAllText(configPath));
-
- ImapServer = configDocument.RootElement.GetProperty("imap_server").GetString();
- ImapPort = configDocument.RootElement.GetProperty("imap_port").GetInt32();
- MailAddress = configDocument.RootElement.GetProperty("mail").GetString();
- Password = configDocument.RootElement.GetProperty("password").GetString();
- PrinterName = configDocument.RootElement.GetProperty("printer_name").GetString();
+ // Prefer YAML if present; else fallback to JSON
+ string baseDir = AppDomain.CurrentDomain.BaseDirectory;
+ string yamlPath = System.IO.Path.Combine(baseDir, "config.yml");
+ string jsonPath = System.IO.Path.Combine(baseDir, "config.json");
- try
+ if (System.IO.File.Exists(yamlPath))
{
- // Can be empty or even may not existing ...
- WebHookUrl = configDocument.RootElement.GetProperty("webhook_url").GetString();
+ LoadConfigFromYaml(yamlPath, ref intervalInSecods);
}
- catch { }
+ else
+ {
+ var configDocument = System.Text.Json.JsonSerializer.Deserialize(System.IO.File.ReadAllText(jsonPath));
+
+ ImapServer = configDocument.RootElement.GetProperty("imap_server").GetString();
+ ImapPort = configDocument.RootElement.GetProperty("imap_port").GetInt32();
+ MailAddress = configDocument.RootElement.GetProperty("mail").GetString();
+ Password = configDocument.RootElement.GetProperty("password").GetString();
+ PrinterName = configDocument.RootElement.GetProperty("printer_name").GetString();
+
+ try
+ {
+ // Can be empty or even may not existing ...
+ WebHookUrl = configDocument.RootElement.GetProperty("webhook_url").GetString();
+ }
+ catch { }
+
+ intervalInSecods = configDocument.RootElement.GetProperty("timer_interval_in_seconds").GetInt32();
- intervalInSecods = configDocument.RootElement.GetProperty("timer_interval_in_seconds").GetInt32();
+ try
+ {
+ PrintPdfAttachments = configDocument.RootElement.GetProperty("print_pdf_attachments").GetBoolean();
+ }
+ catch { }
- var filterProperty = configDocument.RootElement.GetProperty("filter");
- int counter = 0;
- Filter = new string[filterProperty.GetArrayLength()];
- foreach (var word in filterProperty.EnumerateArray())
- Filter[counter++] = word.GetString().ToLower();
+ var filterProperty = configDocument.RootElement.GetProperty("filter");
+ int counter = 0;
+ Filter = new string[filterProperty.GetArrayLength()];
+ foreach (var word in filterProperty.EnumerateArray())
+ Filter[counter++] = word.GetString().ToLower();
+ }
}
catch (Exception ex)
{
@@ -170,11 +190,28 @@ private static void Timer_Tick(object state)
{
// Print text
Console.ForegroundColor = ConsoleColor.Green;
- Logger.LogInfo($"{string.Format(Properties.Resources.strFoundUnreadMail, Filter.Where(f => subject.Contains(f)).FirstOrDefault())} {message.Subject}");
+ Logger.LogInfo($"{string.Format(Properties.Resources.strFoundUnreadMail, Filter.FirstOrDefault(f => subject.Contains(f)))} {message.Subject}");
// Print mail
Logger.LogInfo(string.Format(Properties.Resources.strPrintMessage, message.Subject, PrinterName));
- PrintHtmlPage(message.HtmlBody);
+
+ if (PrintPdfAttachments)
+ {
+ var pdfs = SavePdfAttachmentsToTempFiles(message);
+ if (pdfs != null && pdfs.Any())
+ {
+ PrintPdfFiles(PrinterName, pdfs.ToArray());
+ }
+ else
+ {
+ // Fallback to HTML if no PDFs found
+ PrintHtmlPage(message.HtmlBody);
+ }
+ }
+ else
+ {
+ PrintHtmlPage(message.HtmlBody);
+ }
// Delete mail https://stackoverflow.com/a/24204804/6237448
Logger.LogInfo(Properties.Resources.strMarkMailAsDeleted);
@@ -234,14 +271,16 @@ public static void PrintHtmlPage(string htmlContent)
public static bool? PrintHtmlPages(string printer, params string[] urls)
{
// Spawn the code to print the packing slips
- var info = new ProcessStartInfo();
- info.Arguments = $"-p \"{printer}\" -a A4 \"{string.Join("\" \"", urls)}\"";
+ var info = new ProcessStartInfo
+ {
+ Arguments = $"-p \"{printer}\" -a A4 \"{string.Join("\" \"", urls)}\""
+ };
var pathToExe = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
info.FileName = Path.Combine(pathToExe, "PrintHtml", "PrintHtml.exe");
Process.Start(info);
-
return null;
+
/*using (var p = Process.Start(info))
{
// Wait until it is finished
@@ -252,5 +291,178 @@ public static void PrintHtmlPage(string htmlContent)
return p.ExitCode == 0;
}*/
}
+
+ private static void LoadConfigFromYaml(string yamlPath, ref int intervalInSecods)
+ {
+ try
+ {
+ var lines = System.IO.File.ReadAllLines(yamlPath);
+ var values = ParseSimpleYaml(lines);
+
+ ImapServer = GetDictString(values, "imap_server");
+ ImapPort = GetDictInt(values, "imap_port", 993);
+ MailAddress = GetDictString(values, "mail");
+ Password = GetDictString(values, "password");
+ PrinterName = GetDictString(values, "printer_name");
+ WebHookUrl = GetDictString(values, "webhook_url");
+ intervalInSecods = GetDictInt(values, "timer_interval_in_seconds", intervalInSecods);
+ PrintPdfAttachments = GetDictBool(values, "print_pdf_attachments", false);
+
+ if (values.TryGetValue("filter", out var filterObj) && filterObj is System.Collections.Generic.List list)
+ {
+ Filter = list.Select(s => (s ?? string.Empty).ToLower()).ToArray();
+ }
+ else if (values.TryGetValue("filter", out var filterStr) && filterStr is string s && !string.IsNullOrWhiteSpace(s))
+ {
+ Filter = s.Split(',').Select(x => x.Trim().ToLower()).Where(x => !string.IsNullOrEmpty(x)).ToArray();
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError("Failed to read YAML config.", ex);
+ throw;
+ }
+ }
+
+ private static System.Collections.Generic.Dictionary ParseSimpleYaml(string[] lines)
+ {
+ var dict = new System.Collections.Generic.Dictionary(StringComparer.OrdinalIgnoreCase);
+ string currentListKey = null;
+ System.Collections.Generic.List currentList = null;
+
+ foreach (var rawLine in lines)
+ {
+ var line = rawLine;
+ if (line == null) continue;
+ line = line.Trim();
+ if (line.Length == 0) continue;
+ if (line.StartsWith("#")) continue;
+
+ // list item
+ if (line.StartsWith("- "))
+ {
+ if (currentListKey != null)
+ {
+ currentList = currentList ?? new System.Collections.Generic.List();
+ var item = line.Substring(2).Trim();
+ currentList.Add(Unquote(item));
+ dict[currentListKey] = currentList;
+ }
+ continue;
+ }
+
+ var idx = line.IndexOf(':');
+ if (idx <= 0)
+ continue;
+
+ var key = line.Substring(0, idx).Trim();
+ var value = line.Substring(idx + 1).Trim();
+
+ if (string.IsNullOrEmpty(value))
+ {
+ // start list or nested section; we only support simple lists here
+ currentListKey = key;
+ currentList = new System.Collections.Generic.List();
+ dict[currentListKey] = currentList;
+ }
+ else
+ {
+ currentListKey = null;
+ dict[key] = Unquote(value);
+ }
+ }
+
+ return dict;
+ }
+
+ private static string Unquote(string v)
+ {
+ if (string.IsNullOrEmpty(v)) return v;
+ if ((v.StartsWith("\"") && v.EndsWith("\"")) || (v.StartsWith("'") && v.EndsWith("'")))
+ return v.Substring(1, v.Length - 2);
+ return v;
+ }
+
+ private static string GetDictString(System.Collections.Generic.Dictionary dict, string key)
+ {
+ if (dict.TryGetValue(key, out var v) && v != null)
+ return Convert.ToString(v);
+ return null;
+ }
+
+ private static int GetDictInt(System.Collections.Generic.Dictionary dict, string key, int defaultValue)
+ {
+ if (dict.TryGetValue(key, out var v) && v != null)
+ {
+ if (v is int i) return i;
+ if (int.TryParse(Convert.ToString(v), out var parsed)) return parsed;
+ }
+ return defaultValue;
+ }
+
+ private static bool GetDictBool(System.Collections.Generic.Dictionary dict, string key, bool defaultValue)
+ {
+ if (dict.TryGetValue(key, out var v) && v != null)
+ {
+ var s = Convert.ToString(v)?.Trim().ToLowerInvariant();
+ if (s == "true" || s == "yes" || s == "1") return true;
+ if (s == "false" || s == "no" || s == "0") return false;
+ }
+ return defaultValue;
+ }
+
+ private static System.Collections.Generic.List SavePdfAttachmentsToTempFiles(MimeMessage message)
+ {
+ var result = new System.Collections.Generic.List();
+ if (message == null) return result;
+
+ foreach (var attachment in message.Attachments)
+ {
+ if (attachment is MimePart part)
+ {
+ var mimeType = part.ContentType?.MimeType ?? string.Empty;
+ var fileName = part.FileName ?? string.Empty;
+ bool isPdf = mimeType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase)
+ || fileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase);
+ if (isPdf)
+ {
+ var tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".pdf");
+ using (var stream = System.IO.File.Create(tempPath))
+ {
+ part.Content.DecodeTo(stream);
+ }
+ result.Add(tempPath);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private static void PrintPdfFiles(string printer, params string[] pdfPaths)
+ {
+ if (pdfPaths == null || pdfPaths.Length == 0) return;
+
+ foreach (var pdf in pdfPaths)
+ {
+ try
+ {
+ var psi = new ProcessStartInfo
+ {
+ FileName = pdf,
+ Verb = "printto",
+ UseShellExecute = true,
+ CreateNoWindow = true,
+ WindowStyle = ProcessWindowStyle.Hidden,
+ Arguments = $"\"{printer}\""
+ };
+ Process.Start(psi);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"Failed to print PDF '{pdf}'", ex);
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/AutomaticMailPrinter/config.yml b/AutomaticMailPrinter/config.yml
new file mode 100644
index 0000000..a159392
--- /dev/null
+++ b/AutomaticMailPrinter/config.yml
@@ -0,0 +1,15 @@
+imap_server: imap.gmail.com
+imap_port: 993
+mail: youremail@example.com
+password: yourpassword
+printer_name: Brother HL-L5200DW series Printer
+timer_interval_in_seconds: 60
+filter:
+ - Order
+ - Your Message
+# Optional: URL für Webhooks
+# webhook_url: "https://example.com/webhook"
+# PDFs statt HTML drucken (Anhänge mit .pdf oder application/pdf)
+# Wenn du keine PDFs drucken willst, setze dies auf false
+print_pdf_attachments: true
+
diff --git a/AutomaticMailPrinter/packages.config b/AutomaticMailPrinter/packages.config
deleted file mode 100644
index 4c23c67..0000000
--- a/AutomaticMailPrinter/packages.config
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file