Added Anilist datasource; Handled bug when two-posts were not enough for monthly airing post
This commit is contained in:
@@ -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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,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
|
||||||
|
|||||||
Reference in New Issue
Block a user