public List<Contract_AnimeEpisode> GetEpisodesForSeries(int animeSeriesID, int userID) { List<Contract_AnimeEpisode> eps = new List<Contract_AnimeEpisode>(); try { DateTime start = DateTime.Now; AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeEpisode_UserRepository repEpUsers = new AnimeEpisode_UserRepository(); AnimeSeriesRepository repAnimeSer = new AnimeSeriesRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); CrossRef_File_EpisodeRepository repCrossRefs = new CrossRef_File_EpisodeRepository(); // get all the data first // we do this to reduce the amount of database calls, which makes it a lot faster AnimeSeries series = repAnimeSer.GetByID(animeSeriesID); if (series == null) return eps; List<AnimeEpisode> epList = repEps.GetBySeriesID(animeSeriesID); List<AnimeEpisode_User> userRecordList = repEpUsers.GetByUserIDAndSeriesID(userID, animeSeriesID); Dictionary<int, AnimeEpisode_User> dictUserRecords = new Dictionary<int, AnimeEpisode_User>(); foreach (AnimeEpisode_User epuser in userRecordList) dictUserRecords[epuser.AnimeEpisodeID] = epuser; AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); List<AniDB_Episode> aniEpList = repAniEps.GetByAnimeID(series.AniDB_ID); Dictionary<int, AniDB_Episode> dictAniEps = new Dictionary<int, AniDB_Episode>(); foreach (AniDB_Episode aniep in aniEpList) dictAniEps[aniep.EpisodeID] = aniep; // get all the video local records and cross refs List<VideoLocal> vids = repVids.GetByAniDBAnimeID(series.AniDB_ID); List<CrossRef_File_Episode> crossRefs = repCrossRefs.GetByAnimeID(series.AniDB_ID); TimeSpan ts = DateTime.Now - start; logger.Info("GetEpisodesForSeries: {0} (Database) in {1} ms", series.GetAnime().MainTitle, ts.TotalMilliseconds); start = DateTime.Now; foreach (AnimeEpisode ep in epList) { if (dictAniEps.ContainsKey(ep.AniDB_EpisodeID)) { List<VideoLocal> epVids = new List<VideoLocal>(); foreach (CrossRef_File_Episode xref in crossRefs) { if (xref.EpisodeID == dictAniEps[ep.AniDB_EpisodeID].EpisodeID) { // don't add the same file twice, this will occur when // one file appears over more than one episodes Dictionary<string, string> addedFiles = new Dictionary<string, string>(); foreach (VideoLocal vl in vids) { if (string.Equals(xref.Hash, vl.Hash, StringComparison.InvariantCultureIgnoreCase)) { if (!addedFiles.ContainsKey(xref.Hash.Trim().ToUpper())) { addedFiles[xref.Hash.Trim().ToUpper()] = xref.Hash.Trim().ToUpper(); epVids.Add(vl); } } } } } AnimeEpisode_User epuser = null; if (dictUserRecords.ContainsKey(ep.AnimeEpisodeID)) epuser = dictUserRecords[ep.AnimeEpisodeID]; eps.Add(ep.ToContract(dictAniEps[ep.AniDB_EpisodeID], epVids, epuser, null)); } } ts = DateTime.Now - start; logger.Info("GetEpisodesForSeries: {0} (Contracts) in {1} ms", series.GetAnime().MainTitle, ts.TotalMilliseconds); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return eps; }
public Contract_AnimeEpisode GetNextUnwatchedEpisode(ISession session, int animeSeriesID, int userID) { try { AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeSeriesRepository repAnimeSer = new AnimeSeriesRepository(); AnimeEpisode_UserRepository repEpUser = new AnimeEpisode_UserRepository(); // get all the data first // we do this to reduce the amount of database calls, which makes it a lot faster AnimeSeries series = repAnimeSer.GetByID(session, animeSeriesID); if (series == null) return null; //List<AnimeEpisode> epList = repEps.GetUnwatchedEpisodes(animeSeriesID, userID); List<AnimeEpisode> epList = new List<AnimeEpisode>(); Dictionary<int, AnimeEpisode_User> dictEpUsers = new Dictionary<int, AnimeEpisode_User>(); foreach (AnimeEpisode_User userRecord in repEpUser.GetByUserIDAndSeriesID(session, userID, animeSeriesID)) dictEpUsers[userRecord.AnimeEpisodeID] = userRecord; foreach (AnimeEpisode animeep in repEps.GetBySeriesID(session, animeSeriesID)) { if (!dictEpUsers.ContainsKey(animeep.AnimeEpisodeID)) { epList.Add(animeep); continue; } AnimeEpisode_User usrRec = dictEpUsers[animeep.AnimeEpisodeID]; if (usrRec.WatchedCount == 0 || !usrRec.WatchedDate.HasValue) epList.Add(animeep); } AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); List<AniDB_Episode> aniEpList = repAniEps.GetByAnimeID(session, series.AniDB_ID); Dictionary<int, AniDB_Episode> dictAniEps = new Dictionary<int, AniDB_Episode>(); foreach (AniDB_Episode aniep in aniEpList) dictAniEps[aniep.EpisodeID] = aniep; List<Contract_AnimeEpisode> candidateEps = new List<Contract_AnimeEpisode>(); foreach (AnimeEpisode ep in epList) { if (dictAniEps.ContainsKey(ep.AniDB_EpisodeID)) { AniDB_Episode anidbep = dictAniEps[ep.AniDB_EpisodeID]; if (anidbep.EpisodeType == (int)enEpisodeType.Episode || anidbep.EpisodeType == (int)enEpisodeType.Special) { AnimeEpisode_User userRecord = null; if (dictEpUsers.ContainsKey(ep.AnimeEpisodeID)) userRecord = dictEpUsers[ep.AnimeEpisodeID]; Contract_AnimeEpisode epContract = ep.ToContract(anidbep, new List<VideoLocal>(), userRecord, series.GetUserRecord(session, userID)); candidateEps.Add(epContract); } } } if (candidateEps.Count == 0) return null; // sort by episode type and number to find the next episode List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeType", false, SortType.eInteger)); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeNumber", false, SortType.eInteger)); candidateEps = Sorting.MultiSort<Contract_AnimeEpisode>(candidateEps, sortCriteria); // this will generate a lot of queries when the user doesn have files // for these episodes foreach (Contract_AnimeEpisode canEp in candidateEps) { // now refresh from the database to get file count AnimeEpisode epFresh = repEps.GetByID(canEp.AnimeEpisodeID); if (epFresh.GetVideoLocals().Count > 0) return epFresh.ToContract(true, userID, series.GetUserRecord(session, userID)); } return null; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return null; } }
public MetroContract_Anime_Detail GetAnimeDetail(int animeID, int jmmuserID, int maxEpisodeRecords) { try { using (var session = JMMService.SessionFactory.OpenSession()) { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(session, animeID); if (anime == null) return null; AnimeSeries ser = repSeries.GetByAnimeID(session, animeID); MetroContract_Anime_Detail ret = new MetroContract_Anime_Detail(); ret.AnimeID = anime.AnimeID; if (ser != null) ret.AnimeName = ser.GetSeriesName(session); else ret.AnimeName = anime.MainTitle; if (ser != null) ret.AnimeSeriesID = ser.AnimeSeriesID; else ret.AnimeSeriesID = 0; ret.BeginYear = anime.BeginYear; ret.EndYear = anime.EndYear; ImageDetails imgDet = anime.GetDefaultPosterDetailsNoBlanks(session); ret.PosterImageType = (int)imgDet.ImageType; ret.PosterImageID = imgDet.ImageID; ImageDetails imgDetFan = anime.GetDefaultFanartDetailsNoBlanks(session); if (imgDetFan != null) { ret.FanartImageType = (int)imgDetFan.ImageType; ret.FanartImageID = imgDetFan.ImageID; } else { ret.FanartImageType = 0; ret.FanartImageID = 0; } ret.AnimeType = anime.AnimeTypeDescription; ret.Description = anime.Description; ret.EpisodeCountNormal = anime.EpisodeCountNormal; ret.EpisodeCountSpecial = anime.EpisodeCountSpecial; ret.AirDate = anime.AirDate; ret.EndDate = anime.EndDate; ret.OverallRating = anime.AniDBRating; ret.TotalVotes = anime.AniDBTotalVotes; ret.AllTags = anime.TagsString; ret.NextEpisodesToWatch = new List<MetroContract_Anime_Episode>(); if (ser != null) { AnimeSeries_User serUserRec = ser.GetUserRecord(session, jmmuserID); if (ser != null) ret.UnwatchedEpisodeCount = serUserRec.UnwatchedEpisodeCount; else ret.UnwatchedEpisodeCount = 0; AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeEpisode_UserRepository repEpUser = new AnimeEpisode_UserRepository(); List<AnimeEpisode> epList = new List<AnimeEpisode>(); Dictionary<int, AnimeEpisode_User> dictEpUsers = new Dictionary<int, AnimeEpisode_User>(); foreach (AnimeEpisode_User userRecord in repEpUser.GetByUserIDAndSeriesID(session, jmmuserID, ser.AnimeSeriesID)) dictEpUsers[userRecord.AnimeEpisodeID] = userRecord; foreach (AnimeEpisode animeep in repEps.GetBySeriesID(session, ser.AnimeSeriesID)) { if (!dictEpUsers.ContainsKey(animeep.AnimeEpisodeID)) { epList.Add(animeep); continue; } AnimeEpisode_User usrRec = dictEpUsers[animeep.AnimeEpisodeID]; if (usrRec.WatchedCount == 0 || !usrRec.WatchedDate.HasValue) epList.Add(animeep); } AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); List<AniDB_Episode> aniEpList = repAniEps.GetByAnimeID(session, ser.AniDB_ID); Dictionary<int, AniDB_Episode> dictAniEps = new Dictionary<int, AniDB_Episode>(); foreach (AniDB_Episode aniep in aniEpList) dictAniEps[aniep.EpisodeID] = aniep; List<Contract_AnimeEpisode> candidateEps = new List<Contract_AnimeEpisode>(); foreach (AnimeEpisode ep in epList) { if (dictAniEps.ContainsKey(ep.AniDB_EpisodeID)) { AniDB_Episode anidbep = dictAniEps[ep.AniDB_EpisodeID]; if (anidbep.EpisodeType == (int)enEpisodeType.Episode || anidbep.EpisodeType == (int)enEpisodeType.Special) { AnimeEpisode_User userRecord = null; if (dictEpUsers.ContainsKey(ep.AnimeEpisodeID)) userRecord = dictEpUsers[ep.AnimeEpisodeID]; Contract_AnimeEpisode epContract = ep.ToContract(anidbep, new List<VideoLocal>(), userRecord, serUserRec); candidateEps.Add(epContract); } } } if (candidateEps.Count > 0) { TvDBSummary tvSummary = new TvDBSummary(); tvSummary.Populate(ser.AniDB_ID); // sort by episode type and number to find the next episode List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeType", false, SortType.eInteger)); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeNumber", false, SortType.eInteger)); candidateEps = Sorting.MultiSort<Contract_AnimeEpisode>(candidateEps, sortCriteria); // this will generate a lot of queries when the user doesn have files // for these episodes int cnt = 0; foreach (Contract_AnimeEpisode canEp in candidateEps) { if (dictAniEps.ContainsKey(canEp.AniDB_EpisodeID)) { AniDB_Episode anidbep = dictAniEps[canEp.AniDB_EpisodeID]; AnimeEpisode_User userEpRecord = null; if (dictEpUsers.ContainsKey(canEp.AnimeEpisodeID)) userEpRecord = dictEpUsers[canEp.AnimeEpisodeID]; // now refresh from the database to get file count AnimeEpisode epFresh = repEps.GetByID(session, canEp.AnimeEpisodeID); int fileCount = epFresh.GetVideoLocals(session).Count; if (fileCount > 0) { MetroContract_Anime_Episode contract = new MetroContract_Anime_Episode(); contract.AnimeEpisodeID = epFresh.AnimeEpisodeID; contract.LocalFileCount = fileCount; if (userEpRecord == null) contract.IsWatched = false; else contract.IsWatched = userEpRecord.WatchedCount > 0; // anidb contract.EpisodeNumber = anidbep.EpisodeNumber; contract.EpisodeName = anidbep.RomajiName; if (!string.IsNullOrEmpty(anidbep.EnglishName)) contract.EpisodeName = anidbep.EnglishName; contract.EpisodeType = anidbep.EpisodeType; contract.LengthSeconds = anidbep.LengthSeconds; contract.AirDate = anidbep.AirDateFormatted; // tvdb SetTvDBInfo(tvSummary, anidbep, ref contract); ret.NextEpisodesToWatch.Add(contract); cnt++; } } if (cnt == maxEpisodeRecords) break; } } } return ret; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return null; } }