2013-08-13 05:01:15 +03:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2013-11-26 11:06:28 +03:00
|
|
|
using System.IO;
|
2013-07-19 08:23:04 +03:00
|
|
|
using System.Linq;
|
|
|
|
using NLog;
|
2013-11-26 11:06:28 +03:00
|
|
|
using NzbDrone.Common;
|
2013-09-11 09:33:47 +03:00
|
|
|
using NzbDrone.Core.Instrumentation;
|
2013-07-19 08:23:04 +03:00
|
|
|
using NzbDrone.Core.MediaFiles.Commands;
|
|
|
|
using NzbDrone.Core.MediaFiles.Events;
|
2013-09-14 09:36:07 +03:00
|
|
|
using NzbDrone.Core.Messaging.Commands;
|
|
|
|
using NzbDrone.Core.Messaging.Events;
|
2013-11-26 11:06:28 +03:00
|
|
|
using NzbDrone.Core.Organizer;
|
2013-07-19 08:23:04 +03:00
|
|
|
using NzbDrone.Core.Tv;
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.MediaFiles
|
|
|
|
{
|
2013-11-26 11:06:28 +03:00
|
|
|
public interface IRenameEpisodeFileService
|
|
|
|
{
|
|
|
|
List<RenameEpisodeFilePreview> GetRenamePreviews(int seriesId);
|
|
|
|
List<RenameEpisodeFilePreview> GetRenamePreviews(int seriesId, int seasonNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
public class RenameEpisodeFileService : IRenameEpisodeFileService,
|
2014-02-27 19:51:31 +03:00
|
|
|
IExecute<RenameFilesCommand>,
|
|
|
|
IExecute<RenameSeriesCommand>
|
2013-07-19 08:23:04 +03:00
|
|
|
{
|
|
|
|
private readonly ISeriesService _seriesService;
|
|
|
|
private readonly IMediaFileService _mediaFileService;
|
|
|
|
private readonly IMoveEpisodeFiles _episodeFileMover;
|
2013-09-14 09:36:07 +03:00
|
|
|
private readonly IEventAggregator _eventAggregator;
|
2013-11-26 11:06:28 +03:00
|
|
|
private readonly IEpisodeService _episodeService;
|
|
|
|
private readonly IBuildFileNames _filenameBuilder;
|
2013-07-19 08:23:04 +03:00
|
|
|
private readonly Logger _logger;
|
|
|
|
|
|
|
|
public RenameEpisodeFileService(ISeriesService seriesService,
|
|
|
|
IMediaFileService mediaFileService,
|
|
|
|
IMoveEpisodeFiles episodeFileMover,
|
2013-09-14 09:36:07 +03:00
|
|
|
IEventAggregator eventAggregator,
|
2013-11-26 11:06:28 +03:00
|
|
|
IEpisodeService episodeService,
|
|
|
|
IBuildFileNames filenameBuilder,
|
2013-07-19 08:23:04 +03:00
|
|
|
Logger logger)
|
|
|
|
{
|
|
|
|
_seriesService = seriesService;
|
|
|
|
_mediaFileService = mediaFileService;
|
|
|
|
_episodeFileMover = episodeFileMover;
|
2013-09-14 09:36:07 +03:00
|
|
|
_eventAggregator = eventAggregator;
|
2013-11-26 11:06:28 +03:00
|
|
|
_episodeService = episodeService;
|
|
|
|
_filenameBuilder = filenameBuilder;
|
2013-07-19 08:23:04 +03:00
|
|
|
_logger = logger;
|
|
|
|
}
|
|
|
|
|
2013-11-26 11:06:28 +03:00
|
|
|
public List<RenameEpisodeFilePreview> GetRenamePreviews(int seriesId)
|
|
|
|
{
|
|
|
|
var series = _seriesService.GetSeries(seriesId);
|
|
|
|
var episodes = _episodeService.GetEpisodeBySeries(seriesId);
|
|
|
|
var files = _mediaFileService.GetFilesBySeries(seriesId);
|
|
|
|
|
2013-11-30 04:26:13 +03:00
|
|
|
return GetPreviews(series, episodes, files)
|
|
|
|
.OrderBy(e => e.SeasonNumber)
|
|
|
|
.ThenBy(e => e.EpisodeNumbers.First())
|
|
|
|
.ToList();
|
2013-11-26 11:06:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2013-11-30 04:26:13 +03:00
|
|
|
return GetPreviews(series, episodes, files)
|
|
|
|
.OrderBy(e => e.EpisodeNumbers.First()).ToList();
|
2013-11-26 11:06:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
2014-02-24 00:37:21 +03:00
|
|
|
|
|
|
|
if (!episodesInFile.Any())
|
|
|
|
{
|
|
|
|
_logger.Warn("File ({0}) is not linked to any episodes", file.Path);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-11-26 11:06:28 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2013-07-19 08:23:04 +03:00
|
|
|
private void RenameFiles(List<EpisodeFile> episodeFiles, Series series)
|
|
|
|
{
|
|
|
|
var renamed = new List<EpisodeFile>();
|
|
|
|
|
2013-08-30 09:41:49 +03:00
|
|
|
foreach (var episodeFile in episodeFiles)
|
2013-07-19 08:23:04 +03:00
|
|
|
{
|
2013-08-13 05:01:15 +03:00
|
|
|
try
|
|
|
|
{
|
|
|
|
_logger.Trace("Renaming episode file: {0}", episodeFile);
|
2014-02-28 03:32:08 +03:00
|
|
|
_episodeFileMover.MoveEpisodeFile(episodeFile, series);
|
2013-07-19 08:23:04 +03:00
|
|
|
|
|
|
|
_mediaFileService.Update(episodeFile);
|
|
|
|
renamed.Add(episodeFile);
|
|
|
|
|
2013-08-13 05:01:15 +03:00
|
|
|
_logger.Trace("Renamed episode file: {0}", episodeFile);
|
|
|
|
}
|
|
|
|
catch (SameFilenameException ex)
|
|
|
|
{
|
|
|
|
_logger.Trace("File not renamed, source and destination are the same: {0}", ex.Filename);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
2013-08-30 09:41:49 +03:00
|
|
|
_logger.ErrorException("Failed to rename file: " + episodeFile.Path, ex);
|
2013-08-13 05:01:15 +03:00
|
|
|
}
|
2013-07-19 08:23:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (renamed.Any())
|
|
|
|
{
|
2013-09-14 09:36:07 +03:00
|
|
|
_eventAggregator.PublishEvent(new SeriesRenamedEvent(series));
|
2013-07-19 08:23:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-26 11:06:28 +03:00
|
|
|
public void Execute(RenameFilesCommand message)
|
2013-07-19 08:23:04 +03:00
|
|
|
{
|
|
|
|
var series = _seriesService.GetSeries(message.SeriesId);
|
2013-11-26 11:06:28 +03:00
|
|
|
var episodeFiles = _mediaFileService.Get(message.Files);
|
2013-07-19 08:23:04 +03:00
|
|
|
|
2013-09-11 09:33:47 +03:00
|
|
|
_logger.ProgressInfo("Renaming {0} files for {1}", episodeFiles.Count, series.Title);
|
2013-07-19 08:23:04 +03:00
|
|
|
RenameFiles(episodeFiles, series);
|
2014-02-27 19:51:31 +03:00
|
|
|
_logger.ProgressInfo("Selected episode files renamed for {0}", series.Title);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Execute(RenameSeriesCommand message)
|
|
|
|
{
|
|
|
|
_logger.Trace("Renaming all files for selected series");
|
|
|
|
var seriesToRename = _seriesService.GetSeries(message.SeriesIds);
|
|
|
|
|
|
|
|
foreach (var series in seriesToRename)
|
|
|
|
{
|
|
|
|
var episodeFiles = _mediaFileService.GetFilesBySeries(series.Id);
|
|
|
|
_logger.ProgressInfo("Renaming all files in series: {0}", series.Title);
|
|
|
|
RenameFiles(episodeFiles, series);
|
|
|
|
_logger.ProgressInfo("All episode files renamed for {0}", series.Title);
|
|
|
|
}
|
2013-07-19 08:23:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|