From a372d660273d9d6a425a1feac5866481540ee645 Mon Sep 17 00:00:00 2001 From: AuroraZiling <2935876049@qq.com> Date: Fri, 29 Mar 2024 20:21:59 +0800 Subject: [PATCH 01/15] build: change auto build action branch --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b65071e..f65b9ef 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: "PipManager Continuous Integration" on: push: branches: - - main + - development jobs: build: From 21fd9e6b6e1232a87121ea256e82655544c579c3 Mon Sep 17 00:00:00 2001 From: AuroraZiling <2935876049@qq.com> Date: Sat, 30 Mar 2024 19:01:20 +0800 Subject: [PATCH 02/15] perf: better console output --- .../Services/Action/ActionService.cs | 53 ++++++++++++++++--- .../ViewModels/Pages/Lab/LabViewModel.cs | 2 +- .../Views/Pages/Action/ActionPage.xaml | 12 ++++- .../Views/Pages/Action/ActionPage.xaml.cs | 5 ++ 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/PipManager/Services/Action/ActionService.cs b/src/PipManager/Services/Action/ActionService.cs index 318bc41..f9f2183 100644 --- a/src/PipManager/Services/Action/ActionService.cs +++ b/src/PipManager/Services/Action/ActionService.cs @@ -31,7 +31,8 @@ public void Runner() var errorDetection = false; var consoleError = new StringBuilder(512); var currentAction = ActionList[0]; - currentAction.ConsoleOutput = Lang.Action_CurrentStatus_WaitingInQueue + '\n'; + var currentActionRunning = false; + currentAction.ConsoleOutput = Lang.Action_CurrentStatus_WaitingInQueue; switch (currentAction.OperationType) { case ActionType.Uninstall: @@ -42,7 +43,15 @@ public void Runner() currentAction.OperationStatus = $"Uninstalling {item}"; var result = environmentService.Uninstall(item, (sender, eventArgs) => { - currentAction.ConsoleOutput += string.IsNullOrEmpty(eventArgs.Data) ? Lang.Action_CurrentStatus_WaitingInQueue : eventArgs.Data.Trim() + '\n'; + if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput = eventArgs.Data.Trim(); + currentActionRunning = true; + } + else if (!string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput += '\n' + eventArgs.Data.Trim(); + } }); currentAction.CompletedSubTaskNumber++; Log.Information(result.Success @@ -61,7 +70,15 @@ public void Runner() currentAction.OperationStatus = $"Installing {item}"; var result = environmentService.Install(item, (sender, eventArgs) => { - currentAction.ConsoleOutput += string.IsNullOrEmpty(eventArgs.Data) ? Lang.Action_CurrentStatus_WaitingInQueue : eventArgs.Data.Trim() + '\n'; + if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput = eventArgs.Data.Trim(); + currentActionRunning = true; + } + else if (!string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput += '\n' + eventArgs.Data.Trim(); + } }); currentAction.CompletedSubTaskNumber++; if (!result.Success) @@ -84,7 +101,15 @@ public void Runner() currentAction.OperationStatus = $"Installing from requirements.txt"; var result = environmentService.InstallByRequirements(requirementsTempFilePath, (sender, eventArgs) => { - currentAction.ConsoleOutput += string.IsNullOrEmpty(eventArgs.Data) ? Lang.Action_CurrentStatus_WaitingInQueue : eventArgs.Data.Trim() + '\n'; + if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput = eventArgs.Data.Trim(); + currentActionRunning = true; + } + else if (!string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput += '\n' + eventArgs.Data.Trim(); + } }); if (!result.Success) { @@ -103,7 +128,15 @@ public void Runner() currentAction.OperationStatus = $"Downloading {item}"; var result = environmentService.Download(item, currentAction.Path, (sender, eventArgs) => { - currentAction.ConsoleOutput += string.IsNullOrEmpty(eventArgs.Data) ? Lang.Action_CurrentStatus_WaitingInQueue : eventArgs.Data.Trim() + '\n'; + if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput = eventArgs.Data.Trim(); + currentActionRunning = true; + } + else if (!string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput += '\n' + eventArgs.Data.Trim(); + } }, extraParameters: currentAction.ExtraParameters); currentAction.CompletedSubTaskNumber++; if (!result.Success) @@ -127,7 +160,15 @@ public void Runner() currentAction.OperationStatus = $"Updating {item}"; var result = environmentService.Update(item, (sender, eventArgs) => { - currentAction.ConsoleOutput += string.IsNullOrEmpty(eventArgs.Data) ? Lang.Action_CurrentStatus_WaitingInQueue : eventArgs.Data.Trim() + '\n'; + if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput = eventArgs.Data.Trim(); + currentActionRunning = true; + } + else if (!string.IsNullOrEmpty(eventArgs.Data)) + { + currentAction.ConsoleOutput += '\n' + eventArgs.Data.Trim(); + } }); currentAction.CompletedSubTaskNumber++; if (!result.Success) diff --git a/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs b/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs index af3abce..91ca5d5 100644 --- a/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs @@ -16,7 +16,7 @@ private void ActionTest() actionService.AddOperation(new ActionListItem ( ActionType.Install, - "114514==114", + "pytorch", totalSubTaskNumber: 1, progressIntermediate: false )); diff --git a/src/PipManager/Views/Pages/Action/ActionPage.xaml b/src/PipManager/Views/Pages/Action/ActionPage.xaml index f659997..7d5dfbb 100644 --- a/src/PipManager/Views/Pages/Action/ActionPage.xaml +++ b/src/PipManager/Views/Pages/Action/ActionPage.xaml @@ -5,6 +5,7 @@ xmlns:action="clr-namespace:PipManager.Views.Pages.Action" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:lang="clr-namespace:PipManager.Languages" + xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:pages="clr-namespace:PipManager.Models.Action" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" @@ -115,10 +116,17 @@ Style="{StaticResource BodyLargeTextBlockStyle}" Text="Console Output" /> + Text="{Binding ConsoleOutput}"> + + + + + + diff --git a/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs b/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs index 6d1158a..22174d5 100644 --- a/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs +++ b/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs @@ -14,4 +14,9 @@ public ActionPage(ActionViewModel viewModel) InitializeComponent(); } + + private void TextBox_Scroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e) + { + + } } \ No newline at end of file From a384e1a9fa54d64db4868e48e79542d84275e73c Mon Sep 17 00:00:00 2001 From: AuroraZiling <2935876049@qq.com> Date: Sat, 30 Mar 2024 19:46:29 +0800 Subject: [PATCH 03/15] feat: cancel action (wait in queue) --- src/PipManager/Languages/Lang.Designer.cs | 439 ++++++++++-------- src/PipManager/Languages/Lang.resx | 9 + src/PipManager/Languages/Lang.zh-cn.resx | 9 + src/PipManager/PipManager.csproj | 1 + .../Services/Action/ActionService.cs | 15 +- .../Services/Action/IActionService.cs | 7 +- .../Pages/Action/ActionViewModel.cs | 29 +- .../Views/Pages/Action/ActionPage.xaml | 6 +- 8 files changed, 301 insertions(+), 214 deletions(-) diff --git a/src/PipManager/Languages/Lang.Designer.cs b/src/PipManager/Languages/Lang.Designer.cs index fe36478..0c5e8ba 100644 --- a/src/PipManager/Languages/Lang.Designer.cs +++ b/src/PipManager/Languages/Lang.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 // //------------------------------------------------------------------------------ @@ -13,12 +13,12 @@ namespace PipManager.Languages { /// - /// A strongly-typed resource class, for looking up localized strings, etc. + /// 一个强类型的资源类,用于查找本地化的字符串等。 /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] @@ -33,7 +33,7 @@ internal Lang() { } /// - /// Returns the cached ResourceManager instance used by this class. + /// 返回此类使用的缓存的 ResourceManager 实例。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { @@ -47,8 +47,8 @@ internal Lang() { } /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { @@ -61,7 +61,7 @@ internal Lang() { } /// - /// Looks up a localized string similar to Document. + /// 查找类似 Document 的本地化字符串。 /// public static string About_Document { get { @@ -70,7 +70,7 @@ public static string About_Document { } /// - /// Looks up a localized string similar to Github Discussion. + /// 查找类似 Github Discussion 的本地化字符串。 /// public static string About_GithubDiscussion { get { @@ -79,7 +79,7 @@ public static string About_GithubDiscussion { } /// - /// Looks up a localized string similar to Github Issue. + /// 查找类似 Github Issue 的本地化字符串。 /// public static string About_GithubIssue { get { @@ -88,7 +88,7 @@ public static string About_GithubIssue { } /// - /// Looks up a localized string similar to Github Repo. + /// 查找类似 Github Repo 的本地化字符串。 /// public static string About_GithubRepo { get { @@ -97,7 +97,7 @@ public static string About_GithubRepo { } /// - /// Looks up a localized string similar to More Information. + /// 查找类似 More Information 的本地化字符串。 /// public static string About_MoreInformation { get { @@ -106,7 +106,7 @@ public static string About_MoreInformation { } /// - /// Looks up a localized string similar to Open Source License. + /// 查找类似 Open Source License 的本地化字符串。 /// public static string About_MoreInformation_OpenSourceLicense { get { @@ -115,7 +115,7 @@ public static string About_MoreInformation_OpenSourceLicense { } /// - /// Looks up a localized string similar to Privacy. + /// 查找类似 Privacy 的本地化字符串。 /// public static string About_MoreInformation_Privacy { get { @@ -124,7 +124,7 @@ public static string About_MoreInformation_Privacy { } /// - /// Looks up a localized string similar to Pip Manager will not upload any of your information.. + /// 查找类似 Pip Manager will not upload any of your information. 的本地化字符串。 /// public static string About_MoreInformation_PrivacyLine1 { get { @@ -133,7 +133,7 @@ public static string About_MoreInformation_PrivacyLine1 { } /// - /// Looks up a localized string similar to Pip Manager collects all data locally and stores it in the config.json file in the application directory.. + /// 查找类似 Pip Manager collects all data locally and stores it in the config.json file in the application directory. 的本地化字符串。 /// public static string About_MoreInformation_PrivacyLine2 { get { @@ -142,7 +142,7 @@ public static string About_MoreInformation_PrivacyLine2 { } /// - /// Looks up a localized string similar to Pip Manager does not modify the registry.. + /// 查找类似 Pip Manager does not modify the registry. 的本地化字符串。 /// public static string About_MoreInformation_PrivacyLine3 { get { @@ -151,7 +151,7 @@ public static string About_MoreInformation_PrivacyLine3 { } /// - /// Looks up a localized string similar to Added {0} new operation(s). + /// 查找类似 Added {0} new operation(s) 的本地化字符串。 /// public static string Action_AddOperation_Toast { get { @@ -160,7 +160,7 @@ public static string Action_AddOperation_Toast { } /// - /// Looks up a localized string similar to Exceptions. + /// 查找类似 Exceptions 的本地化字符串。 /// public static string Action_Button_Exceptions { get { @@ -169,7 +169,7 @@ public static string Action_Button_Exceptions { } /// - /// Looks up a localized string similar to Command. + /// 查找类似 Command 的本地化字符串。 /// public static string Action_Command { get { @@ -178,7 +178,7 @@ public static string Action_Command { } /// - /// Looks up a localized string similar to Completed. + /// 查找类似 Completed 的本地化字符串。 /// public static string Action_Completed { get { @@ -187,7 +187,7 @@ public static string Action_Completed { } /// - /// Looks up a localized string similar to Error. + /// 查找类似 Error 的本地化字符串。 /// public static string Action_ConsoleError { get { @@ -196,7 +196,7 @@ public static string Action_ConsoleError { } /// - /// Looks up a localized string similar to No errors detected. + /// 查找类似 No errors detected 的本地化字符串。 /// public static string Action_ConsoleError_Empty { get { @@ -205,7 +205,7 @@ public static string Action_ConsoleError_Empty { } /// - /// Looks up a localized string similar to Output. + /// 查找类似 Output 的本地化字符串。 /// public static string Action_ConsoleOutput { get { @@ -214,7 +214,7 @@ public static string Action_ConsoleOutput { } /// - /// Looks up a localized string similar to Current Status. + /// 查找类似 Current Status 的本地化字符串。 /// public static string Action_CurrentStatus { get { @@ -223,7 +223,7 @@ public static string Action_CurrentStatus { } /// - /// Looks up a localized string similar to Waiting in queue. + /// 查找类似 Waiting in queue 的本地化字符串。 /// public static string Action_CurrentStatus_WaitingInQueue { get { @@ -232,7 +232,7 @@ public static string Action_CurrentStatus_WaitingInQueue { } /// - /// Looks up a localized string similar to Issue. + /// 查找类似 Issue 的本地化字符串。 /// public static string Action_IssueDetected { get { @@ -241,7 +241,7 @@ public static string Action_IssueDetected { } /// - /// Looks up a localized string similar to Issue detected in Action. + /// 查找类似 Issue detected in Action 的本地化字符串。 /// public static string Action_IssueDetectedToast { get { @@ -250,7 +250,7 @@ public static string Action_IssueDetectedToast { } /// - /// Looks up a localized string similar to No Current Operations. + /// 查找类似 No Current Operations 的本地化字符串。 /// public static string Action_NoCurrentOperations { get { @@ -259,7 +259,16 @@ public static string Action_NoCurrentOperations { } /// - /// Looks up a localized string similar to Download. + /// 查找类似 Cancel 的本地化字符串。 + /// + public static string Action_Operation_Cancel { + get { + return ResourceManager.GetString("Action_Operation_Cancel", resourceCulture); + } + } + + /// + /// 查找类似 Download 的本地化字符串。 /// public static string Action_Operation_Download { get { @@ -268,7 +277,7 @@ public static string Action_Operation_Download { } /// - /// Looks up a localized string similar to Package Install. + /// 查找类似 Package Install 的本地化字符串。 /// public static string Action_Operation_Install { get { @@ -277,7 +286,7 @@ public static string Action_Operation_Install { } /// - /// Looks up a localized string similar to Package Install (via requirements.txt). + /// 查找类似 Package Install (via requirements.txt) 的本地化字符串。 /// public static string Action_Operation_InstallByRequirements { get { @@ -286,7 +295,7 @@ public static string Action_Operation_InstallByRequirements { } /// - /// Looks up a localized string similar to Package Uninstallation. + /// 查找类似 Package Uninstallation 的本地化字符串。 /// public static string Action_Operation_Uninstall { get { @@ -295,7 +304,7 @@ public static string Action_Operation_Uninstall { } /// - /// Looks up a localized string similar to Package Update. + /// 查找类似 Package Update 的本地化字符串。 /// public static string Action_Operation_Update { get { @@ -304,7 +313,25 @@ public static string Action_Operation_Update { } /// - /// Looks up a localized string similar to Time. + /// 查找类似 Action Already Running 的本地化字符串。 + /// + public static string Action_OperationCanceled_AlreadyRunning { + get { + return ResourceManager.GetString("Action_OperationCanceled_AlreadyRunning", resourceCulture); + } + } + + /// + /// 查找类似 Action Cancelled 的本地化字符串。 + /// + public static string Action_OperationCanceled_Success { + get { + return ResourceManager.GetString("Action_OperationCanceled_Success", resourceCulture); + } + } + + /// + /// 查找类似 Time 的本地化字符串。 /// public static string ActionException_Badge_Timestamp { get { @@ -313,7 +340,7 @@ public static string ActionException_Badge_Timestamp { } /// - /// Looks up a localized string similar to Bing Search. + /// 查找类似 Bing Search 的本地化字符串。 /// public static string ActionException_BingSearch { get { @@ -322,7 +349,7 @@ public static string ActionException_BingSearch { } /// - /// Looks up a localized string similar to Copy to clipboard. + /// 查找类似 Copy to clipboard 的本地化字符串。 /// public static string ActionException_CopyToClipboard { get { @@ -331,7 +358,7 @@ public static string ActionException_CopyToClipboard { } /// - /// Looks up a localized string similar to Copied to clipboard. + /// 查找类似 Copied to clipboard 的本地化字符串。 /// public static string ActionException_CopyToClipboardNotice { get { @@ -340,7 +367,7 @@ public static string ActionException_CopyToClipboardNotice { } /// - /// Looks up a localized string similar to Exception. + /// 查找类似 Exception 的本地化字符串。 /// public static string ActionException_Exception { get { @@ -349,7 +376,7 @@ public static string ActionException_Exception { } /// - /// Looks up a localized string similar to Google Search. + /// 查找类似 Google Search 的本地化字符串。 /// public static string ActionException_GoogleSearch { get { @@ -358,7 +385,7 @@ public static string ActionException_GoogleSearch { } /// - /// Looks up a localized string similar to Operation. + /// 查找类似 Operation 的本地化字符串。 /// public static string ActionException_Operation { get { @@ -367,7 +394,7 @@ public static string ActionException_Operation { } /// - /// Looks up a localized string similar to Add. + /// 查找类似 Add 的本地化字符串。 /// public static string Common_Button_Add { get { @@ -376,7 +403,7 @@ public static string Common_Button_Add { } /// - /// Looks up a localized string similar to Browse. + /// 查找类似 Browse 的本地化字符串。 /// public static string Common_Button_Browse { get { @@ -385,7 +412,7 @@ public static string Common_Button_Browse { } /// - /// Looks up a localized string similar to Refresh. + /// 查找类似 Refresh 的本地化字符串。 /// public static string Common_Button_Refresh { get { @@ -394,7 +421,7 @@ public static string Common_Button_Refresh { } /// - /// Looks up a localized string similar to Caution. + /// 查找类似 Caution 的本地化字符串。 /// public static string Common_NoticeTitle_Caution { get { @@ -403,7 +430,7 @@ public static string Common_NoticeTitle_Caution { } /// - /// Looks up a localized string similar to Notice. + /// 查找类似 Notice 的本地化字符串。 /// public static string Common_NoticeTitle_Notice { get { @@ -412,7 +439,7 @@ public static string Common_NoticeTitle_Notice { } /// - /// Looks up a localized string similar to Cancel. + /// 查找类似 Cancel 的本地化字符串。 /// public static string ContentDialog_CloseButton_Cancel { get { @@ -421,7 +448,7 @@ public static string ContentDialog_CloseButton_Cancel { } /// - /// Looks up a localized string similar to There are still running background tasks. Do you confirm to exit the software?. + /// 查找类似 There are still running background tasks. Do you confirm to exit the software? 的本地化字符串。 /// public static string ContentDialog_Message_ActionStillRunning { get { @@ -430,7 +457,7 @@ public static string ContentDialog_Message_ActionStillRunning { } /// - /// Looks up a localized string similar to Environment already exists. + /// 查找类似 Environment already exists 的本地化字符串。 /// public static string ContentDialog_Message_EnvironmentAlreadyExists { get { @@ -439,7 +466,7 @@ public static string ContentDialog_Message_EnvironmentAlreadyExists { } /// - /// Looks up a localized string similar to Environment not available. + /// 查找类似 Environment not available 的本地化字符串。 /// public static string ContentDialog_Message_EnvironmentCheckFailed { get { @@ -448,7 +475,7 @@ public static string ContentDialog_Message_EnvironmentCheckFailed { } /// - /// Looks up a localized string similar to Environment available. + /// 查找类似 Environment available 的本地化字符串。 /// public static string ContentDialog_Message_EnvironmentCheckPassed { get { @@ -457,7 +484,7 @@ public static string ContentDialog_Message_EnvironmentCheckPassed { } /// - /// Looks up a localized string similar to The environment will be removed from the list. + /// 查找类似 The environment will be removed from the list 的本地化字符串。 /// public static string ContentDialog_Message_EnvironmentDeletion { get { @@ -466,7 +493,7 @@ public static string ContentDialog_Message_EnvironmentDeletion { } /// - /// Looks up a localized string similar to Error in adding environment. + /// 查找类似 Error in adding environment 的本地化字符串。 /// public static string ContentDialog_Message_EnvironmentInvaild { get { @@ -475,7 +502,7 @@ public static string ContentDialog_Message_EnvironmentInvaild { } /// - /// Looks up a localized string similar to The environment is up to date. + /// 查找类似 The environment is up to date 的本地化字符串。 /// public static string ContentDialog_Message_EnvironmentIsLatest { get { @@ -484,7 +511,7 @@ public static string ContentDialog_Message_EnvironmentIsLatest { } /// - /// Looks up a localized string similar to You didn't choose an environment. + /// 查找类似 You didn't choose an environment 的本地化字符串。 /// public static string ContentDialog_Message_EnvironmentNoSelection { get { @@ -493,7 +520,7 @@ public static string ContentDialog_Message_EnvironmentNoSelection { } /// - /// Looks up a localized string similar to New version detected. Update now?. + /// 查找类似 New version detected. Update now? 的本地化字符串。 /// public static string ContentDialog_Message_FindUpdate { get { @@ -502,7 +529,7 @@ public static string ContentDialog_Message_FindUpdate { } /// - /// Looks up a localized string similar to Following packages will be removed from the environment:. + /// 查找类似 Following packages will be removed from the environment: 的本地化字符串。 /// public static string ContentDialog_Message_LibraryDeletionWarning { get { @@ -511,7 +538,7 @@ public static string ContentDialog_Message_LibraryDeletionWarning { } /// - /// Looks up a localized string similar to Network Error. + /// 查找类似 Network Error 的本地化字符串。 /// public static string ContentDialog_Message_NetworkError { get { @@ -520,7 +547,7 @@ public static string ContentDialog_Message_NetworkError { } /// - /// Looks up a localized string similar to Package(s) are up to date. + /// 查找类似 Package(s) are up to date 的本地化字符串。 /// public static string ContentDialog_Message_PackageIsLatest { get { @@ -529,7 +556,7 @@ public static string ContentDialog_Message_PackageIsLatest { } /// - /// Looks up a localized string similar to Action. + /// 查找类似 Action 的本地化字符串。 /// public static string ContentDialog_PrimaryButton_Action { get { @@ -538,7 +565,7 @@ public static string ContentDialog_PrimaryButton_Action { } /// - /// Looks up a localized string similar to Remove Environment. + /// 查找类似 Remove Environment 的本地化字符串。 /// public static string ContentDialog_PrimaryButton_EnvironmentDeletion { get { @@ -547,7 +574,7 @@ public static string ContentDialog_PrimaryButton_EnvironmentDeletion { } /// - /// Looks up a localized string similar to Operation Warning. + /// 查找类似 Operation Warning 的本地化字符串。 /// public static string ContentDialog_Title_AreYouSure { get { @@ -556,7 +583,7 @@ public static string ContentDialog_Title_AreYouSure { } /// - /// Looks up a localized string similar to Error. + /// 查找类似 Error 的本地化字符串。 /// public static string ContentDialog_Title_Error { get { @@ -565,7 +592,7 @@ public static string ContentDialog_Title_Error { } /// - /// Looks up a localized string similar to Notice. + /// 查找类似 Notice 的本地化字符串。 /// public static string ContentDialog_Title_Notice { get { @@ -574,7 +601,7 @@ public static string ContentDialog_Title_Notice { } /// - /// Looks up a localized string similar to Success. + /// 查找类似 Success 的本地化字符串。 /// public static string ContentDialog_Title_Success { get { @@ -583,7 +610,7 @@ public static string ContentDialog_Title_Success { } /// - /// Looks up a localized string similar to Warning. + /// 查找类似 Warning 的本地化字符串。 /// public static string ContentDialog_Title_Warning { get { @@ -592,7 +619,7 @@ public static string ContentDialog_Title_Warning { } /// - /// Looks up a localized string similar to Developing. + /// 查找类似 Developing 的本地化字符串。 /// public static string Development_Developing { get { @@ -601,7 +628,7 @@ public static string Development_Developing { } /// - /// Looks up a localized string similar to Add Environment. + /// 查找类似 Add Environment 的本地化字符串。 /// public static string Environment_Operation_AddEnvironment { get { @@ -610,7 +637,7 @@ public static string Environment_Operation_AddEnvironment { } /// - /// Looks up a localized string similar to Check Update. + /// 查找类似 Check Update 的本地化字符串。 /// public static string Environment_Operation_CheckEnvironmentUpdate { get { @@ -619,7 +646,7 @@ public static string Environment_Operation_CheckEnvironmentUpdate { } /// - /// Looks up a localized string similar to Remove Environment (from list). + /// 查找类似 Remove Environment (from list) 的本地化字符串。 /// public static string Environment_Operation_RemoveEnvironment { get { @@ -628,7 +655,7 @@ public static string Environment_Operation_RemoveEnvironment { } /// - /// Looks up a localized string similar to Verify Environment. + /// 查找类似 Verify Environment 的本地化字符串。 /// public static string Environment_Operation_VerifyEnvironment { get { @@ -637,7 +664,7 @@ public static string Environment_Operation_VerifyEnvironment { } /// - /// Looks up a localized string similar to Detected Environment. + /// 查找类似 Detected Environment 的本地化字符串。 /// public static string EnvironmentAdd_EnvironmentVariable_Header { get { @@ -646,7 +673,7 @@ public static string EnvironmentAdd_EnvironmentVariable_Header { } /// - /// Looks up a localized string similar to Can't find any environment. + /// 查找类似 Can't find any environment 的本地化字符串。 /// public static string EnvironmentAdd_EnvironmentVariable_NotFound { get { @@ -655,7 +682,7 @@ public static string EnvironmentAdd_EnvironmentVariable_NotFound { } /// - /// Looks up a localized string similar to Environment Variables. + /// 查找类似 Environment Variables 的本地化字符串。 /// public static string EnvironmentAdd_EnvironmentVariable_Title { get { @@ -664,7 +691,7 @@ public static string EnvironmentAdd_EnvironmentVariable_Title { } /// - /// Looks up a localized string similar to Add Environment. + /// 查找类似 Add Environment 的本地化字符串。 /// public static string EnvironmentAdd_Header { get { @@ -673,7 +700,7 @@ public static string EnvironmentAdd_Header { } /// - /// Looks up a localized string similar to Enter Pip command. + /// 查找类似 Enter Pip command 的本地化字符串。 /// public static string EnvironmentAdd_PipCommand_Label { get { @@ -682,7 +709,7 @@ public static string EnvironmentAdd_PipCommand_Label { } /// - /// Looks up a localized string similar to If you are using "pip install", type "pip" in the box. Similarly, for "pip3.11 install", type "pip3.11".. + /// 查找类似 If you are using "pip install", type "pip" in the box. Similarly, for "pip3.11 install", type "pip3.11". 的本地化字符串。 /// public static string EnvironmentAdd_PipCommand_Notice { get { @@ -691,7 +718,7 @@ public static string EnvironmentAdd_PipCommand_Notice { } /// - /// Looks up a localized string similar to Pip Command. + /// 查找类似 Pip Command 的本地化字符串。 /// public static string EnvironmentAdd_PipCommand_Title { get { @@ -700,7 +727,7 @@ public static string EnvironmentAdd_PipCommand_Title { } /// - /// Looks up a localized string similar to Enter the absolute path of python.exe. + /// 查找类似 Enter the absolute path of python.exe 的本地化字符串。 /// public static string EnvironmentAdd_PythonPath_Label { get { @@ -709,7 +736,7 @@ public static string EnvironmentAdd_PythonPath_Label { } /// - /// Looks up a localized string similar to Python Executable Path. + /// 查找类似 Python Executable Path 的本地化字符串。 /// public static string EnvironmentAdd_PythonPath_Title { get { @@ -718,7 +745,7 @@ public static string EnvironmentAdd_PythonPath_Title { } /// - /// Looks up a localized string similar to Current: . + /// 查找类似 Current: 的本地化字符串。 /// public static string EnvironmentCheckEnvironmentUpdate_CurrentVersion { get { @@ -727,7 +754,7 @@ public static string EnvironmentCheckEnvironmentUpdate_CurrentVersion { } /// - /// Looks up a localized string similar to Latest: . + /// 查找类似 Latest: 的本地化字符串。 /// public static string EnvironmentCheckEnvironmentUpdate_LatestVersion { get { @@ -736,7 +763,7 @@ public static string EnvironmentCheckEnvironmentUpdate_LatestVersion { } /// - /// Looks up a localized string similar to Pip Manager - Unexpected Exception. + /// 查找类似 Pip Manager - Unexpected Exception 的本地化字符串。 /// public static string ExceptionWindow_Title { get { @@ -745,7 +772,7 @@ public static string ExceptionWindow_Title { } /// - /// Looks up a localized string similar to Current: {0}. + /// 查找类似 Current: {0} 的本地化字符串。 /// public static string Library_CheckUpdate_Current { get { @@ -754,7 +781,7 @@ public static string Library_CheckUpdate_Current { } /// - /// Looks up a localized string similar to Latest: {0}. + /// 查找类似 Latest: {0} 的本地化字符串。 /// public static string Library_CheckUpdate_Latest { get { @@ -763,7 +790,7 @@ public static string Library_CheckUpdate_Latest { } /// - /// Looks up a localized string similar to {0} package(s) found. + /// 查找类似 {0} package(s) found 的本地化字符串。 /// public static string Library_Data_PackageFound { get { @@ -772,7 +799,7 @@ public static string Library_Data_PackageFound { } /// - /// Looks up a localized string similar to {0} item(s) selected. + /// 查找类似 {0} item(s) selected 的本地化字符串。 /// public static string Library_Data_SelectedItemsCount { get { @@ -781,7 +808,7 @@ public static string Library_Data_SelectedItemsCount { } /// - /// Looks up a localized string similar to Add environment. + /// 查找类似 Add environment 的本地化字符串。 /// public static string Library_Error_AddEnvironment { get { @@ -790,7 +817,7 @@ public static string Library_Error_AddEnvironment { } /// - /// Looks up a localized string similar to No Environment. + /// 查找类似 No Environment 的本地化字符串。 /// public static string Library_Error_NoEnvironment { get { @@ -799,7 +826,7 @@ public static string Library_Error_NoEnvironment { } /// - /// Looks up a localized string similar to Check Update. + /// 查找类似 Check Update 的本地化字符串。 /// public static string Library_Operation_CheckUpdate { get { @@ -808,7 +835,7 @@ public static string Library_Operation_CheckUpdate { } /// - /// Looks up a localized string similar to Delete. + /// 查找类似 Delete 的本地化字符串。 /// public static string Library_Operation_Delete { get { @@ -817,7 +844,7 @@ public static string Library_Operation_Delete { } /// - /// Looks up a localized string similar to Details. + /// 查找类似 Details 的本地化字符串。 /// public static string Library_Operation_Details { get { @@ -826,7 +853,7 @@ public static string Library_Operation_Details { } /// - /// Looks up a localized string similar to Install. + /// 查找类似 Install 的本地化字符串。 /// public static string Library_Operation_Install { get { @@ -835,7 +862,7 @@ public static string Library_Operation_Install { } /// - /// Looks up a localized string similar to Dev. + /// 查找类似 Dev 的本地化字符串。 /// public static string Library_Version_Dev { get { @@ -844,7 +871,7 @@ public static string Library_Version_Dev { } /// - /// Looks up a localized string similar to Post. + /// 查找类似 Post 的本地化字符串。 /// public static string Library_Version_Post { get { @@ -853,7 +880,7 @@ public static string Library_Version_Post { } /// - /// Looks up a localized string similar to Unstable. + /// 查找类似 Unstable 的本地化字符串。 /// public static string Library_Version_Pre { get { @@ -862,7 +889,7 @@ public static string Library_Version_Pre { } /// - /// Looks up a localized string similar to Development Status. + /// 查找类似 Development Status 的本地化字符串。 /// public static string LibraryDetail_Classifier_DevelopmentStatus { get { @@ -871,7 +898,7 @@ public static string LibraryDetail_Classifier_DevelopmentStatus { } /// - /// Looks up a localized string similar to Environment. + /// 查找类似 Environment 的本地化字符串。 /// public static string LibraryDetail_Classifier_Environment { get { @@ -880,7 +907,7 @@ public static string LibraryDetail_Classifier_Environment { } /// - /// Looks up a localized string similar to Intended Audience. + /// 查找类似 Intended Audience 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience { get { @@ -889,7 +916,7 @@ public static string LibraryDetail_Classifier_IntendedAudience { } /// - /// Looks up a localized string similar to Customer Service. + /// 查找类似 Customer Service 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_CustomerService { get { @@ -898,7 +925,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_CustomerService { } /// - /// Looks up a localized string similar to Developers. + /// 查找类似 Developers 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_Developers { get { @@ -907,7 +934,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Developers { } /// - /// Looks up a localized string similar to Education. + /// 查找类似 Education 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_Education { get { @@ -916,7 +943,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Education { } /// - /// Looks up a localized string similar to End Users & Desktop. + /// 查找类似 End Users & Desktop 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_EndUsersDesktop { get { @@ -925,7 +952,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_EndUsersDesktop { } /// - /// Looks up a localized string similar to Financial and Insurance Industry. + /// 查找类似 Financial and Insurance Industry 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_FinancialAndInsuranceIndustry { get { @@ -934,7 +961,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_FinancialAndInsur } /// - /// Looks up a localized string similar to Healthcare Industry. + /// 查找类似 Healthcare Industry 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_HealthcareIndustry { get { @@ -943,7 +970,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_HealthcareIndustr } /// - /// Looks up a localized string similar to Information Technology. + /// 查找类似 Information Technology 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_InformationTechonology { get { @@ -952,7 +979,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_InformationTechon } /// - /// Looks up a localized string similar to Legal Industry. + /// 查找类似 Legal Industry 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_LegalIndustry { get { @@ -961,7 +988,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_LegalIndustry { } /// - /// Looks up a localized string similar to Manufacturing. + /// 查找类似 Manufacturing 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_Manufacturing { get { @@ -970,7 +997,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Manufacturing { } /// - /// Looks up a localized string similar to Other. + /// 查找类似 Other 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_OtherAudience { get { @@ -979,7 +1006,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_OtherAudience { } /// - /// Looks up a localized string similar to Religion. + /// 查找类似 Religion 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_Religion { get { @@ -988,7 +1015,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Religion { } /// - /// Looks up a localized string similar to Science & Research. + /// 查找类似 Science & Research 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_ScienceResearch { get { @@ -997,7 +1024,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_ScienceResearch { } /// - /// Looks up a localized string similar to System Administrators. + /// 查找类似 System Administrators 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_SystemAdministrators { get { @@ -1006,7 +1033,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_SystemAdministrat } /// - /// Looks up a localized string similar to Telecommunications Industry. + /// 查找类似 Telecommunications Industry 的本地化字符串。 /// public static string LibraryDetail_Classifier_IntendedAudience_TelecommunicationsIndustry { get { @@ -1015,7 +1042,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Telecommunication } /// - /// Looks up a localized string similar to Operating System. + /// 查找类似 Operating System 的本地化字符串。 /// public static string LibraryDetail_Classifier_OperatingSystem { get { @@ -1024,7 +1051,7 @@ public static string LibraryDetail_Classifier_OperatingSystem { } /// - /// Looks up a localized string similar to OS Independent. + /// 查找类似 OS Independent 的本地化字符串。 /// public static string LibraryDetail_Classifier_OperatingSystem_OSIndependent { get { @@ -1033,7 +1060,7 @@ public static string LibraryDetail_Classifier_OperatingSystem_OSIndependent { } /// - /// Looks up a localized string similar to Programming Language. + /// 查找类似 Programming Language 的本地化字符串。 /// public static string LibraryDetail_Classifier_ProgrammingLanguage { get { @@ -1042,7 +1069,7 @@ public static string LibraryDetail_Classifier_ProgrammingLanguage { } /// - /// Looks up a localized string similar to Topic. + /// 查找类似 Topic 的本地化字符串。 /// public static string LibraryDetail_Classifier_Topic { get { @@ -1051,7 +1078,7 @@ public static string LibraryDetail_Classifier_Topic { } /// - /// Looks up a localized string similar to Author. + /// 查找类似 Author 的本地化字符串。 /// public static string LibraryDetail_Contact_Author { get { @@ -1060,7 +1087,7 @@ public static string LibraryDetail_Contact_Author { } /// - /// Looks up a localized string similar to Email. + /// 查找类似 Email 的本地化字符串。 /// public static string LibraryDetail_Contact_AuthorEmail { get { @@ -1069,7 +1096,7 @@ public static string LibraryDetail_Contact_AuthorEmail { } /// - /// Looks up a localized string similar to Project Url. + /// 查找类似 Project Url 的本地化字符串。 /// public static string LibraryDetail_Contact_ProjectUrl { get { @@ -1078,7 +1105,7 @@ public static string LibraryDetail_Contact_ProjectUrl { } /// - /// Looks up a localized string similar to Details. + /// 查找类似 Details 的本地化字符串。 /// public static string LibraryDetail_Header { get { @@ -1087,7 +1114,7 @@ public static string LibraryDetail_Header { } /// - /// Looks up a localized string similar to Package. + /// 查找类似 Package 的本地化字符串。 /// public static string LibraryDetail_Package { get { @@ -1096,7 +1123,7 @@ public static string LibraryDetail_Package { } /// - /// Looks up a localized string similar to Path. + /// 查找类似 Path 的本地化字符串。 /// public static string LibraryDetail_Path { get { @@ -1105,7 +1132,7 @@ public static string LibraryDetail_Path { } /// - /// Looks up a localized string similar to Summary. + /// 查找类似 Summary 的本地化字符串。 /// public static string LibraryDetail_Summary { get { @@ -1114,7 +1141,7 @@ public static string LibraryDetail_Summary { } /// - /// Looks up a localized string similar to Unknown. + /// 查找类似 Unknown 的本地化字符串。 /// public static string LibraryDetail_Unknown { get { @@ -1123,7 +1150,7 @@ public static string LibraryDetail_Unknown { } /// - /// Looks up a localized string similar to Version. + /// 查找类似 Version 的本地化字符串。 /// public static string LibraryDetail_Version { get { @@ -1132,7 +1159,7 @@ public static string LibraryDetail_Version { } /// - /// Looks up a localized string similar to Package already in list. + /// 查找类似 Package already in list 的本地化字符串。 /// public static string LibraryInstall_Add_AlreadyInList { get { @@ -1141,7 +1168,7 @@ public static string LibraryInstall_Add_AlreadyInList { } /// - /// Looks up a localized string similar to Package already installed. + /// 查找类似 Package already installed 的本地化字符串。 /// public static string LibraryInstall_Add_AlreadyInstalled { get { @@ -1150,7 +1177,7 @@ public static string LibraryInstall_Add_AlreadyInstalled { } /// - /// Looks up a localized string similar to Default. + /// 查找类似 Default 的本地化字符串。 /// public static string LibraryInstall_Add_Header { get { @@ -1159,7 +1186,7 @@ public static string LibraryInstall_Add_Header { } /// - /// Looks up a localized string similar to Invalid Package Name (PEP 508). + /// 查找类似 Invalid Package Name (PEP 508) 的本地化字符串。 /// public static string LibraryInstall_Add_InvalidPackageName { get { @@ -1168,7 +1195,7 @@ public static string LibraryInstall_Add_InvalidPackageName { } /// - /// Looks up a localized string similar to Enter Package Name. + /// 查找类似 Enter Package Name 的本地化字符串。 /// public static string LibraryInstall_Add_Notice { get { @@ -1177,7 +1204,7 @@ public static string LibraryInstall_Add_Notice { } /// - /// Looks up a localized string similar to Package not found. + /// 查找类似 Package not found 的本地化字符串。 /// public static string LibraryInstall_Add_PackageNotFound { get { @@ -1186,7 +1213,7 @@ public static string LibraryInstall_Add_PackageNotFound { } /// - /// Looks up a localized string similar to Verifying. + /// 查找类似 Verifying 的本地化字符串。 /// public static string LibraryInstall_Add_Verifying { get { @@ -1195,7 +1222,7 @@ public static string LibraryInstall_Add_Verifying { } /// - /// Looks up a localized string similar to Download Distributions. + /// 查找类似 Download Distributions 的本地化字符串。 /// public static string LibraryInstall_Download_Header { get { @@ -1204,7 +1231,7 @@ public static string LibraryInstall_Download_Header { } /// - /// Looks up a localized string similar to Install. + /// 查找类似 Install 的本地化字符串。 /// public static string LibraryInstall_Header { get { @@ -1213,7 +1240,7 @@ public static string LibraryInstall_Header { } /// - /// Looks up a localized string similar to The newest and compatible version will be installed. + /// 查找类似 The newest and compatible version will be installed 的本地化字符串。 /// public static string LibraryInstall_List_DefaultVersion { get { @@ -1222,7 +1249,7 @@ public static string LibraryInstall_List_DefaultVersion { } /// - /// Looks up a localized string similar to Version Specified. + /// 查找类似 Version Specified 的本地化字符串。 /// public static string LibraryInstall_List_VersionSpecified { get { @@ -1231,7 +1258,7 @@ public static string LibraryInstall_List_VersionSpecified { } /// - /// Looks up a localized string similar to Download. + /// 查找类似 Download 的本地化字符串。 /// public static string LibraryInstall_Requirements_Download { get { @@ -1240,7 +1267,7 @@ public static string LibraryInstall_Requirements_Download { } /// - /// Looks up a localized string similar to Download dependencies. + /// 查找类似 Download dependencies 的本地化字符串。 /// public static string LibraryInstall_Requirements_DownloadDependencies { get { @@ -1249,7 +1276,7 @@ public static string LibraryInstall_Requirements_DownloadDependencies { } /// - /// Looks up a localized string similar to Download Folder. + /// 查找类似 Download Folder 的本地化字符串。 /// public static string LibraryInstall_Requirements_DownloadFolder { get { @@ -1258,7 +1285,7 @@ public static string LibraryInstall_Requirements_DownloadFolder { } /// - /// Looks up a localized string similar to requirements.txt Import. + /// 查找类似 requirements.txt Import 的本地化字符串。 /// public static string LibraryInstall_Requirements_Header { get { @@ -1267,7 +1294,7 @@ public static string LibraryInstall_Requirements_Header { } /// - /// Looks up a localized string similar to About. + /// 查找类似 About 的本地化字符串。 /// public static string MainWindow_NavigationContent_About { get { @@ -1276,7 +1303,7 @@ public static string MainWindow_NavigationContent_About { } /// - /// Looks up a localized string similar to Action. + /// 查找类似 Action 的本地化字符串。 /// public static string MainWindow_NavigationContent_Action { get { @@ -1285,7 +1312,7 @@ public static string MainWindow_NavigationContent_Action { } /// - /// Looks up a localized string similar to Environment. + /// 查找类似 Environment 的本地化字符串。 /// public static string MainWindow_NavigationContent_Environment { get { @@ -1294,7 +1321,7 @@ public static string MainWindow_NavigationContent_Environment { } /// - /// Looks up a localized string similar to Lab. + /// 查找类似 Lab 的本地化字符串。 /// public static string MainWindow_NavigationContent_Lab { get { @@ -1303,7 +1330,7 @@ public static string MainWindow_NavigationContent_Lab { } /// - /// Looks up a localized string similar to Library. + /// 查找类似 Library 的本地化字符串。 /// public static string MainWindow_NavigationContent_Library { get { @@ -1312,7 +1339,7 @@ public static string MainWindow_NavigationContent_Library { } /// - /// Looks up a localized string similar to Search. + /// 查找类似 Search 的本地化字符串。 /// public static string MainWindow_NavigationContent_Search { get { @@ -1321,7 +1348,7 @@ public static string MainWindow_NavigationContent_Search { } /// - /// Looks up a localized string similar to Settings. + /// 查找类似 Settings 的本地化字符串。 /// public static string MainWindow_NavigationContent_Settings { get { @@ -1330,7 +1357,7 @@ public static string MainWindow_NavigationContent_Settings { } /// - /// Looks up a localized string similar to Tools. + /// 查找类似 Tools 的本地化字符串。 /// public static string MainWindow_NavigationContent_Tools { get { @@ -1339,7 +1366,7 @@ public static string MainWindow_NavigationContent_Tools { } /// - /// Looks up a localized string similar to Loading.... + /// 查找类似 Loading... 的本地化字符串。 /// public static string Mask_Loading { get { @@ -1348,7 +1375,7 @@ public static string Mask_Loading { } /// - /// Looks up a localized string similar to The newest and compatible version will be selected. + /// 查找类似 The newest and compatible version will be selected 的本地化字符串。 /// public static string Search_DefaultVersion { get { @@ -1357,7 +1384,7 @@ public static string Search_DefaultVersion { } /// - /// Looks up a localized string similar to No Description. + /// 查找类似 No Description 的本地化字符串。 /// public static string Search_List_NoDescription { get { @@ -1366,7 +1393,7 @@ public static string Search_List_NoDescription { } /// - /// Looks up a localized string similar to About {0} results found. + /// 查找类似 About {0} results found 的本地化字符串。 /// public static string Search_List_TotalResultNumber { get { @@ -1375,7 +1402,7 @@ public static string Search_List_TotalResultNumber { } /// - /// Looks up a localized string similar to Update Time: . + /// 查找类似 Update Time: 的本地化字符串。 /// public static string Search_List_UpdateTime { get { @@ -1384,7 +1411,7 @@ public static string Search_List_UpdateTime { } /// - /// Looks up a localized string similar to Details. + /// 查找类似 Details 的本地化字符串。 /// public static string Search_Operation_Details { get { @@ -1393,7 +1420,7 @@ public static string Search_Operation_Details { } /// - /// Looks up a localized string similar to No results. + /// 查找类似 No results 的本地化字符串。 /// public static string Search_Query_NoResults { get { @@ -1402,7 +1429,7 @@ public static string Search_Query_NoResults { } /// - /// Looks up a localized string similar to Timeout. + /// 查找类似 Timeout 的本地化字符串。 /// public static string Search_Query_Timeout { get { @@ -1411,7 +1438,7 @@ public static string Search_Query_Timeout { } /// - /// Looks up a localized string similar to Specify Version. + /// 查找类似 Specify Version 的本地化字符串。 /// public static string Search_VersionSpecified { get { @@ -1420,7 +1447,7 @@ public static string Search_VersionSpecified { } /// - /// Looks up a localized string similar to Download Distributions. + /// 查找类似 Download Distributions 的本地化字符串。 /// public static string SearchDetail_DownloadDistributions { get { @@ -1429,7 +1456,7 @@ public static string SearchDetail_DownloadDistributions { } /// - /// Looks up a localized string similar to Details. + /// 查找类似 Details 的本地化字符串。 /// public static string SearchDetail_Header { get { @@ -1438,7 +1465,7 @@ public static string SearchDetail_Header { } /// - /// Looks up a localized string similar to Install. + /// 查找类似 Install 的本地化字符串。 /// public static string SearchDetail_Install { get { @@ -1447,7 +1474,7 @@ public static string SearchDetail_Install { } /// - /// Looks up a localized string similar to Failed to get installed libraries. + /// 查找类似 Failed to get installed libraries 的本地化字符串。 /// public static string SearchDetail_Install_CannotGetLibraries { get { @@ -1456,7 +1483,7 @@ public static string SearchDetail_Install_CannotGetLibraries { } /// - /// Looks up a localized string similar to Latest Updated:. + /// 查找类似 Latest Updated: 的本地化字符串。 /// public static string SearchDetail_LatestUpdatedTime { get { @@ -1465,7 +1492,7 @@ public static string SearchDetail_LatestUpdatedTime { } /// - /// Looks up a localized string similar to Project description not available online. + /// 查找类似 Project description not available online 的本地化字符串。 /// public static string SearchDetail_ProjectDescription_LoadFailed { get { @@ -1474,7 +1501,7 @@ public static string SearchDetail_ProjectDescription_LoadFailed { } /// - /// Looks up a localized string similar to File Management. + /// 查找类似 File Management 的本地化字符串。 /// public static string Settings_Category_FileManagement { get { @@ -1483,7 +1510,7 @@ public static string Settings_Category_FileManagement { } /// - /// Looks up a localized string similar to Network. + /// 查找类似 Network 的本地化字符串。 /// public static string Settings_Category_Network { get { @@ -1492,7 +1519,7 @@ public static string Settings_Category_Network { } /// - /// Looks up a localized string similar to Package Source. + /// 查找类似 Package Source 的本地化字符串。 /// public static string Settings_Category_PackageSource { get { @@ -1501,7 +1528,7 @@ public static string Settings_Category_PackageSource { } /// - /// Looks up a localized string similar to Personalization. + /// 查找类似 Personalization 的本地化字符串。 /// public static string Settings_Category_Personalization { get { @@ -1510,7 +1537,7 @@ public static string Settings_Category_Personalization { } /// - /// Looks up a localized string similar to Crushes folder not found. + /// 查找类似 Crushes folder not found 的本地化字符串。 /// public static string Settings_FileManagement_CrushesDirNotFound { get { @@ -1519,7 +1546,7 @@ public static string Settings_FileManagement_CrushesDirNotFound { } /// - /// Looks up a localized string similar to Open App Folder. + /// 查找类似 Open App Folder 的本地化字符串。 /// public static string Settings_FileManagement_OpenAppDir { get { @@ -1528,7 +1555,7 @@ public static string Settings_FileManagement_OpenAppDir { } /// - /// Looks up a localized string similar to Open Crushes Folder. + /// 查找类似 Open Crushes Folder 的本地化字符串。 /// public static string Settings_FileManagement_OpenCrushesDir { get { @@ -1537,7 +1564,7 @@ public static string Settings_FileManagement_OpenCrushesDir { } /// - /// Looks up a localized string similar to Open Log Folder. + /// 查找类似 Open Log Folder 的本地化字符串。 /// public static string Settings_FileManagement_OpenLogDir { get { @@ -1546,7 +1573,7 @@ public static string Settings_FileManagement_OpenLogDir { } /// - /// Looks up a localized string similar to Reset Config. + /// 查找类似 Reset Config 的本地化字符串。 /// public static string Settings_FileManagement_ResetConfig { get { @@ -1555,7 +1582,7 @@ public static string Settings_FileManagement_ResetConfig { } /// - /// Looks up a localized string similar to This action will delete all app-related settings. Are you sure you want to keep going with this?. + /// 查找类似 This action will delete all app-related settings. Are you sure you want to keep going with this? 的本地化字符串。 /// public static string Settings_FileManagement_ResetConfig_DialogContent { get { @@ -1564,7 +1591,7 @@ public static string Settings_FileManagement_ResetConfig_DialogContent { } /// - /// Looks up a localized string similar to All configuration settings (config.json) will be restored to the initial state. + /// 查找类似 All configuration settings (config.json) will be restored to the initial state 的本地化字符串。 /// public static string Settings_FileManagement_ResetConfig_Subtitle { get { @@ -1573,7 +1600,7 @@ public static string Settings_FileManagement_ResetConfig_Subtitle { } /// - /// Looks up a localized string similar to Cache cleared. + /// 查找类似 Cache cleared 的本地化字符串。 /// public static string Settings_FileManagement_WebViewSettings_CacheCleared { get { @@ -1582,7 +1609,7 @@ public static string Settings_FileManagement_WebViewSettings_CacheCleared { } /// - /// Looks up a localized string similar to WebView still in use, cannot clear cache. + /// 查找类似 WebView still in use, cannot clear cache 的本地化字符串。 /// public static string Settings_FileManagement_WebViewSettings_CacheIsUsing { get { @@ -1591,7 +1618,7 @@ public static string Settings_FileManagement_WebViewSettings_CacheIsUsing { } /// - /// Looks up a localized string similar to Clear WebView2 Cache. + /// 查找类似 Clear WebView2 Cache 的本地化字符串。 /// public static string Settings_FileManagement_WebViewSettings_ClearCache { get { @@ -1600,7 +1627,7 @@ public static string Settings_FileManagement_WebViewSettings_ClearCache { } /// - /// Looks up a localized string similar to Clear the WebView2 cache used for e.g. search pages. + /// 查找类似 Clear the WebView2 cache used for e.g. search pages 的本地化字符串。 /// public static string Settings_FileManagement_WebViewSettings_ClearCache_Subtitle { get { @@ -1609,7 +1636,7 @@ public static string Settings_FileManagement_WebViewSettings_ClearCache_Subtitle } /// - /// Looks up a localized string similar to Aliyun. + /// 查找类似 Aliyun 的本地化字符串。 /// public static string Settings_PackageSource_Aliyun { get { @@ -1618,7 +1645,7 @@ public static string Settings_PackageSource_Aliyun { } /// - /// Looks up a localized string similar to Douban. + /// 查找类似 Douban 的本地化字符串。 /// public static string Settings_PackageSource_Douban { get { @@ -1627,7 +1654,7 @@ public static string Settings_PackageSource_Douban { } /// - /// Looks up a localized string similar to Test Network. + /// 查找类似 Test Network 的本地化字符串。 /// public static string Settings_PackageSource_NetworkTest { get { @@ -1636,7 +1663,7 @@ public static string Settings_PackageSource_NetworkTest { } /// - /// Looks up a localized string similar to Network Error. + /// 查找类似 Network Error 的本地化字符串。 /// public static string Settings_PackageSource_NetworkTestFailed { get { @@ -1645,7 +1672,7 @@ public static string Settings_PackageSource_NetworkTestFailed { } /// - /// Looks up a localized string similar to Testing. + /// 查找类似 Testing 的本地化字符串。 /// public static string Settings_PackageSource_NetworkTesting { get { @@ -1654,7 +1681,7 @@ public static string Settings_PackageSource_NetworkTesting { } /// - /// Looks up a localized string similar to If you are in mainland China, we recommend choosing a non-PyPI source. + /// 查找类似 If you are in mainland China, we recommend choosing a non-PyPI source 的本地化字符串。 /// public static string Settings_PackageSource_Notice { get { @@ -1663,7 +1690,7 @@ public static string Settings_PackageSource_Notice { } /// - /// Looks up a localized string similar to PyPI Official. + /// 查找类似 PyPI Official 的本地化字符串。 /// public static string Settings_PackageSource_Official { get { @@ -1672,7 +1699,7 @@ public static string Settings_PackageSource_Official { } /// - /// Looks up a localized string similar to Installing and downloading packages via PyPI or other mirror sites. + /// 查找类似 Installing and downloading packages via PyPI or other mirror sites 的本地化字符串。 /// public static string Settings_PackageSource_Subtitle { get { @@ -1681,7 +1708,7 @@ public static string Settings_PackageSource_Subtitle { } /// - /// Looks up a localized string similar to Tsinghua. + /// 查找类似 Tsinghua 的本地化字符串。 /// public static string Settings_PackageSource_Tsinghua { get { @@ -1690,7 +1717,7 @@ public static string Settings_PackageSource_Tsinghua { } /// - /// Looks up a localized string similar to Crush files will be deleted after more than {0} items. + /// 查找类似 Crush files will be deleted after more than {0} items 的本地化字符串。 /// public static string Settings_PersonalizationCrushesAutoDeletion_Tip { get { @@ -1699,7 +1726,7 @@ public static string Settings_PersonalizationCrushesAutoDeletion_Tip { } /// - /// Looks up a localized string similar to Log files will be deleted after more than {0} items. + /// 查找类似 Log files will be deleted after more than {0} items 的本地化字符串。 /// public static string Settings_PersonalizationLogAutoDeletion_Tip { get { @@ -1708,7 +1735,7 @@ public static string Settings_PersonalizationLogAutoDeletion_Tip { } /// - /// Looks up a localized string similar to Dark. + /// 查找类似 Dark 的本地化字符串。 /// public static string Settings_PersonalizationTheme_Dark { get { @@ -1717,7 +1744,7 @@ public static string Settings_PersonalizationTheme_Dark { } /// - /// Looks up a localized string similar to Light. + /// 查找类似 Light 的本地化字符串。 /// public static string Settings_PersonalizationTheme_Light { get { @@ -1726,7 +1753,7 @@ public static string Settings_PersonalizationTheme_Light { } /// - /// Looks up a localized string similar to Crushes Auto Deletion. + /// 查找类似 Crushes Auto Deletion 的本地化字符串。 /// public static string Settings_PersonalizationTitle_CrushesAutoDeletion { get { @@ -1735,7 +1762,7 @@ public static string Settings_PersonalizationTitle_CrushesAutoDeletion { } /// - /// Looks up a localized string similar to Language. + /// 查找类似 Language 的本地化字符串。 /// public static string Settings_PersonalizationTitle_Language { get { @@ -1744,7 +1771,7 @@ public static string Settings_PersonalizationTitle_Language { } /// - /// Looks up a localized string similar to Set language. + /// 查找类似 Set language 的本地化字符串。 /// public static string Settings_PersonalizationTitle_Language_Subtitle { get { @@ -1753,7 +1780,7 @@ public static string Settings_PersonalizationTitle_Language_Subtitle { } /// - /// Looks up a localized string similar to Log Auto Deletion. + /// 查找类似 Log Auto Deletion 的本地化字符串。 /// public static string Settings_PersonalizationTitle_LogAutoDeletion { get { @@ -1762,7 +1789,7 @@ public static string Settings_PersonalizationTitle_LogAutoDeletion { } /// - /// Looks up a localized string similar to Set the log file number limit. + /// 查找类似 Set the log file number limit 的本地化字符串。 /// public static string Settings_PersonalizationTitle_LogAutoDeletion_Subtitle { get { @@ -1771,7 +1798,7 @@ public static string Settings_PersonalizationTitle_LogAutoDeletion_Subtitle { } /// - /// Looks up a localized string similar to Theme. + /// 查找类似 Theme 的本地化字符串。 /// public static string Settings_PersonalizationTitle_Theme { get { @@ -1780,7 +1807,7 @@ public static string Settings_PersonalizationTitle_Theme { } /// - /// Looks up a localized string similar to Change window theme. + /// 查找类似 Change window theme 的本地化字符串。 /// public static string Settings_PersonalizationTitle_Theme_Subtitle { get { @@ -1789,7 +1816,7 @@ public static string Settings_PersonalizationTitle_Theme_Subtitle { } /// - /// Looks up a localized string similar to Changes will take effect after the application is restarted. + /// 查找类似 Changes will take effect after the application is restarted 的本地化字符串。 /// public static string Snackbar_effectAfterRestart { get { @@ -1798,7 +1825,7 @@ public static string Snackbar_effectAfterRestart { } /// - /// Looks up a localized string similar to Install Package. + /// 查找类似 Install Package 的本地化字符串。 /// public static string TrayMenu_Install { get { diff --git a/src/PipManager/Languages/Lang.resx b/src/PipManager/Languages/Lang.resx index 6fc5f0a..66c2675 100644 --- a/src/PipManager/Languages/Lang.resx +++ b/src/PipManager/Languages/Lang.resx @@ -699,4 +699,13 @@ Copied to clipboard + + Action Cancelled + + + Action Already Running + + + Cancel + \ No newline at end of file diff --git a/src/PipManager/Languages/Lang.zh-cn.resx b/src/PipManager/Languages/Lang.zh-cn.resx index 7723af0..faecdc1 100644 --- a/src/PipManager/Languages/Lang.zh-cn.resx +++ b/src/PipManager/Languages/Lang.zh-cn.resx @@ -699,4 +699,13 @@ 已复制 + + 任务已取消 + + + 任务已运行 + + + 取消 + \ No newline at end of file diff --git a/src/PipManager/PipManager.csproj b/src/PipManager/PipManager.csproj index cb198a3..38810f3 100644 --- a/src/PipManager/PipManager.csproj +++ b/src/PipManager/PipManager.csproj @@ -29,6 +29,7 @@ + diff --git a/src/PipManager/Services/Action/ActionService.cs b/src/PipManager/Services/Action/ActionService.cs index f9f2183..b695a28 100644 --- a/src/PipManager/Services/Action/ActionService.cs +++ b/src/PipManager/Services/Action/ActionService.cs @@ -6,13 +6,15 @@ using System.Collections.ObjectModel; using System.IO; using System.Text; +using Meziantou.Framework.WPF.Collections; +using System.Buffers; namespace PipManager.Services.Action; public class ActionService(IEnvironmentService environmentService, IToastService toastService) : IActionService { - public ObservableCollection ActionList { get; set; } = []; + public ConcurrentObservableCollection ActionList { get; set; } = []; public ObservableCollection ExceptionList { get; set; } = []; public void AddOperation(ActionListItem actionListItem) @@ -21,6 +23,17 @@ public void AddOperation(ActionListItem actionListItem) ActionList.Add(actionListItem); } + public string TryCancelOperation(string operationId) + { + var targetAction = ActionList.ToList().FindIndex(action => action.OperationId == operationId); + if (ActionList[targetAction].OperationStatus != Lang.Action_CurrentStatus_WaitingInQueue) + { + return Lang.Action_OperationCanceled_AlreadyRunning; + } + ActionList.Remove(ActionList[targetAction]); + return Lang.Action_OperationCanceled_Success; + } + public void Runner() { // TODO: Refactor (FUCKING MESSY COMMAND and output) diff --git a/src/PipManager/Services/Action/IActionService.cs b/src/PipManager/Services/Action/IActionService.cs index 8b2592d..fc43d29 100644 --- a/src/PipManager/Services/Action/IActionService.cs +++ b/src/PipManager/Services/Action/IActionService.cs @@ -1,14 +1,17 @@ -using PipManager.Models.Action; +using Meziantou.Framework.WPF.Collections; +using PipManager.Models.Action; using System.Collections.ObjectModel; namespace PipManager.Services.Action; public interface IActionService { - public ObservableCollection ActionList { get; set; } + public ConcurrentObservableCollection ActionList { get; set; } public ObservableCollection ExceptionList { get; set; } public void AddOperation(ActionListItem actionListItem); + public string? TryCancelOperation(string operationId); + public void Runner(); } \ No newline at end of file diff --git a/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs b/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs index 7c7367e..fcc45f3 100644 --- a/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs @@ -1,5 +1,8 @@ -using PipManager.Models.Action; +using Meziantou.Framework.WPF.Collections; +using PipManager.Languages; +using PipManager.Models.Action; using PipManager.Services.Action; +using PipManager.Services.Toast; using PipManager.Views.Pages.Action; using Serilog; using System.Collections.ObjectModel; @@ -13,15 +16,17 @@ public partial class ActionViewModel : ObservableObject, INavigationAware private bool _isInitialized; [ObservableProperty] - private ObservableCollection _actions; + private ConcurrentObservableCollection _actions; private readonly IActionService _actionService; + private readonly IToastService _toastService; private readonly INavigationService _navigationService; - public ActionViewModel(IActionService actionService, INavigationService navigationService) + public ActionViewModel(IActionService actionService, INavigationService navigationService, IToastService toastService) { _actionService = actionService; _navigationService = navigationService; + _toastService = toastService; Actions = _actionService.ActionList; } @@ -46,4 +51,22 @@ private void ShowExceptions() { _navigationService.NavigateWithHierarchy(typeof(ActionExceptionPage)); } + + [RelayCommand] + private void CancelAction(string? operationId) + { + if (!string.IsNullOrEmpty(operationId)) + { + var result = _actionService.TryCancelOperation(operationId); + if(result == Lang.Action_OperationCanceled_AlreadyRunning) + { + _toastService.Error(Lang.Action_OperationCanceled_AlreadyRunning); + } + else + { + _toastService.Success(Lang.Action_OperationCanceled_Success); + + } + } + } } \ No newline at end of file diff --git a/src/PipManager/Views/Pages/Action/ActionPage.xaml b/src/PipManager/Views/Pages/Action/ActionPage.xaml index 7d5dfbb..171afa9 100644 --- a/src/PipManager/Views/Pages/Action/ActionPage.xaml +++ b/src/PipManager/Views/Pages/Action/ActionPage.xaml @@ -1,4 +1,5 @@ + ItemsSource="{Binding ViewModel.Actions.AsObservable}"> + From 51ce98006bd1fd1d738c05df7dc6b7e55473aa4d Mon Sep 17 00:00:00 2001 From: AuroraZiling <2935876049@qq.com> Date: Sun, 31 Mar 2024 13:55:39 +0800 Subject: [PATCH 04/15] fix: broken ui --- README.md | 30 ------------------- .../Pages/Library/LibraryInstallPage.xaml | 7 ++--- 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 2a312fb..5e46c93 100644 --- a/README.md +++ b/README.md @@ -74,36 +74,8 @@ Double click `PipManager.exe` or `PipManager_withRuntime.exe` *If you have not i

(back to top)

-## Roadmap - -### Features - -- [x] Install Package - - [x] Default *pip install* - - [x] requirements.txt Import - - [x] Download Distributions - - [ ] Install via distributions - - [ ] Install via VCS -- [x] Update Package -- [x] Delete Package -- [x] Show Packages in list -- [x] Multi-environment Management -- [x] Search Package -- [ ] Dependency Completion Check -- [ ] Scenario Recommendation -- [ ] Cache Management -- [ ] Tools - - [ ] Embedded Lite Python Script Editor - -### Long-term - -- Logging -- Localization -- Rules of action exceptions - See the [Open Issues](https://github.com/AuroraZiling/PipManager/issues) for a full list of proposed features (and known issues). -

(back to top)

## Contributing @@ -113,8 +85,6 @@ See the [Open Issues](https://github.com/AuroraZiling/PipManager/issues) for a f 4. Push to the Branch `development` 5. Open a Pull Request -

(back to top)

- ## License Distributed under the MIT License. See `LICENSE` for more information. diff --git a/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml b/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml index 510190f..80e28a2 100644 --- a/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml +++ b/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml @@ -100,7 +100,6 @@
- - + + Date: Sun, 31 Mar 2024 14:27:25 +0800 Subject: [PATCH 05/15] perf: reasonable action exception help --- .../Services/Action/ActionService.cs | 3 +- .../ViewModels/Pages/About/AboutViewModel.cs | 1 + .../Pages/Action/ActionExceptionViewModel.cs | 34 +++++++++++++++---- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/PipManager/Services/Action/ActionService.cs b/src/PipManager/Services/Action/ActionService.cs index b695a28..263c068 100644 --- a/src/PipManager/Services/Action/ActionService.cs +++ b/src/PipManager/Services/Action/ActionService.cs @@ -36,7 +36,6 @@ public string TryCancelOperation(string operationId) public void Runner() { - // TODO: Refactor (FUCKING MESSY COMMAND and output) while (true) { if (ActionList.Count > 0) @@ -208,7 +207,7 @@ public void Runner() { toastService.Error(Lang.Action_IssueDetectedToast); }); - currentAction.ConsoleError = consoleError.ToString(); + currentAction.ConsoleError = consoleError.ToString().TrimEnd(); ExceptionList.Add(currentAction); } Thread.Sleep(100); diff --git a/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs b/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs index 1bcceae..6d45714 100644 --- a/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs +++ b/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs @@ -39,6 +39,7 @@ private void InitializeViewModel() new AboutNugetLibraryListItem("Antelcat.I18N.WPF", "MIT", "Copyright (c) 2023 Feast", "https://github.com/Antelcat/Antelcat.I18N"), new AboutNugetLibraryListItem("CommunityToolkit.Mvvm", "MIT", "Copyright © .NET Foundation and Contributors", "https://github.com/CommunityToolkit/dotnet"), new AboutNugetLibraryListItem("HtmlAgilityPack", "MIT", "Copyright © ZZZ Projects Inc.", "https://github.com/zzzprojects/html-agility-pack"), + new AboutNugetLibraryListItem("Meziantou.Framework.WPF", "MIT", "Copyright (c) 2019 Gérald Barré", "https://github.com/meziantou/Meziantou.Framework"), new AboutNugetLibraryListItem("Microsoft.Extensions.Hosting", "MIT", "Copyright © .NET Foundation and Contributors", "https://github.com/dotnet/runtime"), new AboutNugetLibraryListItem("Microsoft.Web.WebView2", "Custom License", "© Microsoft Corporation. All rights reserved.", "https://github.com/dotnet/runtime"), new AboutNugetLibraryListItem("Microsoft.Xaml.Behaviors.Wpf", "MIT", "Copyright (c) 2015 Microsoft", "https://github.com/microsoft/XamlBehaviorsWpf"), diff --git a/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs b/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs index 389deff..cb13424 100644 --- a/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs @@ -5,6 +5,8 @@ using Serilog; using System.Collections.ObjectModel; using System.Diagnostics; +using System.IO; +using System.Text; using System.Web; using Wpf.Ui.Controls; @@ -44,17 +46,35 @@ private void InitializeViewModel() Log.Information("[Action][Exceptions] Initialized"); } - public void UpdateActionExceptionList() + private void UpdateActionExceptionList() { Exceptions = new ObservableCollection(_actionService.ExceptionList); } + private static string ExceptionFilter(string parameter) + { + var exceptionBuilder = new StringBuilder(); + using (StringReader reader = new (parameter)) + { + while (reader.ReadLine() is { } line) + { + line = line.Trim(); + if (line.StartsWith("ERROR")) + { + exceptionBuilder.Append(line).Append(' '); + } + } + } + + return exceptionBuilder.ToString(); + } + [RelayCommand] private static void ExceptionBingSearch(string? parameter) { if (parameter != null) { - Process.Start(new ProcessStartInfo($"https://bing.com/search?q={HttpUtility.UrlEncode(parameter)}") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo($"https://bing.com/search?q={HttpUtility.UrlEncode(ExceptionFilter(parameter))}") { UseShellExecute = true }); } } @@ -63,17 +83,19 @@ private static void ExceptionGoogleSearch(string? parameter) { if (parameter != null) { - Process.Start(new ProcessStartInfo($"https://www.google.com/search?q={HttpUtility.UrlEncode(parameter)}") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo($"https://www.google.com/search?q={HttpUtility.UrlEncode(ExceptionFilter(parameter))}") { UseShellExecute = true }); } } [RelayCommand] private void ExceptionCopyToClipboard(string? parameter) { - if (parameter != null) + if (parameter == null) { - Clipboard.SetDataObject(parameter); - _toastService.Success(Lang.ActionException_CopyToClipboardNotice); + return; } + + Clipboard.SetDataObject(ExceptionFilter(parameter)); + _toastService.Success(Lang.ActionException_CopyToClipboardNotice); } } \ No newline at end of file From 8b7799cd335cc8dea8cd5bd23fd68a4cd3ac1a18 Mon Sep 17 00:00:00 2001 From: AuroraZiling <2935876049@qq.com> Date: Sun, 31 Mar 2024 16:15:08 +0800 Subject: [PATCH 06/15] build: Qodana --- src/.github/workflows/qodana_code_quality.yml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/.github/workflows/qodana_code_quality.yml diff --git a/src/.github/workflows/qodana_code_quality.yml b/src/.github/workflows/qodana_code_quality.yml new file mode 100644 index 0000000..1fe63bd --- /dev/null +++ b/src/.github/workflows/qodana_code_quality.yml @@ -0,0 +1,20 @@ +name: Qodana +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + - development + +jobs: + qodana: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: 'Qodana Scan' + uses: JetBrains/qodana-action@v2023.3 + env: + QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} \ No newline at end of file From 5058554a77aa4383ccf483acd13f1bd7dfa825dc Mon Sep 17 00:00:00 2001 From: AuroraZiling <2935876049@qq.com> Date: Sun, 31 Mar 2024 16:15:53 +0800 Subject: [PATCH 07/15] perf: refactor action service command --- src/PipManager/Models/Action/ActionListItem.cs | 6 +++--- .../Models/Pages/LibraryInstallPackageItem.cs | 4 ++-- src/PipManager/Services/Action/ActionService.cs | 14 +++++++------- .../Services/Environment/EnvironmentService.cs | 5 +++-- .../Services/Environment/IEnvironmentService.cs | 2 +- .../Pages/Environment/EnvironmentViewModel.cs | 2 +- .../ViewModels/Pages/Lab/LabViewModel.cs | 2 +- .../ViewModels/Pages/Library/LibraryViewModel.cs | 4 ++-- 8 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/PipManager/Models/Action/ActionListItem.cs b/src/PipManager/Models/Action/ActionListItem.cs index feb1295..267b329 100644 --- a/src/PipManager/Models/Action/ActionListItem.cs +++ b/src/PipManager/Models/Action/ActionListItem.cs @@ -5,7 +5,7 @@ namespace PipManager.Models.Action; public partial class ActionListItem : ObservableObject { - public ActionListItem(ActionType operationType, string operationCommand, string displayCommand = "", string path = "", string[]? extraParameters = null, bool progressIntermediate = false, int totalSubTaskNumber = 1) + public ActionListItem(ActionType operationType, string[] operationCommand, string displayCommand = "", string path = "", string[]? extraParameters = null, bool progressIntermediate = false, int totalSubTaskNumber = 1) { OperationType = operationType; OperationCommand = operationCommand; @@ -15,7 +15,7 @@ public ActionListItem(ActionType operationType, string operationCommand, string ExtraParameters = extraParameters; DisplayCommand = displayCommand switch { - "" => operationCommand, + "" => string.Join(' ', operationCommand), _ => displayCommand, }; OperationDescription = operationType switch @@ -55,7 +55,7 @@ public ActionListItem(ActionType operationType, string operationCommand, string public ActionType OperationType { get; set; } public string OperationDescription { get; set; } public string OperationTimestamp { get; set; } = DateTime.Now.ToLocalTime().ToString("yyyy-M-d HH:mm:ss"); - public string OperationCommand { get; set; } + public string[] OperationCommand { get; set; } public string DisplayCommand { get; set; } public string Path { get; set; } public string[]? ExtraParameters { get; set; } diff --git a/src/PipManager/Models/Pages/LibraryInstallPackageItem.cs b/src/PipManager/Models/Pages/LibraryInstallPackageItem.cs index 828348c..e1b0ea2 100644 --- a/src/PipManager/Models/Pages/LibraryInstallPackageItem.cs +++ b/src/PipManager/Models/Pages/LibraryInstallPackageItem.cs @@ -3,8 +3,8 @@ public class LibraryInstallPackageItem { public string? PackageName { get; set; } - public bool VersionSpecified { get; set; } = false; - public string VersionSpecifiedType { get; set; } = "~="; + public bool VersionSpecified { get; set; } + public string? DistributionFilePath { get; set; } // Distribution Install Only public string TargetVersion { get; set; } = string.Empty; public List? AvailableVersions { get; set; } } \ No newline at end of file diff --git a/src/PipManager/Services/Action/ActionService.cs b/src/PipManager/Services/Action/ActionService.cs index 263c068..be86491 100644 --- a/src/PipManager/Services/Action/ActionService.cs +++ b/src/PipManager/Services/Action/ActionService.cs @@ -49,7 +49,7 @@ public void Runner() { case ActionType.Uninstall: { - var queue = currentAction.OperationCommand.Split(' '); + var queue = currentAction.OperationCommand; foreach (var item in queue) { currentAction.OperationStatus = $"Uninstalling {item}"; @@ -76,7 +76,7 @@ public void Runner() case ActionType.Install: { - var queue = currentAction.OperationCommand.Split(' '); + var queue = currentAction.OperationCommand; foreach (var item in queue) { currentAction.OperationStatus = $"Installing {item}"; @@ -91,7 +91,7 @@ public void Runner() { currentAction.ConsoleOutput += '\n' + eventArgs.Data.Trim(); } - }); + }, extraParameters: currentAction.ExtraParameters); currentAction.CompletedSubTaskNumber++; if (!result.Success) { @@ -109,8 +109,8 @@ public void Runner() case ActionType.InstallByRequirements: { var requirementsTempFilePath = Path.Combine(AppInfo.CachesDir, $"temp_install_requirements_{currentAction.OperationId}.txt"); - File.WriteAllText(requirementsTempFilePath, currentAction.OperationCommand); - currentAction.OperationStatus = $"Installing from requirements.txt"; + File.WriteAllText(requirementsTempFilePath, currentAction.OperationCommand[0]); + currentAction.OperationStatus = "Installing from requirements.txt"; var result = environmentService.InstallByRequirements(requirementsTempFilePath, (sender, eventArgs) => { if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) @@ -134,7 +134,7 @@ public void Runner() } case ActionType.Download: { - var queue = currentAction.OperationCommand.Split(' '); + var queue = currentAction.OperationCommand; foreach (var item in queue) { currentAction.OperationStatus = $"Downloading {item}"; @@ -166,7 +166,7 @@ public void Runner() } case ActionType.Update: { - var queue = currentAction.OperationCommand.Split(' '); + var queue = currentAction.OperationCommand; foreach (var item in queue) { currentAction.OperationStatus = $"Updating {item}"; diff --git a/src/PipManager/Services/Environment/EnvironmentService.cs b/src/PipManager/Services/Environment/EnvironmentService.cs index 8b4b545..af53b6d 100644 --- a/src/PipManager/Services/Environment/EnvironmentService.cs +++ b/src/PipManager/Services/Environment/EnvironmentService.cs @@ -229,15 +229,16 @@ public async Task GetVersions(string packageName) } } - public ActionResponse Install(string packageName, DataReceivedEventHandler consoleOutputCallback) + public ActionResponse Install(string packageName, DataReceivedEventHandler consoleOutputCallback, string[]? extraParameters = null) { + string? extra = extraParameters != null ? string.Join(" ", extraParameters) : null; var process = new Process { StartInfo = new ProcessStartInfo { FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, Arguments = - $"-m pip install \"{packageName}\" -i {configurationService.GetUrlFromPackageSourceType()} --retries 1 --timeout 6", + $"-m pip install \"{packageName}\" -i {configurationService.GetUrlFromPackageSourceType()} --retries 1 --timeout 6 {extra}", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, diff --git a/src/PipManager/Services/Environment/IEnvironmentService.cs b/src/PipManager/Services/Environment/IEnvironmentService.cs index ba5f5c0..0ec592c 100644 --- a/src/PipManager/Services/Environment/IEnvironmentService.cs +++ b/src/PipManager/Services/Environment/IEnvironmentService.cs @@ -15,7 +15,7 @@ public interface IEnvironmentService public Task GetVersions(string packageName); - public ActionResponse Install(string packageName, DataReceivedEventHandler consoleOutputCallback); + public ActionResponse Install(string packageName, DataReceivedEventHandler consoleOutputCallback, string[]? extraParameters = null); public ActionResponse InstallByRequirements(string requirementsFilePath, DataReceivedEventHandler consoleOutputCallback); diff --git a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs index 7eaca89..e8f0996 100644 --- a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs @@ -129,7 +129,7 @@ await Task.Run(async () => actionService.AddOperation(new ActionListItem ( ActionType.Update, - "pip", + ["pip"], progressIntermediate: false, totalSubTaskNumber: 1 )); diff --git a/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs b/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs index 91ca5d5..f461853 100644 --- a/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Lab/LabViewModel.cs @@ -16,7 +16,7 @@ private void ActionTest() actionService.AddOperation(new ActionListItem ( ActionType.Install, - "pytorch", + ["pytorch"], totalSubTaskNumber: 1, progressIntermediate: false )); diff --git a/src/PipManager/ViewModels/Pages/Library/LibraryViewModel.cs b/src/PipManager/ViewModels/Pages/Library/LibraryViewModel.cs index 9fe0121..2628ecb 100644 --- a/src/PipManager/ViewModels/Pages/Library/LibraryViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Library/LibraryViewModel.cs @@ -94,7 +94,7 @@ private async Task DeletePackageAsync() _actionService.AddOperation(new ActionListItem ( ActionType.Uninstall, - command.Trim(), + command.Trim().Split(' '), progressIntermediate: false, totalSubTaskNumber: selected.Count )); @@ -141,7 +141,7 @@ await Task.Run(() => _actionService.AddOperation(new ActionListItem ( ActionType.Update, - operationList.Trim(), + operationList.Trim().Split(' '), progressIntermediate: false, totalSubTaskNumber: msgList.Count )); From 8a78fab03bf5d4af8e8eabb9dd719d79329c35be Mon Sep 17 00:00:00 2001 From: AuroraZiling <2935876049@qq.com> Date: Sun, 31 Mar 2024 17:05:00 +0800 Subject: [PATCH 08/15] feat: install via distributions --- src/PipManager/AppStarting.cs | 13 +- src/PipManager/Languages/Lang.Designer.cs | 462 ++++++++++-------- src/PipManager/Languages/Lang.resx | 15 + src/PipManager/Languages/Lang.zh-cn.resx | 15 + src/PipManager/PipManager.csproj | 1 + .../Pages/Library/LibraryInstallViewModel.cs | 161 +++++- .../Pages/Library/LibraryInstallPage.xaml | 83 +++- 7 files changed, 533 insertions(+), 217 deletions(-) diff --git a/src/PipManager/AppStarting.cs b/src/PipManager/AppStarting.cs index b1abef8..39fe59f 100644 --- a/src/PipManager/AppStarting.cs +++ b/src/PipManager/AppStarting.cs @@ -115,6 +115,17 @@ public void CachesDeletion() var directoryInfo = new DirectoryInfo(AppInfo.CachesDir); var filesInfo = directoryInfo.GetFileSystemInfos(); var cacheFileAmount = 0; + foreach (var subDir in directoryInfo.GetDirectories("tempTarGz-*", SearchOption.AllDirectories)) + { + try + { + subDir.Delete(true); + } + catch (Exception ex) + { + // ignored + } + } foreach (var file in filesInfo) { if (file.Name.StartsWith("temp_")) @@ -126,7 +137,7 @@ public void CachesDeletion() } catch { - continue; + // ignored } } } diff --git a/src/PipManager/Languages/Lang.Designer.cs b/src/PipManager/Languages/Lang.Designer.cs index 0c5e8ba..a67b7ca 100644 --- a/src/PipManager/Languages/Lang.Designer.cs +++ b/src/PipManager/Languages/Lang.Designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 +// This code was generated by a tool. // -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -13,12 +12,12 @@ namespace PipManager.Languages { /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// A strongly-typed resource class, for looking up localized strings, etc. /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] @@ -33,7 +32,7 @@ internal Lang() { } /// - /// 返回此类使用的缓存的 ResourceManager 实例。 + /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { @@ -47,8 +46,8 @@ internal Lang() { } /// - /// 重写当前线程的 CurrentUICulture 属性,对 - /// 使用此强类型资源类的所有资源查找执行重写。 + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { @@ -61,7 +60,7 @@ internal Lang() { } /// - /// 查找类似 Document 的本地化字符串。 + /// Looks up a localized string similar to Document. /// public static string About_Document { get { @@ -70,7 +69,7 @@ public static string About_Document { } /// - /// 查找类似 Github Discussion 的本地化字符串。 + /// Looks up a localized string similar to Github Discussion. /// public static string About_GithubDiscussion { get { @@ -79,7 +78,7 @@ public static string About_GithubDiscussion { } /// - /// 查找类似 Github Issue 的本地化字符串。 + /// Looks up a localized string similar to Github Issue. /// public static string About_GithubIssue { get { @@ -88,7 +87,7 @@ public static string About_GithubIssue { } /// - /// 查找类似 Github Repo 的本地化字符串。 + /// Looks up a localized string similar to Github Repo. /// public static string About_GithubRepo { get { @@ -97,7 +96,7 @@ public static string About_GithubRepo { } /// - /// 查找类似 More Information 的本地化字符串。 + /// Looks up a localized string similar to More Information. /// public static string About_MoreInformation { get { @@ -106,7 +105,7 @@ public static string About_MoreInformation { } /// - /// 查找类似 Open Source License 的本地化字符串。 + /// Looks up a localized string similar to Open Source License. /// public static string About_MoreInformation_OpenSourceLicense { get { @@ -115,7 +114,7 @@ public static string About_MoreInformation_OpenSourceLicense { } /// - /// 查找类似 Privacy 的本地化字符串。 + /// Looks up a localized string similar to Privacy. /// public static string About_MoreInformation_Privacy { get { @@ -124,7 +123,7 @@ public static string About_MoreInformation_Privacy { } /// - /// 查找类似 Pip Manager will not upload any of your information. 的本地化字符串。 + /// Looks up a localized string similar to Pip Manager will not upload any of your information.. /// public static string About_MoreInformation_PrivacyLine1 { get { @@ -133,7 +132,7 @@ public static string About_MoreInformation_PrivacyLine1 { } /// - /// 查找类似 Pip Manager collects all data locally and stores it in the config.json file in the application directory. 的本地化字符串。 + /// Looks up a localized string similar to Pip Manager collects all data locally and stores it in the config.json file in the application directory.. /// public static string About_MoreInformation_PrivacyLine2 { get { @@ -142,7 +141,7 @@ public static string About_MoreInformation_PrivacyLine2 { } /// - /// 查找类似 Pip Manager does not modify the registry. 的本地化字符串。 + /// Looks up a localized string similar to Pip Manager does not modify the registry.. /// public static string About_MoreInformation_PrivacyLine3 { get { @@ -151,7 +150,7 @@ public static string About_MoreInformation_PrivacyLine3 { } /// - /// 查找类似 Added {0} new operation(s) 的本地化字符串。 + /// Looks up a localized string similar to Added {0} new operation(s). /// public static string Action_AddOperation_Toast { get { @@ -160,7 +159,7 @@ public static string Action_AddOperation_Toast { } /// - /// 查找类似 Exceptions 的本地化字符串。 + /// Looks up a localized string similar to Exceptions. /// public static string Action_Button_Exceptions { get { @@ -169,7 +168,7 @@ public static string Action_Button_Exceptions { } /// - /// 查找类似 Command 的本地化字符串。 + /// Looks up a localized string similar to Command. /// public static string Action_Command { get { @@ -178,7 +177,7 @@ public static string Action_Command { } /// - /// 查找类似 Completed 的本地化字符串。 + /// Looks up a localized string similar to Completed. /// public static string Action_Completed { get { @@ -187,7 +186,7 @@ public static string Action_Completed { } /// - /// 查找类似 Error 的本地化字符串。 + /// Looks up a localized string similar to Error. /// public static string Action_ConsoleError { get { @@ -196,7 +195,7 @@ public static string Action_ConsoleError { } /// - /// 查找类似 No errors detected 的本地化字符串。 + /// Looks up a localized string similar to No errors detected. /// public static string Action_ConsoleError_Empty { get { @@ -205,7 +204,7 @@ public static string Action_ConsoleError_Empty { } /// - /// 查找类似 Output 的本地化字符串。 + /// Looks up a localized string similar to Output. /// public static string Action_ConsoleOutput { get { @@ -214,7 +213,7 @@ public static string Action_ConsoleOutput { } /// - /// 查找类似 Current Status 的本地化字符串。 + /// Looks up a localized string similar to Current Status. /// public static string Action_CurrentStatus { get { @@ -223,7 +222,7 @@ public static string Action_CurrentStatus { } /// - /// 查找类似 Waiting in queue 的本地化字符串。 + /// Looks up a localized string similar to Waiting in queue. /// public static string Action_CurrentStatus_WaitingInQueue { get { @@ -232,7 +231,7 @@ public static string Action_CurrentStatus_WaitingInQueue { } /// - /// 查找类似 Issue 的本地化字符串。 + /// Looks up a localized string similar to Issue. /// public static string Action_IssueDetected { get { @@ -241,7 +240,7 @@ public static string Action_IssueDetected { } /// - /// 查找类似 Issue detected in Action 的本地化字符串。 + /// Looks up a localized string similar to Issue detected in Action. /// public static string Action_IssueDetectedToast { get { @@ -250,7 +249,7 @@ public static string Action_IssueDetectedToast { } /// - /// 查找类似 No Current Operations 的本地化字符串。 + /// Looks up a localized string similar to No Current Operations. /// public static string Action_NoCurrentOperations { get { @@ -259,7 +258,7 @@ public static string Action_NoCurrentOperations { } /// - /// 查找类似 Cancel 的本地化字符串。 + /// Looks up a localized string similar to Cancel. /// public static string Action_Operation_Cancel { get { @@ -268,7 +267,7 @@ public static string Action_Operation_Cancel { } /// - /// 查找类似 Download 的本地化字符串。 + /// Looks up a localized string similar to Download. /// public static string Action_Operation_Download { get { @@ -277,7 +276,7 @@ public static string Action_Operation_Download { } /// - /// 查找类似 Package Install 的本地化字符串。 + /// Looks up a localized string similar to Package Install. /// public static string Action_Operation_Install { get { @@ -286,7 +285,7 @@ public static string Action_Operation_Install { } /// - /// 查找类似 Package Install (via requirements.txt) 的本地化字符串。 + /// Looks up a localized string similar to Package Install (via requirements.txt). /// public static string Action_Operation_InstallByRequirements { get { @@ -295,7 +294,7 @@ public static string Action_Operation_InstallByRequirements { } /// - /// 查找类似 Package Uninstallation 的本地化字符串。 + /// Looks up a localized string similar to Package Uninstallation. /// public static string Action_Operation_Uninstall { get { @@ -304,7 +303,7 @@ public static string Action_Operation_Uninstall { } /// - /// 查找类似 Package Update 的本地化字符串。 + /// Looks up a localized string similar to Package Update. /// public static string Action_Operation_Update { get { @@ -313,7 +312,7 @@ public static string Action_Operation_Update { } /// - /// 查找类似 Action Already Running 的本地化字符串。 + /// Looks up a localized string similar to Action Already Running. /// public static string Action_OperationCanceled_AlreadyRunning { get { @@ -322,7 +321,7 @@ public static string Action_OperationCanceled_AlreadyRunning { } /// - /// 查找类似 Action Cancelled 的本地化字符串。 + /// Looks up a localized string similar to Action Cancelled. /// public static string Action_OperationCanceled_Success { get { @@ -331,7 +330,7 @@ public static string Action_OperationCanceled_Success { } /// - /// 查找类似 Time 的本地化字符串。 + /// Looks up a localized string similar to Time. /// public static string ActionException_Badge_Timestamp { get { @@ -340,7 +339,7 @@ public static string ActionException_Badge_Timestamp { } /// - /// 查找类似 Bing Search 的本地化字符串。 + /// Looks up a localized string similar to Bing Search. /// public static string ActionException_BingSearch { get { @@ -349,7 +348,7 @@ public static string ActionException_BingSearch { } /// - /// 查找类似 Copy to clipboard 的本地化字符串。 + /// Looks up a localized string similar to Copy to clipboard. /// public static string ActionException_CopyToClipboard { get { @@ -358,7 +357,7 @@ public static string ActionException_CopyToClipboard { } /// - /// 查找类似 Copied to clipboard 的本地化字符串。 + /// Looks up a localized string similar to Copied to clipboard. /// public static string ActionException_CopyToClipboardNotice { get { @@ -367,7 +366,7 @@ public static string ActionException_CopyToClipboardNotice { } /// - /// 查找类似 Exception 的本地化字符串。 + /// Looks up a localized string similar to Exception. /// public static string ActionException_Exception { get { @@ -376,7 +375,7 @@ public static string ActionException_Exception { } /// - /// 查找类似 Google Search 的本地化字符串。 + /// Looks up a localized string similar to Google Search. /// public static string ActionException_GoogleSearch { get { @@ -385,7 +384,7 @@ public static string ActionException_GoogleSearch { } /// - /// 查找类似 Operation 的本地化字符串。 + /// Looks up a localized string similar to Operation. /// public static string ActionException_Operation { get { @@ -394,7 +393,7 @@ public static string ActionException_Operation { } /// - /// 查找类似 Add 的本地化字符串。 + /// Looks up a localized string similar to Add. /// public static string Common_Button_Add { get { @@ -403,7 +402,7 @@ public static string Common_Button_Add { } /// - /// 查找类似 Browse 的本地化字符串。 + /// Looks up a localized string similar to Browse. /// public static string Common_Button_Browse { get { @@ -412,7 +411,7 @@ public static string Common_Button_Browse { } /// - /// 查找类似 Refresh 的本地化字符串。 + /// Looks up a localized string similar to Refresh. /// public static string Common_Button_Refresh { get { @@ -421,7 +420,7 @@ public static string Common_Button_Refresh { } /// - /// 查找类似 Caution 的本地化字符串。 + /// Looks up a localized string similar to Caution. /// public static string Common_NoticeTitle_Caution { get { @@ -430,7 +429,7 @@ public static string Common_NoticeTitle_Caution { } /// - /// 查找类似 Notice 的本地化字符串。 + /// Looks up a localized string similar to Notice. /// public static string Common_NoticeTitle_Notice { get { @@ -439,7 +438,7 @@ public static string Common_NoticeTitle_Notice { } /// - /// 查找类似 Cancel 的本地化字符串。 + /// Looks up a localized string similar to Cancel. /// public static string ContentDialog_CloseButton_Cancel { get { @@ -448,7 +447,7 @@ public static string ContentDialog_CloseButton_Cancel { } /// - /// 查找类似 There are still running background tasks. Do you confirm to exit the software? 的本地化字符串。 + /// Looks up a localized string similar to There are still running background tasks. Do you confirm to exit the software?. /// public static string ContentDialog_Message_ActionStillRunning { get { @@ -457,7 +456,7 @@ public static string ContentDialog_Message_ActionStillRunning { } /// - /// 查找类似 Environment already exists 的本地化字符串。 + /// Looks up a localized string similar to Environment already exists. /// public static string ContentDialog_Message_EnvironmentAlreadyExists { get { @@ -466,7 +465,7 @@ public static string ContentDialog_Message_EnvironmentAlreadyExists { } /// - /// 查找类似 Environment not available 的本地化字符串。 + /// Looks up a localized string similar to Environment not available. /// public static string ContentDialog_Message_EnvironmentCheckFailed { get { @@ -475,7 +474,7 @@ public static string ContentDialog_Message_EnvironmentCheckFailed { } /// - /// 查找类似 Environment available 的本地化字符串。 + /// Looks up a localized string similar to Environment available. /// public static string ContentDialog_Message_EnvironmentCheckPassed { get { @@ -484,7 +483,7 @@ public static string ContentDialog_Message_EnvironmentCheckPassed { } /// - /// 查找类似 The environment will be removed from the list 的本地化字符串。 + /// Looks up a localized string similar to The environment will be removed from the list. /// public static string ContentDialog_Message_EnvironmentDeletion { get { @@ -493,7 +492,7 @@ public static string ContentDialog_Message_EnvironmentDeletion { } /// - /// 查找类似 Error in adding environment 的本地化字符串。 + /// Looks up a localized string similar to Error in adding environment. /// public static string ContentDialog_Message_EnvironmentInvaild { get { @@ -502,7 +501,7 @@ public static string ContentDialog_Message_EnvironmentInvaild { } /// - /// 查找类似 The environment is up to date 的本地化字符串。 + /// Looks up a localized string similar to The environment is up to date. /// public static string ContentDialog_Message_EnvironmentIsLatest { get { @@ -511,7 +510,7 @@ public static string ContentDialog_Message_EnvironmentIsLatest { } /// - /// 查找类似 You didn't choose an environment 的本地化字符串。 + /// Looks up a localized string similar to You didn't choose an environment. /// public static string ContentDialog_Message_EnvironmentNoSelection { get { @@ -520,7 +519,7 @@ public static string ContentDialog_Message_EnvironmentNoSelection { } /// - /// 查找类似 New version detected. Update now? 的本地化字符串。 + /// Looks up a localized string similar to New version detected. Update now?. /// public static string ContentDialog_Message_FindUpdate { get { @@ -529,7 +528,7 @@ public static string ContentDialog_Message_FindUpdate { } /// - /// 查找类似 Following packages will be removed from the environment: 的本地化字符串。 + /// Looks up a localized string similar to Following packages will be removed from the environment:. /// public static string ContentDialog_Message_LibraryDeletionWarning { get { @@ -538,7 +537,7 @@ public static string ContentDialog_Message_LibraryDeletionWarning { } /// - /// 查找类似 Network Error 的本地化字符串。 + /// Looks up a localized string similar to Network Error. /// public static string ContentDialog_Message_NetworkError { get { @@ -547,7 +546,7 @@ public static string ContentDialog_Message_NetworkError { } /// - /// 查找类似 Package(s) are up to date 的本地化字符串。 + /// Looks up a localized string similar to Package(s) are up to date. /// public static string ContentDialog_Message_PackageIsLatest { get { @@ -556,7 +555,7 @@ public static string ContentDialog_Message_PackageIsLatest { } /// - /// 查找类似 Action 的本地化字符串。 + /// Looks up a localized string similar to Action. /// public static string ContentDialog_PrimaryButton_Action { get { @@ -565,7 +564,7 @@ public static string ContentDialog_PrimaryButton_Action { } /// - /// 查找类似 Remove Environment 的本地化字符串。 + /// Looks up a localized string similar to Remove Environment. /// public static string ContentDialog_PrimaryButton_EnvironmentDeletion { get { @@ -574,7 +573,7 @@ public static string ContentDialog_PrimaryButton_EnvironmentDeletion { } /// - /// 查找类似 Operation Warning 的本地化字符串。 + /// Looks up a localized string similar to Operation Warning. /// public static string ContentDialog_Title_AreYouSure { get { @@ -583,7 +582,7 @@ public static string ContentDialog_Title_AreYouSure { } /// - /// 查找类似 Error 的本地化字符串。 + /// Looks up a localized string similar to Error. /// public static string ContentDialog_Title_Error { get { @@ -592,7 +591,7 @@ public static string ContentDialog_Title_Error { } /// - /// 查找类似 Notice 的本地化字符串。 + /// Looks up a localized string similar to Notice. /// public static string ContentDialog_Title_Notice { get { @@ -601,7 +600,7 @@ public static string ContentDialog_Title_Notice { } /// - /// 查找类似 Success 的本地化字符串。 + /// Looks up a localized string similar to Success. /// public static string ContentDialog_Title_Success { get { @@ -610,7 +609,7 @@ public static string ContentDialog_Title_Success { } /// - /// 查找类似 Warning 的本地化字符串。 + /// Looks up a localized string similar to Warning. /// public static string ContentDialog_Title_Warning { get { @@ -619,7 +618,7 @@ public static string ContentDialog_Title_Warning { } /// - /// 查找类似 Developing 的本地化字符串。 + /// Looks up a localized string similar to Developing. /// public static string Development_Developing { get { @@ -628,7 +627,7 @@ public static string Development_Developing { } /// - /// 查找类似 Add Environment 的本地化字符串。 + /// Looks up a localized string similar to Add Environment. /// public static string Environment_Operation_AddEnvironment { get { @@ -637,7 +636,7 @@ public static string Environment_Operation_AddEnvironment { } /// - /// 查找类似 Check Update 的本地化字符串。 + /// Looks up a localized string similar to Check Update. /// public static string Environment_Operation_CheckEnvironmentUpdate { get { @@ -646,7 +645,7 @@ public static string Environment_Operation_CheckEnvironmentUpdate { } /// - /// 查找类似 Remove Environment (from list) 的本地化字符串。 + /// Looks up a localized string similar to Remove Environment (from list). /// public static string Environment_Operation_RemoveEnvironment { get { @@ -655,7 +654,7 @@ public static string Environment_Operation_RemoveEnvironment { } /// - /// 查找类似 Verify Environment 的本地化字符串。 + /// Looks up a localized string similar to Verify Environment. /// public static string Environment_Operation_VerifyEnvironment { get { @@ -664,7 +663,7 @@ public static string Environment_Operation_VerifyEnvironment { } /// - /// 查找类似 Detected Environment 的本地化字符串。 + /// Looks up a localized string similar to Detected Environment. /// public static string EnvironmentAdd_EnvironmentVariable_Header { get { @@ -673,7 +672,7 @@ public static string EnvironmentAdd_EnvironmentVariable_Header { } /// - /// 查找类似 Can't find any environment 的本地化字符串。 + /// Looks up a localized string similar to Can't find any environment. /// public static string EnvironmentAdd_EnvironmentVariable_NotFound { get { @@ -682,7 +681,7 @@ public static string EnvironmentAdd_EnvironmentVariable_NotFound { } /// - /// 查找类似 Environment Variables 的本地化字符串。 + /// Looks up a localized string similar to Environment Variables. /// public static string EnvironmentAdd_EnvironmentVariable_Title { get { @@ -691,7 +690,7 @@ public static string EnvironmentAdd_EnvironmentVariable_Title { } /// - /// 查找类似 Add Environment 的本地化字符串。 + /// Looks up a localized string similar to Add Environment. /// public static string EnvironmentAdd_Header { get { @@ -700,7 +699,7 @@ public static string EnvironmentAdd_Header { } /// - /// 查找类似 Enter Pip command 的本地化字符串。 + /// Looks up a localized string similar to Enter Pip command. /// public static string EnvironmentAdd_PipCommand_Label { get { @@ -709,7 +708,7 @@ public static string EnvironmentAdd_PipCommand_Label { } /// - /// 查找类似 If you are using "pip install", type "pip" in the box. Similarly, for "pip3.11 install", type "pip3.11". 的本地化字符串。 + /// Looks up a localized string similar to If you are using "pip install", type "pip" in the box. Similarly, for "pip3.11 install", type "pip3.11".. /// public static string EnvironmentAdd_PipCommand_Notice { get { @@ -718,7 +717,7 @@ public static string EnvironmentAdd_PipCommand_Notice { } /// - /// 查找类似 Pip Command 的本地化字符串。 + /// Looks up a localized string similar to Pip Command. /// public static string EnvironmentAdd_PipCommand_Title { get { @@ -727,7 +726,7 @@ public static string EnvironmentAdd_PipCommand_Title { } /// - /// 查找类似 Enter the absolute path of python.exe 的本地化字符串。 + /// Looks up a localized string similar to Enter the absolute path of python.exe. /// public static string EnvironmentAdd_PythonPath_Label { get { @@ -736,7 +735,7 @@ public static string EnvironmentAdd_PythonPath_Label { } /// - /// 查找类似 Python Executable Path 的本地化字符串。 + /// Looks up a localized string similar to Python Executable Path. /// public static string EnvironmentAdd_PythonPath_Title { get { @@ -745,7 +744,7 @@ public static string EnvironmentAdd_PythonPath_Title { } /// - /// 查找类似 Current: 的本地化字符串。 + /// Looks up a localized string similar to Current: . /// public static string EnvironmentCheckEnvironmentUpdate_CurrentVersion { get { @@ -754,7 +753,7 @@ public static string EnvironmentCheckEnvironmentUpdate_CurrentVersion { } /// - /// 查找类似 Latest: 的本地化字符串。 + /// Looks up a localized string similar to Latest: . /// public static string EnvironmentCheckEnvironmentUpdate_LatestVersion { get { @@ -763,7 +762,7 @@ public static string EnvironmentCheckEnvironmentUpdate_LatestVersion { } /// - /// 查找类似 Pip Manager - Unexpected Exception 的本地化字符串。 + /// Looks up a localized string similar to Pip Manager - Unexpected Exception. /// public static string ExceptionWindow_Title { get { @@ -772,7 +771,7 @@ public static string ExceptionWindow_Title { } /// - /// 查找类似 Current: {0} 的本地化字符串。 + /// Looks up a localized string similar to Current: {0}. /// public static string Library_CheckUpdate_Current { get { @@ -781,7 +780,7 @@ public static string Library_CheckUpdate_Current { } /// - /// 查找类似 Latest: {0} 的本地化字符串。 + /// Looks up a localized string similar to Latest: {0}. /// public static string Library_CheckUpdate_Latest { get { @@ -790,7 +789,7 @@ public static string Library_CheckUpdate_Latest { } /// - /// 查找类似 {0} package(s) found 的本地化字符串。 + /// Looks up a localized string similar to {0} package(s) found. /// public static string Library_Data_PackageFound { get { @@ -799,7 +798,7 @@ public static string Library_Data_PackageFound { } /// - /// 查找类似 {0} item(s) selected 的本地化字符串。 + /// Looks up a localized string similar to {0} item(s) selected. /// public static string Library_Data_SelectedItemsCount { get { @@ -808,7 +807,7 @@ public static string Library_Data_SelectedItemsCount { } /// - /// 查找类似 Add environment 的本地化字符串。 + /// Looks up a localized string similar to Add environment. /// public static string Library_Error_AddEnvironment { get { @@ -817,7 +816,7 @@ public static string Library_Error_AddEnvironment { } /// - /// 查找类似 No Environment 的本地化字符串。 + /// Looks up a localized string similar to No Environment. /// public static string Library_Error_NoEnvironment { get { @@ -826,7 +825,7 @@ public static string Library_Error_NoEnvironment { } /// - /// 查找类似 Check Update 的本地化字符串。 + /// Looks up a localized string similar to Check Update. /// public static string Library_Operation_CheckUpdate { get { @@ -835,7 +834,7 @@ public static string Library_Operation_CheckUpdate { } /// - /// 查找类似 Delete 的本地化字符串。 + /// Looks up a localized string similar to Delete. /// public static string Library_Operation_Delete { get { @@ -844,7 +843,7 @@ public static string Library_Operation_Delete { } /// - /// 查找类似 Details 的本地化字符串。 + /// Looks up a localized string similar to Details. /// public static string Library_Operation_Details { get { @@ -853,7 +852,7 @@ public static string Library_Operation_Details { } /// - /// 查找类似 Install 的本地化字符串。 + /// Looks up a localized string similar to Install. /// public static string Library_Operation_Install { get { @@ -862,7 +861,7 @@ public static string Library_Operation_Install { } /// - /// 查找类似 Dev 的本地化字符串。 + /// Looks up a localized string similar to Dev. /// public static string Library_Version_Dev { get { @@ -871,7 +870,7 @@ public static string Library_Version_Dev { } /// - /// 查找类似 Post 的本地化字符串。 + /// Looks up a localized string similar to Post. /// public static string Library_Version_Post { get { @@ -880,7 +879,7 @@ public static string Library_Version_Post { } /// - /// 查找类似 Unstable 的本地化字符串。 + /// Looks up a localized string similar to Unstable. /// public static string Library_Version_Pre { get { @@ -889,7 +888,7 @@ public static string Library_Version_Pre { } /// - /// 查找类似 Development Status 的本地化字符串。 + /// Looks up a localized string similar to Development Status. /// public static string LibraryDetail_Classifier_DevelopmentStatus { get { @@ -898,7 +897,7 @@ public static string LibraryDetail_Classifier_DevelopmentStatus { } /// - /// 查找类似 Environment 的本地化字符串。 + /// Looks up a localized string similar to Environment. /// public static string LibraryDetail_Classifier_Environment { get { @@ -907,7 +906,7 @@ public static string LibraryDetail_Classifier_Environment { } /// - /// 查找类似 Intended Audience 的本地化字符串。 + /// Looks up a localized string similar to Intended Audience. /// public static string LibraryDetail_Classifier_IntendedAudience { get { @@ -916,7 +915,7 @@ public static string LibraryDetail_Classifier_IntendedAudience { } /// - /// 查找类似 Customer Service 的本地化字符串。 + /// Looks up a localized string similar to Customer Service. /// public static string LibraryDetail_Classifier_IntendedAudience_CustomerService { get { @@ -925,7 +924,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_CustomerService { } /// - /// 查找类似 Developers 的本地化字符串。 + /// Looks up a localized string similar to Developers. /// public static string LibraryDetail_Classifier_IntendedAudience_Developers { get { @@ -934,7 +933,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Developers { } /// - /// 查找类似 Education 的本地化字符串。 + /// Looks up a localized string similar to Education. /// public static string LibraryDetail_Classifier_IntendedAudience_Education { get { @@ -943,7 +942,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Education { } /// - /// 查找类似 End Users & Desktop 的本地化字符串。 + /// Looks up a localized string similar to End Users & Desktop. /// public static string LibraryDetail_Classifier_IntendedAudience_EndUsersDesktop { get { @@ -952,7 +951,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_EndUsersDesktop { } /// - /// 查找类似 Financial and Insurance Industry 的本地化字符串。 + /// Looks up a localized string similar to Financial and Insurance Industry. /// public static string LibraryDetail_Classifier_IntendedAudience_FinancialAndInsuranceIndustry { get { @@ -961,7 +960,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_FinancialAndInsur } /// - /// 查找类似 Healthcare Industry 的本地化字符串。 + /// Looks up a localized string similar to Healthcare Industry. /// public static string LibraryDetail_Classifier_IntendedAudience_HealthcareIndustry { get { @@ -970,7 +969,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_HealthcareIndustr } /// - /// 查找类似 Information Technology 的本地化字符串。 + /// Looks up a localized string similar to Information Technology. /// public static string LibraryDetail_Classifier_IntendedAudience_InformationTechonology { get { @@ -979,7 +978,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_InformationTechon } /// - /// 查找类似 Legal Industry 的本地化字符串。 + /// Looks up a localized string similar to Legal Industry. /// public static string LibraryDetail_Classifier_IntendedAudience_LegalIndustry { get { @@ -988,7 +987,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_LegalIndustry { } /// - /// 查找类似 Manufacturing 的本地化字符串。 + /// Looks up a localized string similar to Manufacturing. /// public static string LibraryDetail_Classifier_IntendedAudience_Manufacturing { get { @@ -997,7 +996,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Manufacturing { } /// - /// 查找类似 Other 的本地化字符串。 + /// Looks up a localized string similar to Other. /// public static string LibraryDetail_Classifier_IntendedAudience_OtherAudience { get { @@ -1006,7 +1005,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_OtherAudience { } /// - /// 查找类似 Religion 的本地化字符串。 + /// Looks up a localized string similar to Religion. /// public static string LibraryDetail_Classifier_IntendedAudience_Religion { get { @@ -1015,7 +1014,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Religion { } /// - /// 查找类似 Science & Research 的本地化字符串。 + /// Looks up a localized string similar to Science & Research. /// public static string LibraryDetail_Classifier_IntendedAudience_ScienceResearch { get { @@ -1024,7 +1023,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_ScienceResearch { } /// - /// 查找类似 System Administrators 的本地化字符串。 + /// Looks up a localized string similar to System Administrators. /// public static string LibraryDetail_Classifier_IntendedAudience_SystemAdministrators { get { @@ -1033,7 +1032,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_SystemAdministrat } /// - /// 查找类似 Telecommunications Industry 的本地化字符串。 + /// Looks up a localized string similar to Telecommunications Industry. /// public static string LibraryDetail_Classifier_IntendedAudience_TelecommunicationsIndustry { get { @@ -1042,7 +1041,7 @@ public static string LibraryDetail_Classifier_IntendedAudience_Telecommunication } /// - /// 查找类似 Operating System 的本地化字符串。 + /// Looks up a localized string similar to Operating System. /// public static string LibraryDetail_Classifier_OperatingSystem { get { @@ -1051,7 +1050,7 @@ public static string LibraryDetail_Classifier_OperatingSystem { } /// - /// 查找类似 OS Independent 的本地化字符串。 + /// Looks up a localized string similar to OS Independent. /// public static string LibraryDetail_Classifier_OperatingSystem_OSIndependent { get { @@ -1060,7 +1059,7 @@ public static string LibraryDetail_Classifier_OperatingSystem_OSIndependent { } /// - /// 查找类似 Programming Language 的本地化字符串。 + /// Looks up a localized string similar to Programming Language. /// public static string LibraryDetail_Classifier_ProgrammingLanguage { get { @@ -1069,7 +1068,7 @@ public static string LibraryDetail_Classifier_ProgrammingLanguage { } /// - /// 查找类似 Topic 的本地化字符串。 + /// Looks up a localized string similar to Topic. /// public static string LibraryDetail_Classifier_Topic { get { @@ -1078,7 +1077,7 @@ public static string LibraryDetail_Classifier_Topic { } /// - /// 查找类似 Author 的本地化字符串。 + /// Looks up a localized string similar to Author. /// public static string LibraryDetail_Contact_Author { get { @@ -1087,7 +1086,7 @@ public static string LibraryDetail_Contact_Author { } /// - /// 查找类似 Email 的本地化字符串。 + /// Looks up a localized string similar to Email. /// public static string LibraryDetail_Contact_AuthorEmail { get { @@ -1096,7 +1095,7 @@ public static string LibraryDetail_Contact_AuthorEmail { } /// - /// 查找类似 Project Url 的本地化字符串。 + /// Looks up a localized string similar to Project Url. /// public static string LibraryDetail_Contact_ProjectUrl { get { @@ -1105,7 +1104,7 @@ public static string LibraryDetail_Contact_ProjectUrl { } /// - /// 查找类似 Details 的本地化字符串。 + /// Looks up a localized string similar to Details. /// public static string LibraryDetail_Header { get { @@ -1114,7 +1113,7 @@ public static string LibraryDetail_Header { } /// - /// 查找类似 Package 的本地化字符串。 + /// Looks up a localized string similar to Package. /// public static string LibraryDetail_Package { get { @@ -1123,7 +1122,7 @@ public static string LibraryDetail_Package { } /// - /// 查找类似 Path 的本地化字符串。 + /// Looks up a localized string similar to Path. /// public static string LibraryDetail_Path { get { @@ -1132,7 +1131,7 @@ public static string LibraryDetail_Path { } /// - /// 查找类似 Summary 的本地化字符串。 + /// Looks up a localized string similar to Summary. /// public static string LibraryDetail_Summary { get { @@ -1141,7 +1140,7 @@ public static string LibraryDetail_Summary { } /// - /// 查找类似 Unknown 的本地化字符串。 + /// Looks up a localized string similar to Unknown. /// public static string LibraryDetail_Unknown { get { @@ -1150,7 +1149,7 @@ public static string LibraryDetail_Unknown { } /// - /// 查找类似 Version 的本地化字符串。 + /// Looks up a localized string similar to Version. /// public static string LibraryDetail_Version { get { @@ -1159,7 +1158,7 @@ public static string LibraryDetail_Version { } /// - /// 查找类似 Package already in list 的本地化字符串。 + /// Looks up a localized string similar to Package already in list. /// public static string LibraryInstall_Add_AlreadyInList { get { @@ -1168,7 +1167,7 @@ public static string LibraryInstall_Add_AlreadyInList { } /// - /// 查找类似 Package already installed 的本地化字符串。 + /// Looks up a localized string similar to Package already installed. /// public static string LibraryInstall_Add_AlreadyInstalled { get { @@ -1177,7 +1176,7 @@ public static string LibraryInstall_Add_AlreadyInstalled { } /// - /// 查找类似 Default 的本地化字符串。 + /// Looks up a localized string similar to Default. /// public static string LibraryInstall_Add_Header { get { @@ -1186,7 +1185,7 @@ public static string LibraryInstall_Add_Header { } /// - /// 查找类似 Invalid Package Name (PEP 508) 的本地化字符串。 + /// Looks up a localized string similar to Invalid Package Name (PEP 508). /// public static string LibraryInstall_Add_InvalidPackageName { get { @@ -1195,7 +1194,7 @@ public static string LibraryInstall_Add_InvalidPackageName { } /// - /// 查找类似 Enter Package Name 的本地化字符串。 + /// Looks up a localized string similar to Enter Package Name. /// public static string LibraryInstall_Add_Notice { get { @@ -1204,7 +1203,7 @@ public static string LibraryInstall_Add_Notice { } /// - /// 查找类似 Package not found 的本地化字符串。 + /// Looks up a localized string similar to Package not found. /// public static string LibraryInstall_Add_PackageNotFound { get { @@ -1213,7 +1212,7 @@ public static string LibraryInstall_Add_PackageNotFound { } /// - /// 查找类似 Verifying 的本地化字符串。 + /// Looks up a localized string similar to Verifying. /// public static string LibraryInstall_Add_Verifying { get { @@ -1222,7 +1221,7 @@ public static string LibraryInstall_Add_Verifying { } /// - /// 查找类似 Download Distributions 的本地化字符串。 + /// Looks up a localized string similar to Download Distributions. /// public static string LibraryInstall_Download_Header { get { @@ -1231,7 +1230,7 @@ public static string LibraryInstall_Download_Header { } /// - /// 查找类似 Install 的本地化字符串。 + /// Looks up a localized string similar to Install. /// public static string LibraryInstall_Header { get { @@ -1240,7 +1239,52 @@ public static string LibraryInstall_Header { } /// - /// 查找类似 The newest and compatible version will be installed 的本地化字符串。 + /// Looks up a localized string similar to Distribution File already added to the list. + /// + public static string LibraryInstall_InstallDistributions_AlreadyExists { + get { + return ResourceManager.GetString("LibraryInstall_InstallDistributions_AlreadyExists", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Install via distributions. + /// + public static string LibraryInstall_InstallDistributions_Header { + get { + return ResourceManager.GetString("LibraryInstall_InstallDistributions_Header", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Install dependencies. + /// + public static string LibraryInstall_InstallDistributions_InstallDependencies { + get { + return ResourceManager.GetString("LibraryInstall_InstallDistributions_InstallDependencies", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid Distribution File. + /// + public static string LibraryInstall_InstallDistributions_InvalidFile { + get { + return ResourceManager.GetString("LibraryInstall_InstallDistributions_InvalidFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error while reading a file, check if the file is occupied. + /// + public static string LibraryInstall_InstallDistributions_IOError { + get { + return ResourceManager.GetString("LibraryInstall_InstallDistributions_IOError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The newest and compatible version will be installed. /// public static string LibraryInstall_List_DefaultVersion { get { @@ -1249,7 +1293,7 @@ public static string LibraryInstall_List_DefaultVersion { } /// - /// 查找类似 Version Specified 的本地化字符串。 + /// Looks up a localized string similar to Version Specified. /// public static string LibraryInstall_List_VersionSpecified { get { @@ -1258,7 +1302,7 @@ public static string LibraryInstall_List_VersionSpecified { } /// - /// 查找类似 Download 的本地化字符串。 + /// Looks up a localized string similar to Download. /// public static string LibraryInstall_Requirements_Download { get { @@ -1267,7 +1311,7 @@ public static string LibraryInstall_Requirements_Download { } /// - /// 查找类似 Download dependencies 的本地化字符串。 + /// Looks up a localized string similar to Download dependencies. /// public static string LibraryInstall_Requirements_DownloadDependencies { get { @@ -1276,7 +1320,7 @@ public static string LibraryInstall_Requirements_DownloadDependencies { } /// - /// 查找类似 Download Folder 的本地化字符串。 + /// Looks up a localized string similar to Download Folder. /// public static string LibraryInstall_Requirements_DownloadFolder { get { @@ -1285,7 +1329,7 @@ public static string LibraryInstall_Requirements_DownloadFolder { } /// - /// 查找类似 requirements.txt Import 的本地化字符串。 + /// Looks up a localized string similar to requirements.txt Import. /// public static string LibraryInstall_Requirements_Header { get { @@ -1294,7 +1338,7 @@ public static string LibraryInstall_Requirements_Header { } /// - /// 查找类似 About 的本地化字符串。 + /// Looks up a localized string similar to About. /// public static string MainWindow_NavigationContent_About { get { @@ -1303,7 +1347,7 @@ public static string MainWindow_NavigationContent_About { } /// - /// 查找类似 Action 的本地化字符串。 + /// Looks up a localized string similar to Action. /// public static string MainWindow_NavigationContent_Action { get { @@ -1312,7 +1356,7 @@ public static string MainWindow_NavigationContent_Action { } /// - /// 查找类似 Environment 的本地化字符串。 + /// Looks up a localized string similar to Environment. /// public static string MainWindow_NavigationContent_Environment { get { @@ -1321,7 +1365,7 @@ public static string MainWindow_NavigationContent_Environment { } /// - /// 查找类似 Lab 的本地化字符串。 + /// Looks up a localized string similar to Lab. /// public static string MainWindow_NavigationContent_Lab { get { @@ -1330,7 +1374,7 @@ public static string MainWindow_NavigationContent_Lab { } /// - /// 查找类似 Library 的本地化字符串。 + /// Looks up a localized string similar to Library. /// public static string MainWindow_NavigationContent_Library { get { @@ -1339,7 +1383,7 @@ public static string MainWindow_NavigationContent_Library { } /// - /// 查找类似 Search 的本地化字符串。 + /// Looks up a localized string similar to Search. /// public static string MainWindow_NavigationContent_Search { get { @@ -1348,7 +1392,7 @@ public static string MainWindow_NavigationContent_Search { } /// - /// 查找类似 Settings 的本地化字符串。 + /// Looks up a localized string similar to Settings. /// public static string MainWindow_NavigationContent_Settings { get { @@ -1357,7 +1401,7 @@ public static string MainWindow_NavigationContent_Settings { } /// - /// 查找类似 Tools 的本地化字符串。 + /// Looks up a localized string similar to Tools. /// public static string MainWindow_NavigationContent_Tools { get { @@ -1366,7 +1410,7 @@ public static string MainWindow_NavigationContent_Tools { } /// - /// 查找类似 Loading... 的本地化字符串。 + /// Looks up a localized string similar to Loading.... /// public static string Mask_Loading { get { @@ -1375,7 +1419,7 @@ public static string Mask_Loading { } /// - /// 查找类似 The newest and compatible version will be selected 的本地化字符串。 + /// Looks up a localized string similar to The newest and compatible version will be selected. /// public static string Search_DefaultVersion { get { @@ -1384,7 +1428,7 @@ public static string Search_DefaultVersion { } /// - /// 查找类似 No Description 的本地化字符串。 + /// Looks up a localized string similar to No Description. /// public static string Search_List_NoDescription { get { @@ -1393,7 +1437,7 @@ public static string Search_List_NoDescription { } /// - /// 查找类似 About {0} results found 的本地化字符串。 + /// Looks up a localized string similar to About {0} results found. /// public static string Search_List_TotalResultNumber { get { @@ -1402,7 +1446,7 @@ public static string Search_List_TotalResultNumber { } /// - /// 查找类似 Update Time: 的本地化字符串。 + /// Looks up a localized string similar to Update Time: . /// public static string Search_List_UpdateTime { get { @@ -1411,7 +1455,7 @@ public static string Search_List_UpdateTime { } /// - /// 查找类似 Details 的本地化字符串。 + /// Looks up a localized string similar to Details. /// public static string Search_Operation_Details { get { @@ -1420,7 +1464,7 @@ public static string Search_Operation_Details { } /// - /// 查找类似 No results 的本地化字符串。 + /// Looks up a localized string similar to No results. /// public static string Search_Query_NoResults { get { @@ -1429,7 +1473,7 @@ public static string Search_Query_NoResults { } /// - /// 查找类似 Timeout 的本地化字符串。 + /// Looks up a localized string similar to Timeout. /// public static string Search_Query_Timeout { get { @@ -1438,7 +1482,7 @@ public static string Search_Query_Timeout { } /// - /// 查找类似 Specify Version 的本地化字符串。 + /// Looks up a localized string similar to Specify Version. /// public static string Search_VersionSpecified { get { @@ -1447,7 +1491,7 @@ public static string Search_VersionSpecified { } /// - /// 查找类似 Download Distributions 的本地化字符串。 + /// Looks up a localized string similar to Download Distributions. /// public static string SearchDetail_DownloadDistributions { get { @@ -1456,7 +1500,7 @@ public static string SearchDetail_DownloadDistributions { } /// - /// 查找类似 Details 的本地化字符串。 + /// Looks up a localized string similar to Details. /// public static string SearchDetail_Header { get { @@ -1465,7 +1509,7 @@ public static string SearchDetail_Header { } /// - /// 查找类似 Install 的本地化字符串。 + /// Looks up a localized string similar to Install. /// public static string SearchDetail_Install { get { @@ -1474,7 +1518,7 @@ public static string SearchDetail_Install { } /// - /// 查找类似 Failed to get installed libraries 的本地化字符串。 + /// Looks up a localized string similar to Failed to get installed libraries. /// public static string SearchDetail_Install_CannotGetLibraries { get { @@ -1483,7 +1527,7 @@ public static string SearchDetail_Install_CannotGetLibraries { } /// - /// 查找类似 Latest Updated: 的本地化字符串。 + /// Looks up a localized string similar to Latest Updated:. /// public static string SearchDetail_LatestUpdatedTime { get { @@ -1492,7 +1536,7 @@ public static string SearchDetail_LatestUpdatedTime { } /// - /// 查找类似 Project description not available online 的本地化字符串。 + /// Looks up a localized string similar to Project description not available online. /// public static string SearchDetail_ProjectDescription_LoadFailed { get { @@ -1501,7 +1545,7 @@ public static string SearchDetail_ProjectDescription_LoadFailed { } /// - /// 查找类似 File Management 的本地化字符串。 + /// Looks up a localized string similar to File Management. /// public static string Settings_Category_FileManagement { get { @@ -1510,7 +1554,7 @@ public static string Settings_Category_FileManagement { } /// - /// 查找类似 Network 的本地化字符串。 + /// Looks up a localized string similar to Network. /// public static string Settings_Category_Network { get { @@ -1519,7 +1563,7 @@ public static string Settings_Category_Network { } /// - /// 查找类似 Package Source 的本地化字符串。 + /// Looks up a localized string similar to Package Source. /// public static string Settings_Category_PackageSource { get { @@ -1528,7 +1572,7 @@ public static string Settings_Category_PackageSource { } /// - /// 查找类似 Personalization 的本地化字符串。 + /// Looks up a localized string similar to Personalization. /// public static string Settings_Category_Personalization { get { @@ -1537,7 +1581,7 @@ public static string Settings_Category_Personalization { } /// - /// 查找类似 Crushes folder not found 的本地化字符串。 + /// Looks up a localized string similar to Crushes folder not found. /// public static string Settings_FileManagement_CrushesDirNotFound { get { @@ -1546,7 +1590,7 @@ public static string Settings_FileManagement_CrushesDirNotFound { } /// - /// 查找类似 Open App Folder 的本地化字符串。 + /// Looks up a localized string similar to Open App Folder. /// public static string Settings_FileManagement_OpenAppDir { get { @@ -1555,7 +1599,7 @@ public static string Settings_FileManagement_OpenAppDir { } /// - /// 查找类似 Open Crushes Folder 的本地化字符串。 + /// Looks up a localized string similar to Open Crushes Folder. /// public static string Settings_FileManagement_OpenCrushesDir { get { @@ -1564,7 +1608,7 @@ public static string Settings_FileManagement_OpenCrushesDir { } /// - /// 查找类似 Open Log Folder 的本地化字符串。 + /// Looks up a localized string similar to Open Log Folder. /// public static string Settings_FileManagement_OpenLogDir { get { @@ -1573,7 +1617,7 @@ public static string Settings_FileManagement_OpenLogDir { } /// - /// 查找类似 Reset Config 的本地化字符串。 + /// Looks up a localized string similar to Reset Config. /// public static string Settings_FileManagement_ResetConfig { get { @@ -1582,7 +1626,7 @@ public static string Settings_FileManagement_ResetConfig { } /// - /// 查找类似 This action will delete all app-related settings. Are you sure you want to keep going with this? 的本地化字符串。 + /// Looks up a localized string similar to This action will delete all app-related settings. Are you sure you want to keep going with this?. /// public static string Settings_FileManagement_ResetConfig_DialogContent { get { @@ -1591,7 +1635,7 @@ public static string Settings_FileManagement_ResetConfig_DialogContent { } /// - /// 查找类似 All configuration settings (config.json) will be restored to the initial state 的本地化字符串。 + /// Looks up a localized string similar to All configuration settings (config.json) will be restored to the initial state. /// public static string Settings_FileManagement_ResetConfig_Subtitle { get { @@ -1600,7 +1644,7 @@ public static string Settings_FileManagement_ResetConfig_Subtitle { } /// - /// 查找类似 Cache cleared 的本地化字符串。 + /// Looks up a localized string similar to Cache cleared. /// public static string Settings_FileManagement_WebViewSettings_CacheCleared { get { @@ -1609,7 +1653,7 @@ public static string Settings_FileManagement_WebViewSettings_CacheCleared { } /// - /// 查找类似 WebView still in use, cannot clear cache 的本地化字符串。 + /// Looks up a localized string similar to WebView still in use, cannot clear cache. /// public static string Settings_FileManagement_WebViewSettings_CacheIsUsing { get { @@ -1618,7 +1662,7 @@ public static string Settings_FileManagement_WebViewSettings_CacheIsUsing { } /// - /// 查找类似 Clear WebView2 Cache 的本地化字符串。 + /// Looks up a localized string similar to Clear WebView2 Cache. /// public static string Settings_FileManagement_WebViewSettings_ClearCache { get { @@ -1627,7 +1671,7 @@ public static string Settings_FileManagement_WebViewSettings_ClearCache { } /// - /// 查找类似 Clear the WebView2 cache used for e.g. search pages 的本地化字符串。 + /// Looks up a localized string similar to Clear the WebView2 cache used for e.g. search pages. /// public static string Settings_FileManagement_WebViewSettings_ClearCache_Subtitle { get { @@ -1636,7 +1680,7 @@ public static string Settings_FileManagement_WebViewSettings_ClearCache_Subtitle } /// - /// 查找类似 Aliyun 的本地化字符串。 + /// Looks up a localized string similar to Aliyun. /// public static string Settings_PackageSource_Aliyun { get { @@ -1645,7 +1689,7 @@ public static string Settings_PackageSource_Aliyun { } /// - /// 查找类似 Douban 的本地化字符串。 + /// Looks up a localized string similar to Douban. /// public static string Settings_PackageSource_Douban { get { @@ -1654,7 +1698,7 @@ public static string Settings_PackageSource_Douban { } /// - /// 查找类似 Test Network 的本地化字符串。 + /// Looks up a localized string similar to Test Network. /// public static string Settings_PackageSource_NetworkTest { get { @@ -1663,7 +1707,7 @@ public static string Settings_PackageSource_NetworkTest { } /// - /// 查找类似 Network Error 的本地化字符串。 + /// Looks up a localized string similar to Network Error. /// public static string Settings_PackageSource_NetworkTestFailed { get { @@ -1672,7 +1716,7 @@ public static string Settings_PackageSource_NetworkTestFailed { } /// - /// 查找类似 Testing 的本地化字符串。 + /// Looks up a localized string similar to Testing. /// public static string Settings_PackageSource_NetworkTesting { get { @@ -1681,7 +1725,7 @@ public static string Settings_PackageSource_NetworkTesting { } /// - /// 查找类似 If you are in mainland China, we recommend choosing a non-PyPI source 的本地化字符串。 + /// Looks up a localized string similar to If you are in mainland China, we recommend choosing a non-PyPI source. /// public static string Settings_PackageSource_Notice { get { @@ -1690,7 +1734,7 @@ public static string Settings_PackageSource_Notice { } /// - /// 查找类似 PyPI Official 的本地化字符串。 + /// Looks up a localized string similar to PyPI Official. /// public static string Settings_PackageSource_Official { get { @@ -1699,7 +1743,7 @@ public static string Settings_PackageSource_Official { } /// - /// 查找类似 Installing and downloading packages via PyPI or other mirror sites 的本地化字符串。 + /// Looks up a localized string similar to Installing and downloading packages via PyPI or other mirror sites. /// public static string Settings_PackageSource_Subtitle { get { @@ -1708,7 +1752,7 @@ public static string Settings_PackageSource_Subtitle { } /// - /// 查找类似 Tsinghua 的本地化字符串。 + /// Looks up a localized string similar to Tsinghua. /// public static string Settings_PackageSource_Tsinghua { get { @@ -1717,7 +1761,7 @@ public static string Settings_PackageSource_Tsinghua { } /// - /// 查找类似 Crush files will be deleted after more than {0} items 的本地化字符串。 + /// Looks up a localized string similar to Crush files will be deleted after more than {0} items. /// public static string Settings_PersonalizationCrushesAutoDeletion_Tip { get { @@ -1726,7 +1770,7 @@ public static string Settings_PersonalizationCrushesAutoDeletion_Tip { } /// - /// 查找类似 Log files will be deleted after more than {0} items 的本地化字符串。 + /// Looks up a localized string similar to Log files will be deleted after more than {0} items. /// public static string Settings_PersonalizationLogAutoDeletion_Tip { get { @@ -1735,7 +1779,7 @@ public static string Settings_PersonalizationLogAutoDeletion_Tip { } /// - /// 查找类似 Dark 的本地化字符串。 + /// Looks up a localized string similar to Dark. /// public static string Settings_PersonalizationTheme_Dark { get { @@ -1744,7 +1788,7 @@ public static string Settings_PersonalizationTheme_Dark { } /// - /// 查找类似 Light 的本地化字符串。 + /// Looks up a localized string similar to Light. /// public static string Settings_PersonalizationTheme_Light { get { @@ -1753,7 +1797,7 @@ public static string Settings_PersonalizationTheme_Light { } /// - /// 查找类似 Crushes Auto Deletion 的本地化字符串。 + /// Looks up a localized string similar to Crushes Auto Deletion. /// public static string Settings_PersonalizationTitle_CrushesAutoDeletion { get { @@ -1762,7 +1806,7 @@ public static string Settings_PersonalizationTitle_CrushesAutoDeletion { } /// - /// 查找类似 Language 的本地化字符串。 + /// Looks up a localized string similar to Language. /// public static string Settings_PersonalizationTitle_Language { get { @@ -1771,7 +1815,7 @@ public static string Settings_PersonalizationTitle_Language { } /// - /// 查找类似 Set language 的本地化字符串。 + /// Looks up a localized string similar to Set language. /// public static string Settings_PersonalizationTitle_Language_Subtitle { get { @@ -1780,7 +1824,7 @@ public static string Settings_PersonalizationTitle_Language_Subtitle { } /// - /// 查找类似 Log Auto Deletion 的本地化字符串。 + /// Looks up a localized string similar to Log Auto Deletion. /// public static string Settings_PersonalizationTitle_LogAutoDeletion { get { @@ -1789,7 +1833,7 @@ public static string Settings_PersonalizationTitle_LogAutoDeletion { } /// - /// 查找类似 Set the log file number limit 的本地化字符串。 + /// Looks up a localized string similar to Set the log file number limit. /// public static string Settings_PersonalizationTitle_LogAutoDeletion_Subtitle { get { @@ -1798,7 +1842,7 @@ public static string Settings_PersonalizationTitle_LogAutoDeletion_Subtitle { } /// - /// 查找类似 Theme 的本地化字符串。 + /// Looks up a localized string similar to Theme. /// public static string Settings_PersonalizationTitle_Theme { get { @@ -1807,7 +1851,7 @@ public static string Settings_PersonalizationTitle_Theme { } /// - /// 查找类似 Change window theme 的本地化字符串。 + /// Looks up a localized string similar to Change window theme. /// public static string Settings_PersonalizationTitle_Theme_Subtitle { get { @@ -1816,7 +1860,7 @@ public static string Settings_PersonalizationTitle_Theme_Subtitle { } /// - /// 查找类似 Changes will take effect after the application is restarted 的本地化字符串。 + /// Looks up a localized string similar to Changes will take effect after the application is restarted. /// public static string Snackbar_effectAfterRestart { get { @@ -1825,7 +1869,7 @@ public static string Snackbar_effectAfterRestart { } /// - /// 查找类似 Install Package 的本地化字符串。 + /// Looks up a localized string similar to Install Package. /// public static string TrayMenu_Install { get { diff --git a/src/PipManager/Languages/Lang.resx b/src/PipManager/Languages/Lang.resx index 66c2675..7926e16 100644 --- a/src/PipManager/Languages/Lang.resx +++ b/src/PipManager/Languages/Lang.resx @@ -708,4 +708,19 @@ Cancel + + Error while reading a file, check if the file is occupied + + + Invalid Distribution File + + + Distribution File already added to the list + + + Install via distributions + + + Install dependencies + \ No newline at end of file diff --git a/src/PipManager/Languages/Lang.zh-cn.resx b/src/PipManager/Languages/Lang.zh-cn.resx index faecdc1..1978e60 100644 --- a/src/PipManager/Languages/Lang.zh-cn.resx +++ b/src/PipManager/Languages/Lang.zh-cn.resx @@ -708,4 +708,19 @@ 取消 + + 在读取文件时出现错误,检查文件是否被占用 + + + 该发行文件不可用 + + + 该发行文件已在列表中 + + + 通过发行文件安装 + + + 安装依赖包 + \ No newline at end of file diff --git a/src/PipManager/PipManager.csproj b/src/PipManager/PipManager.csproj index 38810f3..004bead 100644 --- a/src/PipManager/PipManager.csproj +++ b/src/PipManager/PipManager.csproj @@ -37,6 +37,7 @@ + diff --git a/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs b/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs index ac83c7b..52dd55f 100644 --- a/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs @@ -11,8 +11,14 @@ using PipManager.Views.Pages.Action; using System.Collections.ObjectModel; using System.IO; +using System.IO.Compression; +using System.Text; +using ICSharpCode.SharpZipLib.GZip; +using ICSharpCode.SharpZipLib.Tar; +using Serilog; using Wpf.Ui; using Wpf.Ui.Controls; +using TarEntry = System.Formats.Tar.TarEntry; namespace PipManager.ViewModels.Pages.Library; @@ -36,6 +42,7 @@ public LibraryInstallViewModel(IActionService actionService, IMaskService maskSe _contentDialogService = contentDialogService; _environmentService = environmentService; _toastService = toastService; + _installWheelDependencies = false; _navigationService = navigationService; WeakReferenceMessenger.Default.Register(this, Receive); } @@ -44,6 +51,7 @@ public void OnNavigatedTo() { if (!_isInitialized) InitializeViewModel(); + InstallWheelDependencies = true; } public void OnNavigatedFrom() @@ -118,7 +126,7 @@ private void AddDefaultToAction() _actionService.AddOperation(new ActionListItem ( ActionType.Install, - string.Join(' ', operationCommand), + operationCommand.ToArray(), totalSubTaskNumber: operationCommand.Count )); PreInstallPackages.Clear(); @@ -172,7 +180,7 @@ private void AddRequirementsToAction() _actionService.AddOperation(new ActionListItem ( ActionType.InstallByRequirements, - Requirements, + [Requirements], displayCommand: "requirements.txt" )); Requirements = ""; @@ -185,8 +193,8 @@ private void AddRequirementsToAction() [ObservableProperty] private ObservableCollection _preDownloadPackages = []; [ObservableProperty] private string _downloadDistributionsFolderPath = ""; - [ObservableProperty] private bool _downloadDistributionsEnabled = false; - [ObservableProperty] private bool _downloadDependencies = false; + [ObservableProperty] private bool _downloadDistributionsEnabled; + [ObservableProperty] private bool _downloadWheelDependencies; [RelayCommand] private async Task DownloadDistributionsTask() @@ -251,9 +259,9 @@ private void DownloadDistributionsToAction() _actionService.AddOperation(new ActionListItem ( ActionType.Download, - string.Join(' ', operationCommand), + operationCommand.ToArray(), path: DownloadDistributionsFolderPath, - extraParameters: DownloadDependencies ? null : ["--no-deps"], + extraParameters: DownloadWheelDependencies ? null : ["--no-deps"], totalSubTaskNumber: operationCommand.Count )); PreDownloadPackages.Clear(); @@ -280,4 +288,145 @@ private void DeleteDownloadDistributionsTask(object? parameter) } #endregion Download Wheel File + + #region Install via distributions + [ObservableProperty] private ObservableCollection _preInstallDistributions = []; + [ObservableProperty] private bool _installWheelDependencies; + + [RelayCommand] + private async Task SelectDistributions() + { + var openFileDialog = new OpenFileDialog + { + Filter = "Wheel Files|*.whl;*.tar.gz", + Multiselect = true + }; + if (openFileDialog.ShowDialog() != true) + { + return; + } + + foreach (var fileName in openFileDialog.FileNames) + { + var packageName = ""; + var packageVersion = ""; + try + { + if (fileName.EndsWith(".whl")) + { + await using var wheelFileStream = new FileStream(fileName, FileMode.Open); + using var wheelFileArchive = new ZipArchive(wheelFileStream, ZipArchiveMode.Read); + foreach (ZipArchiveEntry entry in wheelFileArchive.Entries) + { + if (!entry.FullName.Contains(".dist-info/METADATA") || !entry.FullName.Contains("PKG-INFO")) + { + continue; + } + + using var streamReader = new StreamReader(entry.Open()); + while (await streamReader.ReadLineAsync() is { } line) + { + if (line.StartsWith("Name: ")) + { + packageName = line[6..]; + } + else if (line.StartsWith("Version: ")) + { + packageVersion = line[9..]; + break; + } + } + } + } + else if (fileName.EndsWith(".tar.gz")) + { + var inStream = File.OpenRead(fileName); + var gzipStream = new GZipInputStream(inStream); + var tarArchive = TarArchive.CreateInputTarArchive(gzipStream, Encoding.UTF8); + var randomizedDirectory = Path.Combine(AppInfo.CachesDir, $"tempTarGz-{Guid.NewGuid():N}"); + tarArchive.ExtractContents(randomizedDirectory); + tarArchive.Close(); + gzipStream.Close(); + inStream.Close(); + string targetDirectory = Directory.GetDirectories(randomizedDirectory)[0]; + + if (File.Exists(Path.Combine(targetDirectory, "PKG-INFO"))) + { + using var streamReader = File.OpenText(Path.Combine(targetDirectory, "PKG-INFO")); + while (await streamReader.ReadLineAsync() is { } line) + { + if (line.StartsWith("Name: ")) + { + packageName = line[6..]; + } + else if (line.StartsWith("Version: ")) + { + packageVersion = line[9..]; + break; + } + } + } + } + } + catch (Exception e) when (e is IOException or InvalidDataException) + { + _toastService.Error(Lang.LibraryInstall_InstallDistributions_IOError); + return; + } + + if (packageName == "" || packageVersion == "") + { + _toastService.Error(Lang.LibraryInstall_InstallDistributions_InvalidFile); + return; + } + + if (PreInstallDistributions.Any(item => item.PackageName == packageName)) + { + _toastService.Error(Lang.LibraryInstall_InstallDistributions_AlreadyExists); + return; + } + + PreInstallDistributions.Add(new LibraryInstallPackageItem + { + PackageName = packageName, + TargetVersion = packageVersion, + DistributionFilePath = fileName + }); + } + } + + [RelayCommand] + private void DeleteInstallDistributions(object? parameter) + { + var target = -1; + for (int index = 0; index < PreInstallDistributions.Count; index++) + { + if (ReferenceEquals(PreInstallDistributions[index].PackageName, parameter)) + { + target = index; + } + } + + if (target != -1) + { + PreInstallDistributions.RemoveAt(target); + } + } + + [RelayCommand] + private void InstallDistributionsToAction() + { + List operationCommand = []; + operationCommand.AddRange(PreInstallDistributions.Select(preInstallPackage => preInstallPackage.DistributionFilePath)!); + _actionService.AddOperation(new ActionListItem + ( + ActionType.Install, + operationCommand.ToArray(), + totalSubTaskNumber: operationCommand.Count, + extraParameters: DownloadWheelDependencies ? null : ["--no-deps"] + )); + PreInstallDistributions.Clear(); + } + + #endregion } \ No newline at end of file diff --git a/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml b/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml index 80e28a2..e622873 100644 --- a/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml +++ b/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml @@ -27,6 +27,7 @@ + + + @@ -283,6 +286,84 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 23f5e7ced1225afdebead50fb4423dd00d74a417 Mon Sep 17 00:00:00 2001 From: Mccree Lee <2935876049@qq.com> Date: Mon, 1 Apr 2024 19:54:11 +0800 Subject: [PATCH 09/15] perf: update WPF-UI --- src/PipManager.sln | 1 + src/PipManager/PipManager.csproj | 4 ++-- .../Pages/Environment/AddEnvironmentPage.xaml | 8 ++++---- .../Views/Pages/Environment/EnvironmentPage.xaml | 8 ++++---- .../Views/Pages/Library/LibraryPage.xaml | 15 ++++++++------- src/PipManager/Views/Pages/Search/SearchPage.xaml | 8 ++++---- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/PipManager.sln b/src/PipManager.sln index dee2b6d..1921647 100644 --- a/src/PipManager.sln +++ b/src/PipManager.sln @@ -8,6 +8,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{B7B16EC6-9787-477B-B84A-7DACBEB96277}" ProjectSection(SolutionItems) = preProject ..\README.md = ..\README.md + .github\workflows\qodana_code_quality.yml = .github\workflows\qodana_code_quality.yml EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PipManager.PackageSearch", "PipManager.PackageSearch\PipManager.PackageSearch.csproj", "{759DBA08-4418-474E-BD6F-773829A81368}" diff --git a/src/PipManager/PipManager.csproj b/src/PipManager/PipManager.csproj index 004bead..bcdbbfc 100644 --- a/src/PipManager/PipManager.csproj +++ b/src/PipManager/PipManager.csproj @@ -39,10 +39,10 @@ - + - +
diff --git a/src/PipManager/Views/Pages/Environment/AddEnvironmentPage.xaml b/src/PipManager/Views/Pages/Environment/AddEnvironmentPage.xaml index f641eb9..ed65968 100644 --- a/src/PipManager/Views/Pages/Environment/AddEnvironmentPage.xaml +++ b/src/PipManager/Views/Pages/Environment/AddEnvironmentPage.xaml @@ -76,7 +76,7 @@ FontSize="22" Text="{I18N {x:Static lang:LangKeys.EnvironmentAdd_EnvironmentVariable_NotFound}}" Visibility="{Binding ViewModel.Found, Converter={StaticResource BoolToVisibility}}" /> - - + @@ -114,8 +114,8 @@ - - + + - - + @@ -81,7 +81,7 @@ - - + + \ No newline at end of file diff --git a/src/PipManager/Views/Pages/Library/LibraryPage.xaml b/src/PipManager/Views/Pages/Library/LibraryPage.xaml index e83c747..363bc59 100644 --- a/src/PipManager/Views/Pages/Library/LibraryPage.xaml +++ b/src/PipManager/Views/Pages/Library/LibraryPage.xaml @@ -94,7 +94,7 @@ - - + @@ -153,13 +153,14 @@ Icon="{ui:SymbolIcon ChevronRight24}" /> - - - - - + + - - + @@ -98,8 +98,8 @@ Icon="{ui:SymbolIcon ChevronRight24}" /> - - + + Date: Mon, 1 Apr 2024 20:01:12 +0800 Subject: [PATCH 10/15] build: Qodana --- {src/.github => .github}/workflows/qodana_code_quality.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src/.github => .github}/workflows/qodana_code_quality.yml (100%) diff --git a/src/.github/workflows/qodana_code_quality.yml b/.github/workflows/qodana_code_quality.yml similarity index 100% rename from src/.github/workflows/qodana_code_quality.yml rename to .github/workflows/qodana_code_quality.yml From 6114083c84347962931e2e93cf26e523027c2739 Mon Sep 17 00:00:00 2001 From: Mccree Lee <2935876049@qq.com> Date: Tue, 2 Apr 2024 19:54:14 +0800 Subject: [PATCH 11/15] perf: better localization --- .github/workflows/qodana_code_quality.yml | 20 -------- src/PipManager.sln | 1 - src/PipManager/Languages/Lang.Designer.cs | 13 ++++- src/PipManager/Languages/Lang.resx | 7 ++- src/PipManager/Languages/Lang.zh-cn.resx | 7 ++- src/PipManager/PipManager.csproj | 4 -- .../Pages/Environment/EnvironmentViewModel.cs | 4 +- .../Pages/Environment/EnvironmentPage.xaml | 50 ++++++++++--------- 8 files changed, 49 insertions(+), 57 deletions(-) delete mode 100644 .github/workflows/qodana_code_quality.yml diff --git a/.github/workflows/qodana_code_quality.yml b/.github/workflows/qodana_code_quality.yml deleted file mode 100644 index 1fe63bd..0000000 --- a/.github/workflows/qodana_code_quality.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Qodana -on: - workflow_dispatch: - pull_request: - push: - branches: - - main - - development - -jobs: - qodana: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2023.3 - env: - QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} \ No newline at end of file diff --git a/src/PipManager.sln b/src/PipManager.sln index 1921647..dee2b6d 100644 --- a/src/PipManager.sln +++ b/src/PipManager.sln @@ -8,7 +8,6 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{B7B16EC6-9787-477B-B84A-7DACBEB96277}" ProjectSection(SolutionItems) = preProject ..\README.md = ..\README.md - .github\workflows\qodana_code_quality.yml = .github\workflows\qodana_code_quality.yml EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PipManager.PackageSearch", "PipManager.PackageSearch\PipManager.PackageSearch.csproj", "{759DBA08-4418-474E-BD6F-773829A81368}" diff --git a/src/PipManager/Languages/Lang.Designer.cs b/src/PipManager/Languages/Lang.Designer.cs index a67b7ca..b990995 100644 --- a/src/PipManager/Languages/Lang.Designer.cs +++ b/src/PipManager/Languages/Lang.Designer.cs @@ -645,7 +645,16 @@ public static string Environment_Operation_CheckEnvironmentUpdate { } /// - /// Looks up a localized string similar to Remove Environment (from list). + /// Looks up a localized string similar to Clear Cache. + /// + public static string Environment_Operation_ClearEnvironmentCache { + get { + return ResourceManager.GetString("Environment_Operation_ClearEnvironmentCache", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Remove from list. /// public static string Environment_Operation_RemoveEnvironment { get { @@ -654,7 +663,7 @@ public static string Environment_Operation_RemoveEnvironment { } /// - /// Looks up a localized string similar to Verify Environment. + /// Looks up a localized string similar to Verify Availability. /// public static string Environment_Operation_VerifyEnvironment { get { diff --git a/src/PipManager/Languages/Lang.resx b/src/PipManager/Languages/Lang.resx index 7926e16..b09bd91 100644 --- a/src/PipManager/Languages/Lang.resx +++ b/src/PipManager/Languages/Lang.resx @@ -208,10 +208,10 @@ Add Environment - Remove Environment (from list) + Remove from list - Verify Environment + Verify Availability Package Source @@ -723,4 +723,7 @@ Install dependencies + + Clear Cache + \ No newline at end of file diff --git a/src/PipManager/Languages/Lang.zh-cn.resx b/src/PipManager/Languages/Lang.zh-cn.resx index 1978e60..aba4908 100644 --- a/src/PipManager/Languages/Lang.zh-cn.resx +++ b/src/PipManager/Languages/Lang.zh-cn.resx @@ -208,10 +208,10 @@ 添加环境 - 从列表中移除环境 + 从列表中移除 - 验证环境可用性 + 验证可用性 包源 @@ -723,4 +723,7 @@ 安装依赖包 + + 清除缓存 + \ No newline at end of file diff --git a/src/PipManager/PipManager.csproj b/src/PipManager/PipManager.csproj index bcdbbfc..c8ebb3d 100644 --- a/src/PipManager/PipManager.csproj +++ b/src/PipManager/PipManager.csproj @@ -100,10 +100,6 @@ - - - - diff --git a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs index e8f0996..7745d8a 100644 --- a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs @@ -74,10 +74,10 @@ private async Task DeleteEnvironmentAsync() EnvironmentItems.Remove(CurrentEnvironment!); CurrentEnvironment = null; configurationService.AppConfig.CurrentEnvironment = null; - configurationService.AppConfig.EnvironmentItems = new List(EnvironmentItems); + configurationService.AppConfig.EnvironmentItems = [..EnvironmentItems]; configurationService.Save(); var mainWindowViewModel = App.GetService(); - mainWindowViewModel.ApplicationTitle = $"Pip Manager"; + mainWindowViewModel.ApplicationTitle = "Pip Manager"; EnvironmentSelected = false; } diff --git a/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml b/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml index e43cabc..e85d8ea 100644 --- a/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml +++ b/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml @@ -1,24 +1,25 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -28,44 +29,45 @@ Content="{I18N {x:Static lang:LangKeys.Environment_Operation_AddEnvironment}}" Icon="{ui:SymbolIcon Add24}" /> + IsEnabled="{Binding ViewModel.CurrentEnvironment, Converter={StaticResource NullToBool}}" + Margin="5,0,0,0" /> + IsEnabled="{Binding ViewModel.CurrentEnvironment, Converter={StaticResource NullToBool}}" + Margin="5,0,0,0" /> + IsEnabled="{Binding ViewModel.CurrentEnvironment, Converter={StaticResource NullToBool}}" + Margin="5,0,0,0" /> + SelectedItem="{Binding ViewModel.CurrentEnvironment}" + VerticalAlignment="Stretch"> - + + + Source="../../../Assets/logo/python-logo-only.png" + Width="48" /> From d6ee23748e935cd1755e9de0fc01c66ed9f65a4a Mon Sep 17 00:00:00 2001 From: Mccree Lee <2935876049@qq.com> Date: Tue, 2 Apr 2024 20:12:06 +0800 Subject: [PATCH 12/15] feat: clear environment caches --- src/PipManager/Languages/Lang.Designer.cs | 18 ++++++++++++++ src/PipManager/Languages/Lang.resx | 6 +++++ src/PipManager/Languages/Lang.zh-cn.resx | 6 +++++ .../Environment/EnvironmentService.cs | 24 +++++++++++++++++++ .../Environment/IEnvironmentService.cs | 2 ++ .../Pages/Environment/EnvironmentViewModel.cs | 20 ++++++++++++++-- .../Pages/Environment/EnvironmentPage.xaml | 6 +++++ 7 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/PipManager/Languages/Lang.Designer.cs b/src/PipManager/Languages/Lang.Designer.cs index b990995..6eaa83e 100644 --- a/src/PipManager/Languages/Lang.Designer.cs +++ b/src/PipManager/Languages/Lang.Designer.cs @@ -455,6 +455,24 @@ public static string ContentDialog_Message_ActionStillRunning { } } + /// + /// Looks up a localized string similar to {0} Caches Cleared. + /// + public static string ContentDialog_Message_CacheCleared { + get { + return ResourceManager.GetString("ContentDialog_Message_CacheCleared", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Failed to clear caches. + /// + public static string ContentDialog_Message_CacheClearFailed { + get { + return ResourceManager.GetString("ContentDialog_Message_CacheClearFailed", resourceCulture); + } + } + /// /// Looks up a localized string similar to Environment already exists. /// diff --git a/src/PipManager/Languages/Lang.resx b/src/PipManager/Languages/Lang.resx index b09bd91..ed1af42 100644 --- a/src/PipManager/Languages/Lang.resx +++ b/src/PipManager/Languages/Lang.resx @@ -726,4 +726,10 @@ Clear Cache + + {0} Caches Cleared + + + Failed to clear caches + \ No newline at end of file diff --git a/src/PipManager/Languages/Lang.zh-cn.resx b/src/PipManager/Languages/Lang.zh-cn.resx index aba4908..0e72601 100644 --- a/src/PipManager/Languages/Lang.zh-cn.resx +++ b/src/PipManager/Languages/Lang.zh-cn.resx @@ -726,4 +726,10 @@ 清除缓存 + + 已清除 {0} 个缓存文件 + + + 清除缓存失败 + \ No newline at end of file diff --git a/src/PipManager/Services/Environment/EnvironmentService.cs b/src/PipManager/Services/Environment/EnvironmentService.cs index af53b6d..54283cf 100644 --- a/src/PipManager/Services/Environment/EnvironmentService.cs +++ b/src/PipManager/Services/Environment/EnvironmentService.cs @@ -36,6 +36,30 @@ public ActionResponse CheckEnvironmentAvailable(EnvironmentItem environmentItem) : new ActionResponse { Success = false, Exception = ExceptionType.Environment_Broken }; } + public ActionResponse PurgeEnvironmentCache(EnvironmentItem environmentItem) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, + Arguments = "-m pip cache purge", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + } + }; + process.Start(); + var output = process.StandardOutput.ReadToEnd(); + var error = process.StandardError.ReadToEnd(); + process.WaitForExit(); + process.Close(); + process.Dispose(); + error = error.Replace("WARNING: No matching packages", "").Trim(); + return !string.IsNullOrEmpty(error) ? new ActionResponse { Success = false, Exception = ExceptionType.Process_Error, Message = error } : new ActionResponse { Success = true, Message = output[15..].TrimEnd()}; + } + public async Task?> GetLibraries() { if (configurationService.AppConfig.CurrentEnvironment is null) diff --git a/src/PipManager/Services/Environment/IEnvironmentService.cs b/src/PipManager/Services/Environment/IEnvironmentService.cs index 0ec592c..9267e32 100644 --- a/src/PipManager/Services/Environment/IEnvironmentService.cs +++ b/src/PipManager/Services/Environment/IEnvironmentService.cs @@ -11,6 +11,8 @@ public interface IEnvironmentService public ActionResponse CheckEnvironmentAvailable(EnvironmentItem environmentItem); + public ActionResponse PurgeEnvironmentCache(EnvironmentItem environmentItem); + public Task?> GetLibraries(); public Task GetVersions(string packageName); diff --git a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs index 7745d8a..2f2bdba 100644 --- a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs @@ -64,7 +64,7 @@ private void InitializeViewModel() private bool _environmentSelected; [RelayCommand] - private async Task DeleteEnvironmentAsync() + private async Task DeleteEnvironment() { var result = await contentDialogService.ShowSimpleDialogAsync( ContentDialogCreateOptions.Warning(Lang.ContentDialog_Message_EnvironmentDeletion, @@ -98,7 +98,7 @@ private async Task CheckEnvironment() Lang.ContentDialog_PrimaryButton_EnvironmentDeletion)); if (result == ContentDialogResult.Primary) { - await DeleteEnvironmentAsync(); + await DeleteEnvironment(); } } } @@ -147,6 +147,22 @@ await Task.Run(async () => } } + [RelayCommand] + private void ClearCache() + { + var result = environmentService.PurgeEnvironmentCache(CurrentEnvironment!); + if (result.Success) + { + Log.Information($"[Environment] Cache cleared ({CurrentEnvironment!.PipVersion} for {CurrentEnvironment.PythonVersion})"); + toastService.Info(string.Format(Lang.ContentDialog_Message_CacheCleared, result.Message)); + } + else + { + Log.Error($"[Environment] Cache clear failed ({CurrentEnvironment!.PipVersion} for {CurrentEnvironment.PythonVersion})"); + toastService.Error(Lang.ContentDialog_Message_CacheClearFailed); + } + } + protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); diff --git a/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml b/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml index e85d8ea..46fd731 100644 --- a/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml +++ b/src/PipManager/Views/Pages/Environment/EnvironmentPage.xaml @@ -46,6 +46,12 @@ Icon="{ui:SymbolIcon ArrowUp24}" IsEnabled="{Binding ViewModel.CurrentEnvironment, Converter={StaticResource NullToBool}}" Margin="5,0,0,0" /> + Date: Tue, 2 Apr 2024 20:26:51 +0800 Subject: [PATCH 13/15] perf: improve code overall --- .../PackageSearchService.cs | 8 +- src/PipManager/App.xaml.cs | 2 +- src/PipManager/AppInfo.cs | 2 +- src/PipManager/AppStarting.cs | 71 +++---- src/PipManager/Helpers/ThreadIdEnricher.cs | 4 +- .../Models/Action/ActionListItem.cs | 2 +- .../Services/Action/ActionService.cs | 11 +- .../Environment/EnvironmentService.cs | 17 +- src/PipManager/Services/Mask/IMaskService.cs | 3 - src/PipManager/Services/Mask/MaskService.cs | 6 +- .../Pages/Action/ActionViewModel.cs | 1 - .../Pages/Library/LibraryDetailViewModel.cs | 5 +- .../Pages/Library/LibraryInstallViewModel.cs | 2 - .../Pages/Search/SearchDetailViewModel.cs | 22 +-- .../Pages/Search/SearchViewModel.cs | 9 +- .../ViewModels/Pages/Tools/ToolsViewModel.cs | 3 + .../ViewModels/Windows/MainWindowViewModel.cs | 8 +- .../Pages/Action/ActionExceptionPage.xaml | 75 ++++--- .../Views/Pages/Action/ActionPage.xaml.cs | 5 - .../Pages/Library/LibraryInstallPage.xaml | 172 ++++++++-------- .../Views/Pages/Library/LibraryPage.xaml | 76 ++++---- .../Views/Pages/Search/SearchDetailPage.xaml | 78 ++++---- .../Pages/Search/SearchDetailPage.xaml.cs | 13 +- .../Views/Pages/Search/SearchPage.xaml | 87 ++++----- .../Views/Pages/Settings/SettingsPage.xaml | 184 +++++++++--------- .../Views/Windows/ExceptionWindow.xaml.cs | 5 +- src/PipManager/Views/Windows/MainWindow.xaml | 73 +++---- .../Views/Windows/MainWindow.xaml.cs | 1 - 28 files changed, 463 insertions(+), 482 deletions(-) diff --git a/src/PipManager.PackageSearch/PackageSearchService.cs b/src/PipManager.PackageSearch/PackageSearchService.cs index 8f787a3..4fffcaf 100644 --- a/src/PipManager.PackageSearch/PackageSearchService.cs +++ b/src/PipManager.PackageSearch/PackageSearchService.cs @@ -1,12 +1,11 @@ using HtmlAgilityPack; using PipManager.PackageSearch.Wrappers.Query; -using Serilog; namespace PipManager.PackageSearch; public class PackageSearchService(HttpClient httpClient) : IPackageSearchService { - public Dictionary<(string, int), QueryWrapper> QueryCaches { get; set; } = []; + private Dictionary<(string, int), QueryWrapper> QueryCaches { get; } = []; public async Task Query(string name, int page = 1) { @@ -14,12 +13,12 @@ public async Task Query(string name, int page = 1) { return QueryCaches[(name, page)]; } - var htmlContent = ""; + string htmlContent; try { htmlContent = await httpClient.GetStringAsync($"https://pypi.org/search/?q={name}&page={page}"); } - catch (Exception exception) when (exception is TaskCanceledException || exception is HttpRequestException) + catch (Exception exception) when (exception is TaskCanceledException or HttpRequestException) { return new QueryWrapper { @@ -53,6 +52,7 @@ public async Task Query(string name, int page = 1) Version = resultItem.ChildNodes[1].ChildNodes[3].InnerText, Description = resultItem.ChildNodes[3].InnerText, Url = $"https://pypi.org{resultItem.Attributes["href"].Value}", + // ReSharper disable once StringLiteralTypo UpdateTime = DateTime.ParseExact(resultItem.ChildNodes[1].ChildNodes[5].ChildNodes[0].Attributes["datetime"].Value, "yyyy-MM-ddTHH:mm:sszzz", null, System.Globalization.DateTimeStyles.RoundtripKind) }); } diff --git a/src/PipManager/App.xaml.cs b/src/PipManager/App.xaml.cs index 2811883..56f99d6 100644 --- a/src/PipManager/App.xaml.cs +++ b/src/PipManager/App.xaml.cs @@ -129,7 +129,7 @@ public static T GetService() [LibraryImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool FreeConsole(); + private static partial void FreeConsole(); private bool _showConsoleWindow; private bool _experimentMode; diff --git a/src/PipManager/AppInfo.cs b/src/PipManager/AppInfo.cs index 8db2990..3e9da3c 100644 --- a/src/PipManager/AppInfo.cs +++ b/src/PipManager/AppInfo.cs @@ -5,7 +5,7 @@ namespace PipManager; public static class AppInfo { - public static readonly string AppVersion = Assembly.GetExecutingAssembly().GetName().Version!.ToString(3) ?? string.Empty; + public static readonly string AppVersion = Assembly.GetExecutingAssembly().GetName().Version!.ToString(3); public static readonly string ConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "config.json"); public static readonly string CrushesDir = Path.Combine(Directory.GetCurrentDirectory(), "crashes"); diff --git a/src/PipManager/AppStarting.cs b/src/PipManager/AppStarting.cs index 39fe59f..a9aa8e8 100644 --- a/src/PipManager/AppStarting.cs +++ b/src/PipManager/AppStarting.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using System.Runtime.InteropServices; +using PipManager.Helpers; namespace PipManager; @@ -11,14 +12,14 @@ public partial class AppStarting { [LibraryImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool AllocConsole(); + private static partial void AllocConsole(); - public readonly AppConfig Config; + private readonly AppConfig _config; public bool ShowConsoleWindow = false; public AppStarting() { - Config = ConfigurationService.LoadConfiguration(); + _config = ConfigurationService.LoadConfiguration(); Directory.CreateDirectory(AppInfo.CrushesDir); Directory.CreateDirectory(AppInfo.LogDir); Directory.CreateDirectory(AppInfo.CachesDir); @@ -26,7 +27,7 @@ public AppStarting() public void LoadLanguage() { - var language = Config.Personalization.Language; + var language = _config.Personalization.Language; if (language != "Auto") { I18NExtension.Culture = new CultureInfo(language); @@ -61,10 +62,10 @@ public void StartLogging() public void LogDeletion() { - if (!Config.Personalization.LogAutoDeletion || !Directory.Exists(AppInfo.LogDir)) return; + if (!_config.Personalization.LogAutoDeletion || !Directory.Exists(AppInfo.LogDir)) return; var fileList = Directory.GetFileSystemEntries(AppInfo.LogDir); var logFileAmount = fileList.Count(file => File.Exists(file) && file.EndsWith(".txt")); - if (logFileAmount >= Config.Personalization.LogAutoDeletionTimes) + if (logFileAmount >= _config.Personalization.LogAutoDeletionTimes) { var directoryInfo = new DirectoryInfo(AppInfo.LogDir); var filesInfo = directoryInfo.GetFileSystemInfos(); @@ -77,7 +78,7 @@ public void LogDeletion() } catch { - continue; + // ignored } } Log.Information($"{logFileAmount} log file(s) deleted"); @@ -86,27 +87,29 @@ public void LogDeletion() public void CrushesDeletion() { - if (!Config.Personalization.CrushesAutoDeletion || !Directory.Exists(AppInfo.CrushesDir)) return; + if (!_config.Personalization.CrushesAutoDeletion || !Directory.Exists(AppInfo.CrushesDir)) return; var fileList = Directory.GetFileSystemEntries(AppInfo.CrushesDir); var crushFileAmount = fileList.Count(file => File.Exists(file) && file.EndsWith(".txt")); - if (crushFileAmount >= Config.Personalization.CrushesAutoDeletionTimes) + if (crushFileAmount < _config.Personalization.CrushesAutoDeletionTimes) { - var directoryInfo = new DirectoryInfo(AppInfo.CrushesDir); - var filesInfo = directoryInfo.GetFileSystemInfos(); - foreach (var file in filesInfo) + return; + } + + var directoryInfo = new DirectoryInfo(AppInfo.CrushesDir); + var filesInfo = directoryInfo.GetFileSystemInfos(); + foreach (var file in filesInfo) + { + if (file.Extension != ".txt") continue; + try { - if (file.Extension != ".txt") continue; - try - { - File.Delete(file.FullName); - } - catch - { - continue; - } + File.Delete(file.FullName); + } + catch + { + // ignored } - Log.Information($"{crushFileAmount} crush file(s) deleted"); } + Log.Information($"{crushFileAmount} crush file(s) deleted"); } public void CachesDeletion() @@ -121,24 +124,26 @@ public void CachesDeletion() { subDir.Delete(true); } - catch (Exception ex) + catch (Exception) { // ignored } } foreach (var file in filesInfo) { - if (file.Name.StartsWith("temp_")) + if (!file.Name.StartsWith("temp_")) { - try - { - File.Delete(file.FullName); - cacheFileAmount++; - } - catch - { - // ignored - } + continue; + } + + try + { + File.Delete(file.FullName); + cacheFileAmount++; + } + catch + { + // ignored } } Log.Information($"{cacheFileAmount} cache file(s) deleted"); diff --git a/src/PipManager/Helpers/ThreadIdEnricher.cs b/src/PipManager/Helpers/ThreadIdEnricher.cs index c232723..1e3de84 100644 --- a/src/PipManager/Helpers/ThreadIdEnricher.cs +++ b/src/PipManager/Helpers/ThreadIdEnricher.cs @@ -1,11 +1,13 @@ using Serilog.Core; using Serilog.Events; +namespace PipManager.Helpers; + internal class ThreadIdEnricher : ILogEventEnricher { public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty( - "ThreadId", Environment.CurrentManagedThreadId)); + "ThreadId", Environment.CurrentManagedThreadId)); } } \ No newline at end of file diff --git a/src/PipManager/Models/Action/ActionListItem.cs b/src/PipManager/Models/Action/ActionListItem.cs index 267b329..01b56ce 100644 --- a/src/PipManager/Models/Action/ActionListItem.cs +++ b/src/PipManager/Models/Action/ActionListItem.cs @@ -72,7 +72,7 @@ public ActionListItem(ActionType operationType, string[] operationCommand, strin [ObservableProperty] [NotifyPropertyChangedFor(nameof(ProgressBarValue))] - private int _completedSubTaskNumber = 0; + private int _completedSubTaskNumber; public double ProgressBarValue { diff --git a/src/PipManager/Services/Action/ActionService.cs b/src/PipManager/Services/Action/ActionService.cs index be86491..7cfd836 100644 --- a/src/PipManager/Services/Action/ActionService.cs +++ b/src/PipManager/Services/Action/ActionService.cs @@ -7,7 +7,6 @@ using System.IO; using System.Text; using Meziantou.Framework.WPF.Collections; -using System.Buffers; namespace PipManager.Services.Action; @@ -53,7 +52,7 @@ public void Runner() foreach (var item in queue) { currentAction.OperationStatus = $"Uninstalling {item}"; - var result = environmentService.Uninstall(item, (sender, eventArgs) => + var result = environmentService.Uninstall(item, (_, eventArgs) => { if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) { @@ -80,7 +79,7 @@ public void Runner() foreach (var item in queue) { currentAction.OperationStatus = $"Installing {item}"; - var result = environmentService.Install(item, (sender, eventArgs) => + var result = environmentService.Install(item, (_, eventArgs) => { if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) { @@ -111,7 +110,7 @@ public void Runner() var requirementsTempFilePath = Path.Combine(AppInfo.CachesDir, $"temp_install_requirements_{currentAction.OperationId}.txt"); File.WriteAllText(requirementsTempFilePath, currentAction.OperationCommand[0]); currentAction.OperationStatus = "Installing from requirements.txt"; - var result = environmentService.InstallByRequirements(requirementsTempFilePath, (sender, eventArgs) => + var result = environmentService.InstallByRequirements(requirementsTempFilePath, (_, eventArgs) => { if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) { @@ -138,7 +137,7 @@ public void Runner() foreach (var item in queue) { currentAction.OperationStatus = $"Downloading {item}"; - var result = environmentService.Download(item, currentAction.Path, (sender, eventArgs) => + var result = environmentService.Download(item, currentAction.Path, (_, eventArgs) => { if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) { @@ -170,7 +169,7 @@ public void Runner() foreach (var item in queue) { currentAction.OperationStatus = $"Updating {item}"; - var result = environmentService.Update(item, (sender, eventArgs) => + var result = environmentService.Update(item, (_, eventArgs) => { if (!currentActionRunning && !string.IsNullOrEmpty(eventArgs.Data)) { diff --git a/src/PipManager/Services/Environment/EnvironmentService.cs b/src/PipManager/Services/Environment/EnvironmentService.cs index 54283cf..573cb8c 100644 --- a/src/PipManager/Services/Environment/EnvironmentService.cs +++ b/src/PipManager/Services/Environment/EnvironmentService.cs @@ -42,7 +42,7 @@ public ActionResponse PurgeEnvironmentCache(EnvironmentItem environmentItem) { StartInfo = new ProcessStartInfo { - FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, + FileName = configurationService.AppConfig.CurrentEnvironment!.PythonPath, Arguments = "-m pip cache purge", UseShellExecute = false, RedirectStandardOutput = true, @@ -229,7 +229,6 @@ public async Task GetVersions(string packageName) packageName = PackageNameNormalizerRegex().Replace(packageName, "-").ToLower(); if (!PackageNameVerificationRegex().IsMatch(packageName)) return new GetVersionsResponse { Status = 2, Versions = [] }; - var sth = $"{configurationService.GetUrlFromPackageSourceType("pypi")}{packageName}/json"; var responseMessage = await _httpClient.GetAsync($"{configurationService.GetUrlFromPackageSourceType("pypi")}{packageName}/json"); var response = await responseMessage.Content.ReadAsStringAsync(); @@ -238,13 +237,13 @@ public async Task GetVersions(string packageName) ?.Releases? .Where(item => item.Value.Count != 0).OrderBy(e => e.Value[0].UploadTime) .ThenBy(e => e.Value[0].UploadTime).ToDictionary(pair => pair.Key, pair => pair.Value); - if (pypiPackageInfo == null || pypiPackageInfo?.Count == 0) + if (pypiPackageInfo == null || pypiPackageInfo.Count == 0) { Log.Warning($"[EnvironmentService] {packageName} package not found"); return new GetVersionsResponse { Status = 1, Versions = [] }; } Log.Information($"[EnvironmentService] Found {packageName}"); - return new GetVersionsResponse { Status = 0, Versions = pypiPackageInfo?.Keys.ToArray() }; + return new GetVersionsResponse { Status = 0, Versions = pypiPackageInfo.Keys.ToArray() }; } catch (Exception) { @@ -260,7 +259,7 @@ public ActionResponse Install(string packageName, DataReceivedEventHandler conso { StartInfo = new ProcessStartInfo { - FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, + FileName = configurationService.AppConfig.CurrentEnvironment!.PythonPath, Arguments = $"-m pip install \"{packageName}\" -i {configurationService.GetUrlFromPackageSourceType()} --retries 1 --timeout 6 {extra}", UseShellExecute = false, @@ -285,7 +284,7 @@ public ActionResponse InstallByRequirements(string requirementsFilePath, DataRec { StartInfo = new ProcessStartInfo { - FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, + FileName = configurationService.AppConfig.CurrentEnvironment!.PythonPath, Arguments = $"-m pip install -r \"{requirementsFilePath}\" -i {configurationService.GetUrlFromPackageSourceType()} --retries 1 --timeout 6", UseShellExecute = false, @@ -311,7 +310,7 @@ public ActionResponse Download(string packageName, string downloadPath, DataRece { StartInfo = new ProcessStartInfo { - FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, + FileName = configurationService.AppConfig.CurrentEnvironment!.PythonPath, Arguments = $"-m pip download -d \"{downloadPath}\" \"{packageName}\" -i {configurationService.GetUrlFromPackageSourceType()} --retries 1 --timeout 6 {extra}", UseShellExecute = false, @@ -336,7 +335,7 @@ public ActionResponse Update(string packageName, DataReceivedEventHandler consol { StartInfo = new ProcessStartInfo { - FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, + FileName = configurationService.AppConfig.CurrentEnvironment!.PythonPath, Arguments = $"-m pip install --upgrade \"{packageName}\" -i {configurationService.GetUrlFromPackageSourceType()} --retries 1 --timeout 6", UseShellExecute = false, @@ -361,7 +360,7 @@ public ActionResponse Uninstall(string packageName, DataReceivedEventHandler con { StartInfo = new ProcessStartInfo { - FileName = configurationService.AppConfig!.CurrentEnvironment!.PythonPath, + FileName = configurationService.AppConfig.CurrentEnvironment!.PythonPath, Arguments = $"-m pip uninstall -y \"{packageName}\"", UseShellExecute = false, RedirectStandardOutput = true, diff --git a/src/PipManager/Services/Mask/IMaskService.cs b/src/PipManager/Services/Mask/IMaskService.cs index 97ff839..e452d74 100644 --- a/src/PipManager/Services/Mask/IMaskService.cs +++ b/src/PipManager/Services/Mask/IMaskService.cs @@ -1,5 +1,4 @@ using PipManager.Controls.Mask; -using PipManager.Models.Action; namespace PipManager.Services.Mask; @@ -7,8 +6,6 @@ public interface IMaskService { public void SetMaskPresenter(MaskPresenter maskPresenter); - public MaskPresenter GetMaskPresenter(); - public void Show(string message = ""); public void Hide(); diff --git a/src/PipManager/Services/Mask/MaskService.cs b/src/PipManager/Services/Mask/MaskService.cs index 98c317d..b44e18c 100644 --- a/src/PipManager/Services/Mask/MaskService.cs +++ b/src/PipManager/Services/Mask/MaskService.cs @@ -1,6 +1,5 @@ using PipManager.Controls.Mask; using PipManager.Languages; -using PipManager.Models.Action; using System.Windows.Controls; namespace PipManager.Services.Mask; @@ -16,12 +15,11 @@ public void SetMaskPresenter(MaskPresenter maskPresenter) _grid = Application.Current.TryFindResource("MaskGrid") as Grid; } - public MaskPresenter GetMaskPresenter() => _presenter ?? throw new ArgumentNullException("The MaskPresenter didn't set previously."); public void Show(string message = "") { if (_presenter == null || _grid == null) - throw new ArgumentNullException("The MaskPresenter didn't set previously."); + throw new ArgumentNullException($"The MaskPresenter didn't set previously."); ((_grid.Children[0] as StackPanel)!.Children[1] as TextBlock)!.Text = Lang.Mask_Loading; ((_grid.Children[0] as StackPanel)!.Children[2] as TextBlock)!.Text = message; _ = _presenter.ShowGrid(_grid); @@ -30,7 +28,7 @@ public void Show(string message = "") public void Hide() { if (_presenter == null) - throw new ArgumentNullException("The MaskPresenter didn't set previously."); + throw new ArgumentNullException($"The MaskPresenter didn't set previously."); _ = _presenter.HideGrid(); } } \ No newline at end of file diff --git a/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs b/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs index fcc45f3..fb5dfbc 100644 --- a/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs @@ -5,7 +5,6 @@ using PipManager.Services.Toast; using PipManager.Views.Pages.Action; using Serilog; -using System.Collections.ObjectModel; using Wpf.Ui; using Wpf.Ui.Controls; diff --git a/src/PipManager/ViewModels/Pages/Library/LibraryDetailViewModel.cs b/src/PipManager/ViewModels/Pages/Library/LibraryDetailViewModel.cs index 4bb0ea0..56a9712 100644 --- a/src/PipManager/ViewModels/Pages/Library/LibraryDetailViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Library/LibraryDetailViewModel.cs @@ -3,7 +3,6 @@ using PipManager.Models.Package; using PipManager.Models.Pages; using System.Collections.ObjectModel; -using Wpf.Ui; using Wpf.Ui.Controls; namespace PipManager.ViewModels.Pages.Library; @@ -12,7 +11,6 @@ public partial class LibraryDetailViewModel : ObservableObject, INavigationAware { public record LibraryDetailMessage(PackageItem Package); private bool _isInitialized; - private readonly INavigationService _navigationService; [ObservableProperty] private PackageItem? _package; @@ -38,9 +36,8 @@ public record LibraryDetailMessage(PackageItem Package); #endregion Classifier - public LibraryDetailViewModel(INavigationService navigationService) + public LibraryDetailViewModel() { - _navigationService = navigationService; WeakReferenceMessenger.Default.Register(this, Receive); } diff --git a/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs b/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs index 52dd55f..919cecc 100644 --- a/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Library/LibraryInstallViewModel.cs @@ -15,10 +15,8 @@ using System.Text; using ICSharpCode.SharpZipLib.GZip; using ICSharpCode.SharpZipLib.Tar; -using Serilog; using Wpf.Ui; using Wpf.Ui.Controls; -using TarEntry = System.Formats.Tar.TarEntry; namespace PipManager.ViewModels.Pages.Library; diff --git a/src/PipManager/ViewModels/Pages/Search/SearchDetailViewModel.cs b/src/PipManager/ViewModels/Pages/Search/SearchDetailViewModel.cs index 1c8603c..a49b5e9 100644 --- a/src/PipManager/ViewModels/Pages/Search/SearchDetailViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Search/SearchDetailViewModel.cs @@ -4,7 +4,6 @@ using PipManager.Languages; using PipManager.PackageSearch.Wrappers.Query; using PipManager.Services.Environment; -using PipManager.Services.Mask; using PipManager.Services.Toast; using PipManager.Views.Pages.Search; using Serilog; @@ -24,11 +23,10 @@ public record SearchDetailMessage(QueryListItemModel Package); private readonly HttpClient _httpClient; private readonly IThemeService _themeService; private readonly IToastService _toastService; - private readonly IMaskService _maskService; private readonly IEnvironmentService _environmentService; [ObservableProperty] - private bool _projectDescriptionVisibility = false; + private bool _projectDescriptionVisibility; private string _themeType = "light"; @@ -56,13 +54,12 @@ public record SearchDetailMessage(QueryListItemModel Package); [ObservableProperty] private QueryListItemModel? _package; - public SearchDetailViewModel(INavigationService navigationService, HttpClient httpClient, IThemeService themeService, IToastService toastService, IMaskService maskService, IEnvironmentService environmentService) + public SearchDetailViewModel(INavigationService navigationService, HttpClient httpClient, IThemeService themeService, IToastService toastService, IEnvironmentService environmentService) { _navigationService = navigationService; _httpClient = httpClient; _themeService = themeService; _toastService = toastService; - _maskService = maskService; _environmentService = environmentService; WeakReferenceMessenger.Default.Register(this, Receive); @@ -118,7 +115,6 @@ private async Task InstallPackage() if (installedPackages.Any(item => item.Name == Package!.Name)) { _toastService.Error(Lang.LibraryInstall_Add_AlreadyInstalled); - return; } } @@ -126,7 +122,7 @@ public void Receive(object recipient, SearchDetailMessage message) { Package = message.Package; - SearchDetailPage.ProjectDescriptionWebView!.Loaded += async (sender, e) => + SearchDetailPage.ProjectDescriptionWebView!.Loaded += async (_, _) => { ProjectDescriptionVisibility = false; var packageVersions = await _environmentService.GetVersions(Package!.Name); @@ -145,8 +141,8 @@ public void Receive(object recipient, SearchDetailMessage message) TargetVersion = AvailableVersions.First(); break; } - var webView2Environment = await CoreWebView2Environment.CreateAsync(null, AppInfo.CachesDir); - await SearchDetailPage.ProjectDescriptionWebView!.EnsureCoreWebView2Async().ConfigureAwait(true); + await CoreWebView2Environment.CreateAsync(null, AppInfo.CachesDir); + await SearchDetailPage.ProjectDescriptionWebView.EnsureCoreWebView2Async().ConfigureAwait(true); try { var projectDescriptionUrl = message.Package.Url; @@ -155,8 +151,8 @@ public void Receive(object recipient, SearchDetailMessage message) htmlDocument.LoadHtml(html); string projectDescriptionHtml = string.Format(_htmlModel, _themeType, ThemeTypeInHex, htmlDocument.DocumentNode.SelectSingleNode("//*[@id=\"description\"]/div").InnerHtml); - SearchDetailPage.ProjectDescriptionWebView!.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Dark; - SearchDetailPage.ProjectDescriptionWebView!.NavigateToString(projectDescriptionHtml); + SearchDetailPage.ProjectDescriptionWebView.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Dark; + SearchDetailPage.ProjectDescriptionWebView.NavigateToString(projectDescriptionHtml); } catch (Exception ex) { @@ -164,8 +160,8 @@ public void Receive(object recipient, SearchDetailMessage message) _toastService.Error(Lang.SearchDetail_ProjectDescription_LoadFailed); string projectDescriptionHtml = string.Format(_htmlModel, _themeType, ThemeTypeInHex, $"

{Lang.SearchDetail_ProjectDescription_LoadFailed}

"); - SearchDetailPage.ProjectDescriptionWebView!.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Dark; - SearchDetailPage.ProjectDescriptionWebView!.NavigateToString(projectDescriptionHtml); + SearchDetailPage.ProjectDescriptionWebView.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Dark; + SearchDetailPage.ProjectDescriptionWebView.NavigateToString(projectDescriptionHtml); } finally { diff --git a/src/PipManager/ViewModels/Pages/Search/SearchViewModel.cs b/src/PipManager/ViewModels/Pages/Search/SearchViewModel.cs index d49ada0..d16c340 100644 --- a/src/PipManager/ViewModels/Pages/Search/SearchViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Search/SearchViewModel.cs @@ -27,16 +27,16 @@ public partial class SearchViewModel(IPackageSearchService packageSearchService, private string _totalResultNumber = ""; [ObservableProperty] - private bool _onQuerying = false; + private bool _onQuerying; [ObservableProperty] - private bool _successQueried = false; + private bool _successQueried; [ObservableProperty] private bool _reachesFirstPage = true; [ObservableProperty] - private bool _reachesLastPage = false; + private bool _reachesLastPage; [ObservableProperty] private int _currentPage = 1; @@ -65,7 +65,6 @@ private void InitializeViewModel() [RelayCommand] private void ToDetailPage(object parameter) { - if (QueryList is null) return; navigationService.Navigate(typeof(SearchDetailPage)); var current = QueryList.Where(searchListItem => searchListItem.Name == parameter as string).ToList()[0]; WeakReferenceMessenger.Default.Send(new SearchDetailMessage(current)); @@ -157,7 +156,7 @@ public async Task Search(string? parameter) MaxPage = 1; CurrentPage = 1; QueryPackageName = parameter; - var result = await packageSearchService.Query(parameter, 1); + var result = await packageSearchService.Query(parameter); Process(result); OnQuerying = false; } diff --git a/src/PipManager/ViewModels/Pages/Tools/ToolsViewModel.cs b/src/PipManager/ViewModels/Pages/Tools/ToolsViewModel.cs index 5daf698..1b8d115 100644 --- a/src/PipManager/ViewModels/Pages/Tools/ToolsViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Tools/ToolsViewModel.cs @@ -6,6 +6,9 @@ namespace PipManager.ViewModels.Pages.Tools; public partial class ToolsViewModel : ObservableObject, INavigationAware { private bool _isInitialized; + + [ObservableProperty] + private string? _testProperty; public void OnNavigatedTo() { diff --git a/src/PipManager/ViewModels/Windows/MainWindowViewModel.cs b/src/PipManager/ViewModels/Windows/MainWindowViewModel.cs index 2216cb2..3ccc622 100644 --- a/src/PipManager/ViewModels/Windows/MainWindowViewModel.cs +++ b/src/PipManager/ViewModels/Windows/MainWindowViewModel.cs @@ -5,16 +5,14 @@ namespace PipManager.ViewModels.Windows; public partial class MainWindowViewModel : ObservableObject { - private readonly IConfigurationService _configurationService; [ObservableProperty] private bool _experimentMode; public MainWindowViewModel(IConfigurationService configurationService) { - _configurationService = configurationService; - if (_configurationService.AppConfig.CurrentEnvironment != null) + if (configurationService.AppConfig.CurrentEnvironment != null) { - Log.Information($"[MainWindow] Environment loaded ({_configurationService.AppConfig.CurrentEnvironment.PipVersion} for {_configurationService.AppConfig.CurrentEnvironment.PythonVersion})"); - ApplicationTitle = $"Pip Manager | {_configurationService.AppConfig.CurrentEnvironment.PipVersion} for {_configurationService.AppConfig.CurrentEnvironment.PythonVersion}"; + Log.Information($"[MainWindow] Environment loaded ({configurationService.AppConfig.CurrentEnvironment.PipVersion} for {configurationService.AppConfig.CurrentEnvironment.PythonVersion})"); + ApplicationTitle = $"Pip Manager | {configurationService.AppConfig.CurrentEnvironment.PipVersion} for {configurationService.AppConfig.CurrentEnvironment.PythonVersion}"; } else { diff --git a/src/PipManager/Views/Pages/Action/ActionExceptionPage.xaml b/src/PipManager/Views/Pages/Action/ActionExceptionPage.xaml index b1a4a7f..380a2b1 100644 --- a/src/PipManager/Views/Pages/Action/ActionExceptionPage.xaml +++ b/src/PipManager/Views/Pages/Action/ActionExceptionPage.xaml @@ -1,25 +1,25 @@ + x:Class="PipManager.Views.Pages.Action.ActionExceptionPage" + x:Name="ActionException" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:action="clr-namespace:PipManager.Views.Pages.Action" + xmlns:action1="clr-namespace:PipManager.Models.Action" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:lang="clr-namespace:PipManager.Languages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -29,39 +29,39 @@ - + + Text="{Binding OperationDescription}" + VerticalAlignment="Center" /> + VerticalAlignment="Center"> - + + TextWrapping="WrapWithOverflow" + VerticalAlignment="Center" /> - + + Margin="5,0,0,0" + Text="{Binding OperationTimestamp}" + VerticalAlignment="Center" /> @@ -76,47 +76,44 @@ + Grid.Row="1" + Orientation="Horizontal" + VerticalAlignment="Bottom"> + Icon="{ui:SymbolIcon Search24}" + Margin="3,0,0,0" /> + Content="{I18N {x:Static lang:LangKeys.ActionException_CopyToClipboard}}" + Margin="3,0,0,0" /> diff --git a/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs b/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs index 22174d5..6d1158a 100644 --- a/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs +++ b/src/PipManager/Views/Pages/Action/ActionPage.xaml.cs @@ -14,9 +14,4 @@ public ActionPage(ActionViewModel viewModel) InitializeComponent(); } - - private void TextBox_Scroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e) - { - - } } \ No newline at end of file diff --git a/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml b/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml index e622873..e327794 100644 --- a/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml +++ b/src/PipManager/Views/Pages/Library/LibraryInstallPage.xaml @@ -1,38 +1,37 @@  + x:Class="PipManager.Views.Pages.Library.LibraryInstallPage" + x:Name="LibraryInstall" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:lang="clr-namespace:PipManager.Languages" + xmlns:library="clr-namespace:PipManager.Views.Pages.Library" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:pages="clr-namespace:PipManager.Models.Pages" + xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - + - + + IsEnabled="{Binding ElementName=AddDefaultTaskList, Path=Items.Count, Converter={StaticResource IntegerToBool}}" + Margin="5,0,0,0" /> - + @@ -70,33 +69,33 @@ + Text="{Binding PackageName}" + VerticalAlignment="Center" /> + IsChecked="{Binding VersionSpecified, Mode=TwoWay}" + x:Name="VersionSpecifiedCheckbox" /> - + - + + Text="{Binding ViewModel.Requirements, Mode=TwoWay}" + x:Name="AddRequirementsTextBox" /> + IsEnabled="{Binding ElementName=AddRequirementsTextBox, Path=Text, Converter={StaticResource StringIsNotNullOrEmpty}}" + Margin="0,10,0,0" /> - + - + @@ -202,33 +201,33 @@ + Text="{Binding PackageName}" + VerticalAlignment="Center" /> + IsChecked="{Binding VersionSpecified, Mode=TwoWay}" + x:Name="DownloadDistributionsVersionSpecifiedCheckbox" /> - + + Text="{I18N {x:Static lang:LangKeys.LibraryInstall_Requirements_DownloadFolder}}" + VerticalAlignment="Center" /> + Margin="10,0,0,0" + Text="{Binding ViewModel.DownloadDistributionsFolderPath, Mode=TwoWay}" + x:Name="DownloadDistributionsFolderBrowseTextBox" /> + IsEnabled="{Binding ElementName=DownloadDistributionsTaskList, Path=Items.Count, Converter={StaticResource IntegerToBool}}" + Margin="5,0,0,0" /> + IsEnabled="{Binding ViewModel.DownloadDistributionsEnabled}" + Margin="5,0,0,0" />
- + + IsEnabled="{Binding ElementName=InstallDistributionsTaskList, Path=Items.Count, Converter={StaticResource IntegerToBool}}" + Margin="5,0,0,0" />
- + @@ -336,17 +335,20 @@ - + - + Margin="10,0,0,0" + Text="{Binding PackageName}" + VerticalAlignment="Center" /> + - + - + diff --git a/src/PipManager/Views/Pages/Library/LibraryPage.xaml b/src/PipManager/Views/Pages/Library/LibraryPage.xaml index 363bc59..5452a22 100644 --- a/src/PipManager/Views/Pages/Library/LibraryPage.xaml +++ b/src/PipManager/Views/Pages/Library/LibraryPage.xaml @@ -1,27 +1,25 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -37,28 +35,28 @@ Icon="{ui:SymbolIcon Add24}" IsEnabled="{Binding ViewModel.EnvironmentFoundVisible}" /> + IsEnabled="{Binding ElementName=LibraryList, Path=SelectedItems.Count, Converter={StaticResource IntegerToBool}}" + Margin="5,0,0,0" /> + IsEnabled="{Binding ElementName=LibraryList, Path=SelectedItems.Count, Converter={StaticResource IntegerToBool}}" + Margin="5,0,0,0" />
+ Orientation="Horizontal" + VerticalAlignment="Center"> @@ -71,14 +69,14 @@ - + @@ -95,15 +93,15 @@ + Visibility="{Binding ViewModel.LibraryList, Converter={StaticResource NotNullToVisibility}}" + x:Name="LibraryList"> @@ -116,9 +114,9 @@ + Text="{Binding PackageName}" + VerticalAlignment="Center" /> @@ -143,19 +141,19 @@ TextWrapping="Wrap" /> + Grid.Column="0" + Grid.ColumnSpan="2" + HorizontalAlignment="Right" + Icon="{ui:SymbolIcon ChevronRight24}" + Margin="0,0,10,0" /> - + @@ -164,17 +162,17 @@ + FontSize="16" + HorizontalAlignment="Center" + Margin="0,5,0,0" />
\ No newline at end of file diff --git a/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml b/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml index 310bb14..683135c 100644 --- a/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml +++ b/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml @@ -1,25 +1,25 @@  + x:Class="PipManager.Views.Pages.Search.SearchDetailPage" + x:Name="SearchDetail" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:lang="clr-namespace:PipManager.Languages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:search="clr-namespace:PipManager.Views.Pages.Search" + xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" + xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -28,27 +28,27 @@ + CornerRadius="5" + Grid.Row="1" + Margin="0,10,0,0" + Padding="3"> + VerticalAlignment="Center" + Visibility="{Binding ViewModel.ProjectDescriptionVisibility, Converter={StaticResource InverseBoolToVisibility}}" + Width="100" /> + NavigationStarting="SearchDetailProjectDescriptionWebView_NavigationStarting" + Visibility="{Binding ViewModel.ProjectDescriptionVisibility, Converter={StaticResource BoolToVisibility}}" + x:Name="SearchDetailProjectDescriptionWebView" /> @@ -57,19 +57,19 @@ + Text="{Binding ViewModel.Package.Name}" + VerticalAlignment="Center" /> + VerticalAlignment="Center"> @@ -78,35 +78,35 @@ FontTypography="Caption" Text="{I18N {x:Static lang:LangKeys.SearchDetail_LatestUpdatedTime}}" /> + Orientation="Horizontal" + VerticalAlignment="Center"> + SelectedItem="{Binding ViewModel.TargetVersion, Mode=TwoWay}" + VerticalAlignment="Center" + Width="150" /> + IsEnabled="False" + Margin="15,0,0,0" /> + IsEnabled="False" + Margin="15,0,0,0" /> diff --git a/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml.cs b/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml.cs index ae5e662..5ef7642 100644 --- a/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml.cs +++ b/src/PipManager/Views/Pages/Search/SearchDetailPage.xaml.cs @@ -1,4 +1,5 @@ -using Microsoft.Web.WebView2.Wpf; +using Microsoft.Web.WebView2.Core; +using Microsoft.Web.WebView2.Wpf; using Wpf.Ui.Controls; using SearchDetailViewModel = PipManager.ViewModels.Pages.Search.SearchDetailViewModel; @@ -6,7 +7,7 @@ namespace PipManager.Views.Pages.Search; public partial class SearchDetailPage : INavigableView { - public static WebView2? ProjectDescriptionWebView { get; set; } + public static WebView2? ProjectDescriptionWebView { get; private set; } public SearchDetailViewModel ViewModel { get; } @@ -15,10 +16,10 @@ public SearchDetailPage(SearchDetailViewModel viewModel) ViewModel = viewModel; DataContext = this; InitializeComponent(); - ProjectDescriptionWebView = SearchDetailProjectDesciptionWebView; + ProjectDescriptionWebView = SearchDetailProjectDescriptionWebView; } - private void SearchDetailProjectDesciptionWebView_NavigationStarting(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs e) + private void SearchDetailProjectDescriptionWebView_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e) { if (e.Uri.StartsWith("http://") || e.Uri.StartsWith("https://")) { @@ -26,9 +27,9 @@ private void SearchDetailProjectDesciptionWebView_NavigationStarting(object send } } - private void SearchDetailProjectDesciptionWebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e) + private void SearchDetailProjectDescriptionWebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs? e) { - if (e != null && e.IsSuccess) + if (e is { IsSuccess: true }) { ProjectDescriptionWebView!.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync( "document.addEventListener('contextmenu', event => event.preventDefault());"); diff --git a/src/PipManager/Views/Pages/Search/SearchPage.xaml b/src/PipManager/Views/Pages/Search/SearchPage.xaml index 558fe04..f9cba8d 100644 --- a/src/PipManager/Views/Pages/Search/SearchPage.xaml +++ b/src/PipManager/Views/Pages/Search/SearchPage.xaml @@ -1,25 +1,25 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -34,68 +34,67 @@ + x:Name="SearchTextBox" /> + IsDefault="True" + Margin="5,0,0,0" + VerticalAlignment="Stretch" /> + VerticalAlignment="Center" + Visibility="{Binding ViewModel.OnQuerying, Converter={StaticResource BoolToVisibility}}" + Width="80" /> + x:Name="SearchList"> + Text="{Binding Name}" + VerticalAlignment="Center" /> + Text="{Binding Version}" + VerticalAlignment="Center" /> + TextWrapping="Wrap" + Width="800" /> + Grid.Column="0" + HorizontalAlignment="Right" + Icon="{ui:SymbolIcon ChevronRight24}" + Margin="0,0,10,0" /> @@ -103,8 +102,8 @@ + Text="{Binding ViewModel.CurrentPage}" + VerticalAlignment="Center" /> + Text=" / " + VerticalAlignment="Center" /> + Text="{Binding ViewModel.MaxPage}" + VerticalAlignment="Center" /> diff --git a/src/PipManager/Views/Pages/Settings/SettingsPage.xaml b/src/PipManager/Views/Pages/Settings/SettingsPage.xaml index f9e6953..899bba2 100644 --- a/src/PipManager/Views/Pages/Settings/SettingsPage.xaml +++ b/src/PipManager/Views/Pages/Settings/SettingsPage.xaml @@ -1,7 +1,16 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - @@ -35,7 +31,7 @@ - + @@ -43,23 +39,23 @@ + Margin="0,8,0,0" + Message="{I18N {x:Static lang:LangKeys.Settings_PackageSource_Notice}}" + Title="{I18N {x:Static lang:LangKeys.Common_NoticeTitle_Notice}}" /> @@ -72,69 +68,69 @@ + Icon="{ui:SymbolIcon NetworkCheck20}" + Margin="0,10,0,0" /> @@ -147,7 +143,7 @@ - + @@ -155,23 +151,23 @@ + SelectedItem="{Binding ViewModel.Language, Mode=TwoWay}" + Width="200" + x:Name="LanguageComboBox"> @@ -181,7 +177,7 @@ - + @@ -189,13 +185,13 @@ @@ -207,17 +203,17 @@ GroupName="themeSelect" IsChecked="{Binding ViewModel.CurrentTheme, Converter={StaticResource ThemeEnumToBooleanConverter}, ConverterParameter=Light, Mode=TwoWay}" /> + IsChecked="{Binding ViewModel.CurrentTheme, Converter={StaticResource ThemeEnumToBooleanConverter}, ConverterParameter=Dark, Mode=TwoWay}" + Margin="10,0,0,0" /> - + @@ -225,33 +221,33 @@ - + + Width="200" + x:Name="LogAutoDeletionSlider"> @@ -259,9 +255,9 @@ @@ -273,7 +269,7 @@ - + @@ -281,33 +277,33 @@ - + + Width="200" + x:Name="CrushesAutoDeletionSlider"> @@ -315,9 +311,9 @@ @@ -337,9 +333,9 @@ + Icon="{ui:SymbolIcon Delete24}" + Margin="0,5,0,0"> @@ -347,13 +343,13 @@ @@ -361,9 +357,9 @@ + Icon="{ui:SymbolIcon AppFolder20}" + Margin="0,3,0,0"> @@ -371,13 +367,13 @@ @@ -385,9 +381,9 @@ + Icon="{ui:SymbolIcon Record20}" + Margin="0,3,0,0"> @@ -395,13 +391,13 @@ @@ -409,9 +405,9 @@ + Icon="{ui:SymbolIcon CircleOff20}" + Margin="0,3,0,0"> @@ -419,20 +415,20 @@ - + @@ -440,13 +436,13 @@ diff --git a/src/PipManager/Views/Windows/ExceptionWindow.xaml.cs b/src/PipManager/Views/Windows/ExceptionWindow.xaml.cs index 5d8deae..f474603 100644 --- a/src/PipManager/Views/Windows/ExceptionWindow.xaml.cs +++ b/src/PipManager/Views/Windows/ExceptionWindow.xaml.cs @@ -16,7 +16,10 @@ public void Initialize(Exception exception) { TypeTextBlock.Text = exception.GetType().ToString(); MessageTextBlock.Text = exception.Message; - StackTraceTextBox.Text = exception.StackTrace; + if (exception.StackTrace != null) + { + StackTraceTextBox.Text = exception.StackTrace; + } } private void ReportButton_OnClick(object sender, RoutedEventArgs e) diff --git a/src/PipManager/Views/Windows/MainWindow.xaml b/src/PipManager/Views/Windows/MainWindow.xaml index 0a561ad..1f914f7 100644 --- a/src/PipManager/Views/Windows/MainWindow.xaml +++ b/src/PipManager/Views/Windows/MainWindow.xaml @@ -1,7 +1,25 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -43,18 +43,18 @@ + Padding="42,0,42,0" + Transition="FadeInWithSlide" + x:Name="NavigationView"> - + + Grid.RowSpan="2" + x:Name="MaskPresenter" /> + Grid.RowSpan="2" + x:Name="MaskActionExceptionPresenter" /> + Grid.RowSpan="2" + x:Name="RootContentDialog" /> + Grid.Row="0" + ShowMaximize="False" + Title="{Binding ViewModel.ApplicationTitle}" + x:Name="TitleBar"> + diff --git a/src/PipManager/Views/Windows/MainWindow.xaml.cs b/src/PipManager/Views/Windows/MainWindow.xaml.cs index e26dd1f..04c72fa 100644 --- a/src/PipManager/Views/Windows/MainWindow.xaml.cs +++ b/src/PipManager/Views/Windows/MainWindow.xaml.cs @@ -18,7 +18,6 @@ public MainWindow( MainWindowViewModel viewModel, INavigationService navigationService, IServiceProvider serviceProvider, - ISnackbarService snackbarService, IContentDialogService contentDialogService, IMaskService maskPresenter, IActionService actionService From 6b935f113ba4f919aa9d71628b43db7862a6e0cb Mon Sep 17 00:00:00 2001 From: Mccree Lee <2935876049@qq.com> Date: Wed, 3 Apr 2024 11:10:41 +0800 Subject: [PATCH 14/15] perf: add some logs --- .../Pages/Action/ActionExceptionViewModel.cs | 2 + .../Pages/Action/ActionViewModel.cs | 23 ++++---- .../Environment/AddEnvironmentViewModel.cs | 56 +++++++++---------- .../Pages/Environment/EnvironmentViewModel.cs | 14 +++-- src/PipManager/Views/Windows/MainWindow.xaml | 4 +- 5 files changed, 52 insertions(+), 47 deletions(-) diff --git a/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs b/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs index cb13424..d8466d7 100644 --- a/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Action/ActionExceptionViewModel.cs @@ -49,6 +49,7 @@ private void InitializeViewModel() private void UpdateActionExceptionList() { Exceptions = new ObservableCollection(_actionService.ExceptionList); + Log.Information("[Action][Exceptions] Exception List updated ({Count} items)", Exceptions.Count); } private static string ExceptionFilter(string parameter) @@ -97,5 +98,6 @@ private void ExceptionCopyToClipboard(string? parameter) Clipboard.SetDataObject(ExceptionFilter(parameter)); _toastService.Success(Lang.ActionException_CopyToClipboardNotice); + Log.Information("[Action][Exceptions] Copied exception to clipboard"); } } \ No newline at end of file diff --git a/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs b/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs index fb5dfbc..bc4300c 100644 --- a/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Action/ActionViewModel.cs @@ -54,18 +54,21 @@ private void ShowExceptions() [RelayCommand] private void CancelAction(string? operationId) { - if (!string.IsNullOrEmpty(operationId)) + if (string.IsNullOrEmpty(operationId)) { - var result = _actionService.TryCancelOperation(operationId); - if(result == Lang.Action_OperationCanceled_AlreadyRunning) - { - _toastService.Error(Lang.Action_OperationCanceled_AlreadyRunning); - } - else - { - _toastService.Success(Lang.Action_OperationCanceled_Success); + return; + } - } + var result = _actionService.TryCancelOperation(operationId); + if(result == Lang.Action_OperationCanceled_AlreadyRunning) + { + _toastService.Error(Lang.Action_OperationCanceled_AlreadyRunning); + Log.Warning("[Action] Operation cancellation failed (already running): {OperationId}", operationId); + } + else + { + _toastService.Success(Lang.Action_OperationCanceled_Success); + Log.Information("[Action] Operation canceled: {OperationId}", operationId); } } } \ No newline at end of file diff --git a/src/PipManager/ViewModels/Pages/Environment/AddEnvironmentViewModel.cs b/src/PipManager/ViewModels/Pages/Environment/AddEnvironmentViewModel.cs index d968b98..0aa1738 100644 --- a/src/PipManager/ViewModels/Pages/Environment/AddEnvironmentViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Environment/AddEnvironmentViewModel.cs @@ -14,10 +14,6 @@ namespace PipManager.ViewModels.Pages.Environment; public partial class AddEnvironmentViewModel(INavigationService navigationService, IConfigurationService configurationService, IEnvironmentService environmentService, IToastService toastService) : ObservableObject, INavigationAware { private bool _isInitialized; - private readonly INavigationService _navigationService = navigationService; - private readonly IConfigurationService _configurationService = configurationService; - private readonly IEnvironmentService _environmentService = environmentService; - private readonly IToastService _toastService = toastService; public void OnNavigatedTo() { @@ -77,7 +73,7 @@ await Task.Run(() => if (!File.Exists(Path.Combine(item, "python.exe"))) continue; var environmentItem = - _configurationService.GetEnvironmentItem(Path.Combine(item, "python.exe")); + configurationService.GetEnvironmentItem(Path.Combine(item, "python.exe")); if (environmentItem == null) continue; EnvironmentItems.Add(environmentItem); } @@ -133,83 +129,83 @@ private void AddEnvironment(string parameter) switch (ByWay) { case 0 when EnvironmentItemInList == null: - _toastService.Error(Lang.ContentDialog_Message_EnvironmentNoSelection); + toastService.Error(Lang.ContentDialog_Message_EnvironmentNoSelection); break; case 0: { - var result = _environmentService.CheckEnvironmentAvailable(EnvironmentItemInList); - var alreadyExists = _environmentService.CheckEnvironmentExists(EnvironmentItemInList); + var result = environmentService.CheckEnvironmentAvailable(EnvironmentItemInList); + var alreadyExists = environmentService.CheckEnvironmentExists(EnvironmentItemInList); if (result.Success) { if (alreadyExists) { - _toastService.Error(Lang.ContentDialog_Message_EnvironmentAlreadyExists); + toastService.Error(Lang.ContentDialog_Message_EnvironmentAlreadyExists); } else { - _configurationService.AppConfig.CurrentEnvironment = EnvironmentItemInList; - _configurationService.AppConfig.EnvironmentItems.Add(EnvironmentItemInList); - _configurationService.Save(); + configurationService.AppConfig.CurrentEnvironment = EnvironmentItemInList; + configurationService.AppConfig.EnvironmentItems.Add(EnvironmentItemInList); + configurationService.Save(); Log.Information($"[AddEnvironment] Environment added ({EnvironmentItemInList.PipVersion} for {EnvironmentItemInList.PythonVersion})"); - _navigationService.GoBack(); + navigationService.GoBack(); } } else { - _toastService.Error(result.Message); + toastService.Error(result.Message); } break; } case 1: { - var result = _configurationService.GetEnvironmentItemFromCommand(PipCommand, "-V"); + var result = configurationService.GetEnvironmentItemFromCommand(PipCommand, "-V"); if (result != null) { - var alreadyExists = _environmentService.CheckEnvironmentExists(result); + var alreadyExists = environmentService.CheckEnvironmentExists(result); if (alreadyExists) { - _toastService.Error(Lang.ContentDialog_Message_EnvironmentAlreadyExists); + toastService.Error(Lang.ContentDialog_Message_EnvironmentAlreadyExists); } else { - _configurationService.AppConfig.CurrentEnvironment = result; - _configurationService.AppConfig.EnvironmentItems.Add(result); + configurationService.AppConfig.CurrentEnvironment = result; + configurationService.AppConfig.EnvironmentItems.Add(result); Log.Information($"[AddEnvironment] Environment added ({result.PipVersion} for {result.PythonVersion})"); - _configurationService.Save(); - _navigationService.GoBack(); + configurationService.Save(); + navigationService.GoBack(); } } else { - _toastService.Error(Lang.ContentDialog_Message_EnvironmentInvaild); + toastService.Error(Lang.ContentDialog_Message_EnvironmentInvaild); } break; } case 2: { - var result = _configurationService.GetEnvironmentItem(PythonPath); + var result = configurationService.GetEnvironmentItem(PythonPath); if (result != null) { - var alreadyExists = _environmentService.CheckEnvironmentExists(result); + var alreadyExists = environmentService.CheckEnvironmentExists(result); if (alreadyExists) { - _toastService.Error(Lang.ContentDialog_Message_EnvironmentAlreadyExists); + toastService.Error(Lang.ContentDialog_Message_EnvironmentAlreadyExists); } else { - _configurationService.AppConfig.CurrentEnvironment = result; - _configurationService.AppConfig.EnvironmentItems.Add(result); + configurationService.AppConfig.CurrentEnvironment = result; + configurationService.AppConfig.EnvironmentItems.Add(result); Log.Information($"[AddEnvironment] Environment added ({result.PipVersion} for {result.PythonVersion})"); - _configurationService.Save(); - _navigationService.GoBack(); + configurationService.Save(); + navigationService.GoBack(); } } else { - _toastService.Error(Lang.ContentDialog_Message_EnvironmentInvaild); + toastService.Error(Lang.ContentDialog_Message_EnvironmentInvaild); } break; diff --git a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs index 2f2bdba..c87d8a6 100644 --- a/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs +++ b/src/PipManager/ViewModels/Pages/Environment/EnvironmentViewModel.cs @@ -36,13 +36,15 @@ public void OnNavigatedTo() var currentEnvironment = configurationService.AppConfig.CurrentEnvironment; foreach (var environmentItem in EnvironmentItems) { - if (currentEnvironment is not null && environmentItem.PythonPath == currentEnvironment.PythonPath) + if (currentEnvironment is null || environmentItem.PythonPath != currentEnvironment.PythonPath) { - CurrentEnvironment = environmentItem; - var mainWindowViewModel = App.GetService(); - mainWindowViewModel.ApplicationTitle = $"Pip Manager | {CurrentEnvironment.PipVersion} for {CurrentEnvironment.PythonVersion}"; - Log.Information($"[Environment] Current Environment changed: {CurrentEnvironment.PythonPath}"); + continue; } + + CurrentEnvironment = environmentItem; + var mainWindowViewModel = App.GetService(); + mainWindowViewModel.ApplicationTitle = $"Pip Manager | {CurrentEnvironment.PipVersion} for {CurrentEnvironment.PythonVersion}"; + Log.Information($"[Environment] Current Environment changed: {CurrentEnvironment.PythonPath}"); } } @@ -140,10 +142,12 @@ await Task.Run(async () => else if (latest == string.Empty) { toastService.Error(Lang.ContentDialog_Message_NetworkError); + Log.Error("[Environment] Network error while checking for updates (environment: {environment})", CurrentEnvironment!.PipVersion); } else { toastService.Info(Lang.ContentDialog_Message_EnvironmentIsLatest); + Log.Information("[Environment] Environment is already up to date (environment: {environment})", CurrentEnvironment!.PipVersion); } } diff --git a/src/PipManager/Views/Windows/MainWindow.xaml b/src/PipManager/Views/Windows/MainWindow.xaml index 1f914f7..776aa14 100644 --- a/src/PipManager/Views/Windows/MainWindow.xaml +++ b/src/PipManager/Views/Windows/MainWindow.xaml @@ -110,12 +110,12 @@ Grid.RowSpan="2" x:Name="RootContentDialog" /> + + Title="{Binding ViewModel.ApplicationTitle}"> From 4e08ecf2ebf649995977d925e4f312c8724496c2 Mon Sep 17 00:00:00 2001 From: Mccree Lee <2935876049@qq.com> Date: Wed, 3 Apr 2024 11:10:59 +0800 Subject: [PATCH 15/15] perf: lazy load dependency list --- .../ViewModels/Pages/About/AboutViewModel.cs | 56 +++++++++++++------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs b/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs index 6d45714..c63e46d 100644 --- a/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs +++ b/src/PipManager/ViewModels/Pages/About/AboutViewModel.cs @@ -30,26 +30,46 @@ private void InitializeViewModel() ExperimentMode = configurationService.ExperimentMode; AppVersion = AppInfo.AppVersion; _isInitialized = true; + NugetLibraryList = + [ + new AboutNugetLibraryListItem("Antelcat.I18N.WPF", "MIT", "Copyright (c) 2023 Feast", + "https://github.com/Antelcat/Antelcat.I18N"), + new AboutNugetLibraryListItem("CommunityToolkit.Mvvm", "MIT", + "Copyright © .NET Foundation and Contributors", "https://github.com/CommunityToolkit/dotnet"), + new AboutNugetLibraryListItem("HtmlAgilityPack", "MIT", "Copyright © ZZZ Projects Inc.", + "https://github.com/zzzprojects/html-agility-pack"), + new AboutNugetLibraryListItem("Meziantou.Framework.WPF", "MIT", "Copyright (c) 2019 Gérald Barré", + "https://github.com/meziantou/Meziantou.Framework"), + new AboutNugetLibraryListItem("Microsoft.Extensions.Hosting", "MIT", + "Copyright © .NET Foundation and Contributors", "https://github.com/dotnet/runtime"), + new AboutNugetLibraryListItem("Microsoft.Web.WebView2", "Custom License", + "© Microsoft Corporation. All rights reserved.", "https://github.com/dotnet/runtime"), + new AboutNugetLibraryListItem("Microsoft.Xaml.Behaviors.Wpf", "MIT", "Copyright (c) 2015 Microsoft", + "https://github.com/microsoft/XamlBehaviorsWpf"), + new AboutNugetLibraryListItem("Newtonsoft.Json", "MIT", "Copyright (c) 2007 James Newton-King", + "https://github.com/JamesNK/Newtonsoft.Json"), + new AboutNugetLibraryListItem("Serilog", "Apache-2.0", "Copyright © 2013-2020 Serilog Contributors", + "https://github.com/serilog/serilog"), + new AboutNugetLibraryListItem("Serilog.Extensions.Logging", "Apache-2.0", + "Copyright © 2013-2020 Serilog Contributors", "https://github.com/serilog/serilog-extensions-logging"), + new AboutNugetLibraryListItem("Serilog.Sinks.Console", "Apache-2.0", + "Copyright © 2016 Serilog Contributors", "https://github.com/serilog/serilog-sinks-console"), + new AboutNugetLibraryListItem("Serilog.Sinks.File", "Apache-2.0", "Copyright © 2016 Serilog Contributors", + "https://github.com/serilog/serilog-sinks-file"), + new AboutNugetLibraryListItem("SharpZipLib", "MIT", "Copyright © 2000-2018 SharpZipLib Contributors", + "https://github.com/icsharpcode/SharpZipLib"), + new AboutNugetLibraryListItem("ValueConverters", "MIT", "Copyright (c) 2019 Thomas Galliker", + "https://github.com/thomasgalliker/ValueConverters.NET"), + new AboutNugetLibraryListItem("WPF-UI", "MIT", + "Copyright (c) 2021-2023 Leszek Pomianowski and WPF UI Contributors", + "https://github.com/lepoco/wpfui"), + new AboutNugetLibraryListItem("WPF-UI.Tray", "MIT", + "Copyright (c) 2021-2023 Leszek Pomianowski and WPF UI Contributors", + "https://github.com/lepoco/wpfui"), + ]; Log.Information("[About] Initialized"); } [ObservableProperty] - private ObservableCollection _nugetLibraryList = - [ - new AboutNugetLibraryListItem("Antelcat.I18N.WPF", "MIT", "Copyright (c) 2023 Feast", "https://github.com/Antelcat/Antelcat.I18N"), - new AboutNugetLibraryListItem("CommunityToolkit.Mvvm", "MIT", "Copyright © .NET Foundation and Contributors", "https://github.com/CommunityToolkit/dotnet"), - new AboutNugetLibraryListItem("HtmlAgilityPack", "MIT", "Copyright © ZZZ Projects Inc.", "https://github.com/zzzprojects/html-agility-pack"), - new AboutNugetLibraryListItem("Meziantou.Framework.WPF", "MIT", "Copyright (c) 2019 Gérald Barré", "https://github.com/meziantou/Meziantou.Framework"), - new AboutNugetLibraryListItem("Microsoft.Extensions.Hosting", "MIT", "Copyright © .NET Foundation and Contributors", "https://github.com/dotnet/runtime"), - new AboutNugetLibraryListItem("Microsoft.Web.WebView2", "Custom License", "© Microsoft Corporation. All rights reserved.", "https://github.com/dotnet/runtime"), - new AboutNugetLibraryListItem("Microsoft.Xaml.Behaviors.Wpf", "MIT", "Copyright (c) 2015 Microsoft", "https://github.com/microsoft/XamlBehaviorsWpf"), - new AboutNugetLibraryListItem("Newtonsoft.Json", "MIT", "Copyright (c) 2007 James Newton-King", "https://github.com/JamesNK/Newtonsoft.Json"), - new AboutNugetLibraryListItem("Serilog", "Apache-2.0", "Copyright © 2013-2020 Serilog Contributors", "https://github.com/serilog/serilog"), - new AboutNugetLibraryListItem("Serilog.Extensions.Logging", "Apache-2.0", "Copyright © 2013-2020 Serilog Contributors", "https://github.com/serilog/serilog-extensions-logging"), - new AboutNugetLibraryListItem("Serilog.Sinks.Console", "Apache-2.0", "Copyright © 2016 Serilog Contributors", "https://github.com/serilog/serilog-sinks-console"), - new AboutNugetLibraryListItem("Serilog.Sinks.File", "Apache-2.0", "Copyright © 2016 Serilog Contributors", "https://github.com/serilog/serilog-sinks-file"), - new AboutNugetLibraryListItem("ValueConverters", "MIT", "Copyright (c) 2019 Thomas Galliker", "https://github.com/thomasgalliker/ValueConverters.NET"), - new AboutNugetLibraryListItem("WPF-UI", "MIT", "Copyright (c) 2021-2023 Leszek Pomianowski and WPF UI Contributors", "https://github.com/lepoco/wpfui"), - new AboutNugetLibraryListItem("WPF-UI.Tray", "MIT", "Copyright (c) 2021-2023 Leszek Pomianowski and WPF UI Contributors", "https://github.com/lepoco/wpfui"), - ]; + private ObservableCollection _nugetLibraryList = []; } \ No newline at end of file