1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-10-05 23:57:20 +02:00

Onedr0p/3 8 17 (#1087)

* Move ToUrlSlug to Parser, fix issue with trakt lists that have non-alphanumeric characters

* Move "Add movies" link in nav to the first link

* String interpolation!

* Add Limit to Trakt List Settings to limit the amount of movies returned, 50 by default

* Updates to FailedDownload

* Update DownloadService and CompleteDownloadService
This commit is contained in:
Devin Buhl 2017-03-08 19:00:00 -05:00 committed by GitHub
parent 5c22d0b61d
commit 571730ddec
11 changed files with 67 additions and 115 deletions

View File

@ -19,7 +19,7 @@ private void SetTitleSlug(IDbConnection conn, IDbTransaction tran)
using (IDbCommand getSeriesCmd = conn.CreateCommand()) using (IDbCommand getSeriesCmd = conn.CreateCommand())
{ {
getSeriesCmd.Transaction = tran; getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = @"SELECT Id, Title, Year FROM Movies"; getSeriesCmd.CommandText = @"SELECT Id, Title, Year, TmdbId FROM Movies";
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader()) using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
{ {
while (seriesReader.Read()) while (seriesReader.Read())
@ -27,8 +27,9 @@ private void SetTitleSlug(IDbConnection conn, IDbTransaction tran)
var id = seriesReader.GetInt32(0); var id = seriesReader.GetInt32(0);
var title = seriesReader.GetString(1); var title = seriesReader.GetString(1);
var year = seriesReader.GetInt32(2); var year = seriesReader.GetInt32(2);
var tmdbId = seriesReader.GetInt32(3);
var titleSlug = ToUrlSlug(title + "-" + year); var titleSlug = Parser.Parser.ToUrlSlug(title + "-" + tmdbId);
using (IDbCommand updateCmd = conn.CreateCommand()) using (IDbCommand updateCmd = conn.CreateCommand())
{ {
@ -43,29 +44,5 @@ private void SetTitleSlug(IDbConnection conn, IDbTransaction tran)
} }
} }
} }
public static string ToUrlSlug(string value)
{
//First to lower case
value = value.ToLowerInvariant();
//Remove all accents
var bytes = Encoding.GetEncoding("Cyrillic").GetBytes(value);
value = Encoding.ASCII.GetString(bytes);
//Replace spaces
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
//Remove invalid chars
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
//Trim dashes from end
value = value.Trim('-', '_');
//Replace double occurences of - or _
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return value;
}
} }
} }

View File

@ -30,14 +30,12 @@ public class CompletedDownloadService : ICompletedDownloadService
private readonly IParsingService _parsingService; private readonly IParsingService _parsingService;
private readonly IMovieService _movieService; private readonly IMovieService _movieService;
private readonly Logger _logger; private readonly Logger _logger;
private readonly ISeriesService _seriesService;
public CompletedDownloadService(IConfigService configService, public CompletedDownloadService(IConfigService configService,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
IHistoryService historyService, IHistoryService historyService,
IDownloadedMovieImportService downloadedMovieImportService, IDownloadedMovieImportService downloadedMovieImportService,
IParsingService parsingService, IParsingService parsingService,
ISeriesService seriesService,
IMovieService movieService, IMovieService movieService,
Logger logger) Logger logger)
{ {
@ -48,7 +46,6 @@ public CompletedDownloadService(IConfigService configService,
_parsingService = parsingService; _parsingService = parsingService;
_movieService = movieService; _movieService = movieService;
_logger = logger; _logger = logger;
_seriesService = seriesService;
} }
public void Process(TrackedDownload trackedDownload, bool ignoreWarnings = false) public void Process(TrackedDownload trackedDownload, bool ignoreWarnings = false)

View File

@ -137,16 +137,16 @@ public void DownloadReport(RemoteMovie remoteMovie)
throw; throw;
} }
var episodeGrabbedEvent = new MovieGrabbedEvent(remoteMovie); var movieGrabbedEvent = new MovieGrabbedEvent(remoteMovie);
episodeGrabbedEvent.DownloadClient = downloadClient.GetType().Name; movieGrabbedEvent.DownloadClient = downloadClient.GetType().Name;
if (!string.IsNullOrWhiteSpace(downloadClientId)) if (!string.IsNullOrWhiteSpace(downloadClientId))
{ {
episodeGrabbedEvent.DownloadId = downloadClientId; movieGrabbedEvent.DownloadId = downloadClientId;
} }
_logger.ProgressInfo("Report sent to {0}. {1}", downloadClient.Definition.Name, downloadTitle); _logger.ProgressInfo("Report sent to {0}. {1}", downloadClient.Definition.Name, downloadTitle);
_eventAggregator.PublishEvent(episodeGrabbedEvent); _eventAggregator.PublishEvent(movieGrabbedEvent);
} }
} }
} }

View File

@ -87,9 +87,9 @@ private void PublishDownloadFailedEvent(List<History.History> historyItems, stri
var downloadFailedEvent = new DownloadFailedEvent var downloadFailedEvent = new DownloadFailedEvent
{ {
SeriesId = historyItem.SeriesId, SeriesId = 0,
MovieId = historyItem.MovieId, MovieId = historyItem.MovieId,
EpisodeIds = historyItems.Select(h => h.EpisodeId).ToList(), EpisodeIds = null,
Quality = historyItem.Quality, Quality = historyItem.Quality,
SourceTitle = historyItem.SourceTitle, SourceTitle = historyItem.SourceTitle,
DownloadClient = historyItem.Data.GetValueOrDefault(History.History.DOWNLOAD_CLIENT), DownloadClient = historyItem.Data.GetValueOrDefault(History.History.DOWNLOAD_CLIENT),

View File

@ -12,17 +12,17 @@ namespace NzbDrone.Core.Download
public class RedownloadFailedDownloadService : IHandleAsync<DownloadFailedEvent> public class RedownloadFailedDownloadService : IHandleAsync<DownloadFailedEvent>
{ {
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly IEpisodeService _episodeService; private readonly IMovieService _movieService;
private readonly IManageCommandQueue _commandQueueManager; private readonly IManageCommandQueue _commandQueueManager;
private readonly Logger _logger; private readonly Logger _logger;
public RedownloadFailedDownloadService(IConfigService configService, public RedownloadFailedDownloadService(IConfigService configService,
IEpisodeService episodeService, IMovieService movieService,
IManageCommandQueue commandQueueManager, IManageCommandQueue commandQueueManager,
Logger logger) Logger logger)
{ {
_configService = configService; _configService = configService;
_episodeService = episodeService; _movieService = movieService;
_commandQueueManager = commandQueueManager; _commandQueueManager = commandQueueManager;
_logger = logger; _logger = logger;
} }
@ -38,40 +38,8 @@ public void HandleAsync(DownloadFailedEvent message)
if (message.MovieId != 0) if (message.MovieId != 0)
{ {
_logger.Debug("Failed download contains a movie, searching again."); _logger.Debug("Failed download contains a movie, searching again.");
_commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List<int> { message.MovieId } }); _commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List<int> { message.MovieId } });
return;
} }
if (message.EpisodeIds.Count == 1)
{
_logger.Debug("Failed download only contains one episode, searching again");
_commandQueueManager.Push(new EpisodeSearchCommand(message.EpisodeIds));
return;
}
var seasonNumber = _episodeService.GetEpisode(message.EpisodeIds.First()).SeasonNumber;
var episodesInSeason = _episodeService.GetEpisodesBySeason(message.SeriesId, seasonNumber);
if (message.EpisodeIds.Count == episodesInSeason.Count)
{
_logger.Debug("Failed download was entire season, searching again");
_commandQueueManager.Push(new SeasonSearchCommand
{
SeriesId = message.SeriesId,
SeasonNumber = seasonNumber
});
return;
}
_logger.Debug("Failed download contains multiple episodes, probably a double episode, searching again");
_commandQueueManager.Push(new EpisodeSearchCommand(message.EpisodeIds));
} }
} }
} }

View File

@ -135,7 +135,7 @@ private List<TrackedDownload> ProcessClientItems(IDownloadClient downloadClient,
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't process tracked download " + downloadItem.Title); _logger.Error(e, $"Couldn't process tracked download {downloadItem.Title}");
} }
return trackedDownloads; return trackedDownloads;

View File

@ -9,11 +9,7 @@
using NzbDrone.Core.Exceptions; using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource.SkyHook.Resource; using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading; using System.Threading;
using NzbDrone.Core.Parser; using NzbDrone.Core.Parser;
using NzbDrone.Core.Profiles; using NzbDrone.Core.Profiles;
@ -133,7 +129,7 @@ public Movie GetMovieInfo(int TmdbId, Profile profile = null)
movie.TmdbId = TmdbId; movie.TmdbId = TmdbId;
movie.ImdbId = resource.imdb_id; movie.ImdbId = resource.imdb_id;
movie.Title = resource.title; movie.Title = resource.title;
movie.TitleSlug = ToUrlSlug(resource.title); movie.TitleSlug = Parser.Parser.ToUrlSlug(resource.title);
movie.CleanTitle = Parser.Parser.CleanSeriesTitle(resource.title); movie.CleanTitle = Parser.Parser.CleanSeriesTitle(resource.title);
movie.SortTitle = Parser.Parser.NormalizeTitle(resource.title); movie.SortTitle = Parser.Parser.NormalizeTitle(resource.title);
movie.Overview = resource.overview; movie.Overview = resource.overview;
@ -475,7 +471,7 @@ private Movie MapMovie(MovieResult result)
{ {
imdbMovie.SortTitle = Parser.Parser.NormalizeTitle(result.title); imdbMovie.SortTitle = Parser.Parser.NormalizeTitle(result.title);
imdbMovie.Title = result.title; imdbMovie.Title = result.title;
imdbMovie.TitleSlug = ToUrlSlug(result.title); imdbMovie.TitleSlug = Parser.Parser.ToUrlSlug(result.title);
if (result.release_date.IsNotNullOrWhiteSpace()) if (result.release_date.IsNotNullOrWhiteSpace())
{ {
@ -662,30 +658,6 @@ private static MediaCoverTypes MapCoverType(string coverType)
} }
} }
public static string ToUrlSlug(string value)
{
//First to lower case
value = value.ToLowerInvariant();
//Remove all accents
var bytes = Encoding.GetEncoding("ISO-8859-8").GetBytes(value);
value = Encoding.ASCII.GetString(bytes);
//Replace spaces
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
//Remove invalid chars
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
//Trim dashes from end
value = value.Trim('-', '_');
//Replace double occurences of - or _
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return value;
}
public Movie MapMovieToTmdbMovie(Movie movie) public Movie MapMovieToTmdbMovie(Movie movie)
{ {
Movie newMovie = movie; Movie newMovie = movie;

View File

@ -1,6 +1,8 @@
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
@ -87,42 +89,43 @@ private IEnumerable<NetImportRequest> GetMovies(string searchParameters)
{ {
var link = Settings.Link.Trim(); var link = Settings.Link.Trim();
var filters = $"?years={Settings.Years}&genres={Settings.Genres.ToLower()}&ratings={Settings.Rating}&certifications={Settings.Ceritification.ToLower()}"; var filtersAndLimit = $"?years={Settings.Years}&genres={Settings.Genres.ToLower()}&ratings={Settings.Rating}&certifications={Settings.Ceritification.ToLower()}&limit={Settings.Limit}";
switch (Settings.ListType) switch (Settings.ListType)
{ {
case (int)TraktListType.UserCustomList: case (int)TraktListType.UserCustomList:
link = link + $"/users/{Settings.Username.Trim()}/lists/{Settings.Listname.Trim()}/items/movies"; var listName = Parser.Parser.ToUrlSlug(Settings.Listname.Trim());
link = link + $"/users/{Settings.Username.Trim()}/lists/{listName}/items/movies?limit={Settings.Limit}";
break; break;
case (int)TraktListType.UserWatchList: case (int)TraktListType.UserWatchList:
link = link + $"/users/{Settings.Username.Trim()}/watchlist/movies"; link = link + $"/users/{Settings.Username.Trim()}/watchlist/movies?limit={Settings.Limit}";
break; break;
case (int)TraktListType.UserWatchedList: case (int)TraktListType.UserWatchedList:
link = link + $"/users/{Settings.Username.Trim()}/watched/movies"; link = link + $"/users/{Settings.Username.Trim()}/watched/movies?limit={Settings.Limit}";
break; break;
case (int)TraktListType.Trending: case (int)TraktListType.Trending:
link = link + "/movies/trending" + filters; link = link + "/movies/trending" + filtersAndLimit;
break; break;
case (int)TraktListType.Popular: case (int)TraktListType.Popular:
link = link + "/movies/popular" + filters; link = link + "/movies/popular" + filtersAndLimit;
break; break;
case (int)TraktListType.Anticipated: case (int)TraktListType.Anticipated:
link = link + "/movies/anticipated" + filters; link = link + "/movies/anticipated" + filtersAndLimit;
break; break;
case (int)TraktListType.BoxOffice: case (int)TraktListType.BoxOffice:
link = link + "/movies/boxoffice" + filters; link = link + "/movies/boxoffice" + filtersAndLimit;
break; break;
case (int)TraktListType.TopWatchedByWeek: case (int)TraktListType.TopWatchedByWeek:
link = link + "/movies/watched/weekly" + filters; link = link + "/movies/watched/weekly" + filtersAndLimit;
break; break;
case (int)TraktListType.TopWatchedByMonth: case (int)TraktListType.TopWatchedByMonth:
link = link + "/movies/watched/monthly" + filters; link = link + "/movies/watched/monthly" + filtersAndLimit;
break; break;
case (int)TraktListType.TopWatchedByYear: case (int)TraktListType.TopWatchedByYear:
link = link + "/movies/watched/yearly" + filters; link = link + "/movies/watched/yearly" + filtersAndLimit;
break; break;
case (int)TraktListType.TopWatchedByAllTime: case (int)TraktListType.TopWatchedByAllTime:
link = link + "/movies/watched/all" + filters; link = link + "/movies/watched/all" + filtersAndLimit;
break; break;
} }
@ -131,7 +134,7 @@ private IEnumerable<NetImportRequest> GetMovies(string searchParameters)
var request = new NetImportRequest($"{link}", HttpAccept.Json); var request = new NetImportRequest($"{link}", HttpAccept.Json);
request.HttpRequest.Headers.Add("trakt-api-version", "2"); request.HttpRequest.Headers.Add("trakt-api-version", "2");
request.HttpRequest.Headers.Add("trakt-api-key", "964f67b126ade0112c4ae1f0aea3a8fb03190f71117bd83af6a0560a99bc52e6"); //aeon request.HttpRequest.Headers.Add("trakt-api-key", "964f67b126ade0112c4ae1f0aea3a8fb03190f71117bd83af6a0560a99bc52e6"); //aeon
if (_configService.TraktAuthToken != null) if (_configService.TraktAuthToken.IsNotNullOrWhiteSpace())
{ {
request.HttpRequest.Headers.Add("Authorization", "Bearer " + _configService.TraktAuthToken); request.HttpRequest.Headers.Add("Authorization", "Bearer " + _configService.TraktAuthToken);
} }

View File

@ -43,6 +43,11 @@ public TraktSettingsValidator()
.Matches(@"^\d+(\-\d+)?$", RegexOptions.IgnoreCase) .Matches(@"^\d+(\-\d+)?$", RegexOptions.IgnoreCase)
.When(c => c.Years.IsNotNullOrWhiteSpace()) .When(c => c.Years.IsNotNullOrWhiteSpace())
.WithMessage("Not a valid year or range of years"); .WithMessage("Not a valid year or range of years");
// Limit not smaller than 1 and not larger than 100
RuleFor(c => c.Limit)
.InclusiveBetween(1, 500)
.WithMessage("Must be 1 thru 500");
} }
} }
@ -60,6 +65,7 @@ public TraktSettings()
Ceritification = "NR,G,PG,PG-13,R,NC-17"; Ceritification = "NR,G,PG,PG-13,R,NC-17";
Genres = ""; Genres = "";
Years = ""; Years = "";
Limit = 100;
} }
[FieldDefinition(0, Label = "Trakt API URL", HelpText = "Link to to Trakt API URL, do not change unless you know what you are doing.")] [FieldDefinition(0, Label = "Trakt API URL", HelpText = "Link to to Trakt API URL, do not change unless you know what you are doing.")]
@ -86,6 +92,9 @@ public TraktSettings()
[FieldDefinition(7, Label = "Years", HelpText = "Filter movies by year or year range")] [FieldDefinition(7, Label = "Years", HelpText = "Filter movies by year or year range")]
public string Years { get; set; } public string Years { get; set; }
[FieldDefinition(8, Label = "Limit", HelpText = "Limit the number of movies to get")]
public int Limit { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()
{ {

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NLog; using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
@ -608,6 +609,30 @@ public static string NormalizeImdbId(string imdbId)
return null; return null;
} }
public static string ToUrlSlug(string value)
{
//First to lower case
value = value.ToLowerInvariant();
//Remove all accents
var bytes = Encoding.GetEncoding("ISO-8859-8").GetBytes(value);
value = Encoding.ASCII.GetString(bytes);
//Replace spaces
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
//Remove invalid chars
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
//Trim dashes from end
value = value.Trim('-', '_');
//Replace double occurences of - or _
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return value;
}
public static string ParseSeriesName(string title) public static string ParseSeriesName(string title)
{ {
Logger.Debug("Parsing string '{0}'", title); Logger.Debug("Parsing string '{0}'", title);

View File

@ -19,8 +19,9 @@
</div> </div>
<div class="navbar-collapse collapse x-navbar-collapse"> <div class="navbar-collapse collapse x-navbar-collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="{{UrlBase}}/" class="x-series-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-series"></i> Movies</a></li>
<li><a href="{{UrlBase}}/addmovies" class="x-series-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-add"></i> Add Movies</a></li> <li><a href="{{UrlBase}}/addmovies" class="x-series-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-add"></i> Add Movies</a></li>
<li><a href="{{UrlBase}}/" class="x-series-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-series"></i> Movies</a></li>
<li><a href="{{UrlBase}}/calendar" class="x-calendar-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-calendar"></i> Calendar</a></li> <li><a href="{{UrlBase}}/calendar" class="x-calendar-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-calendar"></i> Calendar</a></li>
<li><a href="{{UrlBase}}/activity" class="x-activity-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-activity"></i> Activity<span id="x-queue-count" class="navbar-info"></span></a></li> <li><a href="{{UrlBase}}/activity" class="x-activity-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-activity"></i> Activity<span id="x-queue-count" class="navbar-info"></span></a></li>
<li><a href="{{UrlBase}}/wanted" class="x-wanted-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-wanted"></i> Wanted</a></li> <li><a href="{{UrlBase}}/wanted" class="x-wanted-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-wanted"></i> Wanted</a></li>