diff --git a/src/NzbDrone.Api/NzbDrone.Api.csproj b/src/NzbDrone.Api/NzbDrone.Api.csproj
index 6a61d84fc..ff526e2bc 100644
--- a/src/NzbDrone.Api/NzbDrone.Api.csproj
+++ b/src/NzbDrone.Api/NzbDrone.Api.csproj
@@ -118,6 +118,7 @@
+
@@ -260,6 +261,7 @@
+
diff --git a/src/NzbDrone.Api/Wanted/MissingModule.cs b/src/NzbDrone.Api/Wanted/MissingModule.cs
index 9f6215a2e..52470cd1a 100644
--- a/src/NzbDrone.Api/Wanted/MissingModule.cs
+++ b/src/NzbDrone.Api/Wanted/MissingModule.cs
@@ -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;
}
diff --git a/src/NzbDrone.Api/Wanted/MovieMissingModule.cs b/src/NzbDrone.Api/Wanted/MovieMissingModule.cs
new file mode 100644
index 000000000..9a46b9818
--- /dev/null
+++ b/src/NzbDrone.Api/Wanted/MovieMissingModule.cs
@@ -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,
+ IHandle,
+ IHandle
+ {
+ protected readonly IMovieService _movieService;
+
+ public MovieMissingModule(IMovieService movieService,
+ IQualityUpgradableSpecification qualityUpgradableSpecification,
+ IBroadcastSignalRMessage signalRBroadcaster)
+ : base(signalRBroadcaster, "wanted/missing")
+ {
+
+ _movieService = movieService;
+ GetResourcePaged = GetMissingMovies;
+ }
+
+ private PagingResource GetMissingMovies(PagingResource pagingResource)
+ {
+ var pagingSpec = pagingResource.MapToPagingSpec("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);
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Tv/MovieRepository.cs b/src/NzbDrone.Core/Tv/MovieRepository.cs
index f734c5174..d9a8cc32e 100644
--- a/src/NzbDrone.Core/Tv/MovieRepository.cs
+++ b/src/NzbDrone.Core/Tv/MovieRepository.cs
@@ -3,7 +3,7 @@ using System.Linq;
using System.Collections.Generic;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
-
+using NzbDrone.Core.Datastore.Extensions;
namespace NzbDrone.Core.Tv
{
@@ -15,6 +15,7 @@ namespace NzbDrone.Core.Tv
Movie FindByImdbId(string imdbid);
Movie FindByTitleSlug(string slug);
List MoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
+ PagingSpec MoviesWithoutFiles(PagingSpec pagingSpec);
List GetMoviesByFileId(int fileId);
void SetFileId(int fileId, int movieId);
}
@@ -132,5 +133,21 @@ namespace NzbDrone.Core.Tv
return query.ToList();
}
+
+ public PagingSpec MoviesWithoutFiles(PagingSpec pagingSpec)
+ {
+
+ var query = 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);
+
+ pagingSpec.Records = query.ToList();
+ pagingSpec.TotalRecords = pagingSpec.Records.Count;
+
+ return pagingSpec;
+ }
}
}
\ No newline at end of file
diff --git a/src/NzbDrone.Core/Tv/MovieService.cs b/src/NzbDrone.Core/Tv/MovieService.cs
index 0cbf226e4..683182f36 100644
--- a/src/NzbDrone.Core/Tv/MovieService.cs
+++ b/src/NzbDrone.Core/Tv/MovieService.cs
@@ -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,6 +28,7 @@ namespace NzbDrone.Core.Tv
Movie FindByTitleSlug(string slug);
Movie GetMovieByFileId(int fileId);
List GetMoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
+ PagingSpec MoviesWithoutFiles(PagingSpec pagingSpec);
void DeleteMovie(int movieId, bool deleteFiles);
List GetAllMovies();
Movie UpdateMovie(Movie movie);
@@ -232,5 +234,12 @@ namespace NzbDrone.Core.Tv
return episodes;
}
+
+ public PagingSpec MoviesWithoutFiles(PagingSpec pagingSpec)
+ {
+ var movieResult = _movieRepository.MoviesWithoutFiles(pagingSpec);
+
+ return movieResult;
+ }
}
}
diff --git a/src/UI/Cells/MovieStatusWithTextCell.js b/src/UI/Cells/MovieStatusWithTextCell.js
new file mode 100644
index 000000000..c4bcac645
--- /dev/null
+++ b/src/UI/Cells/MovieStatusWithTextCell.js
@@ -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(' Released
');
+ this._setStatusWeight(3);
+ }
+
+ if (numOfMonths > 3) {
+ this.$el.html(' Released
');//TODO: Update for PreDB.me
+ this._setStatusWeight(2);
+ }
+
+ if (numOfMonths < 3) {
+ this.$el.html(' In Cinemas
');
+ this._setStatusWeight(2);
+ }
+
+ if (status === "announced") {
+ this.$el.html(' Announced
');
+ this._setStatusWeight(1);
+ }
+
+ return this;
+ },
+
+ _setStatusWeight : function(weight) {
+ this.model.set('statusWeight', weight, { silent : true });
+ }
+});
diff --git a/src/UI/Cells/cells.less b/src/UI/Cells/cells.less
index ca71defbd..a5a13707a 100644
--- a/src/UI/Cells/cells.less
+++ b/src/UI/Cells/cells.less
@@ -55,6 +55,10 @@
width : 150px;
}
+.movie-status-text-cell {
+ width : 150px;
+}
+
.history-event-type-cell {
width : 10px;
}
diff --git a/src/UI/Wanted/Missing/MissingCollection.js b/src/UI/Wanted/Missing/MissingCollection.js
index 28ceee62e..59f91ed67 100644
--- a/src/UI/Wanted/Missing/MissingCollection.js
+++ b/src/UI/Wanted/Missing/MissingCollection.js
@@ -1,5 +1,5 @@
var _ = require('underscore');
-var EpisodeModel = require('../../Series/EpisodeModel');
+var MovieModel = require('../../Movies/MovieModel');
var PagableCollection = require('backbone.pageable');
var AsFilteredCollection = require('../../Mixins/AsFilteredCollection');
var AsSortedCollection = require('../../Mixins/AsSortedCollection');
@@ -7,13 +7,13 @@ var AsPersistedStateCollection = require('../../Mixins/AsPersistedStateCollectio
var Collection = PagableCollection.extend({
url : window.NzbDrone.ApiRoot + '/wanted/missing',
- model : EpisodeModel,
+ model : MovieModel,
tableName : 'wanted.missing',
state : {
pageSize : 15,
- sortKey : 'airDateUtc',
- order : 1
+ sortKey : 'inCinemas',
+ order : -1
},
queryParams : {
@@ -39,10 +39,6 @@ var Collection = PagableCollection.extend({
]
},
- sortMappings : {
- 'series' : { sortKey : 'series.sortTitle' }
- },
-
parseState : function(resp) {
return { totalRecords : resp.totalRecords };
},
@@ -58,4 +54,4 @@ var Collection = PagableCollection.extend({
Collection = AsFilteredCollection.call(Collection);
Collection = AsSortedCollection.call(Collection);
-module.exports = AsPersistedStateCollection.call(Collection);
\ No newline at end of file
+module.exports = AsPersistedStateCollection.call(Collection);
diff --git a/src/UI/Wanted/Missing/MissingLayout.js b/src/UI/Wanted/Missing/MissingLayout.js
index 96096e780..b3aa9e378 100644
--- a/src/UI/Wanted/Missing/MissingLayout.js
+++ b/src/UI/Wanted/Missing/MissingLayout.js
@@ -5,11 +5,9 @@ var Marionette = require('marionette');
var Backgrid = require('backgrid');
var MissingCollection = require('./MissingCollection');
var SelectAllCell = require('../../Cells/SelectAllCell');
-var SeriesTitleCell = require('../../Cells/SeriesTitleCell');
-var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
-var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
+var MovieTitleCell = require('../../Cells/MovieTitleCell');
var RelativeDateCell = require('../../Cells/RelativeDateCell');
-var EpisodeStatusCell = require('../../Cells/EpisodeStatusCell');
+var MovieStatusWithTextCell = require('../../Cells/MovieStatusWithTextCell');
var GridPager = require('../../Shared/Grid/Pager');
var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout');
var LoadingView = require('../../Shared/LoadingView');
@@ -39,35 +37,29 @@ module.exports = Marionette.Layout.extend({
headerCell : 'select-all',
sortable : false
},
- {
- name : 'series',
- label : 'Series Title',
- cell : SeriesTitleCell,
- sortValue : 'series.sortTitle'
- },
{
name : 'this',
- label : 'Episode',
- cell : EpisodeNumberCell,
+ label : 'Movie Title',
+ cell : MovieTitleCell,
sortable : false
},
{
- name : 'this',
- label : 'Episode Title',
- cell : EpisodeTitleCell,
- sortable : false
+ name : 'inCinemas',
+ label : 'In Cinemas',
+ cell : RelativeDateCell
},
{
- name : 'airDateUtc',
- label : 'Air Date',
+ name : 'physicalRelease',
+ label : 'PhysicalRelease',
cell : RelativeDateCell
},
{
name : 'status',
label : 'Status',
- cell : EpisodeStatusCell,
+ cell : MovieStatusWithTextCell,
sortable : false
- }
+ },
+
],
initialize : function() {