Skip to content

Commit 4e48c3e

Browse files
committed
refactor
1 parent c7cee4a commit 4e48c3e

File tree

10 files changed

+282
-294
lines changed

10 files changed

+282
-294
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using Flow.Launcher.Core.Plugin;
2+
using Flow.Launcher.Infrastructure.Logger;
3+
using Flow.Launcher.Infrastructure.UserSettings;
4+
using Flow.Launcher.Plugin;
5+
using Flow.Launcher.Plugin.SharedCommands;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Windows.Forms;
10+
11+
namespace Flow.Launcher.Core.ExternalPlugins.Environments
12+
{
13+
internal abstract class AbstractPluginEnvironment
14+
{
15+
internal abstract string Language { get; }
16+
17+
internal const string Environments = "Environments";
18+
19+
internal abstract string EnvName { get; }
20+
21+
internal abstract string EnvPath { get; }
22+
23+
internal abstract string InstallPath { get; }
24+
25+
internal abstract string ExecutablePath { get; }
26+
27+
internal virtual string FileDialogFilter => string.Empty;
28+
29+
internal abstract string PluginsSettingsFilePath { get; set; }
30+
31+
internal List<PluginMetadata> PluginMetadataList;
32+
33+
internal PluginsSettings PluginSettings;
34+
35+
internal AbstractPluginEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings)
36+
{
37+
PluginMetadataList = pluginMetadataList;
38+
PluginSettings = pluginSettings;
39+
}
40+
//TODO: CHECK IF NEED TO RESET PATH AFTER FLOW UPDATE
41+
internal IEnumerable<PluginPair> Setup()
42+
{
43+
if (!PluginMetadataList.Any(o => o.Language.Equals(Language, StringComparison.OrdinalIgnoreCase)))
44+
return new List<PluginPair>();
45+
46+
if (!string.IsNullOrEmpty(PluginsSettingsFilePath) && FilesFolders.FileExists(PluginsSettingsFilePath))
47+
{
48+
EnsureLatestInstalled(ExecutablePath, PluginsSettingsFilePath, EnvPath);
49+
50+
return SetPathForPluginPairs(PluginsSettingsFilePath, Language);
51+
}
52+
53+
if (MessageBox.Show($"Flow detected you have installed {Language} plugins, which " +
54+
$"will require {EnvName} to run. Would you like to download {EnvName}? " +
55+
Environment.NewLine + Environment.NewLine +
56+
"Click no if it's already installed, " +
57+
$"and you will be prompted to select the folder that contains the {EnvName} executable",
58+
string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
59+
{
60+
var msg = $"Please select the {EnvName} executable";
61+
var selectedFile = string.Empty;
62+
63+
selectedFile = GetFileFromDialog(msg, FileDialogFilter);
64+
65+
if (!string.IsNullOrEmpty(selectedFile))
66+
PluginsSettingsFilePath = selectedFile;
67+
68+
// Nothing selected because user pressed cancel from the file dialog window
69+
if (string.IsNullOrEmpty(selectedFile))
70+
InstallEnvironment();
71+
}
72+
else
73+
{
74+
InstallEnvironment();
75+
}
76+
77+
if (FilesFolders.FileExists(PluginsSettingsFilePath))
78+
{
79+
return SetPathForPluginPairs(PluginsSettingsFilePath, Language);
80+
}
81+
else
82+
{
83+
MessageBox.Show(
84+
$"Unable to set {Language} executable path, please try from Flow's settings (scroll down to the bottom).");
85+
Log.Error("PluginsLoader",
86+
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
87+
$"{Language}Environment");
88+
89+
return new List<PluginPair>();
90+
}
91+
}
92+
93+
internal abstract void InstallEnvironment();
94+
95+
private void EnsureLatestInstalled(string expectedPath, string currentPath, string installedDirPath)
96+
{
97+
if (expectedPath == currentPath)
98+
return;
99+
100+
FilesFolders.RemoveFolderIfExists(installedDirPath);
101+
102+
InstallEnvironment();
103+
104+
}
105+
106+
private IEnumerable<PluginPair> SetPathForPluginPairs(string filePath, string languageToSet)
107+
{
108+
var pluginPairs = new List<PluginPair>();
109+
110+
foreach (var metadata in PluginMetadataList)
111+
{
112+
if (metadata.Language.Equals(languageToSet, StringComparison.OrdinalIgnoreCase))
113+
{
114+
pluginPairs.Add(new PluginPair
115+
{
116+
Plugin = new PythonPlugin(filePath),
117+
Metadata = metadata
118+
});
119+
}
120+
}
121+
122+
return pluginPairs;
123+
}
124+
125+
private string GetFileFromDialog(string title, string filter = "")
126+
{
127+
var dlg = new OpenFileDialog
128+
{
129+
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
130+
Multiselect = false,
131+
CheckFileExists = true,
132+
CheckPathExists = true,
133+
Title = title,
134+
Filter = filter
135+
};
136+
137+
var result = dlg.ShowDialog();
138+
if (result == DialogResult.OK)
139+
{
140+
return dlg.FileName;
141+
}
142+
else
143+
{
144+
return string.Empty;
145+
}
146+
}
147+
}
148+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
using Flow.Launcher.Infrastructure.UserSettings;
3+
using Flow.Launcher.Plugin;
4+
5+
namespace Flow.Launcher.Core.ExternalPlugins.Environments
6+
{
7+
8+
internal class JavaScriptEnvironment : TypeScriptEnvironment
9+
{
10+
internal override string Language => AllowedLanguage.JavaScript;
11+
12+
internal JavaScriptEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
13+
}
14+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using Droplex;
2+
using Flow.Launcher.Infrastructure.UserSettings;
3+
using Flow.Launcher.Plugin;
4+
using Flow.Launcher.Plugin.SharedCommands;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
8+
namespace Flow.Launcher.Core.ExternalPlugins.Environments
9+
{
10+
internal class PythonEnvironment : AbstractPluginEnvironment
11+
{
12+
internal override string Language => AllowedLanguage.Python;
13+
14+
internal override string EnvName => "Python";
15+
16+
internal override string EnvPath => Path.Combine(DataLocation.DataDirectory(), Environments, EnvName);
17+
18+
internal override string InstallPath => Path.Combine(EnvPath, "PythonEmbeddable-v3.8.9");
19+
20+
internal override string ExecutablePath => Path.Combine(InstallPath, "pythonw.exe");
21+
22+
internal override string FileDialogFilter => "Python|pythonw.exe";
23+
24+
internal override string PluginsSettingsFilePath { get => PluginSettings.PythonExecutablePath; set => PluginSettings.PythonExecutablePath = value; }
25+
26+
internal PythonEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
27+
28+
internal override void InstallEnvironment()
29+
{
30+
FilesFolders.RemoveFolderIfExists(InstallPath);
31+
32+
// Python 3.8.9 is used for Windows 7 compatibility
33+
DroplexPackage.Drop(App.python_3_8_9_embeddable, InstallPath).Wait();
34+
35+
PluginsSettingsFilePath = ExecutablePath;
36+
}
37+
}
38+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Collections.Generic;
2+
using Droplex;
3+
using Flow.Launcher.Infrastructure.UserSettings;
4+
using Flow.Launcher.Plugin.SharedCommands;
5+
using Flow.Launcher.Plugin;
6+
using System.IO;
7+
8+
namespace Flow.Launcher.Core.ExternalPlugins.Environments
9+
{
10+
internal class TypeScriptEnvironment : AbstractPluginEnvironment
11+
{
12+
internal override string Language => AllowedLanguage.TypeScript;
13+
14+
internal override string EnvName => "Node.js";
15+
16+
internal override string EnvPath => Path.Combine(DataLocation.DataDirectory(), Environments, EnvName);
17+
18+
internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
19+
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");
20+
21+
internal override string PluginsSettingsFilePath { get => PluginSettings.NodeExecutablePath; set => PluginSettings.NodeExecutablePath = value; }
22+
23+
internal TypeScriptEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
24+
25+
internal override void InstallEnvironment()
26+
{
27+
FilesFolders.RemoveFolderIfExists(InstallPath);
28+
29+
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
30+
31+
PluginsSettingsFilePath = ExecutablePath;
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)