aboutsummaryrefslogtreecommitdiff
path: root/Sites/PagerMon.cs
blob: 4d193547c9603eb4b6a66e1c84082753db4bce3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using SocketIOClient;
using System;
using System.Text.Json;

namespace PagerParser.PagerProviders;

// Interface class for fetching pager messages from PagerMon
// sites such as Jobyyy over HTTP.
[PagerProvider]
public class PagerMon : IPagerProvider {
    private record PagerMonMessage {
        public long   Timestamp { get; set; }
        public string Message   { get; set; }

        public PagerMessage PagerMessage => new PagerMessage() {
            Timestamp = DateTimeOffset.FromUnixTimeSeconds(Timestamp).UtcDateTime,
            Message   = Message
        };
    }

    private record PagerMonQueryResponse {
        public PagerMonMessage[] Messages { get; set; }
    }

    public event EventHandler        OnConnect;
    public event PagerMessageHandler OnPagerMessage;

    private const string QueryBaseUrl =
        "https://jobyyy.net/api/messages";

    private HttpClient httpClient = new();

    private SocketIO socketIOClient;

    public PagerMon() {
        socketIOClient = new SocketIO("https://jobyyy.net/", new SocketIOOptions() {
            Transport   = SocketIOClient.Transport.TransportProtocol.WebSocket,
            AutoUpgrade = false,
            EIO         = EngineIO.V3
        });

        socketIOClient.OnConnected += (sender, e) =>
            OnConnect?.Invoke(this, e);

        socketIOClient.On("messagePost", PagerMessageReceived);
    }

    public void Connect() =>
        socketIOClient.ConnectAsync().GetAwaiter().GetResult();

    public void Disconnect() =>
        socketIOClient.DisconnectAsync().GetAwaiter().GetResult();

    public PagerMessage[] Fetch() {
        List<PagerMessage> messages = new();

        var result = httpClient
            .GetFromJsonAsync<PagerMonQueryResponse>($"{QueryBaseUrl}?limit=120")
            .GetAwaiter()
            .GetResult();

        if(result is null)
            return Array.Empty<PagerMessage>();

        return result.Messages
            .Select(m => m.PagerMessage)
            .ToArray();
    }

    public async Task<PagerMessage[]> FetchAsync(CancellationToken ct, DateTime until) {
        List<PagerMessage> pagerMessages = new();

        int page = 1;

        while(!ct.IsCancellationRequested) {
            PagerMonQueryResponse? result;
            try {
                result = await httpClient
                .GetFromJsonAsync<PagerMonQueryResponse>($"{QueryBaseUrl}?limit=120&page={page}");
            } catch {
                break;
            }

            if(result is null || result.Messages.Count() == 0)
                break;

            var messages = result.Messages
                .Select(m => m.PagerMessage)
                .OrderBy(m => m.Timestamp)
                .ToArray();

            pagerMessages.AddRange(messages);

            if(messages[0].Timestamp <= until)
                break;

            page++;
        }

        return pagerMessages.ToArray();
    }

    private void PagerMessageReceived(SocketIOResponse resp) {
        var message = JsonSerializer.Deserialize<PagerMonMessage>(
            resp.GetValue(),
            new JsonSerializerOptions() {
                PropertyNameCaseInsensitive = true
            });

        if(message is null)
            return;

        OnPagerMessage?.Invoke(this, new() {
            Message = message.PagerMessage
        });
    }
}