mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-10 15:10:57 -04:00
Compare commits
1 Commits
0.05
...
v2.0.0.447
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a34e69b35b |
@@ -1,7 +1,7 @@
|
||||
# Sonarr #
|
||||
|
||||
This fork of Sonarr aims to turn it into something like Couchpotato.
|
||||
At the moment almost nothing is implemented.
|
||||
|
||||
Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.
|
||||
|
||||
## Major Features Include: ##
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using FluentValidation.Results;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Notifications;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.NotificationTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class NotificationBaseFixture : TestBase
|
||||
{
|
||||
class TestSetting : IProviderConfig
|
||||
{
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult();
|
||||
}
|
||||
}
|
||||
|
||||
class TestNotificationWithOnDownload : NotificationBase<TestSetting>
|
||||
{
|
||||
public override string Name => "TestNotification";
|
||||
public override string Link => "";
|
||||
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage downloadMessage)
|
||||
{
|
||||
TestLogger.Info("OnDownload was called");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestNotificationWithAllEvents : NotificationBase<TestSetting>
|
||||
{
|
||||
public override string Name => "TestNotification";
|
||||
public override string Link => "";
|
||||
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
TestLogger.Info("OnGrab was called");
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
TestLogger.Info("OnDownload was called");
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
TestLogger.Info("OnRename was called");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestNotificationWithNoEvents : NotificationBase<TestSetting>
|
||||
{
|
||||
public override string Name => "TestNotification";
|
||||
public override string Link => "";
|
||||
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_support_OnUpgrade_should_link_to_OnDownload()
|
||||
{
|
||||
var notification = new TestNotificationWithOnDownload();
|
||||
|
||||
notification.SupportsOnDownload.Should().BeTrue();
|
||||
notification.SupportsOnUpgrade.Should().BeTrue();
|
||||
|
||||
notification.SupportsOnGrab.Should().BeFalse();
|
||||
notification.SupportsOnRename.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_support_all_if_implemented()
|
||||
{
|
||||
var notification = new TestNotificationWithAllEvents();
|
||||
|
||||
notification.SupportsOnGrab.Should().BeTrue();
|
||||
notification.SupportsOnDownload.Should().BeTrue();
|
||||
notification.SupportsOnUpgrade.Should().BeTrue();
|
||||
notification.SupportsOnRename.Should().BeTrue();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_support_none_if_none_are_implemented()
|
||||
{
|
||||
var notification = new TestNotificationWithNoEvents();
|
||||
|
||||
notification.SupportsOnGrab.Should().BeFalse();
|
||||
notification.SupportsOnDownload.Should().BeFalse();
|
||||
notification.SupportsOnUpgrade.Should().BeFalse();
|
||||
notification.SupportsOnRename.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -288,6 +288,7 @@
|
||||
<Compile Include="MetadataSource\SkyHook\SkyHookProxySearchFixture.cs" />
|
||||
<Compile Include="MetadataSource\SearchSeriesComparerFixture.cs" />
|
||||
<Compile Include="MetadataSource\SkyHook\SkyHookProxyFixture.cs" />
|
||||
<Compile Include="NotificationTests\NotificationBaseFixture.cs" />
|
||||
<Compile Include="NotificationTests\SynologyIndexerFixture.cs" />
|
||||
<Compile Include="OrganizerTests\FileNameBuilderTests\CleanTitleFixture.cs" />
|
||||
<Compile Include="OrganizerTests\FileNameBuilderTests\EpisodeTitleCollapseFixture.cs" />
|
||||
|
||||
@@ -80,9 +80,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
|
||||
if (remoteEpisode.Series == null)
|
||||
{
|
||||
//remoteEpisode.DownloadAllowed = true; //Fuck you :)
|
||||
//decision = GetDecisionForReport(remoteEpisode, searchCriteria);
|
||||
decision = new DownloadDecision(remoteEpisode, new Rejection("Unknown release. Movie not Found."));
|
||||
decision = new DownloadDecision(remoteEpisode, new Rejection("Unknown Series"));
|
||||
}
|
||||
else if (remoteEpisode.Episodes.Empty())
|
||||
{
|
||||
@@ -145,9 +143,8 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
e.Data.Add("report", remoteEpisode.Release.ToJson());
|
||||
e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson());
|
||||
_logger.Error(e, "Couldn't evaluate decision on " + remoteEpisode.Release.Title + ", with spec: " + spec.GetType().Name);
|
||||
//return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));//TODO UPDATE SPECS!
|
||||
//return null;
|
||||
_logger.Error(e, "Couldn't evaluate decision on " + remoteEpisode.Release.Title);
|
||||
return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
if (subject.Episodes.Any(e => !e.AirDateUtc.HasValue || e.AirDateUtc.Value.After(DateTime.UtcNow)))
|
||||
{
|
||||
_logger.Debug("Full season release {0} rejected. All episodes haven't aired yet.", subject.Release.Title);
|
||||
//return Decision.Reject("Full season release rejected. All episodes haven't aired yet.");
|
||||
return Decision.Reject("Full season release rejected. All episodes haven't aired yet.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
|
||||
if (singleEpisodeSpec.SeasonNumber != remoteEpisode.ParsedEpisodeInfo.SeasonNumber)
|
||||
{
|
||||
_logger.Debug("Season number does not match searched season number, skipping.");
|
||||
//return Decision.Reject("Wrong season");
|
||||
//Unnecessary for Movies
|
||||
return Decision.Reject("Wrong season");
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
|
||||
@@ -29,19 +29,19 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
|
||||
if (singleEpisodeSpec.SeasonNumber != remoteEpisode.ParsedEpisodeInfo.SeasonNumber)
|
||||
{
|
||||
_logger.Debug("Season number does not match searched season number, skipping.");
|
||||
//return Decision.Reject("Wrong season");
|
||||
return Decision.Reject("Wrong season");
|
||||
}
|
||||
|
||||
if (!remoteEpisode.ParsedEpisodeInfo.EpisodeNumbers.Any())
|
||||
{
|
||||
_logger.Debug("Full season result during single episode search, skipping.");
|
||||
//return Decision.Reject("Full season pack");
|
||||
return Decision.Reject("Full season pack");
|
||||
}
|
||||
|
||||
if (!remoteEpisode.ParsedEpisodeInfo.EpisodeNumbers.Contains(singleEpisodeSpec.EpisodeNumber))
|
||||
{
|
||||
_logger.Debug("Episode number does not match searched episode number, skipping.");
|
||||
//return Decision.Reject("Wrong episode");
|
||||
return Decision.Reject("Wrong episode");
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
|
||||
@@ -88,13 +88,12 @@ namespace NzbDrone.Core.Indexers.Rarbg
|
||||
|
||||
if (tvdbId.HasValue)
|
||||
{
|
||||
string imdbId = string.Format("tt{0:D7}", tvdbId);
|
||||
requestBuilder.AddQueryParam("search_imdb", imdbId);
|
||||
requestBuilder.AddQueryParam("search_tvdb", tvdbId.Value);
|
||||
}
|
||||
|
||||
if (query.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
//requestBuilder.AddQueryParam("search_string", string.Format(query, args));
|
||||
requestBuilder.AddQueryParam("search_string", string.Format(query, args));
|
||||
}
|
||||
|
||||
if (!Settings.RankedOnly)
|
||||
@@ -102,7 +101,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
|
||||
requestBuilder.AddQueryParam("ranked", "0");
|
||||
}
|
||||
|
||||
requestBuilder.AddQueryParam("category", "movies");
|
||||
requestBuilder.AddQueryParam("category", "18;41");
|
||||
requestBuilder.AddQueryParam("limit", "100");
|
||||
requestBuilder.AddQueryParam("token", _tokenProvider.GetToken(Settings));
|
||||
requestBuilder.AddQueryParam("format", "json_extended");
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
|
||||
{
|
||||
if (localEpisode.ParsedEpisodeInfo.FullSeason)
|
||||
{
|
||||
//_logger.Debug("Single episode file detected as containing all episodes in the season"); //Not needed for Movies mwhahahahah
|
||||
//return Decision.Reject("Single episode file contains all episodes in seasons");
|
||||
_logger.Debug("Single episode file detected as containing all episodes in the season");
|
||||
return Decision.Reject("Single episode file contains all episodes in seasons");
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
|
||||
@@ -10,7 +10,6 @@ using NzbDrone.Core.Exceptions;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||
using NzbDrone.Core.Tv;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
{
|
||||
@@ -38,11 +37,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
httpRequest.AllowAutoRedirect = true;
|
||||
httpRequest.SuppressHttpError = true;
|
||||
|
||||
string imdbId = string.Format("tt{0:D7}", tvdbSeriesId);
|
||||
|
||||
var imdbRequest = new HttpRequest("http://www.omdbapi.com/?i="+ imdbId + "&plot=full&r=json");
|
||||
|
||||
var httpResponse = _httpClient.Get(imdbRequest);
|
||||
var httpResponse = _httpClient.Get<ShowResource>(httpRequest);
|
||||
|
||||
if (httpResponse.HasHttpError)
|
||||
{
|
||||
@@ -56,47 +51,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
}
|
||||
}
|
||||
|
||||
var response = httpResponse.Content;
|
||||
|
||||
dynamic json = JsonConvert.DeserializeObject(response);
|
||||
|
||||
var series = new Series();
|
||||
|
||||
series.Title = json.Title;
|
||||
series.TitleSlug = series.Title.ToLower().Replace(" ", "-");
|
||||
series.Overview = json.Plot;
|
||||
series.CleanTitle = Parser.Parser.CleanSeriesTitle(series.Title);
|
||||
series.TvdbId = tvdbSeriesId;
|
||||
string airDateStr = json.Released;
|
||||
DateTime airDate = DateTime.Parse(airDateStr);
|
||||
series.FirstAired = airDate;
|
||||
series.Year = airDate.Year;
|
||||
series.ImdbId = imdbId;
|
||||
series.Images = new List<MediaCover.MediaCover>();
|
||||
string url = json.Poster;
|
||||
var imdbPoster = new MediaCover.MediaCover(MediaCoverTypes.Poster, url);
|
||||
series.Images.Add(imdbPoster);
|
||||
string runtime = json.Runtime;
|
||||
int runtimeNum = 0;
|
||||
int.TryParse(runtime.Replace("min", "").Trim(), out runtimeNum);
|
||||
series.Runtime = runtimeNum;
|
||||
|
||||
var season = new Season();
|
||||
season.SeasonNumber = 1;
|
||||
season.Monitored = true;
|
||||
series.Seasons.Add(season);
|
||||
|
||||
|
||||
var episode = new Episode();
|
||||
|
||||
episode.AirDate = airDate.ToBestDateString();
|
||||
episode.Title = json.Title;
|
||||
episode.SeasonNumber = 1;
|
||||
episode.EpisodeNumber = 1;
|
||||
episode.Overview = series.Overview;
|
||||
episode.AirDate = airDate.ToShortDateString();
|
||||
|
||||
var episodes = new List<Episode> { episode };
|
||||
var episodes = httpResponse.Resource.Episodes.Select(MapEpisode);
|
||||
var series = MapSeries(httpResponse.Resource);
|
||||
|
||||
return new Tuple<Series, List<Episode>>(series, episodes.ToList());
|
||||
}
|
||||
@@ -133,66 +89,6 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
.AddQueryParam("term", title.ToLower().Trim())
|
||||
.Build();
|
||||
|
||||
var searchTerm = lowerTitle.Replace("+", "_").Replace(" ", "_");
|
||||
|
||||
var firstChar = searchTerm.First();
|
||||
|
||||
var imdbRequest = new HttpRequest("https://v2.sg.media-imdb.com/suggests/"+firstChar+"/" + searchTerm + ".json");
|
||||
|
||||
var response = _httpClient.Get(imdbRequest);
|
||||
|
||||
var imdbCallback = "imdb$" + searchTerm + "(";
|
||||
|
||||
var responseCleaned = response.Content.Replace(imdbCallback, "").TrimEnd(")");
|
||||
|
||||
dynamic json = JsonConvert.DeserializeObject(responseCleaned);
|
||||
|
||||
var imdbMovies = new List<Series>();
|
||||
|
||||
foreach (dynamic entry in json.d)
|
||||
{
|
||||
var imdbMovie = new Series();
|
||||
imdbMovie.ImdbId = entry.id;
|
||||
string noTT = imdbMovie.ImdbId.Replace("tt", "");
|
||||
try
|
||||
{
|
||||
imdbMovie.TvdbId = (int)Double.Parse(noTT);
|
||||
}
|
||||
catch
|
||||
{
|
||||
imdbMovie.TvdbId = 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
imdbMovie.SortTitle = entry.l;
|
||||
imdbMovie.Title = entry.l;
|
||||
string titleSlug = entry.l;
|
||||
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
||||
imdbMovie.Year = entry.y;
|
||||
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
||||
try
|
||||
{
|
||||
string url = entry.i[0];
|
||||
var imdbPoster = new MediaCover.MediaCover(MediaCoverTypes.Poster, url);
|
||||
imdbMovie.Images.Add(imdbPoster);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Debug(entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
imdbMovies.Add(imdbMovie);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return imdbMovies;
|
||||
|
||||
var httpResponse = _httpClient.Get<List<ShowResource>>(httpRequest);
|
||||
|
||||
return httpResponse.Resource.SelectList(MapSeries);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Boxcar
|
||||
{
|
||||
@@ -15,29 +14,18 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||
}
|
||||
|
||||
public override string Link => "https://boxcar.io/client";
|
||||
public override string Name => "Boxcar";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_GRABBED_TITLE, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE , message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Boxcar";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override string Name => "Custom Script";
|
||||
|
||||
public override string Link => "https://github.com/Sonarr/Sonarr/wiki/Custom-Post-Processing-Scripts";
|
||||
|
||||
public override void OnGrab(GrabMessage message)
|
||||
@@ -95,7 +97,6 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override string Name => "Custom Script";
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
||||
@@ -9,6 +9,9 @@ namespace NzbDrone.Core.Notifications.Email
|
||||
{
|
||||
private readonly IEmailService _emailService;
|
||||
|
||||
public override string Name => "Email";
|
||||
|
||||
|
||||
public Email(IEmailService emailService)
|
||||
{
|
||||
_emailService = emailService;
|
||||
@@ -18,27 +21,18 @@ namespace NzbDrone.Core.Notifications.Email
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string subject = "Sonarr [TV] - Grabbed";
|
||||
var body = string.Format("{0} sent to queue.", grabMessage.Message);
|
||||
var body = $"{grabMessage.Message} sent to queue.";
|
||||
|
||||
_emailService.SendEmail(Settings, subject, body);
|
||||
_emailService.SendEmail(Settings, EPISODE_GRABBED_TITLE_BRANDED, body);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string subject = "Sonarr [TV] - Downloaded";
|
||||
var body = string.Format("{0} Downloaded and sorted.", message.Message);
|
||||
var body = $"{message.Message} Downloaded and sorted.";
|
||||
|
||||
_emailService.SendEmail(Settings, subject, body);
|
||||
_emailService.SendEmail(Settings, EPISODE_DOWNLOADED_TITLE_BRANDED, body);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Email";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
||||
@@ -9,6 +9,9 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||
{
|
||||
private readonly IGrowlService _growlService;
|
||||
|
||||
public override string Name => "Growl";
|
||||
|
||||
|
||||
public Growl(IGrowlService growlService)
|
||||
{
|
||||
_growlService = growlService;
|
||||
@@ -18,25 +21,14 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
|
||||
_growlService.SendNotification(title, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||
_growlService.SendNotification(EPISODE_GRABBED_TITLE, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
|
||||
_growlService.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||
_growlService.SendNotification(EPISODE_GRABBED_TITLE, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Growl";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Join
|
||||
{
|
||||
@@ -14,30 +13,20 @@ namespace NzbDrone.Core.Notifications.Join
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public override string Link => "https://joinjoaomgcd.appspot.com/";
|
||||
public override string Name => "Join";
|
||||
|
||||
public override string Link => "https://joaoapps.com/join/";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Sonarr - Episode Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_GRABBED_TITLE_BRANDED, Message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Sonarr - Episode Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Join";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -3,7 +3,7 @@ using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
namespace NzbDrone.Core.Notifications.Emby
|
||||
{
|
||||
public class MediaBrowser : NotificationBase<MediaBrowserSettings>
|
||||
{
|
||||
@@ -14,25 +14,23 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
_mediaBrowserService = mediaBrowserService;
|
||||
}
|
||||
|
||||
public override string Link => "http://mediabrowser.tv/";
|
||||
public override string Link => "https://emby.media/";
|
||||
public override string Name => "Emby (Media Browser)";
|
||||
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Sonarr - Grabbed";
|
||||
|
||||
if (Settings.Notify)
|
||||
{
|
||||
_mediaBrowserService.Notify(Settings, title, grabMessage.Message);
|
||||
_mediaBrowserService.Notify(Settings, EPISODE_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Sonarr - Downloaded";
|
||||
|
||||
if (Settings.Notify)
|
||||
{
|
||||
_mediaBrowserService.Notify(Settings, title, message.Message);
|
||||
_mediaBrowserService.Notify(Settings, EPISODE_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
if (Settings.UpdateLibrary)
|
||||
@@ -49,7 +47,6 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name => "Emby (Media Browser)";
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
namespace NzbDrone.Core.Notifications.Emby
|
||||
{
|
||||
public class MediaBrowserProxy
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using NLog;
|
||||
using NzbDrone.Core.Rest;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
namespace NzbDrone.Core.Notifications.Emby
|
||||
{
|
||||
public interface IMediaBrowserService
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
namespace NzbDrone.Core.Notifications.Emby
|
||||
{
|
||||
public class MediaBrowserSettingsValidator : AbstractValidator<MediaBrowserSettings>
|
||||
{
|
||||
@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
public bool UpdateLibrary { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Address => string.Format("{0}:{1}", Host, Port);
|
||||
public string Address => $"{Host}:{Port}";
|
||||
|
||||
public bool IsValid => !string.IsNullOrWhiteSpace(Host) && Port > 0;
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@ namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public abstract class NotificationBase<TSettings> : INotification where TSettings : IProviderConfig, new()
|
||||
{
|
||||
protected const string EPISODE_GRABBED_TITLE = "Episode Grabbed";
|
||||
protected const string EPISODE_DOWNLOADED_TITLE = "Episode Downloaded";
|
||||
|
||||
protected const string EPISODE_GRABBED_TITLE_BRANDED = "Sonarr - " + EPISODE_GRABBED_TITLE;
|
||||
protected const string EPISODE_DOWNLOADED_TITLE_BRANDED = "Sonarr - " + EPISODE_DOWNLOADED_TITLE;
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
public Type ConfigContract => typeof(TSettings);
|
||||
@@ -21,14 +27,25 @@ namespace NzbDrone.Core.Notifications
|
||||
|
||||
public abstract string Link { get; }
|
||||
|
||||
public abstract void OnGrab(GrabMessage grabMessage);
|
||||
public abstract void OnDownload(DownloadMessage message);
|
||||
public abstract void OnRename(Series series);
|
||||
public virtual void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
|
||||
public virtual bool SupportsOnGrab => true;
|
||||
public virtual bool SupportsOnDownload => true;
|
||||
public virtual bool SupportsOnUpgrade => true;
|
||||
public virtual bool SupportsOnRename => true;
|
||||
}
|
||||
|
||||
public virtual void OnDownload(DownloadMessage message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnRename(Series series)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool SupportsOnGrab => HasConcreteImplementation("OnGrab");
|
||||
public bool SupportsOnRename => HasConcreteImplementation("OnRename");
|
||||
public bool SupportsOnDownload => HasConcreteImplementation("OnDownload");
|
||||
public bool SupportsOnUpgrade => SupportsOnDownload;
|
||||
|
||||
protected TSettings Settings => (TSettings)Definition.Settings;
|
||||
|
||||
@@ -39,5 +56,18 @@ namespace NzbDrone.Core.Notifications
|
||||
|
||||
public virtual object RequestAction(string action, IDictionary<string, string> query) { return null; }
|
||||
|
||||
|
||||
private bool HasConcreteImplementation(string methodName)
|
||||
{
|
||||
var method = GetType().GetMethod(methodName);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
throw new MissingMethodException(GetType().Name, Name);
|
||||
}
|
||||
|
||||
return !method.DeclaringType.IsAbstract;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||
{
|
||||
@@ -15,30 +13,19 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public override string Link => "http://www.notifymyandroid.com/";
|
||||
public override string Link => "https://www.notifymyandroid.com/";
|
||||
public override string Name => "Notify My Android";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||
_proxy.SendNotification(EPISODE_GRABBED_TITLE, grabMessage.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Notify My Android";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -9,32 +9,24 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
{
|
||||
private readonly IPlexClientService _plexClientService;
|
||||
|
||||
public override string Link => "https://www.plex.tv/";
|
||||
public override string Name => "Plex Media Center";
|
||||
|
||||
public PlexClient(IPlexClientService plexClientService)
|
||||
{
|
||||
_plexClientService = plexClientService;
|
||||
}
|
||||
|
||||
public override string Link => "http://www.plexapp.com/";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string header = "Sonarr [TV] - Grabbed";
|
||||
_plexClientService.Notify(Settings, header, grabMessage.Message);
|
||||
_plexClientService.Notify(Settings, EPISODE_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string header = "Sonarr [TV] - Downloaded";
|
||||
_plexClientService.Notify(Settings, header, message.Message);
|
||||
_plexClientService.Notify(Settings, EPISODE_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Plex Media Center";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
||||
@@ -19,31 +19,19 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override string Name => "Plex Home Theater";
|
||||
public override string Link => "https://plex.tv/";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string header = "Sonarr - Grabbed";
|
||||
|
||||
Notify(Settings, header, grabMessage.Message);
|
||||
Notify(Settings, EPISODE_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string header = "Sonarr - Downloaded";
|
||||
|
||||
Notify(Settings, header, message.Message);
|
||||
Notify(Settings, EPISODE_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override string Name => "Plex Home Theater";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
@@ -64,7 +52,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
var logMessage = string.Format("Unable to connect to PHT Host: {0}:{1}", Settings.Host, Settings.Port);
|
||||
var logMessage = $"Unable to connect to PHT Host: {Settings.Host}:{Settings.Port}";
|
||||
_logger.Debug(ex, logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,8 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
_plexServerService = plexServerService;
|
||||
}
|
||||
|
||||
public override string Link => "http://www.plexapp.com/";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
}
|
||||
public override string Link => "https://www.plex.tv/";
|
||||
public override string Name => "Plex Media Server";
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
@@ -38,10 +35,6 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name => "Plex Media Server";
|
||||
|
||||
public override bool SupportsOnGrab => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -15,30 +15,19 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||
_prowlService = prowlService;
|
||||
}
|
||||
|
||||
public override string Link => "http://www.prowlapp.com/";
|
||||
public override string Link => "https://www.prowlapp.com/";
|
||||
public override string Name => "Prowl";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
|
||||
_prowlService.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
_prowlService.SendNotification(EPISODE_GRABBED_TITLE, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
|
||||
_prowlService.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
_prowlService.SendNotification(EPISODE_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Prowl";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.PushBullet
|
||||
{
|
||||
@@ -14,30 +13,20 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public override string Name => "Pushbullet";
|
||||
public override string Link => "https://www.pushbullet.com/";
|
||||
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Sonarr - Episode Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_GRABBED_TITLE_BRANDED, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Sonarr - Episode Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Pushbullet";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -14,29 +14,19 @@ namespace NzbDrone.Core.Notifications.Pushalot
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public override string Link => "https://www.Pushalot.com/";
|
||||
public override string Name => "Pushalot";
|
||||
public override string Link => "https://pushalot.com/";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_GRABBED_TITLE, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Pushalot";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Pushover
|
||||
{
|
||||
@@ -14,30 +13,19 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public override string Name => "Pushover";
|
||||
public override string Link => "https://pushover.net/";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_GRABBED_TITLE, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Pushover";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||
}
|
||||
|
||||
public override string Name => "Slack";
|
||||
|
||||
public override string Link => "https://my.slack.com/services/new/incoming-webhook/";
|
||||
|
||||
public override void OnGrab(GrabMessage message)
|
||||
|
||||
@@ -16,12 +16,9 @@ namespace NzbDrone.Core.Notifications.Synology
|
||||
_indexerProxy = indexerProxy;
|
||||
}
|
||||
|
||||
public override string Link => "http://www.synology.com";
|
||||
public override string Link => "https://www.synology.com";
|
||||
public override string Name => "Synology Indexer";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
@@ -50,7 +47,6 @@ namespace NzbDrone.Core.Notifications.Synology
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name => "Synology Indexer";
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Telegram
|
||||
{
|
||||
@@ -14,30 +13,19 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public override string Name => "Telegram";
|
||||
public override string Link => "https://telegram.org/";
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_GRABBED_TITLE, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "Telegram";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Exceptions;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Twitter
|
||||
@@ -17,6 +16,7 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||
_twitterService = twitterService;
|
||||
}
|
||||
|
||||
public override string Name => "Twitter";
|
||||
public override string Link => "https://twitter.com/";
|
||||
|
||||
public override void OnGrab(GrabMessage message)
|
||||
@@ -29,10 +29,6 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||
_twitterService.SendNotification($"Imported: {message.Message}", Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
public override object RequestAction(string action, IDictionary<string, string> query)
|
||||
{
|
||||
if (action == "startOAuth")
|
||||
@@ -74,10 +70,6 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||
return new { };
|
||||
}
|
||||
|
||||
public override string Name => "Twitter";
|
||||
|
||||
public override bool SupportsOnRename => false;
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
@@ -26,10 +26,6 @@ namespace NzbDrone.Core.Parser
|
||||
new Regex(@"^(?:\W*S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Matches Movie name with AirYear
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Episodes without a title, Single (S01E05, 1x05) AND Multi (S01E04E05, 1x04x05, etc)
|
||||
new Regex(@"^(?:S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{2,3}(?!\d+)))+)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
@@ -300,8 +296,6 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
public static ParsedEpisodeInfo ParseTitle(string title)
|
||||
{
|
||||
|
||||
ParsedEpisodeInfo realResult = null;
|
||||
try
|
||||
{
|
||||
if (!ValidateBeforeParsing(title)) return null;
|
||||
@@ -348,8 +342,6 @@ namespace NzbDrone.Core.Parser
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach (var regex in ReportTitleRegex)
|
||||
{
|
||||
var match = regex.Matches(simpleTitle);
|
||||
@@ -391,8 +383,6 @@ namespace NzbDrone.Core.Parser
|
||||
Logger.Debug("Release Hash parsed: {0}", result.ReleaseHash);
|
||||
}
|
||||
|
||||
realResult = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -411,7 +401,7 @@ namespace NzbDrone.Core.Parser
|
||||
}
|
||||
|
||||
Logger.Debug("Unable to parse {0}", title);
|
||||
return realResult;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string ParseSeriesName(string title)
|
||||
@@ -535,7 +525,6 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
int airYear;
|
||||
int.TryParse(matchCollection[0].Groups["airyear"].Value, out airYear);
|
||||
//int.TryParse(matchCollection[0].Groups["year"].Value, out airYear);
|
||||
|
||||
ParsedEpisodeInfo result;
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
if (parsedEpisodeInfo == null)
|
||||
{
|
||||
return _seriesService.FindByTitle(title); //Here we have a problem since it is not possible for movies to find a scene mapping, so these releases are always rejected :(
|
||||
return _seriesService.FindByTitle(title);
|
||||
}
|
||||
|
||||
var series = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
||||
@@ -252,12 +252,10 @@ namespace NzbDrone.Core.Parser
|
||||
{
|
||||
Series series = null;
|
||||
|
||||
/*var localEpisode = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
||||
|
||||
var sceneMappingTvdbId = _sceneMappingService.FindTvdbId(parsedEpisodeInfo.SeriesTitle);
|
||||
if (localEpisode != null)
|
||||
if (sceneMappingTvdbId.HasValue)
|
||||
{
|
||||
if (searchCriteria != null && searchCriteria.Series.TvdbId == localEpisode.TvdbId)
|
||||
if (searchCriteria != null && searchCriteria.Series.TvdbId == sceneMappingTvdbId.Value)
|
||||
{
|
||||
return searchCriteria.Series;
|
||||
}
|
||||
@@ -271,7 +269,7 @@ namespace NzbDrone.Core.Parser
|
||||
}
|
||||
|
||||
return series;
|
||||
}*/ //This is only to find scene mapping should not be necessary for movies.
|
||||
}
|
||||
|
||||
if (searchCriteria != null)
|
||||
{
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace NzbDrone.Core.Qualities
|
||||
new QualityDefinition(Quality.WEBDL720p) { Weight = 8, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.Bluray720p) { Weight = 9, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.WEBDL1080p) { Weight = 10, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.Bluray1080p) { Weight = 11, MinSize = 0, MaxSize = null },
|
||||
new QualityDefinition(Quality.Bluray1080p) { Weight = 11, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.HDTV2160p) { Weight = 12, MinSize = 0, MaxSize = null },
|
||||
new QualityDefinition(Quality.WEBDL2160p) { Weight = 13, MinSize = 0, MaxSize = null },
|
||||
new QualityDefinition(Quality.Bluray2160p) { Weight = 14, MinSize = 0, MaxSize = null },
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<i class="icon-sonarr-hdd"/>
|
||||
Import existing series on disk
|
||||
</button>
|
||||
<button class="btn btn-default col-md-2 col-xs-4 x-add-new"><i class="icon-sonarr-active hidden-xs"></i> Add New Movie</button>
|
||||
<button class="btn btn-default col-md-2 col-xs-4 x-add-new"><i class="icon-sonarr-active hidden-xs"></i> Add New Series</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,3 +14,4 @@
|
||||
<div id="add-series-workspace"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{{#if folder}}
|
||||
<input type="text" class="form-control x-series-search" value="{{folder.name}}">
|
||||
{{else}}
|
||||
<input type="text" class="form-control x-series-search" placeholder="Start typing the name of the movie you want to add ...">
|
||||
<input type="text" class="form-control x-series-search" placeholder="Start typing the name of series you want to add ...">
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,11 +35,10 @@ module.exports = NzbDroneCell.extend({
|
||||
},
|
||||
|
||||
_manualSearch : function() {
|
||||
console.warn(this.cellValue);
|
||||
vent.trigger(vent.Commands.ShowEpisodeDetails, {
|
||||
episode : this.cellValue,
|
||||
hideSeriesLink : true,
|
||||
openingTab : 'search'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -13,7 +13,7 @@ var SeriesEditorLayout = require('./Series/Editor/SeriesEditorLayout');
|
||||
|
||||
module.exports = NzbDroneController.extend({
|
||||
addSeries : function(action) {
|
||||
this.setTitle('Add Movie');
|
||||
this.setTitle('Add Series');
|
||||
this.showMainRegion(new AddSeriesLayout({ action : action }));
|
||||
},
|
||||
|
||||
@@ -56,4 +56,4 @@ module.exports = NzbDroneController.extend({
|
||||
this.setTitle('Series Editor');
|
||||
this.showMainRegion(new SeriesEditorLayout());
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -11,7 +11,7 @@ Handlebars.registerHelper('poster', function() {
|
||||
if (!poster[0].url.match(/^https?:\/\//)) {
|
||||
return new Handlebars.SafeString('<img class="series-poster x-series-poster" {0}>'.format(Handlebars.helpers.defaultImg.call(null, poster[0].url, 250)));
|
||||
} else {
|
||||
var url = poster[0].url.replace(/^https?\:/, 'https://'); //IMDb posters need https to work, k?
|
||||
var url = poster[0].url.replace(/^https?\:/, '');
|
||||
return new Handlebars.SafeString('<img class="series-poster x-series-poster" {0}>'.format(Handlebars.helpers.defaultImg.call(null, url)));
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ Handlebars.registerHelper('imdbUrl', function() {
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('tvdbUrl', function() {
|
||||
return 'http://imdb.com/title/tt' + this.tvdbId;
|
||||
return 'http://www.thetvdb.com/?tab=series&id=' + this.tvdbId;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('tvRageUrl', function() {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
<div class="navbar-collapse collapse x-navbar-collapse">
|
||||
<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}}/" class="x-series-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-series"></i> Series</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}}/wanted" class="x-wanted-nav"><i class="icon-sonarr-navbar-icon icon-sonarr-navbar-wanted"></i> Wanted</a></li>
|
||||
@@ -37,8 +37,8 @@
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-search"></i></span>
|
||||
<input type="text" class="col-md-6 form-control x-series-search" placeholder="Search the movies in your library">
|
||||
<input type="text" class="col-md-6 form-control x-series-search" placeholder="Search the series in your library">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,9 +29,9 @@
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<span class="series-info-links">
|
||||
<!--<a href="{{traktUrl}}" class="label label-info">Trakt</a>
|
||||
<a href="{{traktUrl}}" class="label label-info">Trakt</a>
|
||||
|
||||
<a href="{{tvdbUrl}}" class="label label-info">The TVDB</a>-->
|
||||
<a href="{{tvdbUrl}}" class="label label-info">The TVDB</a>
|
||||
|
||||
{{#if imdbId}}
|
||||
<a href="{{imdbUrl}}" class="label label-info">IMDB</a>
|
||||
|
||||
@@ -32,8 +32,7 @@ module.exports = Marionette.Layout.extend({
|
||||
refresh : '.x-refresh',
|
||||
rename : '.x-rename',
|
||||
search : '.x-search',
|
||||
poster : '.x-series-poster',
|
||||
manualSearch : '.x-manual-search'
|
||||
poster : '.x-series-poster'
|
||||
},
|
||||
|
||||
events : {
|
||||
@@ -42,8 +41,7 @@ module.exports = Marionette.Layout.extend({
|
||||
'click .x-edit' : '_editSeries',
|
||||
'click .x-refresh' : '_refreshSeries',
|
||||
'click .x-rename' : '_renameSeries',
|
||||
'click .x-search' : '_seriesSearch',
|
||||
'click .x-manual-search' : '_manualSearchM'
|
||||
'click .x-search' : '_seriesSearch'
|
||||
},
|
||||
|
||||
initialize : function() {
|
||||
@@ -180,11 +178,11 @@ module.exports = Marionette.Layout.extend({
|
||||
if (self.model.get('id') !== seriesId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
if (sceneSeasonNumber === undefined) {
|
||||
sceneSeasonNumber = seasonNumber;
|
||||
}
|
||||
|
||||
|
||||
return _.where(self.model.get('alternateTitles'),
|
||||
function(alt) {
|
||||
return alt.sceneSeasonNumber === sceneSeasonNumber || alt.seasonNumber === seasonNumber;
|
||||
@@ -256,17 +254,5 @@ module.exports = Marionette.Layout.extend({
|
||||
} else {
|
||||
$('body').removeClass('backdrop');
|
||||
}
|
||||
},
|
||||
|
||||
_manualSearchM : function() {
|
||||
console.warn("Manual Search started");
|
||||
console.warn(this.model.get("seriesId"));
|
||||
console.warn(this.model)
|
||||
console.warn(this.episodeCollection);
|
||||
vent.trigger(vent.Commands.ShowEpisodeDetails, {
|
||||
episode : this.episodeCollection.models[0],
|
||||
hideSeriesLink : true,
|
||||
openingTab : 'search'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -5,26 +5,23 @@
|
||||
<div class="col-md-12 col-lg-10">
|
||||
<div>
|
||||
<h1 class="header-text">
|
||||
<i class="x-monitored" title="Toggle monitored state for movie"/>
|
||||
<i class="x-monitored" title="Toggle monitored state for entire series"/>
|
||||
{{title}}
|
||||
<div class="series-actions pull-right">
|
||||
<div class="x-episode-file-editor">
|
||||
<i class="icon-sonarr-episode-file" title="Modify episode files for movie"/>
|
||||
<i class="icon-sonarr-episode-file" title="Modify episode files for series"/>
|
||||
</div>
|
||||
<div class="x-refresh">
|
||||
<i class="icon-sonarr-refresh icon-can-spin" title="Update movie info and scan disk"/>
|
||||
<i class="icon-sonarr-refresh icon-can-spin" title="Update series info and scan disk"/>
|
||||
</div>
|
||||
<div class="x-rename">
|
||||
<i class="icon-sonarr-rename" title="Preview rename for all episodes"/>
|
||||
</div>
|
||||
<div class="x-search">
|
||||
<i class="icon-sonarr-search" title="Search for movie"/>
|
||||
</div>
|
||||
<div class="x-manual-search">
|
||||
<i class="icon-sonarr-search-manual" title="Manual Search"/>
|
||||
<i class="icon-sonarr-search" title="Search for monitored episodes in this series"/>
|
||||
</div>
|
||||
<div class="x-edit">
|
||||
<i class="icon-sonarr-edit" title="Edit movie"/>
|
||||
<i class="icon-sonarr-edit" title="Edit series"/>
|
||||
</div>
|
||||
</div>
|
||||
</h1>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<a href="/addseries" class='btn btn-lg btn-block btn-success x-add-series'>
|
||||
<i class='icon-sonarr-add'></i>
|
||||
Add Movie
|
||||
Add Series
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,7 +80,7 @@ module.exports = Marionette.Layout.extend({
|
||||
collapse : true,
|
||||
items : [
|
||||
{
|
||||
title : 'Add Movie',
|
||||
title : 'Add Series',
|
||||
icon : 'icon-sonarr-add',
|
||||
route : 'addseries'
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user