mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-23 06:45:19 -07:00
Manual Import works now!
Also fixed a few bugs.
This commit is contained in:
parent
dbe5946d10
commit
dd8af0ad8c
10 changed files with 247 additions and 138 deletions
34
src/NzbDrone.Api/NetImport/ListImportModule.cs
Normal file
34
src/NzbDrone.Api/NetImport/ListImportModule.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using Nancy.Extensions;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Movie;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.NetImport
|
||||
{
|
||||
public class ListImportModule : NzbDroneApiModule
|
||||
{
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly ISearchForNewMovie _movieSearch;
|
||||
|
||||
public ListImportModule(IMovieService movieService, ISearchForNewMovie movieSearch)
|
||||
: base("/movie/import")
|
||||
{
|
||||
_movieService = movieService;
|
||||
_movieSearch = movieSearch;
|
||||
Put["/"] = Movie => SaveAll();
|
||||
}
|
||||
|
||||
private Response SaveAll()
|
||||
{
|
||||
var resources = Request.Body.FromJson<List<MovieResource>>();
|
||||
|
||||
var Movies = resources.Select(MovieResource => _movieSearch.MapMovieToTmdbMovie(MovieResource.ToModel())).Where(m => m != null).DistinctBy(m => m.TmdbId).ToList();
|
||||
|
||||
return _movieService.AddMovies(Movies).ToResource().AsResponse(HttpStatusCode.Accepted);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -123,6 +123,7 @@
|
|||
<Compile Include="Movies\RenameMovieModule.cs" />
|
||||
<Compile Include="Movies\RenameMovieResource.cs" />
|
||||
<Compile Include="Movies\MovieEditorModule.cs" />
|
||||
<Compile Include="NetImport\ListImportModule.cs" />
|
||||
<Compile Include="NetImport\NetImportModule.cs" />
|
||||
<Compile Include="NetImport\NetImportResource.cs" />
|
||||
<Compile Include="Parse\ParseModule.cs" />
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Api.Movie
|
|||
|
||||
List<Core.Tv.Movie> realResults = new List<Core.Tv.Movie>();
|
||||
|
||||
foreach (var movie in results)
|
||||
/*foreach (var movie in results)
|
||||
{
|
||||
var mapped = _movieSearch.MapMovieToTmdbMovie(movie);
|
||||
|
||||
|
@ -36,9 +36,9 @@ namespace NzbDrone.Api.Movie
|
|||
{
|
||||
realResults.Add(mapped);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return MapToResource(realResults).AsResponse();
|
||||
return MapToResource(results).AsResponse();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|||
public bool adult { get; set; }
|
||||
public string backdrop_path { get; set; }
|
||||
public Belongs_To_Collection belongs_to_collection { get; set; }
|
||||
public int? status_code { get; set; }
|
||||
public string status_message { get; set; }
|
||||
public int budget { get; set; }
|
||||
public Genre[] genres { get; set; }
|
||||
public string homepage { get; set; }
|
||||
|
|
|
@ -84,6 +84,18 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
|
||||
var resource = response.Resource;
|
||||
|
||||
if (resource.status_message != null)
|
||||
{
|
||||
if (resource.status_code == 34)
|
||||
{
|
||||
_logger.Warn("Movie with TmdbId {0} could not be found. This is probably the case when the movie was deleted from TMDB.", TmdbId);
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.Warn(resource.status_message);
|
||||
return null;
|
||||
}
|
||||
|
||||
var movie = new Movie();
|
||||
|
||||
movie.TmdbId = TmdbId;
|
||||
|
@ -567,10 +579,9 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
Movie newMovie = movie;
|
||||
if (movie.TmdbId > 0)
|
||||
{
|
||||
return newMovie;
|
||||
newMovie = GetMovieInfo(movie.TmdbId);
|
||||
}
|
||||
|
||||
if (movie.ImdbId.IsNotNullOrWhiteSpace())
|
||||
else if (movie.ImdbId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
newMovie = GetMovieInfo(movie.ImdbId);
|
||||
}
|
||||
|
@ -586,7 +597,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
|
||||
if (newMovie == null)
|
||||
{
|
||||
_logger.Warn("Couldn't map movie {0} to a movie on The Movie DB.");
|
||||
_logger.Warn("Couldn't map movie {0} to a movie on The Movie DB. It will not be added :(", movie.Title);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ namespace NzbDrone.Core.NetImport
|
|||
private readonly IMovieService _movieService;
|
||||
private readonly ISearchForNewMovie _movieSearch;
|
||||
private readonly IRootFolderService _rootFolder;
|
||||
private string defaultRootFolder;
|
||||
|
||||
public NetImportSearchService(INetImportFactory netImportFactory, IMovieService movieService,
|
||||
ISearchForNewMovie movieSearch, IRootFolderService rootFolder, Logger logger)
|
||||
|
@ -34,11 +33,6 @@ namespace NzbDrone.Core.NetImport
|
|||
_movieService = movieService;
|
||||
_movieSearch = movieSearch;
|
||||
_rootFolder = rootFolder;
|
||||
var folder = _rootFolder.All().FirstOrDefault();
|
||||
if (folder != null)
|
||||
{
|
||||
defaultRootFolder = folder.Path;
|
||||
}
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace NzbDrone.Core.Tv
|
|||
Movie GetMovie(int movieId);
|
||||
List<Movie> GetMovies(IEnumerable<int> movieIds);
|
||||
Movie AddMovie(Movie newMovie);
|
||||
List<Movie> AddMovies(List<Movie> newMovies);
|
||||
Movie FindByImdbId(string imdbid);
|
||||
Movie FindByTitle(string title);
|
||||
Movie FindByTitle(string title, int year);
|
||||
|
@ -92,6 +93,35 @@ namespace NzbDrone.Core.Tv
|
|||
return newMovie;
|
||||
}
|
||||
|
||||
public List<Movie> AddMovies(List<Movie> newMovies)
|
||||
{
|
||||
_logger.Debug("Adding {0} movies", newMovies.Count);
|
||||
|
||||
newMovies.ForEach(m => Ensure.That(m, () => m).IsNotNull());
|
||||
|
||||
newMovies.ForEach(m =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(m.Path))
|
||||
{
|
||||
var folderName = _fileNameBuilder.GetMovieFolder(m);
|
||||
m.Path = Path.Combine(m.RootFolderPath, folderName);
|
||||
}
|
||||
|
||||
m.CleanTitle = m.Title.CleanSeriesTitle();
|
||||
m.SortTitle = MovieTitleNormalizer.Normalize(m.Title, m.TmdbId);
|
||||
m.Added = DateTime.UtcNow;
|
||||
});
|
||||
|
||||
_movieRepository.InsertMany(newMovies);
|
||||
|
||||
newMovies.ForEach(m =>
|
||||
{
|
||||
_eventAggregator.PublishEvent(new MovieAddedEvent(m));
|
||||
});
|
||||
|
||||
return newMovies;
|
||||
}
|
||||
|
||||
public Movie FindByTitle(string title)
|
||||
{
|
||||
return _movieRepository.FindByTitle(title.CleanSeriesTitle());
|
||||
|
|
|
@ -22,7 +22,8 @@ var MovieStatusCell = require('../../Cells/MovieStatusCell');
|
|||
var MovieDownloadStatusCell = require('../../Cells/MovieDownloadStatusCell');
|
||||
var DownloadedQualityCell = require('../../Cells/DownloadedQualityCell');
|
||||
var MoviesCollection = require('../../Movies/MoviesCollection');
|
||||
|
||||
var Messenger = require('../../Shared/Messenger');
|
||||
require('jquery.dotdotdot');
|
||||
var SchemaModal = require('../../Settings/NetImport/Add/NetImportSchemaModal');
|
||||
|
||||
module.exports = Marionette.Layout.extend({
|
||||
|
@ -35,7 +36,7 @@ module.exports = Marionette.Layout.extend({
|
|||
ui : {
|
||||
moviesSearch : '.x-movies-search',
|
||||
listSelection : ".x-list-selection",
|
||||
|
||||
importSelected : ".x-import-selected"
|
||||
},
|
||||
|
||||
columns : [
|
||||
|
@ -185,9 +186,24 @@ module.exports = Marionette.Layout.extend({
|
|||
_importSelected : function() {
|
||||
var selected = this.importGrid.getSelectedModels();
|
||||
console.log(selected);
|
||||
_.each(selected, function(elem){
|
||||
elem.save();
|
||||
})
|
||||
var promise = MoviesCollection.importFromList(selected);
|
||||
this.ui.importSelected.spinForPromise(promise);
|
||||
this.ui.importSelected.addClass('disabled');
|
||||
|
||||
Messenger.show({
|
||||
message : "Importing {0} movies. This can take multiple minutes depending on how many movies should be imported. Don't close this browser window until it is finished!".format(selected.length),
|
||||
hideOnNavigate : false,
|
||||
hideAfter : 30,
|
||||
type : "error"
|
||||
});
|
||||
|
||||
promise.done(function() {
|
||||
Messenger.show({
|
||||
message : "Imported movies from list.",
|
||||
hideAfter : 8,
|
||||
hideOnNavigate : true
|
||||
});
|
||||
});
|
||||
/*for (m in selected) {
|
||||
debugger;
|
||||
m.save()
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<button class="btn x-fetch-list">Fetch List</button>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<button class="btn btn-success x-import-selected">Import Selected</button>
|
||||
<button class="btn btn-success x-import-selected"><i class="icon-sonarr-add"></i> Import Selected</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,142 +10,163 @@ var moment = require('moment');
|
|||
require('../Mixins/backbone.signalr.mixin');
|
||||
|
||||
var Collection = PageableCollection.extend({
|
||||
url : window.NzbDrone.ApiRoot + '/movie',
|
||||
model : MovieModel,
|
||||
tableName : 'movie',
|
||||
url : window.NzbDrone.ApiRoot + '/movie',
|
||||
model : MovieModel,
|
||||
tableName : 'movie',
|
||||
|
||||
state : {
|
||||
sortKey : 'sortTitle',
|
||||
order : 1,
|
||||
pageSize : 100000,
|
||||
secondarySortKey : 'sortTitle',
|
||||
secondarySortOrder : -1
|
||||
},
|
||||
state : {
|
||||
sortKey : 'sortTitle',
|
||||
order : 1,
|
||||
pageSize : 100000,
|
||||
secondarySortKey : 'sortTitle',
|
||||
secondarySortOrder : -1
|
||||
},
|
||||
|
||||
mode : 'client',
|
||||
mode : 'client',
|
||||
|
||||
save : function() {
|
||||
var self = this;
|
||||
save : function() {
|
||||
var self = this;
|
||||
|
||||
var proxy = _.extend(new Backbone.Model(), {
|
||||
id : '',
|
||||
var proxy = _.extend(new Backbone.Model(), {
|
||||
id : '',
|
||||
|
||||
url : self.url + '/editor',
|
||||
url : self.url + '/editor',
|
||||
|
||||
toJSON : function() {
|
||||
return self.filter(function(model) {
|
||||
return model.edited;
|
||||
});
|
||||
}
|
||||
});
|
||||
toJSON : function() {
|
||||
return self.filter(function(model) {
|
||||
return model.edited;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.listenTo(proxy, 'sync', function(proxyModel, models) {
|
||||
this.add(models, { merge : true });
|
||||
this.trigger('save', this);
|
||||
});
|
||||
this.listenTo(proxy, 'sync', function(proxyModel, models) {
|
||||
this.add(models, { merge : true });
|
||||
this.trigger('save', this);
|
||||
});
|
||||
|
||||
return proxy.save();
|
||||
},
|
||||
return proxy.save();
|
||||
},
|
||||
|
||||
filterModes : {
|
||||
'all' : [
|
||||
null,
|
||||
null
|
||||
],
|
||||
'continuing' : [
|
||||
'status',
|
||||
'continuing'
|
||||
],
|
||||
'ended' : [
|
||||
'status',
|
||||
'ended'
|
||||
],
|
||||
'monitored' : [
|
||||
'monitored',
|
||||
true
|
||||
],
|
||||
'missing' : [
|
||||
'downloaded',
|
||||
false
|
||||
]
|
||||
},
|
||||
importFromList : function(models) {
|
||||
var self = this;
|
||||
|
||||
sortMappings : {
|
||||
title : {
|
||||
sortKey : 'sortTitle'
|
||||
},
|
||||
statusWeight : {
|
||||
sortValue : function(model, attr) {
|
||||
if (model.getStatus() == "released") {
|
||||
return 1;
|
||||
}
|
||||
if (model.getStatus() == "inCinemas") {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
downloadedQuality : {
|
||||
sortValue : function(model, attr) {
|
||||
if (model.get("movieFile")) {
|
||||
return 1000-model.get("movieFile").quality.quality.id;
|
||||
}
|
||||
var proxy = _.extend(new Backbone.Model(), {
|
||||
id : "",
|
||||
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
nextAiring : {
|
||||
sortValue : function(model, attr, order) {
|
||||
var nextAiring = model.get(attr);
|
||||
url : self.url + "/import",
|
||||
|
||||
if (nextAiring) {
|
||||
return moment(nextAiring).unix();
|
||||
}
|
||||
toJSON : function() {
|
||||
return models;
|
||||
}
|
||||
});
|
||||
|
||||
if (order === 1) {
|
||||
return 0;
|
||||
}
|
||||
this.listenTo(proxy, "sync", function(proxyModel, models) {
|
||||
this.add(models, { merge : true});
|
||||
this.trigger("save", this);
|
||||
});
|
||||
|
||||
return Number.MAX_VALUE;
|
||||
}
|
||||
},
|
||||
status: {
|
||||
sortValue : function(model, attr) {
|
||||
debugger;
|
||||
if (model.get("downloaded")) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
percentOfEpisodes : {
|
||||
sortValue : function(model, attr) {
|
||||
var percentOfEpisodes = model.get(attr);
|
||||
var episodeCount = model.get('episodeCount');
|
||||
return proxy.save();
|
||||
},
|
||||
|
||||
return percentOfEpisodes + episodeCount / 1000000;
|
||||
}
|
||||
},
|
||||
inCinemas : {
|
||||
filterModes : {
|
||||
'all' : [
|
||||
null,
|
||||
null
|
||||
],
|
||||
'continuing' : [
|
||||
'status',
|
||||
'continuing'
|
||||
],
|
||||
'ended' : [
|
||||
'status',
|
||||
'ended'
|
||||
],
|
||||
'monitored' : [
|
||||
'monitored',
|
||||
true
|
||||
],
|
||||
'missing' : [
|
||||
'downloaded',
|
||||
false
|
||||
]
|
||||
},
|
||||
|
||||
sortValue : function(model, attr) {
|
||||
var monthNames = ["January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
];
|
||||
if (model.get("inCinemas")) {
|
||||
return model.get("inCinemas");
|
||||
}
|
||||
return "2100-01-01";
|
||||
}
|
||||
},
|
||||
path : {
|
||||
sortValue : function(model) {
|
||||
var path = model.get('path');
|
||||
sortMappings : {
|
||||
title : {
|
||||
sortKey : 'sortTitle'
|
||||
},
|
||||
statusWeight : {
|
||||
sortValue : function(model, attr) {
|
||||
if (model.getStatus() == "released") {
|
||||
return 1;
|
||||
}
|
||||
if (model.getStatus() == "inCinemas") {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
downloadedQuality : {
|
||||
sortValue : function(model, attr) {
|
||||
if (model.get("movieFile")) {
|
||||
return 1000-model.get("movieFile").quality.quality.id;
|
||||
}
|
||||
|
||||
return path.toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
nextAiring : {
|
||||
sortValue : function(model, attr, order) {
|
||||
var nextAiring = model.get(attr);
|
||||
|
||||
if (nextAiring) {
|
||||
return moment(nextAiring).unix();
|
||||
}
|
||||
|
||||
if (order === 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Number.MAX_VALUE;
|
||||
}
|
||||
},
|
||||
status: {
|
||||
sortValue : function(model, attr) {
|
||||
debugger;
|
||||
if (model.get("downloaded")) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
percentOfEpisodes : {
|
||||
sortValue : function(model, attr) {
|
||||
var percentOfEpisodes = model.get(attr);
|
||||
var episodeCount = model.get('episodeCount');
|
||||
|
||||
return percentOfEpisodes + episodeCount / 1000000;
|
||||
}
|
||||
},
|
||||
inCinemas : {
|
||||
|
||||
sortValue : function(model, attr) {
|
||||
var monthNames = ["January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
];
|
||||
if (model.get("inCinemas")) {
|
||||
return model.get("inCinemas");
|
||||
}
|
||||
return "2100-01-01";
|
||||
}
|
||||
},
|
||||
path : {
|
||||
sortValue : function(model) {
|
||||
var path = model.get('path');
|
||||
|
||||
return path.toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Collection = AsFilteredCollection.call(Collection);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue