2011-04-27 04:47:29 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2012-01-27 23:53:11 +01:00
|
|
|
|
using System.Globalization;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
using System.IO;
|
2011-08-06 06:51:36 +02:00
|
|
|
|
using System.Linq;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using NLog;
|
2012-02-05 07:34:36 +01:00
|
|
|
|
using NzbDrone.Common;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
using NzbDrone.Core.Model;
|
|
|
|
|
using NzbDrone.Core.Repository.Quality;
|
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core
|
|
|
|
|
{
|
|
|
|
|
public static class Parser
|
|
|
|
|
{
|
|
|
|
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
|
|
|
|
|
|
|
|
|
private static readonly Regex[] ReportTitleRegex = new[]
|
|
|
|
|
{
|
2011-06-13 20:25:40 +02:00
|
|
|
|
//Episodes with airdate
|
2011-04-27 04:47:29 +02:00
|
|
|
|
new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>\d{2})\W+(?<airday>\d{2})\W?(?!\\)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
2011-06-13 20:25:40 +02:00
|
|
|
|
|
|
|
|
|
//Multi-Part episodes without a title (S01E05.S01E06)
|
2012-02-28 08:31:40 +01:00
|
|
|
|
new Regex(@"^(?:\W*S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,2}(?!\d+)))+){2,}\W?(?!\\)",
|
2011-05-01 02:23:10 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
2011-06-13 20:25:40 +02:00
|
|
|
|
|
2012-02-01 02:17:42 +01:00
|
|
|
|
//Multi-episode Repeated (S01E05 - S01E06, 1x05 - 1x06, etc)
|
2012-02-28 08:31:40 +01:00
|
|
|
|
new Regex(@"^(?<title>.+?)(?:\W+S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{2}(?!\d+)))+){2,}\W?(?!\\)",
|
2011-08-06 06:51:36 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2012-02-28 08:31:40 +01:00
|
|
|
|
//Episodes without a title, Single (S01E05, 1x05) AND Multi (S01E04E05, 1x04x05, etc)
|
|
|
|
|
new Regex(@"^(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex])(?<episode>\d{2}(?!\d+)))+\W*)+\W?(?!\\)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2012-02-01 02:17:42 +01:00
|
|
|
|
//Episodes with a title, Single episodes (S01E05, 1x05, etc) & Multi-episode (S01E05E06, S01E05-06, S01E05 E06, etc)
|
2012-02-22 08:08:08 +01:00
|
|
|
|
new Regex(@"^(?<title>.+?)(?:\W+S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)\W?(?!\\)",
|
2011-06-13 20:25:40 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2012-02-01 02:17:42 +01:00
|
|
|
|
//Episodes over 99 (3-digits or more) (S01E105, S01E105E106, etc)
|
|
|
|
|
new Regex(@"^(?<title>.*?)(?:\W?S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]){1,2}(?<episode>\d+))+)+\W?(?!\\)",
|
2011-06-13 20:25:40 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2012-03-17 03:17:36 +01:00
|
|
|
|
new Regex(@"^(?:S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:\-|[ex]|\W[ex])(?<episode>\d{2}(?!\d+)))+\W*)+\W?(?!\\)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
|
|
|
|
//Episodes with a title, Single episodes (S01E05, 1x05, etc) & Multi-episode (S01E05E06, S01E05-06, S01E05 E06, etc)
|
|
|
|
|
new Regex(@"^(?<title>.+?)(?:\W+S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)\W?(?!\\)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2011-09-18 21:59:23 +02:00
|
|
|
|
//Supports 103/113 naming
|
2012-01-03 03:18:36 +01:00
|
|
|
|
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+)\d{1})(?<episode>\d{2}(?!p|i|\d+)))+\W?(?!\\)",
|
2011-09-18 21:59:23 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2012-02-22 17:23:25 +01:00
|
|
|
|
//Supports 1103/1113 naming
|
|
|
|
|
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+|\(|\[)\d{2})(?<episode>\d{2}(?!p|i|\d+|\)|\])))+\W?(?!\\)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2012-02-15 21:17:10 +01:00
|
|
|
|
//Mini-Series, treated as season 1, episodes are labeled as Part01, Part 01, Part.1
|
|
|
|
|
new Regex(@"^(?<title>.+?)(?:\W+(?:(?:Part\W?|(?<!\d+\W+)e)(?<episode>\d{1,2}(?!\d+)))+)\W?(?!\\)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
|
|
|
|
|
2011-11-18 09:10:30 +01:00
|
|
|
|
//Supports Season only releases
|
2011-09-26 03:00:21 +02:00
|
|
|
|
new Regex(@"^(?<title>.+?)\W(?:S|Season)\W?(?<season>\d{1,2}(?!\d+))\W?(?<extras>EXTRAS|SUBPACK)?(?!\\)",
|
2011-06-13 20:25:40 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled)
|
2011-04-27 04:47:29 +02:00
|
|
|
|
};
|
|
|
|
|
|
2011-06-13 20:25:40 +02:00
|
|
|
|
private static readonly Regex NormalizeRegex = new Regex(@"((^|\W)(a|an|the|and|or|of)($|\W))|\W|(?:(?<=[^0-9]+)|\b)(?!(?:19\d{2}|20\d{2}))\d+(?=[^0-9ip]+|\b)",
|
2011-04-27 04:47:29 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
|
|
2011-08-27 06:37:24 +02:00
|
|
|
|
private static readonly Regex SimpleTitleRegex = new Regex(@"480[i|p]|720[i|p]|1080[i|p]|[x|h|x\s|h\s]264|DD\W?5\W1|\<|\>|\?|\*|\:|\||""",
|
2011-05-23 19:32:37 +02:00
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
|
|
2011-09-14 04:25:33 +02:00
|
|
|
|
private static readonly Regex ReportSizeRegex = new Regex(@"(?<value>\d+\.\d{1,2}|\d+\,\d+\.\d{1,2})\W?(?<unit>GB|MB|GiB|MiB)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
|
|
2012-04-15 01:37:36 +02:00
|
|
|
|
private static readonly Regex HeaderRegex = new Regex(@"(?:\[.+\]\-\[.+\]\-\[.+\]\-\[)(?<nzbTitle>.+)(?:\]\-.+)",
|
|
|
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
|
|
2011-06-30 01:31:16 +02:00
|
|
|
|
internal static EpisodeParseResult ParsePath(string path)
|
|
|
|
|
{
|
|
|
|
|
var fileInfo = new FileInfo(path);
|
2011-11-24 08:35:37 +01:00
|
|
|
|
|
|
|
|
|
var result = ParseTitle(fileInfo.Name);
|
|
|
|
|
|
|
|
|
|
if (result == null)
|
|
|
|
|
{
|
|
|
|
|
Logger.Trace("Attempting to parse episode info using full path. {0}", fileInfo.FullName);
|
|
|
|
|
result = ParseTitle(fileInfo.FullName);
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-20 08:08:05 +01:00
|
|
|
|
if (result != null)
|
|
|
|
|
{
|
|
|
|
|
result.OriginalString = path;
|
|
|
|
|
}
|
2012-02-11 02:54:08 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger.Warn("Unable to parse episode info from path {0}", path);
|
|
|
|
|
}
|
2012-01-20 07:35:10 +01:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
return result;
|
2011-06-30 01:31:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static EpisodeParseResult ParseTitle(string title)
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-11-24 09:12:24 +01:00
|
|
|
|
try
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-11-24 09:12:24 +01:00
|
|
|
|
Logger.Trace("Parsing string '{0}'", title);
|
|
|
|
|
var simpleTitle = SimpleTitleRegex.Replace(title, String.Empty);
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-11-24 09:12:24 +01:00
|
|
|
|
foreach (var regex in ReportTitleRegex)
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-11-24 09:12:24 +01:00
|
|
|
|
var match = regex.Matches(simpleTitle);
|
|
|
|
|
|
|
|
|
|
if (match.Count != 0)
|
2011-11-24 08:35:37 +01:00
|
|
|
|
{
|
2011-11-24 09:12:24 +01:00
|
|
|
|
var result = ParseMatchCollection(match);
|
|
|
|
|
if (result != null)
|
|
|
|
|
{
|
|
|
|
|
//Check if episode is in the future (most likley a parse error)
|
|
|
|
|
if (result.AirDate > DateTime.Now.AddDays(1).Date)
|
2011-12-10 19:54:16 +01:00
|
|
|
|
break;
|
2011-11-24 09:12:24 +01:00
|
|
|
|
|
|
|
|
|
result.Language = ParseLanguage(title);
|
|
|
|
|
result.Quality = ParseQuality(title);
|
2012-01-20 07:35:10 +01:00
|
|
|
|
result.OriginalString = title;
|
2011-11-24 09:12:24 +01:00
|
|
|
|
return result;
|
|
|
|
|
}
|
2011-11-24 08:35:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2011-11-24 09:12:24 +01:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2012-01-20 07:12:07 +01:00
|
|
|
|
Logger.ErrorException("An error has occurred while trying to parse " + title, e);
|
2011-11-24 08:35:37 +01:00
|
|
|
|
}
|
2012-02-11 02:54:08 +01:00
|
|
|
|
|
|
|
|
|
Logger.Trace("Unable to parse {0}", title);
|
2012-02-05 07:34:36 +01:00
|
|
|
|
ReportingService.ReportParseError(title);
|
2011-11-24 08:35:37 +01:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
private static EpisodeParseResult ParseMatchCollection(MatchCollection matchCollection)
|
|
|
|
|
{
|
2012-01-20 06:37:08 +01:00
|
|
|
|
var seriesName = matchCollection[0].Groups["title"].Value;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
int airyear;
|
|
|
|
|
Int32.TryParse(matchCollection[0].Groups["airyear"].Value, out airyear);
|
2011-04-26 17:26:41 +02:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
EpisodeParseResult parsedEpisode;
|
2011-08-27 06:37:24 +02:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
if (airyear < 1900)
|
|
|
|
|
{
|
|
|
|
|
var seasons = new List<int>();
|
2011-09-20 02:13:19 +02:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
foreach (Capture seasonCapture in matchCollection[0].Groups["season"].Captures)
|
|
|
|
|
{
|
|
|
|
|
int parsedSeason;
|
|
|
|
|
if (Int32.TryParse(seasonCapture.Value, out parsedSeason))
|
|
|
|
|
seasons.Add(parsedSeason);
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-12-17 02:58:19 +01:00
|
|
|
|
//If no season was found it should be treated as a mini series and season 1
|
|
|
|
|
if (seasons.Count == 0)
|
|
|
|
|
seasons.Add(1);
|
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
//If more than 1 season was parsed go to the next REGEX (A multi-season release is unlikely)
|
2011-12-17 02:58:19 +01:00
|
|
|
|
if (seasons.Distinct().Count() > 1)
|
2011-11-24 08:35:37 +01:00
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
parsedEpisode = new EpisodeParseResult
|
|
|
|
|
{
|
|
|
|
|
SeasonNumber = seasons.First(),
|
|
|
|
|
EpisodeNumbers = new List<int>()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach (Match matchGroup in matchCollection)
|
|
|
|
|
{
|
|
|
|
|
var episodeCaptures = matchGroup.Groups["episode"].Captures.Cast<Capture>().ToList();
|
|
|
|
|
|
|
|
|
|
//Allows use to return a list of 0 episodes (We can handle that as a full season release)
|
|
|
|
|
if (episodeCaptures.Any())
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2012-02-13 06:01:14 +01:00
|
|
|
|
var first = Convert.ToInt32(episodeCaptures.First().Value);
|
|
|
|
|
var last = Convert.ToInt32(episodeCaptures.Last().Value);
|
|
|
|
|
parsedEpisode.EpisodeNumbers = Enumerable.Range(first, last - first + 1).ToList();
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
2011-11-24 08:35:37 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL
|
|
|
|
|
//Todo: Set a "Extras" flag in EpisodeParseResult if we want to download them ever
|
|
|
|
|
if (!String.IsNullOrWhiteSpace(matchCollection[0].Groups["extras"].Value))
|
|
|
|
|
return null;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
parsedEpisode.FullSeason = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Try to Parse as a daily show
|
|
|
|
|
var airmonth = Convert.ToInt32(matchCollection[0].Groups["airmonth"].Value);
|
|
|
|
|
var airday = Convert.ToInt32(matchCollection[0].Groups["airday"].Value);
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2012-02-24 08:31:15 +01:00
|
|
|
|
//Swap day and month if month is bigger than 12 (scene fail)
|
|
|
|
|
if (airmonth > 12)
|
|
|
|
|
{
|
|
|
|
|
var tempDay = airday;
|
|
|
|
|
airday = airmonth;
|
|
|
|
|
airmonth = tempDay;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
parsedEpisode = new EpisodeParseResult
|
|
|
|
|
{
|
2012-02-24 08:31:15 +01:00
|
|
|
|
|
2011-11-24 09:12:24 +01:00
|
|
|
|
AirDate = new DateTime(airyear, airmonth, airday).Date,
|
2011-11-24 08:35:37 +01:00
|
|
|
|
};
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
2011-11-24 08:35:37 +01:00
|
|
|
|
|
2012-01-20 06:37:08 +01:00
|
|
|
|
parsedEpisode.SeriesTitle = seriesName;
|
2011-11-24 08:35:37 +01:00
|
|
|
|
|
|
|
|
|
Logger.Trace("Episode Parsed. {0}", parsedEpisode);
|
|
|
|
|
|
|
|
|
|
return parsedEpisode;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-12-10 19:54:16 +01:00
|
|
|
|
public static string ParseSeriesName(string title)
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
|
|
|
|
Logger.Trace("Parsing string '{0}'", title);
|
|
|
|
|
|
|
|
|
|
foreach (var regex in ReportTitleRegex)
|
|
|
|
|
{
|
|
|
|
|
var match = regex.Matches(title);
|
|
|
|
|
|
|
|
|
|
if (match.Count != 0)
|
|
|
|
|
{
|
|
|
|
|
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
|
|
|
|
|
|
|
|
|
|
Logger.Trace("Series Parsed. {0}", seriesName);
|
|
|
|
|
return seriesName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-10 19:54:16 +01:00
|
|
|
|
return NormalizeTitle(title);
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-05-28 21:23:35 +02:00
|
|
|
|
internal static Quality ParseQuality(string name)
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
|
|
|
|
Logger.Trace("Trying to parse quality for {0}", name);
|
|
|
|
|
|
2011-05-26 05:13:39 +02:00
|
|
|
|
name = name.Trim();
|
2011-06-13 20:25:40 +02:00
|
|
|
|
var normalizedName = NormalizeTitle(name);
|
2011-05-28 21:23:35 +02:00
|
|
|
|
var result = new Quality { QualityType = QualityTypes.Unknown };
|
2011-06-13 20:25:40 +02:00
|
|
|
|
result.Proper = normalizedName.Contains("proper");
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("dvd") || normalizedName.Contains("bdrip") || normalizedName.Contains("brrip"))
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-05-28 21:23:35 +02:00
|
|
|
|
result.QualityType = QualityTypes.DVD;
|
|
|
|
|
return result;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("xvid") || normalizedName.Contains("divx"))
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("bluray"))
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-05-28 21:23:35 +02:00
|
|
|
|
result.QualityType = QualityTypes.DVD;
|
|
|
|
|
return result;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-05-28 21:23:35 +02:00
|
|
|
|
result.QualityType = QualityTypes.SDTV;
|
|
|
|
|
return result;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("bluray"))
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("720p"))
|
2011-05-28 21:23:35 +02:00
|
|
|
|
{
|
|
|
|
|
result.QualityType = QualityTypes.Bluray720p;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("1080p"))
|
2011-05-28 21:23:35 +02:00
|
|
|
|
{
|
|
|
|
|
result.QualityType = QualityTypes.Bluray1080p;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
|
2011-05-28 21:23:35 +02:00
|
|
|
|
result.QualityType = QualityTypes.Bluray720p;
|
|
|
|
|
return result;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("webdl"))
|
2011-05-28 21:23:35 +02:00
|
|
|
|
{
|
|
|
|
|
result.QualityType = QualityTypes.WEBDL;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2011-06-13 20:25:40 +02:00
|
|
|
|
if (normalizedName.Contains("x264") || normalizedName.Contains("h264") || normalizedName.Contains("720p"))
|
2011-05-28 21:23:35 +02:00
|
|
|
|
{
|
|
|
|
|
result.QualityType = QualityTypes.HDTV;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
//Based on extension
|
2011-05-23 08:48:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-06-30 01:31:16 +02:00
|
|
|
|
if (result.QualityType == QualityTypes.Unknown)
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-05-23 08:48:52 +02:00
|
|
|
|
try
|
2011-04-27 04:47:29 +02:00
|
|
|
|
{
|
2011-05-23 08:48:52 +02:00
|
|
|
|
switch (Path.GetExtension(name).ToLower())
|
|
|
|
|
{
|
|
|
|
|
case ".avi":
|
|
|
|
|
case ".xvid":
|
2012-01-14 06:40:09 +01:00
|
|
|
|
case ".divx":
|
2011-05-23 08:48:52 +02:00
|
|
|
|
case ".wmv":
|
|
|
|
|
case ".mp4":
|
2012-01-14 06:40:09 +01:00
|
|
|
|
case ".mpg":
|
|
|
|
|
case ".mpeg":
|
|
|
|
|
case ".mov":
|
|
|
|
|
case ".rm":
|
|
|
|
|
case ".rmvb":
|
|
|
|
|
case ".flv":
|
|
|
|
|
case ".dvr-ms":
|
|
|
|
|
case ".ogm":
|
2011-05-23 08:48:52 +02:00
|
|
|
|
{
|
2011-05-28 21:23:35 +02:00
|
|
|
|
result.QualityType = QualityTypes.SDTV;
|
2011-05-23 08:48:52 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ".mkv":
|
2012-01-14 06:40:09 +01:00
|
|
|
|
case ".ts":
|
2011-05-23 08:48:52 +02:00
|
|
|
|
{
|
2011-05-28 21:23:35 +02:00
|
|
|
|
result.QualityType = QualityTypes.HDTV;
|
2011-05-23 08:48:52 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
2011-05-23 08:48:52 +02:00
|
|
|
|
catch (ArgumentException)
|
|
|
|
|
{
|
|
|
|
|
//Swallow exception for cases where string contains illegal
|
|
|
|
|
//path characters.
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-05-24 06:41:57 +02:00
|
|
|
|
|
2012-01-20 06:37:08 +01:00
|
|
|
|
if (name.Contains("[HDTV]"))
|
|
|
|
|
{
|
|
|
|
|
result.QualityType = QualityTypes.HDTV;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 00:52:48 +01:00
|
|
|
|
if ((normalizedName.Contains("sdtv") || normalizedName.Contains("pdtv") ||
|
2012-01-20 07:35:10 +01:00
|
|
|
|
(result.QualityType == QualityTypes.Unknown && normalizedName.Contains("hdtv"))) &&
|
2012-01-20 06:37:08 +01:00
|
|
|
|
!normalizedName.Contains("mpeg"))
|
2011-05-23 08:48:52 +02:00
|
|
|
|
{
|
2011-05-28 21:23:35 +02:00
|
|
|
|
result.QualityType = QualityTypes.SDTV;
|
|
|
|
|
return result;
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-24 08:35:37 +01:00
|
|
|
|
internal static LanguageType ParseLanguage(string title)
|
2011-05-09 08:16:26 +02:00
|
|
|
|
{
|
2011-06-23 02:19:19 +02:00
|
|
|
|
var lowerTitle = title.ToLower();
|
|
|
|
|
|
|
|
|
|
if (lowerTitle.Contains("english"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.English;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("french"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.French;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("spanish"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Spanish;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("german"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
{
|
|
|
|
|
//Make sure it doesn't contain Germany (Since we're not using REGEX for all this)
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (!lowerTitle.Contains("germany"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.German;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("italian"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Italian;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("danish"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Danish;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("dutch"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Dutch;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("japanese"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Japanese;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("cantonese"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Cantonese;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("mandarin"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Mandarin;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("korean"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Korean;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("russian"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Russian;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("polish"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Polish;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("vietnamese"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Vietnamese;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("swedish"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Swedish;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("norwegian"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Norwegian;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("finnish"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Finnish;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("turkish"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Turkish;
|
|
|
|
|
|
2011-06-23 02:19:19 +02:00
|
|
|
|
if (lowerTitle.Contains("portuguese"))
|
2011-05-09 08:16:26 +02:00
|
|
|
|
return LanguageType.Portuguese;
|
|
|
|
|
|
|
|
|
|
return LanguageType.English;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-27 04:47:29 +02:00
|
|
|
|
public static string NormalizeTitle(string title)
|
|
|
|
|
{
|
2011-08-22 03:42:00 +02:00
|
|
|
|
long number = 0;
|
|
|
|
|
|
|
|
|
|
//If Title only contains numbers return it as is.
|
|
|
|
|
if (Int64.TryParse(title, out number))
|
2011-08-02 07:10:05 +02:00
|
|
|
|
return title;
|
2011-08-22 03:42:00 +02:00
|
|
|
|
|
2011-04-27 04:47:29 +02:00
|
|
|
|
return NormalizeRegex.Replace(title, String.Empty).ToLower();
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-14 04:25:33 +02:00
|
|
|
|
public static long GetReportSize(string sizeString)
|
|
|
|
|
{
|
|
|
|
|
var match = ReportSizeRegex.Matches(sizeString);
|
|
|
|
|
|
|
|
|
|
if (match.Count != 0)
|
|
|
|
|
{
|
2012-01-27 23:53:11 +01:00
|
|
|
|
var cultureInfo = new CultureInfo("en-US");
|
|
|
|
|
var value = Decimal.Parse(Regex.Replace(match[0].Groups["value"].Value, "\\,", ""), cultureInfo);
|
2011-09-14 04:25:33 +02:00
|
|
|
|
|
|
|
|
|
var unit = match[0].Groups["unit"].Value;
|
|
|
|
|
|
|
|
|
|
if (unit.Equals("MB", StringComparison.InvariantCultureIgnoreCase) || unit.Equals("MiB", StringComparison.InvariantCultureIgnoreCase))
|
|
|
|
|
return Convert.ToInt64(value * 1048576L);
|
|
|
|
|
|
|
|
|
|
if (unit.Equals("GB", StringComparison.InvariantCultureIgnoreCase) || unit.Equals("GiB", StringComparison.InvariantCultureIgnoreCase))
|
|
|
|
|
return Convert.ToInt64(value * 1073741824L);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2012-04-15 01:37:36 +02:00
|
|
|
|
|
|
|
|
|
internal static string ParseHeader(string header)
|
|
|
|
|
{
|
|
|
|
|
var match = HeaderRegex.Matches(header);
|
|
|
|
|
|
|
|
|
|
if (match.Count != 0)
|
|
|
|
|
return match[0].Groups["nzbTitle"].Value;
|
|
|
|
|
|
|
|
|
|
return header;
|
|
|
|
|
}
|
2011-04-27 04:47:29 +02:00
|
|
|
|
}
|
2012-02-13 06:01:14 +01:00
|
|
|
|
} |