Fixed a few things with displaying the Movie Details Page. Implemented the first round of Searching for and Downloading movie Releases. ATM this is still a bit hacky and alot of things need to be cleaned up. However, one can now manually search for and download (only in qBittorrent) a movie torrent.
parent
16e35f68bb
commit
2a3b0304cb
@ -0,0 +1,11 @@
|
|||||||
|
namespace NzbDrone.Core.IndexerSearch.Definitions
|
||||||
|
{
|
||||||
|
public class MovieSearchCriteria : SearchCriteriaBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("[{0}]", Movie.Title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Parser.Model
|
||||||
|
{
|
||||||
|
public class RemoteMovie
|
||||||
|
{
|
||||||
|
public ReleaseInfo Release { get; set; }
|
||||||
|
public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; } //TODO: Change to ParsedMovieInfo, for now though ParsedEpisodeInfo will do.
|
||||||
|
public Movie Movie { get; set; }
|
||||||
|
public bool DownloadAllowed { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Release.Title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
var $ = require('jquery');
|
||||||
|
var vent = require('vent');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var NzbDroneCell = require('../../Cells/NzbDroneCell');
|
||||||
|
|
||||||
|
module.exports = NzbDroneCell.extend({
|
||||||
|
className : 'episode-actions-cell',
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click .x-failed' : '_markAsFailed'
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
this.$el.empty();
|
||||||
|
|
||||||
|
if (this.model.get('eventType') === 'grabbed') {
|
||||||
|
this.$el.html('<i class="icon-sonarr-delete x-failed" title="Mark download as failed"></i>');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
_markAsFailed : function() {
|
||||||
|
var url = window.NzbDrone.ApiRoot + '/history/failed';
|
||||||
|
var data = {
|
||||||
|
id : this.model.get('id')
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url : url,
|
||||||
|
type : 'POST',
|
||||||
|
data : data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,28 @@
|
|||||||
|
var $ = require('jquery');
|
||||||
|
var vent = require('vent');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var NzbDroneCell = require('../../Cells/NzbDroneCell');
|
||||||
|
var HistoryDetailsView = require('../../Activity/History/Details/HistoryDetailsView');
|
||||||
|
require('bootstrap');
|
||||||
|
|
||||||
|
module.exports = NzbDroneCell.extend({
|
||||||
|
className : 'episode-history-details-cell',
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
this.$el.empty();
|
||||||
|
this.$el.html('<i class="icon-sonarr-form-info"></i>');
|
||||||
|
|
||||||
|
var html = new HistoryDetailsView({ model : this.model }).render().$el;
|
||||||
|
|
||||||
|
this.$el.popover({
|
||||||
|
content : html,
|
||||||
|
html : true,
|
||||||
|
trigger : 'hover',
|
||||||
|
title : 'Details',
|
||||||
|
placement : 'left',
|
||||||
|
container : this.$el
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,83 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
var Backgrid = require('backgrid');
|
||||||
|
var HistoryCollection = require('../../Activity/History/HistoryCollection');
|
||||||
|
var EventTypeCell = require('../../Cells/EventTypeCell');
|
||||||
|
var QualityCell = require('../../Cells/QualityCell');
|
||||||
|
var RelativeDateCell = require('../../Cells/RelativeDateCell');
|
||||||
|
var EpisodeHistoryActionsCell = require('./MovieHistoryActionsCell');
|
||||||
|
var EpisodeHistoryDetailsCell = require('./MovieHistoryDetailsCell');
|
||||||
|
var NoHistoryView = require('./NoHistoryView');
|
||||||
|
var LoadingView = require('../../Shared/LoadingView');
|
||||||
|
|
||||||
|
module.exports = Marionette.Layout.extend({
|
||||||
|
template : 'Movies/History/MovieHistoryLayoutTemplate',
|
||||||
|
|
||||||
|
regions : {
|
||||||
|
historyTable : '.history-table'
|
||||||
|
},
|
||||||
|
|
||||||
|
columns : [
|
||||||
|
{
|
||||||
|
name : 'eventType',
|
||||||
|
label : '',
|
||||||
|
cell : EventTypeCell,
|
||||||
|
cellValue : 'this'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'sourceTitle',
|
||||||
|
label : 'Source Title',
|
||||||
|
cell : 'string'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'quality',
|
||||||
|
label : 'Quality',
|
||||||
|
cell : QualityCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'date',
|
||||||
|
label : 'Date',
|
||||||
|
cell : RelativeDateCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'this',
|
||||||
|
label : '',
|
||||||
|
cell : EpisodeHistoryDetailsCell,
|
||||||
|
sortable : false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'this',
|
||||||
|
label : '',
|
||||||
|
cell : EpisodeHistoryActionsCell,
|
||||||
|
sortable : false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
initialize : function(options) {
|
||||||
|
this.model = options.model;
|
||||||
|
|
||||||
|
this.collection = new HistoryCollection({
|
||||||
|
episodeId : this.model.id,
|
||||||
|
tableName : 'episodeHistory'
|
||||||
|
});
|
||||||
|
this.collection.fetch();
|
||||||
|
this.listenTo(this.collection, 'sync', this._showTable);
|
||||||
|
},
|
||||||
|
|
||||||
|
onRender : function() {
|
||||||
|
this.historyTable.show(new LoadingView());
|
||||||
|
},
|
||||||
|
|
||||||
|
_showTable : function() {
|
||||||
|
if (this.collection.any()) {
|
||||||
|
this.historyTable.show(new Backgrid.Grid({
|
||||||
|
collection : this.collection,
|
||||||
|
columns : this.columns,
|
||||||
|
className : 'table table-hover table-condensed'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
this.historyTable.show(new NoHistoryView());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1 @@
|
|||||||
|
<div class="history-table table-responsive"></div>
|
@ -0,0 +1,5 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
|
||||||
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Movies/History/NoHistoryViewTemplate'
|
||||||
|
});
|
@ -0,0 +1,3 @@
|
|||||||
|
<p class="text-warning">
|
||||||
|
No history for this episode.
|
||||||
|
</p>
|
@ -0,0 +1,5 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
|
||||||
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Movies/Search/ButtonsViewTemplate'
|
||||||
|
});
|
@ -0,0 +1,4 @@
|
|||||||
|
<div class="search-buttons">
|
||||||
|
<button class="btn btn-lg btn-block x-search-auto"><i class="icon-sonarr-search-automatic"/> Automatic Search</button>
|
||||||
|
<button class="btn btn-lg btn-block btn-primary x-search-manual"><i class="icon-sonarr-search-manual"/> Manual Search</button>
|
||||||
|
</div>
|
@ -0,0 +1,86 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
var Backgrid = require('backgrid');
|
||||||
|
var ReleaseTitleCell = require('../../Cells/ReleaseTitleCell');
|
||||||
|
var FileSizeCell = require('../../Cells/FileSizeCell');
|
||||||
|
var QualityCell = require('../../Cells/QualityCell');
|
||||||
|
var ApprovalStatusCell = require('../../Cells/ApprovalStatusCell');
|
||||||
|
var DownloadReportCell = require('../../Release/DownloadReportCell');
|
||||||
|
var AgeCell = require('../../Release/AgeCell');
|
||||||
|
var ProtocolCell = require('../../Release/ProtocolCell');
|
||||||
|
var PeersCell = require('../../Release/PeersCell');
|
||||||
|
|
||||||
|
module.exports = Marionette.Layout.extend({
|
||||||
|
template : 'Movies/Search/ManualLayoutTemplate',
|
||||||
|
|
||||||
|
regions : {
|
||||||
|
grid : '#episode-release-grid'
|
||||||
|
},
|
||||||
|
|
||||||
|
columns : [
|
||||||
|
{
|
||||||
|
name : 'protocol',
|
||||||
|
label : 'Source',
|
||||||
|
cell : ProtocolCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'age',
|
||||||
|
label : 'Age',
|
||||||
|
cell : AgeCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'title',
|
||||||
|
label : 'Title',
|
||||||
|
cell : ReleaseTitleCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'indexer',
|
||||||
|
label : 'Indexer',
|
||||||
|
cell : Backgrid.StringCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'size',
|
||||||
|
label : 'Size',
|
||||||
|
cell : FileSizeCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'seeders',
|
||||||
|
label : 'Peers',
|
||||||
|
cell : PeersCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'quality',
|
||||||
|
label : 'Quality',
|
||||||
|
cell : QualityCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'rejections',
|
||||||
|
label : '<i class="icon-sonarr-header-rejections" />',
|
||||||
|
tooltip : 'Rejections',
|
||||||
|
cell : ApprovalStatusCell,
|
||||||
|
sortable : true,
|
||||||
|
sortType : 'fixed',
|
||||||
|
direction : 'ascending',
|
||||||
|
title : 'Release Rejected'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'download',
|
||||||
|
label : '<i class="icon-sonarr-download" />',
|
||||||
|
tooltip : 'Auto-Search Prioritization',
|
||||||
|
cell : DownloadReportCell,
|
||||||
|
sortable : true,
|
||||||
|
sortType : 'fixed',
|
||||||
|
direction : 'ascending'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
onShow : function() {
|
||||||
|
if (!this.isClosed) {
|
||||||
|
this.grid.show(new Backgrid.Grid({
|
||||||
|
row : Backgrid.Row,
|
||||||
|
columns : this.columns,
|
||||||
|
collection : this.collection,
|
||||||
|
className : 'table table-hover'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,2 @@
|
|||||||
|
<div id="episode-release-grid" class="table-responsive"></div>
|
||||||
|
<button class="btn x-search-back">Back</button>
|
@ -0,0 +1,82 @@
|
|||||||
|
var vent = require('vent');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var ButtonsView = require('./ButtonsView');
|
||||||
|
var ManualSearchLayout = require('./ManualLayout');
|
||||||
|
var ReleaseCollection = require('../../Release/ReleaseCollection');
|
||||||
|
var CommandController = require('../../Commands/CommandController');
|
||||||
|
var LoadingView = require('../../Shared/LoadingView');
|
||||||
|
var NoResultsView = require('./NoResultsView');
|
||||||
|
|
||||||
|
module.exports = Marionette.Layout.extend({
|
||||||
|
template : 'Movies/Search/MovieSearchLayoutTemplate',
|
||||||
|
|
||||||
|
regions : {
|
||||||
|
main : '#episode-search-region'
|
||||||
|
},
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click .x-search-auto' : '_searchAuto',
|
||||||
|
'click .x-search-manual' : '_searchManual',
|
||||||
|
'click .x-search-back' : '_showButtons'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize : function() {
|
||||||
|
this.mainView = new ButtonsView();
|
||||||
|
this.releaseCollection = new ReleaseCollection();
|
||||||
|
|
||||||
|
this.listenTo(this.releaseCollection, 'sync', this._showSearchResults);
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow : function() {
|
||||||
|
if (this.startManualSearch) {
|
||||||
|
this._searchManual();
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
this._showMainView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_searchAuto : function(e) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandController.Execute('episodeSearch', {
|
||||||
|
episodeIds : [this.model.get('id')]
|
||||||
|
});
|
||||||
|
|
||||||
|
vent.trigger(vent.Commands.CloseModalCommand);
|
||||||
|
},
|
||||||
|
|
||||||
|
_searchManual : function(e) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mainView = new LoadingView();
|
||||||
|
this._showMainView();
|
||||||
|
this.releaseCollection.fetchMovieReleases(this.model.id);
|
||||||
|
},
|
||||||
|
|
||||||
|
_showMainView : function() {
|
||||||
|
this.main.show(this.mainView);
|
||||||
|
},
|
||||||
|
|
||||||
|
_showButtons : function() {
|
||||||
|
this.mainView = new ButtonsView();
|
||||||
|
this._showMainView();
|
||||||
|
},
|
||||||
|
|
||||||
|
_showSearchResults : function() {
|
||||||
|
if (this.releaseCollection.length === 0) {
|
||||||
|
this.mainView = new NoResultsView();
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
this.mainView = new ManualSearchLayout({ collection : this.releaseCollection });
|
||||||
|
}
|
||||||
|
|
||||||
|
this._showMainView();
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1 @@
|
|||||||
|
<div id="episode-search-region"></div>
|
@ -0,0 +1,5 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
|
||||||
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Movies/Search/NoResultsViewTemplate'
|
||||||
|
});
|
@ -0,0 +1 @@
|
|||||||
|
<div>No results found</div>
|
Loading…
Reference in new issue