mirror of https://github.com/Radarr/Radarr
Updated Parser to parse movie titles. Should also parse things, such as: Director's Cut, Special Edition, etc. This is then displayed in the manual search UI. Importing is not yet updated for the new parser!
This commit is contained in:
parent
402a9e1ee0
commit
fd718b61ac
|
@ -24,6 +24,7 @@ namespace NzbDrone.Api.Indexers
|
|||
public string Indexer { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
public string ReleaseHash { get; set; }
|
||||
public string Edition { get; set; }
|
||||
public string Title { get; set; }
|
||||
public bool FullSeason { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
|
@ -90,6 +91,55 @@ namespace NzbDrone.Api.Indexers
|
|||
if (model.IsForMovie)
|
||||
{
|
||||
downloadAllowed = model.RemoteMovie.DownloadAllowed;
|
||||
var parsedMovieInfo = model.RemoteMovie.ParsedMovieInfo;
|
||||
|
||||
return new ReleaseResource
|
||||
{
|
||||
Guid = releaseInfo.Guid,
|
||||
Quality = parsedMovieInfo.Quality,
|
||||
//QualityWeight
|
||||
Age = releaseInfo.Age,
|
||||
AgeHours = releaseInfo.AgeHours,
|
||||
AgeMinutes = releaseInfo.AgeMinutes,
|
||||
Size = releaseInfo.Size,
|
||||
IndexerId = releaseInfo.IndexerId,
|
||||
Indexer = releaseInfo.Indexer,
|
||||
ReleaseGroup = parsedMovieInfo.ReleaseGroup,
|
||||
ReleaseHash = parsedMovieInfo.ReleaseHash,
|
||||
Title = releaseInfo.Title,
|
||||
FullSeason = parsedMovieInfo.FullSeason,
|
||||
SeasonNumber = parsedMovieInfo.SeasonNumber,
|
||||
Language = parsedMovieInfo.Language,
|
||||
AirDate = "",
|
||||
SeriesTitle = parsedMovieInfo.MovieTitle,
|
||||
EpisodeNumbers = new int[0],
|
||||
AbsoluteEpisodeNumbers = new int[0],
|
||||
Approved = model.Approved,
|
||||
TemporarilyRejected = model.TemporarilyRejected,
|
||||
Rejected = model.Rejected,
|
||||
TvdbId = releaseInfo.TvdbId,
|
||||
TvRageId = releaseInfo.TvRageId,
|
||||
Rejections = model.Rejections.Select(r => r.Reason).ToList(),
|
||||
PublishDate = releaseInfo.PublishDate,
|
||||
CommentUrl = releaseInfo.CommentUrl,
|
||||
DownloadUrl = releaseInfo.DownloadUrl,
|
||||
InfoUrl = releaseInfo.InfoUrl,
|
||||
DownloadAllowed = downloadAllowed,
|
||||
//ReleaseWeight
|
||||
|
||||
MagnetUrl = torrentInfo.MagnetUrl,
|
||||
InfoHash = torrentInfo.InfoHash,
|
||||
Seeders = torrentInfo.Seeders,
|
||||
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
|
||||
Protocol = releaseInfo.DownloadProtocol,
|
||||
|
||||
Edition = parsedMovieInfo.Edition,
|
||||
|
||||
IsDaily = false,
|
||||
IsAbsoluteNumbering = false,
|
||||
IsPossibleSpecialEpisode = false,
|
||||
Special = parsedMovieInfo.Special,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
|
||||
|
|
|
@ -66,9 +66,9 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
|
||||
try
|
||||
{
|
||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(report.Title);
|
||||
var parsedEpisodeInfo = Parser.Parser.ParseMovieTitle(report.Title);
|
||||
|
||||
if (parsedEpisodeInfo != null && !parsedEpisodeInfo.SeriesTitle.IsNullOrWhiteSpace())
|
||||
if (parsedEpisodeInfo != null && !parsedEpisodeInfo.MovieTitle.IsNullOrWhiteSpace())
|
||||
{
|
||||
RemoteMovie remoteEpisode = _parsingService.Map(parsedEpisodeInfo, "", searchCriteria);
|
||||
remoteEpisode.Release = report;
|
||||
|
|
|
@ -57,12 +57,13 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
try
|
||||
{
|
||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
|
||||
var parsedMovieInfo = Parser.Parser.ParseMovieTitle(trackedDownload.DownloadItem.Title);
|
||||
var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId);
|
||||
|
||||
if (parsedEpisodeInfo != null)
|
||||
{
|
||||
trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
|
||||
trackedDownload.RemoteMovie = _parsingService.Map(parsedEpisodeInfo, "", null);
|
||||
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null);
|
||||
}
|
||||
|
||||
if (historyItems.Any())
|
||||
|
|
|
@ -893,6 +893,7 @@
|
|||
<Compile Include="Parser\IsoLanguages.cs" />
|
||||
<Compile Include="Parser\LanguageParser.cs" />
|
||||
<Compile Include="Parser\Model\LocalMovie.cs" />
|
||||
<Compile Include="Parser\Model\ParsedMovieInfo.cs" />
|
||||
<Compile Include="Parser\Model\RemoteMovie.cs" />
|
||||
<Compile Include="Profiles\Delay\DelayProfile.cs" />
|
||||
<Compile Include="Profiles\Delay\DelayProfileService.cs" />
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using System.Linq;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.Parser.Model
|
||||
{
|
||||
public class ParsedMovieInfo
|
||||
{
|
||||
public string MovieTitle { get; set; }
|
||||
public SeriesTitleInfo MovieTitleInfo { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public Language Language { get; set; }
|
||||
public bool FullSeason { get; set; }
|
||||
public bool Special { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
public string ReleaseHash { get; set; }
|
||||
public string Edition { get; set;}
|
||||
public int Year { get; set; }
|
||||
|
||||
public ParsedMovieInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0} - {1} {2}", MovieTitle, MovieTitleInfo.Year, Quality);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ namespace NzbDrone.Core.Parser.Model
|
|||
{
|
||||
public ReleaseInfo Release { get; set; }
|
||||
public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; } //TODO: Change to ParsedMovieInfo, for now though ParsedEpisodeInfo will do.
|
||||
public ParsedMovieInfo ParsedMovieInfo { get; set; }
|
||||
public Movie Movie { get; set; }
|
||||
public bool DownloadAllowed { get; set; }
|
||||
|
||||
|
|
|
@ -15,6 +15,26 @@ namespace NzbDrone.Core.Parser
|
|||
{
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(Parser));
|
||||
|
||||
private static readonly Regex[] ReportMovieTitleRegex = new[]
|
||||
{
|
||||
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.Special.Edition.2011
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<edition>(\w+\.?edition))\.(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>(\w+\.?edition))",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
//Cut Movies, e.g: Mission.Impossible.3.Directors.Cut.2011
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<edition>(\w+\.?cut))\.(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
//Cut Movies, e.g: Mission.Impossible.3.2011.Directors.Cut
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>(\w+\.?cut))",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Normal movie format, e.g: Mission.Impossible.3.2011
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
};
|
||||
|
||||
private static readonly Regex[] ReportTitleRegex = new[]
|
||||
{
|
||||
//Anime - Absolute Episode Number + Title + Season+Episode
|
||||
|
@ -298,6 +318,94 @@ namespace NzbDrone.Core.Parser
|
|||
return result;
|
||||
}
|
||||
|
||||
public static ParsedMovieInfo ParseMovieTitle(string title)
|
||||
{
|
||||
|
||||
ParsedMovieInfo realResult = null;
|
||||
try
|
||||
{
|
||||
if (!ValidateBeforeParsing(title)) return null;
|
||||
|
||||
Logger.Debug("Parsing string '{0}'", title);
|
||||
|
||||
if (ReversedTitleRegex.IsMatch(title))
|
||||
{
|
||||
var titleWithoutExtension = RemoveFileExtension(title).ToCharArray();
|
||||
Array.Reverse(titleWithoutExtension);
|
||||
|
||||
title = new string(titleWithoutExtension) + title.Substring(titleWithoutExtension.Length);
|
||||
|
||||
Logger.Debug("Reversed name detected. Converted to '{0}'", title);
|
||||
}
|
||||
|
||||
var simpleTitle = SimpleTitleRegex.Replace(title, string.Empty);
|
||||
|
||||
simpleTitle = RemoveFileExtension(simpleTitle);
|
||||
|
||||
// TODO: Quick fix stripping [url] - prefixes.
|
||||
simpleTitle = WebsitePrefixRegex.Replace(simpleTitle, string.Empty);
|
||||
|
||||
simpleTitle = CleanTorrentSuffixRegex.Replace(simpleTitle, string.Empty);
|
||||
|
||||
foreach (var regex in ReportMovieTitleRegex)
|
||||
{
|
||||
var match = regex.Matches(simpleTitle);
|
||||
|
||||
if (match.Count != 0)
|
||||
{
|
||||
Logger.Trace(regex);
|
||||
try
|
||||
{
|
||||
var result = ParseMovieMatchCollection(match);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
|
||||
result.Language = LanguageParser.ParseLanguage(title);
|
||||
Logger.Debug("Language parsed: {0}", result.Language);
|
||||
|
||||
result.Quality = QualityParser.ParseQuality(title);
|
||||
Logger.Debug("Quality parsed: {0}", result.Quality);
|
||||
|
||||
result.ReleaseGroup = ParseReleaseGroup(title);
|
||||
|
||||
var subGroup = GetSubGroup(match);
|
||||
if (!subGroup.IsNullOrWhiteSpace())
|
||||
{
|
||||
result.ReleaseGroup = subGroup;
|
||||
}
|
||||
|
||||
Logger.Debug("Release Group parsed: {0}", result.ReleaseGroup);
|
||||
|
||||
result.ReleaseHash = GetReleaseHash(match);
|
||||
if (!result.ReleaseHash.IsNullOrWhiteSpace())
|
||||
{
|
||||
Logger.Debug("Release Hash parsed: {0}", result.ReleaseHash);
|
||||
}
|
||||
|
||||
realResult = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (InvalidDateException ex)
|
||||
{
|
||||
Logger.Debug(ex, ex.Message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!title.ToLower().Contains("password") && !title.ToLower().Contains("yenc"))
|
||||
Logger.Error(e, "An error has occurred while trying to parse " + title);
|
||||
}
|
||||
|
||||
Logger.Debug("Unable to parse {0}", title);
|
||||
return realResult;
|
||||
}
|
||||
|
||||
public static ParsedEpisodeInfo ParseTitle(string title)
|
||||
{
|
||||
|
||||
|
@ -528,6 +636,31 @@ namespace NzbDrone.Core.Parser
|
|||
return seriesTitleInfo;
|
||||
}
|
||||
|
||||
private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection)
|
||||
{
|
||||
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
||||
seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' ');
|
||||
|
||||
int airYear;
|
||||
int.TryParse(matchCollection[0].Groups["year"].Value, out airYear);
|
||||
|
||||
ParsedMovieInfo result;
|
||||
|
||||
result = new ParsedMovieInfo { Year = airYear };
|
||||
|
||||
if (matchCollection[0].Groups["edition"].Success)
|
||||
{
|
||||
result.Edition = matchCollection[0].Groups["edition"].Value.Replace(".", " ");
|
||||
}
|
||||
|
||||
result.MovieTitle = seriesName;
|
||||
result.MovieTitleInfo = GetSeriesTitleInfo(result.MovieTitle);
|
||||
|
||||
Logger.Debug("Movie Parsed. {0}", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchCollection)
|
||||
{
|
||||
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Parser
|
|||
Movie GetMovie(string title);
|
||||
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
||||
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int seriesId, IEnumerable<int> episodeIds);
|
||||
RemoteMovie Map(ParsedEpisodeInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
|
||||
RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
|
||||
List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null);
|
||||
ParsedEpisodeInfo ParseSpecialEpisodeTitle(string title, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
||||
}
|
||||
|
@ -33,6 +33,20 @@ namespace NzbDrone.Core.Parser
|
|||
private readonly ISceneMappingService _sceneMappingService;
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly Logger _logger;
|
||||
private readonly Dictionary<string, string> romanNumeralsMapper = new Dictionary<string, string>
|
||||
{
|
||||
{ "1", "I"},
|
||||
{ "2", "II"},
|
||||
{ "3", "III"},
|
||||
{ "4", "IV"},
|
||||
{ "5", "V"},
|
||||
{ "6", "VI"},
|
||||
{ "7", "VII"},
|
||||
{ "8", "VII"},
|
||||
{ "9", "IX"},
|
||||
{ "10", "X"},
|
||||
|
||||
}; //If a movie has more than 10 parts fuck 'em.
|
||||
|
||||
public ParsingService(IEpisodeService episodeService,
|
||||
ISeriesService seriesService,
|
||||
|
@ -163,19 +177,19 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
public Movie GetMovie(string title)
|
||||
{
|
||||
var parsedEpisodeInfo = Parser.ParseTitle(title);
|
||||
var parsedEpisodeInfo = Parser.ParseMovieTitle(title);
|
||||
|
||||
if (parsedEpisodeInfo == null)
|
||||
{
|
||||
return _movieService.FindByTitle(title);
|
||||
}
|
||||
|
||||
var series = _movieService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
||||
var series = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle);
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
series = _movieService.FindByTitle(parsedEpisodeInfo.SeriesTitleInfo.TitleWithoutYear,
|
||||
parsedEpisodeInfo.SeriesTitleInfo.Year);
|
||||
series = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitleInfo.TitleWithoutYear,
|
||||
parsedEpisodeInfo.MovieTitleInfo.Year);
|
||||
}
|
||||
|
||||
return series;
|
||||
|
@ -201,11 +215,11 @@ namespace NzbDrone.Core.Parser
|
|||
return remoteEpisode;
|
||||
}
|
||||
|
||||
public RemoteMovie Map(ParsedEpisodeInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria = null)
|
||||
public RemoteMovie Map(ParsedMovieInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria = null)
|
||||
{
|
||||
var remoteEpisode = new RemoteMovie
|
||||
{
|
||||
ParsedEpisodeInfo = parsedEpisodeInfo,
|
||||
ParsedMovieInfo = parsedEpisodeInfo,
|
||||
};
|
||||
|
||||
var movie = GetMovie(parsedEpisodeInfo, imdbId, searchCriteria);
|
||||
|
@ -334,23 +348,46 @@ namespace NzbDrone.Core.Parser
|
|||
return null;
|
||||
}
|
||||
|
||||
private Movie GetMovie(ParsedEpisodeInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria)
|
||||
private Movie GetMovie(ParsedMovieInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
if (searchCriteria != null)
|
||||
{
|
||||
if (searchCriteria.Movie.CleanTitle == parsedEpisodeInfo.SeriesTitle.CleanSeriesTitle())
|
||||
var possibleTitles = new List<string>();
|
||||
|
||||
possibleTitles.Add(searchCriteria.Movie.CleanTitle);
|
||||
|
||||
foreach (string altTitle in searchCriteria.Movie.AlternativeTitles)
|
||||
{
|
||||
return searchCriteria.Movie;
|
||||
possibleTitles.Add(altTitle.CleanSeriesTitle());
|
||||
}
|
||||
|
||||
if (imdbId.IsNotNullOrWhiteSpace() && imdbId == searchCriteria.Movie.ImdbId)
|
||||
foreach (string title in possibleTitles)
|
||||
{
|
||||
//TODO: If series is found by TvdbId, we should report it as a scene naming exception, since it will fail to import
|
||||
return searchCriteria.Movie;
|
||||
if (title == parsedEpisodeInfo.MovieTitle.CleanSeriesTitle())
|
||||
{
|
||||
return searchCriteria.Movie;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> entry in romanNumeralsMapper)
|
||||
{
|
||||
string num = entry.Key;
|
||||
string roman = entry.Value.ToLower();
|
||||
|
||||
if (title.Replace(num, roman) == parsedEpisodeInfo.MovieTitle.CleanSeriesTitle())
|
||||
{
|
||||
return searchCriteria.Movie;
|
||||
}
|
||||
|
||||
if (title.Replace(roman, num) == parsedEpisodeInfo.MovieTitle.CleanSeriesTitle())
|
||||
{
|
||||
return searchCriteria.Movie;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Movie movie = _movieService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
||||
Movie movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above!
|
||||
|
||||
if (movie == null && imdbId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
|
@ -360,7 +397,7 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
if (movie == null)
|
||||
{
|
||||
_logger.Debug("No matching movie {0}", parsedEpisodeInfo.SeriesTitle);
|
||||
_logger.Debug("No matching movie {0}", parsedEpisodeInfo.MovieTitle);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
var Backgrid = require('backgrid');
|
||||
var Marionette = require('marionette');
|
||||
require('bootstrap');
|
||||
|
||||
module.exports = Backgrid.Cell.extend({
|
||||
className : 'edition-cell',
|
||||
//template : 'Cells/EditionCellTemplate',
|
||||
|
||||
render : function() {
|
||||
|
||||
var edition = this.model.get(this.column.get('name'));
|
||||
if (!edition) {
|
||||
return this;
|
||||
}
|
||||
var cut = false;
|
||||
|
||||
if (edition.toLowerCase().contains("cut")) {
|
||||
cut = true;
|
||||
}
|
||||
|
||||
//this.templateFunction = Marionette.TemplateCache.get(this.template);
|
||||
|
||||
//var html = this.templateFunction(edition);
|
||||
if (cut) {
|
||||
this.$el.html('<i class="icon-sonarr-form-cut"/ title="{0}">'.format(edition));
|
||||
} else {
|
||||
this.$el.html('<i class="icon-sonarr-form-info"/ title="{0}">'.format(edition));
|
||||
}
|
||||
|
||||
/*this.$el.popover({
|
||||
content : html,
|
||||
html : true,
|
||||
trigger : 'hover',
|
||||
title : this.column.get('title'),
|
||||
placement : 'left',
|
||||
container : this.$el
|
||||
});*/
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
<ul>
|
||||
<li>
|
||||
{{this}}
|
||||
</li>
|
||||
</ul>
|
|
@ -121,6 +121,10 @@
|
|||
.fa-icon-color(@brand-danger);
|
||||
}
|
||||
|
||||
.icon-sonarr-form-cut {
|
||||
.fa-icon-content(@fa-var-scissors);
|
||||
}
|
||||
|
||||
.icon-sonarr-form-info-link {
|
||||
.clickable();
|
||||
.fa-icon-content(@fa-var-info-circle);
|
||||
|
@ -502,4 +506,4 @@
|
|||
|
||||
.icon-sonarr-header-rejections {
|
||||
.fa-icon-content(@fa-var-exclamation-circle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ var DownloadReportCell = require('../../Release/DownloadReportCell');
|
|||
var AgeCell = require('../../Release/AgeCell');
|
||||
var ProtocolCell = require('../../Release/ProtocolCell');
|
||||
var PeersCell = require('../../Release/PeersCell');
|
||||
var EditionCell = require('../../Cells/EditionCell');
|
||||
|
||||
module.exports = Marionette.Layout.extend({
|
||||
template : 'Episode/Search/ManualLayoutTemplate',
|
||||
|
@ -32,6 +33,12 @@ module.exports = Marionette.Layout.extend({
|
|||
label : 'Title',
|
||||
cell : ReleaseTitleCell
|
||||
},
|
||||
{
|
||||
name : 'edition',
|
||||
label : 'Edition',
|
||||
cell : EditionCell,
|
||||
title : "Edition"
|
||||
},
|
||||
{
|
||||
name : 'indexer',
|
||||
label : 'Indexer',
|
||||
|
@ -83,4 +90,4 @@ module.exports = Marionette.Layout.extend({
|
|||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,6 +8,7 @@ var DownloadReportCell = require('../../Release/DownloadReportCell');
|
|||
var AgeCell = require('../../Release/AgeCell');
|
||||
var ProtocolCell = require('../../Release/ProtocolCell');
|
||||
var PeersCell = require('../../Release/PeersCell');
|
||||
var EditionCell = require('../../Cells/EditionCell');
|
||||
|
||||
module.exports = Marionette.Layout.extend({
|
||||
template : 'Movies/Search/ManualLayoutTemplate',
|
||||
|
@ -32,6 +33,12 @@ module.exports = Marionette.Layout.extend({
|
|||
label : 'Title',
|
||||
cell : ReleaseTitleCell
|
||||
},
|
||||
{
|
||||
name : 'edition',
|
||||
label : 'Edition',
|
||||
cell : EditionCell,
|
||||
title : "Edition"
|
||||
},
|
||||
{
|
||||
name : 'indexer',
|
||||
label : 'Indexer',
|
||||
|
|
|
@ -7,6 +7,7 @@ var FileSizeCell = require('../Cells/FileSizeCell');
|
|||
var QualityCell = require('../Cells/QualityCell');
|
||||
var ApprovalStatusCell = require('../Cells/ApprovalStatusCell');
|
||||
var LoadingView = require('../Shared/LoadingView');
|
||||
var EditionCell = require('../Cells/EditionCell');
|
||||
|
||||
module.exports = Marionette.Layout.extend({
|
||||
template : 'Release/ReleaseLayoutTemplate',
|
||||
|
@ -17,6 +18,12 @@ module.exports = Marionette.Layout.extend({
|
|||
},
|
||||
|
||||
columns : [
|
||||
{
|
||||
name : 'edition',
|
||||
label : 'Edition',
|
||||
sortable : false,
|
||||
cell : EditionCell
|
||||
},
|
||||
{
|
||||
name : 'indexer',
|
||||
label : 'Indexer',
|
||||
|
@ -29,12 +36,12 @@ module.exports = Marionette.Layout.extend({
|
|||
sortable : true,
|
||||
cell : Backgrid.StringCell
|
||||
},
|
||||
{
|
||||
/*{
|
||||
name : 'episodeNumbers',
|
||||
episodes : 'episodeNumbers',
|
||||
label : 'season',
|
||||
cell : EpisodeNumberCell
|
||||
},
|
||||
},*/
|
||||
{
|
||||
name : 'size',
|
||||
label : 'Size',
|
||||
|
@ -75,4 +82,4 @@ module.exports = Marionette.Layout.extend({
|
|||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue