Skip to content

Commit

Permalink
Resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack251970 committed Feb 23, 2025
2 parents 8b6dcd0 + 2bc9203 commit cdf02d5
Show file tree
Hide file tree
Showing 40 changed files with 484 additions and 265 deletions.
14 changes: 12 additions & 2 deletions Flow.Launcher.Core/Plugin/JsonRPCPluginBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ internal abstract class JsonRPCPluginBase : IAsyncPlugin, IContextMenu, ISetting
private string SettingConfigurationPath =>
Path.Combine(Context.CurrentPluginMetadata.PluginDirectory, "SettingsTemplate.yaml");

private string SettingPath => Path.Combine(DataLocation.PluginSettingsDirectory,
Context.CurrentPluginMetadata.Name, "Settings.json");
private string SettingDirectory => Path.Combine(DataLocation.PluginSettingsDirectory,
Context.CurrentPluginMetadata.Name);

private string SettingPath => Path.Combine(SettingDirectory, "Settings.json");

public abstract List<Result> LoadContextMenus(Result selectedResult);

Expand Down Expand Up @@ -159,5 +161,13 @@ public Control CreateSettingPanel()
{
return Settings.CreateSettingPanel();
}

public void DeletePluginSettingsDirectory()
{
if (Directory.Exists(SettingDirectory))
{
Directory.Delete(SettingDirectory, true);
}
}
}
}
2 changes: 1 addition & 1 deletion Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void Save()
public Control CreateSettingPanel()
{
if (Settings == null || Settings.Count == 0)
return new();
return null;

var settingWindow = new UserControl();
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
Expand Down
11 changes: 8 additions & 3 deletions Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,15 @@ private void SetupJsonRPC()
RPC.StartListening();
}

public virtual Task ReloadDataAsync()
public virtual async Task ReloadDataAsync()
{
SetupJsonRPC();
return Task.CompletedTask;
try
{
await RPC.InvokeAsync("reload_data", Context);
}
catch (RemoteMethodNotFoundException e)
{
}
}

public virtual async ValueTask DisposeAsync()
Expand Down
74 changes: 65 additions & 9 deletions Flow.Launcher.Core/Plugin/PluginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ public static async Task InitializePluginsAsync()
{
var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name));
API.ShowMsg(
InternationalizationManager.Instance.GetTranslation("failedToInitializePluginsTitle"),
API.GetTranslation("failedToInitializePluginsTitle"),
string.Format(
InternationalizationManager.Instance.GetTranslation("failedToInitializePluginsMessage"),
API.GetTranslation("failedToInitializePluginsMessage"),
failed
),
"",
Expand Down Expand Up @@ -281,7 +281,7 @@ public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Quer
return results;
}

public static void UpdatePluginMetadata(List<Result> results, PluginMetadata metadata, Query query)
public static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMetadata metadata, Query query)
{
foreach (var r in results)
{
Expand Down Expand Up @@ -439,7 +439,7 @@ public static bool PluginModified(string uuid)
public static void UpdatePlugin(PluginMetadata existingVersion, UserPlugin newVersion, string zipFilePath)
{
InstallPlugin(newVersion, zipFilePath, checkModified:false);
UninstallPlugin(existingVersion, removeSettings:false, checkModified:false);
UninstallPlugin(existingVersion, removePluginFromSettings:false, removePluginSettings:false, checkModified: false);
_modifiedPlugins.Add(existingVersion.ID);
}

Expand All @@ -454,9 +454,9 @@ public static void InstallPlugin(UserPlugin plugin, string zipFilePath)
/// <summary>
/// Uninstall a plugin.
/// </summary>
public static void UninstallPlugin(PluginMetadata plugin, bool removeSettings = true)
public static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings = true, bool removePluginSettings = false)
{
UninstallPlugin(plugin, removeSettings, true);
UninstallPlugin(plugin, removePluginFromSettings, removePluginSettings, true);
}

#endregion
Expand Down Expand Up @@ -521,22 +521,78 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c

FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => API.ShowMsgBox(s));

Directory.Delete(tempFolderPluginPath, true);
try
{
if (Directory.Exists(tempFolderPluginPath))
Directory.Delete(tempFolderPluginPath, true);
}
catch (Exception e)
{
Log.Exception($"|PluginManager.InstallPlugin|Failed to delete temp folder {tempFolderPluginPath}", e);
}

if (checkModified)
{
_modifiedPlugins.Add(plugin.ID);
}
}

internal static void UninstallPlugin(PluginMetadata plugin, bool removeSettings, bool checkModified)
internal static void UninstallPlugin(PluginMetadata plugin, bool removePluginFromSettings, bool removePluginSettings, bool checkModified)
{
if (checkModified && PluginModified(plugin.ID))
{
throw new ArgumentException($"Plugin {plugin.Name} has been modified");
}

if (removeSettings)
if (removePluginSettings)
{
if (AllowedLanguage.IsDotNet(plugin.Language)) // for the plugin in .NET, we can use assembly loader
{
var assemblyLoader = new PluginAssemblyLoader(plugin.ExecuteFilePath);
var assembly = assemblyLoader.LoadAssemblyAndDependencies();
var assemblyName = assembly.GetName().Name;

// if user want to remove the plugin settings, we cannot call save method for the plugin json storage instance of this plugin
// so we need to remove it from the api instance
var method = API.GetType().GetMethod("RemovePluginSettings");
var pluginJsonStorage = method?.Invoke(API, new object[] { assemblyName });

// if there exists a json storage for current plugin, we need to delete the directory path
if (pluginJsonStorage != null)
{
var deleteMethod = pluginJsonStorage.GetType().GetMethod("DeleteDirectory");
try
{
deleteMethod?.Invoke(pluginJsonStorage, null);
}
catch (Exception e)
{
Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e);
API.ShowMsg(API.GetTranslation("failedToRemovePluginSettingsTitle"),
string.Format(API.GetTranslation("failedToRemovePluginSettingsMessage"), plugin.Name));
}
}
}
else // the plugin with json prc interface
{
var pluginPair = AllPlugins.FirstOrDefault(p => p.Metadata.ID == plugin.ID);
if (pluginPair != null && pluginPair.Plugin is JsonRPCPlugin jsonRpcPlugin)
{
try
{
jsonRpcPlugin.DeletePluginSettingsDirectory();
}
catch (Exception e)
{
Log.Exception($"|PluginManager.UninstallPlugin|Failed to delete plugin json folder for {plugin.Name}", e);
API.ShowMsg(API.GetTranslation("failedToRemovePluginSettingsTitle"),
string.Format(API.GetTranslation("failedToRemovePluginSettingsMessage"), plugin.Name));
}
}
}
}

if (removePluginFromSettings)
{
Settings.Plugins.Remove(plugin.ID);
AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID);
Expand Down
18 changes: 14 additions & 4 deletions Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@

namespace Flow.Launcher.Infrastructure.Storage
{
public class PluginJsonStorage<T> :JsonStorage<T> where T : new()
public class PluginJsonStorage<T> : JsonStorage<T> where T : new()
{
// Use assembly name to check which plugin is using this storage
public readonly string AssemblyName;

public PluginJsonStorage()
{
// C# related, add python related below
var dataType = typeof(T);
var assemblyName = dataType.Assembly.GetName().Name;
DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, assemblyName);
AssemblyName = dataType.Assembly.GetName().Name;
DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, AssemblyName);
Helper.ValidateDirectory(DirectoryPath);

FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
Expand All @@ -20,6 +23,13 @@ public PluginJsonStorage(T data) : this()
{
Data = data;
}

public void DeleteDirectory()
{
if (Directory.Exists(DirectoryPath))
{
Directory.Delete(DirectoryPath, true);
}
}
}
}

5 changes: 3 additions & 2 deletions Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace Flow.Launcher.Plugin
public interface IPublicAPI
{
/// <summary>
/// Change Flow.Launcher query
/// Change Flow.Launcher query.
/// When current results are from context menu or history, it will go back to query results before changing query.
/// </summary>
/// <param name="query">query text</param>
/// <param name="requery">
Expand Down Expand Up @@ -299,7 +300,7 @@ public interface IPublicAPI

/// <summary>
/// Reloads the query.
/// This method should run when selected item is from query results.
/// When current results are from context menu or history, it will go back to query results before requerying.
/// </summary>
/// <param name="reselect">Choose the first result after reload if true; keep the last selected result if false. Default is true.</param>
public void ReQuery(bool reselect = true);
Expand Down
3 changes: 2 additions & 1 deletion Flow.Launcher.Plugin/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,9 @@ public ValueTask<bool> ExecuteAsync(ActionContext context)
/// The key to identify the record. This is used when FL checks whether the result is the topmost record. Or FL calculates the hashcode of the result for user selected records.
/// This can be useful when your plugin will change the Title or SubTitle of the result dynamically.
/// If the plugin does not specific this, FL just uses Title and SubTitle to identify this result.
/// Note: Because old data does not have this key, we should use null as the default value for consistency.
/// </summary>
public string RecordKey { get; set; } = string.Empty;
public string RecordKey { get; set; } = null;

/// <summary>
/// Info of the preview section of a <see cref="Result"/>
Expand Down
5 changes: 3 additions & 2 deletions Flow.Launcher.Test/FilesFoldersTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Flow.Launcher.Plugin.SharedCommands;
using NUnit.Framework;
using NUnit.Framework.Legacy;

namespace Flow.Launcher.Test
{
Expand Down Expand Up @@ -35,7 +36,7 @@ public class FilesFoldersTest
[TestCase(@"c:\barr", @"c:\foo\..\bar\baz", false)]
public void GivenTwoPaths_WhenCheckPathContains_ThenShouldBeExpectedResult(string parentPath, string path, bool expectedResult)
{
Assert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path));
ClassicAssert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path));
}

// Equality
Expand All @@ -47,7 +48,7 @@ public void GivenTwoPaths_WhenCheckPathContains_ThenShouldBeExpectedResult(strin
[TestCase(@"c:\foo", @"c:\foo\", true)]
public void GivenTwoPathsAreTheSame_WhenCheckPathContains_ThenShouldBeExpectedResult(string parentPath, string path, bool expectedResult)
{
Assert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path, allowEqual: expectedResult));
ClassicAssert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path, allowEqual: expectedResult));
}
}
}
2 changes: 1 addition & 1 deletion Flow.Launcher.Test/Flow.Launcher.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

<ItemGroup>
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="nunit" Version="3.14.0" />
<PackageReference Include="nunit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading

0 comments on commit cdf02d5

Please sign in to comment.