From 2e8c91968f5f2fc4bc19c6a0d6912b88ae3109e2 Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Thu, 1 Feb 2024 16:38:44 +0100 Subject: [PATCH] Add local plugin installation Signed-off-by: Florian Grabmeier --- .../PluginsManager.cs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 8cd58ac52..b9eaea2d4 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -14,6 +14,8 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Windows; +using System.IO.Compression; +using Newtonsoft.Json; namespace Flow.Launcher.Plugin.PluginsManager { @@ -138,6 +140,12 @@ namespace Flow.Launcher.Plugin.PluginsManager MessageBoxButton.YesNo) == MessageBoxResult.No) return; + if (File.Exists(plugin.UrlDownload)) + { + Install(plugin, plugin.UrlDownload); + return; + } + // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download var downloadFilename = string.IsNullOrEmpty(plugin.Version) ? $"{plugin.Name}-{Guid.NewGuid()}.zip" @@ -470,6 +478,54 @@ namespace Flow.Launcher.Plugin.PluginsManager return new List { result }; } + internal List InstallFromLocal(string path) + { + if (string.IsNullOrEmpty(path) || !File.Exists(path)) + { + return new List(); + } + + var plugin = null as UserPlugin; + + using (ZipArchive archive = ZipFile.OpenRead(path)) + { + var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json").ToString(); + ZipArchiveEntry pluginJsonEntry = archive.GetEntry(pluginJsonPath); + + if (pluginJsonEntry != null) + { + using (StreamReader reader = new StreamReader(pluginJsonEntry.Open())) + { + string pluginJsonContent = reader.ReadToEnd(); + plugin = JsonConvert.DeserializeObject(pluginJsonContent); + plugin.IcoPath = Path.Combine(path, pluginJsonEntry.FullName.Split('/')[0], plugin.IcoPath); + } + } + } + + if (plugin == null) + { + return new List(); + } + + plugin.UrlDownload = path; + + var result = new Result + { + Title = plugin.Name, + SubTitle = plugin.UrlDownload, + IcoPath = plugin.IcoPath, + Action = e => + { + Application.Current.MainWindow.Hide(); + _ = InstallOrUpdateAsync(plugin); + + return ShouldHideWindow; + } + }; + return new List { result }; + } + private bool InstallSourceKnown(string url) { var author = url.Split('/')[3]; @@ -489,6 +545,9 @@ namespace Flow.Launcher.Plugin.PluginsManager && search.Split('.').Last() == zip) return InstallFromWeb(search); + if (File.Exists(search) && search.Split('.').Last() == zip) + return InstallFromLocal(search); + var results = PluginsManifest .UserPlugins