Winify – Diff between revs 78 and 83

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 78 Rev 83
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.Drawing; 4 using System.Drawing;
5 using System.IO; 5 using System.IO;
6 using System.Net; 6 using System.Net;
7 using System.Reflection; 7 using System.Reflection;
8 using System.Text; 8 using System.Text;
9 using System.Threading; 9 using System.Threading;
10 using System.Threading.Tasks; 10 using System.Threading.Tasks;
11 using System.Windows.Forms; 11 using System.Windows.Forms;
12 using Microsoft.Win32; 12 using Microsoft.Win32;
13 using NetSparkleUpdater; 13 using NetSparkleUpdater;
14 using NetSparkleUpdater.Enums; 14 using NetSparkleUpdater.Enums;
15 using NetSparkleUpdater.SignatureVerifiers; 15 using NetSparkleUpdater.SignatureVerifiers;
16 using NetSparkleUpdater.UI.WinForms; 16 using NetSparkleUpdater.UI.WinForms;
17 using Serilog; 17 using Serilog;
18 using Servers; 18 using Servers;
19 using Toasts; 19 using Toasts;
20 using Winify.Gotify; 20 using Winify.Gotify;
21 using Winify.Settings; 21 using Winify.Settings;
22 using Winify.Utilities; 22 using Winify.Utilities;
23 using Winify.Utilities.Serialization; 23 using Winify.Utilities.Serialization;
24 using ScheduledContinuation = Toasts.ScheduledContinuation; 24 using ScheduledContinuation = Toasts.ScheduledContinuation;
25   25  
26 namespace Winify 26 namespace Winify
27 { 27 {
28 public partial class MainForm : Form 28 public partial class MainForm : Form
29 { 29 {
30 #region Public Enums, Properties and Fields 30 #region Public Enums, Properties and Fields
31   31  
32 public Configuration.Configuration Configuration { get; set; } 32 public Configuration.Configuration Configuration { get; set; }
33   33  
34 public ScheduledContinuation ChangedConfigurationContinuation { get; set; } 34 public ScheduledContinuation ChangedConfigurationContinuation { get; set; }
35   35  
36 public bool MemorySinkEnabled { get; set; } 36 public bool MemorySinkEnabled { get; set; }
37   37  
38 #endregion 38 #endregion
39   39  
40 #region Private Delegates, Events, Enums, Properties, Indexers and Fields 40 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
41   41  
42 private AboutForm _aboutForm; 42 private AboutForm _aboutForm;
43   43  
44 private ConcurrentBag<GotifyConnection> _gotifyConnections; 44 private ConcurrentBag<GotifyConnection> _gotifyConnections;
45   45  
46 private SettingsForm _settingsForm; 46 private SettingsForm _settingsForm;
47   47  
48 private readonly SparkleUpdater _sparkle; 48 private readonly SparkleUpdater _sparkle;
49   49  
50 private readonly CancellationTokenSource _cancellationTokenSource; 50 private readonly CancellationTokenSource _cancellationTokenSource;
51   51  
52 private readonly CancellationToken _cancellationToken; 52 private readonly CancellationToken _cancellationToken;
53   53  
54 private LogViewForm _logViewForm; 54 private LogViewForm _logViewForm;
55   55  
56 private readonly LogMemorySink _memorySink; 56 private readonly LogMemorySink _memorySink;
57   57  
58 private readonly Toasts.ToastDisplay _toastDisplay; 58 private readonly Toasts.ToastDisplay _toastDisplay;
59   59  
60 #endregion 60 #endregion
61   61  
62 #region Constructors, Destructors and Finalizers 62 #region Constructors, Destructors and Finalizers
63   63  
64 public MainForm() 64 public MainForm()
65 { 65 {
66 InitializeComponent(); 66 InitializeComponent();
67   67  
68 SystemEvents.PowerModeChanged += OnPowerModeChanged; 68 SystemEvents.PowerModeChanged += OnPowerModeChanged;
69   69  
70 _cancellationTokenSource = new CancellationTokenSource(); 70 _cancellationTokenSource = new CancellationTokenSource();
71 _cancellationToken = _cancellationTokenSource.Token; 71 _cancellationToken = _cancellationTokenSource.Token;
72   72  
73 ChangedConfigurationContinuation = new ScheduledContinuation(); 73 ChangedConfigurationContinuation = new ScheduledContinuation();
74   74  
75 _toastDisplay = new Toasts.ToastDisplay(_cancellationToken); 75 _toastDisplay = new Toasts.ToastDisplay(_cancellationToken);
76 } 76 }
77   77  
78 public MainForm(Mutex mutex) : this() 78 public MainForm(Mutex mutex) : this()
79 { 79 {
80 _memorySink = new LogMemorySink(); 80 _memorySink = new LogMemorySink();
81 Log.Logger = new LoggerConfiguration() 81 Log.Logger = new LoggerConfiguration()
82 .MinimumLevel.Debug() 82 .MinimumLevel.Debug()
83 .WriteTo.Conditional(condition => MemorySinkEnabled, configureSink => configureSink.Sink(_memorySink)) 83 .WriteTo.Conditional(condition => MemorySinkEnabled, configureSink => configureSink.Sink(_memorySink))
84 .WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"), 84 .WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"),
85 rollingInterval: RollingInterval.Day) 85 rollingInterval: RollingInterval.Day)
86 .CreateLogger(); 86 .CreateLogger();
87   87  
88 // Start application update. 88 // Start application update.
89 var manifestModuleName = Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName; 89 var manifestModuleName = Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName;
90 var icon = Icon.ExtractAssociatedIcon(manifestModuleName); 90 var icon = Icon.ExtractAssociatedIcon(manifestModuleName);
91   91  
92 _sparkle = new SparkleUpdater("https://winify.grimore.org/update/appcast.xml", 92 _sparkle = new SparkleUpdater("https://winify.grimore.org/update/appcast.xml",
93 new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY=")) 93 new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY="))
94 { 94 {
95 UIFactory = new UIFactory(icon), 95 UIFactory = new UIFactory(icon),
96 RelaunchAfterUpdate = true, 96 RelaunchAfterUpdate = true,
97 SecurityProtocolType = SecurityProtocolType.Tls12 97 SecurityProtocolType = SecurityProtocolType.Tls12
98 }; 98 };
99 _sparkle.StartLoop(true, true); 99 _sparkle.StartLoop(true, true);
100 } 100 }
101   101  
102 /// <summary> 102 /// <summary>
103 /// Clean up any resources being used. 103 /// Clean up any resources being used.
104 /// </summary> 104 /// </summary>
105 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 105 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
106 protected override void Dispose(bool disposing) 106 protected override void Dispose(bool disposing)
107 { 107 {
108 if (disposing && components != null) components.Dispose(); 108 if (disposing && components != null) components.Dispose();
109   109  
110 base.Dispose(disposing); 110 base.Dispose(disposing);
111 } 111 }
112   112  
113 #endregion 113 #endregion
114   114  
115 #region Event Handlers 115 #region Event Handlers
116   116  
117 private async void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e) 117 private async void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
118 { 118 {
119 switch (e.Mode) 119 switch (e.Mode)
120 { 120 {
121 case PowerModes.Resume: 121 case PowerModes.Resume:
122 // Refresh connection to gotify server. 122 // Refresh connection to gotify server.
123 while (_gotifyConnections.TryTake(out var gotifyConnection)) 123 while (_gotifyConnections.TryTake(out var gotifyConnection))
124 { 124 {
125 gotifyConnection.GotifyMessage -= GotifyConnectionGotifyMessage; 125 gotifyConnection.GotifyMessage -= GotifyConnectionGotifyMessage;
126 await gotifyConnection.Stop(); 126 await gotifyConnection.Stop();
127 gotifyConnection.Dispose(); 127 gotifyConnection.Dispose();
128 } 128 }
129   129  
130 var servers = await LoadServers(); 130 var servers = await LoadServers();
131 foreach (var server in servers.Server) 131 foreach (var server in servers.Server)
132 { 132 {
133 var gotifyConnection = new GotifyConnection(server, Configuration); 133 var gotifyConnection = new GotifyConnection(server, Configuration, _cancellationToken);
134 gotifyConnection.GotifyMessage += GotifyConnectionGotifyMessage; 134 gotifyConnection.GotifyMessage += GotifyConnectionGotifyMessage;
135 gotifyConnection.Start(); 135 gotifyConnection.Start();
136 _gotifyConnections.Add(gotifyConnection); 136 _gotifyConnections.Add(gotifyConnection);
137 } 137 }
138 break; 138 break;
139 } 139 }
140 } 140 }
141   141  
142 private async void MainForm_Load(object sender, EventArgs e) 142 private async void MainForm_Load(object sender, EventArgs e)
143 { 143 {
144 Configuration = await LoadConfiguration(); 144 Configuration = await LoadConfiguration();
145   145  
146 var servers = await LoadServers(); 146 var servers = await LoadServers();
147 _gotifyConnections = new ConcurrentBag<GotifyConnection>(); 147 _gotifyConnections = new ConcurrentBag<GotifyConnection>();
148 foreach (var server in servers.Server) 148 foreach (var server in servers.Server)
149 { 149 {
150 var gotifyConnection = new GotifyConnection(server, Configuration); 150 var gotifyConnection = new GotifyConnection(server, Configuration, _cancellationToken);
151 gotifyConnection.GotifyMessage += GotifyConnectionGotifyMessage; 151 gotifyConnection.GotifyMessage += GotifyConnectionGotifyMessage;
152 gotifyConnection.Start(); 152 gotifyConnection.Start();
153 _gotifyConnections.Add(gotifyConnection); 153 _gotifyConnections.Add(gotifyConnection);
154 } 154 }
155 } 155 }
156   156  
157 private void LogViewToolStripMenuItem_Click(object sender, EventArgs e) 157 private void LogViewToolStripMenuItem_Click(object sender, EventArgs e)
158 { 158 {
159 if (_logViewForm != null) 159 if (_logViewForm != null)
160 { 160 {
161 return; 161 return;
162 } 162 }
163   163  
164 _logViewForm = new LogViewForm(this, _memorySink, _cancellationToken); 164 _logViewForm = new LogViewForm(this, _memorySink, _cancellationToken);
165 _logViewForm.Closing += LogViewForm_Closing; 165 _logViewForm.Closing += LogViewForm_Closing;
166 _logViewForm.Show(); 166 _logViewForm.Show();
167 } 167 }
168   168  
169 private void LogViewForm_Closing(object sender, CancelEventArgs e) 169 private void LogViewForm_Closing(object sender, CancelEventArgs e)
170 { 170 {
171 if (_logViewForm == null) 171 if (_logViewForm == null)
172 { 172 {
173 return; 173 return;
174 } 174 }
175   175  
176 _logViewForm.Closing -= LogViewForm_Closing; 176 _logViewForm.Closing -= LogViewForm_Closing;
177 _logViewForm.Close(); 177 _logViewForm.Close();
178 _logViewForm = null; 178 _logViewForm = null;
179 } 179 }
180   180  
181 private async void SettingsToolStripMenuItem_Click(object sender, EventArgs e) 181 private async void SettingsToolStripMenuItem_Click(object sender, EventArgs e)
182 { 182 {
183 if (_settingsForm == null) 183 if (_settingsForm == null)
184 { 184 {
185 var servers = await LoadServers(); 185 var servers = await LoadServers();
186 var announcements = await LoadAnnouncements(); 186 var announcements = await LoadAnnouncements();
187   187  
188 _settingsForm = new SettingsForm(this, servers, announcements, _cancellationToken); 188 _settingsForm = new SettingsForm(this, servers, announcements, _cancellationToken);
189 _settingsForm.Save += SettingsForm_Save; 189 _settingsForm.Save += SettingsForm_Save;
190 _settingsForm.Closing += SettingsForm_Closing; 190 _settingsForm.Closing += SettingsForm_Closing;
191 _settingsForm.Show(); 191 _settingsForm.Show();
192 } 192 }
193 } 193 }
194   194  
195 private async void SettingsForm_Save(object sender, SettingsSavedEventArgs e) 195 private async void SettingsForm_Save(object sender, SettingsSavedEventArgs e)
196 { 196 {
197 // Save the configuration. 197 // Save the configuration.
198 Miscellaneous.LaunchOnBootSet(Configuration.LaunchOnBoot); 198 Miscellaneous.LaunchOnBootSet(Configuration.LaunchOnBoot);
199 ChangedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1), 199 ChangedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
200 async () => { await SaveConfiguration(); }, _cancellationToken); 200 async () => { await SaveConfiguration(); }, _cancellationToken);
201   201  
202 // Save the servers. 202 // Save the servers.
203 await Task.WhenAll(SaveServers(e.Servers), SaveAnnouncements(e.Announcements)); 203 await Task.WhenAll(SaveServers(e.Servers), SaveAnnouncements(e.Announcements));
204   204  
205 // Update connections to gotify servers. 205 // Update connections to gotify servers.
206 while (_gotifyConnections.TryTake(out var gotifyConnection)) 206 while (_gotifyConnections.TryTake(out var gotifyConnection))
207 { 207 {
208 gotifyConnection.GotifyMessage -= GotifyConnectionGotifyMessage; 208 gotifyConnection.GotifyMessage -= GotifyConnectionGotifyMessage;
209 await gotifyConnection.Stop(); 209 await gotifyConnection.Stop();
210 gotifyConnection.Dispose(); 210 gotifyConnection.Dispose();
211 } 211 }
212   212  
213 foreach (var server in e.Servers.Server) 213 foreach (var server in e.Servers.Server)
214 { 214 {
215 var gotifyConnection = new GotifyConnection(server, Configuration); 215 var gotifyConnection = new GotifyConnection(server, Configuration, _cancellationToken);
216 gotifyConnection.GotifyMessage += GotifyConnectionGotifyMessage; 216 gotifyConnection.GotifyMessage += GotifyConnectionGotifyMessage;
217 gotifyConnection.Start(); 217 gotifyConnection.Start();
218 _gotifyConnections.Add(gotifyConnection); 218 _gotifyConnections.Add(gotifyConnection);
219 } 219 }
220 } 220 }
221   221  
222 private async void GotifyConnectionGotifyMessage(object sender, GotifyMessageEventArgs e) 222 private async void GotifyConnectionGotifyMessage(object sender, GotifyMessageEventArgs e)
223 { 223 {
224 var announcements = await LoadAnnouncements(); 224 var announcements = await LoadAnnouncements();
225   225  
226 foreach (var announcement in announcements.Announcement) 226 foreach (var announcement in announcements.Announcement)
227 { 227 {
228 if (announcement.AppId != e.Message.AppId) 228 if (announcement.AppId != e.Message.AppId)
229 { 229 {
230 continue; 230 continue;
231 } 231 }
232   232  
233 if (announcement.Ignore) 233 if (announcement.Ignore)
234 { 234 {
235 return; 235 return;
236 } 236 }
237   237  
238 if (announcement.LingerTime <= 0) 238 if (announcement.LingerTime <= 0)
239 { 239 {
240 return; 240 return;
241 } 241 }
242   242  
243 await _toastDisplay.Queue( 243 await _toastDisplay.Queue(
244 new ToastDisplayData 244 new ToastDisplayData
245 { 245 {
246 Title = $"{e.Message.Title} ({e.Message.Server.Name}/{e.Message.AppId})", 246 Title = $"{e.Message.Title} ({e.Message.Server.Name}/{e.Message.AppId})",
247 Body = e.Message.Message, 247 Body = e.Message.Message,
248 EnableChime = announcement.EnableChime, 248 EnableChime = announcement.EnableChime,
249 Chime = announcement.Chime ?? Configuration.Chime, 249 Chime = announcement.Chime ?? Configuration.Chime,
250 LingerTime = (int)announcement.LingerTime, 250 LingerTime = (int)announcement.LingerTime,
251 Image = e.Image, 251 Image = e.Image,
252 Content = e.Message.Extras.GotifyMessageExtrasClientDisplay.ContentType 252 Content = e.Message.Extras.GotifyMessageExtrasClientDisplay.ContentType
253 }); 253 });
254   254  
255 return; 255 return;
256 } 256 }
257   257  
258 if (Configuration.InfiniteToastDuration) 258 if (Configuration.InfiniteToastDuration)
259 { 259 {
260 await _toastDisplay.Queue(new ToastDisplayData 260 await _toastDisplay.Queue(new ToastDisplayData
261 { 261 {
262 Title = $"{e.Message.Title} ({e.Message.Server.Name}/{e.Message.AppId})", 262 Title = $"{e.Message.Title} ({e.Message.Server.Name}/{e.Message.AppId})",
263 Body = e.Message.Message, 263 Body = e.Message.Message,
264 Chime = Configuration.Chime, 264 Chime = Configuration.Chime,
265 Image = e.Image, 265 Image = e.Image,
266 Content = e.Message.Extras.GotifyMessageExtrasClientDisplay.ContentType 266 Content = e.Message.Extras.GotifyMessageExtrasClientDisplay.ContentType
267 }); 267 });
268   268  
269 return; 269 return;
270 } 270 }
271   271  
272 await _toastDisplay.Queue(new ToastDisplayData 272 await _toastDisplay.Queue(new ToastDisplayData
273 { 273 {
274 Title = $"{e.Message.Title} ({e.Message.Server.Name}/{e.Message.AppId})", 274 Title = $"{e.Message.Title} ({e.Message.Server.Name}/{e.Message.AppId})",
275 Body = e.Message.Message, 275 Body = e.Message.Message,
276 Chime = Configuration.Chime, 276 Chime = Configuration.Chime,
277 LingerTime = Configuration.ToastDuration, 277 LingerTime = Configuration.ToastDuration,
278 Image = e.Image, 278 Image = e.Image,
279 Content = e.Message.Extras.GotifyMessageExtrasClientDisplay.ContentType 279 Content = e.Message.Extras.GotifyMessageExtrasClientDisplay.ContentType
280 }); 280 });
281 } 281 }
282   282  
283 private void SettingsForm_Closing(object sender, CancelEventArgs e) 283 private void SettingsForm_Closing(object sender, CancelEventArgs e)
284 { 284 {
285 if (_settingsForm == null) 285 if (_settingsForm == null)
286 { 286 {
287 return; 287 return;
288 } 288 }
289   289  
290 _settingsForm.Save -= SettingsForm_Save; 290 _settingsForm.Save -= SettingsForm_Save;
291 _settingsForm.Closing -= SettingsForm_Closing; 291 _settingsForm.Closing -= SettingsForm_Closing;
292 _settingsForm.Dispose(); 292 _settingsForm.Dispose();
293 _settingsForm = null; 293 _settingsForm = null;
294 } 294 }
295   295  
296 private void AboutToolStripMenuItem_Click(object sender, EventArgs e) 296 private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
297 { 297 {
298 if (_aboutForm != null) 298 if (_aboutForm != null)
299 { 299 {
300 return; 300 return;
301 } 301 }
302   302  
303 _aboutForm = new AboutForm(); 303 _aboutForm = new AboutForm();
304 _aboutForm.Closing += AboutForm_Closing; 304 _aboutForm.Closing += AboutForm_Closing;
305 _aboutForm.Show(); 305 _aboutForm.Show();
306 } 306 }
307   307  
308 private void AboutForm_Closing(object sender, CancelEventArgs e) 308 private void AboutForm_Closing(object sender, CancelEventArgs e)
309 { 309 {
310 if (_aboutForm == null) 310 if (_aboutForm == null)
311 { 311 {
312 return; 312 return;
313 } 313 }
314   314  
315 _aboutForm.Closing -= AboutForm_Closing; 315 _aboutForm.Closing -= AboutForm_Closing;
316 _aboutForm.Dispose(); 316 _aboutForm.Dispose();
317 _aboutForm = null; 317 _aboutForm = null;
318 } 318 }
319   319  
320 private void QuitToolStripMenuItem_Click(object sender, EventArgs e) 320 private void QuitToolStripMenuItem_Click(object sender, EventArgs e)
321 { 321 {
322 Close(); 322 Close();
323 } 323 }
324   324  
325 private async void UpdateToolStripMenuItem_Click(object sender, EventArgs e) 325 private async void UpdateToolStripMenuItem_Click(object sender, EventArgs e)
326 { 326 {
327 // Manually check for updates, this will not show a ui 327 // Manually check for updates, this will not show a ui
328 var result = await _sparkle.CheckForUpdatesQuietly(); 328 var result = await _sparkle.CheckForUpdatesQuietly();
329 var updates = result.Updates; 329 var updates = result.Updates;
330 if (result.Status == UpdateStatus.UpdateAvailable) 330 if (result.Status == UpdateStatus.UpdateAvailable)
331 { 331 {
332 // if update(s) are found, then we have to trigger the UI to show it gracefully 332 // if update(s) are found, then we have to trigger the UI to show it gracefully
333 _sparkle.ShowUpdateNeededUI(); 333 _sparkle.ShowUpdateNeededUI();
334 return; 334 return;
335 } 335 }
336   336  
337 MessageBox.Show("No updates available at this time.", "Winify", MessageBoxButtons.OK, 337 MessageBox.Show("No updates available at this time.", "Winify", MessageBoxButtons.OK,
338 MessageBoxIcon.Asterisk, 338 MessageBoxIcon.Asterisk,
339 MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly, false); 339 MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly, false);
340 } 340 }
341   341  
342 #endregion 342 #endregion
343   343  
344 #region Public Methods 344 #region Public Methods
345   345  
346 public async Task SaveConfiguration() 346 public async Task SaveConfiguration()
347 { 347 {
348 if (!Directory.Exists(Constants.UserApplicationDirectory)) 348 if (!Directory.Exists(Constants.UserApplicationDirectory))
349 Directory.CreateDirectory(Constants.UserApplicationDirectory); 349 Directory.CreateDirectory(Constants.UserApplicationDirectory);
350   350  
351 switch (await Serialization.Serialize(Configuration, Constants.ConfigurationFile, "Configuration", 351 switch (await Serialization.Serialize(Configuration, Constants.ConfigurationFile, "Configuration",
352 "<!ATTLIST Configuration xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>", 352 "<!ATTLIST Configuration xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
353 CancellationToken.None)) 353 CancellationToken.None))
354 { 354 {
355 case SerializationSuccess<Configuration.Configuration> _: 355 case SerializationSuccess<Configuration.Configuration> _:
356 Log.Information("Serialized configuration."); 356 Log.Information("Serialized configuration.");
357 break; 357 break;
358 case SerializationFailure serializationFailure: 358 case SerializationFailure serializationFailure:
359 Log.Warning(serializationFailure.Exception.Message, "Failed to serialize configuration."); 359 Log.Warning(serializationFailure.Exception.Message, "Failed to serialize configuration.");
360 break; 360 break;
361 } 361 }
362 } 362 }
363   363  
364 public static async Task<Configuration.Configuration> LoadConfiguration() 364 public static async Task<Configuration.Configuration> LoadConfiguration()
365 { 365 {
366 if (!Directory.Exists(Constants.UserApplicationDirectory)) 366 if (!Directory.Exists(Constants.UserApplicationDirectory))
367 Directory.CreateDirectory(Constants.UserApplicationDirectory); 367 Directory.CreateDirectory(Constants.UserApplicationDirectory);
368   368  
369 var deserializationResult = 369 var deserializationResult =
370 await Serialization.Deserialize<Configuration.Configuration>(Constants.ConfigurationFile, 370 await Serialization.Deserialize<Configuration.Configuration>(Constants.ConfigurationFile,
371 Constants.ConfigurationNamespace, Constants.ConfigurationXsd, CancellationToken.None); 371 Constants.ConfigurationNamespace, Constants.ConfigurationXsd, CancellationToken.None);
372   372  
373 switch (deserializationResult) 373 switch (deserializationResult)
374 { 374 {
375 case SerializationSuccess<Configuration.Configuration> serializationSuccess: 375 case SerializationSuccess<Configuration.Configuration> serializationSuccess:
376 return serializationSuccess.Result; 376 return serializationSuccess.Result;
377 case SerializationFailure serializationFailure: 377 case SerializationFailure serializationFailure:
378 Log.Warning(serializationFailure.Exception, "Failed to load configuration."); 378 Log.Warning(serializationFailure.Exception, "Failed to load configuration.");
379 return new Configuration.Configuration(); 379 return new Configuration.Configuration();
380 default: 380 default:
381 return new Configuration.Configuration(); 381 return new Configuration.Configuration();
382 } 382 }
383 } 383 }
384   384  
385 #endregion 385 #endregion
386   386  
387 #region Private Methods 387 #region Private Methods
388   388  
389 private static async Task SaveAnnouncements(Announcements.Announcements announcements) 389 private static async Task SaveAnnouncements(Announcements.Announcements announcements)
390 { 390 {
391 switch (await Serialization.Serialize(announcements, Constants.AnnouncementsFile, "Announcements", 391 switch (await Serialization.Serialize(announcements, Constants.AnnouncementsFile, "Announcements",
392 "<!ATTLIST Announcements xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>", 392 "<!ATTLIST Announcements xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
393 CancellationToken.None)) 393 CancellationToken.None))
394 { 394 {
395 case SerializationFailure serializationFailure: 395 case SerializationFailure serializationFailure:
396 Log.Warning(serializationFailure.Exception, "Unable to serialize announcements."); 396 Log.Warning(serializationFailure.Exception, "Unable to serialize announcements.");
397 break; 397 break;
398 } 398 }
399 } 399 }
400   400  
401 private static async Task SaveServers(Servers.Servers servers) 401 private static async Task SaveServers(Servers.Servers servers)
402 { 402 {
403 // Encrypt password for all servers. 403 // Encrypt password for all servers.
404 var deviceId = Miscellaneous.GetMachineGuid(); 404 var deviceId = Miscellaneous.GetMachineGuid();
405 var @protected = new Servers.Servers 405 var @protected = new Servers.Servers
406 { 406 {
407 Server = new BindingListWithCollectionChanged<Server>() 407 Server = new BindingListWithCollectionChanged<Server>()
408 }; 408 };
409   409  
410 foreach (var server in servers.Server) 410 foreach (var server in servers.Server)
411 { 411 {
412 var password = Encoding.UTF8.GetBytes(server.Password); 412 var password = Encoding.UTF8.GetBytes(server.Password);
413 var encrypted = await AES.Encrypt(password, deviceId); 413 var encrypted = await AES.Encrypt(password, deviceId);
414 var armored = Convert.ToBase64String(encrypted); 414 var armored = Convert.ToBase64String(encrypted);
415   415  
416 @protected.Server.Add(new Server(server.Name, server.Url, server.Username, armored)); 416 @protected.Server.Add(new Server(server.Name, server.Url, server.Username, armored));
417 } 417 }
418   418  
419 switch (await Serialization.Serialize(@protected, Constants.ServersFile, "Servers", 419 switch (await Serialization.Serialize(@protected, Constants.ServersFile, "Servers",
420 "<!ATTLIST Servers xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>", 420 "<!ATTLIST Servers xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
421 CancellationToken.None)) 421 CancellationToken.None))
422 { 422 {
423 case SerializationFailure serializationFailure: 423 case SerializationFailure serializationFailure:
424 Log.Warning(serializationFailure.Exception, "Unable to serialize servers."); 424 Log.Warning(serializationFailure.Exception, "Unable to serialize servers.");
425 break; 425 break;
426 } 426 }
427 } 427 }
428   428  
429 private static async Task<Announcements.Announcements> LoadAnnouncements() 429 private static async Task<Announcements.Announcements> LoadAnnouncements()
430 { 430 {
431 if (!Directory.Exists(Constants.UserApplicationDirectory)) 431 if (!Directory.Exists(Constants.UserApplicationDirectory))
432 Directory.CreateDirectory(Constants.UserApplicationDirectory); 432 Directory.CreateDirectory(Constants.UserApplicationDirectory);
433   433  
434 var deserializationResult = 434 var deserializationResult =
435 await Serialization.Deserialize<Announcements.Announcements>(Constants.AnnouncementsFile, 435 await Serialization.Deserialize<Announcements.Announcements>(Constants.AnnouncementsFile,
436 "urn:winify-announcements-schema", "Announcements.xsd", CancellationToken.None); 436 "urn:winify-announcements-schema", "Announcements.xsd", CancellationToken.None);
437   437  
438 switch (deserializationResult) 438 switch (deserializationResult)
439 { 439 {
440 case SerializationSuccess<Announcements.Announcements> serializationSuccess: 440 case SerializationSuccess<Announcements.Announcements> serializationSuccess:
441 return serializationSuccess.Result; 441 return serializationSuccess.Result;
442 case SerializationFailure serializationFailure: 442 case SerializationFailure serializationFailure:
443 Log.Warning(serializationFailure.Exception, "Unable to load announcements."); 443 Log.Warning(serializationFailure.Exception, "Unable to load announcements.");
444 return new Announcements.Announcements(); 444 return new Announcements.Announcements();
445 default: 445 default:
446 return new Announcements.Announcements(); 446 return new Announcements.Announcements();
447 } 447 }
448 } 448 }
449   449  
450 private static async Task<Servers.Servers> LoadServers() 450 private static async Task<Servers.Servers> LoadServers()
451 { 451 {
452 if (!Directory.Exists(Constants.UserApplicationDirectory)) 452 if (!Directory.Exists(Constants.UserApplicationDirectory))
453 Directory.CreateDirectory(Constants.UserApplicationDirectory); 453 Directory.CreateDirectory(Constants.UserApplicationDirectory);
454   454  
455 var deserializationResult = 455 var deserializationResult =
456 await Serialization.Deserialize<Servers.Servers>(Constants.ServersFile, 456 await Serialization.Deserialize<Servers.Servers>(Constants.ServersFile,
457 "urn:winify-servers-schema", "Servers.xsd", CancellationToken.None); 457 "urn:winify-servers-schema", "Servers.xsd", CancellationToken.None);
458   458  
459 switch (deserializationResult) 459 switch (deserializationResult)
460 { 460 {
461 case SerializationSuccess<Servers.Servers> serializationSuccess: 461 case SerializationSuccess<Servers.Servers> serializationSuccess:
462 // Decrypt password. 462 // Decrypt password.
463 var deviceId = Miscellaneous.GetMachineGuid(); 463 var deviceId = Miscellaneous.GetMachineGuid();
464 var @protected = new Servers.Servers 464 var @protected = new Servers.Servers
465 { 465 {
466 Server = new BindingListWithCollectionChanged<Server>() 466 Server = new BindingListWithCollectionChanged<Server>()
467 }; 467 };
468 foreach (var server in serializationSuccess.Result.Server) 468 foreach (var server in serializationSuccess.Result.Server)
469 { 469 {
470 var unarmored = Convert.FromBase64String(server.Password); 470 var unarmored = Convert.FromBase64String(server.Password);
471 byte[] decrypted; 471 byte[] decrypted;
472 try 472 try
473 { 473 {
474 decrypted = await AES.Decrypt(unarmored, deviceId); 474 decrypted = await AES.Decrypt(unarmored, deviceId);
475 } 475 }
476 catch(Exception exception) 476 catch(Exception exception)
477 { 477 {
478 Log.Warning(exception, $"Could not decrypt password for server {server.Name} in configuration file."); 478 Log.Warning(exception, $"Could not decrypt password for server {server.Name} in configuration file.");
479 continue; 479 continue;
480 } 480 }
481   481  
482 var password = Encoding.UTF8.GetString(decrypted); 482 var password = Encoding.UTF8.GetString(decrypted);
483   483  
484 @protected.Server.Add(new Server(server.Name, server.Url, server.Username, password)); 484 @protected.Server.Add(new Server(server.Name, server.Url, server.Username, password));
485 } 485 }
486   486  
487 return @protected; 487 return @protected;
488   488  
489 case SerializationFailure serializationFailure: 489 case SerializationFailure serializationFailure:
490 Log.Warning(serializationFailure.Exception, "Unable to load servers."); 490 Log.Warning(serializationFailure.Exception, "Unable to load servers.");
491 return new Servers.Servers(); 491 return new Servers.Servers();
492   492  
493 default: 493 default:
494 return new Servers.Servers(); 494 return new Servers.Servers();
495 } 495 }
496 } 496 }
497   497  
498 #endregion 498 #endregion
499 } 499 }
500 } 500 }
501   501  
502
Generated by GNU Enscript 1.6.5.90.
502
Generated by GNU Enscript 1.6.5.90.
503   503  
504   504  
505   505