Skip to content

Commit

Permalink
Merge pull request #4 from andyld97/background
Browse files Browse the repository at this point in the history
feat: Next update
  • Loading branch information
andyld97 authored Jul 8, 2022
2 parents 50bb122 + 643a06f commit 1c46a5f
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 44 deletions.
12 changes: 11 additions & 1 deletion AutomaticMailPrinter/AutomaticMailPrinter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EBE756A9-E6C7-45D7-9575-769607F15C2F}</ProjectGuid>
<OutputType>Exe</OutputType>
<OutputType>WinExe</OutputType>
<RootNamespace>AutomaticMailPrinter</RootNamespace>
<AssemblyName>AutomaticMailPrinter</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
Expand Down Expand Up @@ -50,6 +50,12 @@
<PropertyGroup>
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Crypto, Version=1.9.0.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>..\packages\Portable.BouncyCastle.1.9.0\lib\net40\BouncyCastle.Crypto.dll</HintPath>
Expand Down Expand Up @@ -94,6 +100,8 @@
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand All @@ -102,6 +110,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Logger.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
Expand All @@ -117,6 +126,7 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="app.manifest" />
<None Include="packages.config" />
<None Include="PrintHtml\ca-bundle.crt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
Expand Down
116 changes: 116 additions & 0 deletions AutomaticMailPrinter/Logger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using System;
using System.Globalization;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;

namespace AutomaticMailPrinter
{
public class Logger
{
public static readonly string LOG_PATH = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "AutomaticMailprinterLog.log");
private readonly static LogType CurrentLogLevel = LogType.Info | LogType.Warning | LogType.Error;
private static readonly HttpClient httpClient = new HttpClient();

public static void LogDebug(string message = "", Exception e = null)
{
Log(message, e, LogType.Debug, false);
}

public static void LogInfo(string message = "", Exception e = null, bool sendWebHook = false)
{
// Info can be sended to webhook optinally, but Warnings and Errors are all sended automatically!
Log(message, e, LogType.Info, sendWebHook);
}

public static void LogWarning(string message = "", Exception e = null)
{
Log(message, e, LogType.Warning, true);
}

public static void LogError(string message = "", Exception e = null)
{
Log(message, e, LogType.Error, true);
}

private static void Log(string message, Exception e, LogType type, bool sendWebHook)
{
// Check if log level matches with current log level - otherwise ignroe
if ((CurrentLogLevel & type) != type)
return;

// Prevent logging empty messages
if (string.IsNullOrEmpty(message) && e == null)
return;

// Generate log message
var now = DateTime.Now;

string logContent = string.Empty;
if (!string.IsNullOrEmpty(message))
logContent = message;

if (e != null)
{
if (string.IsNullOrEmpty(logContent))
logContent = e.ToString();
else
logContent += $" [Exception]: {e}";
}

string logMessage = $"{now.ToString(Properties.Resources.strLogFormat, CultureInfo.InvariantCulture)} [{type}]: {logContent}\n";
System.Diagnostics.Debug.WriteLine(logMessage);

if (sendWebHook)
Task.Run(async () => await NotifyWebHookAsync($"[{type} @ {Environment.MachineName}]: {logContent}"));

// Append message to file
try
{
// If log is too long, clear it
var fi = new System.IO.FileInfo(LOG_PATH);
if (fi.Exists && fi.Length > 500 * 1024 * 1024) // 500 MB
fi.Delete();

if (!System.IO.File.Exists(LOG_PATH))
System.IO.File.WriteAllText(LOG_PATH, logMessage);
else
System.IO.File.AppendAllText(LOG_PATH, logMessage);
}
catch
{
// If this fails ... UF ...
}
}

private static async Task NotifyWebHookAsync(string message)
{
if (string.IsNullOrEmpty(Program.WebHookUrl))
return;

try
{
string url = Program.WebHookUrl;
if (url.EndsWith("/"))
url = url.Substring(0, url.Length - 1);
url += $"{HttpUtility.UrlEncode(message)}";

await httpClient.GetAsync(url);
}
catch (Exception ex)
{
// Calling Logger.LogWarning will not work here (because this may result in an endless result)
Logger.Log($"Failed to notify webhook", ex, LogType.Warning, false);
}
}

[Flags]
public enum LogType
{
Debug = 0x01,
Info = 0x02,
Warning = 0x04,
Error = 0x08
}
}
}
76 changes: 37 additions & 39 deletions AutomaticMailPrinter/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
using System.Reflection;
using System.Text.Json;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace AutomaticMailPrinter
{
internal class Program
{
private static System.Threading.Timer timer;
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;

Expand All @@ -23,7 +27,11 @@ internal class Program

static void Main(string[] args)
{
Console.Title = Properties.Resources.strAppTitle;
if (!AppMutex.WaitOne(TimeSpan.FromSeconds(1), false))
{
MessageBox.Show(Properties.Resources.strInstanceAlreadyRunning, Properties.Resources.strError, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

try
{
Expand All @@ -35,15 +43,22 @@ static void Main(string[] args)
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 { }
int intervalInSecods = configDocument.RootElement.GetProperty("timer_interval_in_seconds").GetInt32();

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();

Console.WriteLine(string.Format(Properties.Resources.strConnectToMailServer, $"\"{ImapServer}:{ImapPort}\""));
Logger.LogInfo(string.Format(Properties.Resources.strConnectToMailServer, $"\"{ImapServer}:{ImapPort}\""));

client = new ImapClient();
client.Connect(ImapServer, ImapPort, true);
Expand All @@ -57,26 +72,27 @@ static void Main(string[] args)
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{Properties.Resources.strFailedToReadConfigFile}: {ex.Message}");
Console.ResetColor();
Logger.LogError(Properties.Resources.strFailedToReadConfigFile, ex);
}

Console.ReadLine();
while (true)
{
System.Threading.Thread.Sleep(500);
}

AppMutex.ReleaseMutex();
}

private static void Timer_Tick(object state)
{
try
{
Console.WriteLine(Properties.Resources.strLookingForUnreadMails);
Logger.LogInfo(Properties.Resources.strLookingForUnreadMails);
bool found = false;

if (!client.IsAuthenticated || !client.IsConnected)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine(Properties.Resources.strMailClientIsNotConnectedAnymore);
Console.ResetColor();
Logger.LogWarning(Properties.Resources.strMailClientIsNotConnectedAnymore);

try
{
Expand All @@ -87,15 +103,11 @@ private static void Timer_Tick(object state)
// The Inbox folder is always available on all IMAP servers...
inbox = client.Inbox;

Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(Properties.Resources.strConnectionEstablishedSuccess);
Console.ResetColor();
Logger.LogInfo(Properties.Resources.strConnectionEstablishedSuccess, sendWebHook: true);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{Properties.Resources.strFailedToConnect}: {ex.Message}!");
Console.ResetColor();
Logger.LogError(Properties.Resources.strFailedToConnect, ex);
return;
}

Expand All @@ -111,17 +123,13 @@ private static void Timer_Tick(object state)
{
// Print text
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{string.Format(Properties.Resources.strFoundUnreadMail, Filter.Where(f => subject.Contains(f)).FirstOrDefault())} {message.Subject}");

Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine(Properties.Resources.strMarkMailAsRead);
Logger.LogInfo($"{string.Format(Properties.Resources.strFoundUnreadMail, Filter.Where(f => subject.Contains(f)).FirstOrDefault())} {message.Subject}");
Logger.LogInfo(Properties.Resources.strMarkMailAsRead);

// Mark mail as read
inbox.SetFlags(uid, MessageFlags.Seen, true);

Console.WriteLine(string.Format(Properties.Resources.strPrintMessage, message.Subject, PrinterName));
Console.ResetColor();

Logger.LogInfo(string.Format(Properties.Resources.strPrintMessage, message.Subject, PrinterName));
PrintHtmlPage(message.HtmlBody);
found = true;

Expand All @@ -130,20 +138,14 @@ private static void Timer_Tick(object state)
}

if (!found)
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine(Properties.Resources.strNoUnreadMailFound);
Console.ResetColor();
}
Logger.LogInfo(Properties.Resources.strNoUnreadMailFound);

// Do not disconnect here!
// client.Disconnect(true);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{Properties.Resources.strFailedToRecieveMails}: {ex.Message}");
Console.ResetColor();
Logger.LogError(Properties.Resources.strFailedToRecieveMails, ex);
}
}

Expand All @@ -157,25 +159,21 @@ public static void PlaySound()
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{Properties.Resources.strFailedToPlaySound}: {ex.Message}");
Console.ResetColor();
Logger.LogError(Properties.Resources.strFailedToPlaySound, ex);
}
}

public static void PrintHtmlPage(string htmlContent)
{
try
{
string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp.html");
string path = System.IO.Path.GetTempFileName();
System.IO.File.WriteAllText(path, htmlContent);
PrintHtmlPages(PrinterName, path);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{Properties.Resources.strFailedToPrintMail}: {ex.Message}");
Console.ResetColor();
Logger.LogError(Properties.Resources.strFailedToPrintMail, ex);
}
}

Expand Down
8 changes: 4 additions & 4 deletions AutomaticMailPrinter/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MailPrinter")]
[assembly: AssemblyTitle("AutomaticMailPrinter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MailPrinter")]
[assembly: AssemblyProduct("AutomaticMailPrinter")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
Expand All @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.1")]
[assembly: AssemblyFileVersion("1.0.1")]
Loading

0 comments on commit 1c46a5f

Please sign in to comment.