Skip to content

Commit 3f64a6a

Browse files
committed
Fix: Properly account for a series new to shoko
The webhook should now actually be updated, after a file is matched where a series does not yet exist Misc: Minor code cleanup
1 parent ef1e6ea commit 3f64a6a

File tree

3 files changed

+66
-38
lines changed

3 files changed

+66
-38
lines changed

Apis/DiscordHelper.cs

+35-11
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,19 @@ public async Task<string> SendWebhook(IVideo video, AniDBSearchResult searchResu
5757
}
5858
}
5959

60-
public async Task PatchWebhook(IVideo video, ISeries anime, IEpisode episode, MemoryStream imageStream, string messageId)
60+
#nullable enable
61+
public async Task PatchWebhook(IVideo video, ISeries anime, IEpisode episode, MemoryStream? imageStream, string messageId)
6162
{
6263
Logger.Info(CultureInfo.InvariantCulture, "Attempting to update Discord message (fileId={fileId}, messageId={messageId})", video.ID, messageId);
6364

6465
try
6566
{
67+
if (imageStream == null)
68+
{
69+
await PatchWebhook(video, anime, episode, messageId);
70+
return;
71+
}
72+
6673
MultipartFormDataContent form = new();
6774

6875
var webhook = GetMatchedWebhook(video, anime, episode);
@@ -90,6 +97,22 @@ public async Task PatchWebhook(IVideo video, ISeries anime, IEpisode episode, Me
9097
}
9198
}
9299

100+
public async Task PatchWebhook(IVideo video, ISeries anime, IEpisode episode, string messageId)
101+
{
102+
try {
103+
var webhook = GetMatchedWebhook(video, anime, episode, false);
104+
105+
var response = await _httpClient.PatchAsJsonAsync($"{_baseUrl}/messages/{messageId}", webhook, _options);
106+
_ = response.EnsureSuccessStatusCode();
107+
}
108+
catch (Exception ex)
109+
{
110+
// TODO: More logging
111+
Logger.Debug("Exception: {ex}", ex);
112+
}
113+
}
114+
#nullable disable
115+
93116
private Webhook GetUnmatchedWebhook(IVideo video, AniDBSearchResult searchResult)
94117
{
95118
UriBuilder publicUrl = new(_settings.Shoko.PublicUrl)
@@ -124,13 +147,22 @@ private Webhook GetUnmatchedWebhook(IVideo video, AniDBSearchResult searchResult
124147
};
125148
}
126149

127-
private Webhook GetMatchedWebhook(IVideo video, ISeries anime, IEpisode episode)
150+
private Webhook GetMatchedWebhook(IVideo video, ISeries anime, IEpisode episode, bool includePoster = true)
128151
{
129152
UriBuilder publicUrl = new(_settings.Shoko.PublicUrl)
130153
{
131154
Port = _settings.Shoko.PublicPort ?? -1
132155
};
133156

157+
var webhookAttachments = includePoster ? (WebhookAttachment[])[
158+
new WebhookAttachment
159+
{
160+
Id = 0,
161+
Description = "Anime Poster",
162+
Filename = "unknown.jpg"
163+
}
164+
] : [];
165+
134166
return new Webhook()
135167
{
136168
Username = _settings.Webhook.Username,
@@ -152,15 +184,7 @@ private Webhook GetMatchedWebhook(IVideo video, ISeries anime, IEpisode episode)
152184
Footer = GetFooter(video)
153185
}
154186
],
155-
Attachments =
156-
[
157-
new WebhookAttachment
158-
{
159-
Id = 0,
160-
Description = "Anime Poster",
161-
Filename = "unknown.jpg"
162-
}
163-
]
187+
Attachments = webhookAttachments
164188
};
165189
}
166190

Apis/ShokoHelper.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ public async Task ScanFileById(int fileId)
119119
}
120120
}
121121

122-
public async Task<Image> GetSeriesPoster(ISeries anime)
122+
#nullable enable
123+
public async Task<Image?> GetSeriesPoster(ISeries anime)
123124
{
124125
try
125126
{
@@ -132,9 +133,10 @@ public async Task<Image> GetSeriesPoster(ISeries anime)
132133
{
133134
Logger.Warn(CultureInfo.InvariantCulture, "Poster could not be downloaded for series ID: {animeId}", anime.ID);
134135
Logger.Debug("Exception: {ex}", ex);
135-
return null;
136136
}
137+
return null;
137138
}
139+
#nullable disable
138140

139141
public async Task<MemoryStream> GetImageStream(Image shokoImage)
140142
{

WebhookDump.cs

+27-25
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class WebhookDump : IPlugin
2626

2727
private readonly FileTracker _fileTracker;
2828

29-
private readonly HashSet<int> _episodesMissingReferences = [];
29+
private readonly HashSet<int> _anidbTrackedEpisodeIds = [];
3030

3131
public static void ConfigureServices(IServiceCollection services)
3232
{
@@ -95,23 +95,27 @@ private void OnFileNotMatched(object sender, FileNotMatchedEventArgs fileNotMatc
9595
private void OnFileMatched(object sender, FileEventArgs fileMatchedEvent)
9696
{
9797
var video = fileMatchedEvent.Video;
98+
var series = fileMatchedEvent.Series;
9899
var episodes = fileMatchedEvent.Episodes;
99100

100-
if (video.CrossReferences.Count == 0 && episodes.Count > 0)
101+
if (episodes.Count == 0 && series.Count == 0)
101102
{
102-
_episodesMissingReferences.Add(episodes[0].ID);
103+
foreach (var crossReference in video.CrossReferences)
104+
_anidbTrackedEpisodeIds.Add(crossReference.AnidbEpisodeID);
103105
return;
104106
}
105107

106-
if (fileMatchedEvent.Series.Count == 0 || fileMatchedEvent.Episodes.Count == 0)
108+
if (episodes.Count == 0 || series.Count == 0) // This is just a safeguard...
107109
{
108-
Logger.Debug($"I don't think this should ever be seen, but if it is... Let @fearnlj01 know it can happen (please).");
110+
// I don't know in what circumstance this code will execute...
111+
Logger.Error("I don't think this should ever be seen, but if it is... Let @fearnlj01 know it can happen (please).");
109112
return;
110113
}
111114

112-
AttemptMatchedUpdate(fileMatchedEvent.Series[0], fileMatchedEvent.Episodes[0], video);
115+
AttemptMatchedUpdate(series[0], episodes[0], video);
113116
}
114117

118+
#nullable enable
115119
private async void AttemptMatchedUpdate(ISeries series, IEpisode episode, IVideo video)
116120
{
117121
if (
@@ -126,7 +130,7 @@ private async void AttemptMatchedUpdate(ISeries series, IEpisode episode, IVideo
126130
try
127131
{
128132
var poster = await _shokoHelper.GetSeriesPoster(series);
129-
var imageStream = await _shokoHelper.GetImageStream(poster);
133+
var imageStream = poster != null ? await _shokoHelper.GetImageStream(poster) : null;
130134

131135
await _discordHelper.PatchWebhook(video, series, episode, imageStream, messageId);
132136
_messageTracker.TryRemoveMessage(video.ID);
@@ -136,19 +140,16 @@ private async void AttemptMatchedUpdate(ISeries series, IEpisode episode, IVideo
136140
Logger.Debug("Exception: {ex}", ex);
137141
}
138142
}
143+
#nullable disable
139144

140145
private async void OnAVDumpEvent(object sender, AVDumpEventArgs dumpEvent)
141146
{
142147
if (dumpEvent.Type != AVDumpEventType.Success || !_settings.Webhook.Enabled)
143148
return;
144149

145-
for (var i = 0; i < dumpEvent.VideoIDs?.Count && i < dumpEvent.ED2Ks?.Count; i++)
150+
foreach (var videoId in dumpEvent.VideoIDs ?? Array.Empty<int>())
146151
{
147-
var ed2K = dumpEvent.ED2Ks[i];
148-
var fileId = dumpEvent.VideoIDs[i];
149-
150-
if (!_fileTracker.TryGetValue(fileId, out var video))
151-
continue;
152+
if (!_fileTracker.TryGetValue(videoId, out var video)) continue;
152153

153154
var searchResult = await _shokoHelper.MatchTitle(video.EarliestKnownName);
154155

@@ -174,27 +175,28 @@ private async void OnAVDumpEvent(object sender, AVDumpEventArgs dumpEvent)
174175
});
175176

176177
searchResult.List = searchResult.List.Take(3).ToList();
177-
var messageId = await _discordHelper.SendWebhook(video, ed2K, searchResult);
178+
var messageId = await _discordHelper.SendWebhook(video, searchResult);
178179

179180
_ = _messageTracker.TryAddMessage(video.ID, messageId);
180181
}
181182
}
182183

183184
private void OnEpisodeUpdatedEvent(object sender, EpisodeInfoUpdatedEventArgs episodeInfoUpdatedEvent)
184185
{
185-
var episodeInfo = episodeInfoUpdatedEvent.EpisodeInfo;
186-
var updateReason = episodeInfoUpdatedEvent.Reason;
187-
var seriesInfo = episodeInfoUpdatedEvent.SeriesInfo;
186+
if (episodeInfoUpdatedEvent.Reason is not (UpdateReason.Added or UpdateReason.Updated)) return;
188187

189-
if (!_episodesMissingReferences.Contains(episodeInfo.ID) || episodeInfo.VideoList.Count == 0 ||
190-
(updateReason != UpdateReason.Added && updateReason != UpdateReason.Updated)
191-
)
192-
{
193-
return;
194-
}
188+
var episode = episodeInfoUpdatedEvent.EpisodeInfo;
189+
var series = episodeInfoUpdatedEvent.SeriesInfo;
190+
191+
var anidbEpisodeIds = episode.CrossReferences.Select(reference => reference.AnidbEpisodeID).ToHashSet();
192+
193+
if (episode.VideoList.Count == 0) return;
194+
195+
var removedLog = anidbEpisodeIds.Select(eid => _anidbTrackedEpisodeIds.Remove(eid)).ToList();
196+
if (!removedLog.Any(removedBool => removedBool)) return;
195197

196-
AttemptMatchedUpdate(seriesInfo, episodeInfo, episodeInfo.VideoList[0]);
197-
_episodesMissingReferences.Remove(episodeInfo.ID);
198+
Logger.Debug("Attempting to update webhook by episode added/updated.");
199+
AttemptMatchedUpdate(series, episode, episode.VideoList[0]);
198200
}
199201

200202
private async Task WaitForRescan(IVideo video, int matchAttempts = 1)

0 commit comments

Comments
 (0)