From 2043498cf67f98923ec772dec18c5e390530109e Mon Sep 17 00:00:00 2001 From: James Brindle Date: Sat, 8 May 2021 15:19:26 +0100 Subject: [PATCH] ### Bug Fixes * Fixed issue where main processes continually runs when not all playlists have been processes * Added additional logging for playlists processing - Attempting to troubleshoot 'object instance not set to an instance of an object' a few people are getting trying to upload their playlists --- Installer-x64/Installer-x64.vdproj | 8 +- Installer-x86/Installer.vdproj | 8 +- README.md | 2 +- YTMusicUploader/Business/FileScanner.cs | 15 +- YTMusicUploader/Business/FileUploader.cs | 22 +-- YTMusicUploader/Business/PlaylistProcessor.cs | 185 ++++++++++++------ YTMusicUploader/Logger.cs | 25 +++ YTMusicUploader/MainForm.Designer.cs | 4 +- YTMusicUploader/MainForm.cs | 27 ++- YTMusicUploader/Properties/AssemblyInfo.cs | 4 +- 10 files changed, 195 insertions(+), 105 deletions(-) diff --git a/Installer-x64/Installer-x64.vdproj b/Installer-x64/Installer-x64.vdproj index 56a01b7e..3ca0984e 100644 --- a/Installer-x64/Installer-x64.vdproj +++ b/Installer-x64/Installer-x64.vdproj @@ -7921,15 +7921,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:YT Music Uploader" - "ProductCode" = "8:{865865AA-2AAE-44BC-A574-3BDBF6994287}" - "PackageCode" = "8:{B09324DB-FC08-4A83-B237-7AAA83AE80AF}" + "ProductCode" = "8:{C8936624-2CB9-4293-9158-836C0B580465}" + "PackageCode" = "8:{51917E0C-BA3C-4DDC-ABCC-6730B38C1D88}" "UpgradeCode" = "8:{AB84D0C0-CDF7-4BDF-90B0-C4808DB11DAB}" "AspNetVersion" = "8:4.0.30319.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.7.5" + "ProductVersion" = "8:1.7.6" "Manufacturer" = "8:JB-Net Software Solutions" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:https://github.com/jamesbrindle/YTMusicUploader/issues" @@ -8435,7 +8435,7 @@ { "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_3AB76FEAD3A849FBB271E712B0EA59C3" { - "SourcePath" = "8:..\\YTMusicUploader\\obj\\x64\\Release\\YTMusicUploader.exe" + "SourcePath" = "8:" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_B3B65ED76DD54A94A22A406398263B40" diff --git a/Installer-x86/Installer.vdproj b/Installer-x86/Installer.vdproj index caf5a8aa..b0bc4e30 100644 --- a/Installer-x86/Installer.vdproj +++ b/Installer-x86/Installer.vdproj @@ -7921,15 +7921,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:YT Music Uploader" - "ProductCode" = "8:{6D61441E-0BC8-40EF-8914-DCEF6EB7A452}" - "PackageCode" = "8:{3408BA7F-A292-442F-8468-C81463367967}" + "ProductCode" = "8:{371194FD-F572-4C8A-8DCF-F4D3854BAC0E}" + "PackageCode" = "8:{4F39C7CF-9A3F-4080-A6FD-C0DCF8890968}" "UpgradeCode" = "8:{1E18ED3F-C210-4589-BEB4-58E2680D3C71}" "AspNetVersion" = "8:4.0.30319.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.7.5" + "ProductVersion" = "8:1.7.6" "Manufacturer" = "8:JB-Net Software Solutions" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:https://github.com/jamesbrindle/YTMusicUploader/issues" @@ -8435,7 +8435,7 @@ { "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_858C89B90B894F97A8CDE5C10D88F13E" { - "SourcePath" = "8:..\\YTMusicUploader\\obj\\x86\\Release\\YTMusicUploader.exe" + "SourcePath" = "8:" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_1059907B4555471C9BCCD73D3FBBCC93" diff --git a/README.md b/README.md index 8ea41648..5b50543e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Automatically upload your local personal music library to YouTube Music and bulk     -**[Download Version 1.7.5 Installer](https://github.com/jamesbrindle/YTMusicUploader/releases/tag/v1.7.5)** +**[Download Version 1.7.6 Installer](https://github.com/jamesbrindle/YTMusicUploader/releases/tag/v1.7.6)**     diff --git a/YTMusicUploader/Business/FileScanner.cs b/YTMusicUploader/Business/FileScanner.cs index a766a841..7f0088d4 100644 --- a/YTMusicUploader/Business/FileScanner.cs +++ b/YTMusicUploader/Business/FileScanner.cs @@ -96,15 +96,12 @@ public void Process() } catch (Exception e) { - if (!e.Message.Contains("Thread was being aborted")) - { - Logger.Log( - e, - "FileScanner.Process - Error reading file (possibly removed): " + - file.Path, - Log.LogTypeEnum.Error, - false); - } + Logger.Log( + e, + "FileScanner.Process - Error reading file (possibly removed): " + + file.Path, + Log.LogTypeEnum.Error, + false); } } } diff --git a/YTMusicUploader/Business/FileUploader.cs b/YTMusicUploader/Business/FileUploader.cs index c63040f8..33a2d6e5 100644 --- a/YTMusicUploader/Business/FileUploader.cs +++ b/YTMusicUploader/Business/FileUploader.cs @@ -174,16 +174,7 @@ public async Task Process() } catch (Exception e) { - if (e.Message.ToLower().Contains("thread was being aborted") || - (e.InnerException != null && e.InnerException.Message.ToLower().Contains("thread was being aborted"))) - { - // Non-detrimental - Ignore to not clog up the application log - // Logger.Log(e, "Process.Process", Log.LogTypeEnum.Warning); - } - else - { - Logger.Log(e, "Process.Process", Log.LogTypeEnum.Critical); - } + Logger.Log(e, "Process.Process", Log.LogTypeEnum.Critical); } } else @@ -196,16 +187,7 @@ public async Task Process() } catch (Exception e) { - if (e.Message.ToLower().Contains("thread was being aborted") || - (e.InnerException != null && e.InnerException.Message.ToLower().Contains("thread was being aborted"))) - { - // Non-detrimental - Ignore to not clog up the application log - // Logger.Log(e, "Process.Process", Log.LogTypeEnum.Warning); - } - else - { - Logger.Log(e, "Process.Process", Log.LogTypeEnum.Critical); - } + Logger.Log(e, "Process.Process", Log.LogTypeEnum.Critical); } if (MainForm.ManagingYTMusicStatus != ManagingYTMusicStatusEnum.Showing) diff --git a/YTMusicUploader/Business/PlaylistProcessor.cs b/YTMusicUploader/Business/PlaylistProcessor.cs index c28f7be5..8514d561 100644 --- a/YTMusicUploader/Business/PlaylistProcessor.cs +++ b/YTMusicUploader/Business/PlaylistProcessor.cs @@ -22,6 +22,7 @@ public class PlaylistProcessor public List PlaylistFiles { get; set; } public OnlinePlaylistCollection OnlinePlaylists { get; set; } public bool Stopped { get; set; } = true; + public bool ProcessingPlaylistsFinished { get; set; } = false; public PlaylistProcessor(MainForm mainForm) { @@ -54,6 +55,7 @@ public void Process(bool forceRefreshPlaylists = false) foreach (var playlistFile in PlaylistFiles) { + ProcessingPlaylistsFinished = false; ConnectionCheckWait(); while (MainForm.Paused) @@ -115,73 +117,139 @@ public void Process(bool forceRefreshPlaylists = false) if (MainFormAborting() || !MainForm.Settings.UploadPlaylists) return; - updatedPlaylistFile.PlaylistItems.AsParallel().ForAllInApproximateOrder(playlistItem => + if (updatedPlaylistFile != null && + updatedPlaylistFile.PlaylistItems != null && + updatedPlaylistFile.PlaylistItems.Count > 0) { - while (MainForm.Paused) - ThreadHelper.SafeSleep(500); + updatedPlaylistFile.PlaylistItems.AsParallel().ForAllInApproximateOrder(playlistItem => + { + while (MainForm.Paused) + ThreadHelper.SafeSleep(500); - if (MainFormAborting() || !MainForm.Settings.UploadPlaylists) - return; + if (MainFormAborting() || !MainForm.Settings.UploadPlaylists) + return; - // We can only create or update a playlist if we have the YT Music video (entity) ID - var musicFile = MainForm.MusicFileRepo.LoadFromPath(playlistItem.Path).Result; + // We can only create or update a playlist if we have the YT Music video (entity) ID + MusicFile musicFile = null; - if (string.IsNullOrEmpty(musicFile.VideoId)) - { - string entityId = string.Empty; - ConnectionCheckWait(); - - if (Requests.IsSongUploaded(musicFile.Path, - MainForm.Settings.AuthenticationCookie, - ref entityId, - out string videoId, - MainForm.MusicDataFetcher, - false) != Requests.UploadCheckResult.NotPresent) + try { - musicFile.VideoId = videoId; - musicFile.Save().Wait(); + musicFile = MainForm.MusicFileRepo.LoadFromPath(playlistItem.Path).Result; + } + catch (Exception e) + { + Logger.LogError("TS1: Playlist Processor - Load MusicFile from Path " + playlistItem.Path, e.Message, false, e.StackTrace); + throw; } - } - - if (musicFile != null && !string.IsNullOrEmpty(musicFile.VideoId)) - { - var playlistToAdd = playlistItem; - playlistItem.VideoId = musicFile.VideoId; - playlistFile.PlaylistItems.Add(playlistToAdd); - } - else - { - // Check the file hash instead, in case the playlist file path is somehow different - // to the watch folder file path (i.e. network folder locations or symbolics links) - - string hash = DirectoryHelper.GetFileHash(playlistItem.Path).Result; - musicFile = MainForm.MusicFileRepo.LoadFromHash(hash).Result; if (string.IsNullOrEmpty(musicFile.VideoId)) { string entityId = string.Empty; ConnectionCheckWait(); - if (Requests.IsSongUploaded(musicFile.Path, - MainForm.Settings.AuthenticationCookie, - ref entityId, - out string videoId, - MainForm.MusicDataFetcher, - false) != Requests.UploadCheckResult.NotPresent) + try + { + if (Requests.IsSongUploaded(musicFile.Path, + MainForm.Settings.AuthenticationCookie, + ref entityId, + out string videoId, + MainForm.MusicDataFetcher, + false) != Requests.UploadCheckResult.NotPresent) + { + musicFile.VideoId = videoId; + musicFile.Save().Wait(); + } + } + catch (Exception e) { - musicFile.VideoId = videoId; - musicFile.Save().Wait(); + Logger.LogError("TS2: Playlist Processor - Requests.IsSongUploaded", e.Message, false, e.StackTrace); + throw; } } if (musicFile != null && !string.IsNullOrEmpty(musicFile.VideoId)) { - var playlistToAdd = playlistItem; - playlistItem.VideoId = musicFile.VideoId; - playlistFile.PlaylistItems.Add(playlistToAdd); + try + { + var playlistToAdd = playlistItem; + playlistItem.VideoId = musicFile.VideoId; + playlistFile.PlaylistItems.Add(playlistToAdd); + } + catch (Exception e) + { + Logger.LogError("TS3: Playlist Processor - playlistFile.PlaylistItems.Add", e.Message, false, e.StackTrace); + throw; + } } - } - }, Global.MaxDegreesOfParallelism); + else + { + // Check the file hash instead, in case the playlist file path is somehow different + // to the watch folder file path (i.e. network folder locations or symbolics links) + + string hash = string.Empty; + + try + { + hash = DirectoryHelper.GetFileHash(playlistItem.Path).Result; + } + catch (Exception e) + { + Logger.LogError("TS4: Playlist Processor - DirectoryHelper.GetFileHash " + playlistItem.Path, e.Message, false, e.StackTrace); + } + + try + { + musicFile = MainForm.MusicFileRepo.LoadFromHash(hash).Result; + } + catch (Exception e) + { + Logger.LogError("TS5: Playlist Processor - MusicFileRepo.LoadFromHash", e.Message, false, e.StackTrace); + throw; + } + + try + { + if (string.IsNullOrEmpty(musicFile.VideoId)) + { + string entityId = string.Empty; + ConnectionCheckWait(); + + if (Requests.IsSongUploaded(musicFile.Path, + MainForm.Settings.AuthenticationCookie, + ref entityId, + out string videoId, + MainForm.MusicDataFetcher, + false) != Requests.UploadCheckResult.NotPresent) + { + musicFile.VideoId = videoId; + musicFile.Save().Wait(); + } + } + } + catch (Exception e) + { + Logger.LogError("TS6: Playlist Processor - Requests.IsSongUploaded", e.Message, false, e.StackTrace); + throw; + } + + try + { + if (musicFile != null && !string.IsNullOrEmpty(musicFile.VideoId)) + { + var playlistToAdd = playlistItem; + playlistItem.VideoId = musicFile.VideoId; + playlistFile.PlaylistItems.Add(playlistToAdd); + } + } + catch (Exception e) + { + Logger.LogError("TS7: Playlist Processor - PlaylistItems.Add", e.Message, false, e.StackTrace); + throw; + } + } + + }, Global.MaxDegreesOfParallelism); + } if (MainFormAborting() || !MainForm.Settings.UploadPlaylists) return; @@ -216,16 +284,15 @@ public void Process(bool forceRefreshPlaylists = false) // Ignore - don't create playlist Logger.LogWarning( - "Playlist Processor", - "Empty playlist detected. It will be ignored: " + playlistFile.Path, + "Playlist Processor", + "Empty playlist detected. It will be ignored: " + playlistFile.Path, true); playlistFile.LastModifiedDate = new FileInfo(playlistFile.Path).LastWriteTime; playlistFile.LastUpload = playlistFile.LastModifiedDate; playlistFile.Save().Wait(); } - else if (e.Message.Contains("Could not find the file") || - e.Message.Contains("Object reference not set")) + else if (e.Message.Contains("Could not find the file")) { // Ignore -It's probably been moved / deleted @@ -255,20 +322,16 @@ public void Process(bool forceRefreshPlaylists = false) break; } + if (index == PlaylistFiles.Count) + ProcessingPlaylistsFinished = true; + index++; - } + } } } catch (Exception e) { - if (e.Message.ToLower().Contains("thread was being aborted") || - (e.InnerException != null && e.InnerException.Message.ToLower().Contains("thread was being aborted"))) - { - // Non-detrimental - Ignore to not clog up the application log - // Logger.Log(e, "PlaylistProcessor", Log.LogTypeEnum.Warning); - } - else - Logger.Log(e, "Fatal error in PlaylistProcessor", Log.LogTypeEnum.Critical); + Logger.Log(e, "Fatal error in PlaylistProcessor", Log.LogTypeEnum.Critical); } Stopped = true; diff --git a/YTMusicUploader/Logger.cs b/YTMusicUploader/Logger.cs index 1ef4bbac..8f22181e 100644 --- a/YTMusicUploader/Logger.cs +++ b/YTMusicUploader/Logger.cs @@ -101,6 +101,9 @@ private static bool SendLogToSource /// Exception to log public static void Log(Exception e, bool ignoreRemote = false) { + if (IsInIgnoreList(GetExceptionMessage(e))) + return; + try { ThreadPool.QueueUserWorkItem(delegate @@ -133,6 +136,9 @@ public static void Log(Exception e, bool ignoreRemote = false) /// Exception to log public static void Log(Exception e, LogTypeEnum logType, bool ignoreRemote = false) { + if (IsInIgnoreList(GetExceptionMessage(e))) + return; + try { ThreadPool.QueueUserWorkItem(delegate @@ -165,6 +171,9 @@ public static void Log(Exception e, LogTypeEnum logType, bool ignoreRemote = fal /// Exception to log public static void Log(Exception e, string additionalMessage, bool ignoreRemote = false) { + if (IsInIgnoreList(GetExceptionMessage(e))) + return; + try { ThreadPool.QueueUserWorkItem(delegate @@ -198,6 +207,9 @@ public static void Log(Exception e, string additionalMessage, bool ignoreRemote /// Exception to log public static void Log(Exception e, string additionalMessage, LogTypeEnum logType, bool ignoreRemote = false) { + if (IsInIgnoreList(GetExceptionMessage(e))) + return; + try { ThreadPool.QueueUserWorkItem(delegate @@ -234,6 +246,9 @@ public static void Log(Exception e, string additionalMessage, LogTypeEnum logTyp /// The messsage to log public static void Log(LogTypeEnum logType, string source, string message, bool ignoreRemote = false) { + if (IsInIgnoreList(message)) + return; + try { ThreadPool.QueueUserWorkItem(delegate @@ -295,6 +310,9 @@ public static void LogInfo(string source, string message) /// The messsage to log public static void LogError(string source, string message, bool ignoreRemote = false, string stackTrace = null) { + if (IsInIgnoreList(message)) + return; + try { ThreadPool.QueueUserWorkItem(delegate @@ -413,6 +431,13 @@ private static string GetExceptionStackTrace(Exception e) return e.StackTrace; } + private static bool IsInIgnoreList(string exceptionMessage) + { + if (exceptionMessage.Contains("Thread was being aborted")) + return true; + return false; + } + /// /// Clears historic logs early than the amount of days as defined in the App.config (default 30 days). /// diff --git a/YTMusicUploader/MainForm.Designer.cs b/YTMusicUploader/MainForm.Designer.cs index 0ee9dd57..dbb63ba3 100644 --- a/YTMusicUploader/MainForm.Designer.cs +++ b/YTMusicUploader/MainForm.Designer.cs @@ -322,7 +322,7 @@ private void InitializeComponent() this.pnlHeader.Controls.Add(this.pictureBox1); this.pnlHeader.Location = new System.Drawing.Point(13, 16); this.pnlHeader.Name = "pnlHeader"; - this.pnlHeader.Size = new System.Drawing.Size(357, 46); + this.pnlHeader.Size = new System.Drawing.Size(214, 46); this.pnlHeader.TabIndex = 23; // // pictureBox1 @@ -332,7 +332,7 @@ private void InitializeComponent() this.pictureBox1.Image = global::YTMusicUploader.Properties.Resources.Header; this.pictureBox1.Location = new System.Drawing.Point(0, 0); this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(357, 46); + this.pictureBox1.Size = new System.Drawing.Size(214, 46); this.pictureBox1.TabIndex = 0; this.pictureBox1.TabStop = false; // diff --git a/YTMusicUploader/MainForm.cs b/YTMusicUploader/MainForm.cs index 0971b3b6..44b063a9 100644 --- a/YTMusicUploader/MainForm.cs +++ b/YTMusicUploader/MainForm.cs @@ -81,9 +81,11 @@ public enum ManagingYTMusicStatusEnum public bool Aborting { get; set; } = false; public ManagingYTMusicStatusEnum ManagingYTMusicStatus { get; set; } = ManagingYTMusicStatusEnum.NeverShown; public bool DatabaseIntegrityCheckDone { get; set; } = false; + private DateTime SessionStart { get; set; } = DateTime.Now; private bool StartHidden = false; + // // MusicBrainz Access // @@ -167,11 +169,22 @@ public MainForm(bool hidden) : base(formResizable: false) if (!Settings.LastPlaylistUpload.HasValue) Settings.LastPlaylistUpload = DateTime.Now.AddHours(Global.SessionRestartHours * -1).AddHours(-2); - if (!_scanAndUploadThread.IsAlive && DateTime.Now > ((DateTime)Settings.LastPlaylistUpload).AddHours(Global.SessionRestartHours)) + if (!_scanAndUploadThread.IsAlive && + DateTime.Now > ((DateTime)Settings.LastPlaylistUpload).AddHours(Global.SessionRestartHours) + && !PlaylistProcessor.ProcessingPlaylistsFinished) + { StartMainProcess(); + } } - ThreadHelper.SafeSleep(15000); + if (DateTime.Now.AddHours(Global.SessionRestartHours * -1) > SessionStart) + { + SessionStart = DateTime.Now; + PlaylistProcessor.ProcessingPlaylistsFinished = false; + StartMainProcess(); + } + + ThreadHelper.SafeSleep(15000); } }) { IsBackground = true }; @@ -183,6 +196,15 @@ private void RunDebugCommands() // Debugging code here } + private void GCCollect() + { + try + { + GC.Collect(); + } + catch { } + } + private void MainForm_Load(object sender, EventArgs e) { if (StartHidden) @@ -486,6 +508,7 @@ private void MainProcess(bool restarting = false) } IdleProcessor.Paused = false; + GCCollect(); } private void YTMAuthenticationCheckWait() diff --git a/YTMusicUploader/Properties/AssemblyInfo.cs b/YTMusicUploader/Properties/AssemblyInfo.cs index 40147e3b..a395abea 100644 --- a/YTMusicUploader/Properties/AssemblyInfo.cs +++ b/YTMusicUploader/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.5")] -[assembly: AssemblyFileVersion("1.7.5")] +[assembly: AssemblyVersion("1.7.6")] +[assembly: AssemblyFileVersion("1.7.6")]