mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-23 14:55:20 -07:00
Patch/onedr0p 3 4 2017 (#1006)
* Fix link in History tab (#734) * Fix iCal feed (#746) * Removed DKSubs from hardcoded subs * Fix searching all cut off unmet
This commit is contained in:
parent
3f05ef810e
commit
0f2234bcdc
11 changed files with 84 additions and 66 deletions
|
@ -16,13 +16,13 @@ namespace NzbDrone.Api.Calendar
|
||||||
{
|
{
|
||||||
public class CalendarFeedModule : NzbDroneFeedModule
|
public class CalendarFeedModule : NzbDroneFeedModule
|
||||||
{
|
{
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IMovieService _movieService;
|
||||||
private readonly ITagService _tagService;
|
private readonly ITagService _tagService;
|
||||||
|
|
||||||
public CalendarFeedModule(IEpisodeService episodeService, ITagService tagService)
|
public CalendarFeedModule(IMovieService movieService, ITagService tagService)
|
||||||
: base("calendar")
|
: base("calendar")
|
||||||
{
|
{
|
||||||
_episodeService = episodeService;
|
_movieService = movieService;
|
||||||
_tagService = tagService;
|
_tagService = tagService;
|
||||||
|
|
||||||
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
||||||
|
@ -37,7 +37,7 @@ namespace NzbDrone.Api.Calendar
|
||||||
var start = DateTime.Today.AddDays(-pastDays);
|
var start = DateTime.Today.AddDays(-pastDays);
|
||||||
var end = DateTime.Today.AddDays(futureDays);
|
var end = DateTime.Today.AddDays(futureDays);
|
||||||
var unmonitored = false;
|
var unmonitored = false;
|
||||||
var premiersOnly = false;
|
//var premiersOnly = false;
|
||||||
var tags = new List<int>();
|
var tags = new List<int>();
|
||||||
|
|
||||||
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
||||||
|
@ -46,7 +46,7 @@ namespace NzbDrone.Api.Calendar
|
||||||
var queryPastDays = Request.Query.PastDays;
|
var queryPastDays = Request.Query.PastDays;
|
||||||
var queryFutureDays = Request.Query.FutureDays;
|
var queryFutureDays = Request.Query.FutureDays;
|
||||||
var queryUnmonitored = Request.Query.Unmonitored;
|
var queryUnmonitored = Request.Query.Unmonitored;
|
||||||
var queryPremiersOnly = Request.Query.PremiersOnly;
|
// var queryPremiersOnly = Request.Query.PremiersOnly;
|
||||||
var queryTags = Request.Query.Tags;
|
var queryTags = Request.Query.Tags;
|
||||||
|
|
||||||
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
||||||
|
@ -69,10 +69,10 @@ namespace NzbDrone.Api.Calendar
|
||||||
unmonitored = bool.Parse(queryUnmonitored.Value);
|
unmonitored = bool.Parse(queryUnmonitored.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryPremiersOnly.HasValue)
|
//if (queryPremiersOnly.HasValue)
|
||||||
{
|
//{
|
||||||
premiersOnly = bool.Parse(queryPremiersOnly.Value);
|
// premiersOnly = bool.Parse(queryPremiersOnly.Value);
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (queryTags.HasValue)
|
if (queryTags.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -80,43 +80,56 @@ namespace NzbDrone.Api.Calendar
|
||||||
tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id));
|
tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
var episodes = _episodeService.EpisodesBetweenDates(start, end, unmonitored);
|
var movies = _movieService.GetMoviesBetweenDates(start, end, unmonitored);
|
||||||
var calendar = new Ical.Net.Calendar
|
var calendar = new Ical.Net.Calendar
|
||||||
{
|
{
|
||||||
ProductId = "-//sonarr.tv//Sonarr//EN"
|
ProductId = "-//radarr.video//Radarr//EN"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
foreach (var movie in movies.OrderBy(v => v.Added))
|
||||||
|
|
||||||
foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value))
|
|
||||||
{
|
{
|
||||||
if (premiersOnly && (episode.SeasonNumber == 0 || episode.EpisodeNumber != 1))
|
if (tags.Any() && tags.None(movie.Tags.Contains))
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tags.Any() && tags.None(episode.Series.Tags.Contains))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var occurrence = calendar.Create<Event>();
|
var occurrence = calendar.Create<Event>();
|
||||||
occurrence.Uid = "NzbDrone_episode_" + episode.Id;
|
occurrence.Uid = "NzbDrone_movie_" + movie.Id;
|
||||||
occurrence.Status = episode.HasFile ? EventStatus.Confirmed : EventStatus.Tentative;
|
occurrence.Status = movie.HasFile ? EventStatus.Confirmed : EventStatus.Tentative;
|
||||||
occurrence.Start = new CalDateTime(episode.AirDateUtc.Value) { HasTime = true };
|
|
||||||
occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(episode.Series.Runtime)) { HasTime = true };
|
|
||||||
occurrence.Description = episode.Overview;
|
|
||||||
occurrence.Categories = new List<string>() { episode.Series.Network };
|
|
||||||
|
|
||||||
switch (episode.Series.SeriesType)
|
switch (movie.Status)
|
||||||
{
|
{
|
||||||
case SeriesTypes.Daily:
|
case MovieStatusType.PreDB:
|
||||||
occurrence.Summary = $"{episode.Series.Title} - {episode.Title}";
|
if (movie.PhysicalRelease != null)
|
||||||
|
{
|
||||||
|
occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true };
|
||||||
|
occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MovieStatusType.InCinemas:
|
||||||
|
if (movie.InCinemas != null)
|
||||||
|
{
|
||||||
|
occurrence.Start = new CalDateTime(movie.InCinemas.Value) { HasTime = true };
|
||||||
|
occurrence.End = new CalDateTime(movie.InCinemas.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MovieStatusType.Announced:
|
||||||
|
continue; // no date
|
||||||
default:
|
default:
|
||||||
occurrence.Summary =$"{episode.Series.Title} - {episode.SeasonNumber}x{episode.EpisodeNumber:00} - {episode.Title}";
|
if (movie.PhysicalRelease != null)
|
||||||
|
{
|
||||||
|
occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true };
|
||||||
|
occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
occurrence.Description = movie.Overview;
|
||||||
|
occurrence.Categories = new List<string>() { movie.Studio };
|
||||||
|
|
||||||
|
occurrence.Summary = $"{movie.Title}";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext());
|
var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext());
|
||||||
|
|
|
@ -301,8 +301,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
|
||||||
[TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "korsub")]
|
[TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "korsub")]
|
||||||
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "korsubs")]
|
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "korsubs")]
|
||||||
[TestCase("Movie.Title.2016.1080p.DKSUB.WEBRip.x264.AAC2.0-RADARR", "dksub")]
|
|
||||||
[TestCase("Movie.Title.2016.1080p.DKSUBS.WEBRip.x264.AAC2.0-RADARR", "dksubs")]
|
|
||||||
public void should_parse_hardcoded_subs(string postTitle, string sub)
|
public void should_parse_hardcoded_subs(string postTitle, string sub)
|
||||||
{
|
{
|
||||||
QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub);
|
QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub);
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.IndexerSearch
|
||||||
|
{
|
||||||
|
public class CutoffUnmetMoviesSearchCommand : Command
|
||||||
|
{
|
||||||
|
public override bool SendUpdatesToClient => true;
|
||||||
|
public string FilterKey { get; set; }
|
||||||
|
public string FilterValue { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,21 +12,24 @@ using NzbDrone.Core.DecisionEngine;
|
||||||
|
|
||||||
namespace NzbDrone.Core.IndexerSearch
|
namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
public class MovieSearchService : IExecute<MoviesSearchCommand>, IExecute<MissingMoviesSearchCommand>
|
public class MovieSearchService : IExecute<MoviesSearchCommand>, IExecute<MissingMoviesSearchCommand>, IExecute<CutoffUnmetMoviesSearchCommand>
|
||||||
{
|
{
|
||||||
private readonly IMovieService _movieService;
|
private readonly IMovieService _movieService;
|
||||||
|
private readonly IMovieCutoffService _movieCutoffService;
|
||||||
private readonly ISearchForNzb _nzbSearchService;
|
private readonly ISearchForNzb _nzbSearchService;
|
||||||
private readonly IProcessDownloadDecisions _processDownloadDecisions;
|
private readonly IProcessDownloadDecisions _processDownloadDecisions;
|
||||||
private readonly IQueueService _queueService;
|
private readonly IQueueService _queueService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public MovieSearchService(IMovieService movieService,
|
public MovieSearchService(IMovieService movieService,
|
||||||
|
IMovieCutoffService movieCutoffService,
|
||||||
ISearchForNzb nzbSearchService,
|
ISearchForNzb nzbSearchService,
|
||||||
IProcessDownloadDecisions processDownloadDecisions,
|
IProcessDownloadDecisions processDownloadDecisions,
|
||||||
IQueueService queueService,
|
IQueueService queueService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_movieService = movieService;
|
_movieService = movieService;
|
||||||
|
_movieCutoffService = movieCutoffService;
|
||||||
_nzbSearchService = nzbSearchService;
|
_nzbSearchService = nzbSearchService;
|
||||||
_processDownloadDecisions = processDownloadDecisions;
|
_processDownloadDecisions = processDownloadDecisions;
|
||||||
_queueService = queueService;
|
_queueService = queueService;
|
||||||
|
@ -71,6 +74,25 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Execute(CutoffUnmetMoviesSearchCommand message)
|
||||||
|
{
|
||||||
|
List<Movie> movies = _movieCutoffService.MoviesWhereCutoffUnmet(new PagingSpec<Movie>
|
||||||
|
{
|
||||||
|
Page = 1,
|
||||||
|
PageSize = 100000,
|
||||||
|
SortDirection = SortDirection.Ascending,
|
||||||
|
SortKey = "Id",
|
||||||
|
FilterExpression = _movieService.ConstructFilterExpression(message.FilterKey, message.FilterValue)
|
||||||
|
}).Records.ToList();
|
||||||
|
|
||||||
|
|
||||||
|
var queue = _queueService.GetQueue().Select(q => q.Movie.Id);
|
||||||
|
var missing = movies.Where(e => !queue.Contains(e.Id)).ToList();
|
||||||
|
|
||||||
|
SearchForMissingMovies(missing, message.Trigger == CommandTrigger.Manual);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void SearchForMissingMovies(List<Movie> movies, bool userInvokedSearch)
|
private void SearchForMissingMovies(List<Movie> movies, bool userInvokedSearch)
|
||||||
{
|
{
|
||||||
_logger.ProgressInfo("Performing missing search for {0} movies", movies.Count);
|
_logger.ProgressInfo("Performing missing search for {0} movies", movies.Count);
|
||||||
|
|
|
@ -130,6 +130,7 @@
|
||||||
<Compile Include="Datastore\Migration\130_remove_wombles_kickass.cs" />
|
<Compile Include="Datastore\Migration\130_remove_wombles_kickass.cs" />
|
||||||
<Compile Include="Datastore\Migration\132_rename_torrent_downloadstation.cs" />
|
<Compile Include="Datastore\Migration\132_rename_torrent_downloadstation.cs" />
|
||||||
<Compile Include="Datastore\Migration\133_add_minimumavailability.cs" />
|
<Compile Include="Datastore\Migration\133_add_minimumavailability.cs" />
|
||||||
|
<Compile Include="IndexerSearch\CutoffUnmetMoviesSearchCommand.cs" />
|
||||||
<Compile Include="Indexers\HDBits\HDBitsInfo.cs" />
|
<Compile Include="Indexers\HDBits\HDBitsInfo.cs" />
|
||||||
<Compile Include="NetImport\TMDb\TMDbLanguageCodes.cs" />
|
<Compile Include="NetImport\TMDb\TMDbLanguageCodes.cs" />
|
||||||
<Compile Include="NetImport\TMDb\TMDbSettings.cs" />
|
<Compile Include="NetImport\TMDb\TMDbSettings.cs" />
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Parser
|
||||||
)\b",
|
)\b",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||||
|
|
||||||
private static readonly Regex HardcodedSubsRegex = new Regex(@"\b(?<hcsub>(\w+SUBS?)\b)|(?<hc>(HC))\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
private static readonly Regex HardcodedSubsRegex = new Regex(@"\b(?<hcsub>(\w+SUB)\b)|(?<hc>(HC))\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||||
|
|
||||||
private static readonly Regex RemuxRegex = new Regex(@"\b(?<remux>Remux)\b",
|
private static readonly Regex RemuxRegex = new Regex(@"\b(?<remux>Remux)\b",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
|
@ -2,9 +2,7 @@ var Marionette = require('marionette');
|
||||||
var Backgrid = require('backgrid');
|
var Backgrid = require('backgrid');
|
||||||
var HistoryCollection = require('./HistoryCollection');
|
var HistoryCollection = require('./HistoryCollection');
|
||||||
var EventTypeCell = require('../../Cells/EventTypeCell');
|
var EventTypeCell = require('../../Cells/EventTypeCell');
|
||||||
var MovieTitleCell = require('../../Cells/MovieTitleHistoryCell');
|
var MovieTitleCell = require('../../Cells/MovieTitleCell');
|
||||||
var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
|
|
||||||
var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
|
|
||||||
var HistoryQualityCell = require('./HistoryQualityCell');
|
var HistoryQualityCell = require('./HistoryQualityCell');
|
||||||
var RelativeDateCell = require('../../Cells/RelativeDateCell');
|
var RelativeDateCell = require('../../Cells/RelativeDateCell');
|
||||||
var HistoryDetailsCell = require('./HistoryDetailsCell');
|
var HistoryDetailsCell = require('./HistoryDetailsCell');
|
||||||
|
@ -29,22 +27,10 @@ module.exports = Marionette.Layout.extend({
|
||||||
cellValue : 'this'
|
cellValue : 'this'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name : 'movies',
|
name : 'movie',
|
||||||
label : 'Movie Title',
|
label : 'Movie Title',
|
||||||
cell : MovieTitleCell,
|
cell : MovieTitleCell,
|
||||||
},
|
},
|
||||||
/*{
|
|
||||||
name : 'episode',
|
|
||||||
label : 'Episode',
|
|
||||||
cell : EpisodeNumberCell,
|
|
||||||
sortable : false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'episode',
|
|
||||||
label : 'Episode Title',
|
|
||||||
cell : EpisodeTitleCell,
|
|
||||||
sortable : false
|
|
||||||
},*/
|
|
||||||
{
|
{
|
||||||
name : 'this',
|
name : 'this',
|
||||||
label : 'Quality',
|
label : 'Quality',
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
<ul class='legend-labels'>
|
<ul class='legend-labels'>
|
||||||
<li class="legend-label"><span class="premiere" title="This Movie is still in cinemas and hasn't been released yet. Only poor qualities will be available"></span>In Cinemas</li>
|
<li class="legend-label"><span class="premiere" title="This Movie is still in cinemas and hasn't been released yet. Only poor qualities will be available"></span>In Cinemas</li>
|
||||||
<li class="legend-label"><span class="primary" title="This movie has only been announced yet."></span>Announced</li>
|
<li class="legend-label"><span class="primary" title="This movie has only been announced yet."></span>Announced</li>
|
||||||
<!--<li class="legend-label"><span class="warning" title="Episode is currently airing"></span>On Air</li>-->
|
|
||||||
<li class="legend-label"><span class="purple" title="Movie is currently downloading"></span>Downloading</li>
|
<li class="legend-label"><span class="purple" title="Movie is currently downloading"></span>Downloading</li>
|
||||||
<li class="legend-label"><span class="danger" title="Movie file has not been found"></span>Missing</li>
|
<li class="legend-label"><span class="danger" title="Movie file has not been found"></span>Missing</li>
|
||||||
<li class="legend-label"><span class="success" title="Movie was downloaded and sorted"></span>Downloaded</li>
|
<li class="legend-label"><span class="success" title="Movie was downloaded and sorted"></span>Downloaded</li>
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
var TemplatedCell = require('./TemplatedCell');
|
|
||||||
|
|
||||||
module.exports = TemplatedCell.extend({
|
|
||||||
className : 'series-title-cell',
|
|
||||||
template : 'Cells/SeriesTitleTemplate',
|
|
||||||
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
this.$el.html('<a href="/movies/' + this.model.get("movie").get("titleSlug") +'">' + this.model.get("movie").get("title") + '</a>'); //Hack, but somehow handlebar helper does not work.
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -185,7 +185,7 @@ module.exports = Marionette.Layout.extend({
|
||||||
|
|
||||||
CommandController.bindToCommand({
|
CommandController.bindToCommand({
|
||||||
element : this.$('.x-search-cutoff'),
|
element : this.$('.x-search-cutoff'),
|
||||||
command : { name : 'missingMoviesSearch' }
|
command : { name : 'cutOffUnmetMoviesSearch' }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ module.exports = Marionette.Layout.extend({
|
||||||
_searchMissing : function() {
|
_searchMissing : function() {
|
||||||
if (window.confirm('Are you sure you want to search for {0} filtered missing movies?'.format(this.collection.state.totalRecords) +
|
if (window.confirm('Are you sure you want to search for {0} filtered missing movies?'.format(this.collection.state.totalRecords) +
|
||||||
'One API request to each indexer will be used for each movie. ' + 'This cannot be stopped once started.')) {
|
'One API request to each indexer will be used for each movie. ' + 'This cannot be stopped once started.')) {
|
||||||
CommandController.Execute('missingMoviesSearch', { name : 'missingMoviesSearch',
|
CommandController.Execute('cutOffUnmetMoviesSearch', { name : 'cutOffUnmetMoviesSearch',
|
||||||
filterKey : this.collection.state.filterKey,
|
filterKey : this.collection.state.filterKey,
|
||||||
filterValue : this.collection.state.filterValue });
|
filterValue : this.collection.state.filterValue });
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue