Winify – Blame information for rev 24

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
7 office 2 using System.Collections.Specialized;
1 office 3 using System.ComponentModel;
4 using System.Configuration;
19 office 5 using System.Diagnostics;
4 office 6 using System.IO;
24 office 7 using System.Linq;
15 office 8 using System.Text;
19 office 9 using System.Threading;
4 office 10 using System.Threading.Tasks;
1 office 11 using System.Windows.Forms;
12 using AutoUpdaterDotNET;
18 office 13 using Serilog;
15 office 14 using Servers;
24 office 15 using ToastNotifications;
1 office 16 using Winify.Gotify;
17 using Winify.Properties;
8 office 18 using Winify.Servers.Serialization;
15 office 19 using Winify.Utilities;
1 office 20  
21 namespace Winify
22 {
23 public partial class Form1 : Form
24 {
25 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
26  
21 office 27 private readonly Announcements.Announcements _announcements;
15 office 28  
8 office 29 private readonly global::Servers.Servers _servers;
4 office 30  
24 office 31 private readonly TaskScheduler _uiTaskScheduler;
14 office 32  
1 office 33 private AboutForm _aboutForm;
34  
7 office 35 private GotifyConnectionManager _gotifyConnectionManager;
1 office 36  
37 private SettingsForm _settingsForm;
38  
39 #endregion
40  
41 #region Constructors, Destructors and Finalizers
42  
19 office 43 public Form1(Mutex mutex)
1 office 44 {
45 InitializeComponent();
46  
18 office 47 Log.Logger = new LoggerConfiguration()
48 .MinimumLevel.Debug()
49 .WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"),
50 rollingInterval: RollingInterval.Day)
51 .CreateLogger();
52  
1 office 53 // Upgrade settings if required.
54 if (!ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).HasFile)
55 {
19 office 56 if (Settings.Default.UpdateRequired)
57 {
58 Settings.Default.Upgrade();
59 Settings.Default.Reload();
60  
61 Settings.Default.UpdateRequired = false;
62 Settings.Default.Save();
63  
64 mutex.ReleaseMutex();
65 Process.Start(Application.ExecutablePath);
66 Environment.Exit(0);
67 }
1 office 68 }
69  
70 // Bind to settings changed event.
71 Settings.Default.SettingsLoaded += Default_SettingsLoaded;
72 Settings.Default.SettingsSaving += Default_SettingsSaving;
73 Settings.Default.PropertyChanged += Default_PropertyChanged;
74  
8 office 75 _servers = new global::Servers.Servers();
7 office 76 _servers.Server.CollectionChanged += Server_CollectionChanged;
21 office 77 _servers.Server.ListChanged += Server_ListChanged;
24 office 78 _announcements = new Announcements.Announcements();
21 office 79 _announcements.Announcement.CollectionChanged += Announcements_CollectionChanged;
80 _announcements.Announcement.ListChanged += Announcement_ListChanged;
1 office 81  
24 office 82 _uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
11 office 83  
7 office 84 _gotifyConnectionManager = new GotifyConnectionManager(_servers);
11 office 85 _gotifyConnectionManager.GotifyNotification += GotifyConnectionManager_GotifyNotification;
7 office 86  
14 office 87 LoadServers().ContinueWith(async task =>
4 office 88 {
14 office 89 var restoredServers = await task;
4 office 90  
7 office 91 foreach (var server in restoredServers.Server)
92 {
93 _servers.Server.Add(server);
94 }
4 office 95 });
15 office 96  
97 LoadAnnouncements().ContinueWith(async task =>
98 {
99 var restoreAnnouncements = await task;
100  
101 foreach (var announcement in restoreAnnouncements.Announcement)
102 {
21 office 103 _announcements.Announcement.Add(announcement);
15 office 104 }
105 });
19 office 106  
107 // Start application update.
108 AutoUpdater.Start("http://winify.grimore.org/update/winify.xml");
1 office 109 }
110  
111 /// <summary>
112 /// Clean up any resources being used.
113 /// </summary>
114 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
115 protected override void Dispose(bool disposing)
116 {
117 if (disposing && components != null)
118 {
7 office 119 _servers.Server.CollectionChanged -= Server_CollectionChanged;
21 office 120 _announcements.Announcement.CollectionChanged -= Announcements_CollectionChanged;
7 office 121  
122 Settings.Default.SettingsLoaded -= Default_SettingsLoaded;
123 Settings.Default.SettingsSaving -= Default_SettingsSaving;
124 Settings.Default.PropertyChanged -= Default_PropertyChanged;
125  
11 office 126 _gotifyConnectionManager.GotifyNotification -= GotifyConnectionManager_GotifyNotification;
7 office 127 _gotifyConnectionManager?.Dispose();
128 _gotifyConnectionManager = null;
129  
1 office 130 components.Dispose();
131 }
132  
133 base.Dispose(disposing);
134 }
135  
136 #endregion
137  
138 #region Event Handlers
139  
21 office 140 private async void Announcement_ListChanged(object sender, ListChangedEventArgs e)
141 {
142 await SaveAnnouncements();
143 }
144  
145 private async void Server_ListChanged(object sender, ListChangedEventArgs e)
146 {
147 await SaveServers();
148 }
149  
15 office 150 private async void Announcements_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
151 {
21 office 152 await SaveAnnouncements();
15 office 153 }
154  
11 office 155 private void GotifyConnectionManager_GotifyNotification(object sender, GotifyNotificationEventArgs e)
156 {
24 office 157 Task.Factory.StartNew(() =>
158 {
159 foreach (var announcement in _announcements.Announcement)
160 {
161 if (announcement.AppId == e.Notification.AppId)
162 {
163 var configuredNotification = new Notification($"{e.Notification.Title} ({e.Notification.Server.Name}/{e.Notification.AppId})",
164 e.Notification.Message, announcement.LingerTime, e.Image, FormAnimator.AnimationMethod.Slide,
165 FormAnimator.AnimationDirection.Up);
166  
167 configuredNotification.Show();
168  
169 return;
170 }
171 }
172  
173 var notification = new Notification($"{e.Notification.Title} ({e.Notification.Server.Name}/{e.Notification.AppId})",
174 e.Notification.Message, 5000, e.Image, FormAnimator.AnimationMethod.Slide,
175 FormAnimator.AnimationDirection.Up);
176  
177 notification.Show();
178 }, CancellationToken.None, TaskCreationOptions.None, _uiTaskScheduler);
11 office 179 }
180  
7 office 181 private async void Server_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
182 {
21 office 183 await SaveServers();
7 office 184 }
185  
1 office 186 private static void Default_PropertyChanged(object sender, PropertyChangedEventArgs e)
187 {
188 Settings.Default.Save();
189 }
190  
191 private static void Default_SettingsSaving(object sender, CancelEventArgs e)
192 {
193 }
194  
195 private static void Default_SettingsLoaded(object sender, SettingsLoadedEventArgs e)
196 {
197 }
198  
199 private void SettingsToolStripMenuItem_Click(object sender, EventArgs e)
200 {
201 if (_settingsForm != null)
202 {
203 return;
204 }
205  
21 office 206 _settingsForm = new SettingsForm(_servers, _announcements);
1 office 207 _settingsForm.Closing += SettingsForm_Closing;
208 _settingsForm.Show();
209 }
210  
211 private void SettingsForm_Closing(object sender, CancelEventArgs e)
212 {
5 office 213 if (_settingsForm == null)
1 office 214 {
215 return;
216 }
6 office 217  
1 office 218 _settingsForm.Closing -= SettingsForm_Closing;
219 _settingsForm.Dispose();
220 _settingsForm = null;
221 }
222  
223 private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
224 {
225 if (_aboutForm != null)
226 {
227 return;
228 }
229  
230 _aboutForm = new AboutForm();
231 _aboutForm.Closing += AboutForm_Closing;
232 _aboutForm.Show();
233 }
234  
235 private void AboutForm_Closing(object sender, CancelEventArgs e)
236 {
237 if (_aboutForm == null)
238 {
239 return;
240 }
241  
242 _aboutForm.Closing -= AboutForm_Closing;
243 _aboutForm.Dispose();
244 _aboutForm = null;
245 }
246  
247 private void QuitToolStripMenuItem_Click(object sender, EventArgs e)
248 {
17 office 249 Close();
250  
251 Environment.Exit(0);
1 office 252 }
253  
9 office 254 private void UpdateToolStripMenuItem_Click(object sender, EventArgs e)
255 {
256 AutoUpdater.Start("http://winify.grimore.org/update/winify.xml");
257 }
258  
1 office 259 #endregion
4 office 260  
261 #region Private Methods
262  
21 office 263 private async Task SaveAnnouncements()
264 {
265 switch (await ServersSerialization.Serialize(_announcements, Constants.NotificationsFile, "Announcements",
266 "<!ATTLIST Announcements xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>"))
267 {
268 case SerializationFailure serializationFailure:
269 Log.Warning(serializationFailure.Exception, "Unable to serialize announcements.");
270 break;
271 }
272 }
273  
274 private async Task SaveServers()
275 {
276 // Encrypt password for all servers.
277 var deviceId = Miscellaneous.GetMachineGuid();
278 var @protected = new global::Servers.Servers
279 {
280 Server = new BindingListWithCollectionChanged<Server>()
281 };
282 foreach (var server in _servers.Server)
283 {
284 var encrypted = AES.Encrypt(Encoding.UTF8.GetBytes(server.Password), deviceId);
285 var armored = Convert.ToBase64String(encrypted);
286  
287 @protected.Server.Add(new Server(server.Name, server.Url, server.Username, armored));
288 }
289  
290 switch (await ServersSerialization.Serialize(@protected, Constants.ServersFile, "Servers",
291 "<!ATTLIST Servers xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>"))
292 {
293 case SerializationFailure serializationFailure:
294 Log.Warning(serializationFailure.Exception, "Unable to serialize servers.");
295 break;
296 }
297 }
298  
15 office 299 private static async Task<Announcements.Announcements> LoadAnnouncements()
300 {
301 if (!Directory.Exists(Constants.UserApplicationDirectory))
302 {
303 Directory.CreateDirectory(Constants.UserApplicationDirectory);
304 }
305  
306 var deserializationResult =
307 await ServersSerialization.Deserialize<Announcements.Announcements>(Constants.NotificationsFile,
308 "urn:winify-announcements-schema", "Announcements.xsd");
309  
310 switch (deserializationResult)
311 {
312 case SerializationSuccess<Announcements.Announcements> serializationSuccess:
313 return serializationSuccess.Result;
21 office 314 case SerializationFailure serializationFailure:
315 Log.Warning(serializationFailure.Exception, "Unable to load announcements.");
316 return new Announcements.Announcements();
15 office 317 default:
318 return new Announcements.Announcements();
319 }
320 }
321  
8 office 322 private static async Task<global::Servers.Servers> LoadServers()
4 office 323 {
324 if (!Directory.Exists(Constants.UserApplicationDirectory))
325 {
326 Directory.CreateDirectory(Constants.UserApplicationDirectory);
327 }
328  
15 office 329 var deserializationResult =
330 await ServersSerialization.Deserialize<global::Servers.Servers>(Constants.ServersFile,
331 "urn:winify-servers-schema", "Servers.xsd");
4 office 332  
333 switch (deserializationResult)
334 {
15 office 335 case SerializationSuccess<global::Servers.Servers> serializationSuccess:
336 // Decrypt password.
337 var deviceId = Miscellaneous.GetMachineGuid();
338 var @protected = new global::Servers.Servers
339 {
340 Server = new BindingListWithCollectionChanged<Server>()
341 };
342 foreach (var server in serializationSuccess.Result.Server)
343 {
344 var unarmored = Convert.FromBase64String(server.Password);
345 var decrypted = Encoding.UTF8.GetString(AES.Decrypt(unarmored, deviceId));
4 office 346  
15 office 347 @protected.Server.Add(new Server(server.Name, server.Url, server.Username, decrypted));
348 }
349  
350 return @protected;
351  
21 office 352 case SerializationFailure serializationFailure:
353 Log.Warning(serializationFailure.Exception, "Unable to load servers.");
354 return new global::Servers.Servers();
355  
4 office 356 default:
8 office 357 return new global::Servers.Servers();
4 office 358 }
359 }
360  
361 #endregion
1 office 362 }
363 }