Rename preview for full series and season

New: Preview before renaming files
This commit is contained in:
Mark McDowall 2013-11-26 00:06:28 -08:00
parent bb37444a99
commit e42ac25657
29 changed files with 449 additions and 111 deletions

View File

@ -0,0 +1,42 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaFiles;
namespace NzbDrone.Api.Episodes
{
public class RenameEpisodeModule : NzbDroneRestModule<RenameEpisodeResource>
{
private readonly IRenameEpisodeFileService _renameEpisodeFileService;
public RenameEpisodeModule(IRenameEpisodeFileService renameEpisodeFileService)
: base("rename")
{
_renameEpisodeFileService = renameEpisodeFileService;
GetResourceAll = GetEpisodes;
}
private List<RenameEpisodeResource> GetEpisodes()
{
int seriesId;
if (Request.Query.SeriesId.HasValue)
{
seriesId = (int)Request.Query.SeriesId;
}
else
{
throw new BadRequestException("seriesId is missing");
}
if (Request.Query.SeasonNumber.HasValue)
{
var seasonNumber = (int)Request.Query.SeasonNumber;
return ToListResource(() => _renameEpisodeFileService.GetRenamePreviews(seriesId, seasonNumber));
}
return ToListResource(() => _renameEpisodeFileService.GetRenamePreviews(seriesId));
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NzbDrone.Api.REST;
namespace NzbDrone.Api.Episodes
{
public class RenameEpisodeResource : RestResource
{
public Int32 SeriesId { get; set; }
public Int32 SeasonNumber { get; set; }
public List<Int32> EpisodeNumbers { get; set; }
public Int32 EpisodeFileId { get; set; }
public String ExistingPath { get; set; }
public String NewPath { get; set; }
}
}

View File

@ -95,6 +95,8 @@
<Compile Include="Directories\DirectoryModule.cs" />
<Compile Include="Episodes\EpisodeModule.cs" />
<Compile Include="Episodes\EpisodeResource.cs" />
<Compile Include="Episodes\RenameEpisodeModule.cs" />
<Compile Include="Episodes\RenameEpisodeResource.cs" />
<Compile Include="Extensions\Pipelines\CacheHeaderPipeline.cs" />
<Compile Include="Extensions\Pipelines\GZipPipeline.cs" />
<Compile Include="Extensions\Pipelines\IfModifiedPipeline.cs" />

View File

@ -38,22 +38,14 @@ namespace NzbDrone.Core.Test.MediaFiles
private void GivenNoEpisodeFiles()
{
Mocker.GetMock<IMediaFileService>()
.Setup(s => s.GetFilesBySeries(_series.Id))
.Returns(new List<EpisodeFile>());
Mocker.GetMock<IMediaFileService>()
.Setup(s => s.GetFilesBySeason(_series.Id, _episodeFiles.First().SeasonNumber))
.Setup(s => s.Get(It.IsAny<IEnumerable<int>>()))
.Returns(new List<EpisodeFile>());
}
private void GivenEpisodeFiles()
{
Mocker.GetMock<IMediaFileService>()
.Setup(s => s.GetFilesBySeries(_series.Id))
.Returns(_episodeFiles);
Mocker.GetMock<IMediaFileService>()
.Setup(s => s.GetFilesBySeason(_series.Id, _episodeFiles.First().SeasonNumber))
.Setup(s => s.Get(It.IsAny<IEnumerable<int>>()))
.Returns(_episodeFiles);
}
@ -68,7 +60,7 @@ namespace NzbDrone.Core.Test.MediaFiles
{
GivenNoEpisodeFiles();
Subject.Execute(new RenameSeriesCommand(_series.Id));
Subject.Execute(new RenameFilesCommand(_series.Id, new List<int>{1}));
Mocker.GetMock<IEventAggregator>()
.Verify(v => v.PublishEvent(It.IsAny<SeriesRenamedEvent>()), Times.Never());
@ -83,7 +75,7 @@ namespace NzbDrone.Core.Test.MediaFiles
.Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<Series>()))
.Throws(new SameFilenameException("Same file name", "Filename"));
Subject.Execute(new RenameSeriesCommand(_series.Id));
Subject.Execute(new RenameFilesCommand(_series.Id, new List<int> { 1 }));
Mocker.GetMock<IEventAggregator>()
.Verify(v => v.PublishEvent(It.IsAny<SeriesRenamedEvent>()), Times.Never());
@ -95,7 +87,7 @@ namespace NzbDrone.Core.Test.MediaFiles
GivenEpisodeFiles();
GivenMovedFiles();
Subject.Execute(new RenameSeriesCommand(_series.Id));
Subject.Execute(new RenameFilesCommand(_series.Id, new List<int> { 1 }));
Mocker.GetMock<IEventAggregator>()
.Verify(v => v.PublishEvent(It.IsAny<SeriesRenamedEvent>()), Times.Once());
@ -107,40 +99,24 @@ namespace NzbDrone.Core.Test.MediaFiles
GivenEpisodeFiles();
GivenMovedFiles();
Subject.Execute(new RenameSeriesCommand(_series.Id));
Subject.Execute(new RenameFilesCommand(_series.Id, new List<int> { 1 }));
Mocker.GetMock<IMediaFileService>()
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(2));
}
[Test]
public void rename_season_should_get_episodefiles_for_season()
public void should_get_episodefiles_by_ids_only()
{
GivenEpisodeFiles();
GivenMovedFiles();
Subject.Execute(new RenameSeasonCommand(_series.Id, _episodeFiles.First().SeasonNumber));
var files = new List<int> { 1 };
Subject.Execute(new RenameFilesCommand(_series.Id, files));
Mocker.GetMock<IMediaFileService>()
.Verify(v => v.GetFilesBySeries(_series.Id), Times.Never());
Mocker.GetMock<IMediaFileService>()
.Verify(v => v.GetFilesBySeason(_series.Id, _episodeFiles.First().SeasonNumber), Times.Once());
}
[Test]
public void rename_series_should_get_episodefiles_for_series()
{
GivenEpisodeFiles();
GivenMovedFiles();
Subject.Execute(new RenameSeriesCommand(_series.Id));
Mocker.GetMock<IMediaFileService>()
.Verify(v => v.GetFilesBySeries(_series.Id), Times.Once());
Mocker.GetMock<IMediaFileService>()
.Verify(v => v.GetFilesBySeason(_series.Id, _episodeFiles.First().SeasonNumber), Times.Never());
.Verify(v => v.Get(files), Times.Once());
}
}
}

View File

@ -1,10 +1,12 @@
using System.Collections.Generic;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.MediaFiles.Commands
{
public class RenameSeriesCommand : Command
public class RenameFilesCommand : Command
{
public int SeriesId { get; set; }
public List<int> Files { get; set; }
public override bool SendUpdatesToClient
{
@ -14,13 +16,14 @@ namespace NzbDrone.Core.MediaFiles.Commands
}
}
public RenameSeriesCommand()
public RenameFilesCommand()
{
}
public RenameSeriesCommand(int seriesId)
public RenameFilesCommand(int seriesId, List<int> files)
{
SeriesId = seriesId;
Files = files;
}
}
}

View File

@ -1,24 +0,0 @@
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.MediaFiles.Commands
{
public class RenameSeasonCommand : Command
{
public int SeriesId { get; set; }
public int SeasonNumber { get; set; }
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public RenameSeasonCommand(int seriesId, int seasonNumber)
{
SeriesId = seriesId;
SeasonNumber = seasonNumber;
}
}
}

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
@ -17,6 +18,7 @@ namespace NzbDrone.Core.MediaFiles
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
List<string> FilterExistingFiles(List<string> files, int seriesId);
EpisodeFile Get(int id);
List<EpisodeFile> Get(IEnumerable<int> ids);
}
public class MediaFileService : IMediaFileService, IHandleAsync<SeriesDeletedEvent>
@ -75,6 +77,11 @@ namespace NzbDrone.Core.MediaFiles
return _mediaFileRepository.Get(id);
}
public List<EpisodeFile> Get(IEnumerable<int> ids)
{
return _mediaFileRepository.Get(ids).ToList();
}
public void HandleAsync(SeriesDeletedEvent message)
{
var files = GetFilesBySeries(message.Series.Id);

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Core.MediaFiles
{
public class RenameEpisodeFilePreview
{
public Int32 SeriesId { get; set; }
public Int32 SeasonNumber { get; set; }
public List<Int32> EpisodeNumbers { get; set; }
public Int32 EpisodeFileId { get; set; }
public String ExistingPath { get; set; }
public String NewPath { get; set; }
}
}

View File

@ -1,37 +1,100 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MediaFiles
{
public class RenameEpisodeFileService : IExecute<RenameSeasonCommand>, IExecute<RenameSeriesCommand>
public interface IRenameEpisodeFileService
{
List<RenameEpisodeFilePreview> GetRenamePreviews(int seriesId);
List<RenameEpisodeFilePreview> GetRenamePreviews(int seriesId, int seasonNumber);
}
public class RenameEpisodeFileService : IRenameEpisodeFileService,
IExecute<RenameFilesCommand>
{
private readonly ISeriesService _seriesService;
private readonly IMediaFileService _mediaFileService;
private readonly IMoveEpisodeFiles _episodeFileMover;
private readonly IEventAggregator _eventAggregator;
private readonly IEpisodeService _episodeService;
private readonly IBuildFileNames _filenameBuilder;
private readonly Logger _logger;
public RenameEpisodeFileService(ISeriesService seriesService,
IMediaFileService mediaFileService,
IMoveEpisodeFiles episodeFileMover,
IEventAggregator eventAggregator,
IEpisodeService episodeService,
IBuildFileNames filenameBuilder,
Logger logger)
{
_seriesService = seriesService;
_mediaFileService = mediaFileService;
_episodeFileMover = episodeFileMover;
_eventAggregator = eventAggregator;
_episodeService = episodeService;
_filenameBuilder = filenameBuilder;
_logger = logger;
}
public List<RenameEpisodeFilePreview> GetRenamePreviews(int seriesId)
{
var series = _seriesService.GetSeries(seriesId);
var episodes = _episodeService.GetEpisodeBySeries(seriesId);
var files = _mediaFileService.GetFilesBySeries(seriesId);
return GetPreviews(series, episodes, files).ToList();
}
public List<RenameEpisodeFilePreview> GetRenamePreviews(int seriesId, int seasonNumber)
{
var series = _seriesService.GetSeries(seriesId);
var episodes = _episodeService.GetEpisodesBySeason(seriesId, seasonNumber);
var files = _mediaFileService.GetFilesBySeason(seriesId, seasonNumber);
return GetPreviews(series, episodes, files).ToList();
}
private IEnumerable<RenameEpisodeFilePreview> GetPreviews(Series series, List<Episode> episodes, List<EpisodeFile> files)
{
foreach (var file in files)
{
var episodesInFile = episodes.Where(e => e.EpisodeFileId == file.Id).ToList();
var seasonNumber = episodesInFile.First().SeasonNumber;
var newName = _filenameBuilder.BuildFilename(episodesInFile, series, file);
var newPath = _filenameBuilder.BuildFilePath(series, seasonNumber, newName, Path.GetExtension(file.Path));
if (!file.Path.PathEquals(newPath))
{
yield return new RenameEpisodeFilePreview
{
SeriesId = series.Id,
SeasonNumber = seasonNumber,
EpisodeNumbers = episodesInFile.Select(e => e.EpisodeNumber).ToList(),
EpisodeFileId = file.Id,
ExistingPath = GetRelativePath(series.Path, file.Path),
NewPath = GetRelativePath(series.Path, newPath)
};
}
}
}
private string GetRelativePath(string seriesPath, string path)
{
return path.Substring(seriesPath.Length + 1);
}
private void RenameFiles(List<EpisodeFile> episodeFiles, Series series)
{
var renamed = new List<EpisodeFile>();
@ -64,24 +127,14 @@ namespace NzbDrone.Core.MediaFiles
}
}
public void Execute(RenameSeasonCommand message)
public void Execute(RenameFilesCommand message)
{
var series = _seriesService.GetSeries(message.SeriesId);
var episodeFiles = _mediaFileService.GetFilesBySeason(message.SeriesId, message.SeasonNumber);
_logger.ProgressInfo("Renaming {0} files for {1} season {2}", episodeFiles.Count, series.Title, message.SeasonNumber);
RenameFiles(episodeFiles, series);
_logger.ProgressInfo("Episode Fies renamed for {0} season {1}", series.Title, message.SeasonNumber);
}
public void Execute(RenameSeriesCommand message)
{
var series = _seriesService.GetSeries(message.SeriesId);
var episodeFiles = _mediaFileService.GetFilesBySeries(message.SeriesId);
var episodeFiles = _mediaFileService.Get(message.Files);
_logger.ProgressInfo("Renaming {0} files for {1}", episodeFiles.Count, series.Title);
RenameFiles(episodeFiles, series);
_logger.ProgressInfo("Episode Fies renamed for {0}", series.Title);
_logger.ProgressInfo("Selected Episode Files renamed for {0}", series.Title);
}
}
}

View File

@ -278,9 +278,11 @@
<Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" />
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
<Compile Include="MediaFiles\Commands\RenameFilesCommand.cs" />
<Compile Include="MediaFiles\EpisodeFileMoveResult.cs" />
<Compile Include="MediaFiles\MediaFileExtensions.cs" />
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
<Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" />
<Compile Include="Messaging\Commands\CommandExecutor.cs" />
<Compile Include="Messaging\Commands\ICommandExecutor.cs" />
<Compile Include="Messaging\Commands\IExecute.cs" />
@ -343,8 +345,6 @@
<Compile Include="MediaCover\CoverAlreadyExistsSpecification.cs" />
<Compile Include="MediaFiles\Commands\CleanMediaFileDb.cs" />
<Compile Include="MediaFiles\Commands\CleanUpRecycleBinCommand.cs" />
<Compile Include="MediaFiles\Commands\RenameSeriesCommand.cs" />
<Compile Include="MediaFiles\Commands\RenameSeasonCommand.cs" />
<Compile Include="MediaFiles\Commands\DownloadedEpisodesScanCommand.cs" />
<Compile Include="MediaFiles\EpisodeImport\ImportDecision.cs" />
<Compile Include="MediaFiles\EpisodeImport\IImportDecisionEngineSpecification.cs" />

View File

@ -0,0 +1,6 @@
C:\Dropbox\Dev\NzbDrone\_output\ServiceInstall.exe.config
C:\Dropbox\Dev\NzbDrone\_output\ServiceInstall.exe
C:\Dropbox\Dev\NzbDrone\_output\ServiceInstall.pdb
C:\Dropbox\Dev\NzbDrone\src\ServiceHelpers\ServiceInstall\obj\x86\Debug\ServiceInstall.csprojResolveAssemblyReference.cache
C:\Dropbox\Dev\NzbDrone\src\ServiceHelpers\ServiceInstall\obj\x86\Debug\ServiceInstall.exe
C:\Dropbox\Dev\NzbDrone\src\ServiceHelpers\ServiceInstall\obj\x86\Debug\ServiceInstall.pdb

View File

@ -0,0 +1,5 @@
C:\Dropbox\Dev\NzbDrone\_output\ServiceUninstall.exe.config
C:\Dropbox\Dev\NzbDrone\_output\ServiceUninstall.exe
C:\Dropbox\Dev\NzbDrone\_output\ServiceUninstall.pdb
C:\Dropbox\Dev\NzbDrone\src\ServiceHelpers\ServiceUninstall\obj\x86\Debug\ServiceUninstall.exe
C:\Dropbox\Dev\NzbDrone\src\ServiceHelpers\ServiceUninstall\obj\x86\Debug\ServiceUninstall.pdb

View File

@ -49,7 +49,6 @@ https://github.com/ghinda/css-toggle-switch
left: -100px;
width: 100%;
margin: 0;
padding-right: 100px;
text-align: left;
}

View File

@ -183,4 +183,18 @@ footer {
#errors{
display : none;
}
.rename-preview-item {
margin-bottom: 5px;
padding: 5px;
border-bottom: 1px solid #e5e5e5;
.checkbox {
width: 80px;
margin-left: 0px;
display: inline-block;
padding-top: 0px;
margin-bottom: 0px;
}
}

View File

@ -0,0 +1,38 @@
'use strict';
define(
[
'backbone',
'Rename/RenamePreviewModel'
], function (Backbone, RenamePreviewModel) {
return Backbone.Collection.extend({
url : window.NzbDrone.ApiRoot + '/rename',
model: RenamePreviewModel,
originalFetch: Backbone.Collection.prototype.fetch,
initialize: function (options) {
if (!options.seriesId) {
throw 'seriesId is required';
}
this.seriesId = options.seriesId;
this.seasonNumber = options.seasonNumber;
},
fetch: function (options) {
if (!this.seriesId) {
throw 'seriesId is required';
}
options = options || {};
options.data = {};
options.data.seriesId = this.seriesId;
if (this.seasonNumber) {
options.data.seasonNumber = this.seasonNumber;
}
return this.originalFetch.call(this, options);
}
});
});

View File

@ -0,0 +1,11 @@
'use strict';
define(
[
'marionette',
'Rename/RenamePreviewItemView'
], function (Marionette, RenamePreviewItemView) {
return Marionette.CollectionView.extend({
itemView : RenamePreviewItemView
});
});

View File

@ -0,0 +1,10 @@
'use strict';
define(
[
'vent',
'marionette'
], function (vent, Marionette) {
return Marionette.ItemView.extend({
template: 'Rename/RenamePreviewEmptyCollectionViewTemplate'
});
});

View File

@ -0,0 +1,3 @@
<div class="alert alert-success">
Success! My work is done, no files to rename.
</div>

View File

@ -0,0 +1,13 @@
'use strict';
define(
[
'vent',
'marionette',
'Mixins/AsModelBoundView'
], function (vent, Marionette, AsModelBoundView) {
var view = Marionette.ItemView.extend({
template: 'Rename/RenamePreviewItemViewTemplate'
});
return AsModelBoundView.apply(view);
});

View File

@ -0,0 +1,25 @@
<div class="rename-preview-item">
<div class="row">
<div class="span1">
<label class="checkbox toggle well" title="Rename file">
<input type="checkbox" name="rename"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-warning slide-button"/>
</label>
</div>
<div class="span9">
<div class="row">
<div class="span1">Existing</div>
<div class="span8">{{existingPath}}</div>
</div>
<div class="row">
<div class="span1">Suggested</div>
<div class="span8">{{newPath}}</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,93 @@
'use strict';
define(
[
'underscore',
'vent',
'marionette',
'Rename/RenamePreviewCollection',
'Rename/RenamePreviewCollectionView',
'Rename/RenamePreviewEmptyCollectionView',
'Shared/LoadingView',
'Commands/CommandController'
], function (_, vent, Marionette, RenamePreviewCollection, RenamePreviewCollectionView, EmptyCollectionView, LoadingView, CommandController) {
return Marionette.Layout.extend({
template: 'Rename/RenamePreviewLayoutTemplate',
regions: {
renamePreviews : '#rename-previews'
},
ui: {
pathInfo: '.x-path-info'
},
events: {
'click .x-organize': '_organizeFiles'
},
initialize: function (options) {
this.model = options.series;
this.seasonNumber = options.seasonNumber;
var viewOptions = {};
viewOptions.seriesId = this.model.id;
viewOptions.seasonNumber = this.seasonNumber;
this.collection = new RenamePreviewCollection(viewOptions);
this.listenTo(this.collection, 'sync', this._showPreviews);
this.collection.fetch();
},
onRender: function() {
this.renamePreviews.show(new LoadingView());
},
_showPreviews: function () {
if (this.collection.length === 0) {
this.ui.pathInfo.hide();
this.renamePreviews.show(new EmptyCollectionView());
return;
}
this.collection.invoke('set', { rename: true });
this.renamePreviews.show(new RenamePreviewCollectionView({ collection: this.collection }));
},
_organizeFiles: function () {
if (this.collection.length === 0) {
vent.trigger(vent.Commands.CloseModalCommand);
}
var files = _.map(this.collection.where({ rename: true }), function (model) {
return model.get('episodeFileId');
});
if (files.length === 0) {
vent.trigger(vent.Commands.CloseModalCommand);
return;
}
if (this.seasonNumber) {
CommandController.Execute('renameFiles', {
name : 'renameFiles',
seriesId : this.model.id,
seasonNumber: this.seasonNumber,
files : files
});
}
else {
CommandController.Execute('renameFiles', {
name : 'renameFiles',
seriesId : this.model.id,
seasonNumber: -1,
files : files
});
}
vent.trigger(vent.Commands.CloseModalCommand);
}
});
});

View File

@ -0,0 +1,19 @@
<div class="rename-preview-modal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>
Organize & Rename
</h3>
</div>
<div class="modal-body">
<div class="alert alert-info x-path-info">All paths are relative to: <strong>{{path}}</strong></div>
<div id="rename-previews"></div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal">close</button>
<button class="btn x-organize">Organize</button>
</div>
</div>

View File

@ -0,0 +1,9 @@
'use strict';
define(
[
'backbone'
], function (Backbone) {
return Backbone.Model.extend({
});
});

View File

@ -12,7 +12,7 @@ define(
'Commands/CommandController',
'moment',
'underscore'
], function (vent, Marionette, Backgrid, ToggleCell, EpisodeTitleCell, RelativeDateCell, EpisodeStatusCell, EpisodeActionsCell, CommandController, Moment,_) {
], function (vent, Marionette, Backgrid, ToggleCell, EpisodeTitleCell, RelativeDateCell, EpisodeStatusCell, EpisodeActionsCell, CommandController, Moment, _) {
return Marionette.Layout.extend({
template: 'Series/Details/SeasonLayoutTemplate',
@ -114,7 +114,7 @@ define(
CommandController.bindToCommand({
element: this.ui.seasonRename,
command: {
name : 'renameSeason',
name : 'renameFiles',
seriesId : this.series.id,
seasonNumber: this.model.get('seasonNumber')
}
@ -131,12 +131,7 @@ define(
},
_seasonRename: function () {
CommandController.Execute('renameSeason', {
name : 'renameSeason',
seriesId : this.series.id,
seasonNumber: this.model.get('seasonNumber')
});
vent.trigger(vent.Commands.ShowRenamePreview, { series: this.series, seasonNumber: this.model.get('seasonNumber') });
},
_seasonMonitored: function () {
@ -172,11 +167,6 @@ define(
}
},
_afterRename: function () {
vent.trigger(vent.Events.SeasonRenamed, { series: this.series, seasonNumber: this.model.get('seasonNumber') });
},
_showEpisodes: function () {
this.episodeGrid.show(new Backgrid.Grid({
columns : this.columns,

View File

@ -2,6 +2,7 @@
define(
[
'jquery',
'underscore',
'vent',
'reqres',
'marionette',
@ -13,10 +14,21 @@ define(
'Series/Details/InfoView',
'Commands/CommandController',
'Shared/LoadingView',
'underscore',
'backstrech',
'Mixins/backbone.signalr.mixin'
], function ($,vent,reqres, Marionette, Backbone, EpisodeCollection, EpisodeFileCollection, SeasonCollection, SeasonCollectionView, InfoView, CommandController, LoadingView, _) {
], function ($,
_,
vent,
reqres,
Marionette,
Backbone,
EpisodeCollection,
EpisodeFileCollection,
SeasonCollection,
SeasonCollectionView,
InfoView,
CommandController,
LoadingView) {
return Marionette.Layout.extend({
itemViewContainer: '.x-series-seasons',
@ -47,7 +59,6 @@ define(
initialize: function () {
this.listenTo(this.model, 'change:monitored', this._setMonitoredState);
this.listenTo(vent, vent.Events.SeriesDeleted, this._onSeriesDeleted);
this.listenTo(vent, vent.Events.SeasonRenamed, this._onSeasonRenamed);
vent.on(vent.Events.CommandComplete, this._commandComplete, this);
},
@ -86,7 +97,9 @@ define(
CommandController.bindToCommand({
element: this.ui.rename,
command: {
name: 'renameSeries'
name : 'renameFiles',
seriesId : this.model.id,
seasonNumber: -1
}
});
},
@ -154,11 +167,7 @@ define(
},
_renameSeries: function () {
CommandController.Execute('renameSeries', {
name : 'renameSeries',
seriesId: this.model.id
});
vent.trigger(vent.Commands.ShowRenamePreview, { series: this.model });
},
_seriesSearch: function () {
@ -196,14 +205,8 @@ define(
this.info.show(new InfoView({ model: this.model }));
},
_onSeasonRenamed: function (event) {
if (this.model.get('id') === event.series.get('id')) {
this.episodeFileCollection.fetch();
}
},
_commandComplete: function (options) {
if (options.command.get('name') === 'refreshseries' || options.command.get('name') === 'renameseries') {
if (options.command.get('name') === 'refreshseries' || options.command.get('name') === 'renamefiles') {
if (options.command.get('seriesId') === this.model.get('id')) {
this._showSeasons();
this._setMonitoredState();

View File

@ -9,7 +9,8 @@ define(
'Episode/EpisodeDetailsLayout',
'History/Details/HistoryDetailsView',
'System/Logs/Table/Details/LogDetailsView',
], function (vent, AppLayout, Marionette, EditSeriesView, DeleteSeriesView, EpisodeDetailsLayout, HistoryDetailsView, LogDetailsView) {
'Rename/RenamePreviewLayout'
], function (vent, AppLayout, Marionette, EditSeriesView, DeleteSeriesView, EpisodeDetailsLayout, HistoryDetailsView, LogDetailsView, RenamePreviewLayout) {
return Marionette.AppRouter.extend({
@ -21,6 +22,7 @@ define(
vent.on(vent.Commands.ShowEpisodeDetails, this._showEpisode, this);
vent.on(vent.Commands.ShowHistoryDetails, this._showHistory, this);
vent.on(vent.Commands.ShowLogDetails, this._showLogDetails, this);
vent.on(vent.Commands.ShowRenamePreview, this._showRenamePreview, this);
},
_openModal: function (view) {
@ -54,6 +56,11 @@ define(
_showLogDetails: function (options) {
var view = new LogDetailsView({ model: options.model });
AppLayout.modalRegion.show(view);
},
_showRenamePreview: function (options) {
var view = new RenamePreviewLayout(options);
AppLayout.modalRegion.show(view);
}
});
});

View File

@ -10,7 +10,6 @@ define(
vent.Events = {
SeriesAdded : 'series:added',
SeriesDeleted : 'series:deleted',
SeasonRenamed : 'season:renamed',
CommandComplete: 'command:complete',
ServerUpdated : 'server:updated'
};
@ -25,7 +24,7 @@ define(
ShowLogDetails : 'ShowLogDetails',
SaveSettings : 'saveSettings',
ShowLogFile : 'showLogFile',
ShowNamingWizard : 'showNamingWizard'
ShowRenamePreview : 'showRenamePreview'
};
return vent;