merge from Develop
BIN
Logo/1024.png
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 48 KiB |
BIN
Logo/128.png
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 5.1 KiB |
BIN
Logo/16.png
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 701 B |
BIN
Logo/256.png
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 11 KiB |
BIN
Logo/32.png
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
Logo/400.png
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 17 KiB |
BIN
Logo/48.png
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 2 KiB |
BIN
Logo/512.png
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 22 KiB |
BIN
Logo/64.png
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
Logo/800.png
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 37 KiB |
583
Logo/Radarr.svg
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 31 KiB |
44
README.md
|
@ -12,7 +12,9 @@
|
||||||
| AppVeyor | [](https://ci.appveyor.com/project/galli-leo/Radarr) | [](https://ci.appveyor.com/project/galli-leo/Radarr-usby1) |
|
| AppVeyor | [](https://ci.appveyor.com/project/galli-leo/Radarr) | [](https://ci.appveyor.com/project/galli-leo/Radarr-usby1) |
|
||||||
| Travis | [](https://travis-ci.org/Radarr/Radarr) | [](https://travis-ci.org/Radarr/Radarr) |
|
| Travis | [](https://travis-ci.org/Radarr/Radarr) | [](https://travis-ci.org/Radarr/Radarr) |
|
||||||
|
|
||||||
This fork of Sonarr aims to turn it into something like CouchPotato.
|
A fork of [Sonarr](https://github.com/Sonarr/Sonarr) to work with movies à la Couchpotato.
|
||||||
|
|
||||||
|
**This fork works independently of Sonarr and will not interfere with it.**
|
||||||
|
|
||||||
## Downloads
|
## Downloads
|
||||||
|
|
||||||
|
@ -34,34 +36,34 @@ To connect to the UI, fire up your browser and open <http://localhost:7878> or <
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
### Currently Working
|
### Current Features
|
||||||
|
|
||||||
* Adding new movies
|
|
||||||
* Manually searching for releases of movies
|
|
||||||
* Automatically searching for releases
|
|
||||||
* Automatically importing downloaded movies
|
|
||||||
* Recognizing Special Editions, Director's Cut, etc.
|
|
||||||
* Identifying releases with hardcoded subs
|
|
||||||
* Rarbg.to, Torznab and Newznab Indexer
|
|
||||||
* QBittorrent and Deluge download client (Other clients are coming)
|
|
||||||
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
|
|
||||||
|
|
||||||
### Planned Features
|
|
||||||
|
|
||||||
* Scanning PreDB to know when a new release is available
|
|
||||||
* Fixing the other Indexers and download clients
|
|
||||||
* Importing of Sonarr config
|
|
||||||
|
|
||||||
### Major Features
|
|
||||||
|
|
||||||
|
* Adding new movies with lots of information, such as trailers, ratings, etc.
|
||||||
* Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc.
|
* Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc.
|
||||||
* Can watch for better quality of the movies you have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
|
* Can watch for better quality of the movies you have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
|
||||||
* Automatic failed download handling will try another release if one fails
|
* Automatic failed download handling will try another release if one fails
|
||||||
* Manual search so you can pick any release or to see why a release was not downloaded automatically
|
* Manual search so you can pick any release or to see why a release was not downloaded automatically
|
||||||
* Full integration with SABnzbd and NZBGet
|
* Full integration with SABnzbd and NZBGet
|
||||||
* Full integration with Kodi, Plex (notification, library update, metadata)
|
* Automatically searching for releases as well as RSS Sync
|
||||||
|
* Automatically importing downloaded movies
|
||||||
|
* Recognizing Special Editions, Director's Cut, etc.
|
||||||
|
* Identifying releases with hardcoded subs
|
||||||
|
* All indexers supported by Sonarr also supported
|
||||||
|
* New PassThePopcorn Indexer
|
||||||
|
* QBittorrent, Deluge, rTorrent, Transmission and uTorrent download client (Other clients are coming)
|
||||||
|
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
|
||||||
* And a beautiful UI
|
* And a beautiful UI
|
||||||
|
|
||||||
|
### Planned Features
|
||||||
|
|
||||||
|
* Scanning PreDB to know when a new release is available
|
||||||
|
* Fixing the other Indexers and download clients
|
||||||
|
* Importing movies from various online sources, such as IMDb Watchlists (A complete list can be found [here](https://github.com/Radarr/Radarr/issues/114))
|
||||||
|
* Full integration with Kodi, Plex (notification, library update, metadata)
|
||||||
|
|
||||||
|
##Feature Requests
|
||||||
|
[](http://feathub.com/Radarr/Radarr)
|
||||||
|
|
||||||
## Configuring Development Environment
|
## Configuring Development Environment
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
|
@ -64,6 +64,8 @@ namespace NzbDrone.Api.Authentication
|
||||||
new DefaultHmacProvider(new PassphraseKeyGenerator(_configService.HmacPassphrase, Encoding.ASCII.GetBytes(_configService.HmacSalt)))
|
new DefaultHmacProvider(new PassphraseKeyGenerator(_configService.HmacPassphrase, Encoding.ASCII.GetBytes(_configService.HmacSalt)))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
FormsAuthentication.FormsAuthenticationCookieName = "_ncfaradarr"; //For those people that both have sonarr and radarr.
|
||||||
|
|
||||||
FormsAuthentication.Enable(pipelines, new FormsAuthenticationConfiguration
|
FormsAuthentication.Enable(pipelines, new FormsAuthenticationConfiguration
|
||||||
{
|
{
|
||||||
RedirectUrl = _configFileProvider.UrlBase + "/login",
|
RedirectUrl = _configFileProvider.UrlBase + "/login",
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace NzbDrone.Api.Validation
|
||||||
public class RssSyncIntervalValidator : PropertyValidator
|
public class RssSyncIntervalValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public RssSyncIntervalValidator()
|
public RssSyncIntervalValidator()
|
||||||
: base("Must be between 10 and 120 or 0 to disable")
|
: base("Must be between 10 and 720 or 0 to disable")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ namespace NzbDrone.Api.Validation
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value >= 10 && value <= 120)
|
if (value >= 10 && value <= 720)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 81 KiB |
|
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.Configuration
|
||||||
[Test]
|
[Test]
|
||||||
public void Get_value_should_return_default_when_no_value()
|
public void Get_value_should_return_default_when_no_value()
|
||||||
{
|
{
|
||||||
Subject.RssSyncInterval.Should().Be(15);
|
Subject.RssSyncInterval.Should().Be(60);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.Configuration
|
||||||
public void get_value_with_out_persist_should_not_store_default_value()
|
public void get_value_with_out_persist_should_not_store_default_value()
|
||||||
{
|
{
|
||||||
var interval = Subject.RssSyncInterval;
|
var interval = Subject.RssSyncInterval;
|
||||||
interval.Should().Be(15);
|
interval.Should().Be(60);
|
||||||
Mocker.GetMock<IConfigRepository>().Verify(c => c.Insert(It.IsAny<Config>()), Times.Never());
|
Mocker.GetMock<IConfigRepository>().Verify(c => c.Insert(It.IsAny<Config>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace NzbDrone.Core.Configuration
|
||||||
|
|
||||||
public int RssSyncInterval
|
public int RssSyncInterval
|
||||||
{
|
{
|
||||||
get { return GetValueInt("RssSyncInterval", 15); }
|
get { return GetValueInt("RssSyncInterval", 60); }
|
||||||
|
|
||||||
set { SetValue("RssSyncInterval", value); }
|
set { SetValue("RssSyncInterval", value); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,21 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||||
|
|
||||||
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
|
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (searchCriteria != null)
|
||||||
|
{
|
||||||
|
if (searchCriteria.UserInvokedSearch)
|
||||||
|
{
|
||||||
|
_logger.Debug("Skipping monitored check during search");
|
||||||
|
return Decision.Accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!subject.Movie.Monitored)
|
||||||
|
{
|
||||||
|
return Decision.Reject("Movie is not monitored");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Decision.Accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
|
|
|
@ -5,6 +5,7 @@ using NzbDrone.Core.IndexerSearch;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download
|
namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
|
@ -38,7 +39,7 @@ namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
_logger.Debug("Failed download contains a movie, searching again.");
|
_logger.Debug("Failed download contains a movie, searching again.");
|
||||||
|
|
||||||
_commandQueueManager.Push(new MoviesSearchCommand { MovieId = message.MovieId });
|
_commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List<int> { message.MovieId } });
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,13 +102,13 @@ namespace NzbDrone.Core.Extras
|
||||||
|
|
||||||
public void Handle(MediaCoversUpdatedEvent message)
|
public void Handle(MediaCoversUpdatedEvent message)
|
||||||
{
|
{
|
||||||
var series = message.Series;
|
//var series = message.Series;
|
||||||
var episodeFiles = GetEpisodeFiles(series.Id);
|
//var episodeFiles = GetEpisodeFiles(series.Id);
|
||||||
|
|
||||||
foreach (var extraFileManager in _extraFileManagers)
|
//foreach (var extraFileManager in _extraFileManagers)
|
||||||
{
|
//{
|
||||||
extraFileManager.CreateAfterSeriesScan(series, episodeFiles);
|
// extraFileManager.CreateAfterSeriesScan(series, episodeFiles);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Implementing this will fix a lot of our warning exceptions
|
//TODO: Implementing this will fix a lot of our warning exceptions
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.IndexerSearch
|
||||||
|
{
|
||||||
|
public class MissingMoviesSearchCommand : Command
|
||||||
|
{
|
||||||
|
public override bool SendUpdatesToClient => true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NzbDrone.Core.IndexerSearch
|
namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
public class MoviesSearchCommand : Command
|
public class MoviesSearchCommand : Command
|
||||||
{
|
{
|
||||||
public int MovieId { get; set; }
|
public List<int> MovieIds { get; set; }
|
||||||
|
|
||||||
public override bool SendUpdatesToClient => true;
|
public override bool SendUpdatesToClient => true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,22 +4,23 @@ using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Core.IndexerSearch
|
namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
public class MovieSearchService : IExecute<MoviesSearchCommand>
|
public class MovieSearchService : IExecute<MoviesSearchCommand>, IExecute<MissingMoviesSearchCommand>
|
||||||
{
|
{
|
||||||
private readonly IMovieService _seriesService;
|
private readonly IMovieService _movieService;
|
||||||
private readonly ISearchForNzb _nzbSearchService;
|
private readonly ISearchForNzb _nzbSearchService;
|
||||||
private readonly IProcessDownloadDecisions _processDownloadDecisions;
|
private readonly IProcessDownloadDecisions _processDownloadDecisions;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public MovieSearchService(IMovieService seriesService,
|
public MovieSearchService(IMovieService movieService,
|
||||||
ISearchForNzb nzbSearchService,
|
ISearchForNzb nzbSearchService,
|
||||||
IProcessDownloadDecisions processDownloadDecisions,
|
IProcessDownloadDecisions processDownloadDecisions,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_seriesService = seriesService;
|
_movieService = movieService;
|
||||||
_nzbSearchService = nzbSearchService;
|
_nzbSearchService = nzbSearchService;
|
||||||
_processDownloadDecisions = processDownloadDecisions;
|
_processDownloadDecisions = processDownloadDecisions;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -27,20 +28,35 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
||||||
public void Execute(MoviesSearchCommand message)
|
public void Execute(MoviesSearchCommand message)
|
||||||
{
|
{
|
||||||
var series = _seriesService.GetMovie(message.MovieId);
|
|
||||||
|
|
||||||
var downloadedCount = 0;
|
var downloadedCount = 0;
|
||||||
|
foreach (var movieId in message.MovieIds)
|
||||||
|
{
|
||||||
|
var series = _movieService.GetMovie(movieId);
|
||||||
|
|
||||||
if (!series.Monitored)
|
if (!series.Monitored)
|
||||||
{
|
{
|
||||||
_logger.Debug("Movie {0} is not monitored, skipping search", series.Title);
|
_logger.Debug("Movie {0} is not monitored, skipping search", series.Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
var decisions = _nzbSearchService.MovieSearch(message.MovieId, false);//_nzbSearchService.SeasonSearch(message.MovieId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual);
|
var decisions = _nzbSearchService.MovieSearch(movieId, false);//_nzbSearchService.SeasonSearch(message.MovieId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual);
|
||||||
downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count;
|
downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count;
|
||||||
|
|
||||||
|
}
|
||||||
_logger.ProgressInfo("Movie search completed. {0} reports downloaded.", downloadedCount);
|
_logger.ProgressInfo("Movie search completed. {0} reports downloaded.", downloadedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Execute(MissingMoviesSearchCommand message)
|
||||||
|
{
|
||||||
|
var movies = _movieService.MoviesWithoutFiles(new PagingSpec<Movie>
|
||||||
|
{
|
||||||
|
Page = 1,
|
||||||
|
PageSize = 100000,
|
||||||
|
SortDirection = SortDirection.Ascending,
|
||||||
|
SortKey = "Id",
|
||||||
|
FilterExpression =
|
||||||
|
v =>
|
||||||
|
v.Monitored == true
|
||||||
|
}).Records.ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,13 +54,19 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
|
||||||
private IEnumerable<IndexerRequest> GetRequest(string searchParameters)
|
private IEnumerable<IndexerRequest> GetRequest(string searchParameters)
|
||||||
{
|
{
|
||||||
|
var onlyInternal = "";
|
||||||
|
if (Settings.Internal)
|
||||||
|
{
|
||||||
|
onlyInternal = "&internal=true";
|
||||||
|
}
|
||||||
|
|
||||||
if (searchParameters != null)
|
if (searchParameters != null)
|
||||||
{
|
{
|
||||||
yield return new IndexerRequest(string.Format("{0}/searchapi.php?action=imdbsearch&passkey={1}&imdb={2}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.Passkey.Trim(), searchParameters), HttpAccept.Rss);
|
yield return new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/searchapi.php?action=imdbsearch&passkey={Settings.Passkey.Trim()}&imdb={searchParameters}", HttpAccept.Rss);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yield return new IndexerRequest(string.Format("{0}/searchapi.php?action=latestmovies&passkey={1}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.Passkey.Trim()), HttpAccept.Rss);
|
yield return new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/searchapi.php?action=latestmovies&passkey={Settings.Passkey.Trim()}{onlyInternal}", HttpAccept.Rss);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
[FieldDefinition(1, Label = "Passkey")]
|
[FieldDefinition(1, Label = "Passkey")]
|
||||||
public string Passkey { get; set; }
|
public string Passkey { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(2, Type = FieldType.Checkbox, Label = "Require Internal", HelpText = "Will only include internal releases for RSS Sync.")]
|
||||||
|
public bool Internal { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
{
|
{
|
||||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
|
|
@ -30,12 +30,14 @@ namespace NzbDrone.Core.Jobs
|
||||||
{
|
{
|
||||||
private readonly IScheduledTaskRepository _scheduledTaskRepository;
|
private readonly IScheduledTaskRepository _scheduledTaskRepository;
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, Logger logger)
|
public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, IConfigFileProvider configFileProvider, Logger logger)
|
||||||
{
|
{
|
||||||
_scheduledTaskRepository = scheduledTaskRepository;
|
_scheduledTaskRepository = scheduledTaskRepository;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
|
_configFileProvider = configFileProvider;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +61,18 @@ namespace NzbDrone.Core.Jobs
|
||||||
|
|
||||||
public void Handle(ApplicationStartedEvent message)
|
public void Handle(ApplicationStartedEvent message)
|
||||||
{
|
{
|
||||||
|
float updateInterval = 6 * 60;
|
||||||
|
|
||||||
|
if (_configFileProvider.Branch == "nightly")
|
||||||
|
{
|
||||||
|
updateInterval = 30;
|
||||||
|
}
|
||||||
|
|
||||||
var defaultTasks = new[]
|
var defaultTasks = new[]
|
||||||
{
|
{
|
||||||
new ScheduledTask{ Interval = 0.25f, TypeName = typeof(CheckForFinishedDownloadCommand).FullName},
|
new ScheduledTask{ Interval = 0.25f, TypeName = typeof(CheckForFinishedDownloadCommand).FullName},
|
||||||
new ScheduledTask{ Interval = 5, TypeName = typeof(MessagingCleanupCommand).FullName},
|
new ScheduledTask{ Interval = 5, TypeName = typeof(MessagingCleanupCommand).FullName},
|
||||||
new ScheduledTask{ Interval = 6*60, TypeName = typeof(ApplicationUpdateCommand).FullName},
|
new ScheduledTask{ Interval = updateInterval, TypeName = typeof(ApplicationUpdateCommand).FullName},
|
||||||
// new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName},
|
// new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName},
|
||||||
new ScheduledTask{ Interval = 6*60, TypeName = typeof(CheckHealthCommand).FullName},
|
new ScheduledTask{ Interval = 6*60, TypeName = typeof(CheckHealthCommand).FullName},
|
||||||
new ScheduledTask{ Interval = 24*60, TypeName = typeof(RefreshMovieCommand).FullName},
|
new ScheduledTask{ Interval = 24*60, TypeName = typeof(RefreshMovieCommand).FullName},
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
using NzbDrone.Common.Disk;
|
using System;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
|
using System.Drawing;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaCover
|
namespace NzbDrone.Core.MediaCover
|
||||||
{
|
{
|
||||||
|
@ -12,11 +15,13 @@ namespace NzbDrone.Core.MediaCover
|
||||||
{
|
{
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient)
|
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AlreadyExists(string url, string path)
|
public bool AlreadyExists(string url, string path)
|
||||||
|
@ -26,9 +31,38 @@ namespace NzbDrone.Core.MediaCover
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!IsValidGDIPlusImage(path))
|
||||||
|
{
|
||||||
|
_diskProvider.DeleteFile(path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var headers = _httpClient.Head(new HttpRequest(url)).Headers;
|
var headers = _httpClient.Head(new HttpRequest(url)).Headers;
|
||||||
var fileSize = _diskProvider.GetFileSize(path);
|
var fileSize = _diskProvider.GetFileSize(path);
|
||||||
return fileSize == headers.ContentLength;
|
return fileSize == headers.ContentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsValidGDIPlusImage(string filename)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GdiPlusInterop.CheckGdiPlus();
|
||||||
|
|
||||||
|
using (var bmp = new Bitmap(filename))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (DllNotFoundException ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Could not find libgdiplus. Cannot test if image is corrupt.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Debug(ex, "Corrupted image found at: {0}. Redownloading...", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -48,11 +48,12 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||||
return AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? AudioChannels - 1 + 0.1m : AudioChannels;
|
return AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? AudioChannels - 1 + 0.1m : AudioChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
decimal channels = 0;
|
return
|
||||||
|
AudioChannelPositions.Replace("Object Based /", "").Replace(" / ", "$")
|
||||||
decimal.TryParse(AudioChannelPositions.Split('/').First(), out channels);
|
.Split('$')
|
||||||
|
.First()
|
||||||
return channels;
|
.Split('/')
|
||||||
|
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Profiles;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource
|
namespace NzbDrone.Core.MetadataSource
|
||||||
|
@ -7,6 +8,6 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
public interface IProvideMovieInfo
|
public interface IProvideMovieInfo
|
||||||
{
|
{
|
||||||
Movie GetMovieInfo(string ImdbId);
|
Movie GetMovieInfo(string ImdbId);
|
||||||
Movie GetMovieInfo(int TmdbId);
|
Movie GetMovieInfo(int TmdbId, Profile profile);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,8 @@ using NzbDrone.Core.Tv;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Profiles;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook
|
namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
{
|
{
|
||||||
|
@ -67,25 +69,39 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
return new Tuple<Series, List<Episode>>(series, episodes.ToList());
|
return new Tuple<Series, List<Episode>>(series, episodes.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Movie GetMovieInfo(int TmdbId)
|
public Movie GetMovieInfo(int TmdbId, Profile profile = null)
|
||||||
{
|
{
|
||||||
|
var langCode = profile != null ? IsoLanguages.Get(profile.Language).TwoLetterCode : "us";
|
||||||
|
|
||||||
var request = _movieBuilder.Create()
|
var request = _movieBuilder.Create()
|
||||||
.SetSegment("route", "movie")
|
.SetSegment("route", "movie")
|
||||||
.SetSegment("id", TmdbId.ToString())
|
.SetSegment("id", TmdbId.ToString())
|
||||||
.SetSegment("secondaryRoute", "")
|
.SetSegment("secondaryRoute", "")
|
||||||
.AddQueryParam("append_to_response", "alternative_titles,release_dates,videos")
|
.AddQueryParam("append_to_response", "alternative_titles,release_dates,videos")
|
||||||
.AddQueryParam("country", "US")
|
.AddQueryParam("language", langCode.ToUpper())
|
||||||
|
// .AddQueryParam("country", "US")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
request.AllowAutoRedirect = true;
|
request.AllowAutoRedirect = true;
|
||||||
request.SuppressHttpError = true;
|
request.SuppressHttpError = true;
|
||||||
|
|
||||||
var response = _httpClient.Get<MovieResourceRoot>(request);
|
var response = _httpClient.Get<MovieResourceRoot>(request);
|
||||||
|
|
||||||
var resource = response.Resource;
|
var resource = response.Resource;
|
||||||
|
|
||||||
var movie = new Movie();
|
var movie = new Movie();
|
||||||
|
|
||||||
|
foreach (var alternativeTitle in resource.alternative_titles.titles)
|
||||||
|
{
|
||||||
|
if (alternativeTitle.iso_3166_1.ToLower() == langCode)
|
||||||
|
{
|
||||||
|
movie.AlternativeTitles.Add(alternativeTitle.title);
|
||||||
|
}
|
||||||
|
else if (alternativeTitle.iso_3166_1.ToLower() == "us")
|
||||||
|
{
|
||||||
|
movie.AlternativeTitles.Add(alternativeTitle.title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
movie.TmdbId = TmdbId;
|
movie.TmdbId = TmdbId;
|
||||||
movie.ImdbId = resource.imdb_id;
|
movie.ImdbId = resource.imdb_id;
|
||||||
movie.Title = resource.title;
|
movie.Title = resource.title;
|
||||||
|
@ -106,10 +122,10 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
movie.Images.Add(_configService.GetCoverForURL(resource.backdrop_path, MediaCoverTypes.Banner));
|
movie.Images.Add(_configService.GetCoverForURL(resource.backdrop_path, MediaCoverTypes.Banner));
|
||||||
movie.Runtime = resource.runtime;
|
movie.Runtime = resource.runtime;
|
||||||
|
|
||||||
foreach(Title title in resource.alternative_titles.titles)
|
//foreach(Title title in resource.alternative_titles.titles)
|
||||||
{
|
//{
|
||||||
movie.AlternativeTitles.Add(title.title);
|
// movie.AlternativeTitles.Add(title.title);
|
||||||
}
|
//}
|
||||||
|
|
||||||
foreach(ReleaseDates releaseDates in resource.release_dates.results)
|
foreach(ReleaseDates releaseDates in resource.release_dates.results)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Movie Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Movie Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -24,75 +25,65 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link => "https://github.com/Sonarr/Sonarr/wiki/Custom-Post-Processing-Scripts";
|
public override string Link => "https://github.com/Radarr/Radarr/wiki/Custom-Post-Processing-Scripts";
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage message)
|
public override void OnGrab(GrabMessage message)
|
||||||
{
|
{
|
||||||
var series = message.Series;
|
var movie = message.Movie;
|
||||||
var remoteEpisode = message.Episode;
|
var remoteMovie = message.RemoteMovie;
|
||||||
var releaseGroup = remoteEpisode.ParsedEpisodeInfo.ReleaseGroup;
|
var releaseGroup = remoteMovie.ParsedMovieInfo.ReleaseGroup;
|
||||||
var environmentVariables = new StringDictionary();
|
var environmentVariables = new StringDictionary();
|
||||||
|
|
||||||
environmentVariables.Add("Sonarr_EventType", "Grab");
|
environmentVariables.Add("Radarr_EventType", "Grab");
|
||||||
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString());
|
environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
|
||||||
environmentVariables.Add("Sonarr_Series_Title", series.Title);
|
environmentVariables.Add("Radarr_Movie_Title", movie.Title);
|
||||||
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString());
|
environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId.ToString());
|
||||||
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString());
|
environmentVariables.Add("Radarr_Release_Title", remoteMovie.Release.Title);
|
||||||
environmentVariables.Add("Sonarr_Release_EpisodeCount", remoteEpisode.Episodes.Count.ToString());
|
environmentVariables.Add("Radarr_Release_Indexer", remoteMovie.Release.Indexer);
|
||||||
environmentVariables.Add("Sonarr_Release_SeasonNumber", remoteEpisode.ParsedEpisodeInfo.SeasonNumber.ToString());
|
environmentVariables.Add("Radarr_Release_Size", remoteMovie.Release.Size.ToString());
|
||||||
environmentVariables.Add("Sonarr_Release_EpisodeNumbers", string.Join(",", remoteEpisode.Episodes.Select(e => e.EpisodeNumber)));
|
environmentVariables.Add("Radarr_Release_ReleaseGroup", releaseGroup);
|
||||||
environmentVariables.Add("Sonarr_Release_Title", remoteEpisode.Release.Title);
|
|
||||||
environmentVariables.Add("Sonarr_Release_Indexer", remoteEpisode.Release.Indexer);
|
|
||||||
environmentVariables.Add("Sonarr_Release_Size", remoteEpisode.Release.Size.ToString());
|
|
||||||
environmentVariables.Add("Sonarr_Release_ReleaseGroup", releaseGroup);
|
|
||||||
|
|
||||||
ExecuteScript(environmentVariables);
|
ExecuteScript(environmentVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
var series = message.Series;
|
var movie = message.Movie;
|
||||||
var episodeFile = message.EpisodeFile;
|
var movieFile = message.MovieFile;
|
||||||
var sourcePath = message.SourcePath;
|
var sourcePath = message.SourcePath;
|
||||||
var environmentVariables = new StringDictionary();
|
var environmentVariables = new StringDictionary();
|
||||||
|
|
||||||
environmentVariables.Add("Sonarr_EventType", "Download");
|
environmentVariables.Add("Radarr_EventType", "Download");
|
||||||
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString());
|
environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
|
||||||
environmentVariables.Add("Sonarr_Series_Title", series.Title);
|
environmentVariables.Add("Radarr_Movie_Title", movie.Title);
|
||||||
environmentVariables.Add("Sonarr_Series_Path", series.Path);
|
environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId.ToString());
|
||||||
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString());
|
environmentVariables.Add("Radarr_MovieFile_Id", movieFile.Id.ToString());
|
||||||
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString());
|
environmentVariables.Add("Radarr_MovieFile_RelativePath", movieFile.RelativePath);
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_Id", episodeFile.Id.ToString());
|
environmentVariables.Add("Radarr_MovieFile_Path", Path.Combine(movie.Path, movieFile.RelativePath));
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeCount", episodeFile.Episodes.Value.Count.ToString());
|
environmentVariables.Add("Radarr_MovieFile_Quality", movieFile.Quality.Quality.Name);
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_RelativePath", episodeFile.RelativePath);
|
environmentVariables.Add("Radarr_MovieFile_QualityVersion", movieFile.Quality.Revision.Version.ToString());
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_Path", Path.Combine(series.Path, episodeFile.RelativePath));
|
environmentVariables.Add("Radarr_MovieFile_ReleaseGroup", movieFile.ReleaseGroup ?? string.Empty);
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_SeasonNumber", episodeFile.SeasonNumber.ToString());
|
environmentVariables.Add("Radarr_MovieFile_SceneName", movieFile.SceneName ?? string.Empty);
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeNumbers", string.Join(",", episodeFile.Episodes.Value.Select(e => e.EpisodeNumber)));
|
environmentVariables.Add("Radarr_MovieFile_SourcePath", sourcePath);
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeAirDates", string.Join(",", episodeFile.Episodes.Value.Select(e => e.AirDate)));
|
environmentVariables.Add("Radarr_MovieFile_SourceFolder", Path.GetDirectoryName(sourcePath));
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeAirDatesUtc", string.Join(",", episodeFile.Episodes.Value.Select(e => e.AirDateUtc)));
|
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeTitles", string.Join("|", episodeFile.Episodes.Value.Select(e => e.Title)));
|
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_Quality", episodeFile.Quality.Quality.Name);
|
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_QualityVersion", episodeFile.Quality.Revision.Version.ToString());
|
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_ReleaseGroup", episodeFile.ReleaseGroup ?? string.Empty);
|
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_SceneName", episodeFile.SceneName ?? string.Empty);
|
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_SourcePath", sourcePath);
|
|
||||||
environmentVariables.Add("Sonarr_EpisodeFile_SourceFolder", Path.GetDirectoryName(sourcePath));
|
|
||||||
|
|
||||||
ExecuteScript(environmentVariables);
|
ExecuteScript(environmentVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
var environmentVariables = new StringDictionary();
|
||||||
|
|
||||||
|
environmentVariables.Add("Radarr_EventType", "Rename");
|
||||||
|
environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
|
||||||
|
environmentVariables.Add("Radarr_Movie_Title", movie.Title);
|
||||||
|
environmentVariables.Add("Radarr_Movie_Path", movie.Path);
|
||||||
|
environmentVariables.Add("Radarr_Movie_TvdbId", movie.ImdbId.ToString());
|
||||||
|
ExecuteScript(environmentVariables);
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
var environmentVariables = new StringDictionary();
|
|
||||||
|
|
||||||
environmentVariables.Add("Sonarr_EventType", "Rename");
|
|
||||||
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString());
|
|
||||||
environmentVariables.Add("Sonarr_Series_Title", series.Title);
|
|
||||||
environmentVariables.Add("Sonarr_Series_Path", series.Path);
|
|
||||||
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString());
|
|
||||||
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString());
|
|
||||||
|
|
||||||
ExecuteScript(environmentVariables);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Custom Script";
|
public override string Name => "Custom Script";
|
||||||
|
|
|
@ -8,8 +8,11 @@ namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public Series Series { get; set; }
|
public Series Series { get; set; }
|
||||||
|
public Movie Movie { get; set; }
|
||||||
public EpisodeFile EpisodeFile { get; set; }
|
public EpisodeFile EpisodeFile { get; set; }
|
||||||
public List<EpisodeFile> OldFiles { get; set; }
|
public List<EpisodeFile> OldFiles { get; set; }
|
||||||
|
public MovieFile MovieFile { get; set; }
|
||||||
|
public List<MovieFile> OldMovieFiles { get; set; }
|
||||||
public string SourcePath { get; set; }
|
public string SourcePath { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string subject = "Radarr [TV] - Grabbed";
|
const string subject = "Radarr [Movie] - Grabbed";
|
||||||
var body = string.Format("{0} sent to queue.", grabMessage.Message);
|
var body = string.Format("{0} sent to queue.", grabMessage.Message);
|
||||||
|
|
||||||
_emailService.SendEmail(Settings, subject, body);
|
_emailService.SendEmail(Settings, subject, body);
|
||||||
|
@ -26,12 +26,16 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string subject = "Radarr [TV] - Downloaded";
|
const string subject = "Radarr [Movie] - Downloaded";
|
||||||
var body = string.Format("{0} Downloaded and sorted.", message.Message);
|
var body = string.Format("{0} Downloaded and sorted.", message.Message);
|
||||||
|
|
||||||
_emailService.SendEmail(Settings, subject, body);
|
_emailService.SendEmail(Settings, subject, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public Series Series { get; set; }
|
public Series Series { get; set; }
|
||||||
|
public Movie Movie { get; set; }
|
||||||
|
public RemoteMovie RemoteMovie { get; set; }
|
||||||
public RemoteEpisode Episode { get; set; }
|
public RemoteEpisode Episode { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Movie Grabbed";
|
||||||
|
|
||||||
_growlService.SendNotification(title, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
_growlService.SendNotification(title, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Movie Downloaded";
|
||||||
|
|
||||||
_growlService.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
_growlService.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
void OnGrab(GrabMessage grabMessage);
|
void OnGrab(GrabMessage grabMessage);
|
||||||
void OnDownload(DownloadMessage message);
|
void OnDownload(DownloadMessage message);
|
||||||
void OnRename(Series series);
|
void OnRename(Series series);
|
||||||
|
void OnMovieRename(Movie movie);
|
||||||
bool SupportsOnGrab { get; }
|
bool SupportsOnGrab { get; }
|
||||||
bool SupportsOnDownload { get; }
|
bool SupportsOnDownload { get; }
|
||||||
bool SupportsOnUpgrade { get; }
|
bool SupportsOnUpgrade { get; }
|
||||||
|
|
|
@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Join
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Radarr - Episode Grabbed";
|
const string title = "Radarr - Movie Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Radarr - Episode Downloaded";
|
const string title = "Radarr - Movie Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Notifications.Join
|
||||||
request.AddParameter("apikey", settings.ApiKey);
|
request.AddParameter("apikey", settings.ApiKey);
|
||||||
request.AddParameter("title", title);
|
request.AddParameter("title", title);
|
||||||
request.AddParameter("text", message);
|
request.AddParameter("text", message);
|
||||||
request.AddParameter("icon", "https://cdn.rawgit.com/Sonarr/Sonarr/develop/Logo/256.png"); // Use the Sonarr logo.
|
request.AddParameter("icon", "https://cdn.rawgit.com/Radarr/Radarr/develop/Logo/256.png"); // Use the Radarr logo.
|
||||||
|
|
||||||
var response = client.ExecuteAndValidate(request);
|
var response = client.ExecuteAndValidate(request);
|
||||||
var res = Json.Deserialize<JoinResponseModel>(response.Content);
|
var res = Json.Deserialize<JoinResponseModel>(response.Content);
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Radarr - Grabbed";
|
const string title = "Radarr - Movie Grabbed";
|
||||||
|
|
||||||
if (Settings.Notify)
|
if (Settings.Notify)
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Radarr - Downloaded";
|
const string title = "Radarr - Movie Downloaded";
|
||||||
|
|
||||||
if (Settings.Notify)
|
if (Settings.Notify)
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,10 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
if (Settings.UpdateLibrary)
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
public abstract void OnGrab(GrabMessage grabMessage);
|
public abstract void OnGrab(GrabMessage grabMessage);
|
||||||
public abstract void OnDownload(DownloadMessage message);
|
public abstract void OnDownload(DownloadMessage message);
|
||||||
public abstract void OnRename(Series series);
|
public abstract void OnRename(Series series);
|
||||||
|
public abstract void OnMovieRename(Movie movie);
|
||||||
|
|
||||||
public virtual bool SupportsOnGrab => true;
|
public virtual bool SupportsOnGrab => true;
|
||||||
public virtual bool SupportsOnDownload => true;
|
public virtual bool SupportsOnDownload => true;
|
||||||
|
|
|
@ -15,7 +15,11 @@ namespace NzbDrone.Core.Notifications
|
||||||
public class NotificationService
|
public class NotificationService
|
||||||
: IHandle<EpisodeGrabbedEvent>,
|
: IHandle<EpisodeGrabbedEvent>,
|
||||||
IHandle<EpisodeDownloadedEvent>,
|
IHandle<EpisodeDownloadedEvent>,
|
||||||
IHandle<SeriesRenamedEvent>
|
IHandle<SeriesRenamedEvent>,
|
||||||
|
IHandle<MovieRenamedEvent>,
|
||||||
|
IHandle<MovieGrabbedEvent>,
|
||||||
|
IHandle<MovieDownloadedEvent>
|
||||||
|
|
||||||
{
|
{
|
||||||
private readonly INotificationFactory _notificationFactory;
|
private readonly INotificationFactory _notificationFactory;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
@ -67,6 +71,41 @@ namespace NzbDrone.Core.Notifications
|
||||||
qualityString);
|
qualityString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetMessage(Movie movie, QualityModel quality)
|
||||||
|
{
|
||||||
|
var qualityString = quality.Quality.ToString();
|
||||||
|
|
||||||
|
if (quality.Revision.Version > 1)
|
||||||
|
{
|
||||||
|
qualityString += " Proper";
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Format("{0} [{1}]",
|
||||||
|
movie.Title,
|
||||||
|
qualityString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldHandleMovie(ProviderDefinition definition, Movie movie)
|
||||||
|
{
|
||||||
|
var notificationDefinition = (NotificationDefinition)definition;
|
||||||
|
|
||||||
|
if (notificationDefinition.Tags.Empty())
|
||||||
|
{
|
||||||
|
_logger.Debug("No tags set for this notification.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notificationDefinition.Tags.Intersect(movie.Tags).Any())
|
||||||
|
{
|
||||||
|
_logger.Debug("Notification and series have one or more matching tags.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: this message could be more clear
|
||||||
|
_logger.Debug("{0} does not have any tags that match {1}'s tags", notificationDefinition.Name, movie.Title);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private bool ShouldHandleSeries(ProviderDefinition definition, Series series)
|
private bool ShouldHandleSeries(ProviderDefinition definition, Series series)
|
||||||
{
|
{
|
||||||
var notificationDefinition = (NotificationDefinition) definition;
|
var notificationDefinition = (NotificationDefinition) definition;
|
||||||
|
@ -112,6 +151,33 @@ namespace NzbDrone.Core.Notifications
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieGrabbedEvent message)
|
||||||
|
{
|
||||||
|
var grabMessage = new GrabMessage
|
||||||
|
{
|
||||||
|
Message = GetMessage(message.Movie.Movie, message.Movie.ParsedMovieInfo.Quality),
|
||||||
|
Series = null,
|
||||||
|
Quality = message.Movie.ParsedMovieInfo.Quality,
|
||||||
|
Episode = null,
|
||||||
|
Movie = message.Movie.Movie,
|
||||||
|
RemoteMovie = message.Movie
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var notification in _notificationFactory.OnGrabEnabled())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!ShouldHandleMovie(notification.Definition, message.Movie.Movie)) continue;
|
||||||
|
notification.OnGrab(grabMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Unable to send OnGrab notification to: " + notification.Definition.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeDownloadedEvent message)
|
public void Handle(EpisodeDownloadedEvent message)
|
||||||
{
|
{
|
||||||
var downloadMessage = new DownloadMessage();
|
var downloadMessage = new DownloadMessage();
|
||||||
|
@ -141,6 +207,38 @@ namespace NzbDrone.Core.Notifications
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieDownloadedEvent message)
|
||||||
|
{
|
||||||
|
var downloadMessage = new DownloadMessage();
|
||||||
|
downloadMessage.Message = GetMessage(message.Movie.Movie, message.Movie.Quality);
|
||||||
|
downloadMessage.Series = null;
|
||||||
|
downloadMessage.EpisodeFile = null;
|
||||||
|
downloadMessage.MovieFile = message.MovieFile;
|
||||||
|
downloadMessage.Movie = message.Movie.Movie;
|
||||||
|
downloadMessage.OldFiles = null;
|
||||||
|
downloadMessage.OldMovieFiles = message.OldFiles;
|
||||||
|
downloadMessage.SourcePath = message.Movie.Path;
|
||||||
|
|
||||||
|
foreach (var notification in _notificationFactory.OnDownloadEnabled())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ShouldHandleMovie(notification.Definition, message.Movie.Movie))
|
||||||
|
{
|
||||||
|
if (downloadMessage.OldMovieFiles.Empty() || ((NotificationDefinition)notification.Definition).OnUpgrade)
|
||||||
|
{
|
||||||
|
notification.OnDownload(downloadMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Unable to send OnDownload notification to: " + notification.Definition.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(SeriesRenamedEvent message)
|
public void Handle(SeriesRenamedEvent message)
|
||||||
{
|
{
|
||||||
foreach (var notification in _notificationFactory.OnRenameEnabled())
|
foreach (var notification in _notificationFactory.OnRenameEnabled())
|
||||||
|
@ -159,5 +257,24 @@ namespace NzbDrone.Core.Notifications
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieRenamedEvent message)
|
||||||
|
{
|
||||||
|
foreach (var notification in _notificationFactory.OnRenameEnabled())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ShouldHandleMovie(notification.Definition, message.Movie))
|
||||||
|
{
|
||||||
|
notification.OnMovieRename(message.Movie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Unable to send OnRename notification to: " + notification.Definition.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,18 +19,22 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Movie Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
_proxy.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Movie Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
_proxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
_plexClientService.Notify(Settings, header, message.Message);
|
_plexClientService.Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,10 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
Notify(Settings, header, message.Message);
|
Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -22,19 +22,24 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
UpdateIfEnabled(message.Series);
|
UpdateIfEnabled(message.Movie);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
UpdateIfEnabled(movie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
UpdateIfEnabled(series);
|
//UpdateIfEnabled(movie);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateIfEnabled(Series series)
|
private void UpdateIfEnabled(Movie movie)
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
if (Settings.UpdateLibrary)
|
||||||
{
|
{
|
||||||
_plexServerService.UpdateLibrary(series, Settings);
|
_plexServerService.UpdateMovieSections(movie, Settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
public interface IPlexServerProxy
|
public interface IPlexServerProxy
|
||||||
{
|
{
|
||||||
List<PlexSection> GetTvSections(PlexServerSettings settings);
|
List<PlexSection> GetTvSections(PlexServerSettings settings);
|
||||||
|
List<PlexSection> GetMovieSections(PlexServerSettings settings);
|
||||||
void Update(int sectionId, PlexServerSettings settings);
|
void Update(int sectionId, PlexServerSettings settings);
|
||||||
void UpdateSeries(int metadataId, PlexServerSettings settings);
|
void UpdateSeries(int metadataId, PlexServerSettings settings);
|
||||||
string Version(PlexServerSettings settings);
|
string Version(PlexServerSettings settings);
|
||||||
|
@ -66,6 +67,37 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<PlexSection> GetMovieSections(PlexServerSettings settings)
|
||||||
|
{
|
||||||
|
var request = GetPlexServerRequest("library/sections", Method.GET, settings);
|
||||||
|
var client = GetPlexServerClient(settings);
|
||||||
|
var response = client.Execute(request);
|
||||||
|
|
||||||
|
_logger.Trace("Sections response: {0}", response.Content);
|
||||||
|
CheckForError(response, settings);
|
||||||
|
|
||||||
|
if (response.Content.Contains("_children"))
|
||||||
|
{
|
||||||
|
return Json.Deserialize<PlexMediaContainerLegacy>(response.Content)
|
||||||
|
.Sections
|
||||||
|
.Where(d => d.Type == "movie")
|
||||||
|
.Select(s => new PlexSection
|
||||||
|
{
|
||||||
|
Id = s.Id,
|
||||||
|
Language = s.Language,
|
||||||
|
Locations = s.Locations,
|
||||||
|
Type = s.Type
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Json.Deserialize<PlexResponse<PlexSectionsContainer>>(response.Content)
|
||||||
|
.MediaContainer
|
||||||
|
.Sections
|
||||||
|
.Where(d => d.Type == "movie")
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public void Update(int sectionId, PlexServerSettings settings)
|
public void Update(int sectionId, PlexServerSettings settings)
|
||||||
{
|
{
|
||||||
var resource = string.Format("library/sections/{0}/refresh", sectionId);
|
var resource = string.Format("library/sections/{0}/refresh", sectionId);
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
public interface IPlexServerService
|
public interface IPlexServerService
|
||||||
{
|
{
|
||||||
void UpdateLibrary(Series series, PlexServerSettings settings);
|
void UpdateLibrary(Series series, PlexServerSettings settings);
|
||||||
|
void UpdateMovieSections(Movie movie, PlexServerSettings settings);
|
||||||
ValidationFailure Test(PlexServerSettings settings);
|
ValidationFailure Test(PlexServerSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +63,43 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateMovieSections(Movie movie, PlexServerSettings settings)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.Debug("Sending Update Request to Plex Server");
|
||||||
|
|
||||||
|
var version = _versionCache.Get(settings.Host, () => GetVersion(settings), TimeSpan.FromHours(2));
|
||||||
|
ValidateVersion(version);
|
||||||
|
|
||||||
|
var sections = GetSections(settings);
|
||||||
|
var partialUpdates = _partialUpdateCache.Get(settings.Host, () => PartialUpdatesAllowed(settings, version), TimeSpan.FromHours(2));
|
||||||
|
|
||||||
|
// TODO: Investiate partial updates later, for now just update all movie sections...
|
||||||
|
|
||||||
|
//if (partialUpdates)
|
||||||
|
//{
|
||||||
|
// UpdatePartialSection(series, sections, settings);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
sections.ForEach(s => UpdateSection(s.Id, settings));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Failed to Update Plex host: " + settings.Host);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<PlexSection> GetSections(PlexServerSettings settings)
|
private List<PlexSection> GetSections(PlexServerSettings settings)
|
||||||
{
|
{
|
||||||
_logger.Debug("Getting sections from Plex host: {0}", settings.Host);
|
_logger.Debug("Getting sections from Plex host: {0}", settings.Host);
|
||||||
|
|
||||||
return _plexServerProxy.GetTvSections(settings).ToList();
|
return _plexServerProxy.GetMovieSections(settings).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool PartialUpdatesAllowed(PlexServerSettings settings, Version version)
|
private bool PartialUpdatesAllowed(PlexServerSettings settings, Version version)
|
||||||
|
|
|
@ -19,18 +19,22 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Movie Grabbed";
|
||||||
|
|
||||||
_prowlService.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_prowlService.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Movie Downloaded";
|
||||||
|
|
||||||
_prowlService.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_prowlService.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Radarr - Episode Grabbed";
|
const string title = "Radarr - Movie Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Radarr - Episode Downloaded";
|
const string title = "Radarr - Movie Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Pushalot
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Movie Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Movie Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Movie Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Movie Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
new Attachment
|
new Attachment
|
||||||
{
|
{
|
||||||
Fallback = message.Message,
|
Fallback = message.Message,
|
||||||
Title = message.Series.Title,
|
Title = message.Movie.Title,
|
||||||
Text = message.Message,
|
Text = message.Message,
|
||||||
Color = "warning"
|
Color = "warning"
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
new Attachment
|
new Attachment
|
||||||
{
|
{
|
||||||
Fallback = message.Message,
|
Fallback = message.Message,
|
||||||
Title = message.Series.Title,
|
Title = message.Movie.Title,
|
||||||
Text = message.Message,
|
Text = message.Message,
|
||||||
Color = "good"
|
Color = "good"
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,25 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
NotifySlack(payload);
|
NotifySlack(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
var payload = new SlackPayload
|
||||||
|
{
|
||||||
|
IconEmoji = Settings.Icon,
|
||||||
|
Username = Settings.Username,
|
||||||
|
Text = "Renamed",
|
||||||
|
Attachments = new List<Attachment>
|
||||||
|
{
|
||||||
|
new Attachment
|
||||||
|
{
|
||||||
|
Title = movie.Title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NotifySlack(payload);
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
var payload = new SlackPayload
|
var payload = new SlackPayload
|
||||||
|
|
|
@ -42,6 +42,10 @@ namespace NzbDrone.Core.Notifications.Synology
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
if (Settings.UpdateLibrary)
|
||||||
|
|
|
@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
public override void OnGrab(GrabMessage grabMessage)
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Movie Grabbed";
|
||||||
|
|
||||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Movie Downloaded";
|
||||||
|
|
||||||
_proxy.SendNotification(title, message.Message, Settings);
|
_proxy.SendNotification(title, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,10 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||||
_twitterService.SendNotification($"Imported: {message.Message}", Settings);
|
_twitterService.SendNotification($"Imported: {message.Message}", Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,10 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||||
_service.OnDownload(message.Series, message.EpisodeFile, Settings);
|
_service.OnDownload(message.Series, message.EpisodeFile, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
_service.OnRename(series, Settings);
|
_service.OnRename(series, Settings);
|
||||||
|
|
|
@ -36,6 +36,10 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
UpdateAndClean(message.Series, message.OldFiles.Any());
|
UpdateAndClean(message.Series, message.OldFiles.Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnMovieRename(Movie movie)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnRename(Series series)
|
public override void OnRename(Series series)
|
||||||
{
|
{
|
||||||
UpdateAndClean(series);
|
UpdateAndClean(series);
|
||||||
|
|
|
@ -583,6 +583,7 @@
|
||||||
<Compile Include="Http\HttpProxySettingsProvider.cs" />
|
<Compile Include="Http\HttpProxySettingsProvider.cs" />
|
||||||
<Compile Include="Http\TorcacheHttpInterceptor.cs" />
|
<Compile Include="Http\TorcacheHttpInterceptor.cs" />
|
||||||
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
|
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
|
||||||
|
<Compile Include="IndexerSearch\MissingMoviesSearchCommand.cs" />
|
||||||
<Compile Include="IndexerSearch\MoviesSearchCommand.cs" />
|
<Compile Include="IndexerSearch\MoviesSearchCommand.cs" />
|
||||||
<Compile Include="IndexerSearch\MoviesSearchService.cs" />
|
<Compile Include="IndexerSearch\MoviesSearchService.cs" />
|
||||||
<Compile Include="Indexers\AwesomeHD\AwesomeHDRssParser.cs" />
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDRssParser.cs" />
|
||||||
|
|
|
@ -125,7 +125,8 @@ namespace NzbDrone.Core.Organizer
|
||||||
RelativePath = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE.mkv",
|
RelativePath = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE.mkv",
|
||||||
SceneName = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE",
|
SceneName = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE",
|
||||||
ReleaseGroup = "RlsGrp",
|
ReleaseGroup = "RlsGrp",
|
||||||
MediaInfo = mediaInfo
|
MediaInfo = mediaInfo,
|
||||||
|
Edition = "Ultimate extended edition",
|
||||||
};
|
};
|
||||||
|
|
||||||
_singleEpisodeFile = new EpisodeFile
|
_singleEpisodeFile = new EpisodeFile
|
||||||
|
|
|
@ -12,5 +12,6 @@
|
||||||
ThreeLetterCode = threeLetterCode;
|
ThreeLetterCode = threeLetterCode;
|
||||||
Language = language;
|
Language = language;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,20 +18,20 @@ namespace NzbDrone.Core.Parser
|
||||||
private static readonly Regex[] ReportMovieTitleRegex = new[]
|
private static readonly Regex[] ReportMovieTitleRegex = new[]
|
||||||
{
|
{
|
||||||
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.Special.Edition.2011
|
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.Special.Edition.2011
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\.?((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX)))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\.?((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX)))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition //TODO: Seems to slow down parsing heavily!
|
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition //TODO: Seems to slow down parsing heavily!
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX))",
|
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX))",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Normal movie format, e.g: Mission.Impossible.3.2011
|
//Normal movie format, e.g: Mission.Impossible.3.2011
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
//PassThePopcorn Torrent names: Star.Wars[PassThePopcorn]
|
//PassThePopcorn Torrent names: Star.Wars[PassThePopcorn]
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
//That did not work? Maybe some tool uses [] for years. Who would do that?
|
//That did not work? Maybe some tool uses [] for years. Who would do that?
|
||||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?!\\)",
|
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
|
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|2160[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
|
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
|
||||||
|
@ -696,6 +696,12 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection)
|
private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection)
|
||||||
{
|
{
|
||||||
|
if (!matchCollection[0].Groups["title"].Success)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
||||||
seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' ');
|
seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' ');
|
||||||
|
|
||||||
|
|
|
@ -396,9 +396,15 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
if (searchCriteria == null)
|
if (searchCriteria == null)
|
||||||
{
|
{
|
||||||
|
if (parsedEpisodeInfo.Year > 1900)
|
||||||
|
{
|
||||||
|
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle, parsedEpisodeInfo.Year);
|
||||||
|
//Todo: same as above!
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above!
|
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above!
|
||||||
|
}
|
||||||
return movie;
|
return movie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ using NzbDrone.Core.IndexerSearch;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Tv
|
namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,7 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
if (movie.AddOptions.SearchForMovie)
|
if (movie.AddOptions.SearchForMovie)
|
||||||
{
|
{
|
||||||
_commandQueueManager.Push(new MoviesSearchCommand { MovieId = movie.Id});
|
_commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List<int> { movie.Id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
movie.AddOptions = null;
|
movie.AddOptions = null;
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
movieInfo = _movieInfo.GetMovieInfo(movie.TmdbId);
|
movieInfo = _movieInfo.GetMovieInfo(movie.TmdbId, movie.Profile);
|
||||||
}
|
}
|
||||||
catch (MovieNotFoundException)
|
catch (MovieNotFoundException)
|
||||||
{
|
{
|
||||||
|
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 81 KiB |
BIN
src/Radarr.ico
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 81 KiB |
|
@ -1,7 +1,7 @@
|
||||||
var Marionette = require('marionette');
|
var Marionette = require('marionette');
|
||||||
var Backgrid = require('backgrid');
|
var Backgrid = require('backgrid');
|
||||||
var QueueCollection = require('./QueueCollection');
|
var QueueCollection = require('./QueueCollection');
|
||||||
var SeriesTitleCell = require('../../Cells/MovieTitleCell');
|
var MovieTitleCell = require('../../Cells/MovieTitleCell');
|
||||||
var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
|
var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
|
||||||
var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
|
var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
|
||||||
var QualityCell = require('../../Cells/QualityCell');
|
var QualityCell = require('../../Cells/QualityCell');
|
||||||
|
@ -30,7 +30,7 @@ module.exports = Marionette.Layout.extend({
|
||||||
{
|
{
|
||||||
name : 'movie',
|
name : 'movie',
|
||||||
label : 'Movie',
|
label : 'Movie',
|
||||||
cell : SeriesTitleCell
|
cell : MovieTitleCell
|
||||||
},
|
},
|
||||||
/*{
|
/*{
|
||||||
name : 'episode',
|
name : 'episode',
|
||||||
|
|
|
@ -6,9 +6,7 @@ module.exports = TemplatedCell.extend({
|
||||||
|
|
||||||
|
|
||||||
render : function() {
|
render : function() {
|
||||||
this.$el.html(this.model.get("movie").get("title")); //Hack, but somehow handlebar helper does not work.
|
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.
|
||||||
debugger;
|
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,23 +2,26 @@ var $ = require('jquery');
|
||||||
var vent = require('./vent');
|
var vent = require('./vent');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
ConfigNamespace : 'Radarr.',
|
||||||
|
|
||||||
Events : {
|
Events : {
|
||||||
ConfigUpdatedEvent : 'ConfigUpdatedEvent'
|
ConfigUpdatedEvent : 'ConfigUpdatedEvent'
|
||||||
},
|
},
|
||||||
|
|
||||||
Keys : {
|
Keys : {
|
||||||
DefaultProfileId : 'DefaultProfileId',
|
DefaultProfileId : 'RadarrDefaultProfileId',
|
||||||
DefaultRootFolderId : 'DefaultRootFolderId',
|
DefaultRootFolderId : 'RadarrDefaultRootFolderId',
|
||||||
UseSeasonFolder : 'UseSeasonFolder',
|
UseSeasonFolder : 'RadarrUseSeasonFolder',
|
||||||
DefaultSeriesType : 'DefaultSeriesType',
|
DefaultSeriesType : 'RadarrDefaultSeriesType',
|
||||||
MonitorEpisodes : 'MonitorEpisodes',
|
MonitorEpisodes : 'RadarrMonitorEpisodes',
|
||||||
AdvancedSettings : 'advancedSettings'
|
AdvancedSettings : 'RadarradvancedSettings'
|
||||||
},
|
},
|
||||||
|
|
||||||
getValueJson : function (key, defaultValue) {
|
getValueJson : function (key, defaultValue) {
|
||||||
|
var storeKey = this.ConfigNamespace + key;
|
||||||
defaultValue = defaultValue || {};
|
defaultValue = defaultValue || {};
|
||||||
|
|
||||||
var storeValue = window.localStorage.getItem(key);
|
var storeValue = window.localStorage.getItem(storeKey);
|
||||||
|
|
||||||
if (!storeValue) {
|
if (!storeValue) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
@ -34,7 +37,8 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getValue : function(key, defaultValue) {
|
getValue : function(key, defaultValue) {
|
||||||
var storeValue = window.localStorage.getItem(key);
|
var storeKey = this.ConfigNamespace + key;
|
||||||
|
var storeValue = window.localStorage.getItem(storeKey);
|
||||||
|
|
||||||
if (!storeValue) {
|
if (!storeValue) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
@ -48,22 +52,22 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
setValue : function(key, value) {
|
setValue : function(key, value) {
|
||||||
|
var storeKey = this.ConfigNamespace + key;
|
||||||
console.log('Config: [{0}] => [{1}]'.format(key, value));
|
console.log('Config: [{0}] => [{1}]'.format(storeKey, value));
|
||||||
|
|
||||||
if (this.getValue(key) === value.toString()) {
|
if (this.getValue(key) === value.toString()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
window.localStorage.setItem(key, value);
|
window.localStorage.setItem(storeKey, value);
|
||||||
vent.trigger(this.Events.ConfigUpdatedEvent, {
|
vent.trigger(this.Events.ConfigUpdatedEvent, {
|
||||||
key : key,
|
key : key,
|
||||||
value : value
|
value : value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('Unable to save config: [{0}] => [{1}]'.format(key, value));
|
console.error('Unable to save config: [{0}] => [{1}]'.format(storeKey, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-144x144.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-256x256.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-36x36.png
Normal file
After Width: | Height: | Size: 862 B |
BIN
src/UI/Content/Images/favicon/android-chrome-384x384.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-48x48.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-72x72.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
src/UI/Content/Images/favicon/android-chrome-96x96.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2 KiB |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-114x114.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.2 KiB |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-120x120.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.7 KiB |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-144x144.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.7 KiB |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-152x152.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 3.1 KiB |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-180x180.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 1,018 B |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-57x57.png
Normal file
After Width: | Height: | Size: 890 B |
After Width: | Height: | Size: 1.1 KiB |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-60x60.png
Normal file
After Width: | Height: | Size: 971 B |
After Width: | Height: | Size: 1.3 KiB |
BIN
src/UI/Content/Images/favicon/apple-touch-icon-72x72.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |