Winify – Diff between revs 25 and 28

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