mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-23 06:45:19 -07:00
Files tab is now present. (#245)
* Adding file info tab. Not finished yet. * Adding more media info options. * Deleting files now works. Fixes #127 * Fix button for modifying episode files. * Get Media Info when running DiskScanService.
This commit is contained in:
parent
5daece0ed4
commit
29586667cb
22 changed files with 392 additions and 13 deletions
89
src/NzbDrone.Api/Movies/MovieFileModule.cs
Normal file
89
src/NzbDrone.Api/Movies/MovieFileModule.cs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
using NzbDrone.Api.Movie;
|
||||||
|
using NzbDrone.Core.Datastore.Events;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.DecisionEngine;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.EpisodeFiles
|
||||||
|
{
|
||||||
|
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>
|
||||||
|
//IHandle<EpisodeFileAddedEvent>
|
||||||
|
{
|
||||||
|
private readonly IMediaFileService _mediaFileService;
|
||||||
|
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||||
|
private readonly IMovieService _seriesService;
|
||||||
|
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public MovieFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
|
IMediaFileService mediaFileService,
|
||||||
|
IRecycleBinProvider recycleBinProvider,
|
||||||
|
IMovieService seriesService,
|
||||||
|
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||||
|
Logger logger)
|
||||||
|
: base(signalRBroadcaster)
|
||||||
|
{
|
||||||
|
_mediaFileService = mediaFileService;
|
||||||
|
_recycleBinProvider = recycleBinProvider;
|
||||||
|
_seriesService = seriesService;
|
||||||
|
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||||
|
_logger = logger;
|
||||||
|
/*GetResourceById = GetEpisodeFile;
|
||||||
|
GetResourceAll = GetEpisodeFiles;
|
||||||
|
UpdateResource = SetQuality;*/
|
||||||
|
DeleteResource = DeleteEpisodeFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private EpisodeFileResource GetEpisodeFile(int id)
|
||||||
|
{
|
||||||
|
var episodeFile = _mediaFileService.Get(id);
|
||||||
|
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||||
|
|
||||||
|
return episodeFile.ToResource(series, _qualityUpgradableSpecification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<EpisodeFileResource> GetEpisodeFiles()
|
||||||
|
{
|
||||||
|
if (!Request.Query.SeriesId.HasValue)
|
||||||
|
{
|
||||||
|
throw new BadRequestException("seriesId is missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
var seriesId = (int)Request.Query.SeriesId;
|
||||||
|
|
||||||
|
var series = _seriesService.GetSeries(seriesId);
|
||||||
|
|
||||||
|
return _mediaFileService.GetFilesBySeries(seriesId).ConvertAll(f => f.ToResource(series, _qualityUpgradableSpecification));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetQuality(EpisodeFileResource episodeFileResource)
|
||||||
|
{
|
||||||
|
var episodeFile = _mediaFileService.Get(episodeFileResource.Id);
|
||||||
|
episodeFile.Quality = episodeFileResource.Quality;
|
||||||
|
_mediaFileService.Update(episodeFile);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private void DeleteEpisodeFile(int id)
|
||||||
|
{
|
||||||
|
var episodeFile = _mediaFileService.GetMovie(id);
|
||||||
|
var series = _seriesService.GetMovie(episodeFile.MovieId);
|
||||||
|
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
|
_logger.Info("Deleting episode file: {0}", fullPath);
|
||||||
|
_recycleBinProvider.DeleteFile(fullPath);
|
||||||
|
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(EpisodeFileAddedEvent message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -116,6 +116,7 @@
|
||||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||||
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
||||||
<Compile Include="Indexers\ReleasePushModule.cs" />
|
<Compile Include="Indexers\ReleasePushModule.cs" />
|
||||||
|
<Compile Include="Movies\MovieFileModule.cs" />
|
||||||
<Compile Include="Movies\MovieModule.cs" />
|
<Compile Include="Movies\MovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieModule.cs" />
|
<Compile Include="Movies\RenameMovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieResource.cs" />
|
<Compile Include="Movies\RenameMovieResource.cs" />
|
||||||
|
|
|
@ -30,8 +30,8 @@ namespace NzbDrone.Api.Movie
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public MovieResource Movie { get; set; }
|
public MovieResource Movie { get; set; }
|
||||||
|
public string Edition { get; set; }
|
||||||
|
public Core.MediaFiles.MediaInfo.MediaInfoModel MediaInfo { get; set; }
|
||||||
|
|
||||||
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,8 @@ namespace NzbDrone.Api.Movie
|
||||||
ReleaseGroup = model.ReleaseGroup,
|
ReleaseGroup = model.ReleaseGroup,
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
Movie = movie,
|
Movie = movie,
|
||||||
|
MediaInfo = model.MediaInfo,
|
||||||
|
Edition = model.Edition
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System.Data;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(117)]
|
||||||
|
public class update_movie_file : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Create.Column("Edition").OnTable("MovieFiles").AsString().Nullable();
|
||||||
|
Execute.WithConnection(SetSortTitles);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetSortTitles(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
getSeriesCmd.Transaction = tran;
|
||||||
|
getSeriesCmd.CommandText = @"SELECT Id, RelativePath FROM MovieFiles";
|
||||||
|
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (seriesReader.Read())
|
||||||
|
{
|
||||||
|
var id = seriesReader.GetInt32(0);
|
||||||
|
var relativePath = seriesReader.GetString(1);
|
||||||
|
|
||||||
|
var edition = Parser.Parser.ParseMovieTitle(relativePath).Edition;
|
||||||
|
|
||||||
|
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
updateCmd.Transaction = tran;
|
||||||
|
updateCmd.CommandText = "UPDATE MovieFiles SET Edition = ? WHERE Id = ?";
|
||||||
|
updateCmd.AddParameter(edition);
|
||||||
|
updateCmd.AddParameter(id);
|
||||||
|
|
||||||
|
updateCmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,6 +83,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
episodeFile.MediaInfo = localMovie.MediaInfo;
|
episodeFile.MediaInfo = localMovie.MediaInfo;
|
||||||
episodeFile.Movie = localMovie.Movie;
|
episodeFile.Movie = localMovie.Movie;
|
||||||
episodeFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
episodeFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
||||||
|
episodeFile.Edition = localMovie.ParsedMovieInfo.Edition;
|
||||||
|
|
||||||
bool copyOnly;
|
bool copyOnly;
|
||||||
switch (importMode)
|
switch (importMode)
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie)
|
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie)
|
||||||
{
|
{
|
||||||
return GetImportDecisions(videoFiles, movie, null, false);
|
return GetImportDecisions(videoFiles, movie, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource)
|
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource)
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
List<string> FilterExistingFiles(List<string> files, Series series);
|
List<string> FilterExistingFiles(List<string> files, Series series);
|
||||||
List<string> FilterExistingFiles(List<string> files, Movie movie);
|
List<string> FilterExistingFiles(List<string> files, Movie movie);
|
||||||
EpisodeFile Get(int id);
|
EpisodeFile Get(int id);
|
||||||
|
MovieFile GetMovie(int id);
|
||||||
List<EpisodeFile> Get(IEnumerable<int> ids);
|
List<EpisodeFile> Get(IEnumerable<int> ids);
|
||||||
List<MovieFile> GetMovies(IEnumerable<int> ids);
|
List<MovieFile> GetMovies(IEnumerable<int> ids);
|
||||||
|
|
||||||
|
@ -150,5 +151,9 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
_movieFileRepository.Update(episodeFile);
|
_movieFileRepository.Update(episodeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MovieFile GetMovie(int id)
|
||||||
|
{
|
||||||
|
return _movieFileRepository.Get(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public MediaInfoModel MediaInfo { get; set; }
|
public MediaInfoModel MediaInfo { get; set; }
|
||||||
|
public string Edition { get; set; }
|
||||||
public LazyLoaded<Movie> Movie { get; set; }
|
public LazyLoaded<Movie> Movie { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
<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\003_remove_clean_title_from_scene_mapping.cs" />
|
||||||
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\117_update_movie_file.cs" />
|
||||||
<Compile Include="Datastore\Migration\116_update_movie_sorttitle_again.cs" />
|
<Compile Include="Datastore\Migration\116_update_movie_sorttitle_again.cs" />
|
||||||
<Compile Include="Datastore\Migration\115_update_movie_sorttitle.cs" />
|
<Compile Include="Datastore\Migration\115_update_movie_sorttitle.cs" />
|
||||||
<Compile Include="Datastore\Migration\111_remove_bitmetv.cs" />
|
<Compile Include="Datastore\Migration\111_remove_bitmetv.cs" />
|
||||||
|
|
15
src/UI/Cells/FileTitleCell.js
Normal file
15
src/UI/Cells/FileTitleCell.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
var NzbDroneCell = require('./NzbDroneCell');
|
||||||
|
|
||||||
|
module.exports = NzbDroneCell.extend({
|
||||||
|
className : 'file-title-cell',
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
this.$el.empty();
|
||||||
|
|
||||||
|
var title = this.model.get('relativePath');
|
||||||
|
this.$el.html(title);
|
||||||
|
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
23
src/UI/Cells/MediaInfoCell.js
Normal file
23
src/UI/Cells/MediaInfoCell.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
var NzbDroneCell = require('./NzbDroneCell');
|
||||||
|
|
||||||
|
module.exports = NzbDroneCell.extend({
|
||||||
|
className : 'release-title-cell',
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
this.$el.empty();
|
||||||
|
|
||||||
|
var info = this.model.get('mediaInfo');
|
||||||
|
if (info) {
|
||||||
|
var runtime = info.runTime;
|
||||||
|
if (runtime) {
|
||||||
|
runtime = runtime.split(".")[0];
|
||||||
|
}
|
||||||
|
var video = "{0} ({1}x{2}) ({3})".format(info.videoCodec, info.width, info.height, runtime);
|
||||||
|
var audio = "{0} ({1})".format(info.audioFormat, info.audioLanguages);
|
||||||
|
this.$el.html(video + " " + audio);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
{{#if_gt proper compare="1"}}
|
{{#if_gt proper compare="1"}}
|
||||||
<span class="badge badge-info" title="PROPER">{{quality.name}}</span>
|
<span class="badge badge-info" title="PROPER">{{quality.name}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="badge">{{quality.name}}</span>
|
<span class="badge" title="{{#if hardcodedSubs}}Warning: {{hardcodedSubs}}{{/if}}">{{quality.name}}</span>
|
||||||
{{/if_gt}}
|
{{/if_gt}}
|
|
@ -11,6 +11,7 @@ var LoadingView = require('../../Shared/LoadingView');
|
||||||
var EpisodeFileEditorLayout = require('../../EpisodeFile/Editor/EpisodeFileEditorLayout');
|
var EpisodeFileEditorLayout = require('../../EpisodeFile/Editor/EpisodeFileEditorLayout');
|
||||||
var HistoryLayout = require('../History/MovieHistoryLayout');
|
var HistoryLayout = require('../History/MovieHistoryLayout');
|
||||||
var SearchLayout = require('../Search/MovieSearchLayout');
|
var SearchLayout = require('../Search/MovieSearchLayout');
|
||||||
|
var FilesLayout = require("../Files/FilesLayout");
|
||||||
require('backstrech');
|
require('backstrech');
|
||||||
require('../../Mixins/backbone.signalr.mixin');
|
require('../../Mixins/backbone.signalr.mixin');
|
||||||
|
|
||||||
|
@ -22,7 +23,8 @@ module.exports = Marionette.Layout.extend({
|
||||||
seasons : '#seasons',
|
seasons : '#seasons',
|
||||||
info : '#info',
|
info : '#info',
|
||||||
search : '#movie-search',
|
search : '#movie-search',
|
||||||
history : '#movie-history'
|
history : '#movie-history',
|
||||||
|
files : "#movie-files"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,11 +38,12 @@ module.exports = Marionette.Layout.extend({
|
||||||
poster : '.x-movie-poster',
|
poster : '.x-movie-poster',
|
||||||
manualSearch : '.x-manual-search',
|
manualSearch : '.x-manual-search',
|
||||||
history : '.x-movie-history',
|
history : '.x-movie-history',
|
||||||
search : '.x-movie-search'
|
search : '.x-movie-search',
|
||||||
|
files : ".x-movie-files"
|
||||||
},
|
},
|
||||||
|
|
||||||
events : {
|
events : {
|
||||||
'click .x-episode-file-editor' : '_openEpisodeFileEditor',
|
'click .x-episode-file-editor' : '_showFiles',
|
||||||
'click .x-monitored' : '_toggleMonitored',
|
'click .x-monitored' : '_toggleMonitored',
|
||||||
'click .x-edit' : '_editMovie',
|
'click .x-edit' : '_editMovie',
|
||||||
'click .x-refresh' : '_refreshMovies',
|
'click .x-refresh' : '_refreshMovies',
|
||||||
|
@ -48,7 +51,8 @@ module.exports = Marionette.Layout.extend({
|
||||||
'click .x-search' : '_moviesSearch',
|
'click .x-search' : '_moviesSearch',
|
||||||
'click .x-manual-search' : '_showSearch',
|
'click .x-manual-search' : '_showSearch',
|
||||||
'click .x-movie-history' : '_showHistory',
|
'click .x-movie-history' : '_showHistory',
|
||||||
'click .x-movie-search' : '_showSearch'
|
'click .x-movie-search' : '_showSearch',
|
||||||
|
"click .x-movie-files" : "_showFiles",
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize : function() {
|
initialize : function() {
|
||||||
|
@ -72,11 +76,18 @@ module.exports = Marionette.Layout.extend({
|
||||||
this.searchLayout = new SearchLayout({ model : this.model });
|
this.searchLayout = new SearchLayout({ model : this.model });
|
||||||
this.searchLayout.startManualSearch = true;
|
this.searchLayout.startManualSearch = true;
|
||||||
|
|
||||||
|
this.filesLayout = new FilesLayout({ model : this.model });
|
||||||
|
|
||||||
this._showBackdrop();
|
this._showBackdrop();
|
||||||
this._showSeasons();
|
this._showSeasons();
|
||||||
this._setMonitoredState();
|
this._setMonitoredState();
|
||||||
this._showInfo();
|
this._showInfo();
|
||||||
this._showHistory();
|
if (this.model.get("movieFile")) {
|
||||||
|
this._showFiles()
|
||||||
|
} else {
|
||||||
|
this._showHistory();
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender : function() {
|
onRender : function() {
|
||||||
|
@ -144,6 +155,15 @@ module.exports = Marionette.Layout.extend({
|
||||||
this.search.show(this.searchLayout);
|
this.search.show(this.searchLayout);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_showFiles : function(e) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ui.files.tab('show');
|
||||||
|
this.files.show(this.filesLayout);
|
||||||
|
},
|
||||||
|
|
||||||
_toggleMonitored : function() {
|
_toggleMonitored : function() {
|
||||||
var savePromise = this.model.save('monitored', !this.model.get('monitored'), { wait : true });
|
var savePromise = this.model.save('monitored', !this.model.get('monitored'), { wait : true });
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
{{title}}
|
{{title}}
|
||||||
<div class="movie-actions pull-right">
|
<div class="movie-actions pull-right">
|
||||||
<div class="x-episode-file-editor">
|
<div class="x-episode-file-editor">
|
||||||
<i class="icon-sonarr-episode-file" title="Modify episode files for movie"/>
|
<i class="icon-sonarr-episode-file" title="Modify movie files"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="x-refresh">
|
<div class="x-refresh">
|
||||||
<i class="icon-sonarr-refresh icon-can-spin" title="Update movie info and scan disk"/>
|
<i class="icon-sonarr-refresh icon-can-spin" title="Update movie info and scan disk"/>
|
||||||
|
@ -42,10 +42,12 @@
|
||||||
<ul class="nav nav-tabs" id="myTab">
|
<ul class="nav nav-tabs" id="myTab">
|
||||||
<li><a href="#movie-history" class="x-movie-history">History</a></li>
|
<li><a href="#movie-history" class="x-movie-history">History</a></li>
|
||||||
<li><a href="#movie-search" class="x-movie-search">Search</a></li>
|
<li><a href="#movie-search" class="x-movie-search">Search</a></li>
|
||||||
|
<li><a href="#movie-files" class="x-movie-files">Files</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane" id="movie-history"/>
|
<div class="tab-pane" id="movie-history"/>
|
||||||
<div class="tab-pane" id="movie-search"/>
|
<div class="tab-pane" id="movie-search"/>
|
||||||
|
<div class="tab-pane" id="movie-files"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
26
src/UI/Movies/Files/DeleteFileCell.js
Normal file
26
src/UI/Movies/Files/DeleteFileCell.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
var vent = require('vent');
|
||||||
|
var Backgrid = require('backgrid');
|
||||||
|
|
||||||
|
module.exports = Backgrid.Cell.extend({
|
||||||
|
className : 'delete-episode-file-cell',
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click' : '_onClick'
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
this.$el.empty();
|
||||||
|
this.$el.html('<i class="icon-sonarr-delete" title="Delete movie file from disk"></i>');
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onClick : function() {
|
||||||
|
var self = this;
|
||||||
|
if (window.confirm('Are you sure you want to delete \'{0}\' from disk?'.format(this.model.get('relativePath')))) {
|
||||||
|
this.model.destroy().done(function() {
|
||||||
|
vent.trigger(vent.Events.MovieFileDeleted, { movieFile : self.model });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
3
src/UI/Movies/Files/FileModel.js
Normal file
3
src/UI/Movies/Files/FileModel.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
var Backbone = require('backbone');
|
||||||
|
|
||||||
|
module.exports = Backbone.Model.extend({});
|
30
src/UI/Movies/Files/FilesCollection.js
Normal file
30
src/UI/Movies/Files/FilesCollection.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
var PagableCollection = require('backbone.pageable');
|
||||||
|
var FileModel = require('./FileModel');
|
||||||
|
var AsSortedCollection = require('../../Mixins/AsSortedCollection');
|
||||||
|
|
||||||
|
var Collection = PagableCollection.extend({
|
||||||
|
url : window.NzbDrone.ApiRoot + "/moviefile",
|
||||||
|
model : FileModel,
|
||||||
|
|
||||||
|
state : {
|
||||||
|
pageSize : 2000,
|
||||||
|
sortKey : 'title',
|
||||||
|
order : -1
|
||||||
|
},
|
||||||
|
|
||||||
|
mode : 'client',
|
||||||
|
|
||||||
|
sortMappings : {
|
||||||
|
'quality' : {
|
||||||
|
sortKey : "qualityWeight"
|
||||||
|
},
|
||||||
|
"edition" : {
|
||||||
|
sortKey : "edition"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Collection = AsSortedCollection.call(Collection);
|
||||||
|
|
||||||
|
module.exports = Collection;
|
107
src/UI/Movies/Files/FilesLayout.js
Normal file
107
src/UI/Movies/Files/FilesLayout.js
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
var vent = require('vent');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var Backgrid = require('backgrid');
|
||||||
|
//var ButtonsView = require('./ButtonsView');
|
||||||
|
//var ManualSearchLayout = require('./ManualLayout');
|
||||||
|
var FilesCollection = require('./FilesCollection');
|
||||||
|
var CommandController = require('../../Commands/CommandController');
|
||||||
|
var LoadingView = require('../../Shared/LoadingView');
|
||||||
|
var NoResultsView = require('./NoFilesView');
|
||||||
|
var FileModel = require("./FileModel");
|
||||||
|
var FileTitleCell = require('../../Cells/FileTitleCell');
|
||||||
|
var FileSizeCell = require('../../Cells/FileSizeCell');
|
||||||
|
var QualityCell = require('../../Cells/QualityCell');
|
||||||
|
var MediaInfoCell = require('../../Cells/MediaInfoCell');
|
||||||
|
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');
|
||||||
|
var EditionCell = require('../../Cells/EditionCell');
|
||||||
|
var DeleteFileCell = require("./DeleteFileCell");
|
||||||
|
|
||||||
|
module.exports = Marionette.Layout.extend({
|
||||||
|
template : 'Movies/Files/FilesLayoutTemplate',
|
||||||
|
|
||||||
|
regions : {
|
||||||
|
main : '#movie-files-region',
|
||||||
|
grid : "#movie-files-grid"
|
||||||
|
},
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click .x-search-auto' : '_searchAuto',
|
||||||
|
'click .x-search-manual' : '_searchManual',
|
||||||
|
'click .x-search-back' : '_showButtons'
|
||||||
|
},
|
||||||
|
|
||||||
|
columns : [
|
||||||
|
{
|
||||||
|
name : 'title',
|
||||||
|
label : 'Title',
|
||||||
|
cell : FileTitleCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : "mediaInfo",
|
||||||
|
label : "Media Info",
|
||||||
|
cell : MediaInfoCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'edition',
|
||||||
|
label : 'Edition',
|
||||||
|
cell : EditionCell,
|
||||||
|
title : "Edition",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'size',
|
||||||
|
label : 'Size',
|
||||||
|
cell : FileSizeCell
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'quality',
|
||||||
|
label : 'Quality',
|
||||||
|
cell : QualityCell,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : "delete",
|
||||||
|
label : "",
|
||||||
|
cell : DeleteFileCell,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
initialize : function(movie) {
|
||||||
|
this.filesCollection = new FilesCollection();
|
||||||
|
var file = movie.model.get("movieFile");
|
||||||
|
this.filesCollection.add(file);
|
||||||
|
//this.listenTo(this.releaseCollection, 'sync', this._showSearchResults);
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow : function() {
|
||||||
|
this.grid.show(new Backgrid.Grid({
|
||||||
|
row : Backgrid.Row,
|
||||||
|
columns : this.columns,
|
||||||
|
collection : this.filesCollection,
|
||||||
|
className : 'table table-hover'
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_showMainView : function() {
|
||||||
|
this.main.show(this.mainView);
|
||||||
|
},
|
||||||
|
|
||||||
|
_showButtons : function() {
|
||||||
|
this._showMainView();
|
||||||
|
},
|
||||||
|
|
||||||
|
_showSearchResults : function() {
|
||||||
|
if (this.releaseCollection.length === 0) {
|
||||||
|
this.mainView = new NoResultsView();
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
//this.mainView = new ManualSearchLayout({ collection : this.releaseCollection });
|
||||||
|
}
|
||||||
|
|
||||||
|
this._showMainView();
|
||||||
|
}
|
||||||
|
});
|
1
src/UI/Movies/Files/FilesLayoutTemplate.hbs
Normal file
1
src/UI/Movies/Files/FilesLayoutTemplate.hbs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<div id="movie-files-region"><div id="movie-files-grid" class="table-responsive"></div></div>
|
5
src/UI/Movies/Files/NoFilesView.js
Normal file
5
src/UI/Movies/Files/NoFilesView.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
|
||||||
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Movies/Files/NoFilesViewTemplate'
|
||||||
|
});
|
3
src/UI/Movies/Files/NoFilesViewTemplate.hbs
Normal file
3
src/UI/Movies/Files/NoFilesViewTemplate.hbs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<p class="text-warning">
|
||||||
|
No files for this movie.
|
||||||
|
</p>
|
Loading…
Add table
Add a link
Reference in a new issue