-
-
Notifications
You must be signed in to change notification settings - Fork 455
Automatic Python installation for Python plugins #319
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
Changes from all commits
4933a2e
39229e5
385fabe
f3d0b88
c714167
20f895c
416ad3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,13 +3,14 @@ | |
| using System.IO; | ||
| using System.Linq; | ||
| using System.Reflection; | ||
| using System.Runtime.Loader; | ||
| using System.Threading.Tasks; | ||
| using System.Windows.Forms; | ||
| using Droplex; | ||
| using Flow.Launcher.Infrastructure; | ||
| using Flow.Launcher.Infrastructure.Logger; | ||
| using Flow.Launcher.Infrastructure.UserSettings; | ||
| using Flow.Launcher.Plugin; | ||
| using Flow.Launcher.Plugin.SharedCommands; | ||
|
|
||
| namespace Flow.Launcher.Core.Plugin | ||
| { | ||
|
|
@@ -22,7 +23,7 @@ public static class PluginsLoader | |
| public static List<PluginPair> Plugins(List<PluginMetadata> metadatas, PluginsSettings settings) | ||
| { | ||
| var dotnetPlugins = DotNetPlugins(metadatas); | ||
| var pythonPlugins = PythonPlugins(metadatas, settings.PythonDirectory); | ||
| var pythonPlugins = PythonPlugins(metadatas, settings); | ||
| var executablePlugins = ExecutablePlugins(metadatas); | ||
| var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList(); | ||
| return plugins; | ||
|
|
@@ -113,11 +114,14 @@ public static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source) | |
| return plugins; | ||
| } | ||
|
|
||
| public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source, string pythonDirectory) | ||
| public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source, PluginsSettings settings) | ||
| { | ||
| // try to set Constant.PythonPath, either from | ||
| if (!source.Any(o => o.Language.ToUpper() == AllowedLanguage.Python)) | ||
| return new List<PluginPair>(); | ||
|
|
||
| // Try setting Constant.PythonPath first, either from | ||
| // PATH or from the given pythonDirectory | ||
| if (string.IsNullOrEmpty(pythonDirectory)) | ||
| if (string.IsNullOrEmpty(settings.PythonDirectory)) | ||
| { | ||
| var paths = Environment.GetEnvironmentVariable(PATH); | ||
| if (paths != null) | ||
|
|
@@ -129,47 +133,103 @@ public static IEnumerable<PluginPair> PythonPlugins(List<PluginMetadata> source, | |
|
|
||
| if (pythonInPath) | ||
| { | ||
| Constant.PythonPath = PythonExecutable; | ||
| Constant.PythonPath = | ||
| Path.Combine(paths.Split(';').Where(p => p.ToLower().Contains(Python)).FirstOrDefault(), PythonExecutable); | ||
| settings.PythonDirectory = FilesFolders.GetPreviousExistingDirectory(FilesFolders.LocationExists, Constant.PythonPath); | ||
| } | ||
| else | ||
| { | ||
| Log.Error("|PluginsLoader.PythonPlugins|Python can't be found in PATH."); | ||
| Log.Error("PluginsLoader","Failed to set Python path despite the environment variable PATH is found", "PythonPlugins"); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| Log.Error("|PluginsLoader.PythonPlugins|PATH environment variable is not set."); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| var path = Path.Combine(pythonDirectory, PythonExecutable); | ||
| var path = Path.Combine(settings.PythonDirectory, PythonExecutable); | ||
| if (File.Exists(path)) | ||
| { | ||
| Constant.PythonPath = path; | ||
| } | ||
| else | ||
| { | ||
| Log.Error($"|PluginsLoader.PythonPlugins|Can't find python executable in {path}"); | ||
| Log.Error("PluginsLoader",$"Tried to automatically set from Settings.PythonDirectory " + | ||
| $"but can't find python executable in {path}", "PythonPlugins"); | ||
| } | ||
| } | ||
|
|
||
| // if we have a path to the python executable, | ||
| // load every python plugin pair. | ||
| if (String.IsNullOrEmpty(Constant.PythonPath)) | ||
| if (string.IsNullOrEmpty(settings.PythonDirectory)) | ||
| { | ||
| return new List<PluginPair>(); | ||
| if (MessageBox.Show("Flow detected you have installed Python plugins, " + | ||
| "would you like to install Python to run them? " + | ||
| Environment.NewLine + Environment.NewLine + | ||
| "Click no if it's already installed, " + | ||
| "and you will be prompted to select the folder that contains the Python executable", | ||
| string.Empty, MessageBoxButtons.YesNo) == DialogResult.No | ||
| && string.IsNullOrEmpty(settings.PythonDirectory)) | ||
| { | ||
| var dlg = new FolderBrowserDialog | ||
| { | ||
| SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) | ||
| }; | ||
|
|
||
| var result = dlg.ShowDialog(); | ||
| if (result == DialogResult.OK) | ||
| { | ||
| string pythonDirectory = dlg.SelectedPath; | ||
| if (!string.IsNullOrEmpty(pythonDirectory)) | ||
| { | ||
| var pythonPath = Path.Combine(pythonDirectory, PythonExecutable); | ||
| if (File.Exists(pythonPath)) | ||
| { | ||
| settings.PythonDirectory = pythonDirectory; | ||
| Constant.PythonPath = pythonPath; | ||
| } | ||
| else | ||
| { | ||
| MessageBox.Show("Can't find python in given directory"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| else | ||
| { | ||
| DroplexPackage.Drop(App.python3_9_1).Wait(); | ||
|
|
||
| var installedPythonDirectory = | ||
| Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Programs\Python\Python39"); | ||
| var pythonPath = Path.Combine(installedPythonDirectory, PythonExecutable); | ||
| if (FilesFolders.FileExists(pythonPath)) | ||
| { | ||
| settings.PythonDirectory = installedPythonDirectory; | ||
| Constant.PythonPath = pythonPath; | ||
| } | ||
| else | ||
| { | ||
| Log.Error("PluginsLoader", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if user choose to install python on other path instead of the default path? I think we should allow selection if that it not found.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is to auto set path after auto install. Users can choose the path before hand
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I mean what if user don't choose to install python on the default path?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Happy Chinese New Year @taooceros :) The installation will just install to the default location, it's a passive install, no prompt for install location
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Happy New Year!!! 😃😃 |
||
| $"Failed to set Python path after Droplex install, {pythonPath} does not exist", | ||
| "PythonPlugins"); | ||
| } | ||
| } | ||
| } | ||
| else | ||
|
|
||
| if (string.IsNullOrEmpty(settings.PythonDirectory)) | ||
| { | ||
| return source | ||
| .Where(o => o.Language.ToUpper() == AllowedLanguage.Python) | ||
| .Select(metadata => new PluginPair | ||
| { | ||
| Plugin = new PythonPlugin(Constant.PythonPath), | ||
| Metadata = metadata | ||
| }); | ||
| MessageBox.Show("Unable to set Python executable path, please try from Flow's settings (scroll down to the bottom)."); | ||
| Log.Error("PluginsLoader", | ||
| $"Not able to successfully set Python path, the PythonDirectory variable is still an empty string.", | ||
| "PythonPlugins"); | ||
|
|
||
| return new List<PluginPair>(); | ||
| } | ||
|
|
||
| return source | ||
| .Where(o => o.Language.ToUpper() == AllowedLanguage.Python) | ||
| .Select(metadata => new PluginPair | ||
| { | ||
| Plugin = new PythonPlugin(Constant.PythonPath), | ||
| Metadata = metadata | ||
| }) | ||
| .ToList(); | ||
| } | ||
|
|
||
| public static IEnumerable<PluginPair> ExecutablePlugins(IEnumerable<PluginMetadata> source) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.