-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSonarrCommand.cs
343 lines (270 loc) · 17.4 KB
/
SonarrCommand.cs
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
using DSharpPlus.Entities;
using DSharpPlus;
using DSharpPlus.SlashCommands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Text.Json.Nodes;
using static System.Net.WebRequestMethods;
using System.Threading;
using DSharpPlus.CommandsNext;
using DSharpPlus.Interactivity.Extensions;
using XilftenBot;
using System.Net;
namespace XilftenBot
{
/// <summary>
/// Application command for Sonarr
/// </summary>
public class SonarrCommand : ApplicationCommandModule
{
//Application Command for Adding TV Shows to Sonarr
[SlashCommand("TV", "Search for and add TV show!")]
public async Task TVCommand(InteractionContext ctx, [Option("Tv", "Name of Show")] string showName)
{
//Check if Sonarr is Activated.
if (Xilften.sonarrActivated)
{
//Creates a Delayed Response to the Interaction. (Allows us to Respond to the Interaction later by editing the response.)
await ctx.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource);
DiscordChannel channel = ctx.Channel;
DiscordMember member = ctx.Member;
Console.WriteLine($"TV Search Recieved:{showName} by User {member.Username}");
//search to see if show exists.
if (showName != null)
{
try
{
// Create a new HttpClient and Sonarr API request.
using (var httpClient = new HttpClient())
{
// Add API key to request headers.
httpClient.DefaultRequestHeaders.Add("X-Api-Key", Xilften.sonarrAPI);
// Send GET request to Sonarr.
string requestUrl = Xilften.sonarrIP + $"api/v3/series/lookup?term={showName}";
var response = httpClient.GetAsync(requestUrl).Result;
var json = httpClient.GetAsync(requestUrl).Result.Content.ReadAsStringAsync().Result;
// Check if request was successful.
if (response.IsSuccessStatusCode)
{
//Var to hold the JSON response to build Request.(Do not Modify)
string jsonContent = json.ToString();
string path = "";
string imdbId = "";
string monitor = "";
bool searchForMissingEpisodes = true;
bool searchForCutoffUnmetEpisodes = false;
// Deserialize JSON response (many Shows) into an Array.
JArray objArray = JsonConvert.DeserializeObject<JArray>(json);
//Gets the first Show in the Array and converts it to a json string.
var getSeriesObj = objArray[0];
var getSeriesString = getSeriesObj.ToString();
//Use Try Catch to get the values from the JSON so empty doesnt Crash bot.
try { imdbId = getSeriesObj["imdbId"].ToString(); } catch { }
try { path = getSeriesObj["path"].ToString(); } catch { }
try { monitor = getSeriesObj["monitorNewItems"].ToString(); } catch { }
// Deserialize JSON String into a Series Object.
var seriesDeserializedGet = JsonConvert.DeserializeObject<Series>(getSeriesString);
//Create a new Request Object.
var newRequest = new Request
{
memberName = member.Username,
request=showName,
dateMade=DateTime.Now,
title=seriesDeserializedGet.title,
};
//If we have a path, the show is already on the server.
if (path != "")
{
//Create an Embed to send.
var em = new DiscordEmbedBuilder
{
Color = DiscordColor.SpringGreen,
Title = $"{seriesDeserializedGet.title}",
Url = "https://www.imdb.com/title/" + imdbId,
Description = $"Show is already on the server."
};
//If we have an IMDB ID, add it to the Embed.
if (imdbId != "")
{
em.WithUrl("https://www.imdb.com/title/" + imdbId);
}
em.AddField("Added on: ", $"{seriesDeserializedGet.added}", true);
em.AddField("Status: ", $"{seriesDeserializedGet.status}", true);
em.AddField("Network: ", $"{seriesDeserializedGet.network}", true);
em.AddField("First Aired: ", $"{seriesDeserializedGet.firstAired}", true);
em.AddField("Overview: ", $"{seriesDeserializedGet.overview}", false);
em.Build();
//Create the Webhook and add the Embed.
var wh = new DiscordWebhookBuilder();
wh.AddEmbed(em);
//Update if Request was added, and add it to the Requests List.
newRequest.wasAdded = false;
Xilften.WriteToLog($"{member.Username} requested show {seriesDeserializedGet.title} it Existed on the Server.");
Xilften.requests.Add(DateTime.Now, newRequest);
//Update the Interaction Response with the Embed
await ctx.EditResponseAsync(wh);
}
else if (path == "") //If we do not have a path then the show is not on the server, Check to see if we should add it and add it if we should.
{
//Create an Embed to send
var em = new DiscordEmbedBuilder
{
Color = DiscordColor.Red,
Title = $"{seriesDeserializedGet.title}",
Url = "https://www.imdb.com/title/" + imdbId,
Description = $"This show is not on the server."
};
//If we have an IMDB ID, add it to the Embed.
if (imdbId != "")
{
em.WithUrl("https://www.imdb.com/title/" + imdbId);
}
em.AddField("Status: ", $"{seriesDeserializedGet.status}", true);
em.AddField("Network: ", $"{seriesDeserializedGet.network}", true);
em.AddField("First Aired: ", $"{seriesDeserializedGet.firstAired}", true);
em.AddField("Overview: ", $"{seriesDeserializedGet.overview}", false);
em.Build();
//Create the Webhook and add the Embed.
var wh = new DiscordWebhookBuilder();
wh.AddEmbed(em);
//Update if Request was added, and add it to the Requests List.
newRequest.wasAdded = true;
Xilften.WriteToLog($"{member.Username} requested show {seriesDeserializedGet.title} it did not Exist on the Server.");
Xilften.requests.Add(DateTime.Now, newRequest);
//Update the Interaction Response with the Embed
await ctx.EditResponseAsync(wh);
}
{
// Building Embed
var em = new DiscordEmbedBuilder
{
Color = DiscordColor.Red,
Title = $"{seriesDeserializedGet.title}",
Url = "https://www.imdb.com/title/" + imdbId,
Description = $"This show is not on the server."
};
if (imdbId != "")
{
em.WithUrl("https://www.imdb.com/title/" + imdbId);
}
//Choose the Emoji that will be used to react to the Embed
var emoji = DiscordEmoji.FromName(ctx.Client, ":ok_hand:");
em.AddField("Status: ", $"{seriesDeserializedGet.status}", true);
em.AddField("Network: ", $"{seriesDeserializedGet.network}", true);
em.AddField("First Aired: ", $"{seriesDeserializedGet.firstAired}", true);
em.AddField("Overview: ", $"{seriesDeserializedGet.overview}", false);
//Creates a Blank Field to make the Embed look better
em.AddField("\u200b", "\u200b");
Console.WriteLine($"The show {seriesDeserializedGet.title} was added to Sonarr.");
em.AddField($"{member.Username},", $"React with {emoji} within 30 seconds to add {seriesDeserializedGet.title} to the server!", false);
em.Build();
//adding Embed to Webhook
var wh = new DiscordWebhookBuilder();
wh.AddEmbed(em);
//Editing the Response
var message = await ctx.EditResponseAsync(wh);
//waiting for reaction
var result = await message.WaitForReactionAsync(ctx.Member, emoji);
//if reacted to in time Send Add Post to Server
if (!result.TimedOut)
{
string postUrl = Xilften.sonarrIP + $"api/v3/series";
seriesDeserializedGet.rootFolderPath = Xilften.sonarrRootPath;
seriesDeserializedGet.SetAddOptions(searchForMissingEpisodes, monitor, searchForCutoffUnmetEpisodes);
string updatedPost = JsonConvert.SerializeObject(seriesDeserializedGet, Formatting.Indented);
var payload = new StringContent(updatedPost, Encoding.UTF8, "application/json");
var postResponse = httpClient.PostAsync(postUrl, payload).Result.Content.ReadAsStringAsync();
var postResults = postResponse.Result;
//Here we check to see if post returned successfully
if (postResponse.IsCompletedSuccessfully)
{
Console.WriteLine("Post sent and response Recieved Successfully. ");
await ctx.Channel.SendMessageAsync($"The show {seriesDeserializedGet.title} is adding to the server. Allow 1 hour per season for it to update");
newRequest.wasAdded = true;
Xilften.WriteToLog($"{member.Username} requested show {seriesDeserializedGet.title} it Existed on the Server.");
Xilften.requests.Add(DateTime.Now, newRequest);
Console.WriteLine(Xilften.requests.ToString());
}
else //If not successful sernd error message
{
Console.WriteLine("Post sent and response Recieved Error. ");
await ctx.Channel.SendMessageAsync("There was an error adding the show");
newRequest.wasAdded = false;
Xilften.WriteToLog($"{member.Username} requested show {seriesDeserializedGet.title}, but there was an error. The Post did not complete Successfully.");
Xilften.requests.Add(DateTime.Now, newRequest);
}
}
}
}
else //The post failed to send send error message.
{
Console.WriteLine("Failed to ping Sonarr. Status code: " + response.StatusCode);
await ctx.Channel.SendMessageAsync("There was an error adding the show");
Xilften.WriteToLog($"{member.Username} requested show {showName} but the Post Results were Unsuccessful.");
}
}
}
catch (Exception ex)// There is no connection to Sonarr Send Error Message.
{
Console.WriteLine($"Error Message: {ex.Message}");
await ctx.Channel.SendMessageAsync("There was an error adding the show");
Xilften.WriteToLog($"{member.Username} requested show {showName} But it Failed to establish a connection to Sonarr. Error message: {ex.Message}.");
}
}
}
else //Sonarr Is not active on this server send error message.(Likely Missing the Sonarr API Key or Sonarr IP)
{
await ctx.Channel.SendMessageAsync("Sonarr is not active on this Server.");
Xilften.WriteToLog($"{ctx.Member.Username} requested show {showName} but Sonarr is not activated on this Server.");
}
}
//Command to Restart Sonarr
[SlashCommand("RestartSonarr", "Restart the Sonarr Server!")]
public async Task RestartSonarrCommand(InteractionContext ctx)
{
DiscordMember user = ctx.Member;
DiscordChannel channel = ctx.Channel;
// Check if user has permission to use this command
if (user.Permissions.HasPermission(Permissions.Administrator))
{
// Send request to Sonarr to restart
using (var httpClient = new HttpClient())
{
// Add API key to request headers
httpClient.DefaultRequestHeaders.Add("X-Api-Key", Xilften.sonarrAPI);
// Send Post request to Sonarr
string requestUrl = Xilften.sonarrIP + $"api/v3/system/restart";
var payload = new StringContent("", Encoding.UTF8, "application/json");
var response = httpClient.PostAsync(requestUrl, payload).Result;
// Check if request was successful
if (response.IsSuccessStatusCode)
{
//Create the and build the Embed
var em = new DiscordEmbedBuilder
{
Color = DiscordColor.Azure,
Title = $"Sonarr Reseting",
Description = $"Please Allow a Few Minutes."
};
em.Build();
//Send the Embed in a private message
await channel.SendMessageAsync(embed: em);
}
else
{
//If request Unsuccessful send error message
await channel.SendMessageAsync("Error Reseting Sonarr");
}
}
}
}
}
}