Compare commits

9 Commits

4 changed files with 94 additions and 20 deletions

View File

@@ -13,12 +13,17 @@
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="StackExchange.Redis" Version="2.8.16" /> <PackageReference Include="StackExchange.Redis" Version="2.8.16" />
<PackageReference Include="TMDbLib" Version="2.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="appSettings.json"> <None Update="appSettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="TMDbLib">
<HintPath>..\Libraries\TMDbLib.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View File

@@ -8,12 +8,12 @@ namespace AnimeAnnouncer.Cache
public int LatestSeasonNumber { get; set; } public int LatestSeasonNumber { get; set; }
public int LastEpisodeNumber { get; set; } public int LastEpisodeNumber { get; set; }
public string? PosterPath { get; internal set; } public string? PosterPath { get; set; }
public string? BackdropPath { get; internal set; } public string? BackdropPath { get; set; }
public string? LatestSeasonPosterPath { get; internal set; } public string? LatestSeasonPosterPath { get; set; }
public string? LatestSeasonOverview { get; internal set; } public string? LatestSeasonOverview { get; set; }
public double VoteAverage { get; internal set; } public double VoteAverage { get; set; }
public string? Overview { get; internal set; } public string? Overview { get; set; }
public int? LatestOrdinalEpisodeNumber { get; internal set; } public int? LatestOrdinalEpisodeNumber { get; set; }
} }
} }

View File

@@ -7,6 +7,7 @@ using Mastonet;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using TMDbLib.Client; using TMDbLib.Client;
using TMDbLib.Objects.Authentication;
namespace AnimeAnnouncer namespace AnimeAnnouncer
{ {
@@ -144,9 +145,24 @@ namespace AnimeAnnouncer
latestEpisodeNumber = latestSeason.EpisodeCount; latestEpisodeNumber = latestSeason.EpisodeCount;
//if nearing the end of a season, confirm it's marked with season finale
if(int.Parse(episode) >= (latestEpisodeNumber - 2))
{
var latestSeasonDetail = await tmdbClient.GetTvSeasonAsync(supposedShowId, latestSeasonNumber);
var seasonFinale = latestSeasonDetail.Episodes.LastOrDefault(e => e.EpisodeType.Equals("finale", StringComparison.InvariantCultureIgnoreCase));
if(seasonFinale != null && seasonFinale.EpisodeNumber != latestEpisodeNumber)
{
Console.WriteLine($"Overriding previous finale choice of {latestEpisodeNumber} due to season detail response where it's {seasonFinale.EpisodeNumber}");
latestEpisodeNumber = seasonFinale.EpisodeNumber;
}
}
if(showResult.Seasons.Count > 1) if(showResult.Seasons.Count > 1)
{ {
latestOrdinalEpisodeNumber = showResult.Seasons.Sum(s => s.EpisodeCount); latestOrdinalEpisodeNumber = showResult.Seasons.Where(s => s.SeasonNumber != 0).Sum(s => s.EpisodeCount);
} }
if(tmdbCache != null && searchResults != null) if(tmdbCache != null && searchResults != null)
@@ -164,8 +180,8 @@ namespace AnimeAnnouncer
Overview = showResult.Overview, Overview = showResult.Overview,
VoteAverage = showResult.VoteAverage, VoteAverage = showResult.VoteAverage,
ShowID = supposedShowId, ShowID = supposedShowId,
LatestSeasonNumber = latestSeason.SeasonNumber, LatestSeasonNumber = latestSeasonNumber,
LastEpisodeNumber = latestSeason.EpisodeCount LastEpisodeNumber = latestEpisodeNumber
}; };
_ = tmdbCache.SetCacheItem($"ShowCache-{title}", cachedShow); _ = tmdbCache.SetCacheItem($"ShowCache-{title}", cachedShow);
Console.WriteLine($"{title} Added to cache"); Console.WriteLine($"{title} Added to cache");
@@ -181,8 +197,42 @@ namespace AnimeAnnouncer
if(latestSeasonNumber != int.Parse(season)) if(latestSeasonNumber != int.Parse(season))
{ {
Console.WriteLine($"Failing release due to TMDB's season number {latestSeasonNumber} not matching title season {season}"); var titleSeason = int.Parse(season);
return; bool seasonOverride = false;
if(latestSeasonNumber ==1 && titleSeason > 1 && latestEpisodeNumber > 3)
{ //Check episode groups to see if this is a single-season default show
var showResult = await tmdbClient.GetTvShowAsync(supposedShowId, TMDbLib.Objects.TvShows.TvShowMethods.EpisodeGroups);
var seasonEpisodeGroup = showResult.EpisodeGroups.Results.FirstOrDefault(eg => eg.Name == "Seasons");
if(seasonEpisodeGroup != null)
{ //Evaluate using new episode group
var targetEpisodeGroup = await tmdbClient.GetTvEpisodeGroupsAsync(seasonEpisodeGroup.Id);
if(targetEpisodeGroup != null)
{
var targetSeason = targetEpisodeGroup.Groups.FirstOrDefault(g => g.Order == titleSeason);
if(targetSeason != null)
{ //Episode_Type isn't making it with the current client, guess based on ordering
var targetFinale = targetSeason.Episodes.OrderByDescending(g => g.Order).FirstOrDefault(e => e.EpisodeType.Equals("finale", StringComparison.InvariantCultureIgnoreCase));
//Confirm it's aired within the last week
if(targetFinale != null && targetEpisodeGroup.Groups.OrderByDescending(g => g.Order).FirstOrDefault() == targetSeason)
{ //confirm the episode is marked as finale and that this season is the latest one in the episode group
Console.WriteLine($"!!Choosing S{titleSeason}E{targetFinale.Order + 1} for finale using episode groups");
cachedShow.LatestSeasonNumber = latestSeasonNumber = titleSeason;
cachedShow.LastEpisodeNumber = latestEpisodeNumber = targetFinale.Order + 1;
seasonOverride = true;
_ = tmdbCache.SetCacheItem($"ShowCache-{title}", cachedShow);
}
else
Console.WriteLine("Could not find a finale episode.");
}
}
}
}
if(!seasonOverride)
{
Console.WriteLine($"Failing release due to TMDB's season number {latestSeasonNumber} not matching title season {season}");
return;
}
} }
if(latestEpisodeNumber != int.Parse(episode)) if(latestEpisodeNumber != int.Parse(episode))
@@ -193,6 +243,12 @@ namespace AnimeAnnouncer
return; return;
} }
} }
//Sometimes TMDB metadata hasn't been filled in yet
if(latestEpisodeNumber < 3)
{
Console.WriteLine("Skipping announcement due to a low episode number");
return;
}
// Announce if unique // Announce if unique
if(await tmdbCache.KeyExists($"ShowAnnounced-{supposedShowId}")) if(await tmdbCache.KeyExists($"ShowAnnounced-{supposedShowId}"))
@@ -235,16 +291,21 @@ namespace AnimeAnnouncer
//Prepare Status //Prepare Status
String statusText = $"{cachedShow.Title} ({cachedShow.VoteAverage}/10) DUBBED has finished airing season {cachedShow.LatestSeasonNumber}! Episode {cachedShow.LastEpisodeNumber} is now available for download. {Environment.NewLine + Environment.NewLine}"; String statusText = $"{cachedShow.Title} ({cachedShow.VoteAverage}/10) DUBBED has finished airing season {cachedShow.LatestSeasonNumber}! Episode {cachedShow.LastEpisodeNumber} is now available for download. {Environment.NewLine + Environment.NewLine}";
String overview = !String.IsNullOrWhiteSpace(cachedShow.LatestSeasonOverview) ? cachedShow.LatestSeasonOverview : cachedShow.Overview ?? String.Empty; String overview = !String.IsNullOrWhiteSpace(cachedShow.LatestSeasonOverview) ? cachedShow.LatestSeasonOverview : cachedShow.Overview ?? String.Empty;
if(!String.IsNullOrWhiteSpace(overview)) if (!String.IsNullOrWhiteSpace(overview))
{ {
statusText += $"Overview: {overview}"; statusText += $"{overview}";
} }
if(statusText.Length >= 500) String anidbLink = $"{Environment.NewLine}https://anilist.co/search/anime?search={cachedShow.Title.Replace(" ", "%20")}";
int linkLength = anidbLink.Length;
if (statusText.Length + linkLength + 3 >= 500)
{ {
statusText = statusText[..497] + ".."; statusText = statusText[..(500 - (linkLength + 3))];
} }
_ = mastodonClient.PublishStatus(statusText, statusText += $"..{anidbLink}";
Visibility.Public, mediaIds: attachment != null ? new String[] {attachment.Id} : null);
_ = mastodonClient.PublishStatus(statusText,
Visibility.Public, mediaIds: attachment != null ? new String[] { attachment.Id } : null);
} }
} }

View File

@@ -22,7 +22,7 @@ namespace MassTorrentAdd
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) .SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); .AddJsonFile("appSettings.json", optional: false, reloadOnChange: true);
IConfigurationRoot configuration = builder.Build(); IConfigurationRoot configuration = builder.Build();
transmissionHost = configuration.GetValue<String>("transmissionURI"); transmissionHost = configuration.GetValue<String>("transmissionURI");
@@ -94,6 +94,14 @@ namespace MassTorrentAdd
Metainfo = Convert.ToBase64String(torrentFileData) Metainfo = Convert.ToBase64String(torrentFileData)
}; };
var torrentInfo = transmissionClient.TorrentAdd(newTorrent); var torrentInfo = transmissionClient.TorrentAdd(newTorrent);
var seedSettings = new Transmission.API.RPC.Arguments.TorrentSettings()
{
SeedRatioLimit = 1.0,
SeedRatioMode = 1,
IDs = [torrentInfo.ID]
};
transmissionClient.TorrentSet(seedSettings);
//transmissionClient.TorrentVerify(new object[] { torrentInfo.ID }); //transmissionClient.TorrentVerify(new object[] { torrentInfo.ID });
} }