public string RemoveLinkAniDBTvDBEpisode(int aniDBEpisodeID, int tvDBEpisodeID) { try { AniDB_Episode ep = RepoFactory.AniDB_Episode.GetByEpisodeID(aniDBEpisodeID); if (ep == null) { return("Could not find Episode"); } CrossRef_AniDB_TvDB_Episode_Override xref = RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.GetByAniDBAndTvDBEpisodeIDs(aniDBEpisodeID, tvDBEpisodeID); if (xref == null) { return("Could not find Link!"); } RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.Delete(xref.CrossRef_AniDB_TvDB_Episode_OverrideID); return(string.Empty); } catch (Exception ex) { logger.Error(ex, ex.ToString()); return(ex.Message); } }
public static void LinkAniDBTvDBEpisode(int aniDBID, int tvDBID) { CrossRef_AniDB_TvDB_Episode_Override xref = RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.GetByAniDBAndTvDBEpisodeIDs(aniDBID, tvDBID) ?? new CrossRef_AniDB_TvDB_Episode_Override(); xref.AniDBEpisodeID = aniDBID; xref.TvDBEpisodeID = tvDBID; RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.Save(xref); SVR_AnimeEpisode ep = RepoFactory.AnimeEpisode.GetByAniDBEpisodeID(aniDBID); SVR_AniDB_Anime.UpdateStatsByAnimeID(ep.AniDB_Episode.AnimeID); RepoFactory.AnimeEpisode.Save(ep); logger.Trace($"Changed tvdb episode association: {aniDBID}"); }
public List <CrossRef_AniDB_TvDBV2> GetV2LinksFromAnime(int animeID) { var overrides = RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.GetByAnimeID(animeID); var normals = RepoFactory.CrossRef_AniDB_TvDB_Episode.GetByAnimeID(animeID); List <(int anidb_episode, int tvdb_episode)> ls = new List <(int anidb_episode, int tvdb_episode)>(); foreach (CrossRef_AniDB_TvDB_Episode epo in normals) { CrossRef_AniDB_TvDB_Episode_Override ov = overrides.FirstOrDefault(a => a.AniDBEpisodeID == epo.AniDBEpisodeID); if (ov != null) { ls.Add((ov.AniDBEpisodeID, ov.TvDBEpisodeID)); overrides.Remove(ov); } else { ls.Add((epo.AniDBEpisodeID, epo.TvDBEpisodeID)); } } foreach (CrossRef_AniDB_TvDB_Episode_Override ov in overrides) { ls.Add((ov.AniDBEpisodeID, ov.TvDBEpisodeID)); } List <(AniDB_Episode AniDB, TvDB_Episode TvDB)> eplinks = ls.ToLookup(a => RepoFactory.AniDB_Episode.GetByEpisodeID(a.anidb_episode), b => RepoFactory.TvDB_Episode.GetByTvDBID(b.tvdb_episode)) .Select(a => (AniDB: a.Key, TvDB: a.FirstOrDefault())).Where(a => a.AniDB != null && a.TvDB != null) .OrderBy(a => a.AniDB.EpisodeType).ThenBy(a => a.AniDB.EpisodeNumber).ToList(); List <(int EpisodeType, int EpisodeNumber, int TvDBSeries, int TvDBSeason, int TvDBNumber)> output = new List <(int EpisodeType, int EpisodeNumber, int TvDBSeries, int TvDBSeason, int TvDBNumber)>(); for (int i = 0; i < eplinks.Count; i++) { // Cases: // - first ep // - new type/season // - the next episode is not a simple increment var b = eplinks[i]; if (i == 0) { if (b.AniDB == null || b.TvDB == null) { return(new List <CrossRef_AniDB_TvDBV2>()); } output.Add((b.AniDB.EpisodeType, b.AniDB.EpisodeNumber, b.TvDB.SeriesID, b.TvDB.SeasonNumber, b.TvDB.EpisodeNumber)); continue; } var a = eplinks[i - 1]; if (a.AniDB.EpisodeType != b.AniDB.EpisodeType || b.TvDB.SeasonNumber != a.TvDB.SeasonNumber) { output.Add((b.AniDB.EpisodeType, b.AniDB.EpisodeNumber, b.TvDB.SeriesID, b.TvDB.SeasonNumber, b.TvDB.EpisodeNumber)); continue; } if (b.AniDB.EpisodeNumber - a.AniDB.EpisodeNumber != 1 || b.TvDB.EpisodeNumber - a.TvDB.EpisodeNumber != 1) { output.Add((b.AniDB.EpisodeType, b.AniDB.EpisodeNumber, b.TvDB.SeriesID, b.TvDB.SeasonNumber, b.TvDB.EpisodeNumber)); } } return(output.Select(a => new CrossRef_AniDB_TvDBV2 { AnimeID = animeID, AniDBStartEpisodeType = a.EpisodeType, AniDBStartEpisodeNumber = a.EpisodeNumber, TvDBID = a.TvDBSeries, TvDBSeasonNumber = a.TvDBSeason, TvDBStartEpisodeNumber = a.TvDBNumber, TvDBTitle = RepoFactory.TvDB_Series.GetByTvDBID(a.TvDBSeries)?.SeriesName }).ToList()); }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_TvDBSearchAnime: {0}", AnimeID); try { // first check if the user wants to use the web cache if (ServerSettings.Instance.WebCache.Enabled && ServerSettings.Instance.WebCache.TvDB_Get) { try { List <Azure_CrossRef_AniDB_TvDB> cacheResults = AzureWebAPI.Get_CrossRefAniDBTvDB(AnimeID); if (cacheResults != null && cacheResults.Count > 0) { // check again to see if there are any links, user may have manually added links while // this command was in the queue List <CrossRef_AniDB_TvDB> xrefTemp = RepoFactory.CrossRef_AniDB_TvDB.GetByAnimeID(AnimeID); if (xrefTemp != null && xrefTemp.Count > 0) { return; } // Add overrides for specials List <Azure_CrossRef_AniDB_TvDB> specialXRefs = cacheResults.Where(a => a.TvDBSeasonNumber == 0) .OrderBy(a => a.AniDBStartEpisodeType).ThenBy(a => a.AniDBStartEpisodeNumber) .ToList(); if (specialXRefs.Count != 0) { List <CrossRef_AniDB_TvDB_Episode_Override> overrides = TvDBLinkingHelper.GetSpecialsOverridesFromLegacy(specialXRefs); foreach (CrossRef_AniDB_TvDB_Episode_Override episodeOverride in overrides) { CrossRef_AniDB_TvDB_Episode_Override exists = RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.GetByAniDBAndTvDBEpisodeIDs( episodeOverride.AniDBEpisodeID, episodeOverride.TvDBEpisodeID); if (exists != null) { continue; } RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.Save(episodeOverride); } } foreach (Azure_CrossRef_AniDB_TvDB xref in cacheResults) { TvDB_Series tvser = TvDBApiHelper.GetSeriesInfoOnline(xref.TvDBID, false); if (tvser == null) { continue; } logger.Trace("Found tvdb match on web cache for {0}", AnimeID); TvDBApiHelper.LinkAniDBTvDB(AnimeID, xref.TvDBID, true); } return; } } catch { // ignored } } if (!ServerSettings.Instance.TvDB.AutoLink) { return; } // try to pull a link from a prequel/sequel var relations = RepoFactory.AniDB_Anime_Relation.GetFullLinearRelationTree(AnimeID); int?tvDBID = relations.SelectMany(a => RepoFactory.CrossRef_AniDB_TvDB.GetByAnimeID(a)) .FirstOrDefault(a => a != null)?.TvDBID; if (tvDBID != null) { TvDBApiHelper.LinkAniDBTvDB(AnimeID, tvDBID.Value, true); return; } // search TvDB SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.GetByAnimeID(AnimeID); if (anime == null) { return; } string searchCriteria = CleanTitle(anime.MainTitle); // if not wanting to use web cache, or no match found on the web cache go to TvDB directly List <TVDB_Series_Search_Response> results = TvDBApiHelper.SearchSeries(searchCriteria); logger.Trace("Found {0} tvdb results for {1} on TheTvDB", results.Count, searchCriteria); if (ProcessSearchResults(results, searchCriteria)) { return; } if (results.Count != 0) { return; } bool foundResult = false; foreach (AniDB_Anime_Title title in anime.GetTitles()) { if (!title.TitleType.Equals(Shoko.Models.Constants.AnimeTitleType.Official, StringComparison.InvariantCultureIgnoreCase)) { continue; } if (!title.Language.Equals(Shoko.Models.Constants.AniDBLanguageType.English, StringComparison.InvariantCultureIgnoreCase) && !title.Language.Equals(Shoko.Models.Constants.AniDBLanguageType.Romaji, StringComparison.InvariantCultureIgnoreCase)) { continue; } string cleanTitle = CleanTitle(title.Title); if (searchCriteria.Equals(cleanTitle, StringComparison.InvariantCultureIgnoreCase)) { continue; } searchCriteria = cleanTitle; results = TvDBApiHelper.SearchSeries(searchCriteria); if (results.Count > 0) { foundResult = true; } logger.Trace("Found {0} tvdb results for search on {1}", results.Count, searchCriteria); if (ProcessSearchResults(results, searchCriteria)) { return; } } if (!foundResult) { logger.Warn("Unable to find a matching TvDB series for {0}", anime.MainTitle); } } catch (Exception ex) { logger.Error("Error processing CommandRequest_TvDBSearchAnime: {0} - {1}", AnimeID, ex); } }