public void UpdateUsingGroup(ISession session, int animeGroupID) { try { DateTime start = DateTime.Now; AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup thisgrp = repGroups.GetByID(session, animeGroupID); if (thisgrp == null) return; AdhocRepository repAdHoc = new AdhocRepository(); // get a list of all the groups including this one and everthing above it the heirarchy List<AnimeGroup> allgroups = new List<AnimeGroup>(); allgroups.Add(thisgrp); int? groupID = thisgrp.AnimeGroupParentID; while (groupID.HasValue) { AnimeGroup grpTemp = repGroups.GetByID(session, groupID.Value); if (grpTemp != null) { allgroups.Add(grpTemp); groupID = grpTemp.AnimeGroupParentID; } else groupID = null; } TimeSpan ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP - STEP 1 ({0}) in {1} ms", thisgrp.GroupName, ts.TotalMilliseconds); start = DateTime.Now; VideoLocalRepository repVids = new VideoLocalRepository(); CrossRef_File_EpisodeRepository repXrefs = new CrossRef_File_EpisodeRepository(); foreach (AnimeGroup grp in allgroups) { StatGroupCategories[grp.AnimeGroupID] = grp.CategoriesString; StatGroupTitles[grp.AnimeGroupID] = grp.TitlesString; StatGroupVideoQuality[grp.AnimeGroupID] = grp.VideoQualityString; ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP - STEP 2 ({0}) in {1} ms", grp.GroupName, ts.TotalMilliseconds); start = DateTime.Now; DateTime? airDate_Min = null; DateTime? airDate_Max = null; DateTime? endDate = new DateTime(1980, 1, 1); DateTime? seriesCreatedDate = null; bool isComplete = false; bool hasFinishedAiring = false; bool isCurrentlyAiring = false; string videoQualityEpisodes = ""; List<string> audioLanguages = new List<string>(); List<string> subtitleLanguages = new List<string>(); bool hasTvDB = true; bool hasMAL = true; bool hasMovieDB = true; bool hasMovieDBOrTvDB = true; int seriesCount = 0; int epCount = 0; foreach (AnimeSeries series in grp.GetAllSeries(session)) { seriesCount++; List<VideoLocal> vidsTemp = repVids.GetByAniDBAnimeID(session, series.AniDB_ID); List<CrossRef_File_Episode> crossRefs = repXrefs.GetByAnimeID(session, series.AniDB_ID); Dictionary<int, List<CrossRef_File_Episode>> dictCrossRefs = new Dictionary<int, List<CrossRef_File_Episode>>(); foreach (CrossRef_File_Episode xref in crossRefs) { if (!dictCrossRefs.ContainsKey(xref.EpisodeID)) dictCrossRefs[xref.EpisodeID] = new List<CrossRef_File_Episode>(); dictCrossRefs[xref.EpisodeID].Add(xref); } Dictionary<string, VideoLocal> dictVids = new Dictionary<string, VideoLocal>(); foreach (VideoLocal vid in vidsTemp) dictVids[vid.Hash] = vid; // All Video Quality Episodes // Try to determine if this anime has all the episodes available at a certain video quality // e.g. the series has all episodes in blu-ray // Also look at languages Dictionary<string, int> vidQualEpCounts = new Dictionary<string,int>(); // video quality, count of episodes foreach (AnimeEpisode ep in series.GetAnimeEpisodes(session)) { if (ep.EpisodeTypeEnum != AniDBAPI.enEpisodeType.Episode) continue; List<VideoLocal> epVids = new List<VideoLocal>(); if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID)) { foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID]) { if (xref.EpisodeID == ep.AniDB_EpisodeID) { if (dictVids.ContainsKey(xref.Hash)) epVids.Add(dictVids[xref.Hash]); } } } List<string> qualityAddedSoFar = new List<string>(); // handle mutliple files of the same quality for one episode foreach (VideoLocal vid in epVids) { AniDB_File anifile = vid.GetAniDBFile(session); if (anifile == null) continue; if (!qualityAddedSoFar.Contains(anifile.File_Source)) { if (!vidQualEpCounts.ContainsKey(anifile.File_Source)) vidQualEpCounts[anifile.File_Source] = 1; else vidQualEpCounts[anifile.File_Source]++; qualityAddedSoFar.Add(anifile.File_Source); } } } ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP/Series - STEP 3 ({0}/{1}) in {2} ms",grp.GroupName, series.AnimeSeriesID, ts.TotalMilliseconds); start = DateTime.Now; AniDB_Anime anime = series.GetAnime(session); epCount = epCount + anime.EpisodeCountNormal; foreach (KeyValuePair<string, int> kvp in vidQualEpCounts) { int index = videoQualityEpisodes.IndexOf(kvp.Key, 0, StringComparison.InvariantCultureIgnoreCase); if (index > -1) continue; // don't add if we already have it if (anime.EpisodeCountNormal == kvp.Value) { if (videoQualityEpisodes.Length > 0) videoQualityEpisodes += ","; videoQualityEpisodes += kvp.Key; } } ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP/Series - STEP 4 ({0}/{1}) in {2} ms", grp.GroupName, series.AnimeSeriesID, ts.TotalMilliseconds); start = DateTime.Now; // audio languages Dictionary<int, LanguageStat> dicAudio = repAdHoc.GetAudioLanguageStatsByAnime(session, anime.AnimeID); foreach (KeyValuePair<int, LanguageStat> kvp in dicAudio) { foreach (string lanName in kvp.Value.LanguageNames) { if (!audioLanguages.Contains(lanName)) audioLanguages.Add(lanName); } } ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP/Series - STEP 5 ({0}/{1}) in {2} ms", grp.GroupName, series.AnimeSeriesID, ts.TotalMilliseconds); start = DateTime.Now; // subtitle languages Dictionary<int, LanguageStat> dicSubtitle = repAdHoc.GetSubtitleLanguageStatsByAnime(session, anime.AnimeID); foreach (KeyValuePair<int, LanguageStat> kvp in dicSubtitle) { foreach (string lanName in kvp.Value.LanguageNames) { if (!subtitleLanguages.Contains(lanName)) subtitleLanguages.Add(lanName); } } ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP/Series - STEP 6 ({0}/{1}) in {2} ms", grp.GroupName, series.AnimeSeriesID, ts.TotalMilliseconds); start = DateTime.Now; // Calculate Air Date DateTime? thisDate = series.AirDate; if (thisDate.HasValue) { if (airDate_Min.HasValue) { if (thisDate.Value < airDate_Min.Value) airDate_Min = thisDate; } else airDate_Min = thisDate; if (airDate_Max.HasValue) { if (thisDate.Value > airDate_Max.Value) airDate_Max = thisDate; } else airDate_Max = thisDate; } // calculate end date // if the end date is NULL it actually means it is ongoing, so this is the max possible value thisDate = series.EndDate; if (thisDate.HasValue && endDate.HasValue) { if (thisDate.Value > endDate.Value) endDate = thisDate; } else endDate = null; // Note - only one series has to be finished airing to qualify if (series.EndDate.HasValue && series.EndDate.Value < DateTime.Now) hasFinishedAiring = true; // Note - only one series has to be finished airing to qualify if (!series.EndDate.HasValue || series.EndDate.Value > DateTime.Now) isCurrentlyAiring = true; // We evaluate IsComplete as true if // 1. series has finished airing // 2. user has all episodes locally // Note - only one series has to be complete for the group to be considered complete if (series.EndDate.HasValue) { if (series.EndDate.Value < DateTime.Now && series.MissingEpisodeCount == 0 && series.MissingEpisodeCountGroups == 0) { isComplete = true; } } // Calculate Series Created Date thisDate = series.DateTimeCreated; if (thisDate.HasValue) { if (seriesCreatedDate.HasValue) { if (thisDate.Value < seriesCreatedDate.Value) seriesCreatedDate = thisDate; } else seriesCreatedDate = thisDate; } ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP/Series - STEP 7 ({0}/{1}) in {2} ms", grp.GroupName, series.AnimeSeriesID, ts.TotalMilliseconds); start = DateTime.Now; // for the group, if any of the series don't have a tvdb link // we will consider the group as not having a tvdb link List<CrossRef_AniDB_TvDBV2> tvXrefs = series.GetCrossRefTvDBV2(); if (tvXrefs == null || tvXrefs.Count == 0) hasTvDB = false; if (series.CrossRefMovieDB == null) hasMovieDB = false; if (series.CrossRefMAL == null) hasMAL = false; if ((tvXrefs == null || tvXrefs.Count == 0) && series.CrossRefMovieDB == null) hasMovieDBOrTvDB = false; } StatGroupIsComplete[grp.AnimeGroupID] = isComplete; StatGroupIsFinishedAiring[grp.AnimeGroupID] = hasFinishedAiring; StatGroupIsCurrentlyAiring[grp.AnimeGroupID] = isCurrentlyAiring; StatGroupHasTvDB[grp.AnimeGroupID] = hasTvDB; StatGroupHasMAL[grp.AnimeGroupID] = hasMAL; StatGroupHasMovieDB[grp.AnimeGroupID] = hasMovieDB; StatGroupHasMovieDBOrTvDB[grp.AnimeGroupID] = hasMovieDBOrTvDB; StatGroupSeriesCount[grp.AnimeGroupID] = seriesCount; StatGroupEpisodeCount[grp.AnimeGroupID] = epCount; StatGroupVideoQualityEpisodes[grp.AnimeGroupID] = videoQualityEpisodes; StatGroupAirDate_Min[grp.AnimeGroupID] = airDate_Min; StatGroupAirDate_Max[grp.AnimeGroupID] = airDate_Max; StatGroupEndDate[grp.AnimeGroupID] = endDate; StatGroupSeriesCreatedDate[grp.AnimeGroupID] = seriesCreatedDate; StatGroupUserVoteOverall[grp.AnimeGroupID] = grp.UserVote; StatGroupUserVotePermanent[grp.AnimeGroupID] = grp.UserVotePermanent; StatGroupUserVoteTemporary[grp.AnimeGroupID] = grp.UserVoteTemporary; StatGroupAniDBRating[grp.AnimeGroupID] = grp.AniDBRating; ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP - STEP 8 ({0}) in {1} ms", grp.GroupName, ts.TotalMilliseconds); start = DateTime.Now; string Stat_AudioLanguages = ""; foreach (string audioLan in audioLanguages) { if (Stat_AudioLanguages.Length > 0) Stat_AudioLanguages += ","; Stat_AudioLanguages += audioLan; } this.StatGroupAudioLanguages[grp.AnimeGroupID] = Stat_AudioLanguages; string Stat_SubtitleLanguages = ""; foreach (string subLan in subtitleLanguages) { if (Stat_SubtitleLanguages.Length > 0) Stat_SubtitleLanguages += ","; Stat_SubtitleLanguages += subLan; } this.StatGroupSubtitleLanguages[grp.AnimeGroupID] = Stat_SubtitleLanguages; ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP - STEP 9 ({0}) in {1} ms", grp.GroupName, ts.TotalMilliseconds); start = DateTime.Now; UpdateGroupFilterUsingGroup(grp.AnimeGroupID); UpdatePlexAnimeGroup(session, grp,grp.GetAllSeries()); ts = DateTime.Now - start; logger.Trace("Updating cached stats for GROUP - END ({0}) in {1} ms", grp.GroupName, ts.TotalMilliseconds); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }
public Contract_AniDB_AnimeDetailed ToContractDetailed(ISession session) { AniDB_Anime_TitleRepository repTitles = new AniDB_Anime_TitleRepository(); AniDB_TagRepository repTags = new AniDB_TagRepository(); Contract_AniDB_AnimeDetailed contract = new Contract_AniDB_AnimeDetailed(); contract.AnimeTitles = new List<Contract_AnimeTitle>(); contract.Tags = new List<Contract_AnimeTag>(); contract.CustomTags = new List<Contract_CustomTag>(); contract.AniDBAnime = this.ToContract(session); // get all the anime titles List<AniDB_Anime_Title> animeTitles = repTitles.GetByAnimeID(session, AnimeID); if (animeTitles != null) { foreach (AniDB_Anime_Title title in animeTitles) { Contract_AnimeTitle ctitle = new Contract_AnimeTitle(); ctitle.AnimeID = title.AnimeID; ctitle.Language = title.Language; ctitle.Title = title.Title; ctitle.TitleType = title.TitleType; contract.AnimeTitles.Add(ctitle); } } Dictionary<int, AniDB_Anime_Tag> dictAnimeTags = new Dictionary<int, AniDB_Anime_Tag>(); foreach (AniDB_Anime_Tag animeTag in GetAnimeTags(session)) dictAnimeTags[animeTag.TagID] = animeTag; foreach (AniDB_Tag tag in GetAniDBTags(session)) { Contract_AnimeTag ctag = new Contract_AnimeTag(); ctag.GlobalSpoiler = tag.GlobalSpoiler; ctag.LocalSpoiler = tag.LocalSpoiler; //ctag.Spoiler = tag.Spoiler; //ctag.TagCount = tag.TagCount; ctag.TagDescription = tag.TagDescription; ctag.TagID = tag.TagID; ctag.TagName = tag.TagName; if (dictAnimeTags.ContainsKey(tag.TagID)) ctag.Weight = dictAnimeTags[tag.TagID].Weight; else ctag.Weight = 0; contract.Tags.Add(ctag); } // Get all the custom tags foreach (CustomTag custag in GetCustomTagsForAnime(session)) contract.CustomTags.Add(custag.ToContract()); if (this.UserVote != null) contract.UserVote = this.UserVote.ToContract(); AdhocRepository repAdHoc = new AdhocRepository(); List<string> audioLanguages = new List<string>(); List<string> subtitleLanguages = new List<string>(); //logger.Trace(" XXXX 06"); // audio languages Dictionary<int, LanguageStat> dicAudio = repAdHoc.GetAudioLanguageStatsByAnime(session, this.AnimeID); foreach (KeyValuePair<int, LanguageStat> kvp in dicAudio) { foreach (string lanName in kvp.Value.LanguageNames) { if (!audioLanguages.Contains(lanName)) audioLanguages.Add(lanName); } } //logger.Trace(" XXXX 07"); // subtitle languages Dictionary<int, LanguageStat> dicSubtitle = repAdHoc.GetSubtitleLanguageStatsByAnime(session, this.AnimeID); foreach (KeyValuePair<int, LanguageStat> kvp in dicSubtitle) { foreach (string lanName in kvp.Value.LanguageNames) { if (!subtitleLanguages.Contains(lanName)) subtitleLanguages.Add(lanName); } } //logger.Trace(" XXXX 08"); contract.Stat_AudioLanguages = ""; foreach (string audioLan in audioLanguages) { if (contract.Stat_AudioLanguages.Length > 0) contract.Stat_AudioLanguages += ","; contract.Stat_AudioLanguages += audioLan; } //logger.Trace(" XXXX 09"); contract.Stat_SubtitleLanguages = ""; foreach (string subLan in subtitleLanguages) { if (contract.Stat_SubtitleLanguages.Length > 0) contract.Stat_SubtitleLanguages += ","; contract.Stat_SubtitleLanguages += subLan; } //logger.Trace(" XXXX 10"); contract.Stat_AllVideoQuality = repAdHoc.GetAllVideoQualityForAnime(session, this.AnimeID); contract.Stat_AllVideoQuality_Episodes = ""; AnimeVideoQualityStat stat = repAdHoc.GetEpisodeVideoQualityStatsForAnime(session, this.AnimeID); if (stat != null && stat.VideoQualityEpisodeCount.Count > 0) { foreach (KeyValuePair<string, int> kvp in stat.VideoQualityEpisodeCount) { if (kvp.Value >= EpisodeCountNormal) { if (contract.Stat_AllVideoQuality_Episodes.Length > 0) contract.Stat_AllVideoQuality_Episodes += ","; contract.Stat_AllVideoQuality_Episodes += kvp.Key; } } } //logger.Trace(" XXXX 11"); return contract; }