mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Support installing from local path
This commit is contained in:
parent
f9e7b82b15
commit
248b098e54
4 changed files with 102 additions and 1 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
@ -633,6 +634,42 @@ namespace Flow.Launcher.Core.Plugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task InstallPluginAndCheckRestartAsync(string filePath)
|
||||||
|
{
|
||||||
|
UserPlugin plugin;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using ZipArchive archive = ZipFile.OpenRead(filePath);
|
||||||
|
var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json") ??
|
||||||
|
throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
|
||||||
|
var pluginJsonEntry = archive.GetEntry(pluginJsonPath.ToString()) ??
|
||||||
|
throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
|
||||||
|
|
||||||
|
using Stream stream = pluginJsonEntry.Open();
|
||||||
|
plugin = JsonSerializer.Deserialize<UserPlugin>(stream);
|
||||||
|
plugin.IcoPath = "Images\\zipfolder.png";
|
||||||
|
plugin.LocalInstallPath = filePath;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
API.LogException(ClassName, "Failed to validate zip file", e);
|
||||||
|
API.ShowMsgError(API.GetTranslation("ZipFileNotHavePluginJson"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FlowSettings.ShowUnknownSourceWarning)
|
||||||
|
{
|
||||||
|
if (!InstallSourceKnown(plugin.Website)
|
||||||
|
&& API.ShowMsgBox(string.Format(
|
||||||
|
API.GetTranslation("InstallFromUnknownSourceSubtitle"), Environment.NewLine),
|
||||||
|
API.GetTranslation("InstallFromUnknownSourceTitle"),
|
||||||
|
MessageBoxButton.YesNo) == MessageBoxResult.No)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await InstallPluginAndCheckRestartAsync(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
|
public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
|
||||||
{
|
{
|
||||||
if (API.ShowMsgBox(
|
if (API.ShowMsgBox(
|
||||||
|
|
@ -913,6 +950,24 @@ namespace Flow.Launcher.Core.Plugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool InstallSourceKnown(string url)
|
||||||
|
{
|
||||||
|
var pieces = url.Split('/');
|
||||||
|
|
||||||
|
if (pieces.Length < 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var author = pieces[3];
|
||||||
|
var acceptedSource = "https://github.com";
|
||||||
|
var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
|
||||||
|
|
||||||
|
return url.StartsWith(acceptedSource) &&
|
||||||
|
API.GetAllPlugins().Any(x =>
|
||||||
|
!string.IsNullOrEmpty(x.Metadata.Website) &&
|
||||||
|
x.Metadata.Website.StartsWith(constructedUrlPart)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,12 @@
|
||||||
<system:String x:Key="UpdatePromptSubtitle">{0} by {1} {2}{2}Would you like to update this plugin?</system:String>
|
<system:String x:Key="UpdatePromptSubtitle">{0} by {1} {2}{2}Would you like to update this plugin?</system:String>
|
||||||
<system:String x:Key="DownloadingPlugin">Downloading plugin</system:String>
|
<system:String x:Key="DownloadingPlugin">Downloading plugin</system:String>
|
||||||
<system:String x:Key="AutoRestartAfterChange">Automatically restart after installing/uninstalling/updating plugins in plugin store</system:String>
|
<system:String x:Key="AutoRestartAfterChange">Automatically restart after installing/uninstalling/updating plugins in plugin store</system:String>
|
||||||
|
<system:String x:Key="ZipFileNotHavePluginJson">Zip file does not have a valid plugin.json configuration</system:String>
|
||||||
|
<system:String x:Key="InstallFromUnknownSourceTitle">Installing from an unknown source</system:String>
|
||||||
|
<system:String x:Key="InstallFromUnknownSourceSubtitle">This plugin is 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 in general section of setting window)</system:String>
|
||||||
|
<system:String x:Key="ZipFiles">Zip files</system:String>
|
||||||
|
<system:String x:Key="SelectZipFile">Please select zip file</system:String>
|
||||||
|
<system:String x:Key="installLocalPluginTooltip">Install plugin from local path</system:String>
|
||||||
|
|
||||||
<!-- Setting Theme -->
|
<!-- Setting Theme -->
|
||||||
<system:String x:Key="theme">Theme</system:String>
|
<system:String x:Key="theme">Theme</system:String>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using Flow.Launcher.Core.Plugin;
|
||||||
using Flow.Launcher.Plugin;
|
using Flow.Launcher.Plugin;
|
||||||
using Flow.Launcher.ViewModel;
|
using Flow.Launcher.ViewModel;
|
||||||
|
|
||||||
|
|
@ -96,6 +99,36 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task InstallPluginAsync()
|
||||||
|
{
|
||||||
|
var file = GetFileFromDialog(
|
||||||
|
App.API.GetTranslation("SelectZipFile"),
|
||||||
|
$"{App.API.GetTranslation("ZipFiles")} (*.zip)|*.zip");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(file))
|
||||||
|
await PluginManager.InstallPluginAndCheckRestartAsync(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFileFromDialog(string title, string filter = "")
|
||||||
|
{
|
||||||
|
var dlg = new OpenFileDialog
|
||||||
|
{
|
||||||
|
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads",
|
||||||
|
Multiselect = false,
|
||||||
|
CheckFileExists = true,
|
||||||
|
CheckPathExists = true,
|
||||||
|
Title = title,
|
||||||
|
Filter = filter
|
||||||
|
};
|
||||||
|
|
||||||
|
return dlg.ShowDialog() switch
|
||||||
|
{
|
||||||
|
DialogResult.OK => dlg.FileName,
|
||||||
|
_ => string.Empty
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public bool SatisfiesFilter(PluginStoreItemViewModel plugin)
|
public bool SatisfiesFilter(PluginStoreItemViewModel plugin)
|
||||||
{
|
{
|
||||||
// Check plugin language
|
// Check plugin language
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,13 @@
|
||||||
</ui:MenuFlyout>
|
</ui:MenuFlyout>
|
||||||
</ui:FlyoutService.Flyout>
|
</ui:FlyoutService.Flyout>
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
Height="34"
|
||||||
|
Margin="0 0 10 0"
|
||||||
|
Command="{Binding InstallPluginCommand}"
|
||||||
|
ToolTip="{DynamicResource installLocalPluginTooltip}">
|
||||||
|
<ui:FontIcon FontSize="14" Glyph="" />
|
||||||
|
</Button>
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="PluginStoreFilterTextbox"
|
Name="PluginStoreFilterTextbox"
|
||||||
Width="150"
|
Width="150"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue