Skip to content
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
6 changes: 4 additions & 2 deletions Application/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=1b44e1d426115821"/>
</configSections>
<appSettings>
<add key="CheckInterval" value="1"/>
<add key="NotificationDelay" value="5000"/>
<add key="CheckInterval" value="1"/> <!-- minutes -->
<add key="NotificationDelay" value="5"/> <!-- seconds -->
<add key="PasswordEncryptionEntropy" value="jk0hmx3312xw2ystbsyew3iweo6nfu5tq78nsco8vc3twrb4cba1ru7h9jfmqrlk"/>
<add key="AtomFeedUrl" value="https://mail.google.com/mail/feed/atom"/>
<add key="GoogleMailUrl" value="https://www.google.com/accounts/ServiceLogin?service=mail"/>
</appSettings>
<log4net>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
Expand All @@ -27,6 +28,7 @@
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="FileAppender"/>
</root>
</log4net>
Expand Down
15 changes: 13 additions & 2 deletions Application/Forms/MainForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 97 additions & 15 deletions Application/Forms/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@ public partial class MainForm : Form
// Logger
private static readonly ILog Logger = LogManager.GetLogger(typeof(MainForm));

// Settings defaults
private const int m_notificationDelay_Min = 1; //seconds
private const int m_notificationDelay_Max = 60;
private const int m_notificationDelay_Default = 5;
private const int m_CheckInterval_Min = 1; //minutes
private const int m_CheckInterval_Max = 60;
private const int m_CheckInterval_Default = 1;

// These settings are configurable via the app.config file
private int notificationDelay;
private String gmailUrl;

// The current state of the inbox
private int unreadCount;
Expand All @@ -36,14 +45,15 @@ public MainForm()
InitializeComponent();

// Load the configuration
this.notificationDelay = Convert.ToInt32(ConfigurationManager.AppSettings["NotificationDelay"]);
LoadConfig();

// Initialize the ATOM client
if (ConfigurationManager.AppSettings["AtomFeedUrl"].ToString() == string.Empty)
{
throw new ArgumentNullException("[AtomFeedUrl]", "Invalid config: [AtomFeedUrl] not set !");
}
this.atomMailChecker = new AtomMailChecker(ConfigurationManager.AppSettings["AtomFeedUrl"]);

// Set the timer interval from the config (convert minutes to milliseconds)
timer.Interval = Convert.ToInt32(ConfigurationManager.AppSettings["CheckInterval"]) * 60 * 1000;

// Have we set the username/password already?
if (string.IsNullOrEmpty(UserSettings.Default.Username))
{
Expand All @@ -57,6 +67,39 @@ public MainForm()
}
}

// Loads the configuration
private void LoadConfig()
{
// Set the notification baloon delay
int a_notificationDelay = Convert.ToInt32(ConfigurationManager.AppSettings["NotificationDelay"]);
if (a_notificationDelay > m_notificationDelay_Max || a_notificationDelay < m_notificationDelay_Min)
{
Logger.Warn("Invalid config: [NotificationDelay] = " + a_notificationDelay.ToString() + " ! ...using default");
a_notificationDelay = m_notificationDelay_Default;
}
this.notificationDelay = a_notificationDelay * 1000; // (convert seconds to milliseconds)

// Set the timer interval from the config
int a_CheckInterval = Convert.ToInt32(ConfigurationManager.AppSettings["CheckInterval"]);
if (a_CheckInterval > 60 || a_CheckInterval < 1)
{
Logger.Warn("Invalid config: [CheckInterval] = " + a_CheckInterval.ToString() + " ! ...using default");
a_CheckInterval = m_CheckInterval_Default;
}
timer.Interval = a_CheckInterval * 60 * 1000; // (convert seconds to milliseconds)

//Gmail url
if (ConfigurationManager.AppSettings["GoogleMailUrl"].ToString().Length == 0)
{
Logger.Warn("Invalid config: [GoogleMailUrl] = " + ConfigurationManager.AppSettings["GoogleMailUrl"].ToString() + " ! ...using default");
this.gmailUrl = "https://www.google.com/accounts/ServiceLogin?service=mail";
}
else
{
this.gmailUrl = ConfigurationManager.AppSettings["GoogleMailUrl"].ToString();
}
}

// This makes sure that this window is always hidden
protected override void SetVisibleCore(bool value)
{
Expand All @@ -70,7 +113,7 @@ protected override void SetVisibleCore(bool value)
}

// Downloads the latest Atom feed to check for new mail
private void CheckMail()
private void CheckMail(bool showLast = false)
{
Logger.Debug("Checking mail...");

Expand All @@ -84,6 +127,12 @@ private void CheckMail()
Logger.Warn("Missing credentials");
notifyIcon.Icon = SystrayIcons.SystrayIconError;
notifyIcon.Text = "Please set username/password in Options";
if (showLast)
{
notifyIcon.BalloonTipTitle = "Gmail";
notifyIcon.BalloonTipText = "Please set username/password in Options";
notifyIcon.ShowBalloonTip(notificationDelay);
}
return;
}

Expand All @@ -101,20 +150,32 @@ private void CheckMail()
// Show a notification
if (unreadCount > 0)
{
if (showLast)
lastMail = null;

var newEmails = atomMailChecker.GetNewEmails(lastMail);

if (newEmails.Count() == 1)
if (showLast)
{
notifyIcon.BalloonTipTitle = "New mail from: " + newEmails.Single().From;
notifyIcon.BalloonTipText = newEmails.Single().Subject + Environment.NewLine + newEmails.Single().Preview;
notifyIcon.BalloonTipTitle = "Last mail from: " + newEmails.First().From;
notifyIcon.BalloonTipText = "[Subject:] " + newEmails.First().Subject + Environment.NewLine + "[Preview:] " + newEmails.First().Preview;
notifyIcon.ShowBalloonTip(notificationDelay);
}
if (newEmails.Count() > 1)
else
{
notifyIcon.BalloonTipTitle = "You've got mail";
notifyIcon.BalloonTipText = string.Format("You have {0} new emails", unreadCount);
notifyIcon.ShowBalloonTip(notificationDelay);
}
if (newEmails.Count() == 1)
{
notifyIcon.BalloonTipTitle = "New mail from: " + newEmails.Single().From;
notifyIcon.BalloonTipText = "[Subject:] " + newEmails.Single().Subject + Environment.NewLine + "[Preview:] " + newEmails.Single().Preview;
notifyIcon.ShowBalloonTip(notificationDelay);
}
if (newEmails.Count() > 1)
{
notifyIcon.BalloonTipTitle = "You've got mail";
notifyIcon.BalloonTipText = string.Format("You have {0} new emails", unreadCount);
notifyIcon.ShowBalloonTip(notificationDelay);
}
}
}
else
{
Expand Down Expand Up @@ -158,6 +219,12 @@ private void ShowOptions()
{
if (optionsForm.DialogResult == DialogResult.OK)
CheckMail();
else if (string.IsNullOrEmpty(UserSettings.Default.Username) || string.IsNullOrEmpty(UserSettings.Default.Password))
{
Logger.Warn("Missing credentials");
notifyIcon.Icon = SystrayIcons.SystrayIconError;
notifyIcon.Text = "Please set username/password in Options";
}

optionsForm = null;
};
Expand Down Expand Up @@ -186,13 +253,13 @@ private void ShowAbout()
private void notifyIcon_DoubleClick(object sender, EventArgs e)
{
Logger.Debug("System tray icon: double click");
Process.Start("https://mail.google.com");
Process.Start(gmailUrl);
}

private void viewInboxToolStripMenuItem_Click(object sender, EventArgs e)
{
Logger.Debug("Context menu: view inbox");
Process.Start("https://mail.google.com");
Process.Start(gmailUrl);
}

private void checkMailNowToolStripMenuItem_Click(object sender, EventArgs e)
Expand Down Expand Up @@ -224,6 +291,21 @@ private void exitToolStripMenuItem_Click(object sender, EventArgs e)
Application.Exit();
}

private void lastEmailInfoToolStripMenuItem_Click(object sender, EventArgs e)
{
Logger.Debug("Context menu: show last email");
CheckMail(true);
}

private void notifyIcon_BalloonTipClicked(object sender, EventArgs e)
{
Logger.Debug("Baloon tooltip: clicked");
if (unreadCount > 0)
{
Process.Start(gmailUrl);
}
}

#endregion
}
}
5 changes: 3 additions & 2 deletions Application/Forms/OptionsForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion Application/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ static void Main()
Application.ThreadException += HandleError;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
try
{
Application.Run(new MainForm());
}
catch (Exception ex)
{
Logger.Error("Error while running program!", ex);
MessageBox.Show("Error while running program!\nSee log for details.\nProgram will close.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Logger.Info("Program closed.");
}
Expand Down
4 changes: 2 additions & 2 deletions Application/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.2.0")]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: AssemblyVersion("1.2.1")]
[assembly: AssemblyFileVersion("1.2.1")]

// Initialize log4net
[assembly: log4net.Config.XmlConfigurator(Watch = false)]
16 changes: 16 additions & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ On the first run, you will be asked for credentials (these will be stored [secur
Change Log
===============================

**1.2.1 - Mar 3, 2015**
[by yanoschik]
- (minor) added few comments to code and config
- config modifications:
- NotificationDelay key changed to represent seconds
- added key for Google mail url, which replaces the previously hardcoded one (used for opening mailbox in browser)
- default logging level set to INFO
- reading config moved to a separate method
- important config variables are checked for reasonable values, defaults used if failed
- added option to show last mail -info in baloon tooltip
- clicking on baloon now also opens the browser (like doubleclick on icon or menuitem)
- config dialog has the accept button OK assigned (pressing Enter = clicking OK)
- minor text changes in baloon tooltips
- general handling of exceptions from MainForm -> log & show message before exit
- some minor changes (initial texts for icon and baloontip; notification improved when credentials error occurs; etc.)

**1.2 - Mar 3, 2014**

- Credentials now set via the Options dialog instead of directly in the config file, and stored securely using the Windows Data Protection API.
Expand Down