Skip to content

Proposal for Http Plugin. #1311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions Flow.Launcher.Core/Plugin/HttpPlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Flow.Launcher.Plugin;

namespace Flow.Launcher.Core.Plugin
{
internal class HttpPlugin : JsonRPCPlugin
{
private readonly HttpClient client;
private readonly string url;

public override string SupportedLanguage { get; set; } = AllowedLanguage.Http;

public HttpPlugin(string url)
{
this.client = new HttpClient();
this.url = url;
}

protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default)
{
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Content = new StringContent(rpcRequest.ToString(), Encoding.UTF8);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have trouble mostly with this part. It only directly use the rpcRequest as payload, which is mostly flow's style. Therefore, the use case can only be a customized http server.
I would like to see a http plugin not only provide the endpoints address, but also translate flow's query to the specific payload (a parser), and translate the response back to flow's standard response.

var response = this.client.Send(requestMessage, token);
return response.Content.ReadAsStringAsync().Result;
}

protected override async Task<Stream> RequestAsync(JsonRPCRequestModel rpcRequest, CancellationToken token = default)
{
var response = await this.client.PostAsync(url, new StringContent(rpcRequest.ToString(), Encoding.UTF8), token).ConfigureAwait(false);
return await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
}
}
}
21 changes: 16 additions & 5 deletions Flow.Launcher.Core/Plugin/PluginConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ internal static (List<PluginMetadata>, List<PluginMetadata>) GetUniqueLatestPlug

// If metadata's version greater than each duplicate's version, CompareTo > 0
var count = group.Where(x => metadata.Version.CompareTo(x.Version) > 0).Count();

// Only add if the meatadata's version is the highest of all duplicates in the group
if (count == group.Count() - 1)
{
Expand All @@ -89,7 +89,7 @@ internal static (List<PluginMetadata>, List<PluginMetadata>) GetUniqueLatestPlug
}
}
}

if (!duplicatesExist)
unique_list.Add(metadata);
}
Expand Down Expand Up @@ -128,10 +128,21 @@ private static PluginMetadata GetPluginMetadata(string pluginDirectory)
return null;
}

if (!File.Exists(metadata.ExecuteFilePath))
if (metadata.Language.Equals(AllowedLanguage.Http, StringComparison.OrdinalIgnoreCase))
{
Log.Error($"|PluginConfig.GetPluginMetadata|execute file path didn't exist <{metadata.ExecuteFilePath}> for conifg <{configPath}");
return null;
if (!string.IsNullOrEmpty(metadata.ApiEndpoint))
{
Log.Error($"|PluginConfig.GetPluginMetadata|api endpoint didn't exist <{metadata.ApiEndpoint}> for config <{configPath}");
return null;
}
}
else
{
if (!File.Exists(metadata.ExecuteFilePath))
{
Log.Error($"|PluginConfig.GetPluginMetadata|execute file path didn't exist <{metadata.ExecuteFilePath}> for config <{configPath}");
return null;
}
}

return metadata;
Expand Down
30 changes: 21 additions & 9 deletions Flow.Launcher.Core/Plugin/PluginsLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using Droplex;
Expand All @@ -11,7 +10,6 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using System.Diagnostics;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;

namespace Flow.Launcher.Core.Plugin
Expand All @@ -25,7 +23,8 @@ public static List<PluginPair> Plugins(List<PluginMetadata> metadatas, PluginsSe
var dotnetPlugins = DotNetPlugins(metadatas);
var pythonPlugins = PythonPlugins(metadatas, settings);
var executablePlugins = ExecutablePlugins(metadatas);
var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList();
var httpPlugins = HttpPlugins(metadatas);
var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).Concat(httpPlugins).ToList();
return plugins;
}

Expand Down Expand Up @@ -85,7 +84,7 @@ public static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source)
return;
}

plugins.Add(new PluginPair {Plugin = plugin, Metadata = metadata});
plugins.Add(new PluginPair { Plugin = plugin, Metadata = metadata });
});
metadata.InitTime += milliseconds;
}
Expand Down Expand Up @@ -119,7 +118,7 @@ public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source,
return SetPythonPathForPluginPairs(source, Path.Combine(settings.PythonDirectory, PythonExecutable));

var pythonPath = string.Empty;

if (MessageBox.Show("Flow detected you have installed Python plugins, which " +
"will need Python to run. Would you like to download Python? " +
Environment.NewLine + Environment.NewLine +
Expand Down Expand Up @@ -188,22 +187,35 @@ public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source,
}

private static IEnumerable<PluginPair> SetPythonPathForPluginPairs(List<PluginMetadata> source, string pythonPath)
=> source
=> source
.Where(o => o.Language.ToUpper() == AllowedLanguage.Python)
.Select(metadata => new PluginPair
{
Plugin = new PythonPlugin(pythonPath),
Plugin = new PythonPlugin(pythonPath),
Metadata = metadata
})
.ToList();

public static IEnumerable<PluginPair> ExecutablePlugins(IEnumerable<PluginMetadata> source)
public static IEnumerable<PluginPair> ExecutablePlugins(IEnumerable<PluginMetadata> source)
{
return source
.Where(o => o.Language.ToUpper() == AllowedLanguage.Executable)
.Select(metadata => new PluginPair
{
Plugin = new ExecutablePlugin(metadata.ExecuteFilePath), Metadata = metadata
Plugin = new ExecutablePlugin(metadata.ExecuteFilePath),
Metadata = metadata
});
}


public static IEnumerable<PluginPair> HttpPlugins(List<PluginMetadata> source)
{
return source
.Where(o => o.Language.ToUpper() == AllowedLanguage.Http)
.Select(metadata => new PluginPair
{
Plugin = new HttpPlugin(metadata.ApiEndpoint),
Metadata = metadata
});
}
}
Expand Down
8 changes: 7 additions & 1 deletion Flow.Launcher.Plugin/AllowedLanguage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public static string FSharp
get { return "FSHARP"; }
}

public static string Http
{
get { return "HTTP"; }
}

public static string Executable
{
get { return "EXECUTABLE"; }
Expand All @@ -32,7 +37,8 @@ public static bool IsAllowed(string language)
{
return IsDotNet(language)
|| language.ToUpper() == Python.ToUpper()
|| language.ToUpper() == Executable.ToUpper();
|| language.ToUpper() == Executable.ToUpper()
|| language.ToUpper() == Http.ToUpper();
}
}
}
9 changes: 6 additions & 3 deletions Flow.Launcher.Plugin/PluginMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ public class PluginMetadata : BaseModel
public string Description { get; set; }
public string Website { get; set; }
public bool Disabled { get; set; }
public string ExecuteFilePath { get; private set;}

public string ApiEndpoint { get; set; }

public string ExecuteFilePath { get; private set; }

public string ExecuteFileName { get; set; }

Expand All @@ -35,8 +38,8 @@ internal set

public List<string> ActionKeywords { get; set; }

public string IcoPath { get; set;}
public string IcoPath { get; set; }

public override string ToString()
{
return Name;
Expand Down