Winify – Diff between revs 25 and 26

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 25 Rev 26
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))
60 { 60 {
61 return; 61 return;
62 } 62 }
63   63  
64 // Build the web sockets URI. 64 // Build the web sockets URI.
65 var webSocketsUriBuilder = new UriBuilder(httpUri); 65 var webSocketsUriBuilder = new UriBuilder(httpUri);
66 webSocketsUriBuilder.Scheme = "ws"; 66 webSocketsUriBuilder.Scheme = "ws";
67 webSocketsUriBuilder.Path = $"{webSocketsUriBuilder.Path}/stream"; 67 webSocketsUriBuilder.Path = $"{webSocketsUriBuilder.Path}/stream";
68 var webSocketsUri = webSocketsUriBuilder.Uri; 68 var webSocketsUri = webSocketsUriBuilder.Uri;
69   69  
70 _cancellationTokenSource = new CancellationTokenSource(); 70 _cancellationTokenSource = new CancellationTokenSource();
71 _cancellationToken = _cancellationTokenSource.Token; 71 _cancellationToken = _cancellationTokenSource.Token;
72   72  
73 _runTask = Run(webSocketsUri, httpUri, _server.Username, _server.Password, _cancellationToken); 73 _runTask = Run(webSocketsUri, httpUri, _server.Username, _server.Password, _cancellationToken);
74 } 74 }
75   75  
76 public void Stop() 76 public void Stop()
77 { 77 {
78 if (_cancellationTokenSource != null) 78 if (_cancellationTokenSource != null)
79 { 79 {
80 _cancellationTokenSource.Cancel(); 80 _cancellationTokenSource.Cancel();
81 } 81 }
82 } 82 }
83   83  
84 #endregion 84 #endregion
85   85  
86 #region Private Methods 86 #region Private Methods
87   87  
88 private async Task Run(Uri webSocketsUri, Uri httpUri, string username, string password, 88 private async Task Run(Uri webSocketsUri, Uri httpUri, string username, string password,
89 CancellationToken cancellationToken) 89 CancellationToken cancellationToken)
90 { 90 {
91 try 91 try
92 { 92 {
93 do 93 do
94 { 94 {
95 try 95 try
96 { 96 {
97 using (var webSocketClient = new ClientWebSocket()) 97 using (var webSocketClient = new ClientWebSocket())
98 { 98 {
99 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}")); 99 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
100   100  
101 webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}"); 101 webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}");
102   102  
103 await webSocketClient.ConnectAsync(webSocketsUri, cancellationToken); 103 await webSocketClient.ConnectAsync(webSocketsUri, cancellationToken);
104   104  
105 do 105 do
106 { 106 {
107 var payload = new ArraySegment<byte>(new byte[1024]); 107 var payload = new ArraySegment<byte>(new byte[1024]);
108   108  
109 var result = await webSocketClient.ReceiveAsync(payload, cancellationToken); 109 var result = await webSocketClient.ReceiveAsync(payload, cancellationToken);
110   110  
111 if (result.Count == 0) 111 if (result.Count == 0)
112 { 112 {
113 continue; 113 continue;
114 } 114 }
115   115  
116 if (payload.Array == null || payload.Count == 0) 116 if (payload.Array == null || payload.Count == 0)
117 { 117 {
118 continue; 118 continue;
119 } 119 }
120   120  
121 var message = Encoding.UTF8.GetString(payload.Array, 0, payload.Count); 121 var message = Encoding.UTF8.GetString(payload.Array, 0, payload.Count);
122   122  
123 if (!(JsonConvert.DeserializeObject<GotifyNotification>(message) is GotifyNotification 123 if (!(JsonConvert.DeserializeObject<GotifyNotification>(message) is GotifyNotification
124 gotifyNotification)) 124 gotifyNotification))
125 { 125 {
126 Log.Warning($"Could not deserialize gotify notification: {message}"); 126 Log.Warning($"Could not deserialize gotify notification: {message}");
127   127  
128 continue; 128 continue;
129 } 129 }
130   130  
131 gotifyNotification.Server = _server; 131 gotifyNotification.Server = _server;
132   132  
133 if (!Uri.TryCreate($"{httpUri}/application", UriKind.Absolute, 133 if (!Uri.TryCreate($"{httpUri}/application", UriKind.Absolute,
134 out var applicationUri)) 134 out var applicationUri))
135 { 135 {
136 continue; 136 continue;
137 } 137 }
138   138  
139 var image = await RetrieveGotifyApplicationImage(gotifyNotification.AppId, httpUri, 139 var image = await RetrieveGotifyApplicationImage(gotifyNotification.AppId, httpUri,
140 applicationUri, auth, cancellationToken); 140 applicationUri, auth, cancellationToken);
141   141  
142 GotifyNotification?.Invoke(this, 142 GotifyNotification?.Invoke(this,
143 new GotifyNotificationEventArgs(gotifyNotification, image)); 143 new GotifyNotificationEventArgs(gotifyNotification, image));
144   144  
145 Log.Debug($"Notification message received: {gotifyNotification.Message}"); 145 Log.Debug($"Notification message received: {gotifyNotification.Message}");
146 } while (!cancellationToken.IsCancellationRequested); 146 } while (!cancellationToken.IsCancellationRequested);
147 } 147 }
148 } 148 }
149 catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException) 149 catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException)
150 { 150 {
151 // Reconnect 151 // Reconnect
152 Log.Warning($"Unable to connect to gotify server: {ex.Message}"); 152 Log.Warning($"Unable to connect to gotify server: {ex.Message}");
153   153  
154 await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); 154 await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
155 } 155 }
156 } while (!cancellationToken.IsCancellationRequested); 156 } while (!cancellationToken.IsCancellationRequested);
157 } 157 }
158 catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException) 158 catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException)
159 { 159 {
160 } 160 }
161 catch (Exception ex) 161 catch (Exception ex)
162 { 162 {
163 Log.Warning(ex, "Failure running connection loop."); 163 Log.Warning(ex, "Failure running connection loop.");
164 } 164 }
165   -  
166 var e = "o"; -  
167 } 165 }
168   166  
169 private static async Task<Image> RetrieveGotifyApplicationImage(int appId, Uri httpUri, Uri applicationUri, 167 private static async Task<Image> RetrieveGotifyApplicationImage(int appId, Uri httpUri, Uri applicationUri,
170 string auth, 168 string auth,
171 CancellationToken cancellationToken) 169 CancellationToken cancellationToken)
172 { 170 {
173 using (var httpClient = new HttpClient()) 171 using (var httpClient = new HttpClient())
174 { 172 {
175 httpClient.DefaultRequestHeaders.Authorization = 173 httpClient.DefaultRequestHeaders.Authorization =
176 new AuthenticationHeaderValue("Basic", auth); 174 new AuthenticationHeaderValue("Basic", auth);
177   175  
178 var applicationResponse = await httpClient.GetAsync(applicationUri, cancellationToken); 176 var applicationResponse = await httpClient.GetAsync(applicationUri, cancellationToken);
179   177  
180 var applications = await applicationResponse.Content.ReadAsStringAsync(); 178 var applications = await applicationResponse.Content.ReadAsStringAsync();
181   179  
182 var gotifyApplications = 180 var gotifyApplications =
183 JsonConvert.DeserializeObject<GotifyApplication[]>(applications); 181 JsonConvert.DeserializeObject<GotifyApplication[]>(applications);
184   182  
185 if (gotifyApplications == null) 183 if (gotifyApplications == null)
186 { 184 {
187 return null; 185 return null;
188 } 186 }
189   187  
190 foreach (var application in gotifyApplications) 188 foreach (var application in gotifyApplications)
191 { 189 {
192 if (application.Id != appId) 190 if (application.Id != appId)
193 { 191 {
194 continue; 192 continue;
195 } 193 }
196   194  
197 if (!Uri.TryCreate($"{httpUri}/{application.Image}", UriKind.Absolute, 195 if (!Uri.TryCreate($"{httpUri}/{application.Image}", UriKind.Absolute,
198 out var applicationImageUri)) 196 out var applicationImageUri))
199 { 197 {
200 continue; 198 continue;
201 } 199 }
202   200  
203 var imageResponse = await httpClient.GetAsync(applicationImageUri, cancellationToken); 201 var imageResponse = await httpClient.GetAsync(applicationImageUri, cancellationToken);
204   202  
205 using (var memoryStream = new MemoryStream()) 203 using (var memoryStream = new MemoryStream())
206 { 204 {
207 await imageResponse.Content.CopyToAsync(memoryStream); 205 await imageResponse.Content.CopyToAsync(memoryStream);
208   206  
209 return Image.FromStream(memoryStream); 207 return Image.FromStream(memoryStream);
210 } 208 }
211 } 209 }
212 } 210 }
213   211  
214 return null; 212 return null;
215 } 213 }
216   214  
217 #endregion 215 #endregion
218 } 216 }
219 } 217 }
220   218  
221
Generated by GNU Enscript 1.6.5.90.
219
Generated by GNU Enscript 1.6.5.90.
222   220  
223   221  
224   222