예제 #1
0
        private static List <SearchResult> SearchTagsEquals(string query, int limit, SVR_JMMUser user, ParallelQuery <AniDB_Tag> allTags)
        {
            List <SearchResult>     series     = new List <SearchResult>();
            IEnumerable <CustomTag> customTags = RepoFactory.CustomTag.GetAll();

            series.AddRange(customTags.Where(a => a.TagName.Equals(query, StringComparison.InvariantCultureIgnoreCase)).SelectMany(tag =>
            {
                return(RepoFactory.CrossRef_CustomTag.GetByCustomTagID(tag.CustomTagID)
                       .Select(xref =>
                {
                    if (xref.CrossRefType != (int)CustomTagCrossRefType.Anime)
                    {
                        return null;
                    }
                    var anime = RepoFactory.AnimeSeries.GetByAnimeID(xref.CrossRefID);
                    // Because we are searching tags, then getting series from it, we need to make sure it's allowed
                    // for example, p**n could have the drugs tag, even though it's not a "p**n tag"
                    if (anime?.GetAnime()?.GetAllTags().FindInEnumerable(user.GetHideCategories()) ?? true)
                    {
                        return null;
                    }
                    return new SearchResult
                    {
                        Distance = 0,
                        Index = 0,
                        Match = tag.TagName,
                        Result = anime,
                        ExactMatch = true
                    };
                }).Where(a => a != null).OrderBy(a => a.Distance).ThenBy(a => a.Result.GetSeriesName()));
            }).Take(limit));

            limit -= series.Count;

            series.AddRange(allTags.Where(a => a.TagName.Equals(query, StringComparison.InvariantCultureIgnoreCase)).SelectMany(tag =>
            {
                return(RepoFactory.AniDB_Anime_Tag.GetByTagID(tag.TagID)
                       .Select(xref =>
                {
                    var anime = RepoFactory.AnimeSeries.GetByAnimeID(xref.AnimeID);
                    // Because we are searching tags, then getting series from it, we need to make sure it's allowed
                    // for example, p**n could have the drugs tag, even though it's not a "p**n tag"
                    if (anime?.GetAnime()?.GetAllTags().FindInEnumerable(user.GetHideCategories()) ?? true)
                    {
                        return null;
                    }
                    return new SearchResult
                    {
                        Distance = (600 - xref.Weight) / 600D,
                        Index = 0,
                        Match = tag.TagName,
                        Result = anime,
                        ExactMatch = true
                    };
                }).Where(a => a != null).OrderBy(a => a.Distance).ThenBy(a => a.Result.GetSeriesName()));
            }).Take(limit));
            return(series);
        }
예제 #2
0
파일: User.cs 프로젝트: swtrse/ShokoServer
 public User(SVR_JMMUser user)
 {
     ID             = user.JMMUserID;
     Username       = user.Username;
     IsAdmin        = user.IsAdmin == 1;
     CommunitySites = new List <CommunitySites>();
     if (user.IsAniDBUser == 1)
     {
         CommunitySites.Add(global::Shoko.Models.Enums.CommunitySites.AniDB);
     }
     if (user.IsTraktUser == 1)
     {
         CommunitySites.Add(global::Shoko.Models.Enums.CommunitySites.Trakt);
     }
     if (!string.IsNullOrEmpty(user.PlexToken))
     {
         CommunitySites.Add(global::Shoko.Models.Enums.CommunitySites.Plex);
     }
     TagBlacklist = user.GetHideCategories().ToList();
 }
예제 #3
0
        private static List <SearchResult> SearchTagsFuzzy(string query, int limit, SVR_JMMUser user, ParallelQuery <AniDB_Tag> allTags)
        {
            List <SearchResult> series = new List <SearchResult>();
            IEnumerable <Misc.SearchInfo <CustomTag> > customTags = RepoFactory.CustomTag.GetAll().Select(a =>
            {
                if (user.GetHideCategories().Contains(a.TagName))
                {
                    return(null);
                }
                Misc.SearchInfo <CustomTag> tag = Misc.DiceFuzzySearch(a.TagName, query, 0, a);
                if (tag.Index == -1 || tag.Result == null)
                {
                    return(null);
                }
                return(tag);
            }).Where(a => a != null).OrderBy(a => a.Distance);

            series.AddRange(customTags.SelectMany(tag =>
            {
                return(RepoFactory.CrossRef_CustomTag.GetByCustomTagID(tag.Result.CustomTagID)
                       .Select(xref =>
                {
                    if (xref.CrossRefType != (int)CustomTagCrossRefType.Anime)
                    {
                        return null;
                    }
                    SVR_AnimeSeries anime = RepoFactory.AnimeSeries.GetByAnimeID(xref.CrossRefID);
                    // Because we are searching tags, then getting series from it, we need to make sure it's allowed
                    // for example, p**n could have the drugs tag, even though it's not a "p**n tag"
                    if (anime?.GetAnime()?.GetAllTags().FindInEnumerable(user.GetHideCategories()) ?? true)
                    {
                        return null;
                    }
                    return new SearchResult
                    {
                        Distance = tag.Distance,
                        Index = tag.Index,
                        Match = tag.Result.TagName,
                        Result = anime,
                        ExactMatch = tag.ExactMatch
                    };
                }).Where(b => b != null).OrderBy(b => b.Distance).ThenBy(b => b.Result.GetSeriesName()).ToList());
            }).Take(limit));

            limit -= series.Count;

            var tags = allTags.Select(tag =>
            {
                var result = Misc.DiceFuzzySearch(tag.TagName, query, 0, tag);
                if (result.Index == -1 || result.Result == null)
                {
                    return(null);
                }
                return(result);
            }).Where(a => a != null).OrderBy(a => a.Distance);

            series.AddRange(tags.SelectMany(tag =>
            {
                return(RepoFactory.AniDB_Anime_Tag.GetByTagID(tag.Result.TagID)
                       .Select(xref =>
                {
                    var anime = RepoFactory.AnimeSeries.GetByAnimeID(xref.AnimeID);
                    // Because we are searching tags, then getting series from it, we need to make sure it's allowed
                    // for example, p**n could have the drugs tag, even though it's not a "p**n tag"
                    if (anime?.GetAnime()?.GetAllTags().FindInEnumerable(user.GetHideCategories()) ?? true)
                    {
                        return null;
                    }
                    return new SearchResult
                    {
                        Distance = (600D - xref.Weight) / 600,
                        Index = tag.Index,
                        Match = tag.Result.TagName,
                        Result = anime,
                        ExactMatch = tag.ExactMatch
                    };
                }).Where(a => a != null).OrderBy(a => a.Distance).ThenBy(a => a.Result.GetSeriesName()).ToList());
            }).Take(limit));
            return(series);
        }
예제 #4
0
        /// <summary>
        ///     Search for series with given query in name or tag
        /// </summary>
        /// <param name="query">target string</param>
        /// <param name="userID">user id</param>
        /// <param name="limit">The number of results to return</param>
        /// <param name="flags">The SearchFlags to determine the type of search</param>
        /// <returns>
        ///     <see cref="List{SearchResult}" />
        /// </returns>
        public static List <SearchResult> Search(int userID, string query, int limit, SearchFlags flags, TagFilter.Filter tagFilter = TagFilter.Filter.None)
        {
            query = query.ToLowerInvariant();

            SVR_JMMUser user = RepoFactory.JMMUser.GetByID(userID);

            if (user == null)
            {
                throw new Exception("User not found");
            }

            ParallelQuery <SVR_AnimeSeries> allSeries =
                RepoFactory.AnimeSeries.GetAll().AsParallel().Where(a =>
                                                                    a?.GetAnime() != null && (a.GetAnime().GetAllTags().Count == 0 || !a.GetAnime().GetAllTags().FindInEnumerable(user.GetHideCategories())));

            ParallelQuery <AniDB_Tag> allTags = RepoFactory.AniDB_Tag.GetAll().AsParallel()
                                                .Where(a =>
            {
                List <string> _ = new List <string>();
                return(!user.GetHideCategories().Contains(a.TagName) &&
                       !TagFilter.IsTagBlackListed(a.TagName, tagFilter, ref _));
            });

            //search by anime id
            if (int.TryParse(query, out int aid))
            {
                var aidResults = SearchTitlesByAnimeID(aid, allSeries);
                if (aidResults.Count > 0)
                {
                    return(aidResults);
                }
            }

            #region Search_TitlesOnly

            switch (flags)
            {
            case SearchFlags.Titles:
                return(SearchTitlesIndexOf(query, limit, allSeries));

            case SearchFlags.Fuzzy | SearchFlags.Titles:
                return(SearchTitlesFuzzy(query, limit, allSeries));

            case SearchFlags.Tags:
                return(SearchTagsEquals(query, limit, user, allTags));

            case SearchFlags.Fuzzy | SearchFlags.Tags:
                return(SearchTagsFuzzy(query, limit, user, allTags));

            case SearchFlags.Tags | SearchFlags.Titles:
                List <SearchResult> titleResult = SearchTitlesIndexOf(query, limit, allSeries);

                int tagLimit = limit - titleResult.Count;
                if (tagLimit <= 0)
                {
                    return(titleResult);
                }
                titleResult.AddRange(SearchTagsEquals(query, tagLimit, user, allTags));
                return(titleResult);

            case SearchFlags.Fuzzy | SearchFlags.Tags | SearchFlags.Titles:
                List <SearchResult> titles = SearchTitlesFuzzy(query, limit, allSeries);

                int tagLimit2 = limit - titles.Count;
                if (tagLimit2 <= 0)
                {
                    return(titles);
                }
                titles.AddRange(SearchTagsFuzzy(query, tagLimit2, user, allTags));
                return(titles);
            }

            #endregion

            return(new List <SearchResult>());
        }
예제 #5
0
        public object GetStats()
        {
            SVR_JMMUser user = HttpContext.User.Identity as SVR_JMMUser;

            int    series_count;
            int    file_count;
            string size;

            int  watched_files  = 0;
            int  watched_series = 0;
            long hours          = 0;

            List <string> tags;

            if (user != null)
            {
                var series = Repo.Instance.AnimeSeries.GetAll().Where(a =>
                                                                      !a.GetAnime()?.GetAllTags().FindInEnumerable(user.GetHideCategories()) ?? false).ToList();
                series_count = series.Count;

                var files = series.SelectMany(a => a.GetAnimeEpisodes()).SelectMany(a => a.GetVideoLocals())
                            .DistinctBy(a => a.VideoLocalID).ToList();
                file_count = files.Count;
                size       = SizeSuffix(files.Sum(a => a.FileSize));

                var watched = Repo.Instance.VideoLocal_User.GetByUserID(user.JMMUserID)
                              .Where(a => a.WatchedDate != null).ToList();

                watched_files = watched.Count;

                watched_series = Repo.Instance.AnimeSeries.GetAll().Count(a =>
                {
                    var contract = a.GetUserContract(user.JMMUserID);
                    if (contract?.MissingEpisodeCount > 0)
                    {
                        return(false);
                    }
                    return(contract?.UnwatchedEpisodeCount == 0);
                });

                hours = watched.Select(a => Repo.Instance.VideoLocal.GetByID(a.VideoLocalID)).Where(a => a != null)
                        .Sum(a => a.Duration) / 3600000; // 1000ms * 60s * 60m = ?h

                tags = Repo.Instance.AniDB_Anime_Tag.GetAllForLocalSeries().GroupBy(a => a.TagID)
                       .ToDictionary(a => a.Key, a => a.Count()).OrderByDescending(a => a.Value)
                       .Select(a => Repo.Instance.AniDB_Tag.GetByID(a.Key)?.TagName)
                       .Where(a => a != null && !user.GetHideCategories().Contains(a)).ToList();
                var tagfilter = TagFilter.Filter.AnidbInternal | TagFilter.Filter.Misc | TagFilter.Filter.Source;
                tags = TagFilter.ProcessTags(tagfilter, tags).Take(10).ToList();
            }
            else
            {
                var series = Repo.Instance.AnimeSeries.GetAll();
                series_count = series.Count;

                var files = series.SelectMany(a => a.GetAnimeEpisodes()).SelectMany(a => a.GetVideoLocals())
                            .DistinctBy(a => a.VideoLocalID).ToList();
                file_count = files.Count;
                size       = SizeSuffix(files.Sum(a => a.FileSize));

                tags = Repo.Instance.AniDB_Anime_Tag.GetAllForLocalSeries().GroupBy(a => a.TagID)
                       .ToDictionary(a => a.Key, a => a.Count()).OrderByDescending(a => a.Value)
                       .Select(a => Repo.Instance.AniDB_Tag.GetByID(a.Key)?.TagName)
                       .Where(a => a != null).ToList();
                var tagfilter = TagFilter.Filter.AnidbInternal | TagFilter.Filter.Misc | TagFilter.Filter.Source;
                tags = TagFilter.ProcessTags(tagfilter, tags).Take(10).ToList();
            }

            return(new Dictionary <string, object>
            {
                { "queue", Repo.Instance.CommandRequest.GetByClasses().ToDictionary(a => FromLastPoint(a.Key), a => a.Value) },
                { "file_count", file_count },
                { "series_count", series_count },
                { "collection_size", size },
                { "watched_files", watched_files },
                { "watched_series", watched_series },
                { "hours_watched", hours },
                { "tags", tags }
            });
        }