From 5e3e7a25f3151f5deae42d0f11ccd6e11d4fb681 Mon Sep 17 00:00:00 2001 From: Mark Otway Date: Mon, 17 May 2021 22:45:39 +0100 Subject: [PATCH] Clean up code --- README.md | 0 Settings.json | 10 ++- SonarrAutoImport.sln | 0 SonarrAutoImport/LogHandler.cs | 0 SonarrAutoImport/Program.cs | 18 ++--- SonarrAutoImport/Settings.cs | 6 ++ SonarrAutoImport/SonarrAutoImport.csproj | 8 +-- SonarrAutoImport/SonarrImporter.cs | 87 ++++++++++++++++++------ publish.sh | 0 9 files changed, 89 insertions(+), 40 deletions(-) mode change 100644 => 100755 README.md mode change 100644 => 100755 Settings.json mode change 100644 => 100755 SonarrAutoImport.sln mode change 100644 => 100755 SonarrAutoImport/LogHandler.cs mode change 100644 => 100755 publish.sh diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/Settings.json b/Settings.json old mode 100644 new mode 100755 index f93a889..2b2cdc7 --- a/Settings.json +++ b/Settings.json @@ -1,15 +1,19 @@ { "radarr": { "url" : "http://192.168.1.30:7878", - "apiKey" : "87a3763f384241c2a33dfeea625681ca", + "apiKey" : "87a3763f384241c2a33dfeea625681c5", "mappingPath" : "/downloads/", - "downloadsFolder" : "/volume1/video/FilmDownloads" + "downloadsFolder" : "/volume1/video/FilmDownloads", + "importMode" : "Move", + "timeoutSecs" : "5" }, "sonarr": { "url" : "http://192.168.1.30:8989", - "apiKey" : "8727e07296064e369Xcb05d3c11b9531", + "apiKey" : "8727e07296064e369Xcb05d3c11b9532", "mappingPath" : "/downloads/", "downloadsFolder" : "/volume1/video/Downloads", + "importMode" : "Copy", + "timeoutSecs" : "5", "transforms" : [ { "search" : "Gardeners World 2019", diff --git a/SonarrAutoImport.sln b/SonarrAutoImport.sln old mode 100644 new mode 100755 diff --git a/SonarrAutoImport/LogHandler.cs b/SonarrAutoImport/LogHandler.cs old mode 100644 new mode 100755 diff --git a/SonarrAutoImport/Program.cs b/SonarrAutoImport/Program.cs index 4db3895..7441353 100644 --- a/SonarrAutoImport/Program.cs +++ b/SonarrAutoImport/Program.cs @@ -13,16 +13,10 @@ public class Options { [Option('v', "verbose", HelpText = "Run logging in Verbose Mode")] public bool Verbose { get; set; } - - [Option('c', "copy", Required = false, Default = false, HelpText = "Move or copy")] - public bool ImportMode { get; set; } - + [Option('d', "dry-run", Required = false, Default = false, HelpText = "Dry run - change nothing.")] public bool DryRun { get; set; } - [Option('t', "timeout", Required = false, Default = 1000, HelpText = "Timeout between requests")] - public int Timeout { get; set; } - [Value(0, MetaName = "Settings Path", HelpText = "Path to settings JSON file (default = app dir)", Required = false)] public string SettingsPath { get; set; } = "Settings.json"; }; @@ -45,17 +39,17 @@ private static void RunProcess(Options o) if (settings.sonarr != null) { - Logging.LogHandler.Log("Processing videos for Sonarr..."); - importer.ProcessService(settings.sonarr, o.DryRun, o.Verbose, "DownloadedEpisodesScan", o.ImportMode, o.Timeout); + LogHandler.Log("Processing videos for Sonarr..."); + importer.ProcessService(settings.sonarr, o.DryRun, o.Verbose, "DownloadedEpisodesScan"); } if (settings.radarr != null) { - Logging.LogHandler.Log("Processing videos for Radarr..."); - importer.ProcessService(settings.radarr, o.DryRun, o.Verbose, "DownloadedMoviesScan",o.ImportMode, o.Timeout); + LogHandler.Log("Processing videos for Radarr..."); + importer.ProcessService(settings.radarr, o.DryRun, o.Verbose, "DownloadedMoviesScan"); } } else - Logging.LogHandler.LogError($"Settings not found: {o.SettingsPath}"); + LogHandler.LogError($"Settings not found: {o.SettingsPath}"); } } } diff --git a/SonarrAutoImport/Settings.cs b/SonarrAutoImport/Settings.cs index 3ab48ac..8f19cb5 100644 --- a/SonarrAutoImport/Settings.cs +++ b/SonarrAutoImport/Settings.cs @@ -31,6 +31,12 @@ public class ServiceSettings public string apiKey { get; set; } [DataMember] public List transforms { get; set; } + [DataMember] + public string importMode { get; set; } = "Move"; + [DataMember] + public int timeoutSecs { get; set; } + [DataMember] + public bool trimFolders { get; set; } } [DataContract] diff --git a/SonarrAutoImport/SonarrAutoImport.csproj b/SonarrAutoImport/SonarrAutoImport.csproj index 67916a2..dd51674 100644 --- a/SonarrAutoImport/SonarrAutoImport.csproj +++ b/SonarrAutoImport/SonarrAutoImport.csproj @@ -2,14 +2,14 @@ Exe - netcoreapp3.1 + net5.0 - - + + - + diff --git a/SonarrAutoImport/SonarrImporter.cs b/SonarrAutoImport/SonarrImporter.cs index 6488574..ca39f60 100644 --- a/SonarrAutoImport/SonarrImporter.cs +++ b/SonarrAutoImport/SonarrImporter.cs @@ -5,7 +5,6 @@ using System.Runtime.Serialization; using System.Text.RegularExpressions; using RestSharp; -using System; using System.Threading; namespace SonarrAuto @@ -90,16 +89,24 @@ private string MoveFile(string fullPathName, string newFileName) return fullPathName; } - public void ProcessService( ServiceSettings settings, bool dryRun, bool verbose, string apiCommand, bool import_mymode, int timeout) + public void ProcessService( ServiceSettings settings, bool dryRun, bool verbose, string apiCommand) { DirectoryInfo baseDir = new DirectoryInfo(settings.downloadsFolder); + if (settings.importMode != "Copy" && settings.importMode != "Move") + { + Log($"Invalid importMode '{settings.importMode}' in settings. Defaulting to 'Move'"); + settings.importMode = "Move"; + } + Log("Starting video processing for: {0}", baseDir); if (verbose) { Log(" Base Url: {0}", settings.url); Log(" API Key: {0}", settings.apiKey); Log(" Mapping: {0}", settings.mappingPath); + Log(" Timeout: {0}", settings.timeoutSecs); + Log(" CopyMode: {0}", settings.importMode); Log(" Dry Run: {0}", dryRun); } @@ -119,12 +126,7 @@ public void ProcessService( ServiceSettings settings, bool dryRun, bool verbose, string videoFullPath = file.FullName; string newFileName = TransformFileName(settings.transforms, videoFullPath, verbose); - - if (!dryRun) - { - videoFullPath = MoveFile(file.FullName, newFileName); - } - + if (!dryRun) { videoFullPath = MoveFile(file.FullName, newFileName); @@ -134,21 +136,74 @@ public void ProcessService( ServiceSettings settings, bool dryRun, bool verbose, if (!dryRun) { - QuickImport(path, settings, verbose, apiCommand,import_mymode,timeout); + QuickImport(path, settings, verbose, apiCommand); } else Log(" => {0}", path); + + if (settings.timeoutSecs != 0) + { + Log( $"Sleeping for {settings.timeoutSecs} seconds..."); + Thread.Sleep(settings.timeoutSecs * 1000); + } } Log("All processing complete."); } else Log("No videos found. Nothing to do!"); + + if (settings.trimFolders) + { + Log($"Trimming empty folders in {baseDir.FullName}"); + TrimEmptyFolders(baseDir); + } } else Log($"Folder {baseDir} was not found. Check configuration."); } + private void TrimEmptyFolders(DirectoryInfo baseDir) + { + if ((baseDir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) + return; + + if (baseDir.Name.StartsWith(".") || baseDir.Name.StartsWith("@")) + return; + + var allFolders = baseDir.GetDirectories("*.*", SearchOption.AllDirectories); + + foreach (var folder in allFolders) + { + try + { + TrimEmptyFolders(folder); + + var nonMovieFiles = folder.GetFiles() + .Where(x => !movieExtensions.Contains(x.Extension, StringComparer.OrdinalIgnoreCase) + && !x.Name.StartsWith( ".") + && (x.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden) + .ToList(); + + nonMovieFiles.ForEach(x => + { + Log($" Deleting non-video file: {x.FullName}"); + x.Delete(); + }); + + if (!folder.GetFiles().Any() && !folder.GetDirectories().Any() ) + { + Log($"Removing empty folder: {folder.FullName}"); + folder.Delete(); + } + } + catch (Exception ex) + { + Log($"Unexpected exception during folder trim: {ex.Message}"); + } + } + } + private string TranslatePath(string baseFolder, string fullName, string mapFolder) { string path = Path.GetFullPath(fullName); @@ -158,22 +213,12 @@ private string TranslatePath(string baseFolder, string fullName, string mapFolde return Path.Combine(mapFolder, localPath); } - private void QuickImport(string remotePath, ServiceSettings service, bool verbose, string apiCommand , bool mymode , int timeout) + private void QuickImport(string remotePath, ServiceSettings service, bool verbose, string apiCommand) { - Log($"Sleeping some seconds..."); - Thread.Sleep(timeout); try { RestClient client = new RestClient(service.url); -// - var payload = new PayLoad { path = remotePath, name = apiCommand}; - if (mymode) { - payload = new PayLoad { path = remotePath, name = apiCommand , importMode = "Copy"}; - } -// }else { -// var payload = new PayLoad { path = remotePath, name = apiCommand , importMode = "Copy"}; - -// } + var payload = new PayLoad { path = remotePath, name = apiCommand, importMode = service.importMode }; var request = new RestRequest(Method.POST); diff --git a/publish.sh b/publish.sh old mode 100644 new mode 100755