mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
Add new feature, set file date to episode aired date. Fix, use alternative Trakt API field for episode air time. Improve the Preview Rename tip.
Add, new setting "Set File Date to Airdate" on the Media Management tab of the Settings page to toggle this feature for new, imported and auto updating media files. Change, home page "Series Editor" - "Rename" button to "Update Files" and add "Set File Date To Air Date" action button to this modal to add capability of updating legacy media. Add, non UTC functions given that Windows undesirably adds time to file times set when using UTC. Fix, the Trakt API response show.air_time_utc contains erroneous data, this is replaced with show.air_time.
This commit is contained in:
parent
9d74693bb7
commit
d9eab04029
@ -6,6 +6,7 @@ namespace NzbDrone.Api.Config
|
||||
public class MediaManagementConfigResource : RestResource
|
||||
{
|
||||
public Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||
public Boolean FileDateAiredDate { get; set; }
|
||||
public String RecycleBin { get; set; }
|
||||
public Boolean AutoDownloadPropers { get; set; }
|
||||
public Boolean CreateEmptySeriesFolders { get; set; }
|
||||
|
@ -35,7 +35,7 @@ private List<LogFileResource> GetLogFiles()
|
||||
{
|
||||
Id = i + 1,
|
||||
Filename = Path.GetFileName(file),
|
||||
LastWriteTime = _diskProvider.GetLastFileWrite(file)
|
||||
LastWriteTime = _diskProvider.GetLastFileWriteUTC(file)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,20 @@ public DateTime GetLastFolderWrite(string path)
|
||||
}
|
||||
|
||||
public DateTime GetLastFileWrite(string path)
|
||||
{
|
||||
PathEnsureFileExists(path);
|
||||
|
||||
return new FileInfo(path).LastWriteTime;
|
||||
}
|
||||
|
||||
public DateTime GetLastFileWriteUTC(string path)
|
||||
{
|
||||
PathEnsureFileExists(path);
|
||||
|
||||
return new FileInfo(path).LastWriteTimeUtc;
|
||||
}
|
||||
|
||||
private void PathEnsureFileExists(string path)
|
||||
{
|
||||
Ensure.That(path, () => path).IsValidPath();
|
||||
|
||||
@ -84,8 +98,6 @@ public DateTime GetLastFileWrite(string path)
|
||||
{
|
||||
throw new FileNotFoundException("File doesn't exist: " + path);
|
||||
}
|
||||
|
||||
return new FileInfo(path).LastWriteTimeUtc;
|
||||
}
|
||||
|
||||
public void EnsureFolder(string path)
|
||||
@ -305,6 +317,26 @@ public void FolderSetLastWriteTimeUtc(string path, DateTime dateTime)
|
||||
Directory.SetLastWriteTimeUtc(path, dateTime);
|
||||
}
|
||||
|
||||
public void FileSetLastWriteTime(string path, DateTime dateTime)
|
||||
{
|
||||
Ensure.That(path, () => path).IsValidPath();
|
||||
|
||||
File.SetLastWriteTime(path, dateTime);
|
||||
}
|
||||
public void FileSetLastAccessTime(string path, DateTime dateTime)
|
||||
{
|
||||
Ensure.That(path, () => path).IsValidPath();
|
||||
|
||||
File.SetLastAccessTimeUtc(path, dateTime);
|
||||
}
|
||||
|
||||
public void FileSetLastAccessTimeUtc(string path, DateTime dateTime)
|
||||
{
|
||||
Ensure.That(path, () => path).IsValidPath();
|
||||
|
||||
File.SetLastAccessTimeUtc(path, dateTime);
|
||||
}
|
||||
|
||||
public bool IsFileLocked(string file)
|
||||
{
|
||||
try
|
||||
|
@ -14,6 +14,7 @@ public interface IDiskProvider
|
||||
|
||||
DateTime GetLastFolderWrite(string path);
|
||||
DateTime GetLastFileWrite(string path);
|
||||
DateTime GetLastFileWriteUTC(string path);
|
||||
void EnsureFolder(string path);
|
||||
bool FolderExists(string path);
|
||||
bool FileExists(string path);
|
||||
@ -33,6 +34,8 @@ public interface IDiskProvider
|
||||
void WriteAllText(string filename, string contents);
|
||||
void FileSetLastWriteTimeUtc(string path, DateTime dateTime);
|
||||
void FolderSetLastWriteTimeUtc(string path, DateTime dateTime);
|
||||
void FileSetLastWriteTime(string path, DateTime dateTime);
|
||||
void FileSetLastAccessTime(string path, DateTime dateTime);
|
||||
bool IsFileLocked(string path);
|
||||
string GetPathRoot(string path);
|
||||
string GetParentFolder(string path);
|
||||
|
@ -29,7 +29,7 @@ public void should_convert_trakts_urls_to_local()
|
||||
new MediaCover.MediaCover {CoverType = MediaCoverTypes.Banner}
|
||||
};
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetLastFileWrite(It.IsAny<string>()))
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetLastFileWriteUTC(It.IsAny<string>()))
|
||||
.Returns(new DateTime(1234));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(It.IsAny<string>()))
|
||||
|
@ -42,7 +42,7 @@ private void GivenInWorkingFolder()
|
||||
private void GivenLastWriteTimeUtc(DateTime time)
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.GetLastFileWrite(It.IsAny<string>()))
|
||||
.Setup(s => s.GetLastFileWriteUTC(It.IsAny<string>()))
|
||||
.Returns(time);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ private void WithExpired()
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
|
||||
.Returns(DateTime.UtcNow.AddDays(-10));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWriteUTC(It.IsAny<String>()))
|
||||
.Returns(DateTime.UtcNow.AddDays(-10));
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ private void WithNonExpired()
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
|
||||
.Returns(DateTime.UtcNow.AddDays(-3));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWriteUTC(It.IsAny<String>()))
|
||||
.Returns(DateTime.UtcNow.AddDays(-3));
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,12 @@ public bool AutoUnmonitorPreviouslyDownloadedEpisodes
|
||||
set { SetValue("AutoUnmonitorPreviouslyDownloadedEpisodes", value); }
|
||||
}
|
||||
|
||||
public bool FileDateAiredDate
|
||||
{
|
||||
get { return GetValueBoolean("FileDateAiredDate"); }
|
||||
set { SetValue("FileDateAiredDate", value); }
|
||||
}
|
||||
|
||||
public int Retention
|
||||
{
|
||||
get { return GetValueInt("Retention", 0); }
|
||||
|
@ -20,6 +20,7 @@ public interface IConfigService
|
||||
|
||||
//Media Management
|
||||
Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||
Boolean FileDateAiredDate { get; set; }
|
||||
String RecycleBin { get; set; }
|
||||
Boolean AutoDownloadPropers { get; set; }
|
||||
Boolean CreateEmptySeriesFolders { get; set; }
|
||||
|
@ -67,7 +67,7 @@ public void ConvertToLocalUrls(int seriesId, IEnumerable<MediaCover> covers)
|
||||
|
||||
if (_diskProvider.FileExists(filePath))
|
||||
{
|
||||
var lastWrite = _diskProvider.GetLastFileWrite(filePath);
|
||||
var lastWrite = _diskProvider.GetLastFileWriteUTC(filePath);
|
||||
mediaCover.Url += "?lastWrite=" + lastWrite.Ticks;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.Commands
|
||||
{
|
||||
public class AirDateSeriesCommand : Command
|
||||
{
|
||||
public List<int> SeriesIds { get; set; }
|
||||
|
||||
public override bool SendUpdatesToClient
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,18 +22,21 @@ public interface IMoveEpisodeFiles
|
||||
public class EpisodeFileMovingService : IMoveEpisodeFiles
|
||||
{
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly IUpdateEpisodeFileService _updateEpisodeFileService;
|
||||
private readonly IBuildFileNames _buildFileNames;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public EpisodeFileMovingService(IEpisodeService episodeService,
|
||||
IUpdateEpisodeFileService updateEpisodeFileService,
|
||||
IBuildFileNames buildFileNames,
|
||||
IDiskProvider diskProvider,
|
||||
IConfigService configService,
|
||||
Logger logger)
|
||||
{
|
||||
_episodeService = episodeService;
|
||||
_updateEpisodeFileService = updateEpisodeFileService;
|
||||
_buildFileNames = buildFileNames;
|
||||
_diskProvider = diskProvider;
|
||||
_configService = configService;
|
||||
@ -102,6 +105,11 @@ private EpisodeFile MoveFile(EpisodeFile episodeFile, Series series, string dest
|
||||
_diskProvider.MoveFile(episodeFile.Path, destinationFilename);
|
||||
episodeFile.Path = destinationFilename;
|
||||
|
||||
if (_configService.FileDateAiredDate)
|
||||
{
|
||||
_updateEpisodeFileService.ChangeFileDateToAirdate(episodeFile, series);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Trace("Setting last write time on series folder: {0}", series.Path);
|
||||
|
@ -42,7 +42,7 @@ public bool IsSatisfiedBy(LocalEpisode localEpisode)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_diskProvider.GetLastFileWrite(localEpisode.Path) > DateTime.UtcNow.AddMinutes(-5))
|
||||
if (_diskProvider.GetLastFileWriteUTC(localEpisode.Path) > DateTime.UtcNow.AddMinutes(-5))
|
||||
{
|
||||
_logger.Trace("{0} appears to be unpacking still", localEpisode.Path);
|
||||
return false;
|
||||
|
15
src/NzbDrone.Core/MediaFiles/Events/SeriesAirDatedEvent.cs
Normal file
15
src/NzbDrone.Core/MediaFiles/Events/SeriesAirDatedEvent.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.Events
|
||||
{
|
||||
public class SeriesAirDatedEvent : IEvent
|
||||
{
|
||||
public Series Series { get; private set; }
|
||||
|
||||
public SeriesAirDatedEvent(Series series)
|
||||
{
|
||||
Series = series;
|
||||
}
|
||||
}
|
||||
}
|
@ -139,7 +139,7 @@ public void Cleanup()
|
||||
|
||||
foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
if (_diskProvider.GetLastFileWrite(file).AddDays(7) > DateTime.UtcNow)
|
||||
if (_diskProvider.GetLastFileWriteUTC(file).AddDays(7) > DateTime.UtcNow)
|
||||
{
|
||||
logger.Trace("File hasn't expired yet, skipping: {0}", file);
|
||||
continue;
|
||||
|
156
src/NzbDrone.Core/MediaFiles/UpdateEpisodeFileService.cs
Normal file
156
src/NzbDrone.Core/MediaFiles/UpdateEpisodeFileService.cs
Normal file
@ -0,0 +1,156 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Core.Configuration;
|
||||
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.Tv;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles
|
||||
{
|
||||
public interface IUpdateEpisodeFileService
|
||||
{
|
||||
void ChangeFileDateToAirdate(EpisodeFile episodeFile, Series series);
|
||||
}
|
||||
|
||||
public class UpdateEpisodeFileService : IUpdateEpisodeFileService,
|
||||
IExecute<AirDateSeriesCommand>,
|
||||
IHandle<SeriesScannedEvent>
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly ISeriesService _seriesService;
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public UpdateEpisodeFileService(IDiskProvider diskProvider,
|
||||
IConfigService configService,
|
||||
ISeriesService seriesService,
|
||||
IEpisodeService episodeService,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_configService = configService;
|
||||
_seriesService = seriesService;
|
||||
_episodeService = episodeService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void ChangeFileDateToAirdate(EpisodeFile episodeFile, Series series)
|
||||
{
|
||||
var episode = new Episode();
|
||||
episode.AirDate = episodeFile.Episodes.Value.First().AirDate;
|
||||
episode.EpisodeFile = episodeFile;
|
||||
episode.EpisodeFileId = 1;
|
||||
|
||||
var episodes = new List<Episode>();
|
||||
episodes.Add(episode);
|
||||
|
||||
ChangeFileDateToAirdate(episodes, series);
|
||||
}
|
||||
|
||||
private void ChangeFileDateToAirdate(List<Episode> episodes, Series series)
|
||||
{
|
||||
if (!episodes.Any())
|
||||
{
|
||||
_logger.ProgressDebug("{0} has no media files available to update with air dates", series.Title);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var done = new List<Episode>();
|
||||
|
||||
_logger.ProgressDebug("{0} ... checking {1} media file dates match air date", series.Title, episodes.Count);
|
||||
|
||||
foreach (var episode in episodes)
|
||||
{
|
||||
if (episode.HasFile
|
||||
&& episode.EpisodeFile.IsLoaded
|
||||
&& ChangeFileDate(episode.EpisodeFile.Value.Path, episode.AirDate, series.AirTime))
|
||||
{
|
||||
done.Add(episode);
|
||||
}
|
||||
}
|
||||
|
||||
if (done.Any())
|
||||
{
|
||||
_eventAggregator.PublishEvent(new SeriesAirDatedEvent(series));
|
||||
_logger.ProgressDebug("{0} had {1} of {2} media file dates changed to the date and time the episode aired", series.Title, done.Count, episodes.Count);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_logger.ProgressDebug("{0} has all its media file dates matching the date each aired", series.Title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Execute(AirDateSeriesCommand message)
|
||||
{
|
||||
var seriesToAirDate = _seriesService.GetSeries(message.SeriesIds);
|
||||
|
||||
foreach (var series in seriesToAirDate)
|
||||
{
|
||||
var episodes = _episodeService.EpisodesWithFiles(series.Id);
|
||||
|
||||
ChangeFileDateToAirdate(episodes, series);
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(SeriesScannedEvent message)
|
||||
{
|
||||
if (_configService.FileDateAiredDate)
|
||||
{
|
||||
var episodes = _episodeService.EpisodesWithFiles(message.Series.Id);
|
||||
|
||||
ChangeFileDateToAirdate(episodes, message.Series);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ChangeFileDate(String filePath, String fileDate, String fileTime)
|
||||
{
|
||||
DateTime dateTime, oldDateTime;
|
||||
bool result = false;
|
||||
|
||||
if (DateTime.TryParse(fileDate + ' ' + fileTime, out dateTime))
|
||||
{
|
||||
// avoiding false +ve checks and set date skewing by not using UTC (Windows)
|
||||
oldDateTime = _diskProvider.GetLastFileWrite(filePath);
|
||||
|
||||
if (!DateTime.Equals(dateTime, oldDateTime))
|
||||
{
|
||||
try
|
||||
{
|
||||
_diskProvider.FileSetLastWriteTime(filePath, dateTime);
|
||||
_diskProvider.FileSetLastAccessTime(filePath, dateTime);
|
||||
_logger.Info("Date of file [{0}] changed from \"{1}\" to \"{2}\"", filePath, oldDateTime, dateTime);
|
||||
result = true;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.WarnException("Unable to set date of file [" + filePath + "]", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_logger.Warn("Could not create valid date to set [{0}]", filePath);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -78,7 +78,7 @@ private static Series MapSeries(Show show)
|
||||
series.Overview = show.overview;
|
||||
series.Runtime = show.runtime;
|
||||
series.Network = show.network;
|
||||
series.AirTime = show.air_time_utc;
|
||||
series.AirTime = show.air_time;
|
||||
series.TitleSlug = show.url.ToLower().Replace("http://trakt.tv/show/", "");
|
||||
series.Status = GetSeriesStatus(show.status, show.ended);
|
||||
series.Ratings = GetRatings(show.ratings);
|
||||
|
@ -308,6 +308,7 @@
|
||||
<Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" />
|
||||
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
||||
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
||||
<Compile Include="MediaFiles\Commands\AirDateSeriesCommand.cs" />
|
||||
<Compile Include="MediaFiles\Commands\RenameSeriesCommand.cs" />
|
||||
<Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" />
|
||||
<Compile Include="Lifecycle\Commands\ShutdownCommand.cs" />
|
||||
@ -318,9 +319,11 @@
|
||||
<Compile Include="MediaFiles\EpisodeFileMoveResult.cs" />
|
||||
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" />
|
||||
<Compile Include="MediaFiles\Events\SeriesScannedEvent.cs" />
|
||||
<Compile Include="MediaFiles\Events\SeriesAirDatedEvent.cs" />
|
||||
<Compile Include="MediaFiles\MediaFileExtensions.cs" />
|
||||
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
|
||||
<Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" />
|
||||
<Compile Include="MediaFiles\UpdateEpisodeFileService.cs" />
|
||||
<Compile Include="Messaging\Commands\CommandExecutor.cs" />
|
||||
<Compile Include="Messaging\Commands\ICommandExecutor.cs" />
|
||||
<Compile Include="Messaging\Commands\IExecute.cs" />
|
||||
|
@ -10,7 +10,7 @@ define(
|
||||
'AddSeries/RootFolders/RootFolderCollection',
|
||||
'Shared/Toolbar/ToolbarLayout',
|
||||
'AddSeries/RootFolders/RootFolderLayout',
|
||||
'Series/Editor/Rename/RenameSeriesView',
|
||||
'Series/Editor/UpdateFiles/UpdateFilesSeriesView',
|
||||
'Config'
|
||||
], function (_,
|
||||
Marionette,
|
||||
@ -21,26 +21,26 @@ define(
|
||||
RootFolders,
|
||||
ToolbarLayout,
|
||||
RootFolderLayout,
|
||||
RenameSeriesView,
|
||||
UpdateFilesSeriesView,
|
||||
Config) {
|
||||
return Marionette.ItemView.extend({
|
||||
template: 'Series/Editor/SeriesEditorFooterViewTemplate',
|
||||
|
||||
ui: {
|
||||
monitored : '.x-monitored',
|
||||
qualityProfile: '.x-quality-profiles',
|
||||
seasonFolder : '.x-season-folder',
|
||||
rootFolder : '.x-root-folder',
|
||||
selectedCount : '.x-selected-count',
|
||||
saveButton : '.x-save',
|
||||
renameButton : '.x-rename',
|
||||
container : '.series-editor-footer'
|
||||
monitored : '.x-monitored',
|
||||
qualityProfile : '.x-quality-profiles',
|
||||
seasonFolder : '.x-season-folder',
|
||||
rootFolder : '.x-root-folder',
|
||||
selectedCount : '.x-selected-count',
|
||||
saveButton : '.x-save',
|
||||
updateFilesButton: '.x-update-files',
|
||||
container : '.series-editor-footer'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-save' : '_updateAndSave',
|
||||
'change .x-root-folder': '_rootFolderChanged',
|
||||
'click .x-rename' : '_rename'
|
||||
'click .x-update-files': '_updateFiles'
|
||||
},
|
||||
|
||||
templateHelpers: function () {
|
||||
@ -119,7 +119,7 @@ define(
|
||||
this.ui.seasonFolder.attr('disabled', '');
|
||||
this.ui.rootFolder.attr('disabled', '');
|
||||
this.ui.saveButton.attr('disabled', '');
|
||||
this.ui.renameButton.attr('disabled', '');
|
||||
this.ui.updateFilesButton.attr('disabled', '');
|
||||
}
|
||||
|
||||
else {
|
||||
@ -128,7 +128,7 @@ define(
|
||||
this.ui.seasonFolder.removeAttr('disabled', '');
|
||||
this.ui.rootFolder.removeAttr('disabled', '');
|
||||
this.ui.saveButton.removeAttr('disabled', '');
|
||||
this.ui.renameButton.removeAttr('disabled', '');
|
||||
this.ui.updateFilesButton.removeAttr('disabled', '');
|
||||
}
|
||||
},
|
||||
|
||||
@ -162,12 +162,12 @@ define(
|
||||
});
|
||||
},
|
||||
|
||||
_rename: function () {
|
||||
_updateFiles: function () {
|
||||
var selected = this.editorGrid.getSelectedModels();
|
||||
var renameSeriesView = new RenameSeriesView({ series: selected });
|
||||
this.listenToOnce(renameSeriesView, 'seriesRenamed', this._afterSave);
|
||||
var updateFilesSeriesView = new UpdateFilesSeriesView({ series: selected });
|
||||
this.listenToOnce(updateFilesSeriesView, 'updatingFiles', this._afterSave);
|
||||
|
||||
vent.trigger(vent.Commands.OpenModalCommand, renameSeriesView);
|
||||
vent.trigger(vent.Commands.OpenModalCommand, updateFilesSeriesView);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -45,7 +45,7 @@
|
||||
<span class="pull-right">
|
||||
<span class="selected-count x-selected-count">0 series selected</span>
|
||||
<button class="btn btn-primary x-save">Save</button>
|
||||
<button class="btn btn-danger x-rename">Rename</button>
|
||||
<button class="btn btn-danger x-update-files">Update Files</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
@ -9,10 +9,11 @@ define(
|
||||
], function (_, vent, Backbone, Marionette, CommandController) {
|
||||
|
||||
return Marionette.ItemView.extend({
|
||||
template: 'Series/Editor/Rename/RenameSeriesViewTemplate',
|
||||
template: 'Series/Editor/UpdateFiles/UpdateFilesSeriesViewTemplate',
|
||||
|
||||
events: {
|
||||
'click .x-confirm-rename': '_rename'
|
||||
'click .x-confirm-rename': '_rename',
|
||||
'click .x-confirm-airdate': '_setFileAirDate'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
@ -29,7 +30,19 @@ define(
|
||||
seriesIds : seriesIds
|
||||
});
|
||||
|
||||
this.trigger('seriesRenamed');
|
||||
this.trigger('updatingFiles');
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
},
|
||||
|
||||
_setFileAirDate: function () {
|
||||
var seriesIds = _.pluck(this.series, 'id');
|
||||
|
||||
CommandController.Execute('AirDateSeries', {
|
||||
name: 'AirDateSeries',
|
||||
seriesIds: seriesIds
|
||||
});
|
||||
|
||||
this.trigger('updatingFiles');
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
}
|
||||
});
|
@ -1,23 +1,24 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Rename Selected Series</h3>
|
||||
<h3>Update Files of Selected Series</h3>
|
||||
</div>
|
||||
<div class="modal-body rename-series-modal">
|
||||
<div class="modal-body update-files-series-modal">
|
||||
<div class="alert alert-info">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
You can use the rename function for an individual series to preview the rename
|
||||
Tip: To preview a rename... select "Cancel" then any series title and use the <i data-original-title="" class="icon-nd-rename" title=""></i>
|
||||
</div>
|
||||
|
||||
Are you sure you want to rename all files in the {{numberOfSeries}} selected series?
|
||||
Are you sure you want to update all files in the {{numberOfSeries}} selected series?
|
||||
|
||||
{{debug}}
|
||||
<ul class="selected-series">
|
||||
{{#each series}}
|
||||
<li>{{title}}</li>
|
||||
<li>{{title}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal">cancel</button>
|
||||
<button class="btn btn-danger x-confirm-rename">rename</button>
|
||||
<button class="btn btn-danger x-confirm-airdate">set file date to air date</button>
|
||||
</div>
|
@ -314,9 +314,13 @@
|
||||
.row {
|
||||
margin-left: -40px;
|
||||
}
|
||||
|
||||
.span2 {
|
||||
width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
.rename-series-modal {
|
||||
.update-files-series-modal {
|
||||
.selected-series {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
@ -21,6 +21,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Set File Date to Airdate</label>
|
||||
<div class="controls">
|
||||
<label class="checkbox toggle well">
|
||||
<input type="checkbox" name="fileDateAiredDate" />
|
||||
<p>
|
||||
<span>Yes</span>
|
||||
<span>No</span>
|
||||
</p>
|
||||
<div class="btn btn-primary slide-button" />
|
||||
</label>
|
||||
<span class="help-inline-checkbox">
|
||||
<i class="icon-nd-form-info" title="Adjust added media file dates to the original episode aired date" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Download Propers</label>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user