Compare commits
16 Commits
v0.2.0.196
...
v0.2.0.210
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0bcb27beb | ||
|
|
ec6b389d75 | ||
|
|
f38430d632 | ||
|
|
266f28883a | ||
|
|
309877bf76 | ||
|
|
a50b20a397 | ||
|
|
de5489ae9a | ||
|
|
12e74aa38b | ||
|
|
80ec66b47c | ||
|
|
585fd87ad6 | ||
|
|
ec5161e848 | ||
|
|
0ec54daaff | ||
|
|
3ed1bebb7d | ||
|
|
29ae088a3d | ||
|
|
eb299ce847 | ||
|
|
a7e071318b |
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 |
42
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,32 @@ 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)
|
||||
|
||||
|
||||
## 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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,11 +61,18 @@ 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 = 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},
|
||||
|
||||
@@ -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,31 @@ 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
|
||||
{
|
||||
using (var bmp = new Bitmap(filename))
|
||||
{
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex, "Corrupted image found at: {0}. Redownloading...", filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,12 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
||||
return AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? AudioChannels - 1 + 0.1m : AudioChannels;
|
||||
}
|
||||
|
||||
decimal channels = 0;
|
||||
|
||||
decimal.TryParse(AudioChannelPositions.Split('/').First(), out channels);
|
||||
|
||||
return channels;
|
||||
return
|
||||
AudioChannelPositions.Replace(" / ", "$")
|
||||
.Split('$')
|
||||
.First()
|
||||
.Split('/')
|
||||
.Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,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" />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2,23 +2,26 @@ var $ = require('jquery');
|
||||
var vent = require('./vent');
|
||||
|
||||
module.exports = {
|
||||
ConfigNamespace : 'Radarr.',
|
||||
|
||||
Events : {
|
||||
ConfigUpdatedEvent : 'ConfigUpdatedEvent'
|
||||
},
|
||||
|
||||
Keys : {
|
||||
DefaultProfileId : 'DefaultProfileId',
|
||||
DefaultRootFolderId : 'DefaultRootFolderId',
|
||||
UseSeasonFolder : 'UseSeasonFolder',
|
||||
DefaultSeriesType : 'DefaultSeriesType',
|
||||
MonitorEpisodes : 'MonitorEpisodes',
|
||||
AdvancedSettings : 'advancedSettings'
|
||||
DefaultProfileId : 'RadarrDefaultProfileId',
|
||||
DefaultRootFolderId : 'RadarrDefaultRootFolderId',
|
||||
UseSeasonFolder : 'RadarrUseSeasonFolder',
|
||||
DefaultSeriesType : 'RadarrDefaultSeriesType',
|
||||
MonitorEpisodes : 'RadarrMonitorEpisodes',
|
||||
AdvancedSettings : 'RadarradvancedSettings'
|
||||
},
|
||||
|
||||
getValueJson : function (key, defaultValue) {
|
||||
var storeKey = this.ConfigNamespace + key;
|
||||
defaultValue = defaultValue || {};
|
||||
|
||||
var storeValue = window.localStorage.getItem(key);
|
||||
var storeValue = window.localStorage.getItem(storeKey);
|
||||
|
||||
if (!storeValue) {
|
||||
return defaultValue;
|
||||
@@ -34,7 +37,8 @@ module.exports = {
|
||||
},
|
||||
|
||||
getValue : function(key, defaultValue) {
|
||||
var storeValue = window.localStorage.getItem(key);
|
||||
var storeKey = this.ConfigNamespace + key;
|
||||
var storeValue = window.localStorage.getItem(storeKey);
|
||||
|
||||
if (!storeValue) {
|
||||
return defaultValue;
|
||||
@@ -48,22 +52,22 @@ module.exports = {
|
||||
},
|
||||
|
||||
setValue : function(key, value) {
|
||||
|
||||
console.log('Config: [{0}] => [{1}]'.format(key, value));
|
||||
var storeKey = this.ConfigNamespace + key;
|
||||
console.log('Config: [{0}] => [{1}]'.format(storeKey, value));
|
||||
|
||||
if (this.getValue(key) === value.toString()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
window.localStorage.setItem(key, value);
|
||||
window.localStorage.setItem(storeKey, value);
|
||||
vent.trigger(this.Events.ConfigUpdatedEvent, {
|
||||
key : key,
|
||||
value : value
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Unable to save config: [{0}] => [{1}]'.format(key, value));
|
||||
console.error('Unable to save config: [{0}] => [{1}]'.format(storeKey, value));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -209,7 +209,7 @@ module.exports = Marionette.Layout.extend({
|
||||
_moviesSearch : function() {
|
||||
CommandController.Execute('moviesSearch', {
|
||||
name : 'moviesSearch',
|
||||
movieId : this.model.id
|
||||
movieIds : [this.model.id]
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -182,6 +182,27 @@ module.exports = Marionette.Layout.extend({
|
||||
tooltip : 'Missing Only',
|
||||
icon : 'icon-sonarr-missing',
|
||||
callback : this._setFilter
|
||||
},
|
||||
{
|
||||
key : 'released',
|
||||
title : '',
|
||||
tooltip : 'Released',
|
||||
icon : 'icon-sonarr-movie-released',
|
||||
callback : this._setFilter
|
||||
},
|
||||
{
|
||||
key : 'announced',
|
||||
title : '',
|
||||
tooltip : 'Announced',
|
||||
icon : 'icon-sonarr-movie-announced',
|
||||
callback : this._setFilter
|
||||
},
|
||||
{
|
||||
key : 'cinemas',
|
||||
title : '',
|
||||
tooltip : 'In Cinemas',
|
||||
icon : 'icon-sonarr-movie-cinemas',
|
||||
callback : this._setFilter
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -67,6 +67,21 @@ var Collection = PageableCollection.extend({
|
||||
'missing' : [
|
||||
'downloaded',
|
||||
false
|
||||
],
|
||||
'released' : [
|
||||
null,
|
||||
null,
|
||||
function(model) { return model.getStatus() == "released"; }
|
||||
],
|
||||
'announced' : [
|
||||
null,
|
||||
null,
|
||||
function(model) { return model.getStatus() == "announced"; }
|
||||
],
|
||||
'cinemas' : [
|
||||
null,
|
||||
null,
|
||||
function(model) { return model.getStatus() == "inCinemas"; }
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 col-sm-pull-1">
|
||||
<input type="number" name="downloadedMovieScanInterval" class="form-control" />
|
||||
<input type="number" name="downloadedEpisodesScanInterval" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -165,11 +165,11 @@ module.exports = Marionette.Layout.extend({
|
||||
}));
|
||||
CommandController.bindToCommand({
|
||||
element : this.$('.x-search-selected'),
|
||||
command : { name : 'episodeSearch' }
|
||||
command : { name : 'moviesSearch' }
|
||||
});
|
||||
CommandController.bindToCommand({
|
||||
element : this.$('.x-search-missing'),
|
||||
command : { name : 'missingEpisodeSearch' }
|
||||
command : { name : 'missingMoviesSearch' }
|
||||
});
|
||||
},
|
||||
|
||||
@@ -187,20 +187,20 @@ module.exports = Marionette.Layout.extend({
|
||||
if (selected.length === 0) {
|
||||
Messenger.show({
|
||||
type : 'error',
|
||||
message : 'No episodes selected'
|
||||
message : 'No movies selected'
|
||||
});
|
||||
return;
|
||||
}
|
||||
var ids = _.pluck(selected, 'id');
|
||||
CommandController.Execute('episodeSearch', {
|
||||
name : 'episodeSearch',
|
||||
episodeIds : ids
|
||||
CommandController.Execute('moviesSearch', {
|
||||
name : 'moviesSearch',
|
||||
movieIds : ids
|
||||
});
|
||||
},
|
||||
_searchMissing : function() {
|
||||
if (window.confirm('Are you sure you want to search for {0} missing movies? '.format(this.collection.state.totalRecords) +
|
||||
'One API request to each indexer will be used for each movie. ' + 'This cannot be stopped once started.')) {
|
||||
CommandController.Execute('missingEpisodeSearch', { name : 'missingEpisodeSearch' });
|
||||
CommandController.Execute('missingMoviesSearch', { name : 'missingMoviesSearch' });
|
||||
}
|
||||
},
|
||||
_toggleMonitoredOfSelected : function() {
|
||||
@@ -209,7 +209,7 @@ module.exports = Marionette.Layout.extend({
|
||||
if (selected.length === 0) {
|
||||
Messenger.show({
|
||||
type : 'error',
|
||||
message : 'No episodes selected'
|
||||
message : 'No movies selected'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||