/// <summary> /// Updates all Group Filters. This should be done as the last step. /// </summary> /// <remarks> /// Assumes that all caches are up to date. /// </remarks> private void UpdateGroupFilters(ISessionWrapper session) { _log.Info("Updating Group Filters"); _log.Info("Calculating Tag Filters"); ServerState.Instance.DatabaseBlocked = new ServerState.DatabaseBlockedInfo { Blocked = true, Status = "Calculating Tag Filters" }; _groupFilterRepo.CalculateAnimeSeriesPerTagGroupFilter(session); _log.Info("Calculating All Other Filters"); ServerState.Instance.DatabaseBlocked = new ServerState.DatabaseBlockedInfo { Blocked = true, Status = "Calculating Non-Tag Filters" }; IEnumerable <SVR_GroupFilter> grpFilters = _groupFilterRepo.GetAll(session).Where(a => a.FilterType != (int)GroupFilterType.Tag && ((GroupFilterType)a.FilterType & GroupFilterType.Directory) == 0).ToList(); // The main reason for doing this in parallel is because UpdateEntityReferenceStrings does JSON encoding // and is enough work that it can benefit from running in parallel Parallel.ForEach( grpFilters, filter => { filter.SeriesIds.Clear(); filter.CalculateGroupsAndSeries(); filter.UpdateEntityReferenceStrings(); }); using (ITransaction trans = session.BeginTransaction()) { _groupFilterRepo.BatchUpdate(session, grpFilters); trans.Commit(); } _log.Info("Group Filters updated"); }
public void UpdateGroupFilters() { AnimeGroupRepository repGroups = new AnimeGroupRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); GroupFilterRepository repGrpFilter = new GroupFilterRepository(); List <GroupFilter> gfs = repGrpFilter.GetAll(); List <AnimeGroup> allGrps = repGroups.GetAllTopLevelGroups(); // No Need of subgroups List <AnimeSeries> allSeries = repSeries.GetAll(); foreach (GroupFilter gf in gfs) { bool change = false; foreach (AnimeGroup grp in allGrps) { Contract_AnimeGroup cgrp = grp.GetUserContract(this.JMMUserID); change |= gf.CalculateGroupFilterGroups(cgrp, Contract, JMMUserID); } foreach (AnimeSeries ser in allSeries) { Contract_AnimeSeries cser = ser.GetUserContract(this.JMMUserID); change |= gf.CalculateGroupFilterSeries(cser, Contract, JMMUserID); } if (change) { repGrpFilter.Save(gf); } } }
/// <summary> /// Updates all Group Filters. This should be done as the last step. /// </summary> /// <remarks> /// Assumes that all caches are up to date. /// </remarks> private void UpdateGroupFilters(ISessionWrapper session) { _log.Info("Updating Group Filters"); IReadOnlyList <GroupFilter> grpFilters = _groupFilterRepo.GetAll(session); ILookup <int, int> groupsForTagGroupFilter = _groupFilterRepo.CalculateAnimeGroupsPerTagGroupFilter(session); IReadOnlyList <JMMUser> users = _userRepo.GetAll(); // The main reason for doing this in parallel is because UpdateEntityReferenceStrings does JSON encoding // and is enough work that it can benefit from running in parallel Parallel.ForEach(grpFilters.Where(f => ((GroupFilterType)f.FilterType & GroupFilterType.Directory) != GroupFilterType.Directory), filter => { var userGroupIds = filter.GroupsIds; userGroupIds.Clear(); if (filter.FilterType == (int)GroupFilterType.Tag) { foreach (var user in users) { userGroupIds[user.JMMUserID] = groupsForTagGroupFilter[filter.GroupFilterID].ToHashSet(); } } else // All other group filters are to be handled normally { filter.EvaluateAnimeGroups(); } filter.UpdateEntityReferenceStrings(updateGroups: true, updateSeries: false); }); _groupFilterRepo.BatchUpdate(session, grpFilters); _log.Info("Group Filters updated"); }
/// <summary> /// Updates all Group Filters. This should be done as the last step. /// </summary> /// <remarks> /// Assumes that all caches are up to date. /// </remarks> private void UpdateGroupFilters(ISessionWrapper session) { _log.Info("Updating Group Filters"); IReadOnlyList <SVR_GroupFilter> grpFilters = _groupFilterRepo.GetAll(session); ILookup <int, int> seriesForTagGroupFilter = _groupFilterRepo.CalculateAnimeSeriesPerTagGroupFilter(session); IReadOnlyList <SVR_JMMUser> users = _userRepo.GetAll(); // The main reason for doing this in parallel is because UpdateEntityReferenceStrings does JSON encoding // and is enough work that it can benefit from running in parallel Parallel.ForEach( grpFilters.Where(f => ((GroupFilterType)f.FilterType & GroupFilterType.Directory) != GroupFilterType.Directory), filter => { filter.SeriesIds.Clear(); if (filter.FilterType == (int)GroupFilterType.Tag) { filter.SeriesIds[0] = seriesForTagGroupFilter[filter.GroupFilterID].ToHashSet(); filter.GroupsIds[0] = filter.SeriesIds[0] .Select(id => RepoFactory.AnimeSeries.GetByID(id).TopLevelAnimeGroup?.AnimeGroupID ?? -1) .Where(id => id != -1).ToHashSet(); foreach (var user in users) { filter.SeriesIds[user.JMMUserID] = seriesForTagGroupFilter[filter.GroupFilterID] .Select(id => RepoFactory.AnimeSeries.GetByID(id)) .Where(ser => !(ser.GetAnime()?.GetAllTags()?.FindInEnumerable(user.GetHideCategories()) ?? false)).Select(a => a.AnimeSeriesID).ToHashSet(); filter.GroupsIds[user.JMMUserID] = filter.SeriesIds[user.JMMUserID] .Select(id => RepoFactory.AnimeSeries.GetByID(id).TopLevelAnimeGroup?.AnimeGroupID ?? -1) .Where(id => id != -1).ToHashSet(); } } else // All other group filters are to be handled normally { filter.CalculateGroupsAndSeries(); } filter.UpdateEntityReferenceStrings(); }); _groupFilterRepo.BatchUpdate(session, grpFilters); _log.Info("Group Filters updated"); }
public void DeleteFromFilters() { GroupFilterRepository repo = new GroupFilterRepository(); foreach (GroupFilter gf in repo.GetAll()) { bool change = false; if (gf.SeriesIds.ContainsKey(JMMUserID)) { if (gf.SeriesIds[JMMUserID].Contains(AnimeSeriesID)) { gf.SeriesIds[JMMUserID].Remove(AnimeSeriesID); change = true; } } if (change) { repo.Save(gf); } } }
private static void CreateInitialGroupFilters() { // group filters GroupFilterRepository repFilters = new GroupFilterRepository(); GroupFilterConditionRepository repGFC = new GroupFilterConditionRepository(); if (repFilters.GetAll().Count() > 0) { return; } Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(ServerSettings.Culture); // Favorites GroupFilter gf = new GroupFilter(); gf.GroupFilterName = JMMServer.Properties.Resources.Filter_Favorites; gf.ApplyToSeries = 0; gf.BaseCondition = 1; gf.Locked = 0; gf.FilterType = (int)GroupFilterType.UserDefined; GroupFilterCondition gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.Favourite; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = ""; gf.Conditions.Add(gfc); gf.EvaluateAnimeGroups(); gf.EvaluateAnimeSeries(); repFilters.Save(gf); // Missing Episodes gf = new GroupFilter(); gf.GroupFilterName = JMMServer.Properties.Resources.Filter_MissingEpisodes; gf.ApplyToSeries = 0; gf.BaseCondition = 1; gf.Locked = 0; gf.FilterType = (int)GroupFilterType.UserDefined; gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.MissingEpisodesCollecting; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = ""; gf.Conditions.Add(gfc); gf.EvaluateAnimeGroups(); gf.EvaluateAnimeSeries(); repFilters.Save(gf); // Newly Added Series gf = new GroupFilter(); gf.GroupFilterName = JMMServer.Properties.Resources.Filter_Added; gf.ApplyToSeries = 0; gf.BaseCondition = 1; gf.Locked = 0; gf.FilterType = (int)GroupFilterType.UserDefined; gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.SeriesCreatedDate; gfc.ConditionOperator = (int)GroupFilterOperator.LastXDays; gfc.ConditionParameter = "10"; gf.Conditions.Add(gfc); gf.EvaluateAnimeGroups(); gf.EvaluateAnimeSeries(); repFilters.Save(gf); // Newly Airing Series gf = new GroupFilter(); gf.GroupFilterName = JMMServer.Properties.Resources.Filter_Airing; gf.ApplyToSeries = 0; gf.BaseCondition = 1; gf.Locked = 0; gf.FilterType = (int)GroupFilterType.UserDefined; gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.AirDate; gfc.ConditionOperator = (int)GroupFilterOperator.LastXDays; gfc.ConditionParameter = "30"; gf.Conditions.Add(gfc); gf.EvaluateAnimeGroups(); gf.EvaluateAnimeSeries(); repFilters.Save(gf); // Votes Needed gf = new GroupFilter(); gf.GroupFilterName = JMMServer.Properties.Resources.Filter_Votes; gf.ApplyToSeries = 0; gf.BaseCondition = 1; gf.Locked = 0; gf.FilterType = (int)GroupFilterType.UserDefined; gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.CompletedSeries; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = ""; gf.Conditions.Add(gfc); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.HasUnwatchedEpisodes; gfc.ConditionOperator = (int)GroupFilterOperator.Exclude; gfc.ConditionParameter = ""; gf.Conditions.Add(gfc); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.UserVotedAny; gfc.ConditionOperator = (int)GroupFilterOperator.Exclude; gfc.ConditionParameter = ""; gf.Conditions.Add(gfc); gf.EvaluateAnimeGroups(); gf.EvaluateAnimeSeries(); repFilters.Save(gf); // Recently Watched gf = new GroupFilter(); gf.GroupFilterName = JMMServer.Properties.Resources.Filter_RecentlyWatched; gf.ApplyToSeries = 0; gf.BaseCondition = 1; gf.Locked = 0; gf.FilterType = (int)GroupFilterType.UserDefined; gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.EpisodeWatchedDate; gfc.ConditionOperator = (int)GroupFilterOperator.LastXDays; gfc.ConditionParameter = "10"; gf.Conditions.Add(gfc); gf.EvaluateAnimeGroups(); gf.EvaluateAnimeSeries(); repFilters.Save(gf); // TvDB/MovieDB Link Missing gf = new GroupFilter(); gf.GroupFilterName = JMMServer.Properties.Resources.Filter_LinkMissing; gf.ApplyToSeries = 0; gf.BaseCondition = 1; gf.Locked = 0; gf.FilterType = (int)GroupFilterType.UserDefined; gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.AssignedTvDBOrMovieDBInfo; gfc.ConditionOperator = (int)GroupFilterOperator.Exclude; gfc.ConditionParameter = ""; gf.Conditions.Add(gfc); gf.EvaluateAnimeGroups(); gf.EvaluateAnimeSeries(); repFilters.Save(gf); }
public System.IO.Stream GetFilters(string uid) { JMMUser user = KodiHelper.GetUser(uid); if (user == null) { return(new MemoryStream()); } int userid = user.JMMUserID; KodiObject ret = new KodiObject(KodiHelper.NewMediaContainer("Anime", false)); if (!ret.Init()) { return(new MemoryStream()); } List <Video> dirs = new List <Video>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { GroupFilterRepository repGF = new GroupFilterRepository(); List <GroupFilter> allGfs = repGF.GetAll(session); Dictionary <int, HashSet <int> > gstats = StatsCache.Instance.StatUserGroupFilter[userid]; foreach (GroupFilter gg in allGfs.ToArray()) { if ((!StatsCache.Instance.StatUserGroupFilter.ContainsKey(userid)) || (!StatsCache.Instance.StatUserGroupFilter[userid].ContainsKey(gg.GroupFilterID))) { allGfs.Remove(gg); } } AnimeGroupRepository repGroups = new AnimeGroupRepository(); allGfs.Insert(0, new GroupFilter() { GroupFilterName = "All", GroupFilterID = -999 }); foreach (GroupFilter gg in allGfs) { Random rnd = new Random(123456789); Directory pp = new Directory(); pp.Key = KodiHelper.ServerUrl(int.Parse(ServerSettings.JMMServerPort), MainWindow.PathAddressKodi + "/GetMetadata/" + userid + "/" + (int)JMMType.GroupFilter + "/" + gg.GroupFilterID); pp.PrimaryExtraKey = pp.Key; pp.Title = gg.GroupFilterName; HashSet <int> groups; groups = gg.GroupFilterID == -999 ? new HashSet <int>(repGroups.GetAllTopLevelGroups(session).Select(a => a.AnimeGroupID)) : gstats[gg.GroupFilterID]; if (groups.Count != 0) { bool repeat; int nn = 0; pp.LeafCount = groups.Count.ToString(); pp.ViewedLeafCount = "0"; do { repeat = true; int grp = groups.ElementAt(rnd.Next(groups.Count)); AnimeGroup ag = repGroups.GetByID(grp); List <AnimeSeries> sers = ag.GetSeries(session); if (sers.Count > 0) { AnimeSeries ser = sers[rnd.Next(sers.Count)]; AniDB_Anime anim = ser.GetAnime(session); if (anim != null) { ImageDetails poster = anim.GetDefaultPosterDetailsNoBlanks(session); ImageDetails fanart = anim.GetDefaultFanartDetailsNoBlanks(session); if (poster != null) { pp.Thumb = poster.GenPoster(); } if (fanart != null) { pp.Art = fanart.GenArt(); } if (poster != null) { repeat = false; } } } nn++; if ((repeat) && (nn == 15)) { repeat = false; } } while (repeat); dirs.Add(pp); } } VideoLocalRepository repVids = new VideoLocalRepository(); List <VideoLocal> vids = repVids.GetVideosWithoutEpisode(); if (vids.Count > 0) { JMMContracts.KodiContracts.Directory pp = new JMMContracts.KodiContracts.Directory(); pp.Key = pp.PrimaryExtraKey = KodiHelper.ServerUrl(int.Parse(ServerSettings.JMMServerPort), MainWindow.PathAddressKodi + "/GetMetadata/0/" + (int)JMMType.GroupUnsort + "/0"); pp.Title = "Unsort"; pp.Thumb = KodiHelper.ServerUrl(int.Parse(ServerSettings.JMMServerPort), MainWindow.PathAddressKodi + "/GetSupportImage/plex_unsort.png"); pp.LeafCount = vids.Count.ToString(); pp.ViewedLeafCount = "0"; dirs.Add(pp); } dirs = dirs.OrderBy(a => a.Title).ToList(); } ret.Childrens = dirs; return(ret.GetStream()); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return(new MemoryStream()); } }
private static void CreateInitialGroupFilters() { // group filters GroupFilterRepository repFilters = new GroupFilterRepository(); GroupFilterConditionRepository repGFC = new GroupFilterConditionRepository(); if (repFilters.GetAll().Count() > 0) { return; } // Favorites GroupFilter gf = new GroupFilter(); gf.GroupFilterName = "Favorites"; gf.ApplyToSeries = 0; gf.BaseCondition = 1; repFilters.Save(gf); GroupFilterCondition gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.Favourite; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = ""; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); // Missing Episodes gf = new GroupFilter(); gf.GroupFilterName = "Missing Episodes"; gf.ApplyToSeries = 0; gf.BaseCondition = 1; repFilters.Save(gf); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.MissingEpisodesCollecting; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = ""; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); // Newly Added Series gf = new GroupFilter(); gf.GroupFilterName = "Newly Added Series"; gf.ApplyToSeries = 0; gf.BaseCondition = 1; repFilters.Save(gf); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.SeriesCreatedDate; gfc.ConditionOperator = (int)GroupFilterOperator.LastXDays; gfc.ConditionParameter = "10"; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); // Newly Airing Series gf = new GroupFilter(); gf.GroupFilterName = "Newly Airing Series"; gf.ApplyToSeries = 0; gf.BaseCondition = 1; repFilters.Save(gf); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.AirDate; gfc.ConditionOperator = (int)GroupFilterOperator.LastXDays; gfc.ConditionParameter = "30"; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); // Votes Needed gf = new GroupFilter(); gf.GroupFilterName = "Votes Needed"; gf.ApplyToSeries = 0; gf.BaseCondition = 1; repFilters.Save(gf); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.CompletedSeries; gfc.ConditionOperator = (int)GroupFilterOperator.Include; gfc.ConditionParameter = ""; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.HasUnwatchedEpisodes; gfc.ConditionOperator = (int)GroupFilterOperator.Exclude; gfc.ConditionParameter = ""; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.UserVotedAny; gfc.ConditionOperator = (int)GroupFilterOperator.Exclude; gfc.ConditionParameter = ""; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); // Recently Watched gf = new GroupFilter(); gf.GroupFilterName = "Recently Watched"; gf.ApplyToSeries = 0; gf.BaseCondition = 1; repFilters.Save(gf); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.EpisodeWatchedDate; gfc.ConditionOperator = (int)GroupFilterOperator.LastXDays; gfc.ConditionParameter = "10"; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); // TvDB/MovieDB Link Missing gf = new GroupFilter(); gf.GroupFilterName = "TvDB/MovieDB Link Missing"; gf.ApplyToSeries = 0; gf.BaseCondition = 1; repFilters.Save(gf); gfc = new GroupFilterCondition(); gfc.ConditionType = (int)GroupFilterConditionType.AssignedTvDBOrMovieDBInfo; gfc.ConditionOperator = (int)GroupFilterOperator.Exclude; gfc.ConditionParameter = ""; gfc.GroupFilterID = gf.GroupFilterID; repGFC.Save(gfc); }
public System.IO.Stream GetFilters(string uid) { int t = 0; int.TryParse(uid, out t); JMMUser user = t > 0 ? PlexHelper.GetJMMUser(uid) : PlexHelper.GetUser(uid); if (user == null) { return(new MemoryStream()); } int userid = user.JMMUserID; HistoryInfo info = new HistoryInfo { Key = PlexHelper.ConstructFiltersUrl(userid), Title = "Anime" }; PlexObject ret = new PlexObject(PlexHelper.NewMediaContainer(MediaContainerTypes.Show, info, false)); if (!ret.Init()) { return(new MemoryStream()); } List <Video> dirs = new List <Video>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { GroupFilterRepository repGF = new GroupFilterRepository(); List <GroupFilter> allGfs = repGF.GetAll(session); Dictionary <int, HashSet <int> > gstats = StatsCache.Instance.StatUserGroupFilter[userid]; foreach (GroupFilter gg in allGfs.ToArray()) { if ((!StatsCache.Instance.StatUserGroupFilter.ContainsKey(userid)) || (!StatsCache.Instance.StatUserGroupFilter[userid].ContainsKey(gg.GroupFilterID))) { allGfs.Remove(gg); } } AnimeGroupRepository repGroups = new AnimeGroupRepository(); allGfs.Insert(0, new GroupFilter() { GroupFilterName = "All", GroupFilterID = -999 }); foreach (GroupFilter gg in allGfs) { Random rnd = new Random(123456789); Directory pp = new Directory { Type = "show" }; pp.Key = PlexHelper.ConstructFilterIdUrl(userid, gg.GroupFilterID); pp.Title = gg.GroupFilterName; HashSet <int> groups; groups = gg.GroupFilterID == -999 ? new HashSet <int>(repGroups.GetAllTopLevelGroups(session).Select(a => a.AnimeGroupID)) : gstats[gg.GroupFilterID]; if (groups.Count != 0) { bool repeat; int nn = 0; pp.LeafCount = groups.Count.ToString(); pp.ViewedLeafCount = "0"; do { repeat = true; int grp = groups.ElementAt(rnd.Next(groups.Count)); AnimeGroup ag = repGroups.GetByID(grp); List <AnimeSeries> sers = ag.GetSeries(session); if (sers.Count > 0) { AnimeSeries ser = sers[rnd.Next(sers.Count)]; AniDB_Anime anim = ser.GetAnime(session); if (anim != null) { ImageDetails poster = anim.GetDefaultPosterDetailsNoBlanks(session); ImageDetails fanart = anim.GetDefaultFanartDetailsNoBlanks(session); if (poster != null) { pp.Thumb = poster.GenPoster(); } if (fanart != null) { pp.Art = fanart.GenArt(); } if (poster != null) { repeat = false; } } } nn++; if ((repeat) && (nn == 15)) { repeat = false; } } while (repeat); dirs.Add(pp, info); } } VideoLocalRepository repVids = new VideoLocalRepository(); List <VideoLocal> vids = repVids.GetVideosWithoutEpisode(); if (vids.Count > 0) { Directory pp = new Directory() { Type = "show" }; pp.Key = PlexHelper.ConstructUnsortUrl(userid); pp.Title = "Unsort"; pp.Thumb = PlexHelper.ConstructSupportImageLink("plex_unsort.png"); pp.LeafCount = vids.Count.ToString(); pp.ViewedLeafCount = "0"; dirs.Add(pp, info); } var repPlaylist = new PlaylistRepository(); var playlists = repPlaylist.GetAll(); if (playlists.Count > 0) { Directory pp = new Directory() { Type = "show" }; pp.Key = PlexHelper.ConstructPlaylistUrl(userid); pp.Title = "Playlists"; pp.Thumb = PlexHelper.ConstructSupportImageLink("plex_playlists.png"); pp.LeafCount = playlists.Count.ToString(); pp.ViewedLeafCount = "0"; dirs.Add(pp, info); } dirs = dirs.OrderBy(a => a.Title).ToList(); } ret.Childrens = dirs; return(ret.GetStream()); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return(new MemoryStream()); } }