Skip to content

Commit 2d90481

Browse files
authored
Merge branch 'dev' into dependabot/nuget/nunit-4.3.2
2 parents 4b9c23d + e028ed3 commit 2d90481

File tree

89 files changed

+1369
-645
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+1369
-645
lines changed

Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Flow.Launcher.Infrastructure.Logger;
1+
using Flow.Launcher.Infrastructure.Logger;
22
using System;
33
using System.Collections.Generic;
44
using System.Threading;
@@ -21,7 +21,7 @@ public static class PluginsManifest
2121

2222
public static List<UserPlugin> UserPlugins { get; private set; }
2323

24-
public static async Task UpdateManifestAsync(CancellationToken token = default, bool usePrimaryUrlOnly = false)
24+
public static async Task<bool> UpdateManifestAsync(CancellationToken token = default, bool usePrimaryUrlOnly = false)
2525
{
2626
try
2727
{
@@ -31,8 +31,14 @@ public static async Task UpdateManifestAsync(CancellationToken token = default,
3131
{
3232
var results = await mainPluginStore.FetchAsync(token, usePrimaryUrlOnly).ConfigureAwait(false);
3333

34-
UserPlugins = results;
35-
lastFetchedAt = DateTime.Now;
34+
// If the results are empty, we shouldn't update the manifest because the results are invalid.
35+
if (results.Count != 0)
36+
{
37+
UserPlugins = results;
38+
lastFetchedAt = DateTime.Now;
39+
40+
return true;
41+
}
3642
}
3743
}
3844
catch (Exception e)
@@ -43,6 +49,8 @@ public static async Task UpdateManifestAsync(CancellationToken token = default,
4349
{
4450
manifestUpdateLock.Release();
4551
}
52+
53+
return false;
4654
}
4755
}
4856
}

Flow.Launcher.Core/Flow.Launcher.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
<ItemGroup>
5656
<PackageReference Include="Droplex" Version="1.7.0" />
57-
<PackageReference Include="FSharp.Core" Version="9.0.100" />
57+
<PackageReference Include="FSharp.Core" Version="9.0.101" />
5858
<PackageReference Include="Meziantou.Framework.Win32.Jobs" Version="3.4.0" />
5959
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
6060
<PackageReference Include="squirrel.windows" Version="1.5.2" NoWarn="NU1701" />

Flow.Launcher.Core/MessageBoxEx.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
Foreground="{DynamicResource PopupTextColor}"
1313
ResizeMode="NoResize"
1414
SizeToContent="Height"
15+
Topmost="True"
1516
WindowStartupLocation="CenterScreen"
1617
mc:Ignorable="d">
1718
<WindowChrome.WindowChrome>

Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void Save()
112112
public Control CreateSettingPanel()
113113
{
114114
if (Settings == null || Settings.Count == 0)
115-
return new();
115+
return null;
116116

117117
var settingWindow = new UserControl();
118118
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };

Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,54 +26,33 @@ internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, I
2626

2727
protected override async Task<bool> ExecuteResultAsync(JsonRPCResult result)
2828
{
29-
try
30-
{
31-
var res = await RPC.InvokeAsync<JsonRPCExecuteResponse>(result.JsonRPCAction.Method,
32-
argument: result.JsonRPCAction.Parameters);
29+
var res = await RPC.InvokeAsync<JsonRPCExecuteResponse>(result.JsonRPCAction.Method,
30+
argument: result.JsonRPCAction.Parameters);
3331

34-
return res.Hide;
35-
}
36-
catch
37-
{
38-
return false;
39-
}
32+
return res.Hide;
4033
}
4134

4235
private JoinableTaskFactory JTF { get; } = new JoinableTaskFactory(new JoinableTaskContext());
4336

4437
public override List<Result> LoadContextMenus(Result selectedResult)
4538
{
46-
try
47-
{
48-
var res = JTF.Run(() => RPC.InvokeWithCancellationAsync<JsonRPCQueryResponseModel>("context_menu",
49-
new object[] { selectedResult.ContextData }));
39+
var res = JTF.Run(() => RPC.InvokeWithCancellationAsync<JsonRPCQueryResponseModel>("context_menu",
40+
new object[] { selectedResult.ContextData }));
5041

51-
var results = ParseResults(res);
42+
var results = ParseResults(res);
5243

53-
return results;
54-
}
55-
catch
56-
{
57-
return new List<Result>();
58-
}
44+
return results;
5945
}
6046

6147
public override async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
6248
{
63-
try
64-
{
65-
var res = await RPC.InvokeWithCancellationAsync<JsonRPCQueryResponseModel>("query",
66-
new object[] { query, Settings.Inner },
67-
token);
49+
var res = await RPC.InvokeWithCancellationAsync<JsonRPCQueryResponseModel>("query",
50+
new object[] { query, Settings.Inner },
51+
token);
6852

69-
var results = ParseResults(res);
53+
var results = ParseResults(res);
7054

71-
return results;
72-
}
73-
catch
74-
{
75-
return new List<Result>();
76-
}
55+
return results;
7756
}
7857

7958

Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.ComponentModel;
43
using System.Diagnostics.CodeAnalysis;
54
using System.IO;
65
using System.Runtime.CompilerServices;
@@ -121,10 +120,10 @@ public Task<Stream> HttpGetStreamAsync(string url, CancellationToken token = def
121120
return _api.HttpGetStreamAsync(url, token);
122121
}
123122

124-
public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath,
123+
public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action<double> reportProgress = null,
125124
CancellationToken token = default)
126125
{
127-
return _api.HttpDownloadAsync(url, filePath, token);
126+
return _api.HttpDownloadAsync(url, filePath, reportProgress, token);
128127
}
129128

130129
public void AddActionKeyword(string pluginId, string newActionKeyword)
@@ -162,16 +161,19 @@ public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null
162161
_api.OpenDirectory(DirectoryPath, FileNameOrFilePath);
163162
}
164163

165-
166164
public void OpenUrl(string url, bool? inPrivate = null)
167165
{
168166
_api.OpenUrl(url, inPrivate);
169167
}
170168

171-
172169
public void OpenAppUri(string appUri)
173170
{
174171
_api.OpenAppUri(appUri);
175172
}
173+
174+
public void BackToQueryResults()
175+
{
176+
_api.BackToQueryResults();
177+
}
176178
}
177179
}

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Quer
281281
return results;
282282
}
283283

284-
public static void UpdatePluginMetadata(List<Result> results, PluginMetadata metadata, Query query)
284+
public static void UpdatePluginMetadata(IReadOnlyList<Result> results, PluginMetadata metadata, Query query)
285285
{
286286
foreach (var r in results)
287287
{

Flow.Launcher.Core/Plugin/PythonPlugin.cs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Diagnostics;
1+
using System;
2+
using System.Diagnostics;
23
using System.IO;
34
using System.Text.Json;
45
using System.Threading;
@@ -25,14 +26,13 @@ public PythonPlugin(string filename)
2526

2627
var path = Path.Combine(Constant.ProgramDirectory, JsonRPC);
2728
_startInfo.EnvironmentVariables["PYTHONPATH"] = path;
29+
// Prevent Python from writing .py[co] files.
30+
// Because .pyc contains location infos which will prevent python portable.
31+
_startInfo.EnvironmentVariables["PYTHONDONTWRITEBYTECODE"] = "1";
2832

2933
_startInfo.EnvironmentVariables["FLOW_VERSION"] = Constant.Version;
3034
_startInfo.EnvironmentVariables["FLOW_PROGRAM_DIRECTORY"] = Constant.ProgramDirectory;
3135
_startInfo.EnvironmentVariables["FLOW_APPLICATION_DIRECTORY"] = Constant.ApplicationDirectory;
32-
33-
34-
//Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
35-
_startInfo.ArgumentList.Add("-B");
3636
}
3737

3838
protected override Task<Stream> RequestAsync(JsonRPCRequestModel request, CancellationToken token = default)
@@ -50,10 +50,53 @@ protected override string Request(JsonRPCRequestModel rpcRequest, CancellationTo
5050
// TODO: Async Action
5151
return Execute(_startInfo);
5252
}
53+
5354
public override async Task InitAsync(PluginInitContext context)
5455
{
55-
_startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
56-
_startInfo.ArgumentList.Add("");
56+
// Run .py files via `-c <code>`
57+
if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
58+
{
59+
var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
60+
var libDirectory = Path.Combine(rootDirectory, "lib");
61+
var libPyWin32Directory = Path.Combine(libDirectory, "win32");
62+
var libPyWin32LibDirectory = Path.Combine(libPyWin32Directory, "lib");
63+
var pluginDirectory = Path.Combine(rootDirectory, "plugin");
64+
65+
// This makes it easier for plugin authors to import their own modules.
66+
// They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
67+
// Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
68+
// This code sets sys.path for the plugin author and then runs the .py file via runpy.
69+
_startInfo.ArgumentList.Add("-c");
70+
_startInfo.ArgumentList.Add(
71+
$"""
72+
import sys
73+
sys.path.append(r'{rootDirectory}')
74+
sys.path.append(r'{libDirectory}')
75+
sys.path.append(r'{libPyWin32LibDirectory}')
76+
sys.path.append(r'{libPyWin32Directory}')
77+
sys.path.append(r'{pluginDirectory}')
78+
79+
import runpy
80+
runpy.run_path(r'{context.CurrentPluginMetadata.ExecuteFilePath}', None, '__main__')
81+
"""
82+
);
83+
// Plugins always expect the JSON data to be in the third argument
84+
// (we're always setting it as _startInfo.ArgumentList[2] = ...).
85+
_startInfo.ArgumentList.Add("");
86+
}
87+
// Run .pyz files as is
88+
else
89+
{
90+
// No need for -B flag because we're using PYTHONDONTWRITEBYTECODE env variable now,
91+
// but the plugins still expect data to be sent as the third argument, so we're keeping
92+
// the flag here, even though it's not necessary anymore.
93+
_startInfo.ArgumentList.Add("-B");
94+
_startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
95+
// Plugins always expect the JSON data to be in the third argument
96+
// (we're always setting it as _startInfo.ArgumentList[2] = ...).
97+
_startInfo.ArgumentList.Add("");
98+
}
99+
57100
await base.InitAsync(context);
58101
_startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
59102
}

Flow.Launcher.Core/Plugin/PythonPluginV2.cs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,45 @@ public PythonPluginV2(string filename)
2626

2727
var path = Path.Combine(Constant.ProgramDirectory, JsonRpc);
2828
StartInfo.EnvironmentVariables["PYTHONPATH"] = path;
29-
30-
//Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
31-
StartInfo.ArgumentList.Add("-B");
29+
StartInfo.EnvironmentVariables["PYTHONDONTWRITEBYTECODE"] = "1";
3230
}
3331

3432
public override async Task InitAsync(PluginInitContext context)
3533
{
36-
StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
34+
// Run .py files via `-c <code>`
35+
if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
36+
{
37+
var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
38+
var libDirectory = Path.Combine(rootDirectory, "lib");
39+
var libPyWin32Directory = Path.Combine(libDirectory, "win32");
40+
var libPyWin32LibDirectory = Path.Combine(libPyWin32Directory, "lib");
41+
var pluginDirectory = Path.Combine(rootDirectory, "plugin");
42+
var filePath = context.CurrentPluginMetadata.ExecuteFilePath;
43+
44+
// This makes it easier for plugin authors to import their own modules.
45+
// They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
46+
// Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
47+
// This code sets sys.path for the plugin author and then runs the .py file via runpy.
48+
StartInfo.ArgumentList.Add("-c");
49+
StartInfo.ArgumentList.Add(
50+
$"""
51+
import sys
52+
sys.path.append(r'{rootDirectory}')
53+
sys.path.append(r'{libDirectory}')
54+
sys.path.append(r'{libPyWin32LibDirectory}')
55+
sys.path.append(r'{libPyWin32Directory}')
56+
sys.path.append(r'{pluginDirectory}')
57+
58+
import runpy
59+
runpy.run_path(r'{filePath}', None, '__main__')
60+
"""
61+
);
62+
}
63+
// Run .pyz files as is
64+
else
65+
{
66+
StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
67+
}
3768
await base.InitAsync(context);
3869
}
3970

Flow.Launcher.Core/Resource/AvailableLanguages.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ internal static class AvailableLanguages
3030
public static Language Vietnamese = new Language("vi-vn", "Tiếng Việt");
3131
public static Language Hebrew = new Language("he", "עברית");
3232

33-
3433
public static List<Language> GetAvailableLanguages()
3534
{
3635
List<Language> languages = new List<Language>
@@ -63,5 +62,38 @@ public static List<Language> GetAvailableLanguages()
6362
};
6463
return languages;
6564
}
65+
66+
public static string GetSystemTranslation(string languageCode)
67+
{
68+
return languageCode switch
69+
{
70+
"en" => "System",
71+
"zh-cn" => "系统",
72+
"zh-tw" => "系統",
73+
"uk-UA" => "Система",
74+
"ru" => "Система",
75+
"fr" => "Système",
76+
"ja" => "システム",
77+
"nl" => "Systeem",
78+
"pl" => "System",
79+
"da" => "System",
80+
"de" => "System",
81+
"ko" => "시스템",
82+
"sr" => "Систем",
83+
"pt-pt" => "Sistema",
84+
"pt-br" => "Sistema",
85+
"es" => "Sistema",
86+
"es-419" => "Sistema",
87+
"it" => "Sistema",
88+
"nb-NO" => "System",
89+
"sk" => "Systém",
90+
"tr" => "Sistem",
91+
"cs" => "Systém",
92+
"ar" => "النظام",
93+
"vi-vn" => "Hệ thống",
94+
"he" => "מערכת",
95+
_ => "System",
96+
};
97+
}
6698
}
6799
}

0 commit comments

Comments
 (0)