public static void InitCache() { string t = "AnimeGroups"; ServerState.Instance.CurrentSetupStatus = string.Format(JMMServer.Properties.Resources.Database_Cache, t, string.Empty); AnimeGroupRepository repo = new AnimeGroupRepository(); Cache = new PocoCache <int, AnimeGroup>(repo.InternalGetAll(), a => a.AnimeGroupID); Changes.AddOrUpdateRange(Cache.Keys); Parents = Cache.CreateIndex(a => a.AnimeGroupParentID ?? 0); List <AnimeGroup> grps = Cache.Values.Where(a => a.ContractVersion < AnimeGroup.CONTRACT_VERSION).ToList(); int max = grps.Count; int cnt = 0; foreach (AnimeGroup g in grps) { repo.Save(g, true, false, false); cnt++; if (cnt % 10 == 0) { ServerState.Instance.CurrentSetupStatus = string.Format(JMMServer.Properties.Resources.Database_Cache, t, " DbRegen - " + cnt + "/" + max); } } ServerState.Instance.CurrentSetupStatus = string.Format(JMMServer.Properties.Resources.Database_Cache, t, " DbRegen - " + max + "/" + max); }
public void Save(AnimeSeries obj, bool updateStats) { bool updateStatsCache = false; AnimeGroup oldGroup = null; if (obj.AnimeSeriesID == 0) { updateStatsCache = true; // a new series } else { // get the old version from the DB AnimeSeries oldSeries = GetByID(obj.AnimeSeriesID); if (oldSeries != null) { // means we are moving series to a different group if (oldSeries.AnimeGroupID != obj.AnimeGroupID) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); oldGroup = repGroups.GetByID(oldSeries.AnimeGroupID); updateStatsCache = true; } } } using (var session = JMMService.SessionFactory.OpenSession()) { // populate the database using (var transaction = session.BeginTransaction()) { session.SaveOrUpdate(obj); transaction.Commit(); } } if (updateStats) { if (updateStatsCache) { logger.Trace("Updating group stats by series from AnimeSeriesRepository.Save: {0}", obj.AnimeSeriesID); StatsCache.Instance.UpdateUsingSeries(obj.AnimeSeriesID); } if (oldGroup != null) { logger.Trace("Updating group stats by group from AnimeSeriesRepository.Save: {0}", oldGroup.AnimeGroupID); StatsCache.Instance.UpdateUsingGroup(oldGroup.AnimeGroupID); } } }
public void Save(AnimeSeries obj, bool updateStats) { bool updateStatsCache = false; AnimeGroup oldGroup = null; if (obj.AnimeSeriesID == 0) updateStatsCache = true; // a new series else { // get the old version from the DB AnimeSeries oldSeries = GetByID(obj.AnimeSeriesID); if (oldSeries != null) { // means we are moving series to a different group if (oldSeries.AnimeGroupID != obj.AnimeGroupID) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); oldGroup = repGroups.GetByID(oldSeries.AnimeGroupID); updateStatsCache = true; } } } using (var session = JMMService.SessionFactory.OpenSession()) { // populate the database using (var transaction = session.BeginTransaction()) { session.SaveOrUpdate(obj); transaction.Commit(); } } if (updateStats) { if (updateStatsCache) { logger.Trace("Updating group stats by series from AnimeSeriesRepository.Save: {0}", obj.AnimeSeriesID); StatsCache.Instance.UpdateUsingSeries(obj.AnimeSeriesID); } if (oldGroup != null) { logger.Trace("Updating group stats by group from AnimeSeriesRepository.Save: {0}", oldGroup.AnimeGroupID); StatsCache.Instance.UpdateUsingGroup(oldGroup.AnimeGroupID); } } }
public List<Contract_AnimeGroup> GetAllGroups(int userID) { List<Contract_AnimeGroup> grps = new List<Contract_AnimeGroup>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { DateTime start = DateTime.Now; AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup_UserRepository repUserGroups = new AnimeGroup_UserRepository(); List<AnimeGroup> allGrps = repGroups.GetAll(session); TimeSpan ts = DateTime.Now - start; logger.Info("GetAllGroups (Database) in {0} ms", ts.TotalMilliseconds); start = DateTime.Now; // user records AnimeGroup_UserRepository repGroupUser = new AnimeGroup_UserRepository(); List<AnimeGroup_User> userRecordList = repGroupUser.GetByUserID(session, userID); Dictionary<int, AnimeGroup_User> dictUserRecords = new Dictionary<int, AnimeGroup_User>(); foreach (AnimeGroup_User grpUser in userRecordList) dictUserRecords[grpUser.AnimeGroupID] = grpUser; foreach (AnimeGroup ag in allGrps) { AnimeGroup_User userRec = null; if (dictUserRecords.ContainsKey(ag.AnimeGroupID)) userRec = dictUserRecords[ag.AnimeGroupID]; // calculate stats Contract_AnimeGroup contract = ag.ToContract(userRec); grps.Add(contract); } grps.Sort(); ts = DateTime.Now - start; logger.Info("GetAllGroups (Contracts) in {0} ms", ts.TotalMilliseconds); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return grps; }
public void Delete(int id) { int oldGroupID = 0; using (var session = JMMService.SessionFactory.OpenSession()) { // populate the database using (var transaction = session.BeginTransaction()) { AnimeSeries cr = GetByID(id); if (cr != null) { Cache.Remove(cr); // delete user records AnimeSeries_UserRepository repUsers = new AnimeSeries_UserRepository(); foreach (AnimeSeries_User grpUser in repUsers.GetBySeriesID(id)) { repUsers.Delete(grpUser.AnimeSeries_UserID); } Changes.Remove(cr.AnimeSeriesID); oldGroupID = cr.AnimeGroupID; session.Delete(cr); transaction.Commit(); cr.DeleteFromFilters(); } } } if (oldGroupID > 0) { logger.Trace("Updating group stats by group from AnimeSeriesRepository.Delete: {0}", oldGroupID); AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup oldGroup = repGroups.GetByID(oldGroupID); if (oldGroup != null) { repGroups.Save(oldGroup, true, true); } } }
public List<Contract_AnimeSeries> GetSeriesForGroupRecursive(int animeGroupID, int userID) { List<Contract_AnimeSeries> series = new List<Contract_AnimeSeries>(); try { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup grp = repGroups.GetByID(animeGroupID); if (grp == null) return series; foreach (AnimeSeries ser in grp.GetAllSeries()) series.Add(ser.ToContract(ser.GetUserRecord(userID))); return series; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return series; } }
void workerMyAnime2_DoWork(object sender, DoWorkEventArgs e) { MA2Progress ma2Progress = new MA2Progress(); ma2Progress.CurrentFile = 0; ma2Progress.ErrorMessage = ""; ma2Progress.MigratedFiles = 0; ma2Progress.TotalFiles = 0; try { string databasePath = e.Argument as string; string connString = string.Format(@"data source={0};useutf16encoding=True", databasePath); SQLiteConnection myConn = new SQLiteConnection(connString); myConn.Open(); // get a list of unlinked files VideoLocalRepository repVids = new VideoLocalRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AniDB_AnimeRepository repAniAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); List<VideoLocal> vids = repVids.GetVideosWithoutEpisode(); ma2Progress.TotalFiles = vids.Count; foreach (VideoLocal vid in vids) { ma2Progress.CurrentFile = ma2Progress.CurrentFile + 1; workerMyAnime2.ReportProgress(0, ma2Progress); // search for this file in the XrossRef table in MA2 string sql = string.Format("SELECT AniDB_EpisodeID from CrossRef_Episode_FileHash WHERE Hash = '{0}' AND FileSize = {1}", vid.ED2KHash, vid.FileSize); SQLiteCommand sqCommand = new SQLiteCommand(sql); sqCommand.Connection = myConn; SQLiteDataReader myReader = sqCommand.ExecuteReader(); while (myReader.Read()) { int episodeID = 0; if (!int.TryParse(myReader.GetValue(0).ToString(), out episodeID)) continue; if (episodeID <= 0) continue; sql = string.Format("SELECT AnimeID from AniDB_Episode WHERE EpisodeID = {0}", episodeID); sqCommand = new SQLiteCommand(sql); sqCommand.Connection = myConn; SQLiteDataReader myReader2 = sqCommand.ExecuteReader(); while (myReader2.Read()) { int animeID = myReader2.GetInt32(0); // so now we have all the needed details we can link the file to the episode // as long as wehave the details in JMM AniDB_Anime anime = null; AniDB_Episode ep = repAniEps.GetByEpisodeID(episodeID); if (ep == null) { logger.Debug("Getting Anime record from AniDB...."); anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.AutoGroupSeries); } else anime = repAniAnime.GetByAnimeID(animeID); // create the group/series/episode records if needed AnimeSeries ser = null; if (anime == null) continue; logger.Debug("Creating groups, series and episodes...."); // check if there is an AnimeSeries Record associated with this AnimeID ser = repSeries.GetByAnimeID(animeID); if (ser == null) { // create a new AnimeSeries record ser = anime.CreateAnimeSeriesAndGroup(); } ser.CreateAnimeEpisodes(); // check if we have any group status data for this associated anime // if not we will download it now AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository(); if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(); } // update stats ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } AnimeEpisode epAnime = repEps.GetByAniDBEpisodeID(episodeID); if (epAnime == null) continue; CrossRef_File_EpisodeRepository repXRefs = new CrossRef_File_EpisodeRepository(); CrossRef_File_Episode xref = new CrossRef_File_Episode(); try { xref.PopulateManually(vid, epAnime); } catch (Exception ex) { string msg = string.Format("Error populating XREF: {0} - {1}", vid.ToStringDetailed(), ex.ToString()); throw; } repXRefs.Save(xref); vid.RenameIfRequired(); vid.MoveFileIfRequired(); // update stats for groups and series if (ser != null) { // update all the groups above this series in the heirarchy ser.UpdateStats(true, true, true); StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); } // Add this file to the users list if (ServerSettings.AniDB_MyList_AddFiles) { CommandRequest_AddFileToMyList cmd = new CommandRequest_AddFileToMyList(vid.ED2KHash); cmd.Save(); } ma2Progress.MigratedFiles = ma2Progress.MigratedFiles + 1; workerMyAnime2.ReportProgress(0, ma2Progress); } myReader2.Close(); //Console.WriteLine(myReader.GetString(0)); } myReader.Close(); } myConn.Close(); ma2Progress.CurrentFile = ma2Progress.CurrentFile + 1; workerMyAnime2.ReportProgress(0, ma2Progress); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); ma2Progress.ErrorMessage = ex.Message; workerMyAnime2.ReportProgress(0, ma2Progress); } }
/// <summary> /// Update the stats for this group based on the child series /// Assumes that all the AnimeSeries have had their stats updated already /// </summary> public void UpdateStats(bool watchedStats, bool missingEpsStats) { List<AnimeSeries> seriesList = GetAllSeries(); JMMUserRepository repUsers = new JMMUserRepository(); List<JMMUser> allUsers = repUsers.GetAll(); if (watchedStats) { foreach (JMMUser juser in allUsers) { AnimeGroup_User userRecord = GetUserRecord(juser.JMMUserID); if (userRecord == null) userRecord = new AnimeGroup_User(juser.JMMUserID, this.AnimeGroupID); // reset stats userRecord.WatchedCount = 0; userRecord.UnwatchedEpisodeCount = 0; userRecord.PlayedCount = 0; userRecord.StoppedCount = 0; userRecord.WatchedEpisodeCount = 0; userRecord.WatchedDate = null; foreach (AnimeSeries ser in seriesList) { AnimeSeries_User serUserRecord = ser.GetUserRecord(juser.JMMUserID); if (serUserRecord != null) { userRecord.WatchedCount += serUserRecord.WatchedCount; userRecord.UnwatchedEpisodeCount += serUserRecord.UnwatchedEpisodeCount; userRecord.PlayedCount += serUserRecord.PlayedCount; userRecord.StoppedCount += serUserRecord.StoppedCount; userRecord.WatchedEpisodeCount += serUserRecord.WatchedEpisodeCount; if (serUserRecord.WatchedDate.HasValue) { if (userRecord.WatchedDate.HasValue) { if (serUserRecord.WatchedDate > userRecord.WatchedDate) userRecord.WatchedDate = serUserRecord.WatchedDate; } else userRecord.WatchedDate = serUserRecord.WatchedDate; } } } // now update the stats for the groups logger.Trace("Updating stats for {0}", this.ToString()); AnimeGroup_UserRepository rep = new AnimeGroup_UserRepository(); rep.Save(userRecord); } } if (missingEpsStats) { this.MissingEpisodeCount = 0; this.MissingEpisodeCountGroups = 0; foreach (AnimeSeries ser in seriesList) { this.MissingEpisodeCount += ser.MissingEpisodeCount; this.MissingEpisodeCountGroups += ser.MissingEpisodeCountGroups; } AnimeGroupRepository repGrp = new AnimeGroupRepository(); repGrp.Save(this); } }
public Contract_AnimeGroup_SaveResponse SaveGroup(Contract_AnimeGroup_Save contract, int userID) { Contract_AnimeGroup_SaveResponse contractout = new Contract_AnimeGroup_SaveResponse(); contractout.ErrorMessage = ""; contractout.AnimeGroup = null; try { AnimeGroupRepository repGroup = new AnimeGroupRepository(); AnimeGroup grp = null; if (contract.AnimeGroupID.HasValue) { grp = repGroup.GetByID(contract.AnimeGroupID.Value); if (grp == null) { contractout.ErrorMessage = "Could not find existing group with ID: " + contract.AnimeGroupID.Value.ToString(); return contractout; } } else { grp = new AnimeGroup(); grp.Description = ""; grp.IsManuallyNamed = 0; grp.DateTimeCreated = DateTime.Now; grp.DateTimeUpdated = DateTime.Now; grp.SortName = ""; grp.MissingEpisodeCount = 0; grp.MissingEpisodeCountGroups = 0; grp.OverrideDescription = 0; } if (string.IsNullOrEmpty(contract.GroupName)) { contractout.ErrorMessage = "Must specify a group name"; return contractout; } grp.AnimeGroupParentID = contract.AnimeGroupParentID; grp.Description = contract.Description; grp.GroupName = contract.GroupName; grp.IsManuallyNamed = contract.IsManuallyNamed; grp.OverrideDescription = 0; if (string.IsNullOrEmpty(contract.SortName)) grp.SortName = contract.GroupName; else grp.SortName = contract.SortName; repGroup.Save(grp); AnimeGroup_User userRecord = grp.GetUserRecord(userID); if (userRecord == null) userRecord = new AnimeGroup_User(userID, grp.AnimeGroupID); userRecord.IsFave = contract.IsFave; AnimeGroup_UserRepository repUserRecords = new AnimeGroup_UserRepository(); repUserRecords.Save(userRecord); Contract_AnimeGroup contractGrp = grp.ToContract(grp.GetUserRecord(userID)); contractout.AnimeGroup = contractGrp; return contractout; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); contractout.ErrorMessage = ex.Message; return contractout; } }
public void SetDefaultSeriesForGroup(int animeGroupID, int animeSeriesID) { try { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeGroup grp = repGroups.GetByID(animeGroupID); if (grp == null) return; AnimeSeries ser = repSeries.GetByID(animeSeriesID); if (ser == null) return; grp.DefaultAnimeSeriesID = animeSeriesID; repGroups.Save(grp); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }
public Contract_AnimeGroup GetTopLevelGroupForSeries(int animeSeriesID, int userID) { try { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByID(animeSeriesID); if (ser == null) return null; AnimeGroup grp = ser.TopLevelAnimeGroup; if (grp == null) return null; return grp.ToContract(grp.GetUserRecord(userID)); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return null; }
public Contract_AnimeSeries_SaveResponse MoveSeries(int animeSeriesID, int newAnimeGroupID, int userID) { Contract_AnimeSeries_SaveResponse contractout = new Contract_AnimeSeries_SaveResponse(); contractout.ErrorMessage = ""; contractout.AnimeSeries = null; try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = null; ser = repSeries.GetByID(animeSeriesID); if (ser == null) { contractout.ErrorMessage = "Could not find existing series with ID: " + animeSeriesID.ToString(); return contractout; } // make sure the group exists AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup grpTemp = repGroups.GetByID(newAnimeGroupID); if (grpTemp == null) { contractout.ErrorMessage = "Could not find existing group with ID: " + newAnimeGroupID.ToString(); return contractout; } int oldGroupID = ser.AnimeGroupID; ser.AnimeGroupID = newAnimeGroupID; ser.DateTimeUpdated = DateTime.Now; repSeries.Save(ser); // update stats for new groups //ser.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true); ser.QueueUpdateStats(); // update stats for old groups AnimeGroup grp = repGroups.GetByID(oldGroupID); if (grp != null) { grp.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true); } AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(ser.AniDB_ID); if (anime == null) { contractout.ErrorMessage = string.Format("Could not find anime record with ID: {0}", ser.AniDB_ID); return contractout; } List<CrossRef_AniDB_TvDBV2> xrefs = ser.GetCrossRefTvDBV2(); List<CrossRef_AniDB_MAL> xrefMAL = ser.CrossRefMAL; List<TvDB_Series> sers = new List<TvDB_Series>(); foreach (CrossRef_AniDB_TvDBV2 xref in xrefs) sers.Add(xref.GetTvDBSeries()); CrossRef_AniDB_Other xrefMovie = ser.CrossRefMovieDB; MovieDB_Movie movie=null; if (xrefMovie != null) movie = xrefMovie.GetMovieDB_Movie(); contractout.AnimeSeries = ser.ToContract(anime, xrefs, xrefMovie, ser.GetUserRecord(userID), sers, xrefMAL, false, null, null, null, null,movie); return contractout; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); contractout.ErrorMessage = ex.Message; return contractout; } }
public List<Contract_AnimeGroup> GetAllGroupsAboveGroupInclusive(int animeGroupID, int userID) { List<Contract_AnimeGroup> grps = new List<Contract_AnimeGroup>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup grp = repGroups.GetByID(session, animeGroupID); if (grp == null) return grps; Contract_AnimeGroup contractGrp = grp.ToContract(grp.GetUserRecord(session, userID)); grps.Add(contractGrp); int? groupID = grp.AnimeGroupParentID; while (groupID.HasValue) { AnimeGroup grpTemp = repGroups.GetByID(session, groupID.Value); if (grpTemp != null) { Contract_AnimeGroup contractGrpTemp = grpTemp.ToContract(grpTemp.GetUserRecord(session, userID)); grps.Add(contractGrpTemp); groupID = grpTemp.AnimeGroupParentID; } else { groupID = null; } } return grps; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return grps; }
public string AssociateSingleFile(int videoLocalID, int animeEpisodeID) { try { VideoLocalRepository repVids = new VideoLocalRepository(); VideoLocal vid = repVids.GetByID(videoLocalID); if (vid == null) return "Could not find video record"; AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeEpisode ep = repEps.GetByID(animeEpisodeID); if (ep == null) return "Could not find episode record"; CrossRef_File_EpisodeRepository repXRefs = new CrossRef_File_EpisodeRepository(); CrossRef_File_Episode xref = new CrossRef_File_Episode(); try { xref.PopulateManually(vid, ep); } catch (Exception ex) { string msg = string.Format("Error populating XREF: {0}", vid.ToStringDetailed()); throw; } repXRefs.Save(xref); vid.RenameIfRequired(); vid.MoveFileIfRequired(); CommandRequest_WebCacheSendXRefFileEpisode cr = new CommandRequest_WebCacheSendXRefFileEpisode(xref.CrossRef_File_EpisodeID); cr.Save(); AnimeSeries ser = ep.GetAnimeSeries(); ser.QueueUpdateStats(); // update epidsode added stats AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } CommandRequest_AddFileToMyList cmdAddFile = new CommandRequest_AddFileToMyList(vid.Hash); cmdAddFile.Save(); return ""; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return ""; }
public string AssociateMultipleFiles(List<int> videoLocalIDs, int animeSeriesID, int startingEpisodeNumber, bool singleEpisode) { try { CrossRef_File_EpisodeRepository repXRefs = new CrossRef_File_EpisodeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeSeries ser = repSeries.GetByID(animeSeriesID); if (ser == null) return "Could not find anime series record"; int epNumber = startingEpisodeNumber; int count = 1; foreach (int videoLocalID in videoLocalIDs) { VideoLocal vid = repVids.GetByID(videoLocalID); if (vid == null) return "Could not find video local record"; List<AniDB_Episode> anieps = repAniEps.GetByAnimeIDAndEpisodeNumber(ser.AniDB_ID, epNumber); if (anieps.Count == 0) return "Could not find the AniDB episode record"; AniDB_Episode aniep = anieps[0]; List<AnimeEpisode> eps = repEps.GetByAniEpisodeIDAndSeriesID(aniep.EpisodeID, ser.AnimeSeriesID); if (eps.Count == 0) return "Could not find episode record"; AnimeEpisode ep = eps[0]; CrossRef_File_Episode xref = new CrossRef_File_Episode(); xref.PopulateManually(vid, ep); // TODO do this properly if (singleEpisode) { xref.EpisodeOrder = count; if (videoLocalIDs.Count > 5) xref.Percentage = 100; else xref.Percentage = GetEpisodePercentages(videoLocalIDs.Count)[count - 1]; } repXRefs.Save(xref); vid.RenameIfRequired(); vid.MoveFileIfRequired(); CommandRequest_WebCacheSendXRefFileEpisode cr = new CommandRequest_WebCacheSendXRefFileEpisode(xref.CrossRef_File_EpisodeID); cr.Save(); count++; if (!singleEpisode) epNumber++; } ser.QueueUpdateStats(); // update epidsode added stats ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return ""; }
public List<Contract_GroupFilterExtended> GetAllGroupFiltersExtended(int userID) { List<Contract_GroupFilterExtended> gfs = new List<Contract_GroupFilterExtended>(); try { DateTime start = DateTime.Now; GroupFilterRepository repGF = new GroupFilterRepository(); JMMUserRepository repUsers = new JMMUserRepository(); JMMUser user = repUsers.GetByID(userID); if (user == null) return gfs; List<GroupFilter> allGfs = repGF.GetAll(); TimeSpan ts = DateTime.Now - start; logger.Info("GetAllGroupFilters (Database) in {0} ms", ts.TotalMilliseconds); start = DateTime.Now; AnimeGroupRepository repGroups = new AnimeGroupRepository(); List<AnimeGroup> allGrps = repGroups.GetAllTopLevelGroups(); ts = DateTime.Now - start; logger.Info("GetAllGroups (Database) in {0} ms", ts.TotalMilliseconds); start = DateTime.Now; foreach (GroupFilter gf in allGfs) { Contract_GroupFilter gfContract = gf.ToContract(); Contract_GroupFilterExtended gfeContract = new Contract_GroupFilterExtended(); gfeContract.GroupFilter = gfContract; gfeContract.GroupCount = 0; gfeContract.SeriesCount = 0; if ((StatsCache.Instance.StatUserGroupFilter.ContainsKey(user.JMMUserID)) && (StatsCache.Instance.StatUserGroupFilter[userID].ContainsKey(gf.GroupFilterID))) { HashSet<int> groups = StatsCache.Instance.StatUserGroupFilter[user.JMMUserID][gf.GroupFilterID]; foreach (AnimeGroup grp in allGrps) { if (groups.Contains(grp.AnimeGroupID)) { // calculate stats gfeContract.GroupCount++; } } } gfs.Add(gfeContract); } ts = DateTime.Now - start; logger.Info("GetAllGroupFiltersExtended (FILTER) in {0} ms", ts.TotalMilliseconds); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return gfs; }
public List<MetroContract_Anime_Summary> GetAnimeContinueWatching(int maxRecords, int jmmuserID) { List<MetroContract_Anime_Summary> retAnime = new List<MetroContract_Anime_Summary>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { GroupFilterRepository repGF = new GroupFilterRepository(); JMMUserRepository repUsers = new JMMUserRepository(); JMMUser user = repUsers.GetByID(session, jmmuserID); if (user == null) return retAnime; // find the locked Continue Watching Filter GroupFilter gf = null; List<GroupFilter> lockedGFs = repGF.GetLockedGroupFilters(session); if (lockedGFs != null) { // if it already exists we can leave foreach (GroupFilter gfTemp in lockedGFs) { if (gfTemp.GroupFilterName.Equals(Constants.GroupFilterName.ContinueWatching, StringComparison.InvariantCultureIgnoreCase)) { gf = gfTemp; break; } } } if (gf == null) return retAnime; // Get all the groups // it is more efficient to just get the full list of groups and then filter them later AnimeGroupRepository repGroups = new AnimeGroupRepository(); List<AnimeGroup> allGrps = repGroups.GetAll(session); // get all the user records AnimeGroup_UserRepository repUserRecords = new AnimeGroup_UserRepository(); List<AnimeGroup_User> userRecords = repUserRecords.GetByUserID(session, jmmuserID); Dictionary<int, AnimeGroup_User> dictUserRecords = new Dictionary<int, AnimeGroup_User>(); foreach (AnimeGroup_User userRec in userRecords) dictUserRecords[userRec.AnimeGroupID] = userRec; // get all the groups in this filter for this user HashSet<int> groups = StatsCache.Instance.StatUserGroupFilter[user.JMMUserID][gf.GroupFilterID]; List<Contract_AnimeGroup> comboGroups = new List<Contract_AnimeGroup>(); foreach (AnimeGroup grp in allGrps) { if (groups.Contains(grp.AnimeGroupID)) { AnimeGroup_User userRec = null; if (dictUserRecords.ContainsKey(grp.AnimeGroupID)) userRec = dictUserRecords[grp.AnimeGroupID]; Contract_AnimeGroup rec = grp.ToContract(userRec); comboGroups.Add(rec); } } // apply sorting List<SortPropOrFieldAndDirection> sortCriteria = GroupFilterHelper.GetSortDescriptions(gf); comboGroups = Sorting.MultiSort<Contract_AnimeGroup>(comboGroups, sortCriteria); if ((StatsCache.Instance.StatUserGroupFilter.ContainsKey(user.JMMUserID)) && (StatsCache.Instance.StatUserGroupFilter[user.JMMUserID].ContainsKey(gf.GroupFilterID))) { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); foreach (Contract_AnimeGroup grp in comboGroups) { JMMServiceImplementation imp = new JMMServiceImplementation(); foreach (AnimeSeries ser in repSeries.GetByGroupID(session, grp.AnimeGroupID)) { if (!user.AllowedSeries(ser)) continue; AnimeSeries_User serUser = ser.GetUserRecord(session, jmmuserID); Contract_AnimeEpisode ep = imp.GetNextUnwatchedEpisode(session, ser.AnimeSeriesID, jmmuserID); if (ep != null) { AniDB_Anime anidb_anime = ser.GetAnime(session); MetroContract_Anime_Summary summ = new MetroContract_Anime_Summary(); summ.AnimeID = ser.AniDB_ID; summ.AnimeName = ser.GetSeriesName(session); summ.AnimeSeriesID = ser.AnimeSeriesID; summ.BeginYear = anidb_anime.BeginYear; summ.EndYear = anidb_anime.EndYear; //summ.PosterName = anidb_anime.GetDefaultPosterPathNoBlanks(session); if (serUser != null) summ.UnwatchedEpisodeCount = serUser.UnwatchedEpisodeCount; else summ.UnwatchedEpisodeCount = 0; ImageDetails imgDet = anidb_anime.GetDefaultPosterDetailsNoBlanks(session); summ.ImageType = (int)imgDet.ImageType; summ.ImageID = imgDet.ImageID; retAnime.Add(summ); // Lets only return the specified amount if (retAnime.Count == maxRecords) return retAnime; } else logger.Info(string.Format("GetAnimeContinueWatching:Skipping Anime - no episodes: {0}", ser.AniDB_ID)); } } } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return retAnime; }
public List<Contract_AnimeGroup> GetAllGroups(int userID) { List<Contract_AnimeGroup> grps = new List<Contract_AnimeGroup>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup_UserRepository repUserGroups = new AnimeGroup_UserRepository(); List<AnimeGroup> allGrps = repGroups.GetAll(session); // user records AnimeGroup_UserRepository repGroupUser = new AnimeGroup_UserRepository(); List<AnimeGroup_User> userRecordList = repGroupUser.GetByUserID(session, userID); Dictionary<int, AnimeGroup_User> dictUserRecords = new Dictionary<int, AnimeGroup_User>(); foreach (AnimeGroup_User grpUser in userRecordList) dictUserRecords[grpUser.AnimeGroupID] = grpUser; foreach (AnimeGroup ag in allGrps) { AnimeGroup_User userRec = null; if (dictUserRecords.ContainsKey(ag.AnimeGroupID)) userRec = dictUserRecords[ag.AnimeGroupID]; // calculate stats Contract_AnimeGroup contract = ag.ToContract(userRec); contract.ServerPosterPath = ag.GetPosterPathNoBlanks(session); grps.Add(contract); } grps.Sort(); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return grps; }
public static void GetAnimeSeriesRecursive(ISession session, int animeGroupID, ref List<AnimeSeries> seriesList) { AnimeGroupRepository rep = new AnimeGroupRepository(); AnimeGroup grp = rep.GetByID(session, animeGroupID); if (grp == null) return; // get the series for this group List<AnimeSeries> thisSeries = grp.GetSeries(session); seriesList.AddRange(thisSeries); foreach (AnimeGroup childGroup in grp.GetChildGroups(session)) { GetAnimeSeriesRecursive(session, childGroup.AnimeGroupID, ref seriesList); } }
public string DeleteAnimeGroup(int animeGroupID, bool deleteFiles) { try { AnimeSeriesRepository repAnimeSer = new AnimeSeriesRepository(); AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup grp = repGroups.GetByID(animeGroupID); if (grp == null) return "Group does not exist"; int? parentGroupID = grp.AnimeGroupParentID; foreach (AnimeSeries ser in grp.GetAllSeries()) { DeleteAnimeSeries(ser.AnimeSeriesID, deleteFiles, false); } // delete all sub groups foreach (AnimeGroup subGroup in grp.GetAllChildGroups()) { DeleteAnimeGroup(subGroup.AnimeGroupID, deleteFiles); } GroupFilterConditionRepository repConditions = new GroupFilterConditionRepository(); // delete any group filter conditions which reference these groups foreach (GroupFilterCondition gfc in repConditions.GetByConditionType(GroupFilterConditionType.AnimeGroup)) { int thisGrpID = 0; int.TryParse(gfc.ConditionParameter, out thisGrpID); if (thisGrpID == animeGroupID) repConditions.Delete(gfc.GroupFilterConditionID); } repGroups.Delete(grp.AnimeGroupID); // finally update stats if (parentGroupID.HasValue) { AnimeGroup grpParent = repGroups.GetByID(parentGroupID.Value); if (grpParent != null) { grpParent.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true); StatsCache.Instance.UpdateUsingGroup(grpParent.TopLevelAnimeGroup.AnimeGroupID); } } return ""; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return ex.Message; } }
public List<Contract_AnimeGroup> GetAnimeGroupsForFilter(int groupFilterID, int userID, bool getSingleSeriesGroups) { List<Contract_AnimeGroup> retGroups = new List<Contract_AnimeGroup>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { DateTime start = DateTime.Now; GroupFilterRepository repGF = new GroupFilterRepository(); JMMUserRepository repUsers = new JMMUserRepository(); JMMUser user = repUsers.GetByID(session, userID); if (user == null) return retGroups; GroupFilter gf = null; if (groupFilterID == -999) { // all groups gf = new GroupFilter(); gf.GroupFilterName = "All"; } else { gf = repGF.GetByID(session, groupFilterID); if (gf == null) return retGroups; } //Contract_GroupFilterExtended contract = gf.ToContractExtended(user); AnimeGroupRepository repGroups = new AnimeGroupRepository(); List<AnimeGroup> allGrps = repGroups.GetAll(session); AnimeGroup_UserRepository repUserRecords = new AnimeGroup_UserRepository(); List<AnimeGroup_User> userRecords = repUserRecords.GetByUserID(session, userID); Dictionary<int, AnimeGroup_User> dictUserRecords = new Dictionary<int, AnimeGroup_User>(); foreach (AnimeGroup_User userRec in userRecords) dictUserRecords[userRec.AnimeGroupID] = userRec; TimeSpan ts = DateTime.Now - start; string msg = string.Format("Got groups for filter DB: {0} - {1} in {2} ms", gf.GroupFilterName, allGrps.Count, ts.TotalMilliseconds); logger.Info(msg); start = DateTime.Now; AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); List<AnimeSeries> allSeries = new List<AnimeSeries>(); if (getSingleSeriesGroups) allSeries = repSeries.GetAll(session); if ((StatsCache.Instance.StatUserGroupFilter.ContainsKey(user.JMMUserID)) && (StatsCache.Instance.StatUserGroupFilter[user.JMMUserID].ContainsKey(gf.GroupFilterID))) { HashSet<int> groups = StatsCache.Instance.StatUserGroupFilter[user.JMMUserID][gf.GroupFilterID]; foreach (AnimeGroup grp in allGrps) { AnimeGroup_User userRec = null; if (dictUserRecords.ContainsKey(grp.AnimeGroupID)) userRec = dictUserRecords[grp.AnimeGroupID]; if (groups.Contains(grp.AnimeGroupID)) { Contract_AnimeGroup contractGrp = grp.ToContract(userRec); if (getSingleSeriesGroups) { if (contractGrp.Stat_SeriesCount == 1) { AnimeSeries ser = GetSeriesForGroup(grp.AnimeGroupID, allSeries); if (ser != null) contractGrp.SeriesForNameOverride = ser.ToContract(ser.GetUserRecord(session, userID)); } } retGroups.Add(contractGrp); } } } ts = DateTime.Now - start; msg = string.Format("Got groups for filter EVAL: {0} - {1} in {2} ms", gf.GroupFilterName, retGroups.Count, ts.TotalMilliseconds); logger.Info(msg); return retGroups; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return retGroups; }
public List<Contract_AnimeGroup> GetSubGroupsForGroup(int animeGroupID, int userID) { List<Contract_AnimeGroup> retGroups = new List<Contract_AnimeGroup>(); try { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup grp = repGroups.GetByID(animeGroupID); if (grp == null) return retGroups; foreach (AnimeGroup grpChild in grp.GetChildGroups()) retGroups.Add(grpChild.ToContract(grpChild.GetUserRecord(userID))); return retGroups; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return retGroups; }
public string AssociateSingleFileWithMultipleEpisodes(int videoLocalID, int animeSeriesID, int startEpNum, int endEpNum) { try { VideoLocalRepository repVids = new VideoLocalRepository(); VideoLocal vid = repVids.GetByID(videoLocalID); if (vid == null) return "Could not find video record"; AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); CrossRef_File_EpisodeRepository repXRefs = new CrossRef_File_EpisodeRepository(); AnimeSeries ser = repSeries.GetByID(animeSeriesID); if (ser == null) return "Could not find anime series record"; for (int i = startEpNum; i <= endEpNum; i++) { List<AniDB_Episode> anieps = repAniEps.GetByAnimeIDAndEpisodeNumber(ser.AniDB_ID, i); if (anieps.Count == 0) return "Could not find the AniDB episode record"; AniDB_Episode aniep = anieps[0]; List<AnimeEpisode> eps = repEps.GetByAniEpisodeIDAndSeriesID(aniep.EpisodeID, ser.AnimeSeriesID); if (eps.Count == 0) return "Could not find episode record"; AnimeEpisode ep = eps[0]; CrossRef_File_Episode xref = new CrossRef_File_Episode(); xref.PopulateManually(vid, ep); repXRefs.Save(xref); CommandRequest_WebCacheSendXRefFileEpisode cr = new CommandRequest_WebCacheSendXRefFileEpisode(xref.CrossRef_File_EpisodeID); cr.Save(); } vid.RenameIfRequired(); vid.MoveFileIfRequired(); ser.QueueUpdateStats(); // update epidsode added stats ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } return ""; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return ""; }
/// <summary> /// Delete a series, and everything underneath it (episodes, files) /// </summary> /// <param name="animeSeriesID"></param> /// <param name="deleteFiles">also delete the physical files</param> /// <returns></returns> public string DeleteAnimeSeries(int animeSeriesID, bool deleteFiles, bool deleteParentGroup) { try { AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeSeriesRepository repAnimeSer = new AnimeSeriesRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeSeries ser = repAnimeSer.GetByID(animeSeriesID); if (ser == null) return "Series does not exist"; int animeGroupID = ser.AnimeGroupID; foreach (AnimeEpisode ep in ser.GetAnimeEpisodes()) { foreach (VideoLocal vid in ep.GetVideoLocals()) { if (deleteFiles) { logger.Info("Deleting video local record and file: {0}", vid.FullServerPath); if (!File.Exists(vid.FullServerPath)) return "File could not be found"; File.Delete(vid.FullServerPath); } CommandRequest_DeleteFileFromMyList cmdDel = new CommandRequest_DeleteFileFromMyList(vid.Hash, vid.FileSize); cmdDel.Save(); repVids.Delete(vid.VideoLocalID); } repEps.Delete(ep.AnimeEpisodeID); } repAnimeSer.Delete(ser.AnimeSeriesID); // finally update stats AnimeGroup grp = repGroups.GetByID(animeGroupID); if (grp != null) { if (grp.GetAllSeries().Count == 0) { DeleteAnimeGroup(grp.AnimeGroupID, false); } else { grp.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true); StatsCache.Instance.UpdateUsingGroup(grp.TopLevelAnimeGroup.AnimeGroupID); } } return ""; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return ex.Message; } }
public void Save(AnimeSeries obj, bool updateGroups, bool onlyupdatestats, bool skipgroupfilters = false) { bool newSeries = false; AnimeGroup oldGroup = null; AnimeGroupRepository repGroups = new AnimeGroupRepository(); bool isMigrating = false; lock (obj) { if (obj.AnimeSeriesID == 0) { newSeries = true; // a new series } else { // get the old version from the DB AnimeSeries oldSeries; using (var session = JMMService.SessionFactory.OpenSession()) { oldSeries = session.Get <AnimeSeries>(obj.AnimeSeriesID); } if (oldSeries != null) { // means we are moving series to a different group if (oldSeries.AnimeGroupID != obj.AnimeGroupID) { oldGroup = repGroups.GetByID(oldSeries.AnimeGroupID); AnimeGroup newGroup = repGroups.GetByID(obj.AnimeGroupID); if (newGroup != null && newGroup.GroupName.Equals("AAA Migrating Groups AAA")) { isMigrating = true; } newSeries = true; } } } if (newSeries && !isMigrating) { using (var session = JMMService.SessionFactory.OpenSession()) { obj.Contract = null; // populate the database using (var transaction = session.BeginTransaction()) { session.SaveOrUpdate(obj); transaction.Commit(); } } } HashSet <GroupFilterConditionType> types = obj.UpdateContract(onlyupdatestats); using (var session = JMMService.SessionFactory.OpenSession()) { // populate the database using (var transaction = session.BeginTransaction()) { session.SaveOrUpdate(obj); transaction.Commit(); } } if (!skipgroupfilters && !isMigrating) { GroupFilterRepository.CreateOrVerifyTagsAndYearsFilters(false, obj.Contract?.AniDBAnime?.AniDBAnime?.AllTags, obj.Contract?.AniDBAnime?.AniDBAnime?.AirDate); //This call will create extra years or tags if the Group have a new year or tag obj.UpdateGroupFilters(types, null); } Cache.Update(obj); Changes.AddOrUpdate(obj.AnimeSeriesID); } if (updateGroups && !isMigrating) { if (newSeries) { logger.Trace("Updating group stats by series from AnimeSeriesRepository.Save: {0}", obj.AnimeSeriesID); AnimeGroup grp = repGroups.GetByID(obj.AnimeGroupID); if (grp != null) { repGroups.Save(grp, true, true); } } if (oldGroup != null) { logger.Trace("Updating group stats by group from AnimeSeriesRepository.Save: {0}", oldGroup.AnimeGroupID); repGroups.Save(oldGroup, true, true); } } }
public void RecreateAllGroups() { try { // pause queues JMMService.CmdProcessorGeneral.Paused = true; JMMService.CmdProcessorHasher.Paused = true; JMMService.CmdProcessorImages.Paused = true; AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup_UserRepository repGroupUser = new AnimeGroup_UserRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); // get all the old groups List<AnimeGroup> oldGroups = repGroups.GetAll(); List<AnimeGroup_User> oldGroupUsers = repGroupUser.GetAll(); // create a new group, where we will place all the series temporarily AnimeGroup tempGroup = new AnimeGroup(); tempGroup.GroupName = "AAA Migrating Groups AAA"; tempGroup.Description = "AAA Migrating Groups AAA"; tempGroup.SortName = "AAA Migrating Groups AAA"; tempGroup.DateTimeUpdated = DateTime.Now; tempGroup.DateTimeCreated = DateTime.Now; repGroups.Save(tempGroup); // move all series to the new group foreach (AnimeSeries ser in repSeries.GetAll()) { ser.AnimeGroupID = tempGroup.AnimeGroupID; repSeries.Save(ser, false); } // delete all the old groups foreach (AnimeGroup grp in oldGroups) repGroups.Delete(grp.AnimeGroupID); // delete all the old group user records foreach (AnimeGroup_User grpUser in oldGroupUsers) repGroupUser.Delete(grpUser.AnimeGroupID); // recreate groups foreach (AnimeSeries ser in repSeries.GetAll()) { bool createNewGroup = true; if (ServerSettings.AutoGroupSeries) { List<AnimeGroup> grps = AnimeGroup.GetRelatedGroupsFromAnimeID(ser.AniDB_ID); // only use if there is just one result if (grps != null && grps.Count > 0 && !grps[0].GroupName.Equals("AAA Migrating Groups AAA")) { ser.AnimeGroupID = grps[0].AnimeGroupID; createNewGroup = false; } } if (createNewGroup) { AnimeGroup anGroup = new AnimeGroup(); anGroup.Populate(ser); repGroups.Save(anGroup); ser.AnimeGroupID = anGroup.AnimeGroupID; } repSeries.Save(ser, false); } // delete the temp group if (tempGroup.GetAllSeries().Count == 0) repGroups.Delete(tempGroup.AnimeGroupID); // create group user records and update group stats foreach (AnimeGroup grp in repGroups.GetAll()) grp.UpdateStatsFromTopLevel(true, true); // un-pause queues JMMService.CmdProcessorGeneral.Paused = false; JMMService.CmdProcessorHasher.Paused = false; JMMService.CmdProcessorImages.Paused = false; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }
public static void CreateOrVerifyTagsAndYearsFilters(bool frominit = false, HashSet <string> tags = null, DateTime?airdate = null) { GroupFilterRepository repFilters = new GroupFilterRepository(); using (var session = JMMService.SessionFactory.OpenSession()) { string t = "GroupFilter"; List <GroupFilter> lockedGFs = repFilters.GetLockedGroupFilters(session); AniDB_TagRepository tagsrepo = new AniDB_TagRepository(); AnimeGroupRepository grouprepo = new AnimeGroupRepository(); GroupFilter tagsdirec = lockedGFs.FirstOrDefault(a => a.FilterType == (int)(GroupFilterType.Directory | GroupFilterType.Tag)); if (tagsdirec != null) { HashSet <string> alltags; if (tags == null) { alltags = new HashSet <string>(tagsrepo.GetAll(session).Select(a => a.TagName).Distinct(StringComparer.InvariantCultureIgnoreCase), StringComparer.InvariantCultureIgnoreCase); } else { alltags = new HashSet <string>(tags.Distinct(StringComparer.InvariantCultureIgnoreCase), StringComparer.InvariantCultureIgnoreCase); } HashSet <string> notin = new HashSet <string>(lockedGFs.Where(a => a.FilterType == (int)GroupFilterType.Tag).Select(a => a.Conditions.FirstOrDefault()?.ConditionParameter), StringComparer.InvariantCultureIgnoreCase); alltags.ExceptWith(notin); int max = alltags.Count; int cnt = 0; //AniDB Tags are in english so we use en-us culture TextInfo tinfo = new CultureInfo("en-US", false).TextInfo; foreach (string s in alltags) { cnt++; if (frominit) { ServerState.Instance.CurrentSetupStatus = string.Format(JMMServer.Properties.Resources.Database_Cache, t, Properties.Resources.Filter_CreatingTag + " '" + s + "'" + Properties.Resources.Filter_Filter + cnt + "/" + max); } GroupFilter yf = new GroupFilter { ParentGroupFilterID = tagsdirec.GroupFilterID, InvisibleInClients = 0, GroupFilterName = tinfo.ToTitleCase(s.Replace("`", "'")), BaseCondition = 1, Locked = 1, SortingCriteria = "5;1", FilterType = (int)GroupFilterType.Tag }; GroupFilterCondition gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.Tag; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = s; gfc.GroupFilterID = yf.GroupFilterID; yf.Conditions.Add(gfc); yf.EvaluateAnimeGroups(); yf.EvaluateAnimeSeries(); repFilters.Save(yf); } } GroupFilter yearsdirec = lockedGFs.FirstOrDefault(a => a.FilterType == (int)(GroupFilterType.Directory | GroupFilterType.Year)); if (yearsdirec != null) { HashSet <string> allyears; if (airdate == null) { List <Contract_AnimeGroup> grps = grouprepo.GetAll().Select(a => a.Contract).Where(a => a != null).ToList(); if (grps.Any(a => a.Stat_AirDate_Min.HasValue && a.Stat_AirDate_Max.HasValue)) { DateTime maxtime = grps.Where(a => a.Stat_AirDate_Max.HasValue).Max(a => a.Stat_AirDate_Max.Value); DateTime mintime = grps.Where(a => a.Stat_AirDate_Min.HasValue).Min(a => a.Stat_AirDate_Min.Value); allyears = new HashSet <string>( Enumerable.Range(mintime.Year, maxtime.Year - mintime.Year + 1) .Select(a => a.ToString()), StringComparer.InvariantCultureIgnoreCase); } else { allyears = new HashSet <string>(); } } else { allyears = new HashSet <string>(new string[] { airdate.Value.Year.ToString() }); } HashSet <string> notin = new HashSet <string>( lockedGFs.Where(a => a.FilterType == (int)GroupFilterType.Year) .Select(a => a.Conditions.FirstOrDefault()?.ConditionParameter), StringComparer.InvariantCultureIgnoreCase); allyears.ExceptWith(notin); int max = allyears.Count; int cnt = 0; foreach (string s in allyears) { cnt++; if (frominit) { ServerState.Instance.CurrentSetupStatus = string.Format(JMMServer.Properties.Resources.Database_Cache, t, Properties.Resources.Filter_CreatingYear + " '" + s + "' " + Properties.Resources.Filter_Filter + cnt + "/" + max); } GroupFilter yf = new GroupFilter { ParentGroupFilterID = yearsdirec.GroupFilterID, InvisibleInClients = 0, GroupFilterName = s, BaseCondition = 1, Locked = 1, SortingCriteria = "5;1", FilterType = (int)GroupFilterType.Year }; GroupFilterCondition gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.Year; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = s; gfc.GroupFilterID = yf.GroupFilterID; yf.Conditions.Add(gfc); yf.EvaluateAnimeGroups(); yf.EvaluateAnimeSeries(); repFilters.Save(yf); } } } }
public Contract_AnimeSeries_SaveResponse SaveSeries(Contract_AnimeSeries_Save contract, int userID) { Contract_AnimeSeries_SaveResponse contractout = new Contract_AnimeSeries_SaveResponse(); contractout.ErrorMessage = ""; contractout.AnimeSeries = null; try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = null; int? oldGroupID = null; if (contract.AnimeSeriesID.HasValue) { ser = repSeries.GetByID(contract.AnimeSeriesID.Value); if (ser == null) { contractout.ErrorMessage = "Could not find existing series with ID: " + contract.AnimeSeriesID.Value.ToString(); return contractout; } // check if we are moving a series oldGroupID = ser.AnimeGroupID; } else { ser = new AnimeSeries(); ser.DateTimeCreated = DateTime.Now; ser.DefaultAudioLanguage = ""; ser.DefaultSubtitleLanguage = ""; ser.MissingEpisodeCount = 0; ser.MissingEpisodeCountGroups = 0; ser.LatestLocalEpisodeNumber = 0; ser.SeriesNameOverride = ""; } ser.AnimeGroupID = contract.AnimeGroupID; ser.AniDB_ID = contract.AniDB_ID; ser.DefaultAudioLanguage = contract.DefaultAudioLanguage; ser.DefaultSubtitleLanguage = contract.DefaultSubtitleLanguage; ser.DateTimeUpdated = DateTime.Now; ser.SeriesNameOverride = contract.SeriesNameOverride; ser.DefaultFolder = contract.DefaultFolder; AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(ser.AniDB_ID); if (anime == null) { contractout.ErrorMessage = string.Format("Could not find anime record with ID: {0}", ser.AniDB_ID); return contractout; } repSeries.Save(ser); // update stats for groups //ser.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true ,true, true); ser.QueueUpdateStats(); if (oldGroupID.HasValue) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup grp = repGroups.GetByID(oldGroupID.Value); if (grp != null) { grp.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true); } } List<CrossRef_AniDB_TvDBV2> xrefs = ser.GetCrossRefTvDBV2(); List<CrossRef_AniDB_MAL> xrefMAL = ser.CrossRefMAL; List<TvDB_Series> sers = new List<TvDB_Series>(); foreach (CrossRef_AniDB_TvDBV2 xref in xrefs) sers.Add(xref.GetTvDBSeries()); CrossRef_AniDB_Other xrefMovie = ser.CrossRefMovieDB; MovieDB_Movie movie = null; if (xrefMovie != null) movie = xrefMovie.GetMovieDB_Movie(); contractout.AnimeSeries = ser.ToContract(anime, xrefs, ser.CrossRefMovieDB, ser.GetUserRecord(userID), sers, xrefMAL, false, null, null, null, null,movie); return contractout; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); contractout.ErrorMessage = ex.Message; return contractout; } }
public Contract_AnimeSeries_SaveResponse CreateSeriesFromAnime(int animeID, int? animeGroupID, int userID) { Contract_AnimeSeries_SaveResponse response = new Contract_AnimeSeries_SaveResponse(); response.AnimeSeries = null; response.ErrorMessage = ""; try { using (var session = JMMService.SessionFactory.OpenSession()) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); if (animeGroupID.HasValue) { AnimeGroup grp = repGroups.GetByID(session, animeGroupID.Value); if (grp == null) { response.ErrorMessage = "Could not find the specified group"; return response; } } // make sure a series doesn't already exists for this anime AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(session, animeID); if (ser != null) { response.ErrorMessage = "A series already exists for this anime"; return response; } // make sure the anime exists first AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(session, animeID); if (anime == null) anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(session, animeID, false, false); if (anime == null) { response.ErrorMessage = "Could not get anime information from AniDB"; return response; } if (animeGroupID.HasValue) { ser = new AnimeSeries(); ser.Populate(anime); ser.AnimeGroupID = animeGroupID.Value; repSeries.Save(ser); } else { ser = anime.CreateAnimeSeriesAndGroup(session); } ser.CreateAnimeEpisodes(session); // check if we have any group status data for this associated anime // if not we will download it now AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository(); if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(session); } ser.QueueUpdateStats(); // check for TvDB associations CommandRequest_TvDBSearchAnime cmd = new CommandRequest_TvDBSearchAnime(anime.AnimeID, false); cmd.Save(session); if (ServerSettings.Trakt_IsEnabled && !string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken)) { // check for Trakt associations CommandRequest_TraktSearchAnime cmd2 = new CommandRequest_TraktSearchAnime(anime.AnimeID, false); cmd2.Save(session); } List<CrossRef_AniDB_TvDBV2> xrefs = ser.GetCrossRefTvDBV2(); List<CrossRef_AniDB_MAL> xrefMAL = ser.CrossRefMAL; List<TvDB_Series> sers = new List<TvDB_Series>(); foreach (CrossRef_AniDB_TvDBV2 xref in xrefs) sers.Add(xref.GetTvDBSeries()); CrossRef_AniDB_Other xrefMovie = ser.CrossRefMovieDB; MovieDB_Movie movie = null; if (xrefMovie != null) movie = xrefMovie.GetMovieDB_Movie(); response.AnimeSeries = ser.ToContract(anime, xrefs, xrefMovie, ser.GetUserRecord(userID), sers, xrefMAL, false, null, null, null, null,movie); return response; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); response.ErrorMessage = ex.Message; } return response; }
private static void UpdateStatsTest() { AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in repGroups.GetAllTopLevelGroups()) { grp.UpdateStatsFromTopLevel(true, true); } }
public Contract_AnimeEpisode GetNextUnwatchedEpisodeForGroup(int animeGroupID, int userID) { try { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeSeriesRepository repAnimeSer = new AnimeSeriesRepository(); AnimeGroup grp = repGroups.GetByID(animeGroupID); if (grp == null) return null; List<AnimeSeries> allSeries = grp.GetAllSeries(); List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("AirDate", false, SortType.eDateTime)); allSeries = Sorting.MultiSort<AnimeSeries>(allSeries, sortCriteria); foreach (AnimeSeries ser in allSeries) { Contract_AnimeEpisode contract = GetNextUnwatchedEpisode(ser.AnimeSeriesID, userID); if (contract != null) return contract; } return null; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return null; } }
public List<Contract_AnimeEpisode> GetContinueWatchingFilter(int userID, int maxRecords) { List<Contract_AnimeEpisode> retEps = new List<Contract_AnimeEpisode>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { GroupFilterRepository repGF = new GroupFilterRepository(); JMMUserRepository repUsers = new JMMUserRepository(); JMMUser user = repUsers.GetByID(session, userID); if (user == null) return retEps; // find the locked Continue Watching Filter GroupFilter gf = null; List<GroupFilter> lockedGFs = repGF.GetLockedGroupFilters(session); if (lockedGFs != null) { // if it already exists we can leave foreach (GroupFilter gfTemp in lockedGFs) { if (gfTemp.FilterType == (int)GroupFilterType.ContinueWatching) { gf = gfTemp; break; } } } if (gf == null) return retEps; // Get all the groups // it is more efficient to just get the full list of groups and then filter them later AnimeGroupRepository repGroups = new AnimeGroupRepository(); List<AnimeGroup> allGrps = repGroups.GetAll(session); // get all the user records AnimeGroup_UserRepository repUserRecords = new AnimeGroup_UserRepository(); List<AnimeGroup_User> userRecords = repUserRecords.GetByUserID(session, userID); Dictionary<int, AnimeGroup_User> dictUserRecords = new Dictionary<int, AnimeGroup_User>(); foreach (AnimeGroup_User userRec in userRecords) dictUserRecords[userRec.AnimeGroupID] = userRec; // get all the groups in this filter for this user HashSet<int> groups = StatsCache.Instance.StatUserGroupFilter[user.JMMUserID][gf.GroupFilterID]; List<Contract_AnimeGroup> comboGroups = new List<Contract_AnimeGroup>(); foreach (AnimeGroup grp in allGrps) { if (groups.Contains(grp.AnimeGroupID)) { AnimeGroup_User userRec = null; if (dictUserRecords.ContainsKey(grp.AnimeGroupID)) userRec = dictUserRecords[grp.AnimeGroupID]; Contract_AnimeGroup rec = grp.ToContract(userRec); comboGroups.Add(rec); } } // apply sorting List<SortPropOrFieldAndDirection> sortCriteria = GroupFilterHelper.GetSortDescriptions(gf); comboGroups = Sorting.MultiSort<Contract_AnimeGroup>(comboGroups, sortCriteria); if ((StatsCache.Instance.StatUserGroupFilter.ContainsKey(user.JMMUserID)) && (StatsCache.Instance.StatUserGroupFilter[user.JMMUserID].ContainsKey(gf.GroupFilterID))) { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); foreach (Contract_AnimeGroup grp in comboGroups) { List<AnimeSeries> sers = repSeries.GetByGroupID(session, grp.AnimeGroupID); // sort the series by air date List<SortPropOrFieldAndDirection> sortCriteria2 = new List<SortPropOrFieldAndDirection>(); sortCriteria2.Add(new SortPropOrFieldAndDirection("AirDate", false, SortType.eDateTime)); sers = Sorting.MultiSort<AnimeSeries>(sers, sortCriteria2); List<int> seriesWatching = new List<int>(); foreach (AnimeSeries ser in sers) { if (!user.AllowedSeries(ser)) continue; bool useSeries = true; if (seriesWatching.Count > 0) { if (ser.GetAnime().AnimeType == (int)enAnimeType.TVSeries) { // make sure this series is not a sequel to an existing series we have already added foreach (AniDB_Anime_Relation rel in ser.GetAnime().GetRelatedAnime()) { if (rel.RelationType.ToLower().Trim().Equals("sequel") || rel.RelationType.ToLower().Trim().Equals("prequel")) useSeries = false; } } } if (!useSeries) continue; Contract_AnimeEpisode ep = GetNextUnwatchedEpisode(session, ser.AnimeSeriesID, userID); if (ep != null) { retEps.Add(ep); // Lets only return the specified amount if (retEps.Count == maxRecords) return retEps; if (ser.GetAnime().AnimeType == (int)enAnimeType.TVSeries) seriesWatching.Add(ser.AniDB_ID); } } } } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return retEps; }
public List<AnimeGroup> GetChildGroups(ISession session) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); return repGroups.GetByParentID(session, this.AnimeGroupID); }
private void ProcessFile_AniDB(VideoLocal vidLocal) { logger.Trace("Checking for AniDB_File record for: {0} --- {1}", vidLocal.Hash, vidLocal.FilePath); // check if we already have this AniDB_File info in the database AniDB_FileRepository repAniFile = new AniDB_FileRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AniDB_AnimeRepository repAniAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); VideoLocalRepository repVidLocals = new VideoLocalRepository(); AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); CrossRef_File_EpisodeRepository repXrefFE = new CrossRef_File_EpisodeRepository(); AniDB_File aniFile = null; if (!ForceAniDB) { aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) logger.Trace("AniDB_File record not found"); } int animeID = 0; if (aniFile == null) { // get info from AniDB logger.Debug("Getting AniDB_File record from AniDB...."); Raw_AniDB_File fileInfo = JMMService.AnidbProcessor.GetFileInfo(vidLocal); if (fileInfo != null) { // check if we already have a record aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) aniFile = new AniDB_File(); aniFile.Populate(fileInfo); //overwrite with local file name string localFileName = Path.GetFileName(vidLocal.FilePath); aniFile.FileName = localFileName; repAniFile.Save(aniFile, false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW)) { string[] epIDs = fileInfo.OtherEpisodesRAW.Split(','); foreach (string epid in epIDs) { int id = 0; if (int.TryParse(epid, out id)) { CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id); cmdEp.Save(); } } } animeID = aniFile.AnimeID; } } bool missingEpisodes = false; // if we still haven't got the AniDB_File Info we try the web cache or local records if (aniFile == null) { // check if we have any records from previous imports List<CrossRef_File_Episode> crossRefs = repXrefFE.GetByHash(vidLocal.Hash); if (crossRefs == null || crossRefs.Count == 0) { // lets see if we can find the episode/anime info from the web cache if (ServerSettings.WebCache_XRefFileEpisode_Get) { crossRefs = XMLService.Get_CrossRef_File_Episode(vidLocal); if (crossRefs == null || crossRefs.Count == 0) { logger.Debug("Cannot find AniDB_File record or get cross ref from web cache record so exiting: {0}", vidLocal.ED2KHash); return; } else { foreach (CrossRef_File_Episode xref in crossRefs) { // in this case we need to save the cross refs manually as AniDB did not provide them repXrefFE.Save(xref); } } } else { logger.Debug("Cannot get AniDB_File record so exiting: {0}", vidLocal.ED2KHash); return; } } // we assume that all episodes belong to the same anime foreach (CrossRef_File_Episode xref in crossRefs) { animeID = xref.AnimeID; AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID); if (ep == null) missingEpisodes = true; } } else { // check if we have the episode info // if we don't, we will need to re-download the anime info (which also has episode info) if (aniFile.EpisodeCrossRefs.Count == 0) { animeID = aniFile.AnimeID; // if we have the anidb file, but no cross refs it means something has been broken logger.Debug("Could not find any cross ref records for: {0}", vidLocal.ED2KHash); missingEpisodes = true; } else { foreach (CrossRef_File_Episode xref in aniFile.EpisodeCrossRefs) { AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID); if (ep == null) missingEpisodes = true; animeID = xref.AnimeID; } } } // get from DB AniDB_Anime anime = repAniAnime.GetByAnimeID(animeID); bool animeRecentlyUpdated = false; if (anime != null) { TimeSpan ts = DateTime.Now - anime.DateTimeUpdated; if (ts.TotalHours < 4) animeRecentlyUpdated = true; } // even if we are missing episode info, don't get data more than once every 4 hours // this is to prevent banning if (missingEpisodes && !animeRecentlyUpdated) { logger.Debug("Getting Anime record from AniDB...."); // try using the cache first using (var session = JMMService.SessionFactory.OpenSession()) { anime = JMMService.AnidbProcessor.GetAnimeInfoHTTPFromCache(session, animeID, ServerSettings.AutoGroupSeries); } // if not in cache try from AniDB if (anime == null) anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.AutoGroupSeries); } // create the group/series/episode records if needed AnimeSeries ser = null; if (anime != null) { logger.Debug("Creating groups, series and episodes...."); // check if there is an AnimeSeries Record associated with this AnimeID ser = repSeries.GetByAnimeID(animeID); if (ser == null) { // create a new AnimeSeries record ser = anime.CreateAnimeSeriesAndGroup(); } ser.CreateAnimeEpisodes(); // check if we have any group status data for this associated anime // if not we will download it now AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository(); if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(); } // update stats ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } } vidLocal.RenameIfRequired(); vidLocal.MoveFileIfRequired(); // update stats for groups and series if (ser != null) { // update all the groups above this series in the heirarchy ser.UpdateStats(true, true, true); StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); } // Add this file to the users list if (ServerSettings.AniDB_MyList_AddFiles) { CommandRequest_AddFileToMyList cmd = new CommandRequest_AddFileToMyList(vidLocal.ED2KHash); cmd.Save(); } // lets also try adding to the users trakt collecion by sync'ing the series if (ser != null) { CommandRequest_TraktSyncCollectionSeries cmdTrakt = new CommandRequest_TraktSyncCollectionSeries(ser.AnimeSeriesID, ser.GetAnime().MainTitle); cmdTrakt.Save(); } // sync the series on MAL if (ser != null) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } }
public Contract_AnimeGroup GetGroup(int animeGroupID, int userID) { try { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeGroup grp = repGroups.GetByID(animeGroupID); if (grp == null) return null; Contract_AnimeGroup contractGrpTemp = grp.ToContract(grp.GetUserRecord(userID)); return contractGrpTemp; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return null; }