-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExecute C# code.cs
More file actions
211 lines (190 loc) · 7.91 KB
/
Execute C# code.cs
File metadata and controls
211 lines (190 loc) · 7.91 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
using System;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
public class CPHInline
{
private class TCordSearch
{
public string lat { get; set; }
public string lon { get; set; }
public string name { get; set; }
public string display_name { get; set; }
}
public class WeatherInfo
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public double Generationtime_Ms { get; set; }
public int Utc_Offset_Seconds { get; set; }
public string Timezone { get; set; }
public string Timezone_Abbreviation { get; set; }
public double Elevation { get; set; }
public CurrentWeatherUnits Current_Weather_Units { get; set; }
public CurrentWeather Current_Weather { get; set; }
}
public class CurrentWeatherUnits
{
public string Time { get; set; }
public string Interval { get; set; }
public string Temperature { get; set; }
public string Windspeed { get; set; }
public string Winddirection { get; set; }
public string Is_Day { get; set; }
public string Weathercode { get; set; }
}
public class CurrentWeather
{
public string Time { get; set; }
public int Interval { get; set; }
public double Temperature { get; set; }
public double Windspeed { get; set; }
public int Winddirection { get; set; }
public int Is_Day { get; set; }
public int Weathercode { get; set; }
}
private static readonly HttpClient _httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(30)
};
private static readonly string geoSearch = "https://nominatim.openstreetmap.org/search?city={0}&format=json&limit=1";
private static readonly string defaultURL = "https://api.open-meteo.com/v1/forecast?latitude={0}&longitude={1}¤t_weather=true";
private static string defaultCity;
private static string defaultLat;
private static string defaultLon;
public void Init()
{
_httpClient.DefaultRequestHeaders.Clear();
defaultCity = CPH.GetGlobalVar<string>("weather_default_city", true);
defaultLat = CPH.GetGlobalVar<string>("weather_default_lat", true);
defaultLon = CPH.GetGlobalVar<string>("weather_default_lon", true);
LogInfo( string.Format( "Has been loaded with default city: {0}, default Lat: {1}, default Lon: {2}", defaultCity, defaultLat, defaultLon ) );
}
public void Dispose()
{
_httpClient.Dispose();
}
//Functions for logging - added as separate to automatically add name a tag for the command...
private void LogInfo(String LogLine)
{
CPH.LogInfo("[Weather Command] " + LogLine);
}
private void LogError(String LogLine)
{
CPH.LogError("[Weather Command] " + LogLine);
}
// a function that will return the message to same source as the caller came from
// currently only twitch and youtube implemented, if want other source add as else if()
private void SendMessage(string message)
{
CPH.TryGetArg("commandSource", out string commandSource);
switch (commandSource)
{
case "twitch":
CPH.SendMessage(message);
break;
case "youtube":
CPH.SendYouTubeMessage(message);
break;
case "kick":
CPH.SendKickMessage( message );
break;
default:
LogError("Can't send a message - Source Not Implemented");
break;
}
}
//function that translates weather code into a description
//taken from Open-Meteo docs...
public static string GetWeatherDescription(int code)
{
return code switch
{
0 => "Clear sky",
1 or 2 or 3 => "Mainly clear, partly cloudy, and overcast",
45 or 48 => "Fog and depositing rime fog",
51 or 53 or 55 => "Drizzle: Light, moderate, and dense intensity",
56 or 57 => "Freezing Drizzle: Light and dense intensity",
61 or 63 or 65 => "Rain: Slight, moderate and heavy intensity",
66 or 67 => "Freezing Rain: Light and heavy intensity",
71 or 73 or 75 => "Snow fall: Slight, moderate, and heavy intensity",
77 => "Snow grains",
80 or 81 or 82 => "Rain showers: Slight, moderate, and violent",
85 or 86 => "Snow showers: Slight and heavy",
95 => "Thunderstorm: Slight or moderate",
96 or 99 => "Thunderstorm with slight and heavy hail",
_ => "Unknown weather code"
};
}
//generic Post request that expects to return a JSON object of type T ( provided by caller )
public static T PostRequest<T>(string URL)
{
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("CSharpApp/1.0");
string json = _httpClient.GetStringAsync(URL).GetAwaiter().GetResult();
return JsonConvert.DeserializeObject<T>(json);
}
// check if we need to search for the city, if we dont have input city or the input city is same as default city - then apply latitude and longitude from defaults...
// this will work even if you have setup defaultCity without setting up the coordinates...
private static bool doSearch(ref string inputCity, out string lat, out string lon)
{
lat = null;
lon = null;
if (string.IsNullOrWhiteSpace(inputCity) || string.Equals( inputCity, defaultCity, StringComparison.OrdinalIgnoreCase ) )
{
lat = defaultLat;
lon = defaultLon;
inputCity = defaultCity;
}
return string.IsNullOrWhiteSpace(lat) || string.IsNullOrWhiteSpace(lon);
}
public bool Execute()
{
CPH.TryGetArg("messageStripped", out string rawInput);
bool needsSearch = doSearch(ref rawInput, out string lat, out string lon);
//logic check - cant search if we dont have a city...
if (needsSearch && string.IsNullOrWhiteSpace(rawInput))
{
LogError("Can't search without provided city ( defaultCity not setup? )");
return false;
}
if ( needsSearch )
{
try
{
LogInfo( string.Format( "Looking for coordinates of: " + rawInput ) );
string geoSearchURL = string.Format( geoSearch, Uri.EscapeDataString( rawInput ) );
var CordSearchResult = PostRequest<TCordSearch[]>( geoSearchURL );
LogInfo( string.Format( "Number of found cordinate results: " ) + CordSearchResult?.Length );
if ( CordSearchResult?.Length > 0 )
{
( lat, lon, rawInput ) = ( CordSearchResult[ 0 ].lat, CordSearchResult[ 0 ].lon, CordSearchResult[ 0 ].name);
LogInfo( string.Format( "location found: latitude:{0}, Longitude: {1} for city of {2}", lat, lon, rawInput ) );
}
}
catch ( Exception ex )
{
LogError( "Error: " + ex.Message );
}
}
//logic check - cant get weather without Lat/Lon...
if ( string.IsNullOrWhiteSpace( lat ) || string.IsNullOrWhiteSpace( lon ) )
{
LogError( "Latitude/Longitude not found - unable to get weather!" );
return false;
}
try
{
string URL = string.Format( defaultURL, lat, lon );
var weather = PostRequest<WeatherInfo>( URL );
var w = weather.Current_Weather;
string message = $"Weather in {rawInput}: {w.Temperature}°C, Wind: {w.Windspeed} km/h, Direction: {w.Winddirection}°, Condition : {GetWeatherDescription(w.Weathercode)}";
SendMessage( message );
}
catch (Exception ex)
{
LogError("Error: " + ex.Message);
}
return true;
}
}