mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-11 12:02:35 +02:00
Episode RenamingProvider created, allows renaming by Every Episode for Every Series, by Series, by Season, or individual Episodes.
Currently uses Hard-Coded Naming Convention, Undecided on SAB or SB configuration style, SAB's is more robust (and flawless? -SP).
This commit is contained in:
parent
2a8b598f4f
commit
738700537e
@ -66,7 +66,8 @@ public static void BindKernel()
|
|||||||
_kernel.Bind<ISyncProvider>().To<SyncProvider>().InSingletonScope();
|
_kernel.Bind<ISyncProvider>().To<SyncProvider>().InSingletonScope();
|
||||||
_kernel.Bind<IRssProvider>().To<RssProvider>().InSingletonScope();
|
_kernel.Bind<IRssProvider>().To<RssProvider>().InSingletonScope();
|
||||||
_kernel.Bind<IRssSyncProvider>().To<RssSyncProvider>().InSingletonScope();
|
_kernel.Bind<IRssSyncProvider>().To<RssSyncProvider>().InSingletonScope();
|
||||||
_kernel.Bind<IIndexerProvider>().To<IndexerProvider>().InSingletonScope(); ;
|
_kernel.Bind<IIndexerProvider>().To<IndexerProvider>().InSingletonScope();
|
||||||
|
_kernel.Bind<IRenameProvider>().To<RenameProvider>().InSingletonScope();
|
||||||
_kernel.Bind<INotificationProvider>().To<NotificationProvider>().InSingletonScope();
|
_kernel.Bind<INotificationProvider>().To<NotificationProvider>().InSingletonScope();
|
||||||
_kernel.Bind<ILogProvider>().To<LogProvider>().InSingletonScope();
|
_kernel.Bind<ILogProvider>().To<LogProvider>().InSingletonScope();
|
||||||
_kernel.Bind<IMediaFileProvider>().To<MediaFileProvider>().InSingletonScope();
|
_kernel.Bind<IMediaFileProvider>().To<MediaFileProvider>().InSingletonScope();
|
||||||
|
18
NzbDrone.Core/Model/EpisodeRenameModel.cs
Normal file
18
NzbDrone.Core/Model/EpisodeRenameModel.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Model
|
||||||
|
{
|
||||||
|
public class EpisodeRenameModel
|
||||||
|
{
|
||||||
|
public string SeriesName { get; set; }
|
||||||
|
public int SeasonNumber { get; set; }
|
||||||
|
public int EpisodeNumber { get; set; }
|
||||||
|
public string EpisodeName { get; set; }
|
||||||
|
public string Folder { get; set; }
|
||||||
|
public EpisodeFile EpisodeFile { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,11 @@ public void DeleteFile(string path)
|
|||||||
File.Delete(path);
|
File.Delete(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RenameFile(string sourcePath, string destinationPath)
|
||||||
|
{
|
||||||
|
File.Move(sourcePath, destinationPath);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,5 +12,6 @@ public interface IDiskProvider
|
|||||||
bool FileExists(string path);
|
bool FileExists(string path);
|
||||||
long GetSize(string path);
|
long GetSize(string path);
|
||||||
void DeleteFile(string path);
|
void DeleteFile(string path);
|
||||||
|
void RenameFile(string sourcePath, string destinationPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,5 +15,7 @@ public interface IMediaFileProvider
|
|||||||
string GenerateEpisodePath(EpisodeModel episode);
|
string GenerateEpisodePath(EpisodeModel episode);
|
||||||
void DeleteFromDb(int fileId);
|
void DeleteFromDb(int fileId);
|
||||||
void DeleteFromDisk(int fileId, string path);
|
void DeleteFromDisk(int fileId, string path);
|
||||||
|
void Update(EpisodeFile episodeFile);
|
||||||
|
EpisodeFile GetEpisodeFile(int episodeFileId);
|
||||||
}
|
}
|
||||||
}
|
}
|
15
NzbDrone.Core/Providers/IRenameProvider.cs
Normal file
15
NzbDrone.Core/Providers/IRenameProvider.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Providers
|
||||||
|
{
|
||||||
|
public interface IRenameProvider
|
||||||
|
{
|
||||||
|
void RenameAll();
|
||||||
|
void RenameSeries(int seriesId);
|
||||||
|
void RenameSeason(int seasonId);
|
||||||
|
void RenameEpisode(int episodeId);
|
||||||
|
}
|
||||||
|
}
|
@ -98,7 +98,6 @@ public void CleanUp(List<EpisodeFile> files)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public string GenerateEpisodePath(EpisodeModel episode)
|
public string GenerateEpisodePath(EpisodeModel episode)
|
||||||
{
|
{
|
||||||
var episodeNamePattern = _configProvider.EpisodeNameFormat;
|
var episodeNamePattern = _configProvider.EpisodeNameFormat;
|
||||||
@ -123,6 +122,16 @@ public void DeleteFromDisk(int fileId, string path)
|
|||||||
_repository.Delete<EpisodeFile>(fileId);
|
_repository.Delete<EpisodeFile>(fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Update(EpisodeFile episodeFile)
|
||||||
|
{
|
||||||
|
_repository.Update(episodeFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EpisodeFile GetEpisodeFile(int episodeFileId)
|
||||||
|
{
|
||||||
|
return _repository.Single<EpisodeFile>(episodeFileId);
|
||||||
|
}
|
||||||
|
|
||||||
private List<string> GetMediaFileList(string path)
|
private List<string> GetMediaFileList(string path)
|
||||||
{
|
{
|
||||||
Logger.Debug("Scanning '{0}' for episodes", path);
|
Logger.Debug("Scanning '{0}' for episodes", path);
|
||||||
|
190
NzbDrone.Core/Providers/RenameProvider.cs
Normal file
190
NzbDrone.Core/Providers/RenameProvider.cs
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Providers
|
||||||
|
{
|
||||||
|
public class RenameProvider : IRenameProvider
|
||||||
|
{
|
||||||
|
private readonly ISeriesProvider _seriesProvider;
|
||||||
|
private readonly ISeasonProvider _seasonProvider;
|
||||||
|
private readonly IEpisodeProvider _episodeProvider;
|
||||||
|
private readonly IMediaFileProvider _mediaFileProvider;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IConfigProvider _configProvider;
|
||||||
|
private Thread _renameThread;
|
||||||
|
private List<EpisodeRenameModel> _epsToRename = new List<EpisodeRenameModel>();
|
||||||
|
|
||||||
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public RenameProvider(ISeriesProvider seriesProvider, ISeasonProvider seasonProvider,
|
||||||
|
IEpisodeProvider episodeProvider, IMediaFileProvider mediaFileProvider,
|
||||||
|
IDiskProvider diskProvider, IConfigProvider configProvider)
|
||||||
|
{
|
||||||
|
_seriesProvider = seriesProvider;
|
||||||
|
_seasonProvider = seasonProvider;
|
||||||
|
_episodeProvider = episodeProvider;
|
||||||
|
_mediaFileProvider = mediaFileProvider;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_configProvider = configProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IRenameProvider Members
|
||||||
|
public void RenameAll()
|
||||||
|
{
|
||||||
|
//Get a list of all episode files/episodes and rename them
|
||||||
|
|
||||||
|
var seasonFolder = _configProvider.GetValue("SeasonFolder", "Season %s", true);
|
||||||
|
|
||||||
|
foreach (var series in _seriesProvider.GetAllSeries())
|
||||||
|
{
|
||||||
|
foreach (var episode in series.Episodes)
|
||||||
|
{
|
||||||
|
var episodeRenameModel = new EpisodeRenameModel();
|
||||||
|
episodeRenameModel.SeriesName = series.Title;
|
||||||
|
episodeRenameModel.SeasonNumber = episode.SeasonNumber;
|
||||||
|
episodeRenameModel.EpisodeNumber = episode.EpisodeNumber;
|
||||||
|
episodeRenameModel.EpisodeName = episode.Title;
|
||||||
|
episodeRenameModel.Folder = series.Path + Path.DirectorySeparatorChar + seasonFolder;
|
||||||
|
episodeRenameModel.EpisodeFile = episode.EpisodeFile;
|
||||||
|
|
||||||
|
_epsToRename.Add(episodeRenameModel);
|
||||||
|
StartRename();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenameSeries(int seriesId)
|
||||||
|
{
|
||||||
|
//Get a list of all applicable episode files/episodes and rename them
|
||||||
|
|
||||||
|
var series = _seriesProvider.GetSeries(seriesId);
|
||||||
|
var seasonFolder = _configProvider.GetValue("SeasonFolder", "Season %s", true);
|
||||||
|
|
||||||
|
foreach (var episode in series.Episodes)
|
||||||
|
{
|
||||||
|
var episodeRenameModel = new EpisodeRenameModel();
|
||||||
|
episodeRenameModel.SeriesName = series.Title;
|
||||||
|
episodeRenameModel.SeasonNumber = episode.SeasonNumber;
|
||||||
|
episodeRenameModel.EpisodeNumber = episode.EpisodeNumber;
|
||||||
|
episodeRenameModel.EpisodeName = episode.Title;
|
||||||
|
episodeRenameModel.Folder = series.Path + Path.DirectorySeparatorChar + seasonFolder;
|
||||||
|
episodeRenameModel.EpisodeFile = episode.EpisodeFile;
|
||||||
|
|
||||||
|
_epsToRename.Add(episodeRenameModel);
|
||||||
|
StartRename();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenameSeason(int seasonId)
|
||||||
|
{
|
||||||
|
//Get a list of all applicable episode files/episodes and rename them
|
||||||
|
var season = _seasonProvider.GetSeason(seasonId);
|
||||||
|
var series = _seriesProvider.GetSeries(season.SeriesId);
|
||||||
|
var seasonFolder = _configProvider.GetValue("SeasonFolder", "Season %s", true);
|
||||||
|
|
||||||
|
foreach (var episode in season.Episodes)
|
||||||
|
{
|
||||||
|
var episodeRenameModel = new EpisodeRenameModel();
|
||||||
|
episodeRenameModel.SeriesName = series.Title;
|
||||||
|
episodeRenameModel.SeasonNumber = episode.SeasonNumber;
|
||||||
|
episodeRenameModel.EpisodeNumber = episode.EpisodeNumber;
|
||||||
|
episodeRenameModel.EpisodeName = episode.Title;
|
||||||
|
episodeRenameModel.Folder = series.Path + Path.DirectorySeparatorChar + seasonFolder;
|
||||||
|
episodeRenameModel.EpisodeFile = episode.EpisodeFile;
|
||||||
|
|
||||||
|
_epsToRename.Add(episodeRenameModel);
|
||||||
|
StartRename();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenameEpisode(int episodeId)
|
||||||
|
{
|
||||||
|
var episode = _episodeProvider.GetEpisode(episodeId);
|
||||||
|
var series = _seriesProvider.GetSeries(episode.SeriesId);
|
||||||
|
var seasonFolder = _configProvider.GetValue("SeasonFolder", "Season %s", true);
|
||||||
|
|
||||||
|
var episodeRenameModel = new EpisodeRenameModel();
|
||||||
|
episodeRenameModel.SeriesName = series.Title;
|
||||||
|
episodeRenameModel.SeasonNumber = episode.SeasonNumber;
|
||||||
|
episodeRenameModel.EpisodeNumber = episode.EpisodeNumber;
|
||||||
|
episodeRenameModel.EpisodeName = episode.Title;
|
||||||
|
episodeRenameModel.Folder = series.Path + Path.DirectorySeparatorChar + seasonFolder;
|
||||||
|
episodeRenameModel.EpisodeFile = episode.EpisodeFile;
|
||||||
|
|
||||||
|
_epsToRename.Add(episodeRenameModel);
|
||||||
|
StartRename();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void StartRename()
|
||||||
|
{
|
||||||
|
Logger.Debug("Episode Rename Starting");
|
||||||
|
if (_renameThread == null || !_renameThread.IsAlive)
|
||||||
|
{
|
||||||
|
Logger.Debug("Initializing background rename of episodes");
|
||||||
|
_renameThread = new Thread(RenameProcessor)
|
||||||
|
{
|
||||||
|
Name = "RenameEpisodes",
|
||||||
|
Priority = ThreadPriority.Lowest
|
||||||
|
};
|
||||||
|
|
||||||
|
_renameThread.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Warn("Episode renaming already in progress. Ignoring request.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenameProcessor()
|
||||||
|
{
|
||||||
|
while (_epsToRename.Count > 0)
|
||||||
|
{
|
||||||
|
var ep = _epsToRename.First();
|
||||||
|
_epsToRename.RemoveAt(0);
|
||||||
|
RenameFile(ep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenameFile(EpisodeRenameModel episodeRenameModel)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Update EpisodeFile if successful
|
||||||
|
Logger.Debug("Renaming Episode: {0}", Path.GetFileName(episodeRenameModel.EpisodeFile.Path));
|
||||||
|
var newName = GetNewName(episodeRenameModel);
|
||||||
|
var newFilename = episodeRenameModel.Folder + Path.DirectorySeparatorChar + newName;
|
||||||
|
|
||||||
|
if (!_diskProvider.FolderExists(episodeRenameModel.Folder))
|
||||||
|
_diskProvider.CreateDirectory(episodeRenameModel.Folder);
|
||||||
|
|
||||||
|
_diskProvider.RenameFile(episodeRenameModel.EpisodeFile.Path, newFilename);
|
||||||
|
episodeRenameModel.EpisodeFile.Path = newFilename;
|
||||||
|
_mediaFileProvider.Update(episodeRenameModel.EpisodeFile);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.DebugException(ex.Message, ex);
|
||||||
|
Logger.Warn("Unable to Rename Episode: {0}", Path.GetFileName(episodeRenameModel.EpisodeFile.Path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetNewName(EpisodeRenameModel episodeRenameModel)
|
||||||
|
{
|
||||||
|
//Todo: Get the users preferred naming convention instead of hard-coding it
|
||||||
|
return String.Format("{0} - S{1:00}E{2:00} - {3}", episodeRenameModel.SeriesName,
|
||||||
|
episodeRenameModel.SeasonNumber, episodeRenameModel.EpisodeNumber,
|
||||||
|
episodeRenameModel.EpisodeName);
|
||||||
|
//var fileString = _configProvider.GetValue("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -55,7 +55,7 @@ public void Begin()
|
|||||||
Logger.Debug("Initializing background sync of RSS Feeds.");
|
Logger.Debug("Initializing background sync of RSS Feeds.");
|
||||||
_rssSyncThread = new Thread(SyncWithRss)
|
_rssSyncThread = new Thread(SyncWithRss)
|
||||||
{
|
{
|
||||||
Name = "SyncUnmappedFolders",
|
Name = "RssSync",
|
||||||
Priority = ThreadPriority.Lowest
|
Priority = ThreadPriority.Lowest
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user