Compare commits
105 Commits
v0.2.0.166
...
v0.2.0.238
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
487c5e22ce | ||
|
|
6efd63a292 | ||
|
|
5ebd035b1c | ||
|
|
d50514f8bc | ||
|
|
a417ac2716 | ||
|
|
a89e662721 | ||
|
|
4b1e4eecfb | ||
|
|
8e452f8b6d | ||
|
|
7e6db89eff | ||
|
|
16214e666b | ||
|
|
2b25ce237f | ||
|
|
f0a9955447 | ||
|
|
d0439296fe | ||
|
|
bc3fdb0f80 | ||
|
|
186b2ada36 | ||
|
|
577125f345 | ||
|
|
687dd8a05f | ||
|
|
81861c6121 | ||
|
|
302462f48c | ||
|
|
d132f55830 | ||
|
|
6bbd64e59a | ||
|
|
290c4e1f2e | ||
|
|
1112616514 | ||
|
|
7fddbca4b7 | ||
|
|
692841478c | ||
|
|
23232b9830 | ||
|
|
b886566b25 | ||
|
|
2c56d60678 | ||
|
|
a0c8127ecf | ||
|
|
05f61df59e | ||
|
|
a0b80ad41a | ||
|
|
9e7cb708bf | ||
|
|
1ad4006819 | ||
|
|
5339f8efdc | ||
|
|
b273bfb10e | ||
|
|
b2317ada1f | ||
|
|
336aee7fda | ||
|
|
9e7468d723 | ||
|
|
f05ee13206 | ||
|
|
2b579eb0d3 | ||
|
|
791121fa06 | ||
|
|
f0bcb27beb | ||
|
|
ec6b389d75 | ||
|
|
f38430d632 | ||
|
|
266f28883a | ||
|
|
cc3c2533fa | ||
|
|
f8162b34f2 | ||
|
|
309877bf76 | ||
|
|
a50b20a397 | ||
|
|
de5489ae9a | ||
|
|
12e74aa38b | ||
|
|
80ec66b47c | ||
|
|
585fd87ad6 | ||
|
|
ec5161e848 | ||
|
|
0ec54daaff | ||
|
|
3ed1bebb7d | ||
|
|
29ae088a3d | ||
|
|
eb299ce847 | ||
|
|
a7e071318b | ||
|
|
3d67f6237e | ||
|
|
a691ffa7b7 | ||
|
|
aa9537c201 | ||
|
|
a3d9fb1c20 | ||
|
|
62a1e70c86 | ||
|
|
93d0d21846 | ||
|
|
b1c5a3ac14 | ||
|
|
55a525ba2f | ||
|
|
a53768463b | ||
|
|
24cbd6bcef | ||
|
|
3ab3e66853 | ||
|
|
40ca469339 | ||
|
|
2cbd2f719f | ||
|
|
53cbfa803b | ||
|
|
c0b0310bbd | ||
|
|
30e50062a8 | ||
|
|
85fd8f2c65 | ||
|
|
f72b042d5d | ||
|
|
2d3a3a0677 | ||
|
|
2bb21fedab | ||
|
|
91c820f98b | ||
|
|
7d3118aece | ||
|
|
4f4ad77ad1 | ||
|
|
42f205a731 | ||
|
|
cbb2b778a6 | ||
|
|
b3e03a648d | ||
|
|
acf45a79e8 | ||
|
|
b5d8ac852e | ||
|
|
4aec0e8fc6 | ||
|
|
ecea417fd8 | ||
|
|
6a41f6a435 | ||
|
|
da2d075aa8 | ||
|
|
10dc3993df | ||
|
|
7e5020db9a | ||
|
|
c48fe9de12 | ||
|
|
421e827a95 | ||
|
|
34d8045cf4 | ||
|
|
c6de163748 | ||
|
|
d9e2b22e74 | ||
|
|
65c0137964 | ||
|
|
ae19424ce7 | ||
|
|
7527ec52b7 | ||
|
|
640fcf3eaf | ||
|
|
3ce8232777 | ||
|
|
864b441d8e | ||
|
|
bc2ff149b4 |
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,6 +1,8 @@
|
||||
|
||||
|
||||
|
||||
Please use the search bar and make sure you are not submitting an already submitted issue.
|
||||
|
||||
Provide a description of the feature request or bug, the more details the better.
|
||||
When possible include a log!
|
||||
|
||||
|
||||
BIN
Logo/1024.png
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 48 KiB |
BIN
Logo/128.png
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 5.1 KiB |
BIN
Logo/16.png
|
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 701 B |
BIN
Logo/256.png
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 11 KiB |
BIN
Logo/32.png
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
Logo/400.png
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 17 KiB |
BIN
Logo/48.png
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
Logo/512.png
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 22 KiB |
BIN
Logo/64.png
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
Logo/800.png
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 37 KiB |
597
Logo/Radarr.svg
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 31 KiB |
44
README.md
@@ -12,7 +12,9 @@
|
||||
| AppVeyor | [](https://ci.appveyor.com/project/galli-leo/Radarr) | [](https://ci.appveyor.com/project/galli-leo/Radarr-usby1) |
|
||||
| Travis | [](https://travis-ci.org/Radarr/Radarr) | [](https://travis-ci.org/Radarr/Radarr) |
|
||||
|
||||
This fork of Sonarr aims to turn it into something like CouchPotato.
|
||||
A fork of [Sonarr](https://github.com/Sonarr/Sonarr) to work with movies à la Couchpotato.
|
||||
|
||||
**This fork works independently of Sonarr and will not interfere with it.**
|
||||
|
||||
## Downloads
|
||||
|
||||
@@ -34,34 +36,34 @@ To connect to the UI, fire up your browser and open <http://localhost:7878> or <
|
||||
|
||||
## Features
|
||||
|
||||
### Currently Working
|
||||
|
||||
* Adding new movies
|
||||
* Manually searching for releases of movies
|
||||
* Automatically searching for releases
|
||||
* Automatically importing downloaded movies
|
||||
* Recognizing Special Editions, Director's Cut, etc.
|
||||
* Identifying releases with hardcoded subs
|
||||
* Rarbg.to, Torznab and Newznab Indexer
|
||||
* QBittorrent and Deluge download client (Other clients are coming)
|
||||
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
|
||||
|
||||
### Planned Features
|
||||
|
||||
* Scanning PreDB to know when a new release is available
|
||||
* Fixing the other Indexers and download clients
|
||||
* Importing of Sonarr config
|
||||
|
||||
### Major Features
|
||||
### Current Features
|
||||
|
||||
* Adding new movies with lots of information, such as trailers, ratings, etc.
|
||||
* Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc.
|
||||
* Can watch for better quality of the movies you have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
|
||||
* Automatic failed download handling will try another release if one fails
|
||||
* Manual search so you can pick any release or to see why a release was not downloaded automatically
|
||||
* Full integration with SABnzbd and NZBGet
|
||||
* Full integration with Kodi, Plex (notification, library update, metadata)
|
||||
* Automatically searching for releases as well as RSS Sync
|
||||
* Automatically importing downloaded movies
|
||||
* Recognizing Special Editions, Director's Cut, etc.
|
||||
* Identifying releases with hardcoded subs
|
||||
* All indexers supported by Sonarr also supported
|
||||
* New PassThePopcorn Indexer
|
||||
* QBittorrent, Deluge, rTorrent, Transmission and uTorrent download client (Other clients are coming)
|
||||
* New TorrentPotato Indexer (Works well with [Jackett](https://github.com/Jackett/Jackett))
|
||||
* And a beautiful UI
|
||||
|
||||
### Planned Features
|
||||
|
||||
* Scanning PreDB to know when a new release is available
|
||||
* Fixing the other Indexers and download clients
|
||||
* Importing movies from various online sources, such as IMDb Watchlists (A complete list can be found [here](https://github.com/Radarr/Radarr/issues/114))
|
||||
* Full integration with Kodi, Plex (notification, library update, metadata)
|
||||
|
||||
##Feature Requests
|
||||
[](http://feathub.com/Radarr/Radarr)
|
||||
|
||||
## Configuring Development Environment
|
||||
|
||||
### Requirements
|
||||
|
||||
@@ -64,6 +64,8 @@ namespace NzbDrone.Api.Authentication
|
||||
new DefaultHmacProvider(new PassphraseKeyGenerator(_configService.HmacPassphrase, Encoding.ASCII.GetBytes(_configService.HmacSalt)))
|
||||
);
|
||||
|
||||
FormsAuthentication.FormsAuthenticationCookieName = "_ncfaradarr"; //For those people that both have sonarr and radarr.
|
||||
|
||||
FormsAuthentication.Enable(pipelines, new FormsAuthenticationConfiguration
|
||||
{
|
||||
RedirectUrl = _configFileProvider.UrlBase + "/login",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Api.Series;
|
||||
@@ -11,13 +12,14 @@ namespace NzbDrone.Api.Blacklist
|
||||
{
|
||||
public int SeriesId { get; set; }
|
||||
public List<int> EpisodeIds { get; set; }
|
||||
public int MovieId { get; set; }
|
||||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public DownloadProtocol Protocol { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public MovieResource Movie { get; set; }
|
||||
public SeriesResource Series { get; set; }
|
||||
}
|
||||
|
||||
@@ -30,7 +32,7 @@ namespace NzbDrone.Api.Blacklist
|
||||
return new BlacklistResource
|
||||
{
|
||||
Id = model.Id,
|
||||
|
||||
MovieId = model.MovieId,
|
||||
SeriesId = model.SeriesId,
|
||||
EpisodeIds = model.EpisodeIds,
|
||||
SourceTitle = model.SourceTitle,
|
||||
@@ -39,7 +41,7 @@ namespace NzbDrone.Api.Blacklist
|
||||
Protocol = model.Protocol,
|
||||
Indexer = model.Indexer,
|
||||
Message = model.Message,
|
||||
|
||||
Movie = model.Movie.ToResource(),
|
||||
Series = model.Series.ToResource()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -260,6 +260,7 @@
|
||||
<Compile Include="Wanted\CutoffModule.cs" />
|
||||
<Compile Include="Wanted\LegacyMissingModule.cs" />
|
||||
<Compile Include="Wanted\MissingModule.cs" />
|
||||
<Compile Include="Wanted\MovieMissingModule.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
@@ -294,4 +295,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -201,6 +201,8 @@ namespace NzbDrone.Api.Movie
|
||||
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
|
||||
|
||||
//if (mappings == null) return;
|
||||
|
||||
//Not necessary anymore
|
||||
|
||||
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
|
||||
}
|
||||
@@ -239,7 +241,7 @@ namespace NzbDrone.Api.Movie
|
||||
|
||||
public void Handle(MediaCoversUpdatedEvent message)
|
||||
{
|
||||
//BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ namespace NzbDrone.Api.Series
|
||||
|
||||
public void Handle(MediaCoversUpdatedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
||||
//BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace NzbDrone.Api.Validation
|
||||
public class RssSyncIntervalValidator : PropertyValidator
|
||||
{
|
||||
public RssSyncIntervalValidator()
|
||||
: base("Must be between 10 and 120 or 0 to disable")
|
||||
: base("Must be between 10 and 720 or 0 to disable")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace NzbDrone.Api.Validation
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value >= 10 && value <= 120)
|
||||
if (value >= 10 && value <= 720)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace NzbDrone.Api.Wanted
|
||||
ISeriesService seriesService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing")
|
||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing_episodes")
|
||||
{
|
||||
GetResourcePaged = GetMissingEpisodes;
|
||||
}
|
||||
|
||||
77
src/NzbDrone.Api/Wanted/MovieMissingModule.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Api.Movies;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.SignalR;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using System;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
|
||||
namespace NzbDrone.Api.Wanted
|
||||
{
|
||||
class MovieMissingModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
|
||||
IHandle<MovieGrabbedEvent>,
|
||||
IHandle<MovieDownloadedEvent>
|
||||
{
|
||||
protected readonly IMovieService _movieService;
|
||||
|
||||
public MovieMissingModule(IMovieService movieService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IBroadcastSignalRMessage signalRBroadcaster)
|
||||
: base(signalRBroadcaster, "wanted/missing")
|
||||
{
|
||||
|
||||
_movieService = movieService;
|
||||
GetResourcePaged = GetMissingMovies;
|
||||
}
|
||||
|
||||
private PagingResource<MovieResource> GetMissingMovies(PagingResource<MovieResource> pagingResource)
|
||||
{
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("physicalRelease", SortDirection.Descending);
|
||||
|
||||
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
|
||||
{
|
||||
pagingSpec.FilterExpression = v => v.Monitored == false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pagingSpec.FilterExpression = v => v.Monitored == true;
|
||||
}
|
||||
|
||||
var resource = ApplyToPage(_movieService.MoviesWithoutFiles, pagingSpec, v => MapToResource(v, false));
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
private MovieResource GetMovie(int id)
|
||||
{
|
||||
var movie = _movieService.GetMovie(id);
|
||||
var resource = MapToResource(movie, true);
|
||||
return resource;
|
||||
}
|
||||
|
||||
private MovieResource MapToResource(Core.Tv.Movie movie, bool includeMovieFile)
|
||||
{
|
||||
var resource = movie.ToResource();
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void Handle(MovieGrabbedEvent message)
|
||||
{
|
||||
var resource = message.Movie.Movie.ToResource();
|
||||
|
||||
//add a grabbed field in MovieResource?
|
||||
//resource.Grabbed = true;
|
||||
|
||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||
}
|
||||
|
||||
public void Handle(MovieDownloadedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Movie.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 81 KiB |
@@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.Configuration
|
||||
[Test]
|
||||
public void Get_value_should_return_default_when_no_value()
|
||||
{
|
||||
Subject.RssSyncInterval.Should().Be(15);
|
||||
Subject.RssSyncInterval.Should().Be(60);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.Configuration
|
||||
public void get_value_with_out_persist_should_not_store_default_value()
|
||||
{
|
||||
var interval = Subject.RssSyncInterval;
|
||||
interval.Should().Be(15);
|
||||
interval.Should().Be(60);
|
||||
Mocker.GetMock<IConfigRepository>().Verify(c => c.Insert(It.IsAny<Config>()), Times.Never());
|
||||
}
|
||||
|
||||
|
||||
@@ -92,14 +92,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||
protected void GivenFailedDownload()
|
||||
{
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<NzbgetSettings>()))
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<NzbgetSettings>()))
|
||||
.Returns((string)null);
|
||||
}
|
||||
|
||||
protected void GivenSuccessfulDownload()
|
||||
{
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<NzbgetSettings>()))
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<NzbgetSettings>()))
|
||||
.Returns(Guid.NewGuid().ToString().Replace("-", ""));
|
||||
}
|
||||
|
||||
|
||||
@@ -47,5 +47,17 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
{
|
||||
QualityParser.ParseQuality(title).Revision.Version.Should().Be(version);
|
||||
}
|
||||
|
||||
[TestCase("Deadpool 2016 2160p 4K UltraHD BluRay DTS-HD MA 7 1 x264-Whatevs", 19)]
|
||||
[TestCase("Deadpool 2016 2160p 4K UltraHD DTS-HD MA 7 1 x264-Whatevs", 16)]
|
||||
[TestCase("Deadpool 2016 4K 2160p UltraHD BluRay AAC2 0 HEVC x265", 19)]
|
||||
[TestCase("The Revenant 2015 2160p UHD BluRay DTS x264-Whatevs", 19)]
|
||||
[TestCase("The Revenant 2015 2160p UHD BluRay FLAC 7 1 x264-Whatevs", 19)]
|
||||
[TestCase("The Martian 2015 2160p Ultra HD BluRay DTS-HD MA 7 1 x264-Whatevs", 19)]
|
||||
[TestCase("Into the Inferno 2016 2160p Netflix WEBRip DD5 1 x264-Whatevs", 18)]
|
||||
public void should_parse_ultrahd_from_title(string title, int version)
|
||||
{
|
||||
QualityParser.ParseQuality(title).Quality.Id.Should().Be(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
public int SeriesId { get; set; }
|
||||
public Series Series { get; set; }
|
||||
public int MovieId { get; set; }
|
||||
public Movie Movie { get; set; }
|
||||
public List<int> EpisodeIds { get; set; }
|
||||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle);
|
||||
List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash);
|
||||
List<Blacklist> BlacklistedBySeries(int seriesId);
|
||||
List<Blacklist> BlacklistedByMovie(int seriesId);
|
||||
}
|
||||
|
||||
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
|
||||
@@ -20,15 +20,15 @@ namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
}
|
||||
|
||||
public List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle)
|
||||
public List<Blacklist> BlacklistedByTitle(int movieId, string sourceTitle)
|
||||
{
|
||||
return Query.Where(e => e.SeriesId == seriesId)
|
||||
return Query.Where(e => e.MovieId == movieId)
|
||||
.AndWhere(e => e.SourceTitle.Contains(sourceTitle));
|
||||
}
|
||||
|
||||
public List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash)
|
||||
public List<Blacklist> BlacklistedByTorrentInfoHash(int movieId, string torrentInfoHash)
|
||||
{
|
||||
return Query.Where(e => e.SeriesId == seriesId)
|
||||
return Query.Where(e => e.MovieId == movieId)
|
||||
.AndWhere(e => e.TorrentInfoHash.Contains(torrentInfoHash));
|
||||
}
|
||||
|
||||
@@ -37,9 +37,14 @@ namespace NzbDrone.Core.Blacklisting
|
||||
return Query.Where(b => b.SeriesId == seriesId);
|
||||
}
|
||||
|
||||
public List<Blacklist> BlacklistedByMovie(int movieId)
|
||||
{
|
||||
return Query.Where(b => b.MovieId == movieId);
|
||||
}
|
||||
|
||||
protected override SortBuilder<Blacklist> GetPagedQuery(QueryBuilder<Blacklist> query, PagingSpec<Blacklist> pagingSpec)
|
||||
{
|
||||
var baseQuery = query.Join<Blacklist, Series>(JoinType.Inner, h => h.Series, (h, s) => h.SeriesId == s.Id);
|
||||
var baseQuery = query.Join<Blacklist, Movie>(JoinType.Inner, h => h.Movie, (h, s) => h.MovieId == s.Id);
|
||||
|
||||
return base.GetPagedQuery(baseQuery, pagingSpec);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace NzbDrone.Core.Blacklisting
|
||||
|
||||
IExecute<ClearBlacklistCommand>,
|
||||
IHandle<DownloadFailedEvent>,
|
||||
IHandleAsync<SeriesDeletedEvent>
|
||||
IHandleAsync<MovieDeletedEvent>
|
||||
{
|
||||
private readonly IBlacklistRepository _blacklistRepository;
|
||||
|
||||
@@ -128,8 +128,9 @@ namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
var blacklist = new Blacklist
|
||||
{
|
||||
SeriesId = message.SeriesId,
|
||||
SeriesId = 0,
|
||||
EpisodeIds = message.EpisodeIds,
|
||||
MovieId = message.MovieId,
|
||||
SourceTitle = message.SourceTitle,
|
||||
Quality = message.Quality,
|
||||
Date = DateTime.UtcNow,
|
||||
@@ -144,9 +145,9 @@ namespace NzbDrone.Core.Blacklisting
|
||||
_blacklistRepository.Insert(blacklist);
|
||||
}
|
||||
|
||||
public void HandleAsync(SeriesDeletedEvent message)
|
||||
public void HandleAsync(MovieDeletedEvent message)
|
||||
{
|
||||
var blacklisted = _blacklistRepository.BlacklistedBySeries(message.Series.Id);
|
||||
var blacklisted = _blacklistRepository.BlacklistedByMovie(message.Movie.Id);
|
||||
|
||||
_blacklistRepository.DeleteMany(blacklisted);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace NzbDrone.Core.Configuration
|
||||
|
||||
public int RssSyncInterval
|
||||
{
|
||||
get { return GetValueInt("RssSyncInterval", 15); }
|
||||
get { return GetValueInt("RssSyncInterval", 60); }
|
||||
|
||||
set { SetValue("RssSyncInterval", value); }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using System.Data;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(122)]
|
||||
public class add_movieid_to_blacklist : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Blacklist").AddColumn("MovieId").AsInt32().Nullable().WithDefaultValue(0);
|
||||
Alter.Table("Blacklist").AlterColumn("SeriesId").AsInt32().Nullable();
|
||||
Alter.Table("Blacklist").AlterColumn("EpisodeIds").AsString().Nullable();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,17 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
private int CompareProtocol(DownloadDecision x, DownloadDecision y)
|
||||
{
|
||||
|
||||
|
||||
if (x.IsForMovie)
|
||||
{
|
||||
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||
{
|
||||
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Movie.Tags);
|
||||
var downloadProtocol = remoteEpisode.Release.DownloadProtocol;
|
||||
return downloadProtocol == delayProfile.PreferredProtocol;
|
||||
});
|
||||
}
|
||||
|
||||
var result = CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode =>
|
||||
{
|
||||
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Series.Tags);
|
||||
@@ -75,15 +86,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
return downloadProtocol == delayProfile.PreferredProtocol;
|
||||
});
|
||||
|
||||
if (x.IsForMovie)
|
||||
{
|
||||
result = CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode =>
|
||||
{
|
||||
var delayProfile = _delayProfileService.BestForTags(remoteEpisode.Movie.Tags);
|
||||
var downloadProtocol = remoteEpisode.Release.DownloadProtocol;
|
||||
return downloadProtocol == delayProfile.PreferredProtocol;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -125,8 +128,8 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
|
||||
private int CompareAgeIfUsenet(DownloadDecision x, DownloadDecision y)
|
||||
{
|
||||
if (x.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Usenet ||
|
||||
y.RemoteEpisode.Release.DownloadProtocol != DownloadProtocol.Usenet)
|
||||
if (x.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Usenet ||
|
||||
y.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Usenet)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ namespace NzbDrone.Core.DecisionEngine
|
||||
public List<DownloadDecision> PrioritizeDecisionsForMovies(List<DownloadDecision> decisions)
|
||||
{
|
||||
return decisions.Where(c => c.RemoteMovie.Movie != null)
|
||||
/*.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
|
||||
.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
|
||||
{
|
||||
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService));
|
||||
})
|
||||
.SelectMany(c => c)*/
|
||||
.SelectMany(c => c)
|
||||
.Union(decisions.Where(c => c.RemoteMovie.Movie == null))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
|
||||
throw new NotImplementedException();
|
||||
if (_blacklistService.Blacklisted(subject.Movie.Id, subject.Release))
|
||||
{
|
||||
_logger.Debug("{0} is blacklisted, rejecting.", subject.Release.Title);
|
||||
return Decision.Reject("Release is blacklisted");
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,21 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||
|
||||
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (searchCriteria != null)
|
||||
{
|
||||
if (searchCriteria.UserInvokedSearch)
|
||||
{
|
||||
_logger.Debug("Skipping monitored check during search");
|
||||
return Decision.Accept();
|
||||
}
|
||||
}
|
||||
|
||||
if (!subject.Movie.Monitored)
|
||||
{
|
||||
return Decision.Reject("Movie is not monitored");
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||
|
||||
@@ -32,9 +32,12 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
protected override string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContents)
|
||||
{
|
||||
var category = Settings.TvCategory;
|
||||
|
||||
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||
|
||||
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, Settings);
|
||||
var addpaused = Settings.AddPaused;
|
||||
|
||||
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, addpaused, Settings);
|
||||
|
||||
if (response == null)
|
||||
{
|
||||
@@ -47,9 +50,12 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
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);
|
||||
var addpaused = Settings.AddPaused;
|
||||
|
||||
var response = _proxy.DownloadNzb(fileContents, filename, category, priority, addpaused, Settings);
|
||||
|
||||
if(response == null)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
{
|
||||
public interface INzbgetProxy
|
||||
{
|
||||
string DownloadNzb(byte[] nzbData, string title, string category, int priority, NzbgetSettings settings);
|
||||
string DownloadNzb(byte[] nzbData, string title, string category, int priority, bool addpaused, NzbgetSettings settings);
|
||||
NzbgetGlobalStatus GetGlobalStatus(NzbgetSettings settings);
|
||||
List<NzbgetQueueItem> GetQueue(NzbgetSettings settings);
|
||||
List<NzbgetHistoryItem> GetHistory(NzbgetSettings settings);
|
||||
@@ -45,12 +45,12 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
return version >= minimumVersion;
|
||||
}
|
||||
|
||||
public string DownloadNzb(byte[] nzbData, string title, string category, int priority, NzbgetSettings settings)
|
||||
public string DownloadNzb(byte[] nzbData, string title, string category, int priority, bool addpaused, NzbgetSettings settings)
|
||||
{
|
||||
if (HasVersion(16, settings))
|
||||
{
|
||||
var droneId = Guid.NewGuid().ToString().Replace("-", "");
|
||||
var response = ProcessRequest<int>(settings, "append", title, nzbData, category, priority, false, false, string.Empty, 0, "all", new string[] { "drone", droneId });
|
||||
var response = ProcessRequest<int>(settings, "append", title, nzbData, category, priority, false, addpaused, string.Empty, 0, "all", new string[] { "drone", droneId });
|
||||
if (response <= 0)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -57,6 +57,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||
public bool UseSsl { get; set; }
|
||||
|
||||
[FieldDefinition(8, Label = "Add Paused", Type = FieldType.Checkbox, HelpText = "This option requires at least NzbGet version 16.0")]
|
||||
public bool AddPaused { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
||||
@@ -5,6 +5,7 @@ using NzbDrone.Core.IndexerSearch;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Tv;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.Download
|
||||
{
|
||||
@@ -38,7 +39,7 @@ namespace NzbDrone.Core.Download
|
||||
{
|
||||
_logger.Debug("Failed download contains a movie, searching again.");
|
||||
|
||||
_commandQueueManager.Push(new MoviesSearchCommand { MovieId = message.MovieId });
|
||||
_commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List<int> { message.MovieId } });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,13 +102,13 @@ namespace NzbDrone.Core.Extras
|
||||
|
||||
public void Handle(MediaCoversUpdatedEvent message)
|
||||
{
|
||||
var series = message.Series;
|
||||
var episodeFiles = GetEpisodeFiles(series.Id);
|
||||
//var series = message.Series;
|
||||
//var episodeFiles = GetEpisodeFiles(series.Id);
|
||||
|
||||
foreach (var extraFileManager in _extraFileManagers)
|
||||
{
|
||||
extraFileManager.CreateAfterSeriesScan(series, episodeFiles);
|
||||
}
|
||||
//foreach (var extraFileManager in _extraFileManagers)
|
||||
//{
|
||||
// extraFileManager.CreateAfterSeriesScan(series, episodeFiles);
|
||||
//}
|
||||
}
|
||||
|
||||
//TODO: Implementing this will fix a lot of our warning exceptions
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Core.IndexerSearch
|
||||
{
|
||||
public class MissingMoviesSearchCommand : Command
|
||||
{
|
||||
public override bool SendUpdatesToClient => true;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.IndexerSearch
|
||||
{
|
||||
public class MoviesSearchCommand : Command
|
||||
{
|
||||
public int MovieId { get; set; }
|
||||
public List<int> MovieIds { get; set; }
|
||||
|
||||
public override bool SendUpdatesToClient => true;
|
||||
}
|
||||
|
||||
@@ -4,22 +4,23 @@ using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.IndexerSearch
|
||||
{
|
||||
public class MovieSearchService : IExecute<MoviesSearchCommand>
|
||||
public class MovieSearchService : IExecute<MoviesSearchCommand>, IExecute<MissingMoviesSearchCommand>
|
||||
{
|
||||
private readonly IMovieService _seriesService;
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly ISearchForNzb _nzbSearchService;
|
||||
private readonly IProcessDownloadDecisions _processDownloadDecisions;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MovieSearchService(IMovieService seriesService,
|
||||
public MovieSearchService(IMovieService movieService,
|
||||
ISearchForNzb nzbSearchService,
|
||||
IProcessDownloadDecisions processDownloadDecisions,
|
||||
Logger logger)
|
||||
{
|
||||
_seriesService = seriesService;
|
||||
_movieService = movieService;
|
||||
_nzbSearchService = nzbSearchService;
|
||||
_processDownloadDecisions = processDownloadDecisions;
|
||||
_logger = logger;
|
||||
@@ -27,20 +28,35 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
|
||||
public void Execute(MoviesSearchCommand message)
|
||||
{
|
||||
var series = _seriesService.GetMovie(message.MovieId);
|
||||
|
||||
var downloadedCount = 0;
|
||||
|
||||
foreach (var movieId in message.MovieIds)
|
||||
{
|
||||
var series = _movieService.GetMovie(movieId);
|
||||
|
||||
if (!series.Monitored)
|
||||
{
|
||||
_logger.Debug("Movie {0} is not monitored, skipping search", series.Title);
|
||||
}
|
||||
|
||||
var decisions = _nzbSearchService.MovieSearch(message.MovieId, false);//_nzbSearchService.SeasonSearch(message.MovieId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual);
|
||||
var decisions = _nzbSearchService.MovieSearch(movieId, false);//_nzbSearchService.SeasonSearch(message.MovieId, season.SeasonNumber, false, message.Trigger == CommandTrigger.Manual);
|
||||
downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count;
|
||||
|
||||
|
||||
}
|
||||
_logger.ProgressInfo("Movie search completed. {0} reports downloaded.", downloadedCount);
|
||||
}
|
||||
|
||||
public void Execute(MissingMoviesSearchCommand message)
|
||||
{
|
||||
var movies = _movieService.MoviesWithoutFiles(new PagingSpec<Movie>
|
||||
{
|
||||
Page = 1,
|
||||
PageSize = 100000,
|
||||
SortDirection = SortDirection.Ascending,
|
||||
SortKey = "Id",
|
||||
FilterExpression =
|
||||
v =>
|
||||
v.Monitored == true
|
||||
}).Records.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,13 +54,19 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||
|
||||
private IEnumerable<IndexerRequest> GetRequest(string searchParameters)
|
||||
{
|
||||
var onlyInternal = "";
|
||||
if (Settings.Internal)
|
||||
{
|
||||
onlyInternal = "&internal=true";
|
||||
}
|
||||
|
||||
if (searchParameters != null)
|
||||
{
|
||||
yield return new IndexerRequest(string.Format("{0}/searchapi.php?action=imdbsearch&passkey={1}&imdb={2}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.Passkey.Trim(), searchParameters), HttpAccept.Rss);
|
||||
yield return new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/searchapi.php?action=imdbsearch&passkey={Settings.Passkey.Trim()}&imdb={searchParameters}", HttpAccept.Rss);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new IndexerRequest(string.Format("{0}/searchapi.php?action=latestmovies&passkey={1}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.Passkey.Trim()), HttpAccept.Rss);
|
||||
yield return new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/searchapi.php?action=latestmovies&passkey={Settings.Passkey.Trim()}{onlyInternal}", HttpAccept.Rss);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||
[FieldDefinition(1, Label = "Passkey")]
|
||||
public string Passkey { get; set; }
|
||||
|
||||
[FieldDefinition(2, Type = FieldType.Checkbox, Label = "Require Internal", HelpText = "Will only include internal releases for RSS Sync.")]
|
||||
public bool Internal { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
||||
@@ -30,12 +30,14 @@ namespace NzbDrone.Core.Jobs
|
||||
{
|
||||
private readonly IScheduledTaskRepository _scheduledTaskRepository;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, Logger logger)
|
||||
public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, IConfigFileProvider configFileProvider, Logger logger)
|
||||
{
|
||||
_scheduledTaskRepository = scheduledTaskRepository;
|
||||
_configService = configService;
|
||||
_configFileProvider = configFileProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -59,12 +61,19 @@ namespace NzbDrone.Core.Jobs
|
||||
|
||||
public void Handle(ApplicationStartedEvent message)
|
||||
{
|
||||
float updateInterval = 6 * 60;
|
||||
|
||||
if (_configFileProvider.Branch == "nightly")
|
||||
{
|
||||
updateInterval = 30;
|
||||
}
|
||||
|
||||
var defaultTasks = new[]
|
||||
{
|
||||
new ScheduledTask{ Interval = 0.25f, TypeName = typeof(CheckForFinishedDownloadCommand).FullName},
|
||||
new ScheduledTask{ Interval = 5, TypeName = typeof(MessagingCleanupCommand).FullName},
|
||||
new ScheduledTask{ Interval = 6*60, TypeName = typeof(ApplicationUpdateCommand).FullName},
|
||||
new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName},
|
||||
new ScheduledTask{ Interval = updateInterval, TypeName = typeof(ApplicationUpdateCommand).FullName},
|
||||
// new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName},
|
||||
new ScheduledTask{ Interval = 6*60, TypeName = typeof(CheckHealthCommand).FullName},
|
||||
new ScheduledTask{ Interval = 24*60, TypeName = typeof(RefreshMovieCommand).FullName},
|
||||
new ScheduledTask{ Interval = 24*60, TypeName = typeof(HousekeepingCommand).FullName},
|
||||
@@ -80,6 +89,7 @@ namespace NzbDrone.Core.Jobs
|
||||
{
|
||||
Interval = _configService.DownloadedEpisodesScanInterval,
|
||||
TypeName = typeof(DownloadedEpisodesScanCommand).FullName
|
||||
//TypeName = typeof(DownloadedMovieScanCommand).FullName
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using NzbDrone.Common.Disk;
|
||||
using System;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using System.Drawing;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Core.MediaCover
|
||||
{
|
||||
@@ -12,11 +15,13 @@ namespace NzbDrone.Core.MediaCover
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient)
|
||||
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient, Logger logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool AlreadyExists(string url, string path)
|
||||
@@ -26,9 +31,38 @@ namespace NzbDrone.Core.MediaCover
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsValidGDIPlusImage(path))
|
||||
{
|
||||
_diskProvider.DeleteFile(path);
|
||||
return false;
|
||||
}
|
||||
|
||||
var headers = _httpClient.Head(new HttpRequest(url)).Headers;
|
||||
var fileSize = _diskProvider.GetFileSize(path);
|
||||
return fileSize == headers.ContentLength;
|
||||
}
|
||||
|
||||
private bool IsValidGDIPlusImage(string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
GdiPlusInterop.CheckGdiPlus();
|
||||
|
||||
using (var bmp = new Bitmap(filename))
|
||||
{
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (DllNotFoundException ex)
|
||||
{
|
||||
_logger.Error(ex, "Could not find libgdiplus. Cannot test if image is corrupt.");
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex, "Corrupted image found at: {0}. Redownloading...", filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ namespace NzbDrone.Core.MediaCover
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureCovers(Movie movie)
|
||||
private void EnsureCovers(Movie movie, int retried = 0)
|
||||
{
|
||||
foreach (var cover in movie.Images)
|
||||
{
|
||||
@@ -130,7 +130,25 @@ namespace NzbDrone.Core.MediaCover
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
_logger.Warn(string.Format("Couldn't download media cover for {0}. {1}", movie, e.Message));
|
||||
if (e.Status == WebExceptionStatus.ProtocolError)
|
||||
{
|
||||
_logger.Warn(e, "Server returned different code than 200. The poster is probably not available yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Warn(e, string.Format("Couldn't download media cover for {0}. {1}", movie, e.Message));
|
||||
if (retried < 3)
|
||||
{
|
||||
retried = +1;
|
||||
_logger.Warn("Retrying for the {0}. time in ten seconds.", retried);
|
||||
System.Threading.Thread.Sleep(10*1000);
|
||||
EnsureCovers(movie, retried);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn(e, "Couldn't download media cover even after retrying five times :(.");
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -68,22 +68,22 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||
{
|
||||
//check if already imported
|
||||
if (importResults.Select(r => r.ImportDecision.LocalMovie.Movie)
|
||||
.Select(e => e.Id).Contains(localMovie.Movie.Id))
|
||||
.Select(m => m.Id).Contains(localMovie.Movie.Id))
|
||||
{
|
||||
importResults.Add(new ImportResult(importDecision, "Movie has already been imported"));
|
||||
continue;
|
||||
}
|
||||
|
||||
var episodeFile = new MovieFile();
|
||||
episodeFile.DateAdded = DateTime.UtcNow;
|
||||
episodeFile.MovieId = localMovie.Movie.Id;
|
||||
episodeFile.Path = localMovie.Path.CleanFilePath();
|
||||
episodeFile.Size = _diskProvider.GetFileSize(localMovie.Path);
|
||||
episodeFile.Quality = localMovie.Quality;
|
||||
episodeFile.MediaInfo = localMovie.MediaInfo;
|
||||
episodeFile.Movie = localMovie.Movie;
|
||||
episodeFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
||||
episodeFile.Edition = localMovie.ParsedMovieInfo.Edition;
|
||||
var movieFile = new MovieFile();
|
||||
movieFile.DateAdded = DateTime.UtcNow;
|
||||
movieFile.MovieId = localMovie.Movie.Id;
|
||||
movieFile.Path = localMovie.Path.CleanFilePath();
|
||||
movieFile.Size = _diskProvider.GetFileSize(localMovie.Path);
|
||||
movieFile.Quality = localMovie.Quality;
|
||||
movieFile.MediaInfo = localMovie.MediaInfo;
|
||||
movieFile.Movie = localMovie.Movie;
|
||||
movieFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
||||
movieFile.Edition = localMovie.ParsedMovieInfo.Edition;
|
||||
|
||||
bool copyOnly;
|
||||
switch (importMode)
|
||||
@@ -102,17 +102,17 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||
|
||||
if (newDownload)
|
||||
{
|
||||
episodeFile.SceneName = GetSceneName(downloadClientItem, localMovie);
|
||||
movieFile.SceneName = GetSceneName(downloadClientItem, localMovie);
|
||||
|
||||
var moveResult = _episodeFileUpgrader.UpgradeMovieFile(episodeFile, localMovie, copyOnly);
|
||||
var moveResult = _episodeFileUpgrader.UpgradeMovieFile(movieFile, localMovie, copyOnly); //TODO: Check if this works
|
||||
oldFiles = moveResult.OldFiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
episodeFile.RelativePath = localMovie.Movie.Path.GetRelativePath(episodeFile.Path);
|
||||
movieFile.RelativePath = localMovie.Movie.Path.GetRelativePath(movieFile.Path);
|
||||
}
|
||||
|
||||
_mediaFileService.Add(episodeFile);
|
||||
_mediaFileService.Add(movieFile);
|
||||
importResults.Add(new ImportResult(importDecision));
|
||||
|
||||
if (newDownload)
|
||||
@@ -122,22 +122,22 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||
|
||||
if (downloadClientItem != null)
|
||||
{
|
||||
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, episodeFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId, downloadClientItem.IsReadOnly));
|
||||
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId, downloadClientItem.IsReadOnly));
|
||||
}
|
||||
else
|
||||
{
|
||||
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, episodeFile, newDownload));
|
||||
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload));
|
||||
}
|
||||
|
||||
if (newDownload)
|
||||
{
|
||||
_eventAggregator.PublishEvent(new MovieDownloadedEvent(localMovie, episodeFile, oldFiles));
|
||||
_eventAggregator.PublishEvent(new MovieDownloadedEvent(localMovie, movieFile, oldFiles));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Warn(e, "Couldn't import episode " + localMovie);
|
||||
importResults.Add(new ImportResult(importDecision, "Failed to import episode"));
|
||||
_logger.Warn(e, "Couldn't import movie " + localMovie);
|
||||
importResults.Add(new ImportResult(importDecision, "Failed to import movie"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,11 +111,11 @@ namespace NzbDrone.Core.MediaFiles
|
||||
|
||||
public List<string> FilterExistingFiles(List<string> files, Movie movie)
|
||||
{
|
||||
var seriesFiles = GetFilesBySeries(movie.Id).Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList();
|
||||
var movieFiles = GetFilesByMovie(movie.Id).Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList();
|
||||
|
||||
if (!seriesFiles.Any()) return files;
|
||||
if (!movieFiles.Any()) return files;
|
||||
|
||||
return files.Except(seriesFiles, PathEqualityComparer.Instance).ToList();
|
||||
return files.Except(movieFiles, PathEqualityComparer.Instance).ToList();
|
||||
}
|
||||
|
||||
public EpisodeFile Get(int id)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
@@ -18,14 +18,17 @@ namespace NzbDrone.Core.MediaFiles
|
||||
public class MediaFileTableCleanupService : IMediaFileTableCleanupService
|
||||
{
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MediaFileTableCleanupService(IMediaFileService mediaFileService,
|
||||
IMovieService movieService,
|
||||
IEpisodeService episodeService,
|
||||
Logger logger)
|
||||
{
|
||||
_mediaFileService = mediaFileService;
|
||||
_movieService = movieService;
|
||||
_episodeService = episodeService;
|
||||
_logger = logger;
|
||||
}
|
||||
@@ -89,61 +92,39 @@ namespace NzbDrone.Core.MediaFiles
|
||||
|
||||
public void Clean(Movie movie, List<string> filesOnDisk)
|
||||
{
|
||||
|
||||
//TODO: Update implementation for movies.
|
||||
var seriesFiles = _mediaFileService.GetFilesBySeries(movie.Id);
|
||||
var episodes = _episodeService.GetEpisodeBySeries(movie.Id);
|
||||
var movieFiles = _mediaFileService.GetFilesByMovie(movie.Id);
|
||||
|
||||
var filesOnDiskKeys = new HashSet<string>(filesOnDisk, PathEqualityComparer.Instance);
|
||||
|
||||
foreach (var seriesFile in seriesFiles)
|
||||
foreach(var movieFile in movieFiles)
|
||||
{
|
||||
var episodeFile = seriesFile;
|
||||
var episodeFilePath = Path.Combine(movie.Path, episodeFile.RelativePath);
|
||||
var movieFilePath = Path.Combine(movie.Path, movieFile.RelativePath);
|
||||
|
||||
try
|
||||
{
|
||||
if (!filesOnDiskKeys.Contains(episodeFilePath))
|
||||
if (!filesOnDiskKeys.Contains(movieFilePath))
|
||||
{
|
||||
_logger.Debug("File [{0}] no longer exists on disk, removing from db", episodeFilePath);
|
||||
_mediaFileService.Delete(seriesFile, DeleteMediaFileReason.MissingFromDisk);
|
||||
_logger.Debug("File [{0}] no longer exists on disk, removing from db", movieFilePath);
|
||||
_mediaFileService.Delete(movieFile, DeleteMediaFileReason.MissingFromDisk);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (episodes.None(e => e.EpisodeFileId == episodeFile.Id))
|
||||
{
|
||||
_logger.Debug("File [{0}] is not assigned to any episodes, removing from db", episodeFilePath);
|
||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.NoLinkedEpisodes);
|
||||
continue;
|
||||
}
|
||||
//var localMovie = _parsingService.GetLocalMovie(movieFile.Path, movie);
|
||||
|
||||
// var localEpsiode = _parsingService.GetLocalEpisode(episodeFile.Path, series);
|
||||
//
|
||||
// if (localEpsiode == null || episodes.Count != localEpsiode.Episodes.Count)
|
||||
// {
|
||||
// _logger.Debug("File [{0}] parsed episodes has changed, removing from db", episodeFile.Path);
|
||||
// _mediaFileService.Delete(episodeFile);
|
||||
// continue;
|
||||
// }
|
||||
//if (localMovie == null)
|
||||
//{
|
||||
// _logger.Debug("File [{0}] parsed episodes has changed, removing from db", localMovie.Path);
|
||||
// _mediaFileService.Delete(localMovie);
|
||||
// continue;
|
||||
//}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
var errorMessage = string.Format("Unable to cleanup EpisodeFile in DB: {0}", episodeFile.Id);
|
||||
var errorMessage = string.Format("Unable to cleanup MovieFile in DB: {0}", movieFile.Id);
|
||||
_logger.Error(ex, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var e in episodes)
|
||||
{
|
||||
var episode = e;
|
||||
|
||||
if (episode.EpisodeFileId > 0 && seriesFiles.None(f => f.Id == episode.EpisodeFileId))
|
||||
{
|
||||
episode.EpisodeFileId = 0;
|
||||
_episodeService.UpdateEpisode(episode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,12 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||
return AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? AudioChannels - 1 + 0.1m : AudioChannels;
|
||||
}
|
||||
|
||||
decimal channels = 0;
|
||||
|
||||
decimal.TryParse(AudioChannelPositions.Split('/').First(), out channels);
|
||||
|
||||
return channels;
|
||||
return
|
||||
AudioChannelPositions.Replace("Object Based /", "").Replace(" / ", "$")
|
||||
.Split('$')
|
||||
.First()
|
||||
.Split('/')
|
||||
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -107,7 +107,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||
return;
|
||||
}
|
||||
|
||||
/* var movies = _movieService.MoviesWithFiles(message.Series.Id);
|
||||
var movies = _movieService.MoviesWithFiles(message.Movie.Id);
|
||||
|
||||
var movieFiles = new List<MovieFile>();
|
||||
var updated = new List<MovieFile>();
|
||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||
|
||||
movieFiles.Add(movieFile);
|
||||
|
||||
if (ChangeFileDate(movieFile, message.Series, moviesInFile))
|
||||
if (ChangeFileDate(movieFile, message.Movie))
|
||||
{
|
||||
updated.Add(movieFile);
|
||||
}
|
||||
@@ -127,13 +127,13 @@ namespace NzbDrone.Core.MediaFiles
|
||||
|
||||
if (updated.Any())
|
||||
{
|
||||
_logger.ProgressDebug("Changed file date for {0} files of {1} in {2}", updated.Count, movieFiles.Count, message.Series.Title);
|
||||
_logger.ProgressDebug("Changed file date for {0} files of {1} in {2}", updated.Count, movieFiles.Count, message.Movie.Title);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_logger.ProgressDebug("No file dates changed for {0}", message.Series.Title);
|
||||
}*/
|
||||
_logger.ProgressDebug("No file dates changed for {0}", message.Movie.Title);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ChangeFileDateToLocalAirDate(string filePath, string fileDate, string fileTime)
|
||||
|
||||
@@ -38,10 +38,13 @@ namespace NzbDrone.Core.MediaFiles
|
||||
|
||||
public MovieFileMoveResult UpgradeMovieFile(MovieFile episodeFile, LocalMovie localEpisode, bool copyOnly = false)
|
||||
{
|
||||
_logger.Trace("Upgrading existing episode file.");
|
||||
var moveFileResult = new MovieFileMoveResult();
|
||||
localEpisode.Movie.MovieFile.LazyLoad();
|
||||
var existingFile = localEpisode.Movie.MovieFile;
|
||||
existingFile.LazyLoad();
|
||||
|
||||
if (existingFile.IsLoaded)
|
||||
if (existingFile.IsLoaded && existingFile.Value != null)
|
||||
{
|
||||
var file = existingFile.Value;
|
||||
var episodeFilePath = Path.Combine(localEpisode.Movie.Path, file.RelativePath);
|
||||
@@ -55,6 +58,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||
moveFileResult.OldFiles.Add(file);
|
||||
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn("The existing movie file was not lazy loaded.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Profiles;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource
|
||||
@@ -7,6 +8,6 @@ namespace NzbDrone.Core.MetadataSource
|
||||
public interface IProvideMovieInfo
|
||||
{
|
||||
Movie GetMovieInfo(string ImdbId);
|
||||
Movie GetMovieInfo(int TmdbId);
|
||||
Movie GetMovieInfo(int TmdbId, Profile profile);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ using NzbDrone.Core.Tv;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Profiles;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
{
|
||||
@@ -67,25 +69,39 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
return new Tuple<Series, List<Episode>>(series, episodes.ToList());
|
||||
}
|
||||
|
||||
public Movie GetMovieInfo(int TmdbId)
|
||||
public Movie GetMovieInfo(int TmdbId, Profile profile = null)
|
||||
{
|
||||
var langCode = profile != null ? IsoLanguages.Get(profile.Language).TwoLetterCode : "us";
|
||||
|
||||
var request = _movieBuilder.Create()
|
||||
.SetSegment("route", "movie")
|
||||
.SetSegment("id", TmdbId.ToString())
|
||||
.SetSegment("secondaryRoute", "")
|
||||
.AddQueryParam("append_to_response", "alternative_titles,release_dates,videos")
|
||||
.AddQueryParam("country", "US")
|
||||
.AddQueryParam("language", langCode.ToUpper())
|
||||
// .AddQueryParam("country", "US")
|
||||
.Build();
|
||||
|
||||
request.AllowAutoRedirect = true;
|
||||
request.SuppressHttpError = true;
|
||||
|
||||
var response = _httpClient.Get<MovieResourceRoot>(request);
|
||||
|
||||
var resource = response.Resource;
|
||||
|
||||
var movie = new Movie();
|
||||
|
||||
foreach (var alternativeTitle in resource.alternative_titles.titles)
|
||||
{
|
||||
if (alternativeTitle.iso_3166_1.ToLower() == langCode)
|
||||
{
|
||||
movie.AlternativeTitles.Add(alternativeTitle.title);
|
||||
}
|
||||
else if (alternativeTitle.iso_3166_1.ToLower() == "us")
|
||||
{
|
||||
movie.AlternativeTitles.Add(alternativeTitle.title);
|
||||
}
|
||||
}
|
||||
|
||||
movie.TmdbId = TmdbId;
|
||||
movie.ImdbId = resource.imdb_id;
|
||||
movie.Title = resource.title;
|
||||
@@ -106,10 +122,10 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
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);
|
||||
}
|
||||
//foreach(Title title in resource.alternative_titles.titles)
|
||||
//{
|
||||
// movie.AlternativeTitles.Add(title.title);
|
||||
//}
|
||||
|
||||
foreach(ReleaseDates releaseDates in resource.release_dates.results)
|
||||
{
|
||||
@@ -149,22 +165,28 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
{
|
||||
movie.Status = MovieStatusType.Announced;
|
||||
}
|
||||
|
||||
|
||||
if (resource.videos != null)
|
||||
{
|
||||
foreach(Video video in resource.videos.results)
|
||||
foreach (Video video in resource.videos.results)
|
||||
{
|
||||
if(video.type == "Trailer" && video.site == "YouTube")
|
||||
if (video.type == "Trailer" && video.site == "YouTube")
|
||||
{
|
||||
movie.YouTubeTrailerId = video.key;
|
||||
break;
|
||||
if (video.key != null)
|
||||
{
|
||||
movie.YouTubeTrailerId = video.key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resource.production_companies != null && resource.production_companies.Count() > 0)
|
||||
if (resource.production_companies != null)
|
||||
{
|
||||
movie.Studio = resource.production_companies[0].name;
|
||||
if (resource.production_companies.Any())
|
||||
{
|
||||
movie.Studio = resource.production_companies[0].name;
|
||||
}
|
||||
}
|
||||
|
||||
return movie;
|
||||
@@ -205,14 +227,14 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
|
||||
lowerTitle = lowerTitle.Replace(".", "");
|
||||
|
||||
var parserResult = Parser.Parser.ParseMovieTitle(title.Replace(".", ""), true);
|
||||
var parserResult = Parser.Parser.ParseMovieTitle(title, true);
|
||||
|
||||
var yearTerm = "";
|
||||
|
||||
if (parserResult != null && parserResult.MovieTitle != title)
|
||||
{
|
||||
//Parser found something interesting!
|
||||
lowerTitle = parserResult.MovieTitle.ToLower();
|
||||
lowerTitle = parserResult.MovieTitle.ToLower().Replace(".", " "); //TODO Update so not every period gets replaced (e.g. R.I.P.D.)
|
||||
if (parserResult.Year > 1800)
|
||||
{
|
||||
yearTerm = parserResult.Year.ToString();
|
||||
@@ -345,25 +367,19 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
{
|
||||
imdbMovie.SortTitle = Parser.Parser.NormalizeTitle(result.title);
|
||||
imdbMovie.Title = result.title;
|
||||
string titleSlug = ToUrlSlug(result.title);
|
||||
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
||||
imdbMovie.TitleSlug = ToUrlSlug(result.title);
|
||||
|
||||
if (result.release_date.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
imdbMovie.Year = DateTime.Parse(result.release_date).Year;
|
||||
}
|
||||
//var slugResult = _movieService.FindByTitleSlug(imdbMovie.TitleSlug);
|
||||
//if (slugResult != null)
|
||||
//{
|
||||
// _logger.Debug("Movie with this title slug already exists. Adding year...");
|
||||
//}
|
||||
imdbMovie.TitleSlug += "-" + imdbMovie.Year.ToString();
|
||||
|
||||
imdbMovie.TitleSlug += "-" + imdbMovie.Year;
|
||||
|
||||
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
||||
imdbMovie.Overview = result.overview;
|
||||
try
|
||||
{
|
||||
string url = result.poster_path;
|
||||
var imdbPoster = _configService.GetCoverForURL(result.poster_path, MediaCoverTypes.Poster);
|
||||
imdbMovie.Images.Add(imdbPoster);
|
||||
}
|
||||
|
||||
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
const string title = "Movie Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
const string title = "Movie Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -24,75 +25,65 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override string Link => "https://github.com/Sonarr/Sonarr/wiki/Custom-Post-Processing-Scripts";
|
||||
public override string Link => "https://github.com/Radarr/Radarr/wiki/Custom-Post-Processing-Scripts";
|
||||
|
||||
public override void OnGrab(GrabMessage message)
|
||||
{
|
||||
var series = message.Series;
|
||||
var remoteEpisode = message.Episode;
|
||||
var releaseGroup = remoteEpisode.ParsedEpisodeInfo.ReleaseGroup;
|
||||
var movie = message.Movie;
|
||||
var remoteMovie = message.RemoteMovie;
|
||||
var releaseGroup = remoteMovie.ParsedMovieInfo.ReleaseGroup;
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Sonarr_EventType", "Grab");
|
||||
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString());
|
||||
environmentVariables.Add("Sonarr_Series_Title", series.Title);
|
||||
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString());
|
||||
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString());
|
||||
environmentVariables.Add("Sonarr_Release_EpisodeCount", remoteEpisode.Episodes.Count.ToString());
|
||||
environmentVariables.Add("Sonarr_Release_SeasonNumber", remoteEpisode.ParsedEpisodeInfo.SeasonNumber.ToString());
|
||||
environmentVariables.Add("Sonarr_Release_EpisodeNumbers", string.Join(",", remoteEpisode.Episodes.Select(e => e.EpisodeNumber)));
|
||||
environmentVariables.Add("Sonarr_Release_Title", remoteEpisode.Release.Title);
|
||||
environmentVariables.Add("Sonarr_Release_Indexer", remoteEpisode.Release.Indexer);
|
||||
environmentVariables.Add("Sonarr_Release_Size", remoteEpisode.Release.Size.ToString());
|
||||
environmentVariables.Add("Sonarr_Release_ReleaseGroup", releaseGroup);
|
||||
environmentVariables.Add("Radarr_EventType", "Grab");
|
||||
environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
|
||||
environmentVariables.Add("Radarr_Movie_Title", movie.Title);
|
||||
environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId.ToString());
|
||||
environmentVariables.Add("Radarr_Release_Title", remoteMovie.Release.Title);
|
||||
environmentVariables.Add("Radarr_Release_Indexer", remoteMovie.Release.Indexer);
|
||||
environmentVariables.Add("Radarr_Release_Size", remoteMovie.Release.Size.ToString());
|
||||
environmentVariables.Add("Radarr_Release_ReleaseGroup", releaseGroup);
|
||||
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
var series = message.Series;
|
||||
var episodeFile = message.EpisodeFile;
|
||||
var movie = message.Movie;
|
||||
var movieFile = message.MovieFile;
|
||||
var sourcePath = message.SourcePath;
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Sonarr_EventType", "Download");
|
||||
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString());
|
||||
environmentVariables.Add("Sonarr_Series_Title", series.Title);
|
||||
environmentVariables.Add("Sonarr_Series_Path", series.Path);
|
||||
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString());
|
||||
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString());
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_Id", episodeFile.Id.ToString());
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeCount", episodeFile.Episodes.Value.Count.ToString());
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_RelativePath", episodeFile.RelativePath);
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_Path", Path.Combine(series.Path, episodeFile.RelativePath));
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_SeasonNumber", episodeFile.SeasonNumber.ToString());
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeNumbers", string.Join(",", episodeFile.Episodes.Value.Select(e => e.EpisodeNumber)));
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeAirDates", string.Join(",", episodeFile.Episodes.Value.Select(e => e.AirDate)));
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeAirDatesUtc", string.Join(",", episodeFile.Episodes.Value.Select(e => e.AirDateUtc)));
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_EpisodeTitles", string.Join("|", episodeFile.Episodes.Value.Select(e => e.Title)));
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_Quality", episodeFile.Quality.Quality.Name);
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_QualityVersion", episodeFile.Quality.Revision.Version.ToString());
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_ReleaseGroup", episodeFile.ReleaseGroup ?? string.Empty);
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_SceneName", episodeFile.SceneName ?? string.Empty);
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_SourcePath", sourcePath);
|
||||
environmentVariables.Add("Sonarr_EpisodeFile_SourceFolder", Path.GetDirectoryName(sourcePath));
|
||||
environmentVariables.Add("Radarr_EventType", "Download");
|
||||
environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
|
||||
environmentVariables.Add("Radarr_Movie_Title", movie.Title);
|
||||
environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId.ToString());
|
||||
environmentVariables.Add("Radarr_MovieFile_Id", movieFile.Id.ToString());
|
||||
environmentVariables.Add("Radarr_MovieFile_RelativePath", movieFile.RelativePath);
|
||||
environmentVariables.Add("Radarr_MovieFile_Path", Path.Combine(movie.Path, movieFile.RelativePath));
|
||||
environmentVariables.Add("Radarr_MovieFile_Quality", movieFile.Quality.Quality.Name);
|
||||
environmentVariables.Add("Radarr_MovieFile_QualityVersion", movieFile.Quality.Revision.Version.ToString());
|
||||
environmentVariables.Add("Radarr_MovieFile_ReleaseGroup", movieFile.ReleaseGroup ?? string.Empty);
|
||||
environmentVariables.Add("Radarr_MovieFile_SceneName", movieFile.SceneName ?? string.Empty);
|
||||
environmentVariables.Add("Radarr_MovieFile_SourcePath", sourcePath);
|
||||
environmentVariables.Add("Radarr_MovieFile_SourceFolder", Path.GetDirectoryName(sourcePath));
|
||||
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Radarr_EventType", "Rename");
|
||||
environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString());
|
||||
environmentVariables.Add("Radarr_Movie_Title", movie.Title);
|
||||
environmentVariables.Add("Radarr_Movie_Path", movie.Path);
|
||||
environmentVariables.Add("Radarr_Movie_TvdbId", movie.ImdbId.ToString());
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Sonarr_EventType", "Rename");
|
||||
environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString());
|
||||
environmentVariables.Add("Sonarr_Series_Title", series.Title);
|
||||
environmentVariables.Add("Sonarr_Series_Path", series.Path);
|
||||
environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString());
|
||||
environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString());
|
||||
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override string Name => "Custom Script";
|
||||
|
||||
@@ -8,8 +8,11 @@ namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public Series Series { get; set; }
|
||||
public Movie Movie { get; set; }
|
||||
public EpisodeFile EpisodeFile { get; set; }
|
||||
public List<EpisodeFile> OldFiles { get; set; }
|
||||
public MovieFile MovieFile { get; set; }
|
||||
public List<MovieFile> OldMovieFiles { get; set; }
|
||||
public string SourcePath { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.Email
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string subject = "Radarr [TV] - Grabbed";
|
||||
const string subject = "Radarr [Movie] - Grabbed";
|
||||
var body = string.Format("{0} sent to queue.", grabMessage.Message);
|
||||
|
||||
_emailService.SendEmail(Settings, subject, body);
|
||||
@@ -26,12 +26,16 @@ namespace NzbDrone.Core.Notifications.Email
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string subject = "Radarr [TV] - Downloaded";
|
||||
const string subject = "Radarr [Movie] - Downloaded";
|
||||
var body = string.Format("{0} Downloaded and sorted.", message.Message);
|
||||
|
||||
_emailService.SendEmail(Settings, subject, body);
|
||||
}
|
||||
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public Series Series { get; set; }
|
||||
public Movie Movie { get; set; }
|
||||
public RemoteMovie RemoteMovie { get; set; }
|
||||
public RemoteEpisode Episode { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
|
||||
|
||||
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
const string title = "Movie Grabbed";
|
||||
|
||||
_growlService.SendNotification(title, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
const string title = "Movie Downloaded";
|
||||
|
||||
_growlService.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace NzbDrone.Core.Notifications
|
||||
void OnGrab(GrabMessage grabMessage);
|
||||
void OnDownload(DownloadMessage message);
|
||||
void OnRename(Series series);
|
||||
void OnMovieRename(Movie movie);
|
||||
bool SupportsOnGrab { get; }
|
||||
bool SupportsOnDownload { get; }
|
||||
bool SupportsOnUpgrade { get; }
|
||||
|
||||
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Join
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Radarr - Episode Grabbed";
|
||||
const string title = "Radarr - Movie Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Radarr - Episode Downloaded";
|
||||
const string title = "Radarr - Movie Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace NzbDrone.Core.Notifications.Join
|
||||
request.AddParameter("apikey", settings.ApiKey);
|
||||
request.AddParameter("title", title);
|
||||
request.AddParameter("text", message);
|
||||
request.AddParameter("icon", "https://cdn.rawgit.com/Sonarr/Sonarr/develop/Logo/256.png"); // Use the Sonarr logo.
|
||||
request.AddParameter("icon", "https://cdn.rawgit.com/Radarr/Radarr/develop/Logo/256.png"); // Use the Radarr logo.
|
||||
|
||||
var response = client.ExecuteAndValidate(request);
|
||||
var res = Json.Deserialize<JoinResponseModel>(response.Content);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Radarr - Grabbed";
|
||||
const string title = "Radarr - Movie Grabbed";
|
||||
|
||||
if (Settings.Notify)
|
||||
{
|
||||
@@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Radarr - Downloaded";
|
||||
const string title = "Radarr - Movie Downloaded";
|
||||
|
||||
if (Settings.Notify)
|
||||
{
|
||||
@@ -41,6 +41,10 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
if (Settings.UpdateLibrary)
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace NzbDrone.Core.Notifications
|
||||
public abstract void OnGrab(GrabMessage grabMessage);
|
||||
public abstract void OnDownload(DownloadMessage message);
|
||||
public abstract void OnRename(Series series);
|
||||
public abstract void OnMovieRename(Movie movie);
|
||||
|
||||
public virtual bool SupportsOnGrab => true;
|
||||
public virtual bool SupportsOnDownload => true;
|
||||
|
||||
@@ -15,7 +15,11 @@ namespace NzbDrone.Core.Notifications
|
||||
public class NotificationService
|
||||
: IHandle<EpisodeGrabbedEvent>,
|
||||
IHandle<EpisodeDownloadedEvent>,
|
||||
IHandle<SeriesRenamedEvent>
|
||||
IHandle<SeriesRenamedEvent>,
|
||||
IHandle<MovieRenamedEvent>,
|
||||
IHandle<MovieGrabbedEvent>,
|
||||
IHandle<MovieDownloadedEvent>
|
||||
|
||||
{
|
||||
private readonly INotificationFactory _notificationFactory;
|
||||
private readonly Logger _logger;
|
||||
@@ -67,6 +71,41 @@ namespace NzbDrone.Core.Notifications
|
||||
qualityString);
|
||||
}
|
||||
|
||||
private string GetMessage(Movie movie, QualityModel quality)
|
||||
{
|
||||
var qualityString = quality.Quality.ToString();
|
||||
|
||||
if (quality.Revision.Version > 1)
|
||||
{
|
||||
qualityString += " Proper";
|
||||
}
|
||||
|
||||
return string.Format("{0} [{1}]",
|
||||
movie.Title,
|
||||
qualityString);
|
||||
}
|
||||
|
||||
private bool ShouldHandleMovie(ProviderDefinition definition, Movie movie)
|
||||
{
|
||||
var notificationDefinition = (NotificationDefinition)definition;
|
||||
|
||||
if (notificationDefinition.Tags.Empty())
|
||||
{
|
||||
_logger.Debug("No tags set for this notification.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (notificationDefinition.Tags.Intersect(movie.Tags).Any())
|
||||
{
|
||||
_logger.Debug("Notification and series have one or more matching tags.");
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: this message could be more clear
|
||||
_logger.Debug("{0} does not have any tags that match {1}'s tags", notificationDefinition.Name, movie.Title);
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ShouldHandleSeries(ProviderDefinition definition, Series series)
|
||||
{
|
||||
var notificationDefinition = (NotificationDefinition) definition;
|
||||
@@ -112,6 +151,33 @@ namespace NzbDrone.Core.Notifications
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(MovieGrabbedEvent message)
|
||||
{
|
||||
var grabMessage = new GrabMessage
|
||||
{
|
||||
Message = GetMessage(message.Movie.Movie, message.Movie.ParsedMovieInfo.Quality),
|
||||
Series = null,
|
||||
Quality = message.Movie.ParsedMovieInfo.Quality,
|
||||
Episode = null,
|
||||
Movie = message.Movie.Movie,
|
||||
RemoteMovie = message.Movie
|
||||
};
|
||||
|
||||
foreach (var notification in _notificationFactory.OnGrabEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldHandleMovie(notification.Definition, message.Movie.Movie)) continue;
|
||||
notification.OnGrab(grabMessage);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, "Unable to send OnGrab notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(EpisodeDownloadedEvent message)
|
||||
{
|
||||
var downloadMessage = new DownloadMessage();
|
||||
@@ -141,6 +207,38 @@ namespace NzbDrone.Core.Notifications
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(MovieDownloadedEvent message)
|
||||
{
|
||||
var downloadMessage = new DownloadMessage();
|
||||
downloadMessage.Message = GetMessage(message.Movie.Movie, message.Movie.Quality);
|
||||
downloadMessage.Series = null;
|
||||
downloadMessage.EpisodeFile = null;
|
||||
downloadMessage.MovieFile = message.MovieFile;
|
||||
downloadMessage.Movie = message.Movie.Movie;
|
||||
downloadMessage.OldFiles = null;
|
||||
downloadMessage.OldMovieFiles = message.OldFiles;
|
||||
downloadMessage.SourcePath = message.Movie.Path;
|
||||
|
||||
foreach (var notification in _notificationFactory.OnDownloadEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ShouldHandleMovie(notification.Definition, message.Movie.Movie))
|
||||
{
|
||||
if (downloadMessage.OldMovieFiles.Empty() || ((NotificationDefinition)notification.Definition).OnUpgrade)
|
||||
{
|
||||
notification.OnDownload(downloadMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnDownload notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(SeriesRenamedEvent message)
|
||||
{
|
||||
foreach (var notification in _notificationFactory.OnRenameEnabled())
|
||||
@@ -159,5 +257,24 @@ namespace NzbDrone.Core.Notifications
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(MovieRenamedEvent message)
|
||||
{
|
||||
foreach (var notification in _notificationFactory.OnRenameEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ShouldHandleMovie(notification.Definition, message.Movie))
|
||||
{
|
||||
notification.OnMovieRename(message.Movie);
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnRename notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,18 +19,22 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
const string title = "Movie Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
const string title = "Movie Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
_plexClientService.Notify(Settings, header, message.Message);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
Notify(Settings, header, message.Message);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
|
||||
|
||||
@@ -22,19 +22,24 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
UpdateIfEnabled(message.Series);
|
||||
UpdateIfEnabled(message.Movie);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
UpdateIfEnabled(movie);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
UpdateIfEnabled(series);
|
||||
//UpdateIfEnabled(movie);
|
||||
}
|
||||
|
||||
private void UpdateIfEnabled(Series series)
|
||||
private void UpdateIfEnabled(Movie movie)
|
||||
{
|
||||
if (Settings.UpdateLibrary)
|
||||
{
|
||||
_plexServerService.UpdateLibrary(series, Settings);
|
||||
_plexServerService.UpdateMovieSections(movie, Settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
public interface IPlexServerProxy
|
||||
{
|
||||
List<PlexSection> GetTvSections(PlexServerSettings settings);
|
||||
List<PlexSection> GetMovieSections(PlexServerSettings settings);
|
||||
void Update(int sectionId, PlexServerSettings settings);
|
||||
void UpdateSeries(int metadataId, PlexServerSettings settings);
|
||||
string Version(PlexServerSettings settings);
|
||||
@@ -66,6 +67,37 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public List<PlexSection> GetMovieSections(PlexServerSettings settings)
|
||||
{
|
||||
var request = GetPlexServerRequest("library/sections", Method.GET, settings);
|
||||
var client = GetPlexServerClient(settings);
|
||||
var response = client.Execute(request);
|
||||
|
||||
_logger.Trace("Sections response: {0}", response.Content);
|
||||
CheckForError(response, settings);
|
||||
|
||||
if (response.Content.Contains("_children"))
|
||||
{
|
||||
return Json.Deserialize<PlexMediaContainerLegacy>(response.Content)
|
||||
.Sections
|
||||
.Where(d => d.Type == "movie")
|
||||
.Select(s => new PlexSection
|
||||
{
|
||||
Id = s.Id,
|
||||
Language = s.Language,
|
||||
Locations = s.Locations,
|
||||
Type = s.Type
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return Json.Deserialize<PlexResponse<PlexSectionsContainer>>(response.Content)
|
||||
.MediaContainer
|
||||
.Sections
|
||||
.Where(d => d.Type == "movie")
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public void Update(int sectionId, PlexServerSettings settings)
|
||||
{
|
||||
var resource = string.Format("library/sections/{0}/refresh", sectionId);
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
public interface IPlexServerService
|
||||
{
|
||||
void UpdateLibrary(Series series, PlexServerSettings settings);
|
||||
void UpdateMovieSections(Movie movie, PlexServerSettings settings);
|
||||
ValidationFailure Test(PlexServerSettings settings);
|
||||
}
|
||||
|
||||
@@ -62,11 +63,43 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateMovieSections(Movie movie, PlexServerSettings settings)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Debug("Sending Update Request to Plex Server");
|
||||
|
||||
var version = _versionCache.Get(settings.Host, () => GetVersion(settings), TimeSpan.FromHours(2));
|
||||
ValidateVersion(version);
|
||||
|
||||
var sections = GetSections(settings);
|
||||
var partialUpdates = _partialUpdateCache.Get(settings.Host, () => PartialUpdatesAllowed(settings, version), TimeSpan.FromHours(2));
|
||||
|
||||
// TODO: Investiate partial updates later, for now just update all movie sections...
|
||||
|
||||
//if (partialUpdates)
|
||||
//{
|
||||
// UpdatePartialSection(series, sections, settings);
|
||||
//}
|
||||
|
||||
//else
|
||||
//{
|
||||
sections.ForEach(s => UpdateSection(s.Id, settings));
|
||||
//}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Failed to Update Plex host: " + settings.Host);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private List<PlexSection> GetSections(PlexServerSettings settings)
|
||||
{
|
||||
_logger.Debug("Getting sections from Plex host: {0}", settings.Host);
|
||||
|
||||
return _plexServerProxy.GetTvSections(settings).ToList();
|
||||
return _plexServerProxy.GetMovieSections(settings).ToList();
|
||||
}
|
||||
|
||||
private bool PartialUpdatesAllowed(PlexServerSettings settings, Version version)
|
||||
|
||||
@@ -19,18 +19,22 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
const string title = "Movie Grabbed";
|
||||
|
||||
_prowlService.SendNotification(title, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
const string title = "Movie Downloaded";
|
||||
|
||||
_prowlService.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Radarr - Episode Grabbed";
|
||||
const string title = "Radarr - Movie Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Radarr - Episode Downloaded";
|
||||
const string title = "Radarr - Movie Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Pushalot
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
const string title = "Movie Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
const string title = "Movie Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
const string title = "Movie Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
const string title = "Movie Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
public enum PushoverPriority
|
||||
{
|
||||
Silent = -1,
|
||||
Silent = -2,
|
||||
Quiet = -1,
|
||||
Normal = 0,
|
||||
High = 1,
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||
new Attachment
|
||||
{
|
||||
Fallback = message.Message,
|
||||
Title = message.Series.Title,
|
||||
Title = message.Movie.Title,
|
||||
Text = message.Message,
|
||||
Color = "warning"
|
||||
}
|
||||
@@ -59,7 +59,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||
new Attachment
|
||||
{
|
||||
Fallback = message.Message,
|
||||
Title = message.Series.Title,
|
||||
Title = message.Movie.Title,
|
||||
Text = message.Message,
|
||||
Color = "good"
|
||||
}
|
||||
@@ -69,6 +69,25 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||
NotifySlack(payload);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
var payload = new SlackPayload
|
||||
{
|
||||
IconEmoji = Settings.Icon,
|
||||
Username = Settings.Username,
|
||||
Text = "Renamed",
|
||||
Attachments = new List<Attachment>
|
||||
{
|
||||
new Attachment
|
||||
{
|
||||
Title = movie.Title,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NotifySlack(payload);
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
var payload = new SlackPayload
|
||||
|
||||
@@ -42,6 +42,10 @@ namespace NzbDrone.Core.Notifications.Synology
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
if (Settings.UpdateLibrary)
|
||||
|
||||
@@ -18,18 +18,22 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
const string title = "Episode Grabbed";
|
||||
const string title = "Movie Grabbed";
|
||||
|
||||
_proxy.SendNotification(title, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage message)
|
||||
{
|
||||
const string title = "Episode Downloaded";
|
||||
const string title = "Movie Downloaded";
|
||||
|
||||
_proxy.SendNotification(title, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||
_twitterService.SendNotification($"Imported: {message.Message}", Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||
_service.OnDownload(message.Series, message.EpisodeFile, Settings);
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
_service.OnRename(series, Settings);
|
||||
|
||||
@@ -36,6 +36,10 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||
UpdateAndClean(message.Series, message.OldFiles.Any());
|
||||
}
|
||||
|
||||
public override void OnMovieRename(Movie movie)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnRename(Series series)
|
||||
{
|
||||
UpdateAndClean(series);
|
||||
|
||||
@@ -183,6 +183,7 @@
|
||||
<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\004_updated_history.cs" />
|
||||
<Compile Include="Datastore\Migration\122_add_movieid_to_blacklist.cs" />
|
||||
<Compile Include="Datastore\Migration\121_update_filedate_config.cs" />
|
||||
<Compile Include="Datastore\Migration\120_add_studio_to_table.cs" />
|
||||
<Compile Include="Datastore\Migration\119_add_youtube_trailer_id_table .cs" />
|
||||
@@ -582,6 +583,7 @@
|
||||
<Compile Include="Http\HttpProxySettingsProvider.cs" />
|
||||
<Compile Include="Http\TorcacheHttpInterceptor.cs" />
|
||||
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
|
||||
<Compile Include="IndexerSearch\MissingMoviesSearchCommand.cs" />
|
||||
<Compile Include="IndexerSearch\MoviesSearchCommand.cs" />
|
||||
<Compile Include="IndexerSearch\MoviesSearchService.cs" />
|
||||
<Compile Include="Indexers\AwesomeHD\AwesomeHDRssParser.cs" />
|
||||
|
||||
@@ -46,8 +46,9 @@ namespace NzbDrone.Core.Organizer
|
||||
|
||||
_movie = new Movie
|
||||
{
|
||||
Title = "Movie Title",
|
||||
Year = 2010
|
||||
Title = "The Movie Title",
|
||||
Year = 2010,
|
||||
ImdbId = "tt0066921"
|
||||
};
|
||||
|
||||
_standardSeries = new Series
|
||||
@@ -124,7 +125,8 @@ namespace NzbDrone.Core.Organizer
|
||||
RelativePath = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE.mkv",
|
||||
SceneName = "Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE",
|
||||
ReleaseGroup = "RlsGrp",
|
||||
MediaInfo = mediaInfo
|
||||
MediaInfo = mediaInfo,
|
||||
Edition = "Ultimate extended edition",
|
||||
};
|
||||
|
||||
_singleEpisodeFile = new EpisodeFile
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
ThreeLetterCode = threeLetterCode;
|
||||
Language = language;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,20 +18,20 @@ namespace NzbDrone.Core.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>(\.?((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX)))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\.?((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX)))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
//Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition //TODO: Seems to slow down parsing heavily!
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX))",
|
||||
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Despecialized).(Cut|Edition|Version)|Extended|Uncensored|Remastered|Unrated|Uncut|IMAX))",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Normal movie format, e.g: Mission.Impossible.3.2011
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
//PassThePopcorn Torrent names: Star.Wars[PassThePopcorn]
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
//That did not work? Maybe some tool uses [] for years. Who would do that?
|
||||
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
};
|
||||
|
||||
@@ -268,7 +268,7 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
|
||||
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|2160[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
|
||||
@@ -696,6 +696,12 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
private static ParsedMovieInfo ParseMovieMatchCollection(MatchCollection matchCollection)
|
||||
{
|
||||
if (!matchCollection[0].Groups["title"].Success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' ');
|
||||
seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' ');
|
||||
|
||||
|
||||
@@ -396,9 +396,15 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
if (searchCriteria == null)
|
||||
{
|
||||
|
||||
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above!
|
||||
|
||||
if (parsedEpisodeInfo.Year > 1900)
|
||||
{
|
||||
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle, parsedEpisodeInfo.Year);
|
||||
//Todo: same as above!
|
||||
}
|
||||
else
|
||||
{
|
||||
movie = _movieService.FindByTitle(parsedEpisodeInfo.MovieTitle); //Todo: same as above!
|
||||
}
|
||||
return movie;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using Marr.Data.QGen;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
||||
namespace NzbDrone.Core.Tv
|
||||
{
|
||||
@@ -15,6 +17,8 @@ namespace NzbDrone.Core.Tv
|
||||
Movie FindByImdbId(string imdbid);
|
||||
Movie FindByTitleSlug(string slug);
|
||||
List<Movie> MoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
|
||||
List<Movie> MoviesWithFiles(int movieId);
|
||||
PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec);
|
||||
List<Movie> GetMoviesByFileId(int fileId);
|
||||
void SetFileId(int fileId, int movieId);
|
||||
}
|
||||
@@ -132,5 +136,30 @@ namespace NzbDrone.Core.Tv
|
||||
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
public List<Movie> MoviesWithFiles(int movieId)
|
||||
{
|
||||
return Query.Join<Movie, MovieFile>(JoinType.Inner, m => m.MovieFile, (m, mf) => m.MovieFileId == mf.Id)
|
||||
.Where(m => m.Id == movieId);
|
||||
}
|
||||
|
||||
public PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec)
|
||||
{
|
||||
|
||||
pagingSpec.TotalRecords = GetMoviesWithoutFilesQuery(pagingSpec).GetRowCount();
|
||||
pagingSpec.Records = GetMoviesWithoutFilesQuery(pagingSpec).ToList();
|
||||
|
||||
return pagingSpec;
|
||||
}
|
||||
|
||||
public SortBuilder<Movie> GetMoviesWithoutFilesQuery(PagingSpec<Movie> pagingSpec)
|
||||
{
|
||||
return Query.Where(pagingSpec.FilterExpression)
|
||||
.AndWhere(m => m.MovieFileId == 0)
|
||||
.AndWhere(m => m.Status == MovieStatusType.Released)
|
||||
.OrderBy(pagingSpec.OrderByClause(), pagingSpec.ToSortDirection())
|
||||
.Skip(pagingSpec.PagingOffset())
|
||||
.Take(pagingSpec.PageSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using NzbDrone.Core.IndexerSearch;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.Tv
|
||||
{
|
||||
@@ -37,7 +38,7 @@ namespace NzbDrone.Core.Tv
|
||||
|
||||
if (movie.AddOptions.SearchForMovie)
|
||||
{
|
||||
_commandQueueManager.Push(new MoviesSearchCommand { MovieId = movie.Id});
|
||||
_commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List<int> { movie.Id } });
|
||||
}
|
||||
|
||||
movie.AddOptions = null;
|
||||
|
||||
@@ -12,6 +12,7 @@ using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.Tv
|
||||
{
|
||||
@@ -27,12 +28,14 @@ namespace NzbDrone.Core.Tv
|
||||
Movie FindByTitleSlug(string slug);
|
||||
Movie GetMovieByFileId(int fileId);
|
||||
List<Movie> GetMoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
|
||||
PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec);
|
||||
void DeleteMovie(int movieId, bool deleteFiles);
|
||||
List<Movie> GetAllMovies();
|
||||
Movie UpdateMovie(Movie movie);
|
||||
List<Movie> UpdateMovie(List<Movie> movie);
|
||||
bool MoviePathExists(string folder);
|
||||
void RemoveAddOptions(Movie movie);
|
||||
List<Movie> MoviesWithFiles(int movieId);
|
||||
}
|
||||
|
||||
public class MovieService : IMovieService, IHandle<MovieFileAddedEvent>,
|
||||
@@ -232,5 +235,17 @@ namespace NzbDrone.Core.Tv
|
||||
|
||||
return episodes;
|
||||
}
|
||||
|
||||
public List<Movie> MoviesWithFiles(int movieId)
|
||||
{
|
||||
return _movieRepository.MoviesWithFiles(movieId);
|
||||
}
|
||||
|
||||
public PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec)
|
||||
{
|
||||
var movieResult = _movieRepository.MoviesWithoutFiles(pagingSpec);
|
||||
|
||||
return movieResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace NzbDrone.Core.Tv
|
||||
|
||||
try
|
||||
{
|
||||
movieInfo = _movieInfo.GetMovieInfo(movie.TmdbId);
|
||||
movieInfo = _movieInfo.GetMovieInfo(movie.TmdbId, movie.Profile);
|
||||
}
|
||||
catch (MovieNotFoundException)
|
||||
{
|
||||
|
||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 81 KiB |
BIN
src/Radarr.ico
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 81 KiB |
@@ -1,7 +1,7 @@
|
||||
var Marionette = require('marionette');
|
||||
var Backgrid = require('backgrid');
|
||||
var QueueCollection = require('./QueueCollection');
|
||||
var SeriesTitleCell = require('../../Cells/MovieTitleCell');
|
||||
var MovieTitleCell = require('../../Cells/MovieTitleCell');
|
||||
var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
|
||||
var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
|
||||
var QualityCell = require('../../Cells/QualityCell');
|
||||
@@ -30,7 +30,7 @@ module.exports = Marionette.Layout.extend({
|
||||
{
|
||||
name : 'movie',
|
||||
label : 'Movie',
|
||||
cell : SeriesTitleCell
|
||||
cell : MovieTitleCell
|
||||
},
|
||||
/*{
|
||||
name : 'episode',
|
||||
|
||||
42
src/UI/Cells/MovieStatusWithTextCell.js
Normal file
@@ -0,0 +1,42 @@
|
||||
var NzbDroneCell = require('./NzbDroneCell');
|
||||
|
||||
//used in Wanted tab
|
||||
module.exports = NzbDroneCell.extend({
|
||||
className : 'movie-status-text-cell',
|
||||
|
||||
render : function() {
|
||||
this.$el.empty();
|
||||
var monitored = this.model.get('monitored');
|
||||
var status = this.model.get('status');
|
||||
var inCinemas = this.model.get("inCinemas");
|
||||
var date = new Date(inCinemas);
|
||||
var timeSince = new Date().getTime() - date.getTime();
|
||||
var numOfMonths = timeSince / 1000 / 60 / 60 / 24 / 30;
|
||||
|
||||
if (status === 'released') {
|
||||
this.$el.html('<div class="released-banner"><i class="icon-sonarr-movie-released grid-icon" title=""></i> Released</div>');
|
||||
this._setStatusWeight(3);
|
||||
}
|
||||
|
||||
if (numOfMonths > 3) {
|
||||
this.$el.html('<div class="released-banner"><i class="icon-sonarr-movie-released grid-icon" title=""></i> Released</div>');//TODO: Update for PreDB.me
|
||||
this._setStatusWeight(2);
|
||||
}
|
||||
|
||||
if (numOfMonths < 3) {
|
||||
this.$el.html('<div class="cinemas-banner"><i class="icon-sonarr-movie-cinemas grid-icon" title=""></i> In Cinemas</div>');
|
||||
this._setStatusWeight(2);
|
||||
}
|
||||
|
||||
if (status === "announced") {
|
||||
this.$el.html('<div class="announced-banner"><i class="icon-sonarr-movie-announced grid-icon" title=""></i> Announced</div>');
|
||||
this._setStatusWeight(1);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_setStatusWeight : function(weight) {
|
||||
this.model.set('statusWeight', weight, { silent : true });
|
||||
}
|
||||
});
|
||||