Added Anilist datasource; Handled bug when two-posts were not enough for monthly airing post

This commit is contained in:
2026-08-31 21:36:21 -04:00
parent 8dcc153806
commit e336b2ae08
4 changed files with 93 additions and 3 deletions
+48
View File
@@ -0,0 +1,48 @@
using Mastonet.Entities;
namespace AnimeAnnouncer;
using Kavita.AniListNet; // Contains base classes for interacting with the API
using Kavita.AniListNet.Parameters; // Contains classes for mutation and filtering
using Kavita.AniListNet.Objects; // Contains model classes for handling data
public class Anilist
{
public String Token { get; set; }
private AniClient client;
public Anilist(String token)
{
Token = token;
client = new AniClient();
Task.WaitAll(Authenticate());
}
public async Task<Media> RetrieveAiringShowInformation(String showName)
{
var results = await client.SearchMediaAsync(new SearchMediaFilter
{
Query = showName, // The term to search for
Type = MediaType.Anime, // Filters search results to anime only
Sort = MediaSort.Popularity, // Sorts them by popularity
Format = new Dictionary<MediaFormat, bool>
{
{ MediaFormat.TV, true }, // Set to only search for TV shows and movies
{ MediaFormat.Movie, true },
{ MediaFormat.TVShort, false } // Set to not show TV shorts
}
});
int currentYear = DateTime.Now.Year;
var result = results.Data.Where(p => p.SeasonYear >= currentYear).OrderByDescending(p => p.StartDate).First();
return result;
}
private async Task Authenticate()
{
Boolean success = await client.TryAuthenticateAsync(Token);
if (!success)
throw new Exception("Unable to authenticate with AniList!");
}
}
+4
View File
@@ -19,5 +19,9 @@ namespace AnimeAnnouncer.Cache
public DateTime? LastAirDate { get; set; } public DateTime? LastAirDate { get; set; }
//This is the latest episode number to air, NOT the last episode in the series //This is the latest episode number to air, NOT the last episode in the series
public int? LatestEpisodeNumber { get; set; } public int? LatestEpisodeNumber { get; set; }
public Boolean? AnilistPopulated { get; set; }
public String? AnilistPosterPath { get; set; }
} }
} }
+39 -1
View File
@@ -20,6 +20,7 @@ namespace AnimeAnnouncer
private static TMDbClient tmdbClient; private static TMDbClient tmdbClient;
private static TMDBCache tmdbCache; private static TMDBCache tmdbCache;
private static MastodonClient mastodonClient; private static MastodonClient mastodonClient;
private static Anilist? anilistClient;
private static List<AiringSoonItem> airingSoonList; private static List<AiringSoonItem> airingSoonList;
static void Main(string[] args) static void Main(string[] args)
@@ -56,6 +57,11 @@ namespace AnimeAnnouncer
mastodonClient = new MastodonClient(mastodonInstance, mastodonToken); mastodonClient = new MastodonClient(mastodonInstance, mastodonToken);
} }
String anilistToken = config["AnilistToken"];
if (!String.IsNullOrEmpty(anilistToken))
anilistClient = new Anilist(anilistToken);
airingSoonList = tmdbCache.GetAiringList().Result; airingSoonList = tmdbCache.GetAiringList().Result;
if(airingSoonList == null) if(airingSoonList == null)
@@ -205,9 +211,26 @@ namespace AnimeAnnouncer
lastEpisodeNumber = seasonFinale.EpisodeNumber; lastEpisodeNumber = seasonFinale.EpisodeNumber;
} }
finaleConfirmed = true; finaleConfirmed = true;
if (!lastAirDate.HasValue)
lastAirDate = seasonFinale.AirDate ?? DateTime.Now;
} }
} }
//potentially override TMDB episode count with more reliable anilist data
string? anilistPosterPath = null;
if (latestEpisodeNumber > 3 && anilistClient != null)
{
Console.WriteLine("Looking up Anilist title " + title);
var anilistMedia = await anilistClient.RetrieveAiringShowInformation(title);
if (anilistMedia.Episodes.HasValue && anilistMedia.Episodes != lastEpisodeNumber)
{
Console.WriteLine($"Overriding episode count of {lastEpisodeNumber} using Anilist's showID {anilistMedia.Id} titled {anilistMedia.Title.EnglishTitle} with {anilistMedia.Episodes} episodes.");
lastEpisodeNumber = anilistMedia.Episodes.Value;
}
anilistPosterPath = anilistMedia.BannerImageUrl?.ToString();
}
if(showResult.Seasons.Count > 1) if(showResult.Seasons.Count > 1)
{ {
latestOrdinalEpisodeNumber = showResult.Seasons.Where(s => s.SeasonNumber != 0).Sum(s => s.EpisodeCount); latestOrdinalEpisodeNumber = showResult.Seasons.Where(s => s.SeasonNumber != 0).Sum(s => s.EpisodeCount);
@@ -236,7 +259,9 @@ namespace AnimeAnnouncer
LatestSeasonNumber = latestSeasonNumber, LatestSeasonNumber = latestSeasonNumber,
LastEpisodeNumber = lastEpisodeNumber, LastEpisodeNumber = lastEpisodeNumber,
LastAirDate = lastAirDate, LastAirDate = lastAirDate,
LatestEpisodeNumber = latestEpisodeNumber LatestEpisodeNumber = latestEpisodeNumber,
AnilistPopulated = anilistPosterPath != null,
AnilistPosterPath = anilistPosterPath
}; };
_ = tmdbCache.SetCacheItem($"ShowCache-{title}", cachedShow); _ = tmdbCache.SetCacheItem($"ShowCache-{title}", cachedShow);
Console.WriteLine($"{title} Added to cache"); Console.WriteLine($"{title} Added to cache");
@@ -380,7 +405,20 @@ namespace AnimeAnnouncer
var statusOne = await mastodonClient.PublishStatus(postOne, var statusOne = await mastodonClient.PublishStatus(postOne,
Visibility.Public, null); Visibility.Public, null);
if (postTwo.Length > 500)
{
lineBreakIdx = 500 - new string(postTwo.Take(500).Reverse().ToArray()).IndexOf(Environment.NewLine);
String postThree = postTwo.Substring(lineBreakIdx);
postTwo = postTwo.Substring(0, lineBreakIdx);
var statusTwo = await mastodonClient.PublishStatus(postTwo, Visibility.Public, statusOne.Id); var statusTwo = await mastodonClient.PublishStatus(postTwo, Visibility.Public, statusOne.Id);
Thread.Sleep(1000);
var statusThree = await mastodonClient.PublishStatus(postThree, Visibility.Public, statusTwo.Id);
}
else
{
var statusTwo = await mastodonClient.PublishStatus(postTwo, Visibility.Public, statusOne.Id);
}
}else }else
{ {
_ = mastodonClient.PublishStatus(statusText, _ = mastodonClient.PublishStatus(statusText,
+1 -1
View File
@@ -1,2 +1,2 @@
docker build --pull --rm -f "AnimeAnnouncer/Dockerfile" -t dtr.chrispr.org/animeannouncer:latest . docker build -f "AnimeAnnouncer/Dockerfile" -t dtr.chrispr.org/animeannouncer:latest .
docker push dtr.chrispr.org/animeannouncer:latest docker push dtr.chrispr.org/animeannouncer:latest