public SearchResultsViewModel(WebSearchResult res, string url)
 {
     Score = res.Score;
     URL = url;
     Type = (SearchResultType)res.Type;
     Title = GetTitle(res);
 }
Example #2
0
        public IEnumerable<WebSearchResult> Search(string text)
        {
            string sql =
                "SELECT id, title, actors, year, genres, alternate_titles " +
                "FROM movie_info " +
                "WHERE title LIKE @search OR alternate_titles LIKE @search OR actors LIKE @search";
            return ReadList<WebSearchResult>(sql, delegate(SQLiteDataReader reader)
            {
                var result = new WebSearchResult()
                {
                    Type = WebMediaType.Movie,
                    Id = reader.ReadIntAsString(0),
                    Title = reader.ReadString(1),
                    Details = new WebDictionary<string>()
                    {
                        { "Year", reader.ReadIntAsString(3) },
                        { "Genres", String.Join(", ", reader.ReadPipeList(4)) },
                    }
                };

                // simple score
                int score = result.Title.Contains(text, false) ? (int)Math.Round(40 + (decimal)text.Length / result.Title.Length * 40) : 0;
                var validAlternate = reader.ReadPipeList(5).Where(x => x.Contains(text, false));
                score = Math.Max(score, validAlternate.Count() > 0 ? validAlternate.Max(x => 40 + (int)Math.Round((decimal)text.Length / x.Length * 30)) : 0);

                // actors
                var valid = reader.ReadPipeList(2).Where(x => x.Contains(text, false));
                score = Math.Max(score, valid.Count() > 0 ? valid.Max(x => 40 + (int)Math.Round((decimal)text.Length / x.Length * 30)) : 0);

                // set
                result.Score = score;
                return result;
            }, new SQLiteParameter("@search", "%" + text + "%"));
        }
        private string GetTitle(WebSearchResult result)
        {
            switch (result.Type)
            {
                case WebMediaType.MusicAlbum:
                    return String.Format(FormStrings.SearchResultAlbum, result.Title, result.Details["Artist"]);
                case WebMediaType.MusicTrack:
                    return String.Format(FormStrings.SearchResultTrack, result.Title, result.Details["Artist"]);

                case WebMediaType.TVEpisode:
                    return String.Format("{0} ({1} {2}x{3})", result.Title, result.Details["ShowName"], result.Details["SeasonNumber"], result.Details["EpisodeNumber"]);

                default:
                    return result.Title;
            }
        }
Example #4
0
 private string CreateLink(WebSearchResult result)
 {
     switch (result.Type)
     {
         case WebMediaType.Movie:
             return Url.Action("Details", "MovieLibrary", new { movie = result.Id });
         case WebMediaType.MusicAlbum:
             return Url.Action("Album", "MusicLibrary", new { album = result.Id });
         case WebMediaType.MusicArtist:
             return Url.Action("Albums", "MusicLibrary", new { artist = result.Id });
         case WebMediaType.MusicTrack:
             return Url.Action("Album", "MusicLibrary", new { album = result.Details["AlbumId"], track = result.Id });
         case WebMediaType.TVEpisode:
             return Url.Action("Details", "TVShowsLibrary", new { episode = result.Id });
         case WebMediaType.TVSeason:
             return Url.Action("Episodes", "TVShowsLibrary", new { season = result.Id });
         case WebMediaType.TVShow:
             return Url.Action("Seasons", "TVShowsLibrary", new { show = result.Id });
         default:
             return null;
     }
 }
Example #5
0
        public IEnumerable<WebSearchResult> Search(string text)
        {
            using (DatabaseConnection connection = OpenConnection())
            {
                IEnumerable<WebSearchResult> results;
                SQLiteParameter param = new SQLiteParameter("@search", "%" + text + "%");

                // search for shows
                string showSql = "SELECT ID, Pretty_Name FROM online_series WHERE Pretty_Name LIKE @search";
                IEnumerable<WebSearchResult> shows = ReadList<WebSearchResult>(showSql, delegate(SQLiteDataReader reader)
                {
                    string title = reader.ReadString(1);
                    return new WebSearchResult()
                    {
                        Type = WebMediaType.TVShow,
                        Id = reader.ReadIntAsString(0),
                        Title = title,
                        Score = 40 + (int)Math.Round((decimal)text.Length / title.Length * 40),
                    };
                }, param);
                results = shows;

                string actorShowSql = "SELECT ID, Pretty_Name, Actors FROM online_series WHERE Actors LIKE @search";
                IEnumerable<WebSearchResult> actorShows = ReadList<WebSearchResult>(actorShowSql, delegate(SQLiteDataReader reader)
                {
                    var valid = reader.ReadPipeList(2).Where(x => x.IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0); // contains is case sensitive
                    if (valid.Count() == 0)
                        return null;
                    return new WebSearchResult()
                    {
                        Type = WebMediaType.TVShow,
                        Id = reader.ReadIntAsString(0),
                        Title = reader.ReadString(1),
                        Score = valid.Max(x => 40 + (int)Math.Round((decimal)text.Length / x.Length * 30))
                    };
                }, param);
                results = results.Concat(actorShows);

                #region Episodes
                // initialize
                List<SQLiteParameter> parameters = new List<SQLiteParameter>() { param };

                // search for episodes
                Regex episodeRegex = new Regex(@"^(.*) ([0-9]{1,3})x([0-9]{1,3})$");
                Match episodeResult = episodeRegex.Match(text);
                string episodeRegexWhere = "0";
                if (episodeResult.Success)
                {
                    episodeRegexWhere = "((os.Pretty_Name LIKE @show OR ls.Parsed_Name LIKE @show) AND e.SeasonIndex = @season AND e.EpisodeIndex = @episode)";
                    parameters.Add(new SQLiteParameter("@show", "%" + episodeResult.Groups[1].Value.Trim() + "%"));
                    parameters.Add(new SQLiteParameter("@season", episodeResult.Groups[2].Value));
                    parameters.Add(new SQLiteParameter("@episode", episodeResult.Groups[3].Value));
                }

                // execute
                string episodeSql =
                    "SELECT e.EpisodeID, e.EpisodeName, e.EpisodeIndex, e.SeasonIndex, e.SeriesID, e.GuestStars, os.Pretty_Name, MIN(ls.Parsed_Name) AS Parsed_Name " +
                    "FROM online_episodes e " +
                    "INNER JOIN online_series os ON os.ID = e.SeriesID " +
                    "INNER JOIN local_series ls ON ls.ID = e.SeriesID " +
                    "WHERE e.EpisodeName LIKE @search OR e.GuestStars LIKE @search OR " + episodeRegexWhere + " " +
                    "GROUP BY e.EpisodeID, e.EpisodeName, e.EpisodeIndex, e.SeasonIndex, e.SeriesID, e.GuestStars, os.Pretty_Name ";
                IEnumerable<WebSearchResult> episodes = ReadList<WebSearchResult>(episodeSql, delegate(SQLiteDataReader reader)
                {
                    // read the data
                    string title = reader.ReadString(1);
                    string showTitle = reader.ReadString(6);
                    WebSearchResult result = new WebSearchResult()
                    {
                        Type = WebMediaType.TVEpisode,
                        Id = reader.ReadIntAsString(0),
                        Title = title,
                        Details = new SerializableDictionary<string>()
                    {
                        { "EpisodeNumber", reader.ReadIntAsString(2) },
                        { "SeasonNumber", reader.ReadIntAsString(3) },
                        { "ShowId", reader.ReadIntAsString(4) },
                        { "ShowName", !String.IsNullOrEmpty(showTitle) ? showTitle : reader.ReadString(7) }
                    }
                    };

                    // title
                    int score = title.Contains(text, false) ? 40 + (int)Math.Round((decimal)text.Length / title.Length * 40) : 0;

                    // guest stars
                    var valid = reader.ReadPipeList(5).Where(x => x.Contains(text, false)); // .Contains() is case sensitive
                    score = Math.Max(score, valid.Count() > 0 ? valid.Max(x => 20 + (int)Math.Round((decimal)text.Length / x.Length * 40)) : 0);

                    // regex match
                    if (episodeResult.Success &&
                           (result.Details["ShowName"].Contains(episodeResult.Groups[1].Value.Trim(), false) &&
                            result.Details["SeasonNumber"] == episodeResult.Groups[2].Value &&
                            result.Details["EpisodeNumber"] == episodeResult.Groups[3].Value))
                        score = 100;

                    // set score and return
                    result.Score = score;
                    return result;
                }, parameters.ToArray());

                // when there are multiple matches with 100%, set them all to 95% as we apparantly aren't sure
                if (episodes.Count(x => x.Score == 100) > 1)
                {
                    episodes = episodes.Select(x =>
                    {
                        if (x.Score == 100)
                            x.Score = 95;
                        return x;
                    });
                }
                results = results.Concat(episodes);
                #endregion

                // fancy season search: <showname> s<season>
                Regex seasonRegex = new Regex(@"^(.*) s([0-9]{1,3})$");
                Match seasonResult = seasonRegex.Match(text);
                if (seasonResult.Success)
                {
                    string sql =
                        "SELECT DISTINCT s.ID, s.SeasonIndex, s.SeriesID, o.Pretty_Name, MIN(l.Parsed_Name) AS Parsed_Name " +
                        "FROM season s " +
                        "INNER JOIN online_series o ON s.SeriesID = o.ID " +
                        "INNER JOIN local_series l ON s.SeriesID = l.ID " +
                        "WHERE (o.Pretty_Name = @show OR l.Parsed_Name = @show) AND s.SeasonIndex = @season " +
                        "GROUP BY s.ID, s.SeasonIndex, s.SeriesID, o.Pretty_Name ";
                    results = ReadList<WebSearchResult>(sql, delegate(SQLiteDataReader reader)
                    {
                        string showTitle = !String.IsNullOrEmpty(reader.ReadString(3)) ? reader.ReadString(3) : reader.ReadString(4);
                        return new WebSearchResult()
                        {
                            Type = WebMediaType.TVSeason,
                            Id = reader.ReadString(0),
                            Title = showTitle + " (season " + reader.ReadInt32(1) + ")",
                            Score = 100,
                            Details = new SerializableDictionary<string>()
                        {
                            { "SeasonNumber", reader.ReadIntAsString(1) },
                            { "ShowId", reader.ReadIntAsString(2) },
                            { "ShowName", showTitle }
                        }
                        };
                    }, new SQLiteParameter("@show", seasonResult.Groups[1].Value.Trim()),
                       new SQLiteParameter("@season", seasonResult.Groups[2].Value))
                         .Concat(results);
                }

                // return
                return results;
            }
        }