Skip to content

Commit

Permalink
Merge pull request #2563 from Flow-Launcher/dev
Browse files Browse the repository at this point in the history
Release 1.17.2
  • Loading branch information
jjw24 authored Feb 12, 2024
2 parents b623295 + 2370ec9 commit 2f679e9
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 52 deletions.
19 changes: 15 additions & 4 deletions Flow.Launcher.Core/ExternalPlugins/CommunityPluginSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -16,6 +18,11 @@ public record CommunityPluginSource(string ManifestFileUrl)

private List<UserPlugin> plugins = new();

private static JsonSerializerOptions PluginStoreItemSerializationOption = new JsonSerializerOptions()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};

/// <summary>
/// Fetch and deserialize the contents of a plugins.json file found at <see cref="ManifestFileUrl"/>.
/// We use conditional http requests to keep repeat requests fast.
Expand All @@ -32,12 +39,15 @@ public async Task<List<UserPlugin>> FetchAsync(CancellationToken token)

request.Headers.Add("If-None-Match", latestEtag);

using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false);
using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token)
.ConfigureAwait(false);

if (response.StatusCode == HttpStatusCode.OK)
{
this.plugins = await response.Content.ReadFromJsonAsync<List<UserPlugin>>(cancellationToken: token).ConfigureAwait(false);
this.latestEtag = response.Headers.ETag.Tag;
this.plugins = await response.Content
.ReadFromJsonAsync<List<UserPlugin>>(PluginStoreItemSerializationOption, cancellationToken: token)
.ConfigureAwait(false);
this.latestEtag = response.Headers.ETag?.Tag;

Log.Info(nameof(CommunityPluginSource), $"Loaded {this.plugins.Count} plugins from {ManifestFileUrl}");
return this.plugins;
Expand All @@ -49,7 +59,8 @@ public async Task<List<UserPlugin>> FetchAsync(CancellationToken token)
}
else
{
Log.Warn(nameof(CommunityPluginSource), $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
Log.Warn(nameof(CommunityPluginSource),
$"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
throw new Exception($"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
}
}
Expand Down
4 changes: 2 additions & 2 deletions Flow.Launcher.Core/ExternalPlugins/UserPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public record UserPlugin
public string UrlDownload { get; set; }
public string UrlSourceCode { get; set; }
public string IcoPath { get; set; }
public DateTime LatestReleaseDate { get; set; }
public DateTime DateAdded { get; set; }
public DateTime? LatestReleaseDate { get; set; }
public DateTime? DateAdded { get; set; }

}
}
1 change: 1 addition & 0 deletions Flow.Launcher.Core/Flow.Launcher.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
<ItemGroup>
<PackageReference Include="Droplex" Version="1.7.0" />
<PackageReference Include="FSharp.Core" Version="7.0.401" />
<PackageReference Include="Meziantou.Framework.Win32.Jobs" Version="3.2.1" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageReference Include="squirrel.windows" Version="1.5.2" NoWarn="NU1701" />
<PackageReference Include="StreamJsonRpc" Version="2.17.8" />
Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task InitializeAsync()
_storage = new JsonStorage<ConcurrentDictionary<string, object>>(SettingPath);
Settings = await _storage.LoadAsync();

if (Settings != null || Configuration == null)
if (Configuration == null)
{
return;
}
Expand Down
5 changes: 3 additions & 2 deletions Flow.Launcher.Core/Plugin/NodePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,21 @@ public NodePlugin(string filename)

protected override Task<Stream> RequestAsync(JsonRPCRequestModel request, CancellationToken token = default)
{
_startInfo.ArgumentList[1] = JsonSerializer.Serialize(request);
_startInfo.ArgumentList[1] = JsonSerializer.Serialize(request, RequestSerializeOption);
return ExecuteAsync(_startInfo, token);
}

protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default)
{
// since this is not static, request strings will build up in ArgumentList if index is not specified
_startInfo.ArgumentList[1] = JsonSerializer.Serialize(rpcRequest);
_startInfo.ArgumentList[1] = JsonSerializer.Serialize(rpcRequest, RequestSerializeOption);
return Execute(_startInfo);
}

public override async Task InitAsync(PluginInitContext context)
{
_startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
_startInfo.ArgumentList.Add(string.Empty);
_startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
await base.InitAsync(context);
}
Expand Down
24 changes: 18 additions & 6 deletions Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,24 @@
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin;
using Meziantou.Framework.Win32;
using Nerdbank.Streams;

namespace Flow.Launcher.Core.Plugin
{
internal abstract class ProcessStreamPluginV2 : JsonRPCPluginV2
{
private static JobObject _jobObject = new JobObject();

static ProcessStreamPluginV2()
{
_jobObject.SetLimits(new JobObjectLimits()
{
Flags = JobObjectLimitFlags.KillOnJobClose | JobObjectLimitFlags.DieOnUnhandledException
});

_jobObject.AssignProcess(Process.GetCurrentProcess());
}

public override string SupportedLanguage { get; set; }
protected sealed override IDuplexPipe ClientPipe { get; set; }
Expand All @@ -30,22 +42,22 @@ public override async Task InitAsync(PluginInitContext context)

ClientProcess = Process.Start(StartInfo);
ArgumentNullException.ThrowIfNull(ClientProcess);

SetupPipe(ClientProcess);

ErrorStream = ClientProcess.StandardError;

await base.InitAsync(context);
}

private void SetupPipe(Process process)
{
var (reader, writer) = (PipeReader.Create(process.StandardOutput.BaseStream),
PipeWriter.Create(process.StandardInput.BaseStream));
ClientPipe = new DuplexPipe(reader, writer);
}


public override async Task ReloadDataAsync()
{
var oldProcess = ClientProcess;
Expand All @@ -57,8 +69,8 @@ public override async Task ReloadDataAsync()
await oldProcess.WaitForExitAsync();
oldProcess.Dispose();
}


public override async ValueTask DisposeAsync()
{
ClientProcess.Kill(true);
Expand Down
66 changes: 33 additions & 33 deletions Plugins/Flow.Launcher.Plugin.Sys/Languages/de.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,57 @@
<system:String x:Key="flowlauncher_plugin_sys_command">Befehl</system:String>
<system:String x:Key="flowlauncher_plugin_sys_desc">Beschreibung</system:String>

<system:String x:Key="flowlauncher_plugin_sys_shutdown_computer_cmd">Shutdown</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_computer_cmd">Restart</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_advanced_cmd">Restart With Advanced Boot Options</system:String>
<system:String x:Key="flowlauncher_plugin_sys_log_off_cmd">Log Off/Sign Out</system:String>
<system:String x:Key="flowlauncher_plugin_sys_lock_cmd">Lock</system:String>
<system:String x:Key="flowlauncher_plugin_sys_sleep_cmd">Sleep</system:String>
<system:String x:Key="flowlauncher_plugin_sys_hibernate_cmd">Hibernate</system:String>
<system:String x:Key="flowlauncher_plugin_sys_indexoption_cmd">Index Option</system:String>
<system:String x:Key="flowlauncher_plugin_sys_emptyrecyclebin_cmd">Empty Recycle Bin</system:String>
<system:String x:Key="flowlauncher_plugin_sys_openrecyclebin_cmd">Open Recycle Bin</system:String>
<system:String x:Key="flowlauncher_plugin_sys_shutdown_computer_cmd">Herunterfahren</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_computer_cmd">Neu starten</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_advanced_cmd">Neustart mit erweiterten Startoptionen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_log_off_cmd">Abmelden</system:String>
<system:String x:Key="flowlauncher_plugin_sys_lock_cmd">Sperren</system:String>
<system:String x:Key="flowlauncher_plugin_sys_sleep_cmd">Energie sparen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_hibernate_cmd">Ruhezustand</system:String>
<system:String x:Key="flowlauncher_plugin_sys_indexoption_cmd">Indizierungsoptionen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_emptyrecyclebin_cmd">Papierkorb leeren</system:String>
<system:String x:Key="flowlauncher_plugin_sys_openrecyclebin_cmd">Papierkorb öffnen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_exit_cmd">Schließen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_save_all_settings_cmd">Save Settings</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_cmd">Restart Flow Launcher&quot;</system:String>
<system:String x:Key="flowlauncher_plugin_sys_save_all_settings_cmd">Einstellungen speichern</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_cmd">Flow Launcher neu starten</system:String>
<system:String x:Key="flowlauncher_plugin_sys_setting_cmd">Einstellungen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_reload_plugin_data_cmd">Plugin-Daten neu laden</system:String>
<system:String x:Key="flowlauncher_plugin_sys_check_for_update_cmd">Check For Update</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_log_location_cmd">Open Log Location</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_docs_tips_cmd">Flow Launcher Tips</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_userdata_location_cmd">Flow Launcher UserData Folder</system:String>
<system:String x:Key="flowlauncher_plugin_sys_check_for_update_cmd">Auf Updates prüfen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_log_location_cmd">Log-Speicherort öffnen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_docs_tips_cmd">Flow Launcher Tipps</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_userdata_location_cmd">Flow Launcher Benutzerdaten-Ordner</system:String>
<system:String x:Key="flowlauncher_plugin_sys_toggle_game_mode_cmd">Gott Modus</system:String>

<!-- Command Descriptions -->
<system:String x:Key="flowlauncher_plugin_sys_shutdown_computer">Computer herunterfahren</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_computer">Computer neu starten</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_advanced">Restart the computer with Advanced Boot Options for Safe and Debugging modes, as well as other options</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart_advanced">Startet den Computer mit erweiterten Startoptionen für den abgesicherten Modus neu</system:String>
<system:String x:Key="flowlauncher_plugin_sys_log_off">Abmelden</system:String>
<system:String x:Key="flowlauncher_plugin_sys_lock">Computer sperren</system:String>
<system:String x:Key="flowlauncher_plugin_sys_exit">Flow Launcher schließen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_restart">Flow Launcher neu starten</system:String>
<system:String x:Key="flowlauncher_plugin_sys_setting">Tweak Flow Launcher's settings</system:String>
<system:String x:Key="flowlauncher_plugin_sys_setting">Einstellungen des Flow Launchers anpassen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_sleep">Computer in Schlafmodus versetzen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_emptyrecyclebin">Papierkorb leeren</system:String>
<system:String x:Key="flowlauncher_plugin_sys_openrecyclebin">Open recycle bin</system:String>
<system:String x:Key="flowlauncher_plugin_sys_indexoption">Indexierungsoptionen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_hibernate">Hibernate computer</system:String>
<system:String x:Key="flowlauncher_plugin_sys_save_all_settings">Save all Flow Launcher settings</system:String>
<system:String x:Key="flowlauncher_plugin_sys_reload_plugin_data">Refreshes plugin data with new content</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_log_location">Open Flow Launcher's log location</system:String>
<system:String x:Key="flowlauncher_plugin_sys_check_for_update">Check for new Flow Launcher update</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_docs_tips">Visit Flow Launcher's documentation for more help and how to use tips</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_userdata_location">Open the location where Flow Launcher's settings are stored</system:String>
<system:String x:Key="flowlauncher_plugin_sys_openrecyclebin">Papierkorb öffnen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_indexoption">Indizierungsoptionen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_hibernate">Computer in den Ruhezustand versetzen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_save_all_settings">Alle Flow Launcher Einstellungen speichern</system:String>
<system:String x:Key="flowlauncher_plugin_sys_reload_plugin_data">Aktualisiert Plugin-Daten mit neuen Inhalten</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_log_location">Öffnet den Speicherort der Flow Launcher Logs</system:String>
<system:String x:Key="flowlauncher_plugin_sys_check_for_update">Prüft auf neue Flow Launcher Updates</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_docs_tips">Öffnet die Dokumentation von Flow Launcher für Hilfe und Tipps</system:String>
<system:String x:Key="flowlauncher_plugin_sys_open_userdata_location">Öffnet den Ort an dem Flow Laucher Einstellungen speichert</system:String>
<system:String x:Key="flowlauncher_plugin_sys_toggle_game_mode">Gott Modus</system:String>

<!-- Dialogs -->
<system:String x:Key="flowlauncher_plugin_sys_dlgtitle_success">Erfolgreich</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_all_settings_saved">All Flow Launcher settings saved</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_all_applicableplugins_reloaded">Reloaded all applicable plugin data</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_shutdown_computer">Are you sure you want to shut the computer down?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_restart_computer">Are you sure you want to restart the computer?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_restart_computer_advanced">Are you sure you want to restart the computer with Advanced Boot Options?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_logoff_computer">Are you sure you want to log off?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_all_settings_saved">Alle Flow Launcher Einstellungen wurden gespeichert</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_all_applicableplugins_reloaded">Alle betroffenen Plugin-Daten wurden neu geladen</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_shutdown_computer">Soll der Computer wirklich heruntergefahren werden?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_restart_computer">Soll der Computer wirklich neu gestartet werden?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_restart_computer_advanced">Soll der Computer wirklich mit erweiterten Startoptionen neu gestartet werden?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_logoff_computer">Soll der aktuelle Benutzer wirklich abgemeldet werden?</system:String>

<system:String x:Key="flowlauncher_plugin_sys_plugin_name">Systembefehle</system:String>
<system:String x:Key="flowlauncher_plugin_sys_plugin_description">Stellt Systemrelevante Befehle bereit. z.B. herunterfahren, sperren, Einstellungen, usw.</system:String>
Expand Down
2 changes: 1 addition & 1 deletion Plugins/Flow.Launcher.Plugin.Sys/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Name": "System Commands",
"Description": "Provide System related commands. e.g. shutdown,lock, setting etc.",
"Author": "qianlifeng",
"Version": "3.1.0",
"Version": "3.1.1",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.Sys.dll",
Expand Down
3 changes: 2 additions & 1 deletion Plugins/Flow.Launcher.Plugin.WebSearch/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ public Settings()
public SuggestionSource[] Suggestions { get; set; } = {
new Google(),
new Baidu(),
new Bing()
new Bing(),
new DuckDuckGo()
};

[JsonIgnore]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Logger;
using System.Net.Http;
using System.Threading;
using System.Text.Json;

namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
{
public class DuckDuckGo : SuggestionSource
{
public override async Task<List<string>> SuggestionsAsync(string query, CancellationToken token)
{
// When the search query is empty, DuckDuckGo returns `[]`. When it's not empty, it returns data
// in the following format: `["query", ["suggestion1", "suggestion2", ...]]`.
if (string.IsNullOrEmpty(query))
{
return new List<string>();
}

try
{
const string api = "https://duckduckgo.com/ac/?type=list&q=";

await using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeDataString(query), token: token).ConfigureAwait(false);

using var json = await JsonDocument.ParseAsync(resultStream, cancellationToken: token);

var results = json.RootElement.EnumerateArray().ElementAt(1);

return results.EnumerateArray().Select(o => o.GetString()).ToList();

}
catch (Exception e) when (e is HttpRequestException or {InnerException: TimeoutException})
{
Log.Exception("|DuckDuckGo.Suggestions|Can't get suggestion from DuckDuckGo", e);
return null;
}
catch (JsonException e)
{
Log.Exception("|DuckDuckGo.Suggestions|can't parse suggestions", e);
return new List<string>();
}
}

public override string ToString()
{
return "DuckDuckGo";
}
}
}
2 changes: 1 addition & 1 deletion Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"Name": "Web Searches",
"Description": "Provide the web search ability",
"Author": "qianlifeng",
"Version": "3.0.6",
"Version": "3.0.7",
"Language": "csharp",
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
"ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '1.17.1.{build}'
version: '1.17.2.{build}'

init:
- ps: |
Expand Down

0 comments on commit 2f679e9

Please sign in to comment.