mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-17 21:26:22 -04:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a63587bb19 | ||
|
|
eb46343ce8 | ||
|
|
8fa43fb9f7 | ||
|
|
6d5e9ad4a1 | ||
|
|
70c8228605 | ||
|
|
82470bd995 | ||
|
|
a263558383 | ||
|
|
7d82e35650 | ||
|
|
8616bcedd4 | ||
|
|
2c66322121 | ||
|
|
1402bc883e | ||
|
|
1325822798 | ||
|
|
7a786d4c0e | ||
|
|
87c7afac16 | ||
|
|
06d39579a5 | ||
|
|
c8ea0a73e2 | ||
|
|
eeb3c88131 | ||
|
|
fd718b61ac | ||
|
|
4a3b2a0014 | ||
|
|
cbd87dcc38 | ||
|
|
956de03a62 | ||
|
|
2b74098040 | ||
|
|
402a9e1ee0 | ||
|
|
e68653463d | ||
|
|
0715962ec5 | ||
|
|
5668a3bcfd | ||
|
|
bd241dcbe0 | ||
|
|
90ff73d45f | ||
|
|
c2c7015f39 | ||
|
|
579602419e | ||
|
|
96332978a0 | ||
|
|
1488c0a0fc | ||
|
|
a3dfa05f25 |
@@ -24,6 +24,7 @@ namespace NzbDrone.Api.Indexers
|
|||||||
public string Indexer { get; set; }
|
public string Indexer { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public string ReleaseHash { get; set; }
|
public string ReleaseHash { get; set; }
|
||||||
|
public string Edition { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public bool FullSeason { get; set; }
|
public bool FullSeason { get; set; }
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
@@ -90,6 +91,55 @@ namespace NzbDrone.Api.Indexers
|
|||||||
if (model.IsForMovie)
|
if (model.IsForMovie)
|
||||||
{
|
{
|
||||||
downloadAllowed = model.RemoteMovie.DownloadAllowed;
|
downloadAllowed = model.RemoteMovie.DownloadAllowed;
|
||||||
|
var parsedMovieInfo = model.RemoteMovie.ParsedMovieInfo;
|
||||||
|
|
||||||
|
return new ReleaseResource
|
||||||
|
{
|
||||||
|
Guid = releaseInfo.Guid,
|
||||||
|
Quality = parsedMovieInfo.Quality,
|
||||||
|
//QualityWeight
|
||||||
|
Age = releaseInfo.Age,
|
||||||
|
AgeHours = releaseInfo.AgeHours,
|
||||||
|
AgeMinutes = releaseInfo.AgeMinutes,
|
||||||
|
Size = releaseInfo.Size,
|
||||||
|
IndexerId = releaseInfo.IndexerId,
|
||||||
|
Indexer = releaseInfo.Indexer,
|
||||||
|
ReleaseGroup = parsedMovieInfo.ReleaseGroup,
|
||||||
|
ReleaseHash = parsedMovieInfo.ReleaseHash,
|
||||||
|
Title = releaseInfo.Title,
|
||||||
|
FullSeason = parsedMovieInfo.FullSeason,
|
||||||
|
SeasonNumber = parsedMovieInfo.SeasonNumber,
|
||||||
|
Language = parsedMovieInfo.Language,
|
||||||
|
AirDate = "",
|
||||||
|
SeriesTitle = parsedMovieInfo.MovieTitle,
|
||||||
|
EpisodeNumbers = new int[0],
|
||||||
|
AbsoluteEpisodeNumbers = new int[0],
|
||||||
|
Approved = model.Approved,
|
||||||
|
TemporarilyRejected = model.TemporarilyRejected,
|
||||||
|
Rejected = model.Rejected,
|
||||||
|
TvdbId = releaseInfo.TvdbId,
|
||||||
|
TvRageId = releaseInfo.TvRageId,
|
||||||
|
Rejections = model.Rejections.Select(r => r.Reason).ToList(),
|
||||||
|
PublishDate = releaseInfo.PublishDate,
|
||||||
|
CommentUrl = releaseInfo.CommentUrl,
|
||||||
|
DownloadUrl = releaseInfo.DownloadUrl,
|
||||||
|
InfoUrl = releaseInfo.InfoUrl,
|
||||||
|
DownloadAllowed = downloadAllowed,
|
||||||
|
//ReleaseWeight
|
||||||
|
|
||||||
|
MagnetUrl = torrentInfo.MagnetUrl,
|
||||||
|
InfoHash = torrentInfo.InfoHash,
|
||||||
|
Seeders = torrentInfo.Seeders,
|
||||||
|
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
|
||||||
|
Protocol = releaseInfo.DownloadProtocol,
|
||||||
|
|
||||||
|
Edition = parsedMovieInfo.Edition,
|
||||||
|
|
||||||
|
IsDaily = false,
|
||||||
|
IsAbsoluteNumbering = false,
|
||||||
|
IsPossibleSpecialEpisode = false,
|
||||||
|
Special = parsedMovieInfo.Special,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
|
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
||||||
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
||||||
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
||||||
PostValidator.RuleFor(s => s.ImdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
|
PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
|
||||||
|
|
||||||
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public DateTime? InCinemas { get; set; }
|
public DateTime? InCinemas { get; set; }
|
||||||
public List<MediaCover> Images { get; set; }
|
public List<MediaCover> Images { get; set; }
|
||||||
|
public string Website { get; set; }
|
||||||
|
|
||||||
public string RemotePoster { get; set; }
|
public string RemotePoster { get; set; }
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
@@ -42,6 +43,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
public DateTime? LastInfoSync { get; set; }
|
public DateTime? LastInfoSync { get; set; }
|
||||||
public string CleanTitle { get; set; }
|
public string CleanTitle { get; set; }
|
||||||
public string ImdbId { get; set; }
|
public string ImdbId { get; set; }
|
||||||
|
public int TmdbId { get; set; }
|
||||||
public string TitleSlug { get; set; }
|
public string TitleSlug { get; set; }
|
||||||
public string RootFolderPath { get; set; }
|
public string RootFolderPath { get; set; }
|
||||||
public string Certification { get; set; }
|
public string Certification { get; set; }
|
||||||
@@ -50,6 +52,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
public DateTime Added { get; set; }
|
public DateTime Added { get; set; }
|
||||||
public AddMovieOptions AddOptions { get; set; }
|
public AddMovieOptions AddOptions { get; set; }
|
||||||
public Ratings Ratings { get; set; }
|
public Ratings Ratings { get; set; }
|
||||||
|
public List<string> AlternativeTitles { get; set; }
|
||||||
|
|
||||||
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
||||||
|
|
||||||
@@ -79,7 +82,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
return new MovieResource
|
return new MovieResource
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.Id,
|
||||||
|
TmdbId = model.TmdbId,
|
||||||
Title = model.Title,
|
Title = model.Title,
|
||||||
//AlternateTitles
|
//AlternateTitles
|
||||||
SortTitle = model.SortTitle,
|
SortTitle = model.SortTitle,
|
||||||
@@ -108,10 +111,12 @@ namespace NzbDrone.Api.Movie
|
|||||||
TitleSlug = model.TitleSlug,
|
TitleSlug = model.TitleSlug,
|
||||||
RootFolderPath = model.RootFolderPath,
|
RootFolderPath = model.RootFolderPath,
|
||||||
Certification = model.Certification,
|
Certification = model.Certification,
|
||||||
|
Website = model.Website,
|
||||||
Genres = model.Genres,
|
Genres = model.Genres,
|
||||||
Tags = model.Tags,
|
Tags = model.Tags,
|
||||||
Added = model.Added,
|
Added = model.Added,
|
||||||
AddOptions = model.AddOptions,
|
AddOptions = model.AddOptions,
|
||||||
|
AlternativeTitles = model.AlternativeTitles,
|
||||||
Ratings = model.Ratings
|
Ratings = model.Ratings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -123,6 +128,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
return new Core.Tv.Movie
|
return new Core.Tv.Movie
|
||||||
{
|
{
|
||||||
Id = resource.Id,
|
Id = resource.Id,
|
||||||
|
TmdbId = resource.TmdbId,
|
||||||
|
|
||||||
Title = resource.Title,
|
Title = resource.Title,
|
||||||
//AlternateTitles
|
//AlternateTitles
|
||||||
@@ -151,10 +157,12 @@ namespace NzbDrone.Api.Movie
|
|||||||
TitleSlug = resource.TitleSlug,
|
TitleSlug = resource.TitleSlug,
|
||||||
RootFolderPath = resource.RootFolderPath,
|
RootFolderPath = resource.RootFolderPath,
|
||||||
Certification = resource.Certification,
|
Certification = resource.Certification,
|
||||||
|
Website = resource.Website,
|
||||||
Genres = resource.Genres,
|
Genres = resource.Genres,
|
||||||
Tags = resource.Tags,
|
Tags = resource.Tags,
|
||||||
Added = resource.Added,
|
Added = resource.Added,
|
||||||
AddOptions = resource.AddOptions,
|
AddOptions = resource.AddOptions,
|
||||||
|
AlternativeTitles = resource.AlternativeTitles,
|
||||||
Ratings = resource.Ratings
|
Ratings = resource.Ratings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -162,6 +170,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
public static Core.Tv.Movie ToModel(this MovieResource resource, Core.Tv.Movie movie)
|
public static Core.Tv.Movie ToModel(this MovieResource resource, Core.Tv.Movie movie)
|
||||||
{
|
{
|
||||||
movie.ImdbId = resource.ImdbId;
|
movie.ImdbId = resource.ImdbId;
|
||||||
|
movie.TmdbId = resource.TmdbId;
|
||||||
|
|
||||||
movie.Path = resource.Path;
|
movie.Path = resource.Path;
|
||||||
movie.ProfileId = resource.ProfileId;
|
movie.ProfileId = resource.ProfileId;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ namespace NzbDrone.Common.Cloud
|
|||||||
{
|
{
|
||||||
IHttpRequestBuilderFactory Services { get; }
|
IHttpRequestBuilderFactory Services { get; }
|
||||||
IHttpRequestBuilderFactory SkyHookTvdb { get; }
|
IHttpRequestBuilderFactory SkyHookTvdb { get; }
|
||||||
|
IHttpRequestBuilderFactory TMDB { get; }
|
||||||
|
IHttpRequestBuilderFactory TMDBSingle { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SonarrCloudRequestBuilder : ISonarrCloudRequestBuilder
|
public class SonarrCloudRequestBuilder : ISonarrCloudRequestBuilder
|
||||||
@@ -18,10 +20,20 @@ namespace NzbDrone.Common.Cloud
|
|||||||
SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/")
|
SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/")
|
||||||
.SetSegment("language", "en")
|
.SetSegment("language", "en")
|
||||||
.CreateFactory();
|
.CreateFactory();
|
||||||
|
|
||||||
|
TMDB = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}/{id}{secondaryRoute}")
|
||||||
|
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
|
||||||
|
.CreateFactory();
|
||||||
|
|
||||||
|
TMDBSingle = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}")
|
||||||
|
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
|
||||||
|
.CreateFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHttpRequestBuilderFactory Services { get; private set; }
|
public IHttpRequestBuilderFactory Services { get; private set; }
|
||||||
|
|
||||||
public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; }
|
public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; }
|
||||||
|
public IHttpRequestBuilderFactory TMDB { get; private set; }
|
||||||
|
public IHttpRequestBuilderFactory TMDBSingle { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/NzbDrone.Core/Datastore/Migration/106_add_tmdb_stuff.cs
Normal file
21
src/NzbDrone.Core/Datastore/Migration/106_add_tmdb_stuff.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(106)]
|
||||||
|
public class add_tmdb_stuff : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AddColumn("TmdbId").AsInt32().WithDefaultValue(0);
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AddColumn("Website").AsString().Nullable();
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AlterColumn("ImdbId").AsString().Nullable();
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AddColumn("AlternativeTitles").AsString().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/NzbDrone.Core/Datastore/Migration/107_fix_movie_files.cs
Normal file
14
src/NzbDrone.Core/Datastore/Migration/107_fix_movie_files.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(107)]
|
||||||
|
public class fix_movie_files : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("MovieFiles").AlterColumn("Path").AsString().Nullable(); //Should be deleted, but to much work, ¯\_(ツ)_/¯
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,9 +66,9 @@ namespace NzbDrone.Core.DecisionEngine
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(report.Title);
|
var parsedEpisodeInfo = Parser.Parser.ParseMovieTitle(report.Title);
|
||||||
|
|
||||||
if (parsedEpisodeInfo != null && !parsedEpisodeInfo.SeriesTitle.IsNullOrWhiteSpace())
|
if (parsedEpisodeInfo != null && !parsedEpisodeInfo.MovieTitle.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
RemoteMovie remoteEpisode = _parsingService.Map(parsedEpisodeInfo, "", searchCriteria);
|
RemoteMovie remoteEpisode = _parsingService.Map(parsedEpisodeInfo, "", searchCriteria);
|
||||||
remoteEpisode.Release = report;
|
remoteEpisode.Release = report;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
|||||||
ScanGracePeriod = TimeSpan.FromSeconds(30);
|
ScanGracePeriod = TimeSpan.FromSeconds(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent)
|
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents)
|
||||||
{
|
{
|
||||||
var title = remoteEpisode.Release.Title;
|
var title = remoteEpisode.Release.Title;
|
||||||
|
|
||||||
@@ -42,7 +42,25 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
|||||||
|
|
||||||
using (var stream = _diskProvider.OpenWriteStream(filepath))
|
using (var stream = _diskProvider.OpenWriteStream(filepath))
|
||||||
{
|
{
|
||||||
stream.Write(fileContent, 0, fileContent.Length);
|
stream.Write(fileContents, 0, fileContents.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("NZB Download succeeded, saved to: {0}", filepath);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
|
||||||
|
{
|
||||||
|
var title = remoteMovie.Release.Title;
|
||||||
|
|
||||||
|
title = FileNameBuilder.CleanFileName(title);
|
||||||
|
|
||||||
|
var filepath = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
||||||
|
|
||||||
|
using (var stream = _diskProvider.OpenWriteStream(filepath))
|
||||||
|
{
|
||||||
|
stream.Write(fileContents, 0, fileContents.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("NZB Download succeeded, saved to: {0}", filepath);
|
_logger.Debug("NZB Download succeeded, saved to: {0}", filepath);
|
||||||
|
|||||||
@@ -31,6 +31,50 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string AddFromMagnetLink(RemoteMovie remoteEpisode, string hash, string magnetLink)
|
||||||
|
{
|
||||||
|
var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings);
|
||||||
|
|
||||||
|
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
_proxy.SetLabel(actualHash, Settings.TvCategory, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
_proxy.SetTorrentConfiguration(actualHash, "remove_at_ratio", false, Settings);
|
||||||
|
|
||||||
|
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||||
|
|
||||||
|
if (isRecentEpisode && Settings.RecentTvPriority == (int)DelugePriority.First ||
|
||||||
|
!isRecentEpisode && Settings.OlderTvPriority == (int)DelugePriority.First)
|
||||||
|
{
|
||||||
|
_proxy.MoveTorrentToTopInQueue(actualHash, Settings);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return actualHash.ToUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromTorrentFile(RemoteMovie remoteEpisode, string hash, string filename, byte[] fileContent)
|
||||||
|
{
|
||||||
|
var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||||
|
|
||||||
|
if (!Settings.TvCategory.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
_proxy.SetLabel(actualHash, Settings.TvCategory, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
_proxy.SetTorrentConfiguration(actualHash, "remove_at_ratio", false, Settings);
|
||||||
|
|
||||||
|
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||||
|
|
||||||
|
if (isRecentEpisode && Settings.RecentTvPriority == (int)DelugePriority.First ||
|
||||||
|
!isRecentEpisode && Settings.OlderTvPriority == (int)DelugePriority.First)
|
||||||
|
{
|
||||||
|
_proxy.MoveTorrentToTopInQueue(actualHash, Settings);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return actualHash.ToUpper();
|
||||||
|
}
|
||||||
|
|
||||||
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)
|
||||||
{
|
{
|
||||||
var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings);
|
var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 8112;
|
Port = 8112;
|
||||||
Password = "deluge";
|
Password = "deluge";
|
||||||
TvCategory = "tv-sonarr";
|
TvCategory = "movie-radarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
|||||||
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(DelugePriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||||
|
|||||||
@@ -29,11 +29,25 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
|||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent)
|
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents)
|
||||||
{
|
{
|
||||||
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||||
|
|
||||||
|
var response = _proxy.DownloadNzb(fileContents, filename, priority, Settings);
|
||||||
|
|
||||||
var response = _proxy.DownloadNzb(fileContent, filename, priority, Settings);
|
if (response == null)
|
||||||
|
{
|
||||||
|
throw new DownloadClientException("Failed to add nzb {0}", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
|
||||||
|
{
|
||||||
|
var priority = Settings.RecentTvPriority;
|
||||||
|
|
||||||
|
var response = _proxy.DownloadNzb(fileContents, filename, priority, Settings);
|
||||||
|
|
||||||
if (response == null)
|
if (response == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent)
|
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents)
|
||||||
{
|
{
|
||||||
var category = Settings.TvCategory;
|
var category = Settings.TvCategory;
|
||||||
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||||
|
|
||||||
var response = _proxy.DownloadNzb(fileContent, filename, category, priority, Settings);
|
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
||||||
|
|
||||||
if (response == null)
|
if (response == null)
|
||||||
{
|
{
|
||||||
@@ -44,6 +44,21 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
|
||||||
|
{
|
||||||
|
var category = Settings.TvCategory; // TODO: Update this to MovieCategory?
|
||||||
|
var priority = Settings.RecentTvPriority;
|
||||||
|
|
||||||
|
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
||||||
|
|
||||||
|
if(response == null)
|
||||||
|
{
|
||||||
|
throw new DownloadClientException("Failed to add nzb {0}", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<DownloadClientItem> GetQueue()
|
private IEnumerable<DownloadClientItem> GetQueue()
|
||||||
{
|
{
|
||||||
NzbgetGlobalStatus globalStatus;
|
NzbgetGlobalStatus globalStatus;
|
||||||
@@ -72,13 +87,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||||||
|
|
||||||
var droneParameter = item.Parameters.SingleOrDefault(p => p.Name == "drone");
|
var droneParameter = item.Parameters.SingleOrDefault(p => p.Name == "drone");
|
||||||
|
|
||||||
var queueItem = new DownloadClientItem();
|
var queueItem = new DownloadClientItem()
|
||||||
queueItem.DownloadId = droneParameter == null ? item.NzbId.ToString() : droneParameter.Value.ToString();
|
{
|
||||||
queueItem.Title = item.NzbName;
|
DownloadId = droneParameter == null ? item.NzbId.ToString() : droneParameter.Value.ToString(),
|
||||||
queueItem.TotalSize = totalSize;
|
Title = item.NzbName,
|
||||||
queueItem.Category = item.Category;
|
TotalSize = totalSize,
|
||||||
queueItem.DownloadClient = Definition.Name;
|
Category = item.Category,
|
||||||
|
DownloadClient = Definition.Name
|
||||||
|
};
|
||||||
if (globalStatus.DownloadPaused || remainingSize == pausedSize && remainingSize != 0)
|
if (globalStatus.DownloadPaused || remainingSize == pausedSize && remainingSize != 0)
|
||||||
{
|
{
|
||||||
queueItem.Status = DownloadItemStatus.Paused;
|
queueItem.Status = DownloadItemStatus.Paused;
|
||||||
@@ -131,17 +147,18 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||||||
{
|
{
|
||||||
var droneParameter = item.Parameters.SingleOrDefault(p => p.Name == "drone");
|
var droneParameter = item.Parameters.SingleOrDefault(p => p.Name == "drone");
|
||||||
|
|
||||||
var historyItem = new DownloadClientItem();
|
var historyItem = new DownloadClientItem()
|
||||||
historyItem.DownloadClient = Definition.Name;
|
{
|
||||||
historyItem.DownloadId = droneParameter == null ? item.Id.ToString() : droneParameter.Value.ToString();
|
DownloadClient = Definition.Name,
|
||||||
historyItem.Title = item.Name;
|
DownloadId = droneParameter == null ? item.Id.ToString() : droneParameter.Value.ToString(),
|
||||||
historyItem.TotalSize = MakeInt64(item.FileSizeHi, item.FileSizeLo);
|
Title = item.Name,
|
||||||
historyItem.OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(item.DestDir));
|
TotalSize = MakeInt64(item.FileSizeHi, item.FileSizeLo),
|
||||||
historyItem.Category = item.Category;
|
OutputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, new OsPath(item.DestDir)),
|
||||||
historyItem.Message = string.Format("PAR Status: {0} - Unpack Status: {1} - Move Status: {2} - Script Status: {3} - Delete Status: {4} - Mark Status: {5}", item.ParStatus, item.UnpackStatus, item.MoveStatus, item.ScriptStatus, item.DeleteStatus, item.MarkStatus);
|
Category = item.Category,
|
||||||
historyItem.Status = DownloadItemStatus.Completed;
|
Message = string.Format("PAR Status: {0} - Unpack Status: {1} - Move Status: {2} - Script Status: {3} - Delete Status: {4} - Mark Status: {5}", item.ParStatus, item.UnpackStatus, item.MoveStatus, item.ScriptStatus, item.DeleteStatus, item.MarkStatus),
|
||||||
historyItem.RemainingTime = TimeSpan.Zero;
|
Status = DownloadItemStatus.Completed,
|
||||||
|
RemainingTime = TimeSpan.Zero
|
||||||
|
};
|
||||||
if (item.DeleteStatus == "MANUAL")
|
if (item.DeleteStatus == "MANUAL")
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||||||
{
|
{
|
||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 6789;
|
Port = 6789;
|
||||||
TvCategory = "tv";
|
TvCategory = "Movies";
|
||||||
|
Username = "nzbget";
|
||||||
|
Password = "tegbzn6789";
|
||||||
RecentTvPriority = (int)NzbgetPriority.Normal;
|
RecentTvPriority = (int)NzbgetPriority.Normal;
|
||||||
OlderTvPriority = (int)NzbgetPriority.Normal;
|
OlderTvPriority = (int)NzbgetPriority.Normal;
|
||||||
}
|
}
|
||||||
@@ -44,7 +46,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(NzbgetPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
|||||||
{
|
{
|
||||||
Host = "localhost";
|
Host = "localhost";
|
||||||
Port = 9091;
|
Port = 9091;
|
||||||
TvCategory = "tv-sonarr";
|
TvCategory = "movie-radarr";
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
|
||||||
@@ -37,9 +37,10 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
|||||||
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Sonarr avoids conflicts with unrelated downloads, but it's optional")]
|
[FieldDefinition(4, Label = "Category", Type = FieldType.Textbox, HelpText = "Adding a category specific to Radarr avoids conflicts with unrelated downloads, but it's optional")]
|
||||||
public string TvCategory { get; set; }
|
public string TvCategory { get; set; }
|
||||||
|
|
||||||
|
//Todo: update this shit.
|
||||||
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
[FieldDefinition(5, Label = "Recent Priority", Type = FieldType.Select, SelectOptions = typeof(QBittorrentPriority), HelpText = "Priority to use when grabbing episodes that aired within the last 14 days")]
|
||||||
public int RecentTvPriority { get; set; }
|
public int RecentTvPriority { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,27 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|||||||
// patch can be a number (releases) or 'x' (git)
|
// patch can be a number (releases) or 'x' (git)
|
||||||
private static readonly Regex VersionRegex = new Regex(@"(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+|x)(?<candidate>.*)", RegexOptions.Compiled);
|
private static readonly Regex VersionRegex = new Regex(@"(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+|x)(?<candidate>.*)", RegexOptions.Compiled);
|
||||||
|
|
||||||
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent)
|
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents)
|
||||||
{
|
{
|
||||||
var category = Settings.TvCategory;
|
var category = Settings.TvCategory;
|
||||||
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||||
|
|
||||||
|
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
||||||
|
|
||||||
var response = _proxy.DownloadNzb(fileContent, filename, category, priority, Settings);
|
if (response != null && response.Ids.Any())
|
||||||
|
{
|
||||||
|
return response.Ids.First();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
|
||||||
|
{
|
||||||
|
var category = Settings.TvCategory;
|
||||||
|
var priority = Settings.RecentTvPriority;
|
||||||
|
|
||||||
|
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
||||||
|
|
||||||
if (response != null && response.Ids.Any())
|
if (response != null && response.Ids.Any())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnsureThat;
|
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
|
|||||||
@@ -57,12 +57,17 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
|
||||||
|
var parsedMovieInfo = Parser.Parser.ParseMovieTitle(trackedDownload.DownloadItem.Title);
|
||||||
var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId);
|
var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId);
|
||||||
|
|
||||||
|
if (parsedMovieInfo != null)
|
||||||
|
{
|
||||||
|
trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null);
|
||||||
|
}
|
||||||
|
|
||||||
if (parsedEpisodeInfo != null)
|
if (parsedEpisodeInfo != null)
|
||||||
{
|
{
|
||||||
trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
|
trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0);
|
||||||
trackedDownload.RemoteMovie = _parsingService.Map(parsedEpisodeInfo, "", null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (historyItems.Any())
|
if (historyItems.Any())
|
||||||
|
|||||||
@@ -30,12 +30,9 @@ namespace NzbDrone.Core.Download
|
|||||||
|
|
||||||
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
|
||||||
|
|
||||||
protected abstract string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent);
|
protected abstract string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents);
|
||||||
|
|
||||||
protected virtual string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
|
protected abstract string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents);
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Download(RemoteEpisode remoteEpisode)
|
public override string Download(RemoteEpisode remoteEpisode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace NzbDrone.Core.History
|
|||||||
public class HistoryService : IHistoryService,
|
public class HistoryService : IHistoryService,
|
||||||
IHandle<EpisodeGrabbedEvent>,
|
IHandle<EpisodeGrabbedEvent>,
|
||||||
IHandle<MovieGrabbedEvent>,
|
IHandle<MovieGrabbedEvent>,
|
||||||
|
IHandle<MovieImportedEvent>,
|
||||||
IHandle<EpisodeImportedEvent>,
|
IHandle<EpisodeImportedEvent>,
|
||||||
IHandle<DownloadFailedEvent>,
|
IHandle<DownloadFailedEvent>,
|
||||||
IHandle<EpisodeFileDeletedEvent>,
|
IHandle<EpisodeFileDeletedEvent>,
|
||||||
@@ -186,7 +187,7 @@ namespace NzbDrone.Core.History
|
|||||||
{
|
{
|
||||||
EventType = HistoryEventType.Grabbed,
|
EventType = HistoryEventType.Grabbed,
|
||||||
Date = DateTime.UtcNow,
|
Date = DateTime.UtcNow,
|
||||||
Quality = message.Movie.ParsedEpisodeInfo.Quality,
|
Quality = message.Movie.ParsedMovieInfo.Quality,
|
||||||
SourceTitle = message.Movie.Release.Title,
|
SourceTitle = message.Movie.Release.Title,
|
||||||
SeriesId = 0,
|
SeriesId = 0,
|
||||||
EpisodeId = 0,
|
EpisodeId = 0,
|
||||||
@@ -196,7 +197,7 @@ namespace NzbDrone.Core.History
|
|||||||
|
|
||||||
history.Data.Add("Indexer", message.Movie.Release.Indexer);
|
history.Data.Add("Indexer", message.Movie.Release.Indexer);
|
||||||
history.Data.Add("NzbInfoUrl", message.Movie.Release.InfoUrl);
|
history.Data.Add("NzbInfoUrl", message.Movie.Release.InfoUrl);
|
||||||
history.Data.Add("ReleaseGroup", message.Movie.ParsedEpisodeInfo.ReleaseGroup);
|
history.Data.Add("ReleaseGroup", message.Movie.ParsedMovieInfo.ReleaseGroup);
|
||||||
history.Data.Add("Age", message.Movie.Release.Age.ToString());
|
history.Data.Add("Age", message.Movie.Release.Age.ToString());
|
||||||
history.Data.Add("AgeHours", message.Movie.Release.AgeHours.ToString());
|
history.Data.Add("AgeHours", message.Movie.Release.AgeHours.ToString());
|
||||||
history.Data.Add("AgeMinutes", message.Movie.Release.AgeMinutes.ToString());
|
history.Data.Add("AgeMinutes", message.Movie.Release.AgeMinutes.ToString());
|
||||||
@@ -209,9 +210,9 @@ namespace NzbDrone.Core.History
|
|||||||
history.Data.Add("TvRageId", message.Movie.Release.TvRageId.ToString());
|
history.Data.Add("TvRageId", message.Movie.Release.TvRageId.ToString());
|
||||||
history.Data.Add("Protocol", ((int)message.Movie.Release.DownloadProtocol).ToString());
|
history.Data.Add("Protocol", ((int)message.Movie.Release.DownloadProtocol).ToString());
|
||||||
|
|
||||||
if (!message.Movie.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace())
|
if (!message.Movie.ParsedMovieInfo.ReleaseHash.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
history.Data.Add("ReleaseHash", message.Movie.ParsedEpisodeInfo.ReleaseHash);
|
history.Data.Add("ReleaseHash", message.Movie.ParsedMovieInfo.ReleaseHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
var torrentRelease = message.Movie.Release as TorrentInfo;
|
var torrentRelease = message.Movie.Release as TorrentInfo;
|
||||||
@@ -264,6 +265,45 @@ namespace NzbDrone.Core.History
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieImportedEvent message)
|
||||||
|
{
|
||||||
|
if (!message.NewDownload)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var downloadId = message.DownloadId;
|
||||||
|
|
||||||
|
if (downloadId.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
//downloadId = FindDownloadId(message); For now fuck off.
|
||||||
|
}
|
||||||
|
|
||||||
|
var movie = message.MovieInfo.Movie;
|
||||||
|
var history = new History
|
||||||
|
{
|
||||||
|
EventType = HistoryEventType.DownloadFolderImported,
|
||||||
|
Date = DateTime.UtcNow,
|
||||||
|
Quality = message.MovieInfo.Quality,
|
||||||
|
SourceTitle = movie.Title,
|
||||||
|
SeriesId = 0,
|
||||||
|
EpisodeId = 0,
|
||||||
|
DownloadId = downloadId,
|
||||||
|
MovieId = movie.Id,
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//Won't have a value since we publish this event before saving to DB.
|
||||||
|
//history.Data.Add("FileId", message.ImportedEpisode.Id.ToString());
|
||||||
|
history.Data.Add("DroppedPath", message.MovieInfo.Path);
|
||||||
|
history.Data.Add("ImportedPath", Path.Combine(movie.Path, message.ImportedMovie.RelativePath));
|
||||||
|
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||||
|
|
||||||
|
_historyRepository.Insert(history);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(DownloadFailedEvent message)
|
public void Handle(DownloadFailedEvent message)
|
||||||
{
|
{
|
||||||
foreach (var episodeId in message.EpisodeIds)
|
foreach (var episodeId in message.EpisodeIds)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -249,15 +249,15 @@ namespace NzbDrone.Core.IndexerSearch
|
|||||||
|
|
||||||
private TSpec Get<TSpec>(Series series, List<Episode> episodes, bool userInvokedSearch) where TSpec : SearchCriteriaBase, new()
|
private TSpec Get<TSpec>(Series series, List<Episode> episodes, bool userInvokedSearch) where TSpec : SearchCriteriaBase, new()
|
||||||
{
|
{
|
||||||
var spec = new TSpec();
|
var spec = new TSpec()
|
||||||
|
{
|
||||||
spec.Series = series;
|
Series = series,
|
||||||
spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
|
SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
|
||||||
episodes.Select(e => e.SeasonNumber).Distinct().ToList(),
|
episodes.Select(e => e.SeasonNumber).Distinct().ToList(),
|
||||||
episodes.Select(e => e.SceneSeasonNumber ?? e.SeasonNumber).Distinct().ToList());
|
episodes.Select(e => e.SceneSeasonNumber ?? e.SeasonNumber).Distinct().ToList()),
|
||||||
|
|
||||||
spec.Episodes = episodes;
|
|
||||||
|
|
||||||
|
Episodes = episodes
|
||||||
|
};
|
||||||
spec.SceneTitles.Add(series.Title);
|
spec.SceneTitles.Add(series.Title);
|
||||||
spec.UserInvokedSearch = userInvokedSearch;
|
spec.UserInvokedSearch = userInvokedSearch;
|
||||||
|
|
||||||
@@ -266,18 +266,18 @@ namespace NzbDrone.Core.IndexerSearch
|
|||||||
|
|
||||||
private TSpec Get<TSpec>(Movie movie, bool userInvokedSearch) where TSpec : SearchCriteriaBase, new()
|
private TSpec Get<TSpec>(Movie movie, bool userInvokedSearch) where TSpec : SearchCriteriaBase, new()
|
||||||
{
|
{
|
||||||
var spec = new TSpec();
|
var spec = new TSpec()
|
||||||
|
{
|
||||||
|
Movie = movie,
|
||||||
|
/*spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
|
||||||
|
episodes.Select(e => e.SeasonNumber).Distinct().ToList(),
|
||||||
|
episodes.Select(e => e.SceneSeasonNumber ?? e.SeasonNumber).Distinct().ToList());
|
||||||
|
|
||||||
spec.Movie = movie;
|
spec.Episodes = episodes;
|
||||||
/*spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
|
|
||||||
episodes.Select(e => e.SeasonNumber).Distinct().ToList(),
|
|
||||||
episodes.Select(e => e.SceneSeasonNumber ?? e.SeasonNumber).Distinct().ToList());
|
|
||||||
|
|
||||||
spec.Episodes = episodes;
|
|
||||||
|
|
||||||
spec.SceneTitles.Add(series.Title);*/
|
|
||||||
spec.UserInvokedSearch = userInvokedSearch;
|
|
||||||
|
|
||||||
|
spec.SceneTitles.Add(series.Title);*/
|
||||||
|
UserInvokedSearch = userInvokedSearch
|
||||||
|
};
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,8 +106,8 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (capabilities.SupportedTvSearchParameters != null &&
|
if (capabilities.SupportedTvSearchParameters != null &&
|
||||||
new[] { "q", "tvdbid", "rid" }.Any(v => capabilities.SupportedTvSearchParameters.Contains(v)) &&
|
new[] { "q", "imdb" }.Any(v => capabilities.SupportedMovieSearchParamters.Contains(v)) &&
|
||||||
new[] { "season", "ep" }.All(v => capabilities.SupportedTvSearchParameters.Contains(v)))
|
new[] { "imdbtitle", "imdbyear" }.All(v => capabilities.SupportedMovieSearchParamters.Contains(v)))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
public int MaxPageSize { get; set; }
|
public int MaxPageSize { get; set; }
|
||||||
public string[] SupportedSearchParameters { get; set; }
|
public string[] SupportedSearchParameters { get; set; }
|
||||||
public string[] SupportedTvSearchParameters { get; set; }
|
public string[] SupportedTvSearchParameters { get; set; }
|
||||||
|
public string[] SupportedMovieSearchParamters { get; set; }
|
||||||
public bool SupportsAggregateIdSearch { get; set; }
|
public bool SupportsAggregateIdSearch { get; set; }
|
||||||
public List<NewznabCategory> Categories { get; set; }
|
public List<NewznabCategory> Categories { get; set; }
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
DefaultPageSize = 100;
|
DefaultPageSize = 100;
|
||||||
MaxPageSize = 100;
|
MaxPageSize = 100;
|
||||||
SupportedSearchParameters = new[] { "q" };
|
SupportedSearchParameters = new[] { "q" };
|
||||||
|
SupportedMovieSearchParamters = new[] { "q", "imdb", "imdbtitle", "imdbyear" };
|
||||||
SupportedTvSearchParameters = new[] { "q", "rid", "season", "ep" }; // This should remain 'rid' for older newznab installs.
|
SupportedTvSearchParameters = new[] { "q", "rid", "season", "ep" }; // This should remain 'rid' for older newznab installs.
|
||||||
SupportsAggregateIdSearch = false;
|
SupportsAggregateIdSearch = false;
|
||||||
Categories = new List<NewznabCategory>();
|
Categories = new List<NewznabCategory>();
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
public NewznabCapabilities GetCapabilities(NewznabSettings indexerSettings)
|
public NewznabCapabilities GetCapabilities(NewznabSettings indexerSettings)
|
||||||
{
|
{
|
||||||
var key = indexerSettings.ToJson();
|
var key = indexerSettings.ToJson();
|
||||||
|
_capabilitiesCache.Clear();
|
||||||
var capabilities = _capabilitiesCache.Get(key, () => FetchCapabilities(indexerSettings), TimeSpan.FromDays(7));
|
var capabilities = _capabilitiesCache.Get(key, () => FetchCapabilities(indexerSettings), TimeSpan.FromDays(7));
|
||||||
|
|
||||||
return capabilities;
|
return capabilities;
|
||||||
@@ -98,6 +99,16 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
capabilities.SupportedTvSearchParameters = xmlTvSearch.Attribute("supportedParams").Value.Split(',');
|
capabilities.SupportedTvSearchParameters = xmlTvSearch.Attribute("supportedParams").Value.Split(',');
|
||||||
capabilities.SupportsAggregateIdSearch = true;
|
capabilities.SupportsAggregateIdSearch = true;
|
||||||
}
|
}
|
||||||
|
var xmlMovieSearch = xmlSearching.Element("movie-search");
|
||||||
|
if (xmlMovieSearch == null || xmlMovieSearch.Attribute("available").Value != "yes")
|
||||||
|
{
|
||||||
|
capabilities.SupportedMovieSearchParamters = null;
|
||||||
|
}
|
||||||
|
else if (xmlMovieSearch.Attribute("supportedParams") != null)
|
||||||
|
{
|
||||||
|
capabilities.SupportedMovieSearchParamters = xmlMovieSearch.Attribute("supportedParams").Value.Split(',');
|
||||||
|
capabilities.SupportsAggregateIdSearch = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var xmlCategories = xmlRoot.Element("categories");
|
var xmlCategories = xmlRoot.Element("categories");
|
||||||
|
|||||||
@@ -85,6 +85,17 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool SupportsMovieSearch
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var capabilities = _capabilitiesProvider.GetCapabilities(Settings);
|
||||||
|
|
||||||
|
return capabilities.SupportedMovieSearchParamters != null &&
|
||||||
|
capabilities.SupportedMovieSearchParamters.Contains("imdb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool SupportsAggregatedIdSearch
|
private bool SupportsAggregatedIdSearch
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -109,6 +120,25 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
return pageableRequests;
|
return pageableRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
var pageableRequests = new IndexerPageableRequestChain();
|
||||||
|
|
||||||
|
if(SupportsMovieSearch)
|
||||||
|
{
|
||||||
|
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "movie",
|
||||||
|
string.Format("&imdbid={0}", searchCriteria.Movie.ImdbId.Substring(2)))); //strip off the "tt" - VERY HACKY
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Let's try anyways with q parameter, worst case nothing found.
|
||||||
|
pageableRequests.Add(GetPagedRequests(MaxPages, Settings.Categories, "search",
|
||||||
|
string.Format("&q={0}", searchCriteria.Movie.Title)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return pageableRequests;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual IndexerPageableRequestChain GetSearchRequests(SingleEpisodeSearchCriteria searchCriteria)
|
public virtual IndexerPageableRequestChain GetSearchRequests(SingleEpisodeSearchCriteria searchCriteria)
|
||||||
{
|
{
|
||||||
var pageableRequests = new IndexerPageableRequestChain();
|
var pageableRequests = new IndexerPageableRequestChain();
|
||||||
@@ -274,10 +304,5 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
{
|
{
|
||||||
return title.Replace("+", "%20");
|
return title.Replace("+", "%20");
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
|
||||||
{
|
|
||||||
return new IndexerPageableRequestChain();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
@@ -60,7 +60,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||||||
|
|
||||||
public NewznabSettings()
|
public NewznabSettings()
|
||||||
{
|
{
|
||||||
Categories = new[] { 5030, 5040 };
|
Categories = new[] { 2030, 2040, 2050 };
|
||||||
AnimeCategories = Enumerable.Empty<int>();
|
AnimeCategories = Enumerable.Empty<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ namespace NzbDrone.Core.MetadataSource
|
|||||||
public interface IProvideMovieInfo
|
public interface IProvideMovieInfo
|
||||||
{
|
{
|
||||||
Movie GetMovieInfo(string ImdbId);
|
Movie GetMovieInfo(string ImdbId);
|
||||||
|
Movie GetMovieInfo(int TmdbId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ConfigResource
|
||||||
|
{
|
||||||
|
public Images images { get; set; }
|
||||||
|
public string[] change_keys { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Images
|
||||||
|
{
|
||||||
|
public string base_url { get; set; }
|
||||||
|
public string secure_base_url { get; set; }
|
||||||
|
public string[] backdrop_sizes { get; set; }
|
||||||
|
public string[] logo_sizes { get; set; }
|
||||||
|
public string[] poster_sizes { get; set; }
|
||||||
|
public string[] profile_sizes { get; set; }
|
||||||
|
public string[] still_sizes { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
public class MovieSearchRoot
|
||||||
|
{
|
||||||
|
public int page { get; set; }
|
||||||
|
public MovieResult[] results { get; set; }
|
||||||
|
public int total_results { get; set; }
|
||||||
|
public int total_pages { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MovieResult
|
||||||
|
{
|
||||||
|
public string poster_path { get; set; }
|
||||||
|
public bool adult { get; set; }
|
||||||
|
public string overview { get; set; }
|
||||||
|
public string release_date { get; set; }
|
||||||
|
public int?[] genre_ids { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
public string original_title { get; set; }
|
||||||
|
public string original_language { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
public string backdrop_path { get; set; }
|
||||||
|
public float popularity { get; set; }
|
||||||
|
public int vote_count { get; set; }
|
||||||
|
public bool video { get; set; }
|
||||||
|
public float vote_average { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class MovieResourceRoot
|
||||||
|
{
|
||||||
|
public bool adult { get; set; }
|
||||||
|
public string backdrop_path { get; set; }
|
||||||
|
public Belongs_To_Collection belongs_to_collection { get; set; }
|
||||||
|
public int budget { get; set; }
|
||||||
|
public Genre[] genres { get; set; }
|
||||||
|
public string homepage { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
public string imdb_id { get; set; }
|
||||||
|
public string original_language { get; set; }
|
||||||
|
public string original_title { get; set; }
|
||||||
|
public string overview { get; set; }
|
||||||
|
public float popularity { get; set; }
|
||||||
|
public string poster_path { get; set; }
|
||||||
|
public Production_Companies[] production_companies { get; set; }
|
||||||
|
public Production_Countries[] production_countries { get; set; }
|
||||||
|
public string release_date { get; set; }
|
||||||
|
public int revenue { get; set; }
|
||||||
|
public int runtime { get; set; }
|
||||||
|
public Spoken_Languages[] spoken_languages { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
public string tagline { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
public bool video { get; set; }
|
||||||
|
public float vote_average { get; set; }
|
||||||
|
public int vote_count { get; set; }
|
||||||
|
public AlternativeTitles alternative_titles { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Belongs_To_Collection
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
public string poster_path { get; set; }
|
||||||
|
public string backdrop_path { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Genre
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Production_Companies
|
||||||
|
{
|
||||||
|
public string name { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Production_Countries
|
||||||
|
{
|
||||||
|
public string iso_3166_1 { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Spoken_Languages
|
||||||
|
{
|
||||||
|
public string iso_639_1 { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AlternativeTitles
|
||||||
|
{
|
||||||
|
public List<Title> titles { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Title
|
||||||
|
{
|
||||||
|
public string iso_3166_1 { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ using NzbDrone.Common.Http;
|
|||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||||
|
using NzbDrone.Core.MetadataSource;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -20,11 +21,15 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private readonly IHttpRequestBuilderFactory _requestBuilder;
|
private readonly IHttpRequestBuilderFactory _requestBuilder;
|
||||||
|
private readonly IHttpRequestBuilderFactory _movieBuilder;
|
||||||
|
private readonly ITmdbConfigService _configService;
|
||||||
|
|
||||||
public SkyHookProxy(IHttpClient httpClient, ISonarrCloudRequestBuilder requestBuilder, Logger logger)
|
public SkyHookProxy(IHttpClient httpClient, ISonarrCloudRequestBuilder requestBuilder, ITmdbConfigService configService, Logger logger)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_requestBuilder = requestBuilder.SkyHookTvdb;
|
_requestBuilder = requestBuilder.SkyHookTvdb;
|
||||||
|
_movieBuilder = requestBuilder.TMDB;
|
||||||
|
_configService = configService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +63,65 @@ 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)
|
||||||
|
{
|
||||||
|
var request = _movieBuilder.Create()
|
||||||
|
.SetSegment("route", "movie")
|
||||||
|
.SetSegment("id", TmdbId.ToString())
|
||||||
|
.SetSegment("secondaryRoute", "")
|
||||||
|
.AddQueryParam("append_to_response", "alternative_titles")
|
||||||
|
.AddQueryParam("country", "US")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
request.AllowAutoRedirect = true;
|
||||||
|
request.SuppressHttpError = true;
|
||||||
|
|
||||||
|
var response = _httpClient.Get<MovieResourceRoot>(request);
|
||||||
|
|
||||||
|
var resource = response.Resource;
|
||||||
|
|
||||||
|
var movie = new Movie();
|
||||||
|
|
||||||
|
movie.TmdbId = TmdbId;
|
||||||
|
movie.ImdbId = resource.imdb_id;
|
||||||
|
movie.Title = resource.title;
|
||||||
|
movie.TitleSlug = movie.Title.ToLower().Replace(" ", "-");
|
||||||
|
movie.CleanTitle = Parser.Parser.CleanSeriesTitle(movie.Title);
|
||||||
|
movie.Overview = resource.overview;
|
||||||
|
movie.Website = resource.homepage;
|
||||||
|
movie.InCinemas = DateTime.Parse(resource.release_date);
|
||||||
|
movie.Year = movie.InCinemas.Value.Year;
|
||||||
|
|
||||||
|
movie.Images.Add(_configService.GetCoverForURL(resource.poster_path, MediaCoverTypes.Poster));//TODO: Update to load image specs from tmdb page!
|
||||||
|
movie.Images.Add(_configService.GetCoverForURL(resource.backdrop_path, MediaCoverTypes.Banner));
|
||||||
|
movie.Runtime = resource.runtime;
|
||||||
|
|
||||||
|
foreach(Title title in resource.alternative_titles.titles)
|
||||||
|
{
|
||||||
|
movie.AlternativeTitles.Add(title.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
movie.Ratings = new Ratings();
|
||||||
|
movie.Ratings.Votes = resource.vote_count;
|
||||||
|
movie.Ratings.Value = (decimal)resource.vote_average;
|
||||||
|
|
||||||
|
foreach(Genre genre in resource.genres)
|
||||||
|
{
|
||||||
|
movie.Genres.Add(genre.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource.status == "Released")
|
||||||
|
{
|
||||||
|
movie.Status = MovieStatusType.Released;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
movie.Status = MovieStatusType.Announced;
|
||||||
|
}
|
||||||
|
|
||||||
|
return movie;
|
||||||
|
}
|
||||||
|
|
||||||
public Movie GetMovieInfo(string ImdbId)
|
public Movie GetMovieInfo(string ImdbId)
|
||||||
{
|
{
|
||||||
var imdbRequest = new HttpRequest("http://www.omdbapi.com/?i=" + ImdbId + "&plot=full&r=json");
|
var imdbRequest = new HttpRequest("http://www.omdbapi.com/?i=" + ImdbId + "&plot=full&r=json");
|
||||||
@@ -136,11 +200,22 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var searchTerm = lowerTitle.Replace("+", "_").Replace(" ", "_");
|
var searchTerm = lowerTitle.Replace("_", "+").Replace(" ", "+");
|
||||||
|
|
||||||
var firstChar = searchTerm.First();
|
var firstChar = searchTerm.First();
|
||||||
|
|
||||||
var imdbRequest = new HttpRequest("https://v2.sg.media-imdb.com/suggests/" + firstChar + "/" + searchTerm + ".json");
|
var request = _movieBuilder.Create()
|
||||||
|
.SetSegment("route", "search")
|
||||||
|
.SetSegment("id", "movie")
|
||||||
|
.SetSegment("secondaryRoute", "")
|
||||||
|
.AddQueryParam("query", searchTerm)
|
||||||
|
.AddQueryParam("include_adult", false)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
request.AllowAutoRedirect = true;
|
||||||
|
request.SuppressHttpError = true;
|
||||||
|
|
||||||
|
/*var imdbRequest = new HttpRequest("https://v2.sg.media-imdb.com/suggests/" + firstChar + "/" + searchTerm + ".json");
|
||||||
|
|
||||||
var response = _httpClient.Get(imdbRequest);
|
var response = _httpClient.Get(imdbRequest);
|
||||||
|
|
||||||
@@ -154,31 +229,36 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||||||
|
|
||||||
_logger.Warn("Json object: " + json);
|
_logger.Warn("Json object: " + json);
|
||||||
|
|
||||||
_logger.Warn("Crash ahead.");
|
_logger.Warn("Crash ahead.");*/
|
||||||
|
|
||||||
|
var response = _httpClient.Get<MovieSearchRoot>(request);
|
||||||
|
|
||||||
|
var movieResults = response.Resource.results;
|
||||||
|
|
||||||
var imdbMovies = new List<Movie>();
|
var imdbMovies = new List<Movie>();
|
||||||
|
|
||||||
foreach (MovieResource entry in json.d)
|
foreach (MovieResult result in movieResults)
|
||||||
{
|
{
|
||||||
var imdbMovie = new Movie();
|
var imdbMovie = new Movie();
|
||||||
imdbMovie.ImdbId = entry.id;
|
imdbMovie.TmdbId = result.id;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
imdbMovie.SortTitle = entry.l;
|
imdbMovie.SortTitle = result.title;
|
||||||
imdbMovie.Title = entry.l;
|
imdbMovie.Title = result.title;
|
||||||
string titleSlug = entry.l;
|
string titleSlug = result.title;
|
||||||
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
||||||
imdbMovie.Year = entry.y;
|
imdbMovie.Year = DateTime.Parse(result.release_date).Year;
|
||||||
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
||||||
|
imdbMovie.Overview = result.overview;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string url = (string)entry.i[0];
|
string url = result.poster_path;
|
||||||
var imdbPoster = new MediaCover.MediaCover(MediaCoverTypes.Poster, url);
|
var imdbPoster = _configService.GetCoverForURL(result.poster_path, MediaCoverTypes.Poster);
|
||||||
imdbMovie.Images.Add(imdbPoster);
|
imdbMovie.Images.Add(imdbPoster);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Debug(entry);
|
_logger.Debug(result);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
77
src/NzbDrone.Core/MetadataSource/TmdbConfigurationService.cs
Normal file
77
src/NzbDrone.Core/MetadataSource/TmdbConfigurationService.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using NzbDrone.Core.MediaCover;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Common.Cloud;
|
||||||
|
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MetadataSource
|
||||||
|
{
|
||||||
|
public interface ITmdbConfigService
|
||||||
|
{
|
||||||
|
MediaCover.MediaCover GetCoverForURL(string url, MediaCover.MediaCoverTypes type);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TmdbConfigService : ITmdbConfigService
|
||||||
|
{
|
||||||
|
private readonly ICached<ConfigResource> _configurationCache;
|
||||||
|
private readonly IHttpClient _httpClient;
|
||||||
|
private readonly IHttpRequestBuilderFactory _tmdbBuilder;
|
||||||
|
|
||||||
|
public TmdbConfigService(ICacheManager cacheManager, IHttpClient httpClient, ISonarrCloudRequestBuilder requestBuilder)
|
||||||
|
{
|
||||||
|
_configurationCache = cacheManager.GetCache<ConfigResource>(GetType(), "configuration_cache");
|
||||||
|
_httpClient = httpClient;
|
||||||
|
_tmdbBuilder = requestBuilder.TMDBSingle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaCover.MediaCover GetCoverForURL(string url, MediaCover.MediaCoverTypes type)
|
||||||
|
{
|
||||||
|
if (_configurationCache.Count == 0)
|
||||||
|
{
|
||||||
|
RefreshCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
var images = _configurationCache.Find("configuration").images;
|
||||||
|
|
||||||
|
var cover = new MediaCover.MediaCover();
|
||||||
|
cover.CoverType = type;
|
||||||
|
|
||||||
|
var realUrl = images.base_url;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MediaCoverTypes.Banner:
|
||||||
|
realUrl += images.backdrop_sizes.Last();
|
||||||
|
break;
|
||||||
|
case MediaCoverTypes.Poster:
|
||||||
|
realUrl += images.poster_sizes.Last();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
realUrl += "original";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
realUrl += url;
|
||||||
|
|
||||||
|
cover.Url = realUrl;
|
||||||
|
|
||||||
|
return cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshCache()
|
||||||
|
{
|
||||||
|
var request = _tmdbBuilder.Create().SetSegment("route", "configuration").Build();
|
||||||
|
|
||||||
|
var response = _httpClient.Get<ConfigResource>(request);
|
||||||
|
|
||||||
|
if (response.Resource.images != null)
|
||||||
|
{
|
||||||
|
_configurationCache.Set("configuration", response.Resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -183,6 +183,8 @@
|
|||||||
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
||||||
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
||||||
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\107_fix_movie_files.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\106_add_tmdb_stuff.cs" />
|
||||||
<Compile Include="Datastore\Migration\105_fix_history_movieId.cs" />
|
<Compile Include="Datastore\Migration\105_fix_history_movieId.cs" />
|
||||||
<Compile Include="Datastore\Migration\005_added_eventtype_to_history.cs" />
|
<Compile Include="Datastore\Migration\005_added_eventtype_to_history.cs" />
|
||||||
<Compile Include="Datastore\Migration\006_add_index_to_log_time.cs" />
|
<Compile Include="Datastore\Migration\006_add_index_to_log_time.cs" />
|
||||||
@@ -804,6 +806,7 @@
|
|||||||
<Compile Include="MetadataSource\IProvideMovieInfo.cs" />
|
<Compile Include="MetadataSource\IProvideMovieInfo.cs" />
|
||||||
<Compile Include="MetadataSource\ISearchForNewMovie.cs" />
|
<Compile Include="MetadataSource\ISearchForNewMovie.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ActorResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\ActorResource.cs" />
|
||||||
|
<Compile Include="MetadataSource\SkyHook\Resource\ConfigurationResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\EpisodeResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\EpisodeResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ImageResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\ImageResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\RatingResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\RatingResource.cs" />
|
||||||
@@ -811,6 +814,7 @@
|
|||||||
<Compile Include="MetadataSource\SkyHook\Resource\MovieResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\MovieResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ShowResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\ShowResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\TimeOfDayResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\TimeOfDayResource.cs" />
|
||||||
|
<Compile Include="MetadataSource\SkyHook\Resource\TMDBResources.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\SkyHookProxy.cs" />
|
<Compile Include="MetadataSource\SkyHook\SkyHookProxy.cs" />
|
||||||
<Compile Include="MetadataSource\SearchSeriesComparer.cs" />
|
<Compile Include="MetadataSource\SearchSeriesComparer.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\SkyHookException.cs" />
|
<Compile Include="MetadataSource\SkyHook\SkyHookException.cs" />
|
||||||
@@ -835,6 +839,7 @@
|
|||||||
<Compile Include="Extras\Metadata\MetadataType.cs" />
|
<Compile Include="Extras\Metadata\MetadataType.cs" />
|
||||||
<Compile Include="MetadataSource\IProvideSeriesInfo.cs" />
|
<Compile Include="MetadataSource\IProvideSeriesInfo.cs" />
|
||||||
<Compile Include="MetadataSource\ISearchForNewSeries.cs" />
|
<Compile Include="MetadataSource\ISearchForNewSeries.cs" />
|
||||||
|
<Compile Include="MetadataSource\TmdbConfigurationService.cs" />
|
||||||
<Compile Include="Notifications\Join\JoinAuthException.cs" />
|
<Compile Include="Notifications\Join\JoinAuthException.cs" />
|
||||||
<Compile Include="Notifications\Join\JoinInvalidDeviceException.cs" />
|
<Compile Include="Notifications\Join\JoinInvalidDeviceException.cs" />
|
||||||
<Compile Include="Notifications\Join\JoinResponseModel.cs" />
|
<Compile Include="Notifications\Join\JoinResponseModel.cs" />
|
||||||
@@ -891,6 +896,7 @@
|
|||||||
<Compile Include="Parser\IsoLanguages.cs" />
|
<Compile Include="Parser\IsoLanguages.cs" />
|
||||||
<Compile Include="Parser\LanguageParser.cs" />
|
<Compile Include="Parser\LanguageParser.cs" />
|
||||||
<Compile Include="Parser\Model\LocalMovie.cs" />
|
<Compile Include="Parser\Model\LocalMovie.cs" />
|
||||||
|
<Compile Include="Parser\Model\ParsedMovieInfo.cs" />
|
||||||
<Compile Include="Parser\Model\RemoteMovie.cs" />
|
<Compile Include="Parser\Model\RemoteMovie.cs" />
|
||||||
<Compile Include="Profiles\Delay\DelayProfile.cs" />
|
<Compile Include="Profiles\Delay\DelayProfile.cs" />
|
||||||
<Compile Include="Profiles\Delay\DelayProfileService.cs" />
|
<Compile Include="Profiles\Delay\DelayProfileService.cs" />
|
||||||
|
|||||||
@@ -346,7 +346,9 @@ namespace NzbDrone.Core.Organizer
|
|||||||
public static string CleanFolderName(string name)
|
public static string CleanFolderName(string name)
|
||||||
{
|
{
|
||||||
name = FileNameCleanupRegex.Replace(name, match => match.Captures[0].Value[0].ToString());
|
name = FileNameCleanupRegex.Replace(name, match => match.Captures[0].Value[0].ToString());
|
||||||
return name.Trim(' ', '.');
|
name = name.Trim(' ', '.');
|
||||||
|
|
||||||
|
return CleanFileName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddSeriesTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Series series)
|
private void AddSeriesTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Series series)
|
||||||
|
|||||||
31
src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs
Normal file
31
src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Parser.Model
|
||||||
|
{
|
||||||
|
public class ParsedMovieInfo
|
||||||
|
{
|
||||||
|
public string MovieTitle { get; set; }
|
||||||
|
public SeriesTitleInfo MovieTitleInfo { get; set; }
|
||||||
|
public QualityModel Quality { get; set; }
|
||||||
|
public int SeasonNumber { get; set; }
|
||||||
|
public Language Language { get; set; }
|
||||||
|
public bool FullSeason { get; set; }
|
||||||
|
public bool Special { get; set; }
|
||||||
|
public string ReleaseGroup { get; set; }
|
||||||
|
public string ReleaseHash { get; set; }
|
||||||
|
public string Edition { get; set;}
|
||||||
|
public int Year { get; set; }
|
||||||
|
|
||||||
|
public ParsedMovieInfo()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("{0} - {1} {2}", MovieTitle, MovieTitleInfo.Year, Quality);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ namespace NzbDrone.Core.Parser.Model
|
|||||||
{
|
{
|
||||||
public ReleaseInfo Release { get; set; }
|
public ReleaseInfo Release { get; set; }
|
||||||
public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; } //TODO: Change to ParsedMovieInfo, for now though ParsedEpisodeInfo will do.
|
public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; } //TODO: Change to ParsedMovieInfo, for now though ParsedEpisodeInfo will do.
|
||||||
|
public ParsedMovieInfo ParsedMovieInfo { get; set; }
|
||||||
public Movie Movie { get; set; }
|
public Movie Movie { get; set; }
|
||||||
public bool DownloadAllowed { get; set; }
|
public bool DownloadAllowed { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,26 @@ namespace NzbDrone.Core.Parser
|
|||||||
{
|
{
|
||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(Parser));
|
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(Parser));
|
||||||
|
|
||||||
|
private static readonly Regex[] ReportMovieTitleRegex = new[]
|
||||||
|
{
|
||||||
|
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.Special.Edition.2011
|
||||||
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<edition>(\w+\.?edition))\.(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition //TODO: Seems to slow down parsing heavily!
|
||||||
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}edition))",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
//Cut Movies, e.g: Mission.Impossible.3.Directors.Cut.2011
|
||||||
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<edition>(\w+\.?cut))\.(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
//Cut Movies, e.g: Mission.Impossible.3.2011.Directors.Cut
|
||||||
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}cut))",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
//Normal movie format, e.g: Mission.Impossible.3.2011
|
||||||
|
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
};
|
||||||
|
|
||||||
private static readonly Regex[] ReportTitleRegex = new[]
|
private static readonly Regex[] ReportTitleRegex = new[]
|
||||||
{
|
{
|
||||||
//Anime - Absolute Episode Number + Title + Season+Episode
|
//Anime - Absolute Episode Number + Title + Season+Episode
|
||||||
@@ -298,6 +318,96 @@ namespace NzbDrone.Core.Parser
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ParsedMovieInfo ParseMovieTitle(string title)
|
||||||
|
{
|
||||||
|
|
||||||
|
ParsedMovieInfo realResult = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!ValidateBeforeParsing(title)) return null;
|
||||||
|
|
||||||
|
title = title.Replace(" ", "."); //TODO: Determine if this breaks something. However, it shouldn't.
|
||||||
|
|
||||||
|
Logger.Debug("Parsing string '{0}'", title);
|
||||||
|
|
||||||
|
if (ReversedTitleRegex.IsMatch(title))
|
||||||
|
{
|
||||||
|
var titleWithoutExtension = RemoveFileExtension(title).ToCharArray();
|
||||||
|
Array.Reverse(titleWithoutExtension);
|
||||||
|
|
||||||
|
title = new string(titleWithoutExtension) + title.Substring(titleWithoutExtension.Length);
|
||||||
|
|
||||||
|
Logger.Debug("Reversed name detected. Converted to '{0}'", title);
|
||||||
|
}
|
||||||
|
|
||||||
|
var simpleTitle = SimpleTitleRegex.Replace(title, string.Empty);
|
||||||
|
|
||||||
|
simpleTitle = RemoveFileExtension(simpleTitle);
|
||||||
|
|
||||||
|
// TODO: Quick fix stripping [url] - prefixes.
|
||||||
|
simpleTitle = WebsitePrefixRegex.Replace(simpleTitle, string.Empty);
|
||||||
|
|
||||||
|
simpleTitle = CleanTorrentSuffixRegex.Replace(simpleTitle, string.Empty);
|
||||||
|
|
||||||
|
foreach (var regex in ReportMovieTitleRegex)
|
||||||
|
{
|
||||||
|
var match = regex.Matches(simpleTitle);
|
||||||
|
|
||||||
|
if (match.Count != 0)
|
||||||
|
{
|
||||||
|
Logger.Trace(regex);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = ParseMovieMatchCollection(match);
|
||||||
|
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
result.Language = LanguageParser.ParseLanguage(title);
|
||||||
|
Logger.Debug("Language parsed: {0}", result.Language);
|
||||||
|
|
||||||
|
result.Quality = QualityParser.ParseQuality(title);
|
||||||
|
Logger.Debug("Quality parsed: {0}", result.Quality);
|
||||||
|
|
||||||
|
result.ReleaseGroup = ParseReleaseGroup(title);
|
||||||
|
|
||||||
|
var subGroup = GetSubGroup(match);
|
||||||
|
if (!subGroup.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
result.ReleaseGroup = subGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Debug("Release Group parsed: {0}", result.ReleaseGroup);
|
||||||
|
|
||||||
|
result.ReleaseHash = GetReleaseHash(match);
|
||||||
|
if (!result.ReleaseHash.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
Logger.Debug("Release Hash parsed: {0}", result.ReleaseHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
realResult = result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidDateException ex)
|
||||||
|
{
|
||||||
|
Logger.Debug(ex, ex.Message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (!title.ToLower().Contains("password") && !title.ToLower().Contains("yenc"))
|
||||||
|
Logger.Error(e, "An error has occurred while trying to parse " + title);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Debug("Unable to parse {0}", title);
|
||||||
|
return realResult;
|
||||||
|
}
|
||||||
|
|
||||||
public static ParsedEpisodeInfo ParseTitle(string title)
|
public static ParsedEpisodeInfo ParseTitle(string title)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -528,6 +638,31 @@ namespace NzbDrone.Core.Parser
|
|||||||
return seriesTitleInfo;
|
return seriesTitleInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection)
|
||||||
|
{
|
||||||
|
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
||||||
|
seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' ');
|
||||||
|
|
||||||
|
int airYear;
|
||||||
|
int.TryParse(matchCollection[0].Groups["year"].Value, out airYear);
|
||||||
|
|
||||||
|
ParsedMovieInfo result;
|
||||||
|
|
||||||
|
result = new ParsedMovieInfo { Year = airYear };
|
||||||
|
|
||||||
|
if (matchCollection[0].Groups["edition"].Success)
|
||||||
|
{
|
||||||
|
result.Edition = matchCollection[0].Groups["edition"].Value.Replace(".", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.MovieTitle = seriesName;
|
||||||
|
result.MovieTitleInfo = GetSeriesTitleInfo(result.MovieTitle);
|
||||||
|
|
||||||
|
Logger.Debug("Movie Parsed. {0}", result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchCollection)
|
private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchCollection)
|
||||||
{
|
{
|
||||||
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
Movie GetMovie(string title);
|
Movie GetMovie(string title);
|
||||||
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
||||||
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int seriesId, IEnumerable<int> episodeIds);
|
RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo, int seriesId, IEnumerable<int> episodeIds);
|
||||||
RemoteMovie Map(ParsedEpisodeInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
|
RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, SearchCriteriaBase searchCriteria = null);
|
||||||
List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null);
|
List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource, SearchCriteriaBase searchCriteria = null);
|
||||||
ParsedEpisodeInfo ParseSpecialEpisodeTitle(string title, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
ParsedEpisodeInfo ParseSpecialEpisodeTitle(string title, int tvdbId, int tvRageId, SearchCriteriaBase searchCriteria = null);
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,20 @@ namespace NzbDrone.Core.Parser
|
|||||||
private readonly ISceneMappingService _sceneMappingService;
|
private readonly ISceneMappingService _sceneMappingService;
|
||||||
private readonly IMovieService _movieService;
|
private readonly IMovieService _movieService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
private readonly Dictionary<string, string> romanNumeralsMapper = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "1", "I"},
|
||||||
|
{ "2", "II"},
|
||||||
|
{ "3", "III"},
|
||||||
|
{ "4", "IV"},
|
||||||
|
{ "5", "V"},
|
||||||
|
{ "6", "VI"},
|
||||||
|
{ "7", "VII"},
|
||||||
|
{ "8", "VII"},
|
||||||
|
{ "9", "IX"},
|
||||||
|
{ "10", "X"},
|
||||||
|
|
||||||
|
}; //If a movie has more than 10 parts fuck 'em.
|
||||||
|
|
||||||
public ParsingService(IEpisodeService episodeService,
|
public ParsingService(IEpisodeService episodeService,
|
||||||
ISeriesService seriesService,
|
ISeriesService seriesService,
|
||||||
@@ -163,19 +177,19 @@ namespace NzbDrone.Core.Parser
|
|||||||
|
|
||||||
public Movie GetMovie(string title)
|
public Movie GetMovie(string title)
|
||||||
{
|
{
|
||||||
var parsedEpisodeInfo = Parser.ParseTitle(title);
|
var parsedEpisodeInfo = Parser.ParseMovieTitle(title);
|
||||||
|
|
||||||
if (parsedEpisodeInfo == null)
|
if (parsedEpisodeInfo == null)
|
||||||
{
|
{
|
||||||
return _movieService.FindByTitle(title);
|
return _movieService.FindByTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
var series = _movieService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
var series = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle);
|
||||||
|
|
||||||
if (series == null)
|
if (series == null)
|
||||||
{
|
{
|
||||||
series = _movieService.FindByTitle(parsedEpisodeInfo.SeriesTitleInfo.TitleWithoutYear,
|
series = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitleInfo.TitleWithoutYear,
|
||||||
parsedEpisodeInfo.SeriesTitleInfo.Year);
|
parsedEpisodeInfo.MovieTitleInfo.Year);
|
||||||
}
|
}
|
||||||
|
|
||||||
return series;
|
return series;
|
||||||
@@ -201,11 +215,11 @@ namespace NzbDrone.Core.Parser
|
|||||||
return remoteEpisode;
|
return remoteEpisode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteMovie Map(ParsedEpisodeInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria = null)
|
public RemoteMovie Map(ParsedMovieInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria = null)
|
||||||
{
|
{
|
||||||
var remoteEpisode = new RemoteMovie
|
var remoteEpisode = new RemoteMovie
|
||||||
{
|
{
|
||||||
ParsedEpisodeInfo = parsedEpisodeInfo,
|
ParsedMovieInfo = parsedEpisodeInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
var movie = GetMovie(parsedEpisodeInfo, imdbId, searchCriteria);
|
var movie = GetMovie(parsedEpisodeInfo, imdbId, searchCriteria);
|
||||||
@@ -334,23 +348,56 @@ namespace NzbDrone.Core.Parser
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Movie GetMovie(ParsedEpisodeInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria)
|
private Movie GetMovie(ParsedMovieInfo parsedEpisodeInfo, string imdbId, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
if (searchCriteria != null)
|
if (searchCriteria != null)
|
||||||
{
|
{
|
||||||
if (searchCriteria.Movie.CleanTitle == parsedEpisodeInfo.SeriesTitle.CleanSeriesTitle())
|
var possibleTitles = new List<string>();
|
||||||
|
|
||||||
|
possibleTitles.Add(searchCriteria.Movie.CleanTitle);
|
||||||
|
|
||||||
|
foreach (string altTitle in searchCriteria.Movie.AlternativeTitles)
|
||||||
{
|
{
|
||||||
return searchCriteria.Movie;
|
possibleTitles.Add(altTitle.CleanSeriesTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imdbId.IsNotNullOrWhiteSpace() && imdbId == searchCriteria.Movie.ImdbId)
|
foreach (string title in possibleTitles)
|
||||||
{
|
{
|
||||||
//TODO: If series is found by TvdbId, we should report it as a scene naming exception, since it will fail to import
|
if (title == parsedEpisodeInfo.MovieTitle.CleanSeriesTitle())
|
||||||
return searchCriteria.Movie;
|
{
|
||||||
|
return searchCriteria.Movie;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> entry in romanNumeralsMapper)
|
||||||
|
{
|
||||||
|
string num = entry.Key;
|
||||||
|
string roman = entry.Value.ToLower();
|
||||||
|
|
||||||
|
if (title.Replace(num, roman) == parsedEpisodeInfo.MovieTitle.CleanSeriesTitle())
|
||||||
|
{
|
||||||
|
return searchCriteria.Movie;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title.Replace(roman, num) == parsedEpisodeInfo.MovieTitle.CleanSeriesTitle())
|
||||||
|
{
|
||||||
|
return searchCriteria.Movie;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Movie movie = _movieService.FindByTitle(parsedEpisodeInfo.SeriesTitle);
|
Movie movie = null;
|
||||||
|
|
||||||
|
if (searchCriteria == null)
|
||||||
|
{
|
||||||
|
|
||||||
|
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above!
|
||||||
|
|
||||||
|
return movie;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (movie == null && imdbId.IsNotNullOrWhiteSpace())
|
if (movie == null && imdbId.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
@@ -360,7 +407,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
|
|
||||||
if (movie == null)
|
if (movie == null)
|
||||||
{
|
{
|
||||||
_logger.Debug("No matching movie {0}", parsedEpisodeInfo.SeriesTitle);
|
_logger.Debug("No matching movie {0}", parsedEpisodeInfo.MovieTitle);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace NzbDrone.Core.Queue
|
|||||||
Id = HashConverter.GetHashInt31(string.Format("trackedDownload-{0}", trackedDownload.DownloadItem.DownloadId)),
|
Id = HashConverter.GetHashInt31(string.Format("trackedDownload-{0}", trackedDownload.DownloadItem.DownloadId)),
|
||||||
Series = null,
|
Series = null,
|
||||||
Episode = null,
|
Episode = null,
|
||||||
Quality = trackedDownload.RemoteMovie.ParsedEpisodeInfo.Quality,
|
Quality = trackedDownload.RemoteMovie.ParsedMovieInfo.Quality,
|
||||||
Title = trackedDownload.DownloadItem.Title,
|
Title = trackedDownload.DownloadItem.Title,
|
||||||
Size = trackedDownload.DownloadItem.TotalSize,
|
Size = trackedDownload.DownloadItem.TotalSize,
|
||||||
Sizeleft = trackedDownload.DownloadItem.RemainingSize,
|
Sizeleft = trackedDownload.DownloadItem.RemainingSize,
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ namespace NzbDrone.Core.Tv
|
|||||||
Genres = new List<string>();
|
Genres = new List<string>();
|
||||||
Actors = new List<Actor>();
|
Actors = new List<Actor>();
|
||||||
Tags = new HashSet<int>();
|
Tags = new HashSet<int>();
|
||||||
|
AlternativeTitles = new List<string>();
|
||||||
}
|
}
|
||||||
|
public int TmdbId { get; set; }
|
||||||
public string ImdbId { get; set; }
|
public string ImdbId { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string CleanTitle { get; set; }
|
public string CleanTitle { get; set; }
|
||||||
@@ -30,6 +31,7 @@ namespace NzbDrone.Core.Tv
|
|||||||
public int Runtime { get; set; }
|
public int Runtime { get; set; }
|
||||||
public List<MediaCover.MediaCover> Images { get; set; }
|
public List<MediaCover.MediaCover> Images { get; set; }
|
||||||
public string TitleSlug { get; set; }
|
public string TitleSlug { get; set; }
|
||||||
|
public string Website { get; set; }
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
public Ratings Ratings { get; set; }
|
public Ratings Ratings { get; set; }
|
||||||
@@ -44,7 +46,7 @@ namespace NzbDrone.Core.Tv
|
|||||||
public AddMovieOptions AddOptions { get; set; }
|
public AddMovieOptions AddOptions { get; set; }
|
||||||
public LazyLoaded<MovieFile> MovieFile { get; set; }
|
public LazyLoaded<MovieFile> MovieFile { get; set; }
|
||||||
public int MovieFileId { get; set; }
|
public int MovieFileId { get; set; }
|
||||||
|
public List<string> AlternativeTitles { get; set; }
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format("[{0}][{1}]", ImdbId, Title.NullSafe());
|
return string.Format("[{0}][{1}]", ImdbId, Title.NullSafe());
|
||||||
|
|||||||
@@ -19,6 +19,21 @@ namespace NzbDrone.Core.Tv
|
|||||||
|
|
||||||
public class MovieRepository : BasicRepository<Movie>, IMovieRepository
|
public class MovieRepository : BasicRepository<Movie>, IMovieRepository
|
||||||
{
|
{
|
||||||
|
private readonly Dictionary<string, string> romanNumeralsMapper = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "1", "I"},
|
||||||
|
{ "2", "II"},
|
||||||
|
{ "3", "III"},
|
||||||
|
{ "4", "IV"},
|
||||||
|
{ "5", "V"},
|
||||||
|
{ "6", "VI"},
|
||||||
|
{ "7", "VII"},
|
||||||
|
{ "8", "VII"},
|
||||||
|
{ "9", "IX"},
|
||||||
|
{ "10", "X"},
|
||||||
|
|
||||||
|
}; //If a movie has more than 10 parts fuck 'em.
|
||||||
|
|
||||||
public MovieRepository(IMainDatabase database, IEventAggregator eventAggregator)
|
public MovieRepository(IMainDatabase database, IEventAggregator eventAggregator)
|
||||||
: base(database, eventAggregator)
|
: base(database, eventAggregator)
|
||||||
{
|
{
|
||||||
@@ -33,8 +48,46 @@ namespace NzbDrone.Core.Tv
|
|||||||
{
|
{
|
||||||
cleanTitle = cleanTitle.ToLowerInvariant();
|
cleanTitle = cleanTitle.ToLowerInvariant();
|
||||||
|
|
||||||
return Query.Where(s => s.CleanTitle == cleanTitle)
|
var cleanRoman = cleanTitle;
|
||||||
.SingleOrDefault();
|
|
||||||
|
var cleanNum = cleanTitle;
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> entry in romanNumeralsMapper)
|
||||||
|
{
|
||||||
|
string num = entry.Key;
|
||||||
|
string roman = entry.Value.ToLower();
|
||||||
|
|
||||||
|
cleanRoman = cleanRoman.Replace(num, roman);
|
||||||
|
|
||||||
|
cleanNum = cleanNum.Replace(roman, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = Query.Where(s => s.CleanTitle == cleanTitle).SingleOrDefault();
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
result = Query.Where(s => s.CleanTitle == cleanNum).OrWhere(s => s.CleanTitle == cleanRoman).SingleOrDefault();
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
var movies = this.All();
|
||||||
|
|
||||||
|
result = movies.Where(m => m.AlternativeTitles.Any(t => Parser.Parser.CleanSeriesTitle(t.ToLower()) == cleanTitle ||
|
||||||
|
Parser.Parser.CleanSeriesTitle(t.ToLower()) == cleanRoman ||
|
||||||
|
Parser.Parser.CleanSeriesTitle(t.ToLower()) == cleanNum)).SingleOrDefault();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Movie FindByTitle(string cleanTitle, int year)
|
public Movie FindByTitle(string cleanTitle, int year)
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace NzbDrone.Core.Tv
|
|||||||
_logger.Info("Adding Movie {0} Path: [{1}]", newMovie, newMovie.Path);
|
_logger.Info("Adding Movie {0} Path: [{1}]", newMovie, newMovie.Path);
|
||||||
|
|
||||||
newMovie.CleanTitle = newMovie.Title.CleanSeriesTitle();
|
newMovie.CleanTitle = newMovie.Title.CleanSeriesTitle();
|
||||||
newMovie.SortTitle = MovieTitleNormalizer.Normalize(newMovie.Title, newMovie.ImdbId);
|
newMovie.SortTitle = MovieTitleNormalizer.Normalize(newMovie.Title, newMovie.TmdbId);
|
||||||
newMovie.Added = DateTime.UtcNow;
|
newMovie.Added = DateTime.UtcNow;
|
||||||
|
|
||||||
_movieRepository.Insert(newMovie);
|
_movieRepository.Insert(newMovie);
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ namespace NzbDrone.Core.Tv
|
|||||||
{
|
{
|
||||||
public static class MovieTitleNormalizer
|
public static class MovieTitleNormalizer
|
||||||
{
|
{
|
||||||
private readonly static Dictionary<string, string> PreComputedTitles = new Dictionary<string, string>
|
private readonly static Dictionary<int, string> PreComputedTitles = new Dictionary<int, string>
|
||||||
{
|
{
|
||||||
{ "tt_109823457098", "a to z" },
|
{ 999999999, "a to z" },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string Normalize(string title, string imdbid)
|
public static string Normalize(string title, int tmdbid)
|
||||||
{
|
{
|
||||||
if (PreComputedTitles.ContainsKey(imdbid))
|
if (PreComputedTitles.ContainsKey(tmdbid))
|
||||||
{
|
{
|
||||||
return PreComputedTitles[imdbid];
|
return PreComputedTitles[tmdbid];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Parser.Parser.NormalizeTitle(title).ToLower();
|
return Parser.Parser.NormalizeTitle(title).ToLower();
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace NzbDrone.Core.Tv
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
movieInfo = _movieInfo.GetMovieInfo(movie.ImdbId);
|
movieInfo = _movieInfo.GetMovieInfo(movie.TmdbId);
|
||||||
}
|
}
|
||||||
catch (MovieNotFoundException)
|
catch (MovieNotFoundException)
|
||||||
{
|
{
|
||||||
@@ -59,10 +59,10 @@ namespace NzbDrone.Core.Tv
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movie.ImdbId != movieInfo.ImdbId)
|
if (movie.TmdbId != movieInfo.TmdbId)
|
||||||
{
|
{
|
||||||
_logger.Warn("Movie '{0}' (tvdbid {1}) was replaced with '{2}' (tvdbid {3}), because the original was a duplicate.", movie.Title, movie.ImdbId, movieInfo.Title, movieInfo.ImdbId);
|
_logger.Warn("Movie '{0}' (tvdbid {1}) was replaced with '{2}' (tvdbid {3}), because the original was a duplicate.", movie.Title, movie.TmdbId, movieInfo.Title, movieInfo.TmdbId);
|
||||||
movie.ImdbId = movieInfo.ImdbId;
|
movie.TmdbId = movieInfo.TmdbId;
|
||||||
}
|
}
|
||||||
|
|
||||||
movie.Title = movieInfo.Title;
|
movie.Title = movieInfo.Title;
|
||||||
@@ -80,6 +80,8 @@ namespace NzbDrone.Core.Tv
|
|||||||
movie.Genres = movieInfo.Genres;
|
movie.Genres = movieInfo.Genres;
|
||||||
movie.Certification = movieInfo.Certification;
|
movie.Certification = movieInfo.Certification;
|
||||||
movie.InCinemas = movieInfo.InCinemas;
|
movie.InCinemas = movieInfo.InCinemas;
|
||||||
|
movie.Website = movieInfo.Website;
|
||||||
|
movie.AlternativeTitles = movieInfo.AlternativeTitles;
|
||||||
movie.Year = movieInfo.Year;
|
movie.Year = movieInfo.Year;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ namespace NzbDrone.Core.Validation.Paths
|
|||||||
{
|
{
|
||||||
if (context.PropertyValue == null) return true;
|
if (context.PropertyValue == null) return true;
|
||||||
|
|
||||||
var imdbid = context.PropertyValue.ToString();
|
int tmdbId = (int)context.PropertyValue;
|
||||||
|
|
||||||
return (!_seriesService.GetAllMovies().Exists(s => s.ImdbId == imdbid));
|
return (!_seriesService.GetAllMovies().Exists(s => s.TmdbId == tmdbId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ module.exports = Marionette.Layout.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (!this.isExisting) {
|
else if (!this.isExisting) {
|
||||||
this.resultCollectionView.setExisting(options.movie.get('imdbId'))
|
this.resultCollectionView.setExisting(options.movie.get('tmdbId'))
|
||||||
/*this.collection.term = '';
|
/*this.collection.term = '';
|
||||||
this.collection.reset();
|
this.collection.reset();
|
||||||
this._clearResults();
|
this._clearResults();
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ module.exports = Marionette.CollectionView.extend({
|
|||||||
return this.showing >= this.collection.length;
|
return this.showing >= this.collection.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
setExisting : function(imdbid) {
|
setExisting : function(tmdbid) {
|
||||||
var movies = this.collection.where({ imdbId : imdbid });
|
var movies = this.collection.where({ tmdbId : tmdbid });
|
||||||
console.warn(movies)
|
console.warn(movies)
|
||||||
//debugger;
|
//debugger;
|
||||||
if (movies.length > 0) {
|
if (movies.length > 0) {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ var view = Marionette.ItemView.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_configureTemplateHelpers : function() {
|
_configureTemplateHelpers : function() {
|
||||||
var existingMovies = MoviesCollection.where({ imdbId : this.model.get('imdbId') });
|
var existingMovies = MoviesCollection.where({ tmdbId : this.model.get('tmdbId') });
|
||||||
console.log(existingMovies)
|
console.log(existingMovies)
|
||||||
if (existingMovies.length > 0) {
|
if (existingMovies.length > 0) {
|
||||||
this.templateHelpers.existing = existingMovies[0].toJSON();
|
this.templateHelpers.existing = existingMovies[0].toJSON();
|
||||||
|
|||||||
41
src/UI/Cells/EditionCell.js
Normal file
41
src/UI/Cells/EditionCell.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
var Backgrid = require('backgrid');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
require('bootstrap');
|
||||||
|
|
||||||
|
module.exports = Backgrid.Cell.extend({
|
||||||
|
className : 'edition-cell',
|
||||||
|
//template : 'Cells/EditionCellTemplate',
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
|
||||||
|
var edition = this.model.get(this.column.get('name'));
|
||||||
|
if (!edition) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
var cut = false;
|
||||||
|
|
||||||
|
if (edition.toLowerCase().contains("cut")) {
|
||||||
|
cut = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.templateFunction = Marionette.TemplateCache.get(this.template);
|
||||||
|
|
||||||
|
//var html = this.templateFunction(edition);
|
||||||
|
if (cut) {
|
||||||
|
this.$el.html('<i class="icon-sonarr-form-cut"/ title="{0}">'.format(edition));
|
||||||
|
} else {
|
||||||
|
this.$el.html('<i class="icon-sonarr-form-special"/ title="{0}">'.format(edition));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*this.$el.popover({
|
||||||
|
content : html,
|
||||||
|
html : true,
|
||||||
|
trigger : 'hover',
|
||||||
|
title : this.column.get('title'),
|
||||||
|
placement : 'left',
|
||||||
|
container : this.$el
|
||||||
|
});*/
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
5
src/UI/Cells/EditionCellTemplate.hbs
Normal file
5
src/UI/Cells/EditionCellTemplate.hbs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
{{this}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
@@ -13,23 +13,23 @@ module.exports = NzbDroneCell.extend({
|
|||||||
switch (this.cellValue.get('eventType')) {
|
switch (this.cellValue.get('eventType')) {
|
||||||
case 'grabbed':
|
case 'grabbed':
|
||||||
icon = 'icon-sonarr-downloading';
|
icon = 'icon-sonarr-downloading';
|
||||||
toolTip = 'Episode grabbed from {0} and sent to download client'.format(this.cellValue.get('data').indexer);
|
toolTip = 'Movie grabbed from {0} and sent to download client'.format(this.cellValue.get('data').indexer);
|
||||||
break;
|
break;
|
||||||
case 'seriesFolderImported':
|
case 'seriesFolderImported':
|
||||||
icon = 'icon-sonarr-hdd';
|
icon = 'icon-sonarr-hdd';
|
||||||
toolTip = 'Existing episode file added to library';
|
toolTip = 'Existing movie file added to library';
|
||||||
break;
|
break;
|
||||||
case 'downloadFolderImported':
|
case 'downloadFolderImported':
|
||||||
icon = 'icon-sonarr-imported';
|
icon = 'icon-sonarr-imported';
|
||||||
toolTip = 'Episode downloaded successfully and picked up from download client';
|
toolTip = 'Movie downloaded successfully and picked up from download client';
|
||||||
break;
|
break;
|
||||||
case 'downloadFailed':
|
case 'downloadFailed':
|
||||||
icon = 'icon-sonarr-download-failed';
|
icon = 'icon-sonarr-download-failed';
|
||||||
toolTip = 'Episode download failed';
|
toolTip = 'Movie download failed';
|
||||||
break;
|
break;
|
||||||
case 'episodeFileDeleted':
|
case 'episodeFileDeleted':
|
||||||
icon = 'icon-sonarr-deleted';
|
icon = 'icon-sonarr-deleted';
|
||||||
toolTip = 'Episode file deleted';
|
toolTip = 'Movie file deleted';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
icon = 'icon-sonarr-unknown';
|
icon = 'icon-sonarr-unknown';
|
||||||
@@ -41,4 +41,4 @@ module.exports = NzbDroneCell.extend({
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -121,6 +121,14 @@
|
|||||||
.fa-icon-color(@brand-danger);
|
.fa-icon-color(@brand-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-sonarr-form-cut {
|
||||||
|
.fa-icon-content(@fa-var-scissors);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-sonarr-form-special {
|
||||||
|
.fa-icon-content(@fa-var-exclamation-circle);
|
||||||
|
}
|
||||||
|
|
||||||
.icon-sonarr-form-info-link {
|
.icon-sonarr-form-info-link {
|
||||||
.clickable();
|
.clickable();
|
||||||
.fa-icon-content(@fa-var-info-circle);
|
.fa-icon-content(@fa-var-info-circle);
|
||||||
@@ -502,4 +510,4 @@
|
|||||||
|
|
||||||
.icon-sonarr-header-rejections {
|
.icon-sonarr-header-rejections {
|
||||||
.fa-icon-content(@fa-var-exclamation-circle);
|
.fa-icon-content(@fa-var-exclamation-circle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ var DownloadReportCell = require('../../Release/DownloadReportCell');
|
|||||||
var AgeCell = require('../../Release/AgeCell');
|
var AgeCell = require('../../Release/AgeCell');
|
||||||
var ProtocolCell = require('../../Release/ProtocolCell');
|
var ProtocolCell = require('../../Release/ProtocolCell');
|
||||||
var PeersCell = require('../../Release/PeersCell');
|
var PeersCell = require('../../Release/PeersCell');
|
||||||
|
var EditionCell = require('../../Cells/EditionCell');
|
||||||
|
|
||||||
module.exports = Marionette.Layout.extend({
|
module.exports = Marionette.Layout.extend({
|
||||||
template : 'Episode/Search/ManualLayoutTemplate',
|
template : 'Episode/Search/ManualLayoutTemplate',
|
||||||
@@ -32,6 +33,12 @@ module.exports = Marionette.Layout.extend({
|
|||||||
label : 'Title',
|
label : 'Title',
|
||||||
cell : ReleaseTitleCell
|
cell : ReleaseTitleCell
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name : 'edition',
|
||||||
|
label : 'Edition',
|
||||||
|
cell : EditionCell,
|
||||||
|
title : "Edition"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name : 'indexer',
|
name : 'indexer',
|
||||||
label : 'Indexer',
|
label : 'Indexer',
|
||||||
@@ -83,4 +90,4 @@ module.exports = Marionette.Layout.extend({
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Handlebars.registerHelper('remotePoster', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Handlebars.SafeString('<img class="series-poster placeholder-image" src="{0}">'.format(placeholder));
|
return new Handlebars.SafeString('<img class="series-poster placeholder-image" src="{0}">'.format(placeholder));
|
||||||
})
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('traktUrl', function() {
|
Handlebars.registerHelper('traktUrl', function() {
|
||||||
return 'http://trakt.tv/search/tvdb/' + this.tvdbId + '?id_type=show';
|
return 'http://trakt.tv/search/tvdb/' + this.tvdbId + '?id_type=show';
|
||||||
@@ -47,6 +47,25 @@ Handlebars.registerHelper('tvdbUrl', function() {
|
|||||||
return 'http://imdb.com/title/tt' + this.imdbId;
|
return 'http://imdb.com/title/tt' + this.imdbId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('tmdbUrl', function() {
|
||||||
|
return 'https://www.themoviedb.org/movie/' + this.tmdbId;
|
||||||
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('homepage', function() {
|
||||||
|
return this.website;
|
||||||
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('alternativeTitlesString', function() {
|
||||||
|
var titles = this.alternativeTitles;
|
||||||
|
if (titles.length == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (titles.length == 1) {
|
||||||
|
return titles[0];
|
||||||
|
}
|
||||||
|
return titles.slice(0,titles.length-1).join(", ") + " and " + titles[titles.length-1];
|
||||||
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('inCinemas', function() {
|
Handlebars.registerHelper('inCinemas', function() {
|
||||||
var monthNames = ["January", "February", "March", "April", "May", "June",
|
var monthNames = ["January", "February", "March", "April", "May", "June",
|
||||||
"July", "August", "September", "October", "November", "December"
|
"July", "August", "September", "October", "November", "December"
|
||||||
@@ -55,7 +74,7 @@ Handlebars.registerHelper('inCinemas', function() {
|
|||||||
var year = cinemasDate.getFullYear();
|
var year = cinemasDate.getFullYear();
|
||||||
var month = monthNames[cinemasDate.getMonth()];
|
var month = monthNames[cinemasDate.getMonth()];
|
||||||
return "In Cinemas " + month + " " + year;
|
return "In Cinemas " + month + " " + year;
|
||||||
})
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('tvRageUrl', function() {
|
Handlebars.registerHelper('tvRageUrl', function() {
|
||||||
return 'http://www.tvrage.com/shows/id-' + this.tvRageId;
|
return 'http://www.tvrage.com/shows/id-' + this.tvRageId;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-8">
|
||||||
{{profile profileId}}
|
{{profile profileId}}
|
||||||
|
|
||||||
{{#if network}}
|
{{#if network}}
|
||||||
@@ -27,11 +27,13 @@
|
|||||||
<span class="label label-default">Announced</span>
|
<span class="label label-default">Announced</span>
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-4">
|
||||||
<span class="series-info-links">
|
<span class="series-info-links">
|
||||||
<!--<a href="{{traktUrl}}" class="label label-info">Trakt</a>
|
<!--<a href="{{traktUrl}}" class="label label-info">Trakt</a>-->
|
||||||
|
{{#if website}}
|
||||||
<a href="{{tvdbUrl}}" class="label label-info">The TVDB</a>-->
|
<a href="{{homepage}}" class="label label-info">Homepage</a>
|
||||||
|
{{/if}}
|
||||||
|
<a href="{{tmdbUrl}}" class="label label-info">The Movie DB</a>
|
||||||
|
|
||||||
{{#if imdbId}}
|
{{#if imdbId}}
|
||||||
<a href="{{imdbUrl}}" class="label label-info">IMDB</a>
|
<a href="{{imdbUrl}}" class="label label-info">IMDB</a>
|
||||||
@@ -40,18 +42,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if alternateTitles}}
|
{{#if alternativeTitles}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{{#each alternateTitles}}
|
<span class="alternative-titles">
|
||||||
{{#if_eq seasonNumber compare="-1"}}
|
Also known as: {{alternativeTitlesString}}.
|
||||||
<span class="label label-default">{{title}}</span>
|
</span>
|
||||||
{{/if_eq}}
|
|
||||||
|
|
||||||
{{#if_eq sceneSeasonNumber compare="-1"}}
|
|
||||||
<span class="label label-default">{{title}}</span>
|
|
||||||
{{/if_eq}}
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ module.exports = Marionette.Layout.extend({
|
|||||||
|
|
||||||
_showBackdrop : function () {
|
_showBackdrop : function () {
|
||||||
$('body').addClass('backdrop');
|
$('body').addClass('backdrop');
|
||||||
var fanArt = this._getImage('fanart');
|
var fanArt = this._getImage('banner');
|
||||||
|
|
||||||
if (fanArt) {
|
if (fanArt) {
|
||||||
this._backstrech = $.backstretch(fanArt);
|
this._backstrech = $.backstretch(fanArt);
|
||||||
|
|||||||
@@ -36,12 +36,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="movie-info">
|
<div id="movie-info">
|
||||||
<ul class="nav nav-tabs" id="myTab">
|
<div class="movie-tabs">
|
||||||
<li><a href="#movie-history" class="x-movie-history">History</a></li>
|
<div>
|
||||||
<li><a href="#movie-search" class="x-movie-search">Search</a></li>
|
<div class="movie-tabs-card">
|
||||||
</ul>
|
<ul class="nav nav-tabs" id="myTab">
|
||||||
<div class="tab-content">
|
<li><a href="#movie-history" class="x-movie-history">History</a></li>
|
||||||
<div class="tab-pane" id="movie-history"/>
|
<li><a href="#movie-search" class="x-movie-search">Search</a></li>
|
||||||
<div class="tab-pane" id="movie-search"/>
|
</ul>
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane" id="movie-history"/>
|
||||||
|
<div class="tab-pane" id="movie-search"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ var DownloadReportCell = require('../../Release/DownloadReportCell');
|
|||||||
var AgeCell = require('../../Release/AgeCell');
|
var AgeCell = require('../../Release/AgeCell');
|
||||||
var ProtocolCell = require('../../Release/ProtocolCell');
|
var ProtocolCell = require('../../Release/ProtocolCell');
|
||||||
var PeersCell = require('../../Release/PeersCell');
|
var PeersCell = require('../../Release/PeersCell');
|
||||||
|
var EditionCell = require('../../Cells/EditionCell');
|
||||||
|
|
||||||
module.exports = Marionette.Layout.extend({
|
module.exports = Marionette.Layout.extend({
|
||||||
template : 'Movies/Search/ManualLayoutTemplate',
|
template : 'Movies/Search/ManualLayoutTemplate',
|
||||||
@@ -32,6 +33,12 @@ module.exports = Marionette.Layout.extend({
|
|||||||
label : 'Title',
|
label : 'Title',
|
||||||
cell : ReleaseTitleCell
|
cell : ReleaseTitleCell
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name : 'edition',
|
||||||
|
label : 'Edition',
|
||||||
|
cell : EditionCell,
|
||||||
|
title : "Edition"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name : 'indexer',
|
name : 'indexer',
|
||||||
label : 'Indexer',
|
label : 'Indexer',
|
||||||
|
|||||||
@@ -8,6 +8,22 @@
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.movie-tabs-card {
|
||||||
|
.card;
|
||||||
|
.opacity(0.9);
|
||||||
|
margin : 30px 10px;
|
||||||
|
padding : 10px 25px;
|
||||||
|
|
||||||
|
.show-hide-episodes {
|
||||||
|
.clickable();
|
||||||
|
text-align : center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
.clickable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.edit-movie-modal, .delete-movie-modal {
|
.edit-movie-modal, .delete-movie-modal {
|
||||||
overflow : visible;
|
overflow : visible;
|
||||||
|
|
||||||
@@ -253,6 +269,12 @@
|
|||||||
margin-bottom : 50px;
|
margin-bottom : 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alternative-titles {
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(255, 255, 255, 180);
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
|
||||||
.movie-season {
|
.movie-season {
|
||||||
|
|
||||||
.episode-number-cell {
|
.episode-number-cell {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ var FileSizeCell = require('../Cells/FileSizeCell');
|
|||||||
var QualityCell = require('../Cells/QualityCell');
|
var QualityCell = require('../Cells/QualityCell');
|
||||||
var ApprovalStatusCell = require('../Cells/ApprovalStatusCell');
|
var ApprovalStatusCell = require('../Cells/ApprovalStatusCell');
|
||||||
var LoadingView = require('../Shared/LoadingView');
|
var LoadingView = require('../Shared/LoadingView');
|
||||||
|
var EditionCell = require('../Cells/EditionCell');
|
||||||
|
|
||||||
module.exports = Marionette.Layout.extend({
|
module.exports = Marionette.Layout.extend({
|
||||||
template : 'Release/ReleaseLayoutTemplate',
|
template : 'Release/ReleaseLayoutTemplate',
|
||||||
@@ -17,6 +18,12 @@ module.exports = Marionette.Layout.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
columns : [
|
columns : [
|
||||||
|
{
|
||||||
|
name : 'edition',
|
||||||
|
label : 'Edition',
|
||||||
|
sortable : false,
|
||||||
|
cell : EditionCell
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name : 'indexer',
|
name : 'indexer',
|
||||||
label : 'Indexer',
|
label : 'Indexer',
|
||||||
@@ -29,12 +36,12 @@ module.exports = Marionette.Layout.extend({
|
|||||||
sortable : true,
|
sortable : true,
|
||||||
cell : Backgrid.StringCell
|
cell : Backgrid.StringCell
|
||||||
},
|
},
|
||||||
{
|
/*{
|
||||||
name : 'episodeNumbers',
|
name : 'episodeNumbers',
|
||||||
episodes : 'episodeNumbers',
|
episodes : 'episodeNumbers',
|
||||||
label : 'season',
|
label : 'season',
|
||||||
cell : EpisodeNumberCell
|
cell : EpisodeNumberCell
|
||||||
},
|
},*/
|
||||||
{
|
{
|
||||||
name : 'size',
|
name : 'size',
|
||||||
label : 'Size',
|
label : 'Size',
|
||||||
@@ -75,4 +82,4 @@ module.exports = Marionette.Layout.extend({
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user