Winify – Diff between revs 83 and 84

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