Jackett/src/Jackett/Models/TorznabQuery.cs

298 lines
9.8 KiB
C#
Raw Normal View History

2015-07-19 00:27:41 +00:00
using Jackett.Utils;
using System;
2015-04-13 06:25:21 +00:00
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
2015-04-13 06:25:21 +00:00
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
2015-04-13 06:25:21 +00:00
using System.Threading.Tasks;
2015-07-19 00:27:41 +00:00
namespace Jackett.Models
2015-04-13 06:25:21 +00:00
{
public class TorznabQuery
{
public string QueryType { get; set; }
public int[] Categories { get; set; }
public int Extended { get; set; }
public string ApiKey { get; set; }
public int Limit { get; set; }
public int Offset { get; set; }
2017-01-31 18:32:32 +00:00
public int? RageID { get; set; }
public string ImdbID { get; set; }
public int Season { get; set; }
public string Episode { get; set; }
public string SearchTerm { get; set; }
2015-08-02 17:39:32 +00:00
2016-12-06 17:24:40 +00:00
public bool IsTest { get; set; }
2017-01-25 15:59:36 +00:00
public string ImdbIDShort { get { return (ImdbID != null ? ImdbID.TrimStart('t') : null); } }
protected string[] QueryStringParts = null;
public bool IsSearch
{
get
{
return (QueryStringParts != null && QueryStringParts.Length > 0);
}
}
public bool IsTVSearch
{
get
{
return QueryType == "tvsearch";
}
}
public bool IsMovieSearch
{
get
{
return QueryType == "movie";
}
}
public bool IsTVRageSearch
{
get
{
return RageID != null;
}
}
public bool IsImdbQuery
{
get
{
return ImdbID != null;
}
}
public bool HasSpecifiedCategories
{
get
{
return (Categories != null && Categories.Length > 0);
}
}
2015-08-02 17:39:32 +00:00
public string SanitizedSearchTerm
{
get
{
if (SearchTerm == null)
return string.Empty;
char[] arr = SearchTerm.ToCharArray();
arr = Array.FindAll<char>(arr, c => (char.IsLetterOrDigit(c)
|| char.IsWhiteSpace(c)
|| c == '-'
|| c == '.'
|| c == '_'
|| c == '('
|| c == ')'
2016-12-06 08:04:40 +00:00
|| c == '@'
2016-12-06 10:09:10 +00:00
|| c == '\''
|| c == '['
|| c == ']'
2015-08-02 17:39:32 +00:00
));
var safetitle = new string(arr);
return safetitle;
}
}
2015-07-29 20:11:30 +00:00
public TorznabQuery()
{
Categories = new int[0];
2016-12-06 17:24:40 +00:00
IsTest = false;
2015-07-29 20:11:30 +00:00
}
public TorznabQuery CreateFallback(string search) {
var ret = Clone();
if (Categories == null || Categories.Length == 0) {
ret.Categories = new int[]{ TorznabCatType.Movies.ID,
TorznabCatType.MoviesForeign.ID,
TorznabCatType.MoviesOther.ID,
TorznabCatType.MoviesSD.ID,
TorznabCatType.MoviesHD.ID,
TorznabCatType.Movies3D.ID,
TorznabCatType.MoviesBluRay.ID,
TorznabCatType.MoviesDVD.ID,
TorznabCatType.MoviesWEBDL.ID,
};
}
ret.SearchTerm = search;
return ret;
}
public TorznabQuery Clone() {
var ret = new TorznabQuery();
ret.QueryType = QueryType;
if (Categories != null && Categories.Length > 0) {
ret.Categories = new int [Categories.Length];
Array.Copy (Categories, ret.Categories, Categories.Length);
}
ret.Extended = Extended;
ret.ApiKey = ApiKey;
ret.Limit = Limit;
ret.Offset = Offset;
ret.Season = Season;
ret.Episode = Episode;
ret.SearchTerm = SearchTerm;
ret.IsTest = IsTest;
if (QueryStringParts != null && QueryStringParts.Length > 0) {
ret.QueryStringParts = new string [QueryStringParts.Length];
Array.Copy (QueryStringParts, ret.QueryStringParts, QueryStringParts.Length);
}
return ret;
}
public string GetQueryString()
{
return (SanitizedSearchTerm + " " + GetEpisodeSearchString()).Trim();
}
// Some trackers don't support AND logic for search terms resulting in unwanted results.
// Using this method we can AND filter it within jackett.
// With limit we can limit the amount of characters which should be compared (use it if a tracker doesn't return the full title).
public bool MatchQueryStringAND(string title, int? limit = null, string queryStringOverride = null)
{
// We cache the regex split results so we have to do it only once for each query.
if (QueryStringParts == null)
{
var queryString = GetQueryString();
if (queryStringOverride != null)
queryString = queryStringOverride;
if (limit != null && limit > 0)
{
if (limit > queryString.Length)
limit = queryString.Length;
queryString = queryString.Substring(0, (int)limit);
}
Regex SplitRegex = new Regex("[^a-zA-Z0-9]+");
QueryStringParts = SplitRegex.Split(queryString);
}
// Check if each part of the query string is in the given title.
foreach (var QueryStringPart in QueryStringParts)
{
if (title.IndexOf(QueryStringPart, StringComparison.OrdinalIgnoreCase) < 0)
{
return false;
}
}
return true;
}
public string GetEpisodeSearchString()
{
if (Season == 0)
return string.Empty;
string episodeString;
DateTime showDate;
if (DateTime.TryParseExact(string.Format("{0} {1}", Season, Episode), "yyyy MM/dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out showDate))
episodeString = showDate.ToString("yyyy.MM.dd");
else if (string.IsNullOrEmpty(Episode))
episodeString = string.Format("S{0:00}", Season);
else
2017-06-25 16:25:16 +00:00
{
try
{
episodeString = string.Format("S{0:00}E{1:00}", Season, ParseUtil.CoerceInt(Episode));
} catch (FormatException) // e.g. seaching for S01E01A
{
episodeString = string.Format("S{0:00}E{1}", Season, Episode);
}
}
return episodeString;
}
2015-04-13 06:25:21 +00:00
public static TorznabQuery FromHttpQuery(NameValueCollection query)
{
2015-04-16 06:04:28 +00:00
2015-04-13 06:25:21 +00:00
//{t=tvsearch&cat=5030%2c5040&extended=1&apikey=test&offset=0&limit=100&rid=24493&season=5&ep=1}
var q = new TorznabQuery();
q.QueryType = query["t"];
if (query["q"] == null)
{
q.SearchTerm = string.Empty;
}
else
{
q.SearchTerm = query["q"];
}
2015-06-28 18:07:25 +00:00
if (query["cat"] != null)
{
2017-01-16 16:23:19 +00:00
q.Categories = query["cat"].Split(',').Where(s => !string.IsNullOrWhiteSpace(s)).Select(s => int.Parse(s)).ToArray();
}else
{
2017-01-16 16:23:19 +00:00
if (q.QueryType == "movie" && string.IsNullOrWhiteSpace(query["imdbid"]))
q.Categories = new int[] { TorznabCatType.Movies.ID };
else
q.Categories = new int[0];
2015-06-28 18:07:25 +00:00
}
if (query["extended"] != null)
{
q.Extended = ParseUtil.CoerceInt(query["extended"]);
2015-06-28 18:07:25 +00:00
}
2015-04-13 06:25:21 +00:00
q.ApiKey = query["apikey"];
2015-06-28 18:07:25 +00:00
if (query["limit"] != null)
{
q.Limit = ParseUtil.CoerceInt(query["limit"]);
2015-06-28 18:07:25 +00:00
}
if (query["offset"] != null)
{
q.Offset = ParseUtil.CoerceInt(query["offset"]);
2015-06-28 18:07:25 +00:00
}
2015-04-16 06:04:28 +00:00
2017-01-16 16:23:19 +00:00
q.ImdbID = query["imdbid"];
int rageId;
if (int.TryParse(query["rid"], out rageId))
{
q.RageID = rageId;
}
int season;
if (int.TryParse(query["season"], out season))
{
q.Season = season;
}
q.Episode = query["ep"];
2015-04-16 06:04:28 +00:00
2015-04-13 06:25:21 +00:00
return q;
}
public void ExpandCatsToSubCats()
{
if (Categories.Count() == 0)
return;
var newCatList = new List<int>();
newCatList.AddRange(Categories);
foreach (var cat in Categories)
{
var majorCat = TorznabCatType.AllCats.Where(c => c.ID == cat).FirstOrDefault();
// If we search for TV we should also search for all sub cats
if (majorCat != null)
{
newCatList.AddRange(majorCat.SubCategories.Select(s => s.ID));
}
}
Categories = newCatList.Distinct().ToArray();
}
2015-04-13 06:25:21 +00:00
}
}