Winify

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 66  →  ?path2? @ 67
File deleted
\ No newline at end of file
/trunk/Winify/Gotify/GotifyNotificationEventArgs.cs
/trunk/Winify/Gotify/GotifyConnection.cs
@@ -3,13 +3,10 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Caching;
using System.Runtime.CompilerServices;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
@@ -17,9 +14,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Pkcs;
using Serilog;
using Servers;
using WebSocketSharp;
@@ -34,7 +29,7 @@
{
#region Public Events & Delegates
 
public event EventHandler<GotifyNotificationEventArgs> GotifyNotification;
public event EventHandler<GotifyMessageEventArgs> GotifyMessage;
 
#endregion
 
@@ -57,8 +52,6 @@
private readonly Configuration.Configuration _configuration;
private IDisposable _tplRetrievePastMessagesLink;
private IDisposable _tplWebSocketsBufferBlockTransformLink;
private IDisposable _tplWebSocketsTransformActionLink;
private IDisposable _tplWebSocketsTransformActionNullLink;
private readonly BufferBlock<GotifyConnectionData> _webSocketMessageBufferBlock;
private readonly Stopwatch _webSocketsClientPingStopWatch;
private readonly ScheduledContinuation _webSocketsServerResponseScheduledContinuation;
@@ -82,64 +75,47 @@
CancellationToken = _cancellationToken
});
 
var webSocketTransformBlock = new TransformBlock<GotifyConnectionData, GotifyMessage>(data =>
var webSocketActionBlock = new ActionBlock<GotifyConnectionData>(async gotifyConnectionData =>
{
if (data.Payload == null || data.Payload.Length == 0)
try
{
return null;
}
using var memoryStream = new MemoryStream(gotifyConnectionData.Payload);
using var streamReader = new StreamReader(memoryStream);
using var jsonTextReader = new JsonTextReader(streamReader);
 
GotifyMessage gotifyNotification;
var gotifyMessage = _jsonSerializer.Deserialize<GotifyMessage>(jsonTextReader) ?? throw new ArgumentNullException();
 
try
{
var message = Encoding.UTF8.GetString(data.Payload, 0, data.Payload.Length);
gotifyMessage.Server = gotifyConnectionData.Server;
 
gotifyNotification = JsonConvert.DeserializeObject<GotifyMessage>(message);
using var imageStream = await RetrieveGotifyApplicationImage(gotifyMessage.AppId, _cancellationToken);
 
if (gotifyNotification == null)
if (imageStream == null || imageStream.Length == 0)
{
throw new ArgumentNullException();
Log.Warning("Could not find any application image for notification.");
 
return;
}
 
gotifyNotification.Server = data.Server;
var image = new Bitmap(imageStream);
 
GotifyMessage?.Invoke(this,
new GotifyMessageEventArgs(gotifyMessage, image));
 
Log.Debug($"Notification message received: {gotifyMessage.Message}");
}
catch (Exception exception)
catch (JsonSerializationException exception)
{
Log.Warning(exception, "Could not deserialize notification.");
 
return null;
Log.Warning(exception, "Could not deserialize notification message.");
}
 
return gotifyNotification;
 
}, new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken });
 
var webSocketActionBlock = new ActionBlock<GotifyMessage>(async message =>
{
using var imageStream = await RetrieveGotifyApplicationImage(message.AppId, _cancellationToken);
if (imageStream == null || imageStream.Length == 0)
catch (Exception exception)
{
Log.Warning("Could not find any application image for notification.");
 
return;
Log.Warning(exception, "Generic failure.");
}
 
var image = new Bitmap(imageStream);
 
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(message, image));
 
Log.Debug($"Notification message received: {message.Message}");
 
}, new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken });
 
_tplWebSocketsBufferBlockTransformLink = _webSocketMessageBufferBlock.LinkTo(webSocketTransformBlock,
_tplWebSocketsBufferBlockTransformLink = _webSocketMessageBufferBlock.LinkTo(webSocketActionBlock,
new DataflowLinkOptions { PropagateCompletion = true });
_tplWebSocketsTransformActionLink = webSocketTransformBlock.LinkTo(webSocketActionBlock,
new DataflowLinkOptions { PropagateCompletion = true }, message => message != null);
_tplWebSocketsTransformActionNullLink = webSocketTransformBlock.LinkTo(DataflowBlock.NullTarget<GotifyMessage>(),
new DataflowLinkOptions() { PropagateCompletion = true });
}
 
public GotifyConnection(Server server, Configuration.Configuration configuration) : this()
@@ -208,18 +184,6 @@
_tplWebSocketsBufferBlockTransformLink = null;
}
 
if (_tplWebSocketsTransformActionLink != null)
{
_tplWebSocketsTransformActionLink.Dispose();
_tplWebSocketsTransformActionLink = null;
}
 
if (_tplWebSocketsTransformActionNullLink != null)
{
_tplWebSocketsTransformActionNullLink.Dispose();
_tplWebSocketsTransformActionNullLink = null;
}
 
if (_tplRetrievePastMessagesLink != null)
{
_tplRetrievePastMessagesLink.Dispose();
@@ -309,7 +273,7 @@
 
private void OnUnresponsiveServer()
{
Log.Warning($"Server {_server} has not responded in a long while...");
Log.Warning($"Server {_server.Name} has not responded in a long while...");
}
 
private async void WebSocketSharp_OnError(object sender, ErrorEventArgs e)
@@ -329,7 +293,7 @@
{
if (e.IsPing)
{
Log.Information($"Server {_server} sent PING message");
Log.Information($"Server {_server.Name} sent PING message");
 
_webSocketsServerResponseScheduledContinuation.Schedule(TimeSpan.FromMinutes(1), OnUnresponsiveServer, _cancellationToken);
return;
@@ -382,7 +346,6 @@
return;
}
 
GotifyMessageQuery gotifyMessageQuery;
try
{
using var messageStream = await _httpClient.GetStreamAsync(combinedUri);
@@ -389,50 +352,52 @@
using var streamReader = new StreamReader(messageStream);
using var jsonTextReader = new JsonTextReader(streamReader);
 
gotifyMessageQuery = _jsonSerializer.Deserialize<GotifyMessageQuery>(jsonTextReader);
var gotifyMessageQuery = _jsonSerializer.Deserialize<GotifyMessageQuery>(jsonTextReader) ??
throw new ArgumentNullException();
 
if (gotifyMessageQuery.Messages == null)
{
Log.Warning("Invalid application messages deserialized deserialized.");
 
return;
}
 
foreach (var message in gotifyMessageQuery.Messages)
{
if (message.Date <
DateTime.Now - TimeSpan.FromHours(_configuration.RetrievePastNotificationHours))
{
continue;
}
 
using var imageStream = await RetrieveGotifyApplicationImage(message.AppId, _cancellationToken);
if (imageStream == null || imageStream.Length == 0)
{
Log.Warning("Could not find any application image for notification.");
 
continue;
}
 
var image = new Bitmap(imageStream);
message.Server = gotifyConnectionApplication.Server;
 
GotifyMessage?.Invoke(this,
new GotifyMessageEventArgs(message, image));
}
}
catch (HttpRequestException exception)
{
Log.Warning(exception, $"Could not get application {gotifyConnectionApplication.Application.Id}.");
 
return;
}
catch (JsonSerializationException exception)
{
Log.Warning(exception,$"Could not deserialize the message response for application {gotifyConnectionApplication.Application.Id}.");
 
return;
Log.Warning(exception,
$"Could not deserialize the message response for application {gotifyConnectionApplication.Application.Id}.");
}
 
if (gotifyMessageQuery == null || gotifyMessageQuery.Messages == null)
catch (Exception exception)
{
Log.Warning("Invalid application messages deserialized deserialized.");
 
return;
Log.Warning(exception, "Generic failure.");
}
 
foreach (var message in gotifyMessageQuery.Messages)
{
if (message.Date < DateTime.Now - TimeSpan.FromHours(_configuration.RetrievePastNotificationHours))
{
continue;
}
using var imageStream = await RetrieveGotifyApplicationImage(message.AppId, _cancellationToken);
if (imageStream == null || imageStream.Length == 0)
{
Log.Warning("Could not find any application image for notification.");
 
continue;
}
 
var image = new Bitmap(imageStream);
message.Server = gotifyConnectionApplication.Server;
 
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(message, image));
}
 
}, new ExecutionDataflowBlockOptions { CancellationToken = cancellationToken });
 
gotifyApplicationBufferBlock.LinkTo(gotifyApplicationActionBlock,
@@ -448,7 +413,6 @@
await Task.WhenAll(tasks);
gotifyApplicationBufferBlock.Complete();
await gotifyApplicationActionBlock.Completion;
 
}
 
private async Task HeartBeat(CancellationToken cancellationToken)
@@ -462,13 +426,13 @@
_webSocketsClientPingStopWatch.Restart();
if (!_webSocketSharp.Ping())
{
Log.Warning($"Server {_server} did not respond to PING message.");
Log.Warning($"Server {_server.Name} did not respond to PING message.");
continue;
}
 
var delta = _webSocketsClientPingStopWatch.ElapsedMilliseconds;
 
Log.Information($"PING response latency for {_server} is {delta}ms");
Log.Information($"PING response latency for {_server.Name} is {delta}ms");
 
_webSocketsServerResponseScheduledContinuation.Schedule(TimeSpan.FromMinutes(1), OnUnresponsiveServer, _cancellationToken);
} while (!cancellationToken.IsCancellationRequested);
@@ -479,7 +443,7 @@
}
catch (Exception exception)
{
Log.Warning(exception, $"Heartbeat for server {_server} has failed due to {exception.Message}");
Log.Warning(exception, $"Heartbeat for server {_server.Name} has failed.");
}
}
 
@@ -537,17 +501,17 @@
 
try
{
var imageResponse = await _httpClient.GetAsync(applicationImageUri, cancellationToken);
var imageResponse = await _httpClient.GetStreamAsync(applicationImageUri);
 
var memoryStream = new MemoryStream();
 
await imageResponse.Content.CopyToAsync(memoryStream);
await imageResponse.CopyToAsync(memoryStream);
 
return memoryStream;
}
catch (Exception exception)
{
Log.Error($"Could not retrieve application image: {exception.Message}");
Log.Error(exception,"Could not retrieve application image.");
}
}
 
/trunk/Winify/Gotify/GotifyMessageEventArgs.cs
@@ -0,0 +1,26 @@
using System;
using System.Drawing;
 
namespace Winify.Gotify
{
public class GotifyMessageEventArgs : EventArgs
{
#region Constructors, Destructors and Finalizers
 
public GotifyMessageEventArgs(GotifyMessage message, Image image)
{
Message = message;
Image = image;
}
 
#endregion
 
#region Public Enums, Properties and Fields
 
public GotifyMessage Message { get; set; }
 
public Image Image { get; set; }
 
#endregion
}
}
/trunk/Winify/Gotify/GotifyMessageExtras.cs
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json;
 
namespace Winify.Gotify
{
/trunk/Winify/Gotify/GotifyMessageExtrasClientDisplay.cs
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json;
 
namespace Winify.Gotify
{
/trunk/Winify/Gotify/GotifyMessageQuery.cs
@@ -1,10 +1,4 @@
using Newtonsoft.Json;
using Servers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Winify.Gotify
{
/trunk/Winify/Gotify/GotifyPaging.cs
@@ -1,10 +1,4 @@
using Newtonsoft.Json;
using Servers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Winify.Gotify
{