From 57b78b5797850c04317f2b6e313ded170a5bc16a Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Sun, 19 Nov 2023 17:07:29 +0100 Subject: [PATCH 1/9] Fix merge Signed-off-by: Florian Grabmeier --- .../Languages/en.xaml | 2 ++ .../PluginsManager.cs | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index 42a1ac9b8..cc2360edf 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -30,6 +30,8 @@ This plugin is already installed Plugin Manifest Download Failed Please check if you can connect to github.com. This error means you may not be able to install or update plugins. + Update All Plugins + Would you like to update all plugins? Plugin {0} successfully updated. Restarting Flow, please wait... Installing from an unknown source You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 00f77f872..03802ff9e 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -296,6 +296,23 @@ namespace Flow.Launcher.Plugin.PluginsManager } }); + if (resultsForUpdate.Count() > 1) + { + var updateAllResult = new Result + { + Title = Context.API.GetTranslation("plugin_pluginsmanager_update_all_title"), + SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), + IcoPath = icoPath, + Action = e => + { + // TODO: logic here + return true; + }, + ContextData = new UserPlugin() + }; + results = results.Prepend(updateAllResult); + } + return Search(results, search); } From cb59b6b2645753847ed2e91d8dd6044455bf8b0f Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Wed, 22 Nov 2023 14:25:17 +0100 Subject: [PATCH 2/9] Implemet basic update all logic Signed-off-by: Florian Grabmeier --- .../PluginsManager.cs | 77 +++++++++++++++++-- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 03802ff9e..159950ac2 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -7,6 +7,7 @@ using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin.SharedCommands; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; @@ -167,7 +168,7 @@ namespace Flow.Launcher.Plugin.PluginsManager Log.Exception("PluginsManager", "An error occurred while downloading plugin", e); return; } - + if (Settings.AutoRestartAfterChanging) { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"), @@ -292,7 +293,8 @@ namespace Flow.Launcher.Plugin.PluginsManager ContextData = new UserPlugin { - Website = x.PluginNewUserPlugin.Website, UrlSourceCode = x.PluginNewUserPlugin.UrlSourceCode + Website = x.PluginNewUserPlugin.Website, + UrlSourceCode = x.PluginNewUserPlugin.UrlSourceCode } }); @@ -305,8 +307,70 @@ namespace Flow.Launcher.Plugin.PluginsManager IcoPath = icoPath, Action = e => { - // TODO: logic here - return true; + string message; + //TODO: display all plugins to be updated in the message + if (/*Settings.AutoRestartAfterChanging*/ false) // TODO: remove false + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), "FlowLauncher will restart after updating all plugins.", + Environment.NewLine, Environment.NewLine); + } + else + { + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), + Environment.NewLine); + } + if (MessageBox.Show(message, + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + MessageBoxButton.YesNo) == MessageBoxResult.Yes) + { + Debug.Print("Looping through plugins to update"); + foreach (var plugin in resultsForUpdate) + { + Debug.Print($"Updating {plugin.Name}"); + var downloadToFilePath = Path.Combine(Path.GetTempPath(), + $"{plugin.Name}-{plugin.NewVersion}.zip"); + + _ = Task.Run(async delegate + { + if (File.Exists(downloadToFilePath)) + { + File.Delete(downloadToFilePath); + } + + await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath) + .ConfigureAwait(false); + + PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); + + //TODO: fix + // if (Settings.AutoRestartAfterChanging) + // { + // Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + // string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"), + // x.Name)); + // Context.API.RestartApp(); + // } + // else + // { + // Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + // string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_no_restart"), + // x.Name)); + // } + }).ContinueWith(t => + { + Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", + t.Exception.InnerException); + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), + plugin.Name)); + }, TaskContinuationOptions.OnlyOnFaulted); + } + Debug.Print("Finished updating all plugins"); + return true; // User confirmed to update all plugins + } + return false; //user cancelled }, ContextData = new UserPlugin() }; @@ -454,7 +518,8 @@ namespace Flow.Launcher.Plugin.PluginsManager string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name)); Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); } - catch (ArgumentException e) { + catch (ArgumentException e) + { Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), string.Format(Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"), plugin.Name)); Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); @@ -518,7 +583,7 @@ namespace Flow.Launcher.Plugin.PluginsManager { try { - PluginManager.UninstallPlugin(plugin, removeSettings:true); + PluginManager.UninstallPlugin(plugin, removeSettings: true); } catch (ArgumentException e) { From 8180c1cd40ea5410a3a3b6f5df8ddf34dc690470 Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Wed, 22 Nov 2023 14:49:43 +0100 Subject: [PATCH 3/9] Display correct messages Signed-off-by: Florian Grabmeier --- .../Languages/en.xaml | 2 +- .../PluginsManager.cs | 46 +++++++++---------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index cc2360edf..99daa40f3 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -30,7 +30,7 @@ This plugin is already installed Plugin Manifest Download Failed Please check if you can connect to github.com. This error means you may not be able to install or update plugins. - Update All Plugins + Update all plugins Would you like to update all plugins? Plugin {0} successfully updated. Restarting Flow, please wait... Installing from an unknown source diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 159950ac2..57f252e4c 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -308,25 +308,21 @@ namespace Flow.Launcher.Plugin.PluginsManager Action = e => { string message; - //TODO: display all plugins to be updated in the message - if (/*Settings.AutoRestartAfterChanging*/ false) // TODO: remove false + if (Settings.AutoRestartAfterChanging) { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), "FlowLauncher will restart after updating all plugins.", - Environment.NewLine, Environment.NewLine); + message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n"; } else { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), - Environment.NewLine); + message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n"; } + if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_update_title"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) { - Debug.Print("Looping through plugins to update"); foreach (var plugin in resultsForUpdate) { - Debug.Print($"Updating {plugin.Name}"); var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip"); @@ -342,20 +338,6 @@ namespace Flow.Launcher.Plugin.PluginsManager PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); - //TODO: fix - // if (Settings.AutoRestartAfterChanging) - // { - // Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - // string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"), - // x.Name)); - // Context.API.RestartApp(); - // } - // else - // { - // Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - // string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_no_restart"), - // x.Name)); - // } }).ContinueWith(t => { Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", @@ -367,10 +349,24 @@ namespace Flow.Launcher.Plugin.PluginsManager plugin.Name)); }, TaskContinuationOptions.OnlyOnFaulted); } - Debug.Print("Finished updating all plugins"); - return true; // User confirmed to update all plugins + + if (Settings.AutoRestartAfterChanging) + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"), + "all")); + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_no_restart"), + "all")); + } + + return true; } - return false; //user cancelled + return false; }, ContextData = new UserPlugin() }; From a3b9a4f9d01e64c5deb6b9425d07d58426fe86c5 Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Wed, 22 Nov 2023 14:55:53 +0100 Subject: [PATCH 4/9] Run updates in parallel Signed-off-by: Florian Grabmeier --- .../PluginsManager.cs | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 57f252e4c..e57530270 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -321,34 +321,33 @@ namespace Flow.Launcher.Plugin.PluginsManager Context.API.GetTranslation("plugin_pluginsmanager_update_title"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) { - foreach (var plugin in resultsForUpdate) + Parallel.ForEach(resultsForUpdate, plugin => { - var downloadToFilePath = Path.Combine(Path.GetTempPath(), - $"{plugin.Name}-{plugin.NewVersion}.zip"); + var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip"); _ = Task.Run(async delegate + { + if (File.Exists(downloadToFilePath)) { - if (File.Exists(downloadToFilePath)) - { - File.Delete(downloadToFilePath); - } + File.Delete(downloadToFilePath); + } - await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath) - .ConfigureAwait(false); + await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath) + .ConfigureAwait(false); - PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); + PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); - }).ContinueWith(t => - { - Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", - t.Exception.InnerException); - Context.API.ShowMsg( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), - plugin.Name)); - }, TaskContinuationOptions.OnlyOnFaulted); - } + }).ContinueWith(t => + { + Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", + t.Exception.InnerException); + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), + plugin.Name)); + }, TaskContinuationOptions.OnlyOnFaulted); + }); if (Settings.AutoRestartAfterChanging) { From 4ed1c3c442e724b17551ad3ad3095cd21d7cd599 Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Thu, 23 Nov 2023 08:53:47 +0100 Subject: [PATCH 5/9] Update prompts Signed-off-by: Florian Grabmeier --- .../Languages/en.xaml | 4 ++++ .../PluginsManager.cs | 14 ++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index 99daa40f3..004d81e8b 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -32,6 +32,9 @@ Please check if you can connect to github.com. This error means you may not be able to install or update plugins. Update all plugins Would you like to update all plugins? + Would you like to update {0} plugins?{1}FlowLauncher will restart after updating all plugins. + Would you like to update {0} plugins? + {0} plugins successfully updated. Restarting Flow, please wait... Plugin {0} successfully updated. Restarting Flow, please wait... Installing from an unknown source You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings) @@ -39,6 +42,7 @@ Plugin {0} successfully installed. Please restart Flow. Plugin {0} successfully uninstalled. Please restart Flow. Plugin {0} successfully updated. Please restart Flow. + {0} plugins successfully updated. Please restart Flow. Plugin {0} has already been modified. Please restart Flow before making any further changes. diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index e57530270..88ad8ed32 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -310,11 +310,13 @@ namespace Flow.Launcher.Plugin.PluginsManager string message; if (Settings.AutoRestartAfterChanging) { - message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n"; + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"), + resultsForUpdate.Count(), Environment.NewLine); } else { - message = "Would you like to update all plugins?\nFlowLauncher will restart after updating all plugins.\n"; + message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"), + resultsForUpdate.Count()); } if (MessageBox.Show(message, @@ -352,15 +354,15 @@ namespace Flow.Launcher.Plugin.PluginsManager if (Settings.AutoRestartAfterChanging) { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"), - "all")); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"), + resultsForUpdate.Count())); Context.API.RestartApp(); } else { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_no_restart"), - "all")); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"), + resultsForUpdate.Count())); } return true; From 5169a16458ad8a7f9feab74e885354659ea82095 Mon Sep 17 00:00:00 2001 From: flox_x <93255373+flooxo@users.noreply.github.com> Date: Fri, 15 Dec 2023 17:57:04 +0100 Subject: [PATCH 6/9] Apply suggestions from code review Typo Co-authored-by: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> --- Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml index 004d81e8b..a89d9df21 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml @@ -32,7 +32,7 @@ Please check if you can connect to github.com. This error means you may not be able to install or update plugins. Update all plugins Would you like to update all plugins? - Would you like to update {0} plugins?{1}FlowLauncher will restart after updating all plugins. + Would you like to update {0} plugins?{1}Flow Launcher will restart after updating all plugins. Would you like to update {0} plugins? {0} plugins successfully updated. Restarting Flow, please wait... Plugin {0} successfully updated. Restarting Flow, please wait... From dcaa74dbe5ae30f1ce99fa5ddb51ce67072efcb3 Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Fri, 29 Dec 2023 11:17:46 +0100 Subject: [PATCH 7/9] Fix reduce nesting Signed-off-by: Florian Grabmeier --- .../PluginsManager.cs | 91 ++++++++++--------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 88ad8ed32..fd5cbbe98 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -321,53 +321,54 @@ namespace Flow.Launcher.Plugin.PluginsManager if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - MessageBoxButton.YesNo) == MessageBoxResult.Yes) + MessageBoxButton.YesNo) == MessageBoxResult.No) { - Parallel.ForEach(resultsForUpdate, plugin => - { - var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip"); - - _ = Task.Run(async delegate - { - if (File.Exists(downloadToFilePath)) - { - File.Delete(downloadToFilePath); - } - - await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath) - .ConfigureAwait(false); - - PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); - - }).ContinueWith(t => - { - Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", - t.Exception.InnerException); - Context.API.ShowMsg( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), - plugin.Name)); - }, TaskContinuationOptions.OnlyOnFaulted); - }); - - if (Settings.AutoRestartAfterChanging) - { - Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"), - resultsForUpdate.Count())); - Context.API.RestartApp(); - } - else - { - Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"), - resultsForUpdate.Count())); - } - - return true; + return false; } - return false; + + Parallel.ForEach(resultsForUpdate, plugin => + { + var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip"); + + _ = Task.Run(async delegate + { + if (File.Exists(downloadToFilePath)) + { + File.Delete(downloadToFilePath); + } + + await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath) + .ConfigureAwait(false); + + PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); + + }).ContinueWith(t => + { + Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", + t.Exception.InnerException); + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), + plugin.Name)); + }, TaskContinuationOptions.OnlyOnFaulted); + }); + + if (Settings.AutoRestartAfterChanging) + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"), + resultsForUpdate.Count())); + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"), + resultsForUpdate.Count())); + } + + return true; }, ContextData = new UserPlugin() }; From 26c35a84b1569724c27ff38da9bc4086ec861953 Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Wed, 3 Jan 2024 09:29:56 +0100 Subject: [PATCH 8/9] Fix use async Signed-off-by: Florian Grabmeier --- .../PluginsManager.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index fd5cbbe98..cd77e6daf 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -305,7 +305,7 @@ namespace Flow.Launcher.Plugin.PluginsManager Title = Context.API.GetTranslation("plugin_pluginsmanager_update_all_title"), SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_update_all_subtitle"), IcoPath = icoPath, - Action = e => + AsyncAction = async e => { string message; if (Settings.AutoRestartAfterChanging) @@ -326,11 +326,11 @@ namespace Flow.Launcher.Plugin.PluginsManager return false; } - Parallel.ForEach(resultsForUpdate, plugin => + await Task.WhenAll(resultsForUpdate.Select(async plugin => { var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip"); - _ = Task.Run(async delegate + try { if (File.Exists(downloadToFilePath)) { @@ -341,18 +341,17 @@ namespace Flow.Launcher.Plugin.PluginsManager .ConfigureAwait(false); PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); - - }).ContinueWith(t => + } + catch (Exception ex) { - Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", - t.Exception.InnerException); + Log.Exception("PluginsManager", $"Update failed for {plugin.Name}", ex.InnerException); Context.API.ShowMsg( Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), string.Format( Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), plugin.Name)); - }, TaskContinuationOptions.OnlyOnFaulted); - }); + } + })); if (Settings.AutoRestartAfterChanging) { From c80a638b65e9632fe8778d646e40923dd908b199 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Mon, 15 Jan 2024 16:49:46 -0600 Subject: [PATCH 9/9] fix multiple enumeration and revert logic for single update --- .../PluginsManager.cs | 235 ++++++++++-------- 1 file changed, 133 insertions(+), 102 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index cd77e6daf..8cd58ac52 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -60,7 +60,8 @@ namespace Flow.Launcher.Plugin.PluginsManager AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} ", Action = _ => { - Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} "); + Context.API.ChangeQuery( + $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.InstallCommand} "); return false; } }, @@ -71,7 +72,8 @@ namespace Flow.Launcher.Plugin.PluginsManager AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} ", Action = _ => { - Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} "); + Context.API.ChangeQuery( + $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UninstallCommand} "); return false; } }, @@ -82,7 +84,8 @@ namespace Flow.Launcher.Plugin.PluginsManager AutoCompleteText = $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} ", Action = _ => { - Context.API.ChangeQuery($"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} "); + Context.API.ChangeQuery( + $"{Context.CurrentPluginMetadata.ActionKeyword} {Settings.UpdateCommand} "); return false; } } @@ -121,14 +124,14 @@ namespace Flow.Launcher.Plugin.PluginsManager if (Settings.AutoRestartAfterChanging) { message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_prompt"), - plugin.Name, plugin.Author, - Environment.NewLine, Environment.NewLine); + plugin.Name, plugin.Author, + Environment.NewLine, Environment.NewLine); } else { message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_prompt_no_restart"), - plugin.Name, plugin.Author, - Environment.NewLine); + plugin.Name, plugin.Author, + Environment.NewLine); } if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_install_title"), @@ -155,16 +158,17 @@ namespace Flow.Launcher.Plugin.PluginsManager } catch (HttpRequestException e) { - Context.API.ShowMsgError(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name), - Context.API.GetTranslation("plugin_pluginsmanager_download_error")); + Context.API.ShowMsgError( + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name), + Context.API.GetTranslation("plugin_pluginsmanager_download_error")); Log.Exception("PluginsManager", "An error occurred while downloading plugin", e); return; } catch (Exception e) { Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), - plugin.Name)); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), + plugin.Name)); Log.Exception("PluginsManager", "An error occurred while downloading plugin", e); return; } @@ -172,27 +176,29 @@ namespace Flow.Launcher.Plugin.PluginsManager if (Settings.AutoRestartAfterChanging) { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_restart"), - plugin.Name)); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_restart"), + plugin.Name)); Context.API.RestartApp(); } else { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_no_restart"), - plugin.Name)); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_success_no_restart"), + plugin.Name)); } } - internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token, bool usePrimaryUrlOnly = false) + internal async ValueTask> RequestUpdateAsync(string search, CancellationToken token, + bool usePrimaryUrlOnly = false) { await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly); - var resultsForUpdate = + var resultsForUpdate = ( from existingPlugin in Context.API.GetAllPlugins() join pluginFromManifest in PluginsManifest.UserPlugins on existingPlugin.Metadata.ID equals pluginFromManifest.ID - where existingPlugin.Metadata.Version.CompareTo(pluginFromManifest.Version) < + where String.Compare(existingPlugin.Metadata.Version, pluginFromManifest.Version, + StringComparison.InvariantCulture) < 0 // if current version precedes manifest version && !PluginManager.PluginModified(existingPlugin.Metadata.ID) select @@ -205,7 +211,7 @@ namespace Flow.Launcher.Plugin.PluginsManager existingPlugin.Metadata.IcoPath, PluginExistingMetadata = existingPlugin.Metadata, PluginNewUserPlugin = pluginFromManifest - }; + }).ToList(); if (!resultsForUpdate.Any()) return new List @@ -227,68 +233,77 @@ namespace Flow.Launcher.Plugin.PluginsManager IcoPath = x.IcoPath, Action = e => { - string message; if (Settings.AutoRestartAfterChanging) { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_prompt"), - x.Name, x.Author, - Environment.NewLine, Environment.NewLine); + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_prompt"), + x.Name, x.Author, + Environment.NewLine, Environment.NewLine); } else { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_prompt_no_restart"), - x.Name, x.Author, - Environment.NewLine); + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_prompt_no_restart"), + x.Name, x.Author, + Environment.NewLine); } if (MessageBox.Show(message, Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - MessageBoxButton.YesNo) == MessageBoxResult.Yes) + MessageBoxButton.YesNo) != MessageBoxResult.Yes) { - var downloadToFilePath = Path.Combine(Path.GetTempPath(), - $"{x.Name}-{x.NewVersion}.zip"); - - _ = Task.Run(async delegate - { - if (File.Exists(downloadToFilePath)) - { - File.Delete(downloadToFilePath); - } - - await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath) - .ConfigureAwait(false); - - PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin, downloadToFilePath); - - if (Settings.AutoRestartAfterChanging) - { - Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_restart"), - x.Name)); - Context.API.RestartApp(); - } - else - { - Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_success_no_restart"), - x.Name)); - } - }).ContinueWith(t => - { - Log.Exception("PluginsManager", $"Update failed for {x.Name}", - t.Exception.InnerException); - Context.API.ShowMsg( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format( - Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), - x.Name)); - }, TaskContinuationOptions.OnlyOnFaulted); - - return true; + return false; } - return false; + var downloadToFilePath = Path.Combine(Path.GetTempPath(), + $"{x.Name}-{x.NewVersion}.zip"); + + _ = Task.Run(async delegate + { + if (File.Exists(downloadToFilePath)) + { + File.Delete(downloadToFilePath); + } + + await Http.DownloadAsync(x.PluginNewUserPlugin.UrlDownload, downloadToFilePath) + .ConfigureAwait(false); + + PluginManager.UpdatePlugin(x.PluginExistingMetadata, x.PluginNewUserPlugin, + downloadToFilePath); + + if (Settings.AutoRestartAfterChanging) + { + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format( + Context.API.GetTranslation( + "plugin_pluginsmanager_update_success_restart"), + x.Name)); + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format( + Context.API.GetTranslation( + "plugin_pluginsmanager_update_success_no_restart"), + x.Name)); + } + }).ContinueWith(t => + { + Log.Exception("PluginsManager", $"Update failed for {x.Name}", + t.Exception.InnerException); + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), + string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"), + x.Name)); + }, TaskContinuationOptions.OnlyOnFaulted); + + return true; + }, ContextData = new UserPlugin @@ -298,6 +313,7 @@ namespace Flow.Launcher.Plugin.PluginsManager } }); + // Update all result if (resultsForUpdate.Count() > 1) { var updateAllResult = new Result @@ -310,25 +326,28 @@ namespace Flow.Launcher.Plugin.PluginsManager string message; if (Settings.AutoRestartAfterChanging) { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"), - resultsForUpdate.Count(), Environment.NewLine); + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt"), + resultsForUpdate.Count(), Environment.NewLine); } else { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"), - resultsForUpdate.Count()); + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_all_prompt_no_restart"), + resultsForUpdate.Count()); } if (MessageBox.Show(message, - Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - MessageBoxButton.YesNo) == MessageBoxResult.No) + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + MessageBoxButton.YesNo) == MessageBoxResult.No) { return false; } await Task.WhenAll(resultsForUpdate.Select(async plugin => { - var downloadToFilePath = Path.Combine(Path.GetTempPath(), $"{plugin.Name}-{plugin.NewVersion}.zip"); + var downloadToFilePath = Path.Combine(Path.GetTempPath(), + $"{plugin.Name}-{plugin.NewVersion}.zip"); try { @@ -340,7 +359,8 @@ namespace Flow.Launcher.Plugin.PluginsManager await Http.DownloadAsync(plugin.PluginNewUserPlugin.UrlDownload, downloadToFilePath) .ConfigureAwait(false); - PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, downloadToFilePath); + PluginManager.UpdatePlugin(plugin.PluginExistingMetadata, plugin.PluginNewUserPlugin, + downloadToFilePath); } catch (Exception ex) { @@ -356,15 +376,17 @@ namespace Flow.Launcher.Plugin.PluginsManager if (Settings.AutoRestartAfterChanging) { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"), - resultsForUpdate.Count())); + string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_restart"), + resultsForUpdate.Count())); Context.API.RestartApp(); } else { Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_update_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"), - resultsForUpdate.Count())); + string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_all_success_no_restart"), + resultsForUpdate.Count())); } return true; @@ -429,9 +451,11 @@ namespace Flow.Launcher.Plugin.PluginsManager if (Settings.WarnFromUnknownSource) { if (!InstallSourceKnown(plugin.UrlDownload) - && MessageBox.Show(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning"), + && MessageBox.Show(string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning"), Environment.NewLine), - Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning_title"), + Context.API.GetTranslation( + "plugin_pluginsmanager_install_unknown_source_warning_title"), MessageBoxButton.YesNo) == MessageBoxResult.No) return false; } @@ -443,10 +467,7 @@ namespace Flow.Launcher.Plugin.PluginsManager } }; - return new List - { - result - }; + return new List { result }; } private bool InstallSourceKnown(string url) @@ -455,10 +476,12 @@ namespace Flow.Launcher.Plugin.PluginsManager var acceptedSource = "https://github.com"; var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author); - return url.StartsWith(acceptedSource) && Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart)); + return url.StartsWith(acceptedSource) && + Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(constructedUrlPart)); } - internal async ValueTask> RequestInstallOrUpdate(string search, CancellationToken token, bool usePrimaryUrlOnly = false) + internal async ValueTask> RequestInstallOrUpdate(string search, CancellationToken token, + bool usePrimaryUrlOnly = false) { await PluginsManifest.UpdateManifestAsync(token, usePrimaryUrlOnly); @@ -497,7 +520,8 @@ namespace Flow.Launcher.Plugin.PluginsManager private void Install(UserPlugin plugin, string downloadedFilePath) { if (!File.Exists(downloadedFilePath)) - throw new FileNotFoundException($"Plugin {plugin.ID} zip file not found at {downloadedFilePath}", downloadedFilePath); + throw new FileNotFoundException($"Plugin {plugin.ID} zip file not found at {downloadedFilePath}", + downloadedFilePath); try { PluginManager.InstallPlugin(plugin, downloadedFilePath); @@ -506,19 +530,21 @@ namespace Flow.Launcher.Plugin.PluginsManager catch (FileNotFoundException e) { Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile")); + Context.API.GetTranslation("plugin_pluginsmanager_install_errormetadatafile")); Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); } catch (InvalidOperationException e) { Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), plugin.Name)); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_duplicate"), + plugin.Name)); Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); } catch (ArgumentException e) { Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"), plugin.Name)); + string.Format(Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error"), + plugin.Name)); Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); } } @@ -538,15 +564,17 @@ namespace Flow.Launcher.Plugin.PluginsManager string message; if (Settings.AutoRestartAfterChanging) { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt"), - x.Metadata.Name, x.Metadata.Author, - Environment.NewLine, Environment.NewLine); + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt"), + x.Metadata.Name, x.Metadata.Author, + Environment.NewLine, Environment.NewLine); } else { - message = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt_no_restart"), - x.Metadata.Name, x.Metadata.Author, - Environment.NewLine); + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_uninstall_prompt_no_restart"), + x.Metadata.Name, x.Metadata.Author, + Environment.NewLine); } if (MessageBox.Show(message, @@ -561,9 +589,12 @@ namespace Flow.Launcher.Plugin.PluginsManager } else { - Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"), - string.Format(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_success_no_restart"), - x.Metadata.Name)); + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_uninstall_title"), + string.Format( + Context.API.GetTranslation( + "plugin_pluginsmanager_uninstall_success_no_restart"), + x.Metadata.Name)); } return true; @@ -586,7 +617,7 @@ namespace Flow.Launcher.Plugin.PluginsManager { Log.Exception("Flow.Launcher.Plugin.PluginsManager", e.Message, e); Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_uninstall_error_title"), - Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error")); + Context.API.GetTranslation("plugin_pluginsmanager_plugin_modified_error")); } } }