Winify – Diff between revs 26 and 28

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 26 Rev 28
1 using System; 1 using System;
2 using System.Drawing; 2 using System.Drawing;
3 using System.IO; 3 using System.IO;
4 using System.Net.Http; 4 using System.Net.Http;
5 using System.Net.Http.Headers; 5 using System.Net.Http.Headers;
6 using System.Net.WebSockets; 6 using System.Net.WebSockets;
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 Newtonsoft.Json; 10 using Newtonsoft.Json;
11 using Serilog; 11 using Serilog;
12 using Servers; 12 using Servers;
13 using ClientWebSocket = System.Net.WebSockets.Managed.ClientWebSocket; 13 using ClientWebSocket = System.Net.WebSockets.Managed.ClientWebSocket;
14   14  
15 namespace Winify.Gotify 15 namespace Winify.Gotify
16 { 16 {
17 public class GotifyConnection : IDisposable 17 public class GotifyConnection : IDisposable
18 { 18 {
19 #region Public Events & Delegates 19 #region Public Events & Delegates
20   20  
21 public event EventHandler<GotifyNotificationEventArgs> GotifyNotification; 21 public event EventHandler<GotifyNotificationEventArgs> GotifyNotification;
22   22  
23 #endregion 23 #endregion
24   24  
25 #region Private Delegates, Events, Enums, Properties, Indexers and Fields 25 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
26   26  
27 private readonly Server _server; 27 private readonly Server _server;
28   28  
29 private CancellationToken _cancellationToken; 29 private CancellationToken _cancellationToken;
30   30  
31 private CancellationTokenSource _cancellationTokenSource; 31 private CancellationTokenSource _cancellationTokenSource;
32   32  
33 private Task _runTask; 33 private Task _runTask;
34   34  
35 #endregion 35 #endregion
36   36  
37 #region Constructors, Destructors and Finalizers 37 #region Constructors, Destructors and Finalizers
38   38  
39 public GotifyConnection(Server server) 39 public GotifyConnection(Server server)
40 { 40 {
41 _server = server; 41 _server = server;
42 } 42 }
43   43  
44 public void Dispose() 44 public void Dispose()
45 { 45 {
46 if (_cancellationTokenSource != null) 46 if (_cancellationTokenSource != null)
47 { 47 {
48 _cancellationTokenSource.Dispose(); 48 _cancellationTokenSource.Dispose();
49 _cancellationTokenSource = null; 49 _cancellationTokenSource = null;
50 } 50 }
51 } 51 }
52   52  
53 #endregion 53 #endregion
54   54  
55 #region Public Methods 55 #region Public Methods
56   56  
57 public void Start() 57 public void Start()
58 { 58 {
59 if (!Uri.TryCreate(_server.Url, UriKind.Absolute, out var httpUri)) 59 if (!Uri.TryCreate(_server.Url, UriKind.Absolute, out var httpUri)) return;
60 { -  
61 return; -  
62 } -  
63   60  
64 // Build the web sockets URI. 61 // Build the web sockets URI.
65 var webSocketsUriBuilder = new UriBuilder(httpUri); 62 var webSocketsUriBuilder = new UriBuilder(httpUri);
66 webSocketsUriBuilder.Scheme = "ws"; 63 webSocketsUriBuilder.Scheme = "ws";
67 webSocketsUriBuilder.Path = $"{webSocketsUriBuilder.Path}/stream"; 64 webSocketsUriBuilder.Path = Path.Combine($"{webSocketsUriBuilder.Path}", "stream");
68 var webSocketsUri = webSocketsUriBuilder.Uri; 65 var webSocketsUri = webSocketsUriBuilder.Uri;
69   66  
70 _cancellationTokenSource = new CancellationTokenSource(); 67 _cancellationTokenSource = new CancellationTokenSource();
71 _cancellationToken = _cancellationTokenSource.Token; 68 _cancellationToken = _cancellationTokenSource.Token;
72   69  
73 _runTask = Run(webSocketsUri, httpUri, _server.Username, _server.Password, _cancellationToken); 70 _runTask = Run(webSocketsUri, httpUri, _server.Username, _server.Password, _cancellationToken);
74 } 71 }
75   72  
76 public void Stop() 73 public void Stop()
77 { 74 {
78 if (_cancellationTokenSource != null) -  
79 { -  
80 _cancellationTokenSource.Cancel(); 75 if (_cancellationTokenSource != null) _cancellationTokenSource.Cancel();
81 } -  
82 } 76 }
83   77  
84 #endregion 78 #endregion
85   79  
86 #region Private Methods 80 #region Private Methods
87   81  
88 private async Task Run(Uri webSocketsUri, Uri httpUri, string username, string password, 82 private async Task Run(Uri webSocketsUri, Uri httpUri, string username, string password,
89 CancellationToken cancellationToken) 83 CancellationToken cancellationToken)
90 { 84 {
91 try 85 try
92 { 86 {
93 do 87 do
94 { 88 {
95 try 89 try
96 { 90 {
97 using (var webSocketClient = new ClientWebSocket()) 91 using (var webSocketClient = new ClientWebSocket())
98 { 92 {
99 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}")); 93 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
100   94  
101 webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}"); 95 webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}");
102   96  
103 await webSocketClient.ConnectAsync(webSocketsUri, cancellationToken); 97 await webSocketClient.ConnectAsync(webSocketsUri, cancellationToken);
104   98  
105 do 99 do
106 { 100 {
107 var payload = new ArraySegment<byte>(new byte[1024]); 101 var payload = new ArraySegment<byte>(new byte[1024]);
108   102  
109 var result = await webSocketClient.ReceiveAsync(payload, cancellationToken); 103 var result = await webSocketClient.ReceiveAsync(payload, cancellationToken);
110   104  
111 if (result.Count == 0) -  
112 { -  
113 continue; -  
114 } 105 if (result.Count == 0) continue;
115   -  
116 if (payload.Array == null || payload.Count == 0) -  
117 { -  
118 continue; 106  
119 } 107 if (payload.Array == null || payload.Count == 0) continue;
120   108  
121 var message = Encoding.UTF8.GetString(payload.Array, 0, payload.Count); 109 var message = Encoding.UTF8.GetString(payload.Array, 0, payload.Count);
122   110  
-   111 var gotifyNotification = JsonConvert.DeserializeObject<GotifyNotification>(message);
123 if (!(JsonConvert.DeserializeObject<GotifyNotification>(message) is GotifyNotification 112  
124 gotifyNotification)) 113 if (gotifyNotification == null)
125 { 114 {
126 Log.Warning($"Could not deserialize gotify notification: {message}"); 115 Log.Warning($"Could not deserialize gotify notification: {message}");
127   116  
128 continue; 117 continue;
129 } 118 }
130   119  
131 gotifyNotification.Server = _server; 120 gotifyNotification.Server = _server;
132   121  
133 if (!Uri.TryCreate($"{httpUri}/application", UriKind.Absolute, 122 if (!Uri.TryCreate(Path.Combine($"{httpUri}", "application"), UriKind.Absolute,
134 out var applicationUri)) -  
135 { 123 out var applicationUri))
136 continue; -  
137 } 124 continue;
138   125  
139 var image = await RetrieveGotifyApplicationImage(gotifyNotification.AppId, httpUri, 126 var image = await RetrieveGotifyApplicationImage(gotifyNotification.AppId, httpUri,
140 applicationUri, auth, cancellationToken); 127 applicationUri, auth, cancellationToken);
141   128  
142 GotifyNotification?.Invoke(this, 129 GotifyNotification?.Invoke(this,
143 new GotifyNotificationEventArgs(gotifyNotification, image)); 130 new GotifyNotificationEventArgs(gotifyNotification, image));
144   131  
145 Log.Debug($"Notification message received: {gotifyNotification.Message}"); 132 Log.Debug($"Notification message received: {gotifyNotification.Message}");
146 } while (!cancellationToken.IsCancellationRequested); 133 } while (!cancellationToken.IsCancellationRequested);
147 } 134 }
148 } 135 }
149 catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException) 136 catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException)
150 { 137 {
151 // Reconnect 138 // Reconnect
152 Log.Warning($"Unable to connect to gotify server: {ex.Message}"); 139 Log.Warning($"Unable to connect to gotify server: {ex.Message}");
153   140  
154 await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); 141 await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
155 } 142 }
156 } while (!cancellationToken.IsCancellationRequested); 143 } while (!cancellationToken.IsCancellationRequested);
157 } 144 }
158 catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException) 145 catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException)
159 { 146 {
160 } 147 }
161 catch (Exception ex) 148 catch (Exception ex)
162 { 149 {
163 Log.Warning(ex, "Failure running connection loop."); 150 Log.Warning(ex, "Failure running connection loop.");
164 } 151 }
165 } 152 }
166   153  
167 private static async Task<Image> RetrieveGotifyApplicationImage(int appId, Uri httpUri, Uri applicationUri, 154 private static async Task<Image> RetrieveGotifyApplicationImage(int appId, Uri httpUri, Uri applicationUri,
168 string auth, 155 string auth,
169 CancellationToken cancellationToken) 156 CancellationToken cancellationToken)
170 { 157 {
171 using (var httpClient = new HttpClient()) 158 using (var httpClient = new HttpClient())
172 { 159 {
173 httpClient.DefaultRequestHeaders.Authorization = 160 httpClient.DefaultRequestHeaders.Authorization =
174 new AuthenticationHeaderValue("Basic", auth); 161 new AuthenticationHeaderValue("Basic", auth);
175   162  
176 var applicationResponse = await httpClient.GetAsync(applicationUri, cancellationToken); 163 var applicationResponse = await httpClient.GetAsync(applicationUri, cancellationToken);
177   164  
178 var applications = await applicationResponse.Content.ReadAsStringAsync(); 165 var applications = await applicationResponse.Content.ReadAsStringAsync();
179   166  
180 var gotifyApplications = 167 var gotifyApplications =
181 JsonConvert.DeserializeObject<GotifyApplication[]>(applications); 168 JsonConvert.DeserializeObject<GotifyApplication[]>(applications);
182   169  
183 if (gotifyApplications == null) -  
184 { -  
185 return null; -  
186 } 170 if (gotifyApplications == null) return null;
187   171  
188 foreach (var application in gotifyApplications) 172 foreach (var application in gotifyApplications)
189 { 173 {
190 if (application.Id != appId) 174 if (application.Id != appId) continue;
191 { -  
192 continue; -  
193 } -  
194   175  
195 if (!Uri.TryCreate($"{httpUri}/{application.Image}", UriKind.Absolute, 176 if (!Uri.TryCreate(Path.Combine($"{httpUri}", $"{application.Image}"), UriKind.Absolute,
196 out var applicationImageUri)) -  
197 { 177 out var applicationImageUri))
198 continue; -  
199 } 178 continue;
200   179  
201 var imageResponse = await httpClient.GetAsync(applicationImageUri, cancellationToken); 180 var imageResponse = await httpClient.GetAsync(applicationImageUri, cancellationToken);
202   181  
203 using (var memoryStream = new MemoryStream()) 182 using (var memoryStream = new MemoryStream())
204 { 183 {
205 await imageResponse.Content.CopyToAsync(memoryStream); 184 await imageResponse.Content.CopyToAsync(memoryStream);
206   185  
207 return Image.FromStream(memoryStream); 186 return Image.FromStream(memoryStream);
208 } 187 }
209 } 188 }
210 } 189 }
211   190  
212 return null; 191 return null;
213 } 192 }
214   193  
215 #endregion 194 #endregion
216 } 195 }
217 } 196 }
218   197  
219
Generated by GNU Enscript 1.6.5.90.
198
Generated by GNU Enscript 1.6.5.90.
220   199  
221   200  
222   201