diff --git a/src/PipManager/Models/AppConfigModels/EnvironmentItem.cs b/src/PipManager/Models/AppConfigModels/EnvironmentItem.cs index 885384e..ac81b41 100644 --- a/src/PipManager/Models/AppConfigModels/EnvironmentItem.cs +++ b/src/PipManager/Models/AppConfigModels/EnvironmentItem.cs @@ -8,14 +8,16 @@ public EnvironmentItem() { } - public EnvironmentItem(string pipVersion, string pythonPath, string pythonVersion) + public EnvironmentItem(string pipVersion, string pythonPath, string pythonVersion, string pythonDllPath) { PipVersion = pipVersion; PythonPath = pythonPath; PythonVersion = pythonVersion; + PythonDllPath = pythonDllPath; } [JsonProperty("pipVersion")] public string? PipVersion { get; set; } [JsonProperty("pythonPath")] public string? PythonPath { get; set; } [JsonProperty("pythonVersion")] public string? PythonVersion { get; set; } + [JsonProperty("pythonDllPath")] public string? PythonDllPath { get; set; } } \ No newline at end of file diff --git a/src/PipManager/PipManager.csproj b/src/PipManager/PipManager.csproj index 0ef5769..3390e2c 100644 --- a/src/PipManager/PipManager.csproj +++ b/src/PipManager/PipManager.csproj @@ -32,6 +32,7 @@ + diff --git a/src/PipManager/Services/Configuration/ConfigurationService.cs b/src/PipManager/Services/Configuration/ConfigurationService.cs index bcd9d23..261de8e 100644 --- a/src/PipManager/Services/Configuration/ConfigurationService.cs +++ b/src/PipManager/Services/Configuration/ConfigurationService.cs @@ -73,16 +73,17 @@ public string FindPythonPathByPipDir(string pipDir) public EnvironmentItem? GetEnvironmentItem(string pythonPath) { var pythonVersion = FileVersionInfo.GetVersionInfo(pythonPath).FileVersion!; - var pythonDirectory = Directory.GetParent(pythonPath)!.FullName; - var pipDirectory = GetPipDirectories(pythonDirectory); - - if (pipDirectory == null) + var pythonDirectory = Directory.GetParent(pythonPath)!; + var pipDirectory = GetPipDirectories(pythonDirectory.FullName); + var pythonDllName = $"{pythonDirectory.Name.ToLower().Replace(".", "")}.dll"; + var pythonDllPath = pythonDirectory.GetFiles(pythonDllName, SearchOption.AllDirectories).FirstOrDefault(); + if (pythonDllPath == null || pipDirectory == null) { return null; } var pipVersion = GetPipVersionInInitFile().Match(File.ReadAllText(Path.Combine(pipDirectory, @"__init__.py"))).Groups[1].Value; - return new EnvironmentItem(pipVersion, pythonPath, pythonVersion); + return new EnvironmentItem(pipVersion, pythonPath, pythonVersion, pythonDllPath.FullName); } public EnvironmentItem? GetEnvironmentItemFromCommand(string command, string arguments) @@ -137,9 +138,12 @@ public string FindPythonPathByPipDir(string pipDir) } pipVersion = pipVersion.Trim(); var pythonPath = FindPythonPathByPipDir(pipDir.Trim()); + var pythonDirectory = Directory.GetParent(pythonPath)!; + var pythonDllName = $"{pythonDirectory.Name.ToLower().Replace(".", "")}.dll"; + var pythonDllPath = pythonDirectory.GetFiles(pythonDllName, SearchOption.AllDirectories).FirstOrDefault(); pythonVersion = pythonVersion.Trim(); proc.Close(); - return pipDir.Length > 0 ? new EnvironmentItem(pipVersion, pythonPath, pythonVersion) : null; + return pipDir.Length > 0 && pythonDllPath != null ? new EnvironmentItem(pipVersion, pythonPath, pythonVersion, pythonDllPath.FullName) : null; } public void RefreshAllEnvironmentVersions() diff --git a/src/PipManager/Services/Environment/EnvironmentService.cs b/src/PipManager/Services/Environment/EnvironmentService.cs index 262e313..88cd2e8 100644 --- a/src/PipManager/Services/Environment/EnvironmentService.cs +++ b/src/PipManager/Services/Environment/EnvironmentService.cs @@ -13,6 +13,7 @@ using System.IO; using System.Net.Http; using System.Text.RegularExpressions; +using Python.Runtime; using Wpf.Ui.Controls; using Path = System.IO.Path; @@ -222,6 +223,37 @@ public ActionResponse PurgeEnvironmentCache(EnvironmentItem environmentItem) return [.. packages.OrderBy(x => x.Name)]; } + public ParseRequirementsResponse ParseRequirements(IEnumerable requirements) + { + var parsedRequirements = new ParseRequirementsResponse { Success = true, Requirements = [] }; + Runtime.PythonDLL = configurationService.AppConfig.CurrentEnvironment!.PythonDllPath!; + PythonEngine.Initialize(); + using (Py.GIL()) + { + try + { + dynamic packagingModule = Py.Import("packaging.requirements"); + dynamic requirementClass = packagingModule.Requirement; + foreach (var requirement in requirements) + { + dynamic requirementParser = requirementClass(requirement); + parsedRequirements.Requirements.Add(new ParsedRequirement + { + Name = requirementParser.name.ToString(), + Specifier = requirementParser.specifier.ToString() + }); + } + } + catch (PythonException ex) + { + Log.Error(ex.Message); + } + + } + + return parsedRequirements; + } + public async Task GetVersions(string packageName) { try diff --git a/src/PipManager/Services/Environment/IEnvironmentService.cs b/src/PipManager/Services/Environment/IEnvironmentService.cs index a9e7bb9..3cc3693 100644 --- a/src/PipManager/Services/Environment/IEnvironmentService.cs +++ b/src/PipManager/Services/Environment/IEnvironmentService.cs @@ -17,6 +17,7 @@ public interface IEnvironmentService public Task GetVersions(string packageName); public bool TryKillProcess(); + public ParseRequirementsResponse ParseRequirements(IEnumerable requirements); public ActionResponse Install(string packageName, DataReceivedEventHandler consoleOutputCallback, string[]? extraParameters = null); diff --git a/src/PipManager/Services/Environment/Response/ParseRequirementsResponse.cs b/src/PipManager/Services/Environment/Response/ParseRequirementsResponse.cs new file mode 100644 index 0000000..60d28ce --- /dev/null +++ b/src/PipManager/Services/Environment/Response/ParseRequirementsResponse.cs @@ -0,0 +1,13 @@ +namespace PipManager.Services.Environment.Response; + +public class ParseRequirementsResponse +{ + public bool Success { get; init; } + public List? Requirements { get; init; } +} + +public class ParsedRequirement +{ + public required string Name { get; init; } + public required string Specifier { get; init; } +} diff --git a/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs b/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs index c34112b..203eaf4 100644 --- a/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs @@ -1,15 +1,28 @@ -using PipManager.Models.Action; +using System.IO; +using System.Windows.Shapes; +using Microsoft.Extensions.Configuration; +using PipManager.Models.Action; using PipManager.Services.Action; +using PipManager.Services.Configuration; +using PipManager.Services.Environment; +using Python.Runtime; using Serilog; using Wpf.Ui.Controls; namespace PipManager.ViewModels.Pages.Lab; -public partial class LabViewModel(IActionService actionService) +public partial class LabViewModel(IActionService actionService, IEnvironmentService environmentService) : ObservableObject, INavigationAware { private bool _isInitialized; + [RelayCommand] + private void ParseTest() + { + var parsed = environmentService.ParseRequirements(["requests", "numpy"]); + parsed.Requirements.ForEach(item => Log.Information(item.Specifier)); + } + [RelayCommand] private void ActionTest() { diff --git a/src/PipManager/Views/Pages/Lab/LabPage.xaml b/src/PipManager/Views/Pages/Lab/LabPage.xaml index 09b4493..185df6f 100644 --- a/src/PipManager/Views/Pages/Lab/LabPage.xaml +++ b/src/PipManager/Views/Pages/Lab/LabPage.xaml @@ -18,5 +18,6 @@ mc:Ignorable="d"> + \ No newline at end of file