Winify – Rev
?pathlinks?
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using AutoUpdaterDotNET;
using Serilog;
using Servers;
using ToastNotifications;
using Winify.Gotify;
using Winify.Properties;
using Winify.Servers.Serialization;
using Winify.Utilities;
namespace Winify
{
public partial class Form1 : Form
{
#region Private Delegates, Events, Enums, Properties, Indexers and Fields
private readonly Announcements.Announcements _announcements;
private readonly global::Servers.Servers _servers;
private readonly TaskScheduler _uiTaskScheduler;
private AboutForm _aboutForm;
private GotifyConnectionManager _gotifyConnectionManager;
private SettingsForm _settingsForm;
#endregion
#region Constructors, Destructors and Finalizers
public Form1(Mutex mutex)
{
InitializeComponent();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"),
rollingInterval: RollingInterval.Day)
.CreateLogger();
// Upgrade settings if required.
if (!ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).HasFile)
{
if (Settings.Default.UpdateRequired)
{
Settings.Default.Upgrade();
Settings.Default.Reload();
Settings.Default.UpdateRequired = false;
Settings.Default.Save();
mutex.ReleaseMutex();
Process.Start(Application.ExecutablePath);
Environment.Exit(0);
}
}
// Bind to settings changed event.
Settings.Default.SettingsLoaded += Default_SettingsLoaded;
Settings.Default.SettingsSaving += Default_SettingsSaving;
Settings.Default.PropertyChanged += Default_PropertyChanged;
_servers = new global::Servers.Servers();
_servers.Server.CollectionChanged += Server_CollectionChanged;
_servers.Server.ListChanged += Server_ListChanged;
_announcements = new Announcements.Announcements();
_announcements.Announcement.CollectionChanged += Announcements_CollectionChanged;
_announcements.Announcement.ListChanged += Announcement_ListChanged;
_uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
_gotifyConnectionManager = new GotifyConnectionManager(_servers);
_gotifyConnectionManager.GotifyNotification += GotifyConnectionManager_GotifyNotification;
LoadServers().ContinueWith(async task =>
{
var restoredServers = await task;
foreach (var server in restoredServers.Server)
{
_servers.Server.Add(server);
}
});
LoadAnnouncements().ContinueWith(async task =>
{
var restoreAnnouncements = await task;
foreach (var announcement in restoreAnnouncements.Announcement)
{
_announcements.Announcement.Add(announcement);
}
});
// Start application update.
AutoUpdater.Start("http://winify.grimore.org/update/winify.xml");
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && components != null)
{
_servers.Server.CollectionChanged -= Server_CollectionChanged;
_announcements.Announcement.CollectionChanged -= Announcements_CollectionChanged;
Settings.Default.SettingsLoaded -= Default_SettingsLoaded;
Settings.Default.SettingsSaving -= Default_SettingsSaving;
Settings.Default.PropertyChanged -= Default_PropertyChanged;
_gotifyConnectionManager.GotifyNotification -= GotifyConnectionManager_GotifyNotification;
_gotifyConnectionManager?.Dispose();
_gotifyConnectionManager = null;
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
#region Event Handlers
private async void Announcement_ListChanged(object sender, ListChangedEventArgs e)
{
await SaveAnnouncements();
}
private async void Server_ListChanged(object sender, ListChangedEventArgs e)
{
await SaveServers();
}
private async void Announcements_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
await SaveAnnouncements();
}
private void GotifyConnectionManager_GotifyNotification(object sender, GotifyNotificationEventArgs e)
{
Task.Factory.StartNew(() =>
{
foreach (var announcement in _announcements.Announcement)
{
if (announcement.AppId == e.Notification.AppId)
{
var configuredNotification = new Notification($"{e.Notification.Title} ({e.Notification.Server.Name}/{e.Notification.AppId})",
e.Notification.Message, announcement.LingerTime, e.Image, FormAnimator.AnimationMethod.Slide,
FormAnimator.AnimationDirection.Up);
configuredNotification.Show();
return;
}
}
var notification = new Notification($"{e.Notification.Title} ({e.Notification.Server.Name}/{e.Notification.AppId})",
e.Notification.Message, 5000, e.Image, FormAnimator.AnimationMethod.Slide,
FormAnimator.AnimationDirection.Up);
notification.Show();
}, CancellationToken.None, TaskCreationOptions.None, _uiTaskScheduler);
}
private async void Server_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
await SaveServers();
}
private static void Default_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Settings.Default.Save();
}
private static void Default_SettingsSaving(object sender, CancelEventArgs e)
{
}
private static void Default_SettingsLoaded(object sender, SettingsLoadedEventArgs e)
{
}
private void SettingsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_settingsForm != null)
{
return;
}
_settingsForm = new SettingsForm(_servers, _announcements);
_settingsForm.Closing += SettingsForm_Closing;
_settingsForm.Show();
}
private void SettingsForm_Closing(object sender, CancelEventArgs e)
{
if (_settingsForm == null)
{
return;
}
_settingsForm.Closing -= SettingsForm_Closing;
_settingsForm.Dispose();
_settingsForm = null;
}
private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_aboutForm != null)
{
return;
}
_aboutForm = new AboutForm();
_aboutForm.Closing += AboutForm_Closing;
_aboutForm.Show();
}
private void AboutForm_Closing(object sender, CancelEventArgs e)
{
if (_aboutForm == null)
{
return;
}
_aboutForm.Closing -= AboutForm_Closing;
_aboutForm.Dispose();
_aboutForm = null;
}
private void QuitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
Environment.Exit(0);
}
private void UpdateToolStripMenuItem_Click(object sender, EventArgs e)
{
AutoUpdater.Start("http://winify.grimore.org/update/winify.xml");
}
#endregion
#region Private Methods
private async Task SaveAnnouncements()
{
switch (await ServersSerialization.Serialize(_announcements, Constants.NotificationsFile, "Announcements",
"<!ATTLIST Announcements xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>"))
{
case SerializationFailure serializationFailure:
Log.Warning(serializationFailure.Exception, "Unable to serialize announcements.");
break;
}
}
private async Task SaveServers()
{
// Encrypt password for all servers.
var deviceId = Miscellaneous.GetMachineGuid();
var @protected = new global::Servers.Servers
{
Server = new BindingListWithCollectionChanged<Server>()
};
foreach (var server in _servers.Server)
{
var encrypted = AES.Encrypt(Encoding.UTF8.GetBytes(server.Password), deviceId);
var armored = Convert.ToBase64String(encrypted);
@protected.Server.Add(new Server(server.Name, server.Url, server.Username, armored));
}
switch (await ServersSerialization.Serialize(@protected, Constants.ServersFile, "Servers",
"<!ATTLIST Servers xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>"))
{
case SerializationFailure serializationFailure:
Log.Warning(serializationFailure.Exception, "Unable to serialize servers.");
break;
}
}
private static async Task<Announcements.Announcements> LoadAnnouncements()
{
if (!Directory.Exists(Constants.UserApplicationDirectory))
{
Directory.CreateDirectory(Constants.UserApplicationDirectory);
}
var deserializationResult =
await ServersSerialization.Deserialize<Announcements.Announcements>(Constants.NotificationsFile,
"urn:winify-announcements-schema", "Announcements.xsd");
switch (deserializationResult)
{
case SerializationSuccess<Announcements.Announcements> serializationSuccess:
return serializationSuccess.Result;
case SerializationFailure serializationFailure:
Log.Warning(serializationFailure.Exception, "Unable to load announcements.");
return new Announcements.Announcements();
default:
return new Announcements.Announcements();
}
}
private static async Task<global::Servers.Servers> LoadServers()
{
if (!Directory.Exists(Constants.UserApplicationDirectory))
{
Directory.CreateDirectory(Constants.UserApplicationDirectory);
}
var deserializationResult =
await ServersSerialization.Deserialize<global::Servers.Servers>(Constants.ServersFile,
"urn:winify-servers-schema", "Servers.xsd");
switch (deserializationResult)
{
case SerializationSuccess<global::Servers.Servers> serializationSuccess:
// Decrypt password.
var deviceId = Miscellaneous.GetMachineGuid();
var @protected = new global::Servers.Servers
{
Server = new BindingListWithCollectionChanged<Server>()
};
foreach (var server in serializationSuccess.Result.Server)
{
var unarmored = Convert.FromBase64String(server.Password);
var decrypted = Encoding.UTF8.GetString(AES.Decrypt(unarmored, deviceId));
@protected.Server.Add(new Server(server.Name, server.Url, server.Username, decrypted));
}
return @protected;
case SerializationFailure serializationFailure:
Log.Warning(serializationFailure.Exception, "Unable to load servers.");
return new global::Servers.Servers();
default:
return new global::Servers.Servers();
}
}
#endregion
}
}
Generated by GNU Enscript 1.6.5.90.