From 24b7f7cfc292193d3672f1376e11a41b6c4b333e Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Thu, 24 Oct 2024 02:40:57 -0400 Subject: [PATCH 01/71] UI tweak --- src/setup.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/setup.bat b/src/setup.bat index eaee308..1572964 100644 --- a/src/setup.bat +++ b/src/setup.bat @@ -820,7 +820,7 @@ REM Installs a module in the module's directory, and returns success if "!moduleName!" == "" set moduleName=!moduleId! - set announcement=Installing module !moduleName! !moduleVersion! + set announcement=Installing module !moduleName! !moduleVersion! (!moduleType!) call "!utilsScript!" WriteLine "!announcement!" "White" "Blue" !lineWidth! call "!utilsScript!" WriteLine @@ -922,7 +922,7 @@ REM Installs a module in the module's directory, and returns success call "!utilsScript!" WriteLine "moduleStartFilePath = !moduleStartFilePath!" "!color_info!" ) - call "!utilsScript!" WriteLine "!moduleType! module install" !color_mute! + REM call "!utilsScript!" WriteLine "!moduleType! module install" !color_mute! if exist "!moduleDirPath!\install.bat" ( From cc0632a0da8e1dd4559334abec09bf84b45a4fe2 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 29 Oct 2024 13:16:07 +1100 Subject: [PATCH 02/71] Corrections to macOS .NET install script --- devops/install/dotnet-install.sh | 6 +++++- src/SDK/install.sh | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/devops/install/dotnet-install.sh b/devops/install/dotnet-install.sh index 08acd9e..5877bf0 100644 --- a/devops/install/dotnet-install.sh +++ b/devops/install/dotnet-install.sh @@ -926,7 +926,11 @@ get_user_install_path() { if [ ! -z "${DOTNET_INSTALL_DIR:-}" ]; then echo "$DOTNET_INSTALL_DIR" else - echo "$HOME/.dotnet" + if [ "$normalized_os" == "osx" ]; then + echo "/usr/local/share/dotnet" + else + echo "$HOME/.dotnet" + fi fi return 0 } diff --git a/src/SDK/install.sh b/src/SDK/install.sh index eade12c..613bda7 100644 --- a/src/SDK/install.sh +++ b/src/SDK/install.sh @@ -111,8 +111,8 @@ fi # Setup .NET for the server, the SDK Utilities, and any .NET modules that may # need it if [ "$executionEnvironment" = "Development" ]; then - setupDotNet "$serverDotNetVersion" "aspnetcore" setupDotNet "$serverDotNetVersion" "sdk" + setupDotNet "$serverDotNetVersion" "aspnetcore" else setupDotNet "$serverDotNetVersion" "aspnetcore" fi From c3f97e56d0709953f2724bff8f13febf2e1cabd1 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 3 Nov 2024 16:34:13 +1100 Subject: [PATCH 03/71] comments --- src/SDK/NET/Backend/BackendClient.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDK/NET/Backend/BackendClient.cs b/src/SDK/NET/Backend/BackendClient.cs index 732afe1..8e8e65b 100644 --- a/src/SDK/NET/Backend/BackendClient.cs +++ b/src/SDK/NET/Backend/BackendClient.cs @@ -19,8 +19,9 @@ public class BackendClient private record LoggingData(string message, string category, LogLevel logLevel, string label); - private static HttpClient? _httpGetRequestClient; - private static HttpClient? _httpSendResponseClient; + private static HttpClient? _httpGetRequestClient; // For querying server's request queue + private static HttpClient? _httpSendResponseClient; // For sending response to request to server + private Channel _loggingQueue = Channel.CreateBounded(1024); private int _errorPauseSecs = 0; From 2b08a343718e62323a016d060b074fbfc47507ab Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 17 Nov 2024 14:01:10 -0500 Subject: [PATCH 04/71] Potential duplicate checkin: VSCode git weirdness --- .../package-ObjectDetectionYOLOv5-6.2.yml | 7 +++-- README.md | 18 ++++++------ devops/build/create_packages.bat | 3 +- devops/install/dotnet-install.sh | 6 +++- .../modulesettings.json | 2 +- .../modulesettings.json | 2 +- src/SDK/NET/Backend/BackendClient.cs | 5 ++-- src/SDK/NET/Common/VersionInfo.cs | 16 ++++++++++ src/SDK/NET/Modules/ModuleBase.cs | 1 - src/SDK/NET/Modules/ModuleDescription.cs | 12 +++++++- src/SDK/install.sh | 2 +- src/demos/clients/Javascript/Vision.html | 4 +-- .../DotNetLongProcess/modulesettings.json | 2 +- .../modules/DotNetSimple/modulesettings.json | 2 +- .../PythonLongProcess/modulesettings.json | 2 +- .../modules/PythonSimple/modulesettings.json | 2 +- src/server/Config/ModuleOptions.cs | 5 ++++ src/server/Controllers/ModuleController.cs | 9 ++++-- src/server/Modules/ModuleInstaller.cs | 15 ++++++++-- src/server/Modules/ModuleSettings.cs | 1 + src/server/Version/ServerVersionService.cs | 18 ++++++++++-- src/server/appsettings.development.json | 9 ++++-- src/server/appsettings.json | 29 ++++++++++++++----- src/server/wwwroot/explorer.html | 2 +- src/server/wwwroot/index.html | 16 +++++----- 25 files changed, 135 insertions(+), 55 deletions(-) diff --git a/.github/workflows/package-ObjectDetectionYOLOv5-6.2.yml b/.github/workflows/package-ObjectDetectionYOLOv5-6.2.yml index 505e787..e107e6b 100644 --- a/.github/workflows/package-ObjectDetectionYOLOv5-6.2.yml +++ b/.github/workflows/package-ObjectDetectionYOLOv5-6.2.yml @@ -13,17 +13,18 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Create module package file id: create_package run: | cd modules/ObjectDetectionYOLOv5-6.2 - package_file=$(curl -sL https://raw.githubusercontent.com/codeproject/CodeProject.AI-Server/refs/heads/main/devops/build/create_packages.sh --no-color --github-action | bash) + package_file=$(curl -sL https://raw.githubusercontent.com/codeproject/CodeProject.AI-Server/refs/heads/main/devops/build/create_packages.sh | bash -s -- --no-color --github-action) + echo "package_file=$package_file" echo "package_file=$package_file" >> $GITHUB_OUTPUT - name: Upload ZIP as artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ steps.create_package.outputs.package_file }} path: ${{ steps.create_package.outputs.package_file }} diff --git a/README.md b/README.md index 2937ab4..76765e8 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,19 @@ # CodeProject.AI Server - [**Download the latest version**](https://www.codeproject.com/ai/latest.aspx) + [**Download the latest version**](https://codeproject.github.io/codeproject.ai/latest.html) A standalone, self-hosted, fast, free and Open Source Artificial Intelligence microserver for any platform, any language. It can be installed locally, required no off-device or out of network data transfer, and is easy to use. -![Object detection](https://www.codeproject.com/ai/docs/img/DetectThings.png) +![Object detection](https://codeproject.github.io/codeproject.ai/img/DetectThings.png) # Supported Platforms
-| | | | | | | | | +| | | | | | | | | | :------: | :---: | :---------: | :-----: | :----: | :----: | :--------------------: | :-------------------: | | Windows | macOS | macOS arm64 | Ubuntu / Debian | Raspberry Pi arm64 | Docker | Visual Studio
2019+ | Visual Studio
Code | @@ -32,7 +32,7 @@ transfer, and is easy to use. 1. AI programming is something every single developer should be aware of. We wanted a fun project we could use to help teach developers and get them involved in AI. We'll be using CodeProject.AI as a focus for articles and exploration to make it fun and painless to learn AI programming. -3. We got sick of fighting versions and libraries and models and being blocked by tiny annoying things every step of the way. So we put put this together so we could save you the frustation. We'll take care of the housekeeping, you focus on the code. +3. We got sick of fighting versions and libraries and models and being blocked by tiny annoying things every step of the way. So we put put this together so we could save you the frustration. We'll take care of the housekeeping, you focus on the code. 2. We also got sick of needing to sign up to potentially expensive services for AI functionality. This is something we need, and by sharing maybe you can use it too, and hopefully add your own modules and improvements along the way. @@ -40,7 +40,7 @@ transfer, and is easy to use. ### 1: Running and playing with the features -1. [**Download the latest version**](https://www.codeproject.com/ai/latest.aspx), install, and launch the shortcut to the server's dashboard on your desktop. +1. [**Download the latest version**](https://codeproject.github.io/codeproject.ai/latest.html), install, and launch the shortcut to the server's dashboard on your desktop. 2. On the dashboard, top and centre, is a link to the CodeProject.AI Explorer. Open that and play! ### 2: Running and debugging the code @@ -127,8 +127,8 @@ The current release provides support for CPU on each platform, DirectML on Windo ## How to Guides - - [Installing CodeProject.AI on your machine](https://www.codeproject.com/ai/docs/why/install_on_windows.html). For those who have CodeProject.AI integrated with Home Assist or Blue Iris - - [Setting up the development environment](https://www.codeproject.com/ai/docs/devguide/install_dev.html) (spoiler: it's easy!) - - [Running in Docker](https://www.codeproject.com/ai/docs/why/running_in_docker.html) - - Setup or install issues? See [Common Errors](https://www.codeproject.com/ai/docs/devguide/common_errors.html) + - [Installing CodeProject.AI on your machine](https://codeproject.github.io/codeproject.ai/why/install_on_windows.html). For those who have CodeProject.AI integrated with Home Assist or Blue Iris + - [Setting up the development environment](https://codeproject.github.io/codeproject.ai/devguide/install_dev.html) (spoiler: it's easy!) + - [Running in Docker](https://codeproject.github.io/codeproject.ai/why/running_in_docker.html) + - Setup or install issues? See [Common Errors](https://codeproject.github.io/codeproject.ai/devguide/common_errors.html) diff --git a/devops/build/create_packages.bat b/devops/build/create_packages.bat index 63b2af4..427b641 100644 --- a/devops/build/create_packages.bat +++ b/devops/build/create_packages.bat @@ -62,7 +62,7 @@ set rootDirPath=%cd% popd set sdkPath=%rootDirPath%\%srcDir%\%sdkDir% set utilsScriptsDirPath=%rootDirPath%\%srcDir%\scripts -set utilsScript=!utilsScriptsDirPath!\utils.bat +set utilsScript=%utilsScriptsDirPath%\utils.bat :: Override some values via parameters :::::::::::::::::::::::::::::::::::::::: @@ -103,7 +103,6 @@ set modulesDirPath=!rootDirPath!\!modulesDir! set externalModulesDirPath=!rootDirPath!\..\!externalModulesDir! set packageDirPath=!rootDirPath!\!packageDir! -if [ ! -d "${packageDirPath}" ]; then mkdir -p "${packageDirPath}"; fi if not exist "!packageDirPath!" mkdir "!packageDirPath!" diff --git a/devops/install/dotnet-install.sh b/devops/install/dotnet-install.sh index 08acd9e..5877bf0 100644 --- a/devops/install/dotnet-install.sh +++ b/devops/install/dotnet-install.sh @@ -926,7 +926,11 @@ get_user_install_path() { if [ ! -z "${DOTNET_INSTALL_DIR:-}" ]; then echo "$DOTNET_INSTALL_DIR" else - echo "$HOME/.dotnet" + if [ "$normalized_os" == "osx" ]; then + echo "/usr/local/share/dotnet" + else + echo "$HOME/.dotnet" + fi fi return 0 } diff --git a/modules/ObjectDetectionYOLOv5-6.2/modulesettings.json b/modules/ObjectDetectionYOLOv5-6.2/modulesettings.json index 122b7b9..6563942 100644 --- a/modules/ObjectDetectionYOLOv5-6.2/modulesettings.json +++ b/modules/ObjectDetectionYOLOv5-6.2/modulesettings.json @@ -11,7 +11,7 @@ "License": "GPL-3.0", "LicenseUrl": "https://opensource.org/licenses/GPL-3.0", "Author": "Matthew Dennis", - "Homepage": "https://codeproject.com/ai", + "Homepage": "https://codeproject.github.io/codeproject.ai", "BasedOn": "Ultralytics YOLOv5", "BasedOnUrl": "https://github.com/ultralytics/yolov5" }, diff --git a/modules/ObjectDetectionYOLOv5Net/modulesettings.json b/modules/ObjectDetectionYOLOv5Net/modulesettings.json index 2909ceb..a0acdc7 100644 --- a/modules/ObjectDetectionYOLOv5Net/modulesettings.json +++ b/modules/ObjectDetectionYOLOv5Net/modulesettings.json @@ -12,7 +12,7 @@ "License": "MIT", "LicenseUrl": "https://opensource.org/licenses/MIT", "Author": "Matthew Dennis", - "Homepage": "https://codeproject.com/ai", + "Homepage": "https://codeproject.github.io/codeproject.ai", "BasedOn": "yolov5-net", "BasedOnUrl": "https://github.com/techwingslab/yolov5-net" }, diff --git a/src/SDK/NET/Backend/BackendClient.cs b/src/SDK/NET/Backend/BackendClient.cs index 732afe1..8e8e65b 100644 --- a/src/SDK/NET/Backend/BackendClient.cs +++ b/src/SDK/NET/Backend/BackendClient.cs @@ -19,8 +19,9 @@ public class BackendClient private record LoggingData(string message, string category, LogLevel logLevel, string label); - private static HttpClient? _httpGetRequestClient; - private static HttpClient? _httpSendResponseClient; + private static HttpClient? _httpGetRequestClient; // For querying server's request queue + private static HttpClient? _httpSendResponseClient; // For sending response to request to server + private Channel _loggingQueue = Channel.CreateBounded(1024); private int _errorPauseSecs = 0; diff --git a/src/SDK/NET/Common/VersionInfo.cs b/src/SDK/NET/Common/VersionInfo.cs index f05ba3a..a9d7452 100644 --- a/src/SDK/NET/Common/VersionInfo.cs +++ b/src/SDK/NET/Common/VersionInfo.cs @@ -2,6 +2,22 @@ namespace CodeProject.AI.SDK.Common { + /// + /// Maps to the server's version.json file + /// + public class VersionFileContents + { + public class VersionSectionWrap + { + /// + /// The Version info + /// + public VersionInfo? VersionInfo { get; set; } = null; + } + + public VersionSectionWrap? VersionSection { get; set; } = null; + } + /// /// The current version of the server. /// diff --git a/src/SDK/NET/Modules/ModuleBase.cs b/src/SDK/NET/Modules/ModuleBase.cs index c9d01ef..18dd57d 100644 --- a/src/SDK/NET/Modules/ModuleBase.cs +++ b/src/SDK/NET/Modules/ModuleBase.cs @@ -327,7 +327,6 @@ public static bool IsCompatible(this ModuleBase module, string? currentServerVer available = platformOK; } - // Final check: is the module specifically excluded from the current platform? return available; } } diff --git a/src/SDK/NET/Modules/ModuleDescription.cs b/src/SDK/NET/Modules/ModuleDescription.cs index 6e91833..f331200 100644 --- a/src/SDK/NET/Modules/ModuleDescription.cs +++ b/src/SDK/NET/Modules/ModuleDescription.cs @@ -169,10 +169,12 @@ public static class ModuleDescriptionExtensions /// This module that requires initialisation /// The current version of the server /// The path to the folder containing this module + /// The base URL for downloading module install packages /// The location of this module /// True on success; false otherwise public static void Initialise(this ModuleDescription module, string currentServerVersion, - string moduleDirPath, ModuleLocation moduleLocation) + string moduleDirPath, string moduleStorageUrl, + ModuleLocation moduleLocation) { module.ModuleDirPath = moduleDirPath; module.WorkingDirectory = module.ModuleDirPath; // This once was allowed to be different to moduleDirPath @@ -181,6 +183,14 @@ public static void Initialise(this ModuleDescription module, string currentServe module.CheckVersionAgainstModuleReleases(); SetLatestCompatibleVersion(module, currentServerVersion); + // When we downloaded this list from CodeProject the download URL was set. When we get + // this list from a modules.json file (eg off github) then the download Url isn't set + if (string.IsNullOrWhiteSpace(module.DownloadUrl)) + { + // TODO: Generalise this in a utility method + module.DownloadUrl = $"{moduleStorageUrl}{module.ModuleId}-{module.Version}.zip"; + } + // Set the status of all entries based on availability on this platform module.Status = module.IsCompatible(currentServerVersion) ? ModuleStatusType.Available : ModuleStatusType.NotAvailable; diff --git a/src/SDK/install.sh b/src/SDK/install.sh index eade12c..613bda7 100644 --- a/src/SDK/install.sh +++ b/src/SDK/install.sh @@ -111,8 +111,8 @@ fi # Setup .NET for the server, the SDK Utilities, and any .NET modules that may # need it if [ "$executionEnvironment" = "Development" ]; then - setupDotNet "$serverDotNetVersion" "aspnetcore" setupDotNet "$serverDotNetVersion" "sdk" + setupDotNet "$serverDotNetVersion" "aspnetcore" else setupDotNet "$serverDotNetVersion" "aspnetcore" fi diff --git a/src/demos/clients/Javascript/Vision.html b/src/demos/clients/Javascript/Vision.html index ee06a5e..e322ba7 100644 --- a/src/demos/clients/Javascript/Vision.html +++ b/src/demos/clients/Javascript/Vision.html @@ -1057,7 +1057,7 @@
- + @@ -1108,7 +1108,7 @@ - + - + CodeProject.AI diff --git a/src/server/wwwroot/index.html b/src/server/wwwroot/index.html index 58de4df..0d17c84 100644 --- a/src/server/wwwroot/index.html +++ b/src/server/wwwroot/index.html @@ -142,7 +142,7 @@ S12.291,7.968,12.291,8.455z" /> - + CodeProject.AI @@ -153,10 +153,10 @@
- Docs + Docs
From 47211b9795fe1bfd1a2f20538b8e3e5c69180892 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 17 Nov 2024 14:47:46 -0500 Subject: [PATCH 05/71] Corrections for stricter compiling --- src/SDK/NET/API/ApiClient.cs | 6 +++++- src/SDK/NET/API/ModuleResponses.cs | 2 ++ src/SDK/NET/API/ServerResponses.cs | 2 ++ src/SDK/NET/Backend/BackendClient.cs | 8 ++++++-- src/SDK/NET/Backend/BackendRequests.cs | 3 ++- src/SDK/NET/Backend/ModuleWorkerBase.cs | 10 ++++++++-- src/SDK/NET/Common/RequestPayload.cs | 6 +++++- src/SDK/NET/FrontEndClient/FaceProcessingClient.cs | 3 +++ src/SDK/NET/FrontEndClient/FrontEndClient.cs | 3 +++ src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs | 1 + src/SDK/NET/FrontEndClient/SceneClassifierClient.cs | 1 + src/SDK/NET/Modules/ModuleBase.cs | 4 +++- src/SDK/NET/Modules/ProcessStatus.cs | 5 +++-- src/SDK/NET/Utils/ExpandoExtensions.cs | 2 ++ src/SDK/NET/Utils/ImageUtils.cs | 1 + src/SDK/NET/Utils/JsonUtils.cs | 4 ++++ src/SDK/NET/Utils/ObjectPool.cs | 3 ++- src/SDK/NET/Utils/SystemInfo.cs | 5 +++++ src/SDK/NET/Utils/Text.cs | 5 ++++- src/setup.bat | 4 ++++ 20 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/SDK/NET/API/ApiClient.cs b/src/SDK/NET/API/ApiClient.cs index ced2a46..1404cf7 100644 --- a/src/SDK/NET/API/ApiClient.cs +++ b/src/SDK/NET/API/ApiClient.cs @@ -1,4 +1,8 @@ -using System.Net.Http.Json; +using System; +using System.IO; +using System.Net.Http; +using System.Net.Http.Json; +using System.Threading.Tasks; using CodeProject.AI.SDK.Common; namespace CodeProject.AI.SDK.API diff --git a/src/SDK/NET/API/ModuleResponses.cs b/src/SDK/NET/API/ModuleResponses.cs index 6659855..a112d34 100644 --- a/src/SDK/NET/API/ModuleResponses.cs +++ b/src/SDK/NET/API/ModuleResponses.cs @@ -1,4 +1,6 @@ using System.Text.Json.Serialization; +using System.Threading; +using System.Threading.Tasks; namespace CodeProject.AI.SDK.API { diff --git a/src/SDK/NET/API/ServerResponses.cs b/src/SDK/NET/API/ServerResponses.cs index 8b6fb20..d5ca8ab 100644 --- a/src/SDK/NET/API/ServerResponses.cs +++ b/src/SDK/NET/API/ServerResponses.cs @@ -3,6 +3,8 @@ using CodeProject.AI.SDK.Modules; using CodeProject.AI.SDK.Common; using CodeProject.AI.SDK.Server; +using System.Collections.Generic; +using System; namespace CodeProject.AI.SDK.API { diff --git a/src/SDK/NET/Backend/BackendClient.cs b/src/SDK/NET/Backend/BackendClient.cs index 8e8e65b..6e40e83 100644 --- a/src/SDK/NET/Backend/BackendClient.cs +++ b/src/SDK/NET/Backend/BackendClient.cs @@ -1,9 +1,13 @@ -using System.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; using System.Dynamic; +using System.Net.Http; using System.Net.Http.Json; using System.Text.Json; +using System.Threading; using System.Threading.Channels; - +using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace CodeProject.AI.SDK diff --git a/src/SDK/NET/Backend/BackendRequests.cs b/src/SDK/NET/Backend/BackendRequests.cs index 50fadbe..0995f8c 100644 --- a/src/SDK/NET/Backend/BackendRequests.cs +++ b/src/SDK/NET/Backend/BackendRequests.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System; +using System.Text.Json.Serialization; namespace CodeProject.AI.SDK { diff --git a/src/SDK/NET/Backend/ModuleWorkerBase.cs b/src/SDK/NET/Backend/ModuleWorkerBase.cs index 0856da4..1d576bc 100644 --- a/src/SDK/NET/Backend/ModuleWorkerBase.cs +++ b/src/SDK/NET/Backend/ModuleWorkerBase.cs @@ -1,7 +1,13 @@ -using System.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; using System.Dynamic; +using System.IO; +using System.Linq; +using System.Net.Http; using System.Net.Http.Json; - +using System.Threading; +using System.Threading.Tasks; using CodeProject.AI.SDK.API; using CodeProject.AI.SDK.Utils; diff --git a/src/SDK/NET/Common/RequestPayload.cs b/src/SDK/NET/Common/RequestPayload.cs index 8400779..a15d147 100644 --- a/src/SDK/NET/Common/RequestPayload.cs +++ b/src/SDK/NET/Common/RequestPayload.cs @@ -1,4 +1,8 @@ -using System.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; namespace CodeProject.AI.SDK { diff --git a/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs b/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs index c058508..7224afb 100644 --- a/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs +++ b/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs @@ -1,4 +1,7 @@  +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using CodeProject.AI.SDK.API; namespace CodeProject.AI.SDK.Server diff --git a/src/SDK/NET/FrontEndClient/FrontEndClient.cs b/src/SDK/NET/FrontEndClient/FrontEndClient.cs index 0882051..0a29c59 100644 --- a/src/SDK/NET/FrontEndClient/FrontEndClient.cs +++ b/src/SDK/NET/FrontEndClient/FrontEndClient.cs @@ -1,4 +1,7 @@  +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using CodeProject.AI.SDK.API; namespace CodeProject.AI.SDK.Server diff --git a/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs b/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs index f88b0a5..1bd7478 100644 --- a/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs +++ b/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs @@ -1,4 +1,5 @@  +using System.Threading.Tasks; using CodeProject.AI.SDK.API; using CodeProject.AI.SDK.Server; diff --git a/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs b/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs index 2bfbefa..6fcadfb 100644 --- a/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs +++ b/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs @@ -1,4 +1,5 @@  +using System.Threading.Tasks; using CodeProject.AI.SDK.API; namespace CodeProject.AI.SDK.Server diff --git a/src/SDK/NET/Modules/ModuleBase.cs b/src/SDK/NET/Modules/ModuleBase.cs index 18dd57d..7a506a8 100644 --- a/src/SDK/NET/Modules/ModuleBase.cs +++ b/src/SDK/NET/Modules/ModuleBase.cs @@ -1,4 +1,6 @@ -using System.Text.Json.Serialization; +using System; +using System.Linq; +using System.Text.Json.Serialization; using CodeProject.AI.SDK.API; using CodeProject.AI.SDK.Common; using CodeProject.AI.SDK.Utils; diff --git a/src/SDK/NET/Modules/ProcessStatus.cs b/src/SDK/NET/Modules/ProcessStatus.cs index 4507bf7..9f22544 100644 --- a/src/SDK/NET/Modules/ProcessStatus.cs +++ b/src/SDK/NET/Modules/ProcessStatus.cs @@ -1,8 +1,9 @@ -using System.Runtime.Serialization; +using System; +using System.Runtime.Serialization; using System.Text; using System.Text.Json.Nodes; using System.Text.Json.Serialization; - +using System.Threading; using CodeProject.AI.SDK.Server; namespace CodeProject.AI.SDK.Modules diff --git a/src/SDK/NET/Utils/ExpandoExtensions.cs b/src/SDK/NET/Utils/ExpandoExtensions.cs index 178a920..832f1fa 100644 --- a/src/SDK/NET/Utils/ExpandoExtensions.cs +++ b/src/SDK/NET/Utils/ExpandoExtensions.cs @@ -1,3 +1,5 @@ +using System; +using System.Collections.Generic; using System.Dynamic; using System.Reflection; using System.Text.Json; diff --git a/src/SDK/NET/Utils/ImageUtils.cs b/src/SDK/NET/Utils/ImageUtils.cs index b452a1b..a11b7f7 100644 --- a/src/SDK/NET/Utils/ImageUtils.cs +++ b/src/SDK/NET/Utils/ImageUtils.cs @@ -1,3 +1,4 @@ +using System.IO; using SkiaSharp; namespace CodeProject.AI.SDK.Utils diff --git a/src/SDK/NET/Utils/JsonUtils.cs b/src/SDK/NET/Utils/JsonUtils.cs index 8003ecf..ae877da 100644 --- a/src/SDK/NET/Utils/JsonUtils.cs +++ b/src/SDK/NET/Utils/JsonUtils.cs @@ -1,7 +1,11 @@ +using System; +using System.IO; +using System.Linq; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.RegularExpressions; +using System.Threading.Tasks; namespace CodeProject.AI.SDK.Utils { diff --git a/src/SDK/NET/Utils/ObjectPool.cs b/src/SDK/NET/Utils/ObjectPool.cs index 478fbe7..1089080 100644 --- a/src/SDK/NET/Utils/ObjectPool.cs +++ b/src/SDK/NET/Utils/ObjectPool.cs @@ -1,4 +1,5 @@ -using System.Collections.Concurrent; +using System; +using System.Collections.Concurrent; namespace CodeProject.AI.SDK.Utils { diff --git a/src/SDK/NET/Utils/SystemInfo.cs b/src/SDK/NET/Utils/SystemInfo.cs index a0ca2cd..9f638ea 100644 --- a/src/SDK/NET/Utils/SystemInfo.cs +++ b/src/SDK/NET/Utils/SystemInfo.cs @@ -5,6 +5,11 @@ using System.Text.RegularExpressions; using Hardware.Info; +using System.Threading.Tasks; +using System.Collections.Generic; +using System; +using System.Linq; +using System.IO; #pragma warning disable CA1416 // Validate platform compatibility namespace CodeProject.AI.SDK.Utils diff --git a/src/SDK/NET/Utils/Text.cs b/src/SDK/NET/Utils/Text.cs index 3b27c7f..90cad76 100644 --- a/src/SDK/NET/Utils/Text.cs +++ b/src/SDK/NET/Utils/Text.cs @@ -1,4 +1,7 @@ -using System.Text.RegularExpressions; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; namespace CodeProject.AI.SDK.Utils { diff --git a/src/setup.bat b/src/setup.bat index 1f00ba9..650d486 100644 --- a/src/setup.bat +++ b/src/setup.bat @@ -689,6 +689,10 @@ goto:eof :SetupJSONParser + if /i "!executionEnvironment!" == "Development" ( + call "%utilsScript%" SetupDotNet !dotNetSDKVersion! SDK + ) + pushd !rootDirPath!\utils\ParseJSON if not exist ParseJSON.exe ( call "!utilsScript!" Write "Building ParseJSON..." From 9dc04564be4740d064b7eff710067eb6908079de Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 17 Nov 2024 14:48:02 -0500 Subject: [PATCH 06/71] env vars don't work in launch,json in Windows --- .vscode/launch.json | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 73f3e55..199f225 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,6 +14,9 @@ "preLaunchTask": "build-server", // "postDebugTask": "stop-all", "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", + "windows": { + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", + }, "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -83,6 +86,9 @@ "preLaunchTask": "build-all", // "postDebugTask": "stop-all", "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", + "windows": { + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", + }, "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -139,6 +145,9 @@ "type": "coreclr", "request": "launch", "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", + "windows": { + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", + }, "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -188,7 +197,10 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-server", - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.exe", + "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", + "windows": { + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.exe", + }, "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -231,6 +243,9 @@ "request": "launch", "preLaunchTask": "build-yolo-net", "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/${env:dotNetTarget}/ObjectDetectionYOLOv5Net", + "windows": { + "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/9.0/ObjectDetectionYOLOv5Net", + }, "linux": { "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/${env:dotNetTarget}/ObjectDetectionYOLOv5Net.dll", }, @@ -333,6 +348,9 @@ "request": "launch", "preLaunchTask": "build-parsejson", "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/${env:dotNetTarget}/ParseJSON", + "windows": { + "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/9.0/ParseJSON", + }, "linux": { "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/${env:dotNetTarget}/ParseJSON.dll", }, @@ -451,7 +469,7 @@ "request": "launch", "preLaunchTask": "build-ai-explorer", "windows": { - "program": "${workspaceFolder}/src/demos/clients/Net/AiExplorer/bin/Debug/${env:dotNetTarget}-windows/AiExplorer.exe", + "program": "${workspaceFolder}/src/demos/clients/Net/AiExplorer/bin/Debug/net9.0-windows/AiExplorer.exe", }, "args": [], "cwd": "${workspaceFolder}", @@ -472,7 +490,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-json-client", - "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/${env:dotNetTarget}/JsonAPI", + "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/net9.0/JsonAPI", "linux": { "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/${env:dotNetTarget}/JsonAPI.dll", }, @@ -598,6 +616,9 @@ "request": "launch", "preLaunchTask": "build-demo-net", "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/${env:dotNetTarget}/DotNetSimple", + "windows": { + "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/net9.0/DotNetSimple", + }, "linux": { "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/${env:dotNetTarget}/DotNetSimple.dll", }, @@ -625,6 +646,9 @@ "request": "launch", "preLaunchTask": "build-demo_module_dotnetlongprocess", "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/${env:dotNetTarget}/DotNetLongProcess", + "windows": { + "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/net9.0/DotNetLongProcess", + }, "linux": { "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/${env:dotNetTarget}/DotNetLongProcess.dll", }, From b8a6f8e0364b76e12424bbbc4a4a57fbd8b195cc Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 17 Nov 2024 15:01:15 -0500 Subject: [PATCH 07/71] Corrections to .NET handling in macOS --- .vscode/launch.json | 43 ++++++++----------------------------------- src/scripts/utils.sh | 4 ++++ 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 199f225..cb503e7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,10 +13,7 @@ "request": "launch", "preLaunchTask": "build-server", // "postDebugTask": "stop-all", - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", - "windows": { - "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", - }, + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -85,10 +82,7 @@ "request": "launch", "preLaunchTask": "build-all", // "postDebugTask": "stop-all", - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", - "windows": { - "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", - }, + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -144,10 +138,7 @@ "name": "Launch Server", "type": "coreclr", "request": "launch", - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", - "windows": { - "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", - }, + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -197,10 +188,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-server", - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server", - "windows": { - "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.exe", - }, + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.exe", "linux": { "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", }, @@ -242,10 +230,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-yolo-net", - "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/${env:dotNetTarget}/ObjectDetectionYOLOv5Net", - "windows": { - "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/9.0/ObjectDetectionYOLOv5Net", - }, + "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/9.0/ObjectDetectionYOLOv5Net", "linux": { "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/${env:dotNetTarget}/ObjectDetectionYOLOv5Net.dll", }, @@ -347,10 +332,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-parsejson", - "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/${env:dotNetTarget}/ParseJSON", - "windows": { - "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/9.0/ParseJSON", - }, + "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/9.0/ParseJSON", "linux": { "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/${env:dotNetTarget}/ParseJSON.dll", }, @@ -494,9 +476,6 @@ "linux": { "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/${env:dotNetTarget}/JsonAPI.dll", }, - "osx": { - "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/${env:dotNetTarget}/JsonAPI.dll", - }, "args": [], "cwd": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/", "stopAtEntry": false, @@ -615,10 +594,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-demo-net", - "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/${env:dotNetTarget}/DotNetSimple", - "windows": { - "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/net9.0/DotNetSimple", - }, + "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/net9.0/DotNetSimple", "linux": { "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/${env:dotNetTarget}/DotNetSimple.dll", }, @@ -645,10 +621,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-demo_module_dotnetlongprocess", - "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/${env:dotNetTarget}/DotNetLongProcess", - "windows": { - "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/net9.0/DotNetLongProcess", - }, + "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/net9.0/DotNetLongProcess", "linux": { "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/${env:dotNetTarget}/DotNetLongProcess.dll", }, diff --git a/src/scripts/utils.sh b/src/scripts/utils.sh index 50bd7d1..f08d151 100644 --- a/src/scripts/utils.sh +++ b/src/scripts/utils.sh @@ -823,6 +823,10 @@ function setupDotNet () { export DOTNET_ROOT=${dotnet_path} export PATH=${DOTNET_ROOT}${PATH:+:${PATH}} + if [ -e /usr/local/bin/dotnet ]; then + rm /usr/local/bin/dotnet + fi + if [ ! -e /usr/local/bin/dotnet ]; then ln -fs "${dotnet_path}dotnet" "/usr/local/bin/dotnet" fi From 00331db5946fcc38d92a7d3c34326146ebe5f081 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Mon, 18 Nov 2024 13:35:14 -0500 Subject: [PATCH 08/71] Corrections for Ubuntu launch, install and get OS name) --- .vscode/launch.json | 23 +++++++++++++---------- devops/install/dotnet-install.sh | 4 +++- src/SDK/NET/Utils/SystemInfo.cs | 27 ++++++++++++++++++++++----- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index cb503e7..59bb104 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,7 +15,10 @@ // "postDebugTask": "stop-all", "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", "linux": { - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", + // This is what you get from trusting ChatGPT + // "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.dll", + }, "args": [], "cwd": "${workspaceFolder}/src/server/", @@ -84,7 +87,7 @@ // "postDebugTask": "stop-all", "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", "linux": { - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.dll", }, "args": [], "cwd": "${workspaceFolder}/src/server/", @@ -140,7 +143,7 @@ "request": "launch", "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server", "linux": { - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.dll", }, "args": [], "cwd": "${workspaceFolder}/src/server/", @@ -190,12 +193,12 @@ "preLaunchTask": "build-server", "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.exe", "linux": { - "program": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/CodeProject.AI.Server.dll", + "program": "${workspaceFolder}/src/server/bin/Debug/net9.0/CodeProject.AI.Server.dll", }, "args": [ "--ModuleOptions:LaunchModules=false" ], - "cwd": "${workspaceFolder}/src/server/bin/Debug/${env:dotNetTarget}/", + "cwd": "${workspaceFolder}/src/server/bin/Debug/net9.0/", "stopAtEntry": false, /* "serverReadyAction": { @@ -232,7 +235,7 @@ "preLaunchTask": "build-yolo-net", "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/9.0/ObjectDetectionYOLOv5Net", "linux": { - "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/${env:dotNetTarget}/ObjectDetectionYOLOv5Net.dll", + "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/net9.0/ObjectDetectionYOLOv5Net.dll", }, // "args": [ "--selftest" ], // "cwd": "${workspaceFolder}", @@ -334,7 +337,7 @@ "preLaunchTask": "build-parsejson", "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/9.0/ParseJSON", "linux": { - "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/${env:dotNetTarget}/ParseJSON.dll", + "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/net9.0/ParseJSON.dll", }, "args": [ "$.Modules.ALPR.Platforms", "test.json" ], "cwd": "${workspaceFolder}/utils/ParseJSON/", @@ -474,7 +477,7 @@ "preLaunchTask": "build-json-client", "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/net9.0/JsonAPI", "linux": { - "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/${env:dotNetTarget}/JsonAPI.dll", + "program": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/bin/Debug/net9.0/JsonAPI.dll", }, "args": [], "cwd": "${workspaceFolder}/src/demos/clients/Net/JsonAPI/", @@ -596,7 +599,7 @@ "preLaunchTask": "build-demo-net", "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/net9.0/DotNetSimple", "linux": { - "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/${env:dotNetTarget}/DotNetSimple.dll", + "program": "${workspaceFolder}/src/demos/modules/DotNetSimple/bin/Debug/net9.0/DotNetSimple.dll", }, // "args": [ "--selftest" ], // "cwd": "${workspaceFolder}", @@ -623,7 +626,7 @@ "preLaunchTask": "build-demo_module_dotnetlongprocess", "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/net9.0/DotNetLongProcess", "linux": { - "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/${env:dotNetTarget}/DotNetLongProcess.dll", + "program": "${workspaceFolder}/src/demos/modules/DotNetLongProcess/bin/Debug/net9.0/DotNetLongProcess.dll", }, // "args": [ "--selftest" ], // "cwd": "${workspaceFolder}", diff --git a/devops/install/dotnet-install.sh b/devops/install/dotnet-install.sh index 5877bf0..a166c9c 100644 --- a/devops/install/dotnet-install.sh +++ b/devops/install/dotnet-install.sh @@ -979,7 +979,9 @@ copy_files_or_dirs_from_list() { if [ "$osname" = "linux-musl" ]; then printf -- "-u"; else - printf -- "-n"; + # cp: warning: behavior of -n is non-portable and may change in future; use --update=none instead + # printf -- "-n"; + printf -- "--update=none"; fi fi) diff --git a/src/SDK/NET/Utils/SystemInfo.cs b/src/SDK/NET/Utils/SystemInfo.cs index 9f638ea..82ea822 100644 --- a/src/SDK/NET/Utils/SystemInfo.cs +++ b/src/SDK/NET/Utils/SystemInfo.cs @@ -1696,16 +1696,33 @@ private async static Task CheckOSVersionNameAsync() if (IsLinux) { - // Output is in the form: var results = await GetProcessInfoAsync("/bin/bash", "-c \". /etc/os-release;echo $NAME\"", null) - .ConfigureAwait(false); + .ConfigureAwait(false); if (results is not null) _osName = results["output"]?.Trim(); // eg "ubuntu", "debian" - results = await GetProcessInfoAsync("/bin/bash", "-c \". /etc/os-release;echo $VERSION_ID\"", null) - .ConfigureAwait(false); + // VERSION is in form "24.10 (Oracular Oriole)" + var pattern = @"(?\d+\.\d+) \((?[a-z\s]+)\)"; + var options = RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture; + results = await GetProcessInfoAsync("/bin/bash", "-c \". /etc/os-release;echo $VERSION\"", + pattern, options).ConfigureAwait(false); if (results is not null) - _osVersion = results["output"]?.Trim(); // eg. "22.04" for Ubuntu 22.04, "12" for Debian 12 + { + _osVersion = results["version"]?.Trim(); // eg. "22.04" for Ubuntu 22.04, "12" for Debian 12 + string? name = results["name"]?.Trim(); // eg. "Oracular Oriole" for Ubuntu 24.10 + if (!string.IsNullOrWhiteSpace(name)) + _osName += " (" + name + ")"; + } + + // Just in case above failed + if (string.IsNullOrWhiteSpace(_osVersion)) + { + // VERSION_ID is in form "24.10" + results = await GetProcessInfoAsync("/bin/bash", "-c \". /etc/os-release;echo $VERSION_ID\"", null) + .ConfigureAwait(false); + if (results is not null) + _osVersion = results["output"]?.Trim(); // eg. "22.04" for Ubuntu 22.04, "12" for Debian 12 + } } else if (IsWindows) { From 891bbdc83b3ef62360b807434c7e6c220df6dcbb Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Mon, 18 Nov 2024 22:08:57 -0500 Subject: [PATCH 09/71] Updates to Windows setup script for winget install --- src/scripts/utils.bat | 60 ++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/scripts/utils.bat b/src/scripts/utils.bat index affef9c..0bcdd71 100644 --- a/src/scripts/utils.bat +++ b/src/scripts/utils.bat @@ -644,26 +644,40 @@ shift & goto :%~1 if errorlevel 1 ( call :Write "Installing WinGet..." %color_info% - set "archType=x64" - if /i "!architecture!" == "arm64" set "archType=arm64" - - REM https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget-on-windows-sandbox - powershell -command ^ - $progressPreference = 'silentlyContinue'; ^ - Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; ^ - Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.!archType!.14.00.Desktop.appx -OutFile Microsoft.VCLibs.!archType!.14.00.Desktop.appx; ^ - Invoke-WebRequest -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.!archType!.appx -OutFile Microsoft.UI.Xaml.2.8.!archType!.appx; ^ - Add-AppxPackage Microsoft.VCLibs.!archType!.14.00.Desktop.appx; ^ - Add-AppxPackage Microsoft.UI.Xaml.2.8.!archType!.appx; ^ - Add-AppxPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; - - call :WriteLine "Done." %color_info% - - call :Write "Cleaning up..." %color_info% - del Microsoft.VCLibs.!archType!.14.00.Desktop.appx - del Microsoft.UI.Xaml.2.8.!archType!.appx - del Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle - call :WriteLine "Done." %color_info% + set DoWingetInstall=true + if "!DoWingetInstall!" == "true" ( + set "archType=x64" + if /i "!architecture!" == "arm64" set "archType=arm64" + + REM https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget-on-windows-sandbox + if /i "%verbosity%" == "quiet" ( + set progressType=silentlyContinue + ) else ( + set progressType=Continue + ) + powershell -command $progressPreference = '!progressType!'; ^ + Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; ^ + Add-AppxPackage Microsoft.VCLibs.!archType!.14.00.Desktop.appx; + + powershell -command $progressPreference = '!progressType!'; ^ + Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.!archType!.14.00.Desktop.appx -OutFile Microsoft.VCLibs.!archType!.14.00.Desktop.appx; ^ + Add-AppxPackage Microsoft.UI.Xaml.2.8.!archType!.appx; + + powershell -command $progressPreference = '!progressType!'; ^ + Invoke-WebRequest -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.!archType!.appx -OutFile Microsoft.UI.Xaml.2.8.!archType!.appx; ^ + Add-AppxPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; + + call :WriteLine "Done." %color_info% + + call :Write "Cleaning up..." %color_info% + del Microsoft.VCLibs.140.00.UWPDesktop.appx + del Microsoft.VCLibs.!archType!.14.00.Desktop.appx + del Microsoft.UI.Xaml.2.8.!archType!.appx + del Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle + call :WriteLine "Done." %color_info% + ) else ( + powershell -command "Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe" + ) ) if /i "!requestedType!" == "SDK" ( @@ -671,6 +685,12 @@ shift & goto :%~1 ) else ( winget install Microsoft.DotNet.AspNetCore.!requestedNetMajorVersion! ) + + call :WriteLine "" + call :WriteLine "** You may need to restart this terminal (or VS Code if you're " %color_error% + call :WriteLine " in VS Code) and rerun setup.bat for the rest of this setup " %color_error% + call :WriteLine " script to work." %color_error% + call :WriteLine "" ) ) ) From 9658c8df6bd46bffd5a17c89e4d2e1448d1e5bfb Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 08:53:53 -0500 Subject: [PATCH 10/71] Spelling --- .vscode/settings.json | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 0d894b3..736780c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,22 +10,30 @@ "appsettings", "argmax", "Armv", + "arounds", + "ASKPASS", "ASPNETCORE", "astype", "AUTOINSTALL", "aync", "BASEPATH", + "bitness", "callbacktask", "Cartooniser", "categorised", + "chcp", "codeproject", + "colour", "colourised", "colours", "Consolas", + "consoleloggerparameters", "CPAI", "createallsubdirs", + "Crockford", "Cuda", "CUDNN", + "Darkmode", "Denoising", "denormalize", "deserialise", @@ -38,15 +46,22 @@ "dtype", "edgetpu", "endtimer", + "ensurepip", + "errorlevel", "Everytime", "Expando", "facerec", "fbytes", "fiftyone", "fileglob", + "filesize", + "findstr", "formdata", "fouo", + "generalise", "getframe", + "HKCU", + "HKLM", "hostbuilder", "hostnames", "hyps", @@ -69,6 +84,8 @@ "labelledby", "Lanczos", "licence", + "LOCALAPPDATA", + "logicaldisk", "logvals", "maxs", "membuffer", @@ -76,7 +93,9 @@ "millidegree", "modulesettings", "nbsp", + "norestart", "normalises", + "noscroll", "nowait", "nvcc", "objectdetection", @@ -87,36 +106,55 @@ "orangepi", "otsu", "paddleocr", + "parsejson", "peasy", "platenumber", "pluralise", + "popd", "postinst", "postprocess", "prerm", + "pstree", + "pushd", "pycoral", + "pypi", "pyproj", + "pythonhosted", "pywrap", "Quadro", "QUEUENAME", + "Radxa", + "radxarock", "raspberrypi", "rebalancing", "RECOG", "recognised", "recursesubdirs", + "redist", + "redistributables", + "regpath", + "rembg", "reqid", "reqtype", "reso", "RKNN", "rocm", + "rocminfo", "runhidden", "runtimes", "safetensors", "selftest", "serversettings", + "setuptools", + "setx", "shellexec", + "sideloaded", "skia", + "Sonoma", + "standardise", "starttimer", "statuseseses", + "subshell", "Systemmd", "Tegra", "tegrastats", @@ -125,16 +163,20 @@ "tflite", "topbanner", "torchvision", + "totalspacebytes", "tpus", "ufeff", "unclip", "uninstallexe", "upsampling", + "usebackq", "userid", "utilise", "venv", "vggish", + "waitretry", "wavfile", + "winget", "womp", "wslconfig", "wwwroot", From 59559b14ee5f130b80ccc60957dad817df45dc27 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 09:35:38 -0500 Subject: [PATCH 11/71] Corrections to winget vc redist check and setup / spelling --- src/scripts/utils.bat | 210 +++++++++++++++++++++++++++--------------- src/setup.bat | 44 ++++----- src/setup.sh | 16 ++-- 3 files changed, 167 insertions(+), 103 deletions(-) diff --git a/src/scripts/utils.bat b/src/scripts/utils.bat index 0bcdd71..7a59696 100644 --- a/src/scripts/utils.bat +++ b/src/scripts/utils.bat @@ -127,13 +127,13 @@ shift & goto :%~1 :: Sets the currentColor global for the given foreground/background colors -:: currentColor must be output to the terminal before outputing text in +:: currentColor must be output to the terminal before outputting text in :: order to generate a colored output. :: :: string foreground color name. Optional if no background provided. :: Defaults to "White" :: string background color name. Optional. Defaults to Black. -:: string intense. Optional. If "true" then the insensity is turned up +:: string intense. Optional. If "true" then the intensity is turned up :setColor REM If you want to get a little fancy then you can also try @@ -343,7 +343,7 @@ shift & goto :%~1 if errorlevel 16 ( call :WriteLine "Failed" !color_error! else if errorlevel 8 ( - call :WriteLine "Some files inot copied" !color_warn! + call :WriteLine "Some files not copied" !color_warn! ) else ( call :WriteLine "done" !color_success! ) @@ -369,7 +369,7 @@ shift & goto :%~1 SetLocal EnableDelayedExpansion REM Param 1: The URL where the download can be found. - REM eg "https://codeproject-ai.s3.ca-central-1.amazonaws.com/server/models/" + REM eg "https://mycdn.com/server/models/" set assetStorageUrl=%1 set assetStorageUrl=!assetStorageUrl:"=! @@ -382,7 +382,8 @@ shift & goto :%~1 set downloadToDir=!downloadToDir:"=! REM Param 4: The name of the folder within the downloads directory where - REM the contents should be extracted. eg. assets + REM the contents should be extracted. eg. assets. + REM NOTE: If this param is empty then no extraction will happen set dirToExtract=%4 set dirToExtract=!dirToExtract:"=! @@ -393,22 +394,25 @@ shift & goto :%~1 if "!message!" == "" set message=Downloading !fileToGet!... if /i "%verbosity%" neq "quiet" ( - call :WriteLine "Downloading !fileToGet! from !assetStorageUrl! to !downloadToDir!\!dirToExtract!" "!color_info!" + call :WriteLine "Downloading !fileToGet! from !assetStorageUrl! to !downloadToDir!" "!color_info!" ) call :Write "!message!" "!color_primary!" - set extension=!fileToGet:~-3! - if /i "!extension!" NEQ ".gz" ( - set extension=!fileToGet:~-4! - if /i "!extension!" NEQ ".zip" ( - call :WriteLine "Unknown and unsupported file type for file !fileToGet!" "!color_error!" - exit /b REM no point in carrying on + REM If we're to extract this file then ensure it's an extractable file + if "!dirToExtract!" neq "" ( + set extension=!fileToGet:~-3! + if /i "!extension!" NEQ ".gz" ( + set extension=!fileToGet:~-4! + if /i "!extension!" NEQ ".zip" ( + call :WriteLine "Unknown and unsupported file type for file !fileToGet!" "!color_error!" + exit /b REM no point in carrying on + ) ) ) if /i "%verbosity%" neq "quiet" ( - call :WriteLine "Checking '!downloadToDir!\!fileToGet!'" "!color_info!" + call :WriteLine "Checking..." "!color_info!" ) if exist "!downloadToDir!\!fileToGet!" ( @@ -425,7 +429,7 @@ shift & goto :%~1 REM Be careful with the quotes so we can handle paths with spaces powershell -command "Start-BitsTransfer -Source '!assetStorageUrl!!fileToGet!' -Description !fileToGet! -Destination '!downloadToDir!\!fileToGet!'" - REM If these fail, it could be becuase of hanging transfers + REM If these fail, it could be because of hanging transfers if errorlevel 1 ( powershell -Command "Get-BitsTransfer | Remove-BitsTransfer" powershell -command "Start-BitsTransfer -Source '!assetStorageUrl!!fileToGet!' -Description !fileToGet! -Destination '!downloadToDir!\!fileToGet!'" @@ -453,18 +457,19 @@ shift & goto :%~1 call :WriteLine "Heading to !downloadToDir!" "!color_info!" ) - pushd "!downloadToDir!" - if not exist "!downloadToDir!\!dirToExtract!" mkdir "!downloadToDir!\!dirToExtract!" + REM Extract the file if we've been given an extraction folder name + if "!dirToExtract!" neq "" ( + pushd "!downloadToDir!" + if not exist "!downloadToDir!\!dirToExtract!" mkdir "!downloadToDir!\!dirToExtract!" - call :ExtractToDirectory "!fileToGet!" "!dirToExtract!" - - if errorlevel 1 ( + call :ExtractToDirectory "!fileToGet!" "!dirToExtract!" + if errorlevel 1 ( + popd + exit /b 1 + ) popd - exit /b 1 ) - popd - call :WriteLine "done." "!color_success!" exit /b @@ -518,6 +523,101 @@ shift & goto :%~1 exit /b +:EnsureVCRedistInstalled + SetLocal EnableDelayedExpansion + + set url_x64=https://aka.ms/vs/17/release/ + set file_x64=vc_redist.x64.exe + + call :Write "Checking for VC++ Redist..." %color_info% + reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\17.0\VC\Runtimes\x64" >nul 2>&1 + if %errorlevel% equ 0 ( + call :WriteLine "v17 Present." %color_success% + exit /b + ) + reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\16.0\VC\Runtimes\x64" >nul 2>&1 + if %errorlevel% equ 0 ( + call :WriteLine "v16 Present." %color_success% + exit /b + ) + reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\15.0\VC\Runtimes\x64" >nul 2>&1 + if %errorlevel% equ 0 ( + call :WriteLine "v15 Present." %color_success% + exit /b + ) + reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" >nul 2>&1 + if %errorlevel% equ 0 ( + call :WriteLine "v14 Present." %color_success% + exit /b + ) + + REM params: "https://cdn.com/assets" "file.zip" "\downloads\myModuleDir" "extract_dir" "Downloading files..." + REM Empty "extract_dir" means file will not be unzipped (since it's not a zip) + call :DownloadAndExtract "!url_x64!" "!file_x64!" "!downloadDirPath!\!platform!" "" "Downloading VC++ Redist files..." + + if exist "!downloadDirPath!\!platform!\!file_x64!" ( + call :Write "Installing VC++ Redist..." %color_info% + if /i "%verbosity%" == "quiet" ( + "!downloadDirPath!\!platform!\!file_x64!" /quiet /norestart + ) else ( + "!downloadDirPath!\!platform!\!file_x64!" /norestart + ) + call :WriteLine "Done." %color_info% + + REM -- Cleanup: Delete the installer files after installation + REM del /f /q "!downloadDirPath!\!platform!\!file_x64!" + ) else ( + call :WriteLine "Unable to download VC redist installer" !color_error! + ) + + exit /b + + +:EnsureWinGetInstalled + SetLocal EnableDelayedExpansion + + where winget >NUL 2>NUL + if errorlevel 1 ( + call :Write "Installing WinGet..." %color_info% + + set DoWingetInstall=true + + if "!DoWingetInstall!" == "true" ( + set "archType=x64" + if /i "!architecture!" == "arm64" set "archType=arm64" + + REM https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget-on-windows-sandbox + if /i "%verbosity%" == "quiet" ( + set progressType=silentlyContinue + ) else ( + set progressType=Continue + ) + powershell -command $progressPreference = '!progressType!'; ^ + Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; ^ + Add-AppxPackage Microsoft.VCLibs.!archType!.14.00.Desktop.appx; + + powershell -command $progressPreference = '!progressType!'; ^ + Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.!archType!.14.00.Desktop.appx -OutFile Microsoft.VCLibs.!archType!.14.00.Desktop.appx; ^ + Add-AppxPackage Microsoft.UI.Xaml.2.8.!archType!.appx; + + powershell -command $progressPreference = '!progressType!'; ^ + Invoke-WebRequest -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.!archType!.appx -OutFile Microsoft.UI.Xaml.2.8.!archType!.appx; ^ + Add-AppxPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; + + call :WriteLine "Done." %color_info% + + call :Write "Cleaning up..." %color_info% + del Microsoft.VCLibs.!archType!.14.00.Desktop.appx + del Microsoft.UI.Xaml.2.8.!archType!.appx + del Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle + call :WriteLine "Done." %color_info% + ) else ( + powershell -command "Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe" + ) + ) + + exit /b + :SetupDotNet SetLocal EnableDelayedExpansion @@ -640,45 +740,7 @@ shift & goto :%~1 ) ) else ( - where winget >NUL 2>NUL - if errorlevel 1 ( - call :Write "Installing WinGet..." %color_info% - - set DoWingetInstall=true - if "!DoWingetInstall!" == "true" ( - set "archType=x64" - if /i "!architecture!" == "arm64" set "archType=arm64" - - REM https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget-on-windows-sandbox - if /i "%verbosity%" == "quiet" ( - set progressType=silentlyContinue - ) else ( - set progressType=Continue - ) - powershell -command $progressPreference = '!progressType!'; ^ - Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; ^ - Add-AppxPackage Microsoft.VCLibs.!archType!.14.00.Desktop.appx; - - powershell -command $progressPreference = '!progressType!'; ^ - Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.!archType!.14.00.Desktop.appx -OutFile Microsoft.VCLibs.!archType!.14.00.Desktop.appx; ^ - Add-AppxPackage Microsoft.UI.Xaml.2.8.!archType!.appx; - - powershell -command $progressPreference = '!progressType!'; ^ - Invoke-WebRequest -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.!archType!.appx -OutFile Microsoft.UI.Xaml.2.8.!archType!.appx; ^ - Add-AppxPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle; - - call :WriteLine "Done." %color_info% - - call :Write "Cleaning up..." %color_info% - del Microsoft.VCLibs.140.00.UWPDesktop.appx - del Microsoft.VCLibs.!archType!.14.00.Desktop.appx - del Microsoft.UI.Xaml.2.8.!archType!.appx - del Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle - call :WriteLine "Done." %color_info% - ) else ( - powershell -command "Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe" - ) - ) + call :EnsureWinGetInstalled if /i "!requestedType!" == "SDK" ( winget install Microsoft.DotNet.SDK.!requestedNetMajorVersion! @@ -720,7 +782,7 @@ shift & goto :%~1 REM The path to the folder containing the base python installation set pythonRuntimeInstallPath=!runtimesDirPath!\bin\!os!\!pythonName! - REM For debugging, or correcting, we can force redownloads. Be careful though. + REM For debugging, or correcting, we can force re-downloads. Be careful though. if /i "%forceOverwrite%" == "true" ( REM Force Re-download @@ -731,7 +793,7 @@ shift & goto :%~1 REM Force overwrite of python installation call :WriteLine "Cleaning Python directory to force re-install of Python" "!color_info!" - call :WriteLine "This will mean any previous PIP installs wwill be lost." "!color_warn!" + call :WriteLine "This will mean any previous PIP installs will be lost." "!color_warn!" if exist "!pythonRuntimeInstallPath!" rmdir /s %rmdirFlags% "!pythonRuntimeInstallPath!" ) @@ -802,7 +864,7 @@ shift & goto :%~1 set searchDir=%~1 if /i "%verbosity%" neq "quiet" ( - call :WriteLine "Searching for a suitable requirements.txts file in !searchDir!" "!color_info!" + call :WriteLine "Searching for a suitable requirements.txt file in !searchDir!" "!color_info!" ) REM This is getting complicated. The order of priority for the requirements file is: @@ -1296,7 +1358,7 @@ shift & goto :%~1 :GetCudaVersion - rem setlocal enabledelayedexpansion + REM SetLocal EnableDelayedExpansion :: Use nvcc to find the CUDA version where nvcc >nul 2>&1 @@ -1381,7 +1443,7 @@ shift & goto :%~1 ) REM Module settings files are loaded in this order. Each file will overwrite (but not delete) - REM settings of the previous file. Becuase of this, we're going to search the files in REVERSE + REM settings of the previous file. Because of this, we're going to search the files in REVERSE REM order until we find the first value based on the most specific to least specific file. REM modulesettings.json REM modulesettings.development.json @@ -1448,9 +1510,9 @@ shift & goto :%~1 REM Gets a value from the modulesettings.json file (any JSON file, really) based -REM purely on the name of the propery. THIS METHOD DOES NOT TAKE INTO ACCOUNT THE +REM purely on the name of the property. THIS METHOD DOES NOT TAKE INTO ACCOUNT THE REM DEPTH OF A PROPERTY. If the property is at the root level or 10 levels down, -REM it's all the same. The extraction is done purely by grep/sed, so is very niaive. +REM it's all the same. The extraction is done purely by grep/sed, so is very naive. :GetValueFromModuleSettings jsonFilePath moduleId property returnValue set "moduleSettingValue=" SetLocal EnableDelayedExpansion @@ -1579,7 +1641,7 @@ REM it's all the same. The extraction is done purely by grep/sed, so is very nia exit /b -REM Gets the moduleID from a modulesettings.json file. See above function for commentss +REM Gets the moduleID from a modulesettings.json file. See above function for comments :GetModuleIdFromModuleSettingsFile jsonFilePath returnValue set "moduleSettingValue=" SetLocal EnableDelayedExpansion @@ -1765,7 +1827,7 @@ REM Gets the moduleID from a modulesettings.json file. See above function for c REM Strips single line comments from a file and stores the cleaned contents in a new file :StripJSONComments - setlocal enabledelayedexpansion + SetLocal EnableDelayedExpansion set inputFilePath=%~1 set cleanFilePath=%~2 @@ -1904,7 +1966,7 @@ REM Call this, then test: if "%online%" == "true" echo 'online' REM echo VERSION IS '%%a' set version=%%a ) - endlocal & set VCredistVersion=%version:v=% + EndLocal & set VCredistVersion=%version:v=% exit /b @@ -1913,7 +1975,7 @@ REM Get Windows Version :: Get the OS Name and version information :getWindowsOSName OSName - REM setlocal enabledelayedexpansion + REM SetLocal EnableDelayedExpansion REM Get the OS version information for /f "tokens=4-6 delims=. " %%i in ('ver') do ( @@ -1965,7 +2027,7 @@ REM Thanks to https://stackoverflow.com/a/15809139/1128209 :: Nodes are normally strictly numeric, without a 0 prefix. A letter suffix :: is treated as a separate node :: - setlocal enableDelayedExpansion + SetLocal EnableDelayedExpansion set "v1=%~1" set "v2=%~2" @@ -2021,7 +2083,7 @@ REM Thanks to https://stackoverflow.com/a/15809139/1128209 :timeSince startTime duration - setlocal enableDelayedExpansion + SetLocal EnableDelayedExpansion set "startTime=%~1" diff --git a/src/setup.bat b/src/setup.bat index 650d486..bfc1a86 100644 --- a/src/setup.bat +++ b/src/setup.bat @@ -8,7 +8,7 @@ :: :: 1. From within the \src (or the root directory of the installation) in :: order to setup the full system, including serer, SDKs, demos and modules. -:: This method is typically used for setting up the Developmnent environment. +:: This method is typically used for setting up the Development environment. :: :: 2. From within a module's directory (or demo or server folder) to setup just :: that module, demo or the server @@ -44,7 +44,7 @@ @echo off REM cls -setlocal enabledelayedexpansion +SetLocal EnableDelayedExpansion REM Set CodePage UTF-8 for our emojis chcp 65001 >NUL @@ -100,9 +100,9 @@ set skipPipInstall=false :: Further: one-step means if you re-run the installer, the entire req file is :: always re-processed, whereas if oneStep is false, each package is checked for :: existence before running pip, speeding re-installs dramatically. -:: Finally: one-step is an awful user experience. Everyghing hangs for minutes. +:: Finally: one-step is an awful user experience. Everything hangs for minutes. :: Setting it to false provides far better (but maybe slower) feedback mechanism. -:: FOR PIP INCOMPATIBILITY ISSUES: Set this to true and verbisity to loud to get +:: FOR PIP INCOMPATIBILITY ISSUES: Set this to true and verbosity to loud to get :: excellent debug feedback from pip. set oneStepPIP=false @@ -292,7 +292,7 @@ set architecture=%PROCESSOR_ARCHITECTURE% :: A NOTE ON PLATFORM. :: We use the full "x86_64" for architecture, but follow the common convention -:: of abbreviating this to "x64" when used in conjuntion with OS. So windows-x64 +:: of abbreviating this to "x64" when used in conjunction with OS. So windows-x64 :: rather than windows-x86_64. To simplify further, if the platform value doesn't :: have a suffix then it's assumed to be -x64. This may change in the future. if /i "!architecture!" == "arm64" ( @@ -325,18 +325,18 @@ set mainSetupStarttime=%time% REM Commented: WMIC not always available :: REM Report disk space available :: for /f "tokens=1,2 delims== " %%a in ('wmic logicaldisk where "DeviceID='%cd:~0,2%'" get FreeSpace^,Size^,VolumeName /format:list') do ( -:: if "%%a"=="FreeSpace" set freespacebytes=%%b +:: if "%%a"=="FreeSpace" set freeSpaceBytes=%%b :: if "%%a"=="Size" set totalspacebytes=%%b -:: if "%%a"=="VolumeName" set volumename=%%b +:: if "%%a"=="VolumeName" set volumeName=%%b :: ) :: REM Anything over 2Gb kills this -:: REM set /a freeSpaceGb=!freespacebytes! / 1073741824 -:: REM set /a freeSpaceGbfraction=!freespacebytes! %% 1073741824 * 10 / 1073741824 -:: set /a freeSpaceGb=!freespacebytes:~0,-4! / 1048576 -:: set /a freeSpaceGbfraction=!freespacebytes:~0,-4! %% 1048576 * 10 / 1048576 +:: REM set /a freeSpaceGb=!freeSpaceBytes! / 1073741824 +:: REM set /a freeSpaceGbFraction=!freeSpaceBytes! %% 1073741824 * 10 / 1073741824 +:: set /a freeSpaceGb=!freeSpaceBytes:~0,-4! / 1048576 +:: set /a freeSpaceGbFraction=!freeSpaceBytes:~0,-4! %% 1048576 * 10 / 1048576 :: set /a totalSpaceGb=!totalspacebytes:~0,-4! / 1048576 -for /f "tokens=6*" %%A in ('vol') do set volumename=%%A +for /f "tokens=6*" %%A in ('vol') do set volumeName=%%A set driveRoot=%CD:~0,3% for /f "usebackq" %%A in (`powershell -NoProfile -Command "(Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Root -eq '!driveRoot!' }).Free + (Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Root -eq '!driveRoot!' }).Used"`) do ( set totalspacebytes=%%A @@ -345,16 +345,16 @@ REM chop off last 3 digits (divide by 1000) then divide by 1024^2 to get Gb. Thi REM is to avoid numerical overflow but results in bad maths. set /a totalSpaceGb=!totalspacebytes:~0,-3! / 1048576 -for /f "tokens=3" %%A in ('dir !driveRoot!') do set freespacebytes=%%A -set freespacebytes=!freespacebytes:,=! -set /a freeSpaceGb=!freespacebytes:~0,-3! / 1048576 -set /a freeSpaceGbfraction=!freespacebytes:~0,-3! %% 1048576 * 10 / 1048576 +for /f "tokens=3" %%A in ('dir !driveRoot!') do set freeSpaceBytes=%%A +set freeSpaceBytes=!freeSpaceBytes:,=! +set /a freeSpaceGb=!freeSpaceBytes:~0,-3! / 1048576 +set /a freeSpaceGbFraction=!freeSpaceBytes:~0,-3! %% 1048576 * 10 / 1048576 -if "!volumename!" == "" set volumename=(No label) +if "!volumeName!" == "" set volumeName=(No label) -REM call "!utilsScript!" WriteLine "!freespacebytes! of !totalspacebytes! available on !VolumeName! (!os_name! !architecture! - !platform!)" !color_mute! -call "!utilsScript!" WriteLine "!freeSpaceGb!.!freeSpaceGbfraction!Gb of !totalSpaceGb!Gb available on !VolumeName! (!os_name! !architecture! - !platform!)" !color_mute! +REM call "!utilsScript!" WriteLine "!freeSpaceBytes! of !totalspacebytes! available on !VolumeName! (!os_name! !architecture! - !platform!)" !color_mute! +call "!utilsScript!" WriteLine "!freeSpaceGb!.!freeSpaceGbFraction!Gb of !totalSpaceGb!Gb available on !VolumeName! (!os_name! !architecture! - !platform!)" !color_mute! :: Ensure directories are created and download required assets. @@ -363,6 +363,8 @@ call "!utilsScript!" WriteLine call "!utilsScript!" WriteLine "General CodeProject.AI setup" "White" "Blue" !lineWidth! call "!utilsScript!" WriteLine +call "!utilsScript!" EnsureVCRedistInstalled + :: Before we start, ensure we can read the JSON config files call :SetupJSONParser if errorlevel 1 goto:eof @@ -742,10 +744,10 @@ goto:eof ) set virtualEnvDirPath=!pythonDirPath!\venv - REM The path to the python intepreter for this venv + REM The path to the python interpreter for this venv set venvPythonCmdPath=!virtualEnvDirPath!\Scripts\python.exe - REM The location where python packages will be installed for this venvvenv + REM The location where python packages will be installed for this venv set packagesDirPath=%virtualEnvDirPath%\Lib\site-packages exit /b diff --git a/src/setup.sh b/src/setup.sh index 62a4dd1..9b0f032 100644 --- a/src/setup.sh +++ b/src/setup.sh @@ -10,7 +10,7 @@ # # 1. From within the /src (or /app, or root directory of the installation) in # order to setup the full system, including serer, SDKs, demos and modules. -# This method is typically used for setting up the Developmnent environment. +# This method is typically used for setting up the Development environment. # # 2. From within a module's directory (or demo or server folder) to setup just # that module, demo or the server @@ -260,7 +260,7 @@ fi # Standard output may be used as a return value in the functions. Expose stream # 3 so we can do 'echo "Hello, World!" >&3' within these functions for debugging -# wihtout interfering with return values. +# without interfering with return values. exec 3>&1 # Execution environment, setup mode and Paths :::::::::::::::::::::::::::::::: @@ -363,7 +363,7 @@ function setupPythonPaths () { fi virtualEnvDirPath="${pythonDirPath}/venv" - # The path to the python intepreter for this venv + # The path to the python interpreter for this venv venvPythonCmdPath="${virtualEnvDirPath}/bin/python${pythonVersion}" # The location where python packages will be installed for this venv @@ -740,7 +740,7 @@ fi # oneStep means we install python packages using pip -r requirements.txt rather # than installing module by module. one-step allows the dependency manager to # make some better calls, but also means the entire install can fail on a single -# bad (and potentially unnneeded) module. Turning one-step off means you get a +# bad (and potentially unneeded) module. Turning one-step off means you get a # more granular set of error messages should things go wrong, and a nicer UX. if [ "$inDocker" = true ]; then oneStepPIP=false @@ -964,8 +964,8 @@ elif [ "$os" = "linux" ]; then write ") " $color_primary fi if [ -x "$(command -v rocminfo)" ]; then - amdinfo=$(rocminfo | grep -i -E 'AMD ROCm System Management Interface') > /dev/null 2>&1 - if [[ ${amdinfo} == *'AMD ROCm System Management Interface'* ]]; then hasROCm=true; fi + amdInfo=$(rocminfo | grep -i -E 'AMD ROCm System Management Interface') > /dev/null 2>&1 + if [[ ${amdInfo} == *'AMD ROCm System Management Interface'* ]]; then hasROCm=true; fi fi fi if [ "$hasROCm" = true ]; then writeLine "Yes" $color_success; else writeLine "No" $color_warn; fi @@ -1045,8 +1045,8 @@ if [ "$setupMode" = 'SetupEverything' ]; then done if [ "$installExternalModules" == "true" ]; then - # Walk through the modules directoorym for modules that live in the external - # folder. For isntance modules that are in extenal Git repos / projects + # Walk through the modules directory for modules that live in the external + # folder. For instance modules that are in external Git repos / projects writeLine writeLine "Processing External CodeProject.AI Server Modules" "White" "DarkGreen" $lineWidth writeLine From 12fa5925ae03dea0d5d58b1beb3269cf8df09f68 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 11:15:38 -0500 Subject: [PATCH 12/71] Updated cuDNN install script for Windows --- devops/install/install_CUDnn.bat | 237 +++++++++++++++++++------------ 1 file changed, 148 insertions(+), 89 deletions(-) diff --git a/devops/install/install_CUDnn.bat b/devops/install/install_CUDnn.bat index b2d64e3..bb54bb0 100644 --- a/devops/install/install_CUDnn.bat +++ b/devops/install/install_CUDnn.bat @@ -39,12 +39,18 @@ REM Settings set dryRun=false +:: The location of large packages that need to be downloaded (eg an AWS S3 bucket +:: name). This will be overwritten using the value from appsettings.json +REM set assetStorageUrl=https://codeproject-ai.s3.ca-central-1.amazonaws.com/server/assets/ +set assetStorageUrl=https://codeproject-ai-bunny.b-cdn.net/server/assets/ +REM set assetStorageUrl=https://www.codeproject.com/ai/download/server/assets/ + set cuDNNLocation=https://developer.nvidia.com/rdp/cudnn-download -set cuDNNArchiveDownloadUrl=https://codeproject-ai.s3.ca-central-1.amazonaws.com/server/assets/libraries/ +set cuDNNArchiveDownloadUrl=!assetStorageUrl!libraries/ -set CUDA10_cuDNN_version=8.4.1.50 -set CUDA11_cuDNN_version=8.9.4.25 -set CUDA12_cuDNN_version=8.9.7.29 +set CUDA10_cuDNN_version=8.7.0.84 +set CUDA11_cuDNN_version=8.9.7.29 +set CUDA12_cuDNN_version=9.5.1 set zLibLocation=http://www.winimage.com/zLibDll/ set zLibArchiveName=zlib123dllx64 @@ -84,9 +90,23 @@ if "!cuda_major_version!" == "10" ( set cuda_version=12 set cuDNN_version=!CUDA12_cuDNN_version! ) -set cuDNNArchiveFilename=cudnn-windows-x86_64-!cuDNN_version!_cuda!cuda_version!-archive.zip -set cuDNNPattern=cudnn-windows-x86_64-*_cuda!cuda_version!-archive.zip -set "cuDNNRegex=cudnn-windows-x86_64-([0-9]*).([0-9]*).([0-9]*).([0-9]*)_cuda!cuda_version!-archive.zip" + +if "!cuda_major_version!" == "12" ( + set cuDNNInstallerFilename=cudnn_!cuDNN_version!_windows.exe + set cuDNNPattern=cudnn_*_windows.exe + set "cuDNNRegex=cudnn-([0-9]*).([0-9]*).([0-9]*)_windows.exe" +) else ( + set cuDNNArchiveFilename=cudnn-windows-x86_64-!cuDNN_version!_cuda!cuda_version!-archive.zip + set cuDNNPattern=cudnn-windows-x86_64-*_cuda!cuda_version!-archive.zip + set "cuDNNRegex=cudnn-windows-x86_64-([0-9]*).([0-9]*).([0-9]*).([0-9]*)_cuda!cuda_version!-archive.zip" +) + +REM Check + +if exist "C:\Program Files\NVIDIA\CUDNN\v*.*" ( + echo cuDNN is installed. + goto:eof +) REM Install @@ -105,125 +125,164 @@ set zLibInstalled=false :: but before we start lets ensure we attempt to have at least one version present. echo Searching for existing cuDNN installers !cuDNNPattern! -IF not exist "!cuDNNPattern!" ( +If not exist "!cuDNNPattern!" ( echo No cuDNN archive found. Downloading !cuDNNArchiveFilename!... - powershell -command "Start-BitsTransfer -Source '!cuDNNArchiveDownloadUrl!!cuDNNArchiveFilename!' -Destination '!cuDNNArchiveFilename!'" + if "!cuda_major_version!" == "12" ( + powershell -command "Start-BitsTransfer -Source '!cuDNNArchiveDownloadUrl!!cuDNNInstallerFilename!' -Destination '!cuDNNInstallerFilename!'" + ) else ( + powershell -command "Start-BitsTransfer -Source '!cuDNNArchiveDownloadUrl!!cuDNNArchiveFilename!' -Destination '!cuDNNArchiveFilename!'" + ) ) -IF exist "!cuDNNPattern!" ( - for /F "usebackq delims=" %%f in (`dir /B /A-D /O-N !cuDNNPattern!`) do ( +if "!cuda_major_version!" == "12" ( + If exist "!cuDNNPattern!" ( + for /F "usebackq delims=" %%f in (`dir /B /A-D /O-N !cuDNNPattern!`) do ( - REM We have a cuDNN archive. Get the archive name with and without extension - set cuDNNInstallerFilename=%%~nxf - set cuDNNInstallerNameNoExt=%%~nf + REM We have a cuDNN archive. Get the archive name with and without extension + set cuDNNInstallerFilename=%%~nxf + echo Found !cuDNNInstallerFilename! - echo Found !cuDNNInstallerFilename! + REM Get the version. Filename is similar to cudnn-9.5.1_windows.exe + REM where the version here is 9.5.1. We only need major/minor. - REM Get the version. Filename is similar to cudnn-windows-x86_64-8.5.0.96_cuda11-archive.zip, - REM where the version here is 8.5.0.96. We only need major/minor. + for /f "delims=" %%i in (' + powershell -c "'!cuDNNInstallerFilename!' -replace '!cuDNNRegex!','$1.$2'" + ') do set version=%%i - for /f "delims=" %%i in (' - powershell -c "'!cuDNNInstallerFilename!' -replace '!cuDNNRegex!','$1.$2'" - ') do set version=%%i + if "!version!" == "" ( + echo No installer available. + goto:eof + ) + echo Found cuDNN installer for version !version!. Installing... + + !cuDNNInstallerFilename! + + del !cuDNNInstallerFilename! + + set cuDNNInstalled=true - if "!version!" == "" ( - echo No installer available. - goto:eof + echo done. + + REM Only process the first archive we find + call :InstallChecks ) - echo Found cuDNN installer for version !version!. Expanding... + ) - REM Expand the archive +) else ( + IF exist "!cuDNNPattern!" ( + for /F "usebackq delims=" %%f in (`dir /B /A-D /O-N !cuDNNPattern!`) do ( - rem echo Expanding... - - set tarExists=true - tar -xf "!cuDNNInstallerFilename!" > nul 2>nul - if "%errorlevel%" == "9009" set tarExists=false + REM We have a cuDNN archive. Get the archive name with and without extension + set cuDNNInstallerFilename=%%~nxf + set cuDNNInstallerNameNoExt=%%~nf - if "!tarExists!" == "false" ( - powershell -command "Expand-Archive -Path '!cuDNNInstallerFilename!' -DestinationPath '!cuDNNInstallerNameNoExt!' -Force" - ) + echo Found !cuDNNInstallerFilename! - REM Move the directories into C:\Program Files\NVIDIA\CUDNN\v + REM Get the version. Filename is similar to cudnn-windows-x86_64-8.5.0.96_cuda11-archive.zip, + REM where the version here is 8.5.0.96. We only need major/minor. - echo Installing cuDNN files... + for /f "delims=" %%i in (' + powershell -c "'!cuDNNInstallerFilename!' -replace '!cuDNNRegex!','$1.$2'" + ') do set version=%%i - if not exist "C:\Program Files\NVIDIA" mkdir "C:\Program Files\NVIDIA" > NUL - if not exist "C:\Program Files\NVIDIA\CUDNN" mkdir "C:\Program Files\NVIDIA\CUDNN" > NUL - if not exist "C:\Program Files\NVIDIA\CUDNN\v!version!\" mkdir "C:\Program Files\NVIDIA\CUDNN\v!version!\" > NUL + if "!version!" == "" ( + echo No installer available. + goto:eof + ) + echo Found cuDNN installer for version !version!. Expanding... - robocopy /e "!cuDNNInstallerNameNoExt! " "C:\Program Files\NVIDIA\CUDNN\v!version! " /MOVE /NC /NS /NJS /NJH > NUL + REM Expand the archive - set cuDNNInstalled=true + rem echo Expanding... + + set tarExists=true + tar -xf "!cuDNNInstallerFilename!" > nul 2>nul + if "%errorlevel%" == "9009" set tarExists=false + if "!tarExists!" == "false" ( + powershell -command "Expand-Archive -Path '!cuDNNInstallerFilename!' -DestinationPath '!cuDNNInstallerNameNoExt!' -Force" + ) - echo Installing ZLib + REM Move the directories into C:\Program Files\NVIDIA\CUDNN\v - REM Next step is to grab ZLib and intall that. We'll place it next to the cuDNN files in - REM C:\Program Files\NVIDIA\CUDNN\v\zLib + echo Installing cuDNN files... - if not exist "!zLibArchiveName!.zip" ( - powershell -command "Start-BitsTransfer -Source '!zLibLocation!!zLibArchiveName!.zip' -Destination '!zLibArchiveName!.zip'" - ) + if not exist "C:\Program Files\NVIDIA" mkdir "C:\Program Files\NVIDIA" > NUL + if not exist "C:\Program Files\NVIDIA\CUDNN" mkdir "C:\Program Files\NVIDIA\CUDNN" > NUL + if not exist "C:\Program Files\NVIDIA\CUDNN\v!version!\" mkdir "C:\Program Files\NVIDIA\CUDNN\v!version!\" > NUL - if exist "!zLibArchiveName!.zip" ( - echo Expanding ZLib... - if "!tarExists!" == "true" ( - if not exist "!zLibArchiveName!" mkdir "!zLibArchiveName!" > NUL - copy !zLibArchiveName!.zip !zLibArchiveName!\ > NUL - pushd !zLibArchiveName! > NUL - tar -xf "!zLibArchiveName!.zip" > nul 2>nul - del !zLibArchiveName!.zip > NUL - popd > NUL - ) else ( - powershell -command "Expand-Archive -Path '!zLibArchiveName!.zip' -DestinationPath '!zLibArchiveName!' -Force" - ) + robocopy /e "!cuDNNInstallerNameNoExt! " "C:\Program Files\NVIDIA\CUDNN\v!version! " /MOVE /NC /NS /NJS /NJH > NUL - echo Installing ZLib... - if not exist "C:\Program Files\NVIDIA\CUDNN\v!version!\zlib" mkdir "C:\Program Files\NVIDIA\CUDNN\v!version!\zlib" - robocopy /e "!zLibArchiveName! " "C:\Program Files\NVIDIA\CUDNN\v!version!\zlib\ " /MOVE /NC /NS /NJS /NJH > NUL + set cuDNNInstalled=true - set zLibInstalled=true - ) - if /i "!dryRun!" == "false" ( - REM We need to set the PATH variable. Some caveats: - REM 1. When you set the PATH variable, %PATH% will not reflect the update you just made, so - REM doing "PATH = PATH + change1" followed by "PATH = PATH + change2" results in just Change2 - REM being added. So: do all the changes in one fell swoop. - REM 2. We can't use setx /M PATH "%PATH%;C:\Program Files\NVIDIA\CUDNN\v!version!\zlib\dll_x64" - REM because setx truncates the path to 1024 characters. In 2022. Insanity. - REM 3. Only update the path if we need to. Check for existance before modifying! + echo Installing ZLib - echo Updating PATH environment variable... + REM Next step is to grab ZLib and install that. We'll place it next to the cuDNN files in + REM C:\Program Files\NVIDIA\CUDNN\v\zLib - set newPath=!PATH! + if not exist "!zLibArchiveName!.zip" ( + powershell -command "Start-BitsTransfer -Source '!zLibLocation!!zLibArchiveName!.zip' -Destination '!zLibArchiveName!.zip'" + ) - REM Add ZLib path if it hasn't already been added - if "!zLibInstalled!" == "true" ( - if /i "!PATH:C:\Program Files\NVIDIA\CUDNN\v!version!\zlib=!" == "!PATH!" ( - set newPath=!newPath!;C:\Program Files\NVIDIA\CUDNN\v!version!\zlib\dll_x64 + if exist "!zLibArchiveName!.zip" ( + echo Expanding ZLib... + if "!tarExists!" == "true" ( + if not exist "!zLibArchiveName!" mkdir "!zLibArchiveName!" > NUL + copy !zLibArchiveName!.zip !zLibArchiveName!\ > NUL + pushd !zLibArchiveName! > NUL + tar -xf "!zLibArchiveName!.zip" > nul 2>nul + del !zLibArchiveName!.zip > NUL + popd > NUL + ) else ( + powershell -command "Expand-Archive -Path '!zLibArchiveName!.zip' -DestinationPath '!zLibArchiveName!' -Force" ) + + echo Installing ZLib... + if not exist "C:\Program Files\NVIDIA\CUDNN\v!version!\zlib" mkdir "C:\Program Files\NVIDIA\CUDNN\v!version!\zlib" + robocopy /e "!zLibArchiveName! " "C:\Program Files\NVIDIA\CUDNN\v!version!\zlib\ " /MOVE /NC /NS /NJS /NJH > NUL + + set zLibInstalled=true ) - REM Add cuDNN path if it hasn't already been added - if /i "!PATH:C:\Program Files\NVIDIA\CUDNN\v!version!\bin=!" == "!PATH!" ( - set newPath=!newPath!;C:\Program Files\NVIDIA\CUDNN\v!version!\bin - ) - if /i "!newPath" NEQ "!PATH!" ( - rem echo New Path is !newPath! - powershell -command "[Environment]::SetEnvironmentVariable('PATH', '!newPath!','Machine'); + if /i "!dryRun!" == "false" ( + REM We need to set the PATH variable. Some caveats: + REM 1. When you set the PATH variable, %PATH% will not reflect the update you just made, so + REM doing "PATH = PATH + change1" followed by "PATH = PATH + change2" results in just Change2 + REM being added. So: do all the changes in one fell swoop. + REM 2. We can't use setx /M PATH "%PATH%;C:\Program Files\NVIDIA\CUDNN\v!version!\zlib\dll_x64" + REM because setx truncates the path to 1024 characters. In 2022. Insanity. + REM 3. Only update the path if we need to. Check for existance before modifying! + + echo Updating PATH environment variable... + + set newPath=!PATH! + + REM Add ZLib path if it hasn't already been added + if "!zLibInstalled!" == "true" ( + if /i "!PATH:C:\Program Files\NVIDIA\CUDNN\v!version!\zlib=!" == "!PATH!" ( + set newPath=!newPath!;C:\Program Files\NVIDIA\CUDNN\v!version!\zlib\dll_x64 + ) + ) + REM Add cuDNN path if it hasn't already been added + if /i "!PATH:C:\Program Files\NVIDIA\CUDNN\v!version!\bin=!" == "!PATH!" ( + set newPath=!newPath!;C:\Program Files\NVIDIA\CUDNN\v!version!\bin + ) + + if /i "!newPath" NEQ "!PATH!" ( + rem echo New Path is !newPath! + powershell -command "[Environment]::SetEnvironmentVariable('PATH', '!newPath!','Machine'); + ) ) - ) - echo done. + echo done. - REM Only process the first archive we find - call :InstallChecks + REM Only process the first archive we find + call :InstallChecks + ) ) ) - goto:eof :InstallChecks From 05978af09e8c81a691398994fbb48037e059f936 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 12:45:20 -0500 Subject: [PATCH 13/71] Alloing InstallGPU / hasCUDA to be overridden in install scripts --- CodeProject.AI-Server.code-workspace | 5 ++++- src/scripts/utils.bat | 7 +++++-- src/setup.bat | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CodeProject.AI-Server.code-workspace b/CodeProject.AI-Server.code-workspace index 78872cc..c93b98d 100644 --- a/CodeProject.AI-Server.code-workspace +++ b/CodeProject.AI-Server.code-workspace @@ -86,6 +86,9 @@ } ], "settings": { - "csharp.debug.logging.moduleLoad": false + "csharp.debug.logging.moduleLoad": false, + "cSpell.words": [ + "paddlepaddle" + ] } } \ No newline at end of file diff --git a/src/scripts/utils.bat b/src/scripts/utils.bat index 7a59696..0a5d9e8 100644 --- a/src/scripts/utils.bat +++ b/src/scripts/utils.bat @@ -904,7 +904,7 @@ shift & goto :%~1 if "!requirementsFilename!" == "" ( REM Unless installGPU is false, we are installing CUDA equipped packages - REM even if EnableGPU = false in the modulesettings files. This allows + REM even if installGPU = false in the modulesettings files. This allows REM you to toggle CUDA support at runtime, rather than install time. if /i "!installGPU!" == "true" ( if /i "!hasCUDA!" == "true" ( @@ -1414,7 +1414,10 @@ shift & goto :%~1 if /i "!prevPart!" == "cuDNN" ( if /i "!part:~0,1!" == "v" ( set "cuDNN_version=!part:~1!" - REM @echo cuDNN version = !cuDNN_version! + + for /f "tokens=1 delims=." %%c in ("!cuDNN_version!") do ( set cuDNN_major_version=%%c ) + + REM @echo cuDNN version = !cuDNN_version! / !cuDNN_major_version! exit /b ) else ( set prevPart=!part! diff --git a/src/setup.bat b/src/setup.bat index bfc1a86..767ce1b 100644 --- a/src/setup.bat +++ b/src/setup.bat @@ -1075,6 +1075,8 @@ REM Saves the state of the installation environment set stateCurrentDir=%cd% set stateVerbosity=!verbosity! set stateOneStepPIP=!oneStepPIP! + set stateHasCUDA=!hasCUDA! + set stateInstallGPU=!installGPU! exit /b @@ -1084,5 +1086,7 @@ REM Restores the state of the installation environment cd "!stateCurrentDir!" set verbosity=!stateVerbosity! set oneStepPIP=!stateOneStepPIP! + set hasCUDA=!stateHasCUDA! + set installGPU=!stateInstallGPU! exit /b From 7a5a0e3c17a8872dee235e1ed2c2a21a891b0b94 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 15:53:39 -0500 Subject: [PATCH 14/71] Checks on whether the CUDA toolkit is installed --- src/setup.bat | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/setup.bat b/src/setup.bat index 767ce1b..c0c47c4 100644 --- a/src/setup.bat +++ b/src/setup.bat @@ -417,16 +417,22 @@ REM Test for CUDA drivers call "!utilsScript!" Write "CUDA Present..." set hasCUDA=false +set hasCUDAToolkit=false call "!utilsScript!" GetCudaVersion if "!cuda_version!" neq "" set hasCUDA=true if /i "!hasCUDA!" == "true" ( + + REM CUDA Toolkit != CUDA drivers. We need the files and CUDA_PATH to be in place + if exist "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v*" set hasCUDAToolkit=true + if "%CUDA_PATH%" == "" set hasCUDAToolkit=false + call "!utilsScript!" GetCuDNNVersion if "!cuDNN_version!" == "" ( - call "!utilsScript!" WriteLine "Yes (CUDA !cuda_version!, No cuDNN found)" !color_success! + call "!utilsScript!" WriteLine "Yes (CUDA !cuda_version!, No cuDNN found, CUDA Toolkit: !hasCUDAToolkit!)" !color_success! ) else ( - call "!utilsScript!" WriteLine "Yes (CUDA !cuda_version!, cuDNN !cuDNN_version!)" !color_success! + call "!utilsScript!" WriteLine "Yes (CUDA !cuda_version!, cuDNN !cuDNN_version!, CUDA Toolkit: !hasCUDAToolkit!)" !color_success! ) ) else ( call "!utilsScript!" WriteLine "No" !color_warn! From c05b3a45e931a29fb99579a4421529d34248a881 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 16:02:16 -0500 Subject: [PATCH 15/71] script cleanup --- src/setup.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup.bat b/src/setup.bat index c0c47c4..23dcfa0 100644 --- a/src/setup.bat +++ b/src/setup.bat @@ -426,7 +426,7 @@ if /i "!hasCUDA!" == "true" ( REM CUDA Toolkit != CUDA drivers. We need the files and CUDA_PATH to be in place if exist "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v*" set hasCUDAToolkit=true - if "%CUDA_PATH%" == "" set hasCUDAToolkit=false + if "%CUDA_PATH%" == "" ( set "hasCUDAToolkit=false" ) else ( set "hasCUDAToolkit=true" ) call "!utilsScript!" GetCuDNNVersion if "!cuDNN_version!" == "" ( From f5728986b09822319bd90fd6bf370b87f685c735 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 16:25:58 -0500 Subject: [PATCH 16/71] Corrected cleam --- devops/install/clean.bat | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/devops/install/clean.bat b/devops/install/clean.bat index 5858341..48a77ef 100644 --- a/devops/install/clean.bat +++ b/devops/install/clean.bat @@ -9,6 +9,8 @@ cls setlocal enabledelayedexpansion +start ..\utils\stop_all.bat + set useColor=true set doDebug=false set lineWidth=70 @@ -111,6 +113,17 @@ if /i "!cleanInstallAll!" == "true" ( set cleanUserData=true ) +echo clean assets = %cleanAssets% +echo clean build = %cleanBuild% +echo clean data = %cleanUserData% +echo clean download-cache = %cleanDownloadCache% +echo clean install = %cleanInstallCurrentOS% +echo clean install-all = %cleanInstallAll% +echo clean libraries = %cleanLibraries% +echo clean libraries-all = %cleanLibrariesAll% +echo clean all = %cleanAll% + + REM Start cleaning ============================================================= if /i "%cleanAssets%" == "true" ( @@ -210,11 +223,9 @@ if /i "%cleanDownloadCache%" == "true" ( call "!utilsScript!" WriteLine REM remove non module or model folders - FOR /d %%a IN ("%rootDir%\downloads\*") DO ( + FOR /d %%a IN ("%rootDir%\downloads\modules\assets\*") DO ( IF /i NOT "%%~nxa"=="modules" IF /i NOT "%%~nxa"=="models" call :RemoveDir "%%a" - - REM clean out module folders - call :RemoveFile "%rootDir%\downloads\modules\" + ) REM clean out models files FOR %%a IN ("%rootDir%\downloads\models\*") DO ( @@ -246,7 +257,7 @@ if /i "%cleanInstallCurrentOS%" == "true" ( if /i "%cleanInstallAll%" == "true" ( call "!utilsScript!" WriteLine - call "!utilsScript!" WriteLine "Cleaning install for other platforms" "White" "Blue" !lineWidth! + call "!utilsScript!" WriteLine "Cleaning install for all platforms" "White" "Blue" !lineWidth! call "!utilsScript!" WriteLine REM Clean shared python installs and venvs From 0904c9aa36d88b3418a2371c55f2e72eaf8caafd Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Tue, 19 Nov 2024 22:53:46 -0500 Subject: [PATCH 17/71] Minor nips and tucks --- devops/install/install_CUDnn.bat | 2 +- src/SDK/NET/Common.targets | 2 +- src/server/wwwroot/assets/explorer.js | 5 +---- .../CodeProject.AI.SDK.Tests/CodeProject.AI.SDK.Tests.csproj | 1 + .../CodeProject.AI.API.Server.Backend.Tests.csproj | 1 + 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/devops/install/install_CUDnn.bat b/devops/install/install_CUDnn.bat index bb54bb0..60e091c 100644 --- a/devops/install/install_CUDnn.bat +++ b/devops/install/install_CUDnn.bat @@ -252,7 +252,7 @@ if "!cuda_major_version!" == "12" ( REM being added. So: do all the changes in one fell swoop. REM 2. We can't use setx /M PATH "%PATH%;C:\Program Files\NVIDIA\CUDNN\v!version!\zlib\dll_x64" REM because setx truncates the path to 1024 characters. In 2022. Insanity. - REM 3. Only update the path if we need to. Check for existance before modifying! + REM 3. Only update the path if we need to. Check for existence before modifying! echo Updating PATH environment variable... diff --git a/src/SDK/NET/Common.targets b/src/SDK/NET/Common.targets index 4ffded8..9680e62 100644 --- a/src/SDK/NET/Common.targets +++ b/src/SDK/NET/Common.targets @@ -1,7 +1,7 @@  diff --git a/modules/ObjectDetectionYOLOv5Net/install.sh b/modules/ObjectDetectionYOLOv5Net/install.sh index 311507e..7cb395e 100644 --- a/modules/ObjectDetectionYOLOv5Net/install.sh +++ b/modules/ObjectDetectionYOLOv5Net/install.sh @@ -19,8 +19,12 @@ if [ "$1" != "install" ]; then exit 1 fi +installBinaries=false +if [ "$executionEnvironment" = "Production" ]; then installBinaries=true; fi +if [ "$launchedBy" = "server" ]; then installBinaries=true; fi + # Pull down the correct .NET image of ObjectDetectionYOLOv5Net based on this OS / GPU combo -if [ "${executionEnvironment}" = "Production" ] || [ "${launchedBy}" = "server" ]; then +if [ "${installBinaries}" = true ]; then imageName="ObjectDetectionYOLOv5Net-CPU-${moduleVersion}.zip" if [ "${installGPU}" = "true" ] && [ "${os}" != "macos" ]; then # Having issues with the OpenVINO version on linux diff --git a/src/demos/modules/DotNetSimple/DotNetSimple.csproj b/src/demos/modules/DotNetSimple/DotNetSimple.csproj index 7c389c3..9fa3940 100644 --- a/src/demos/modules/DotNetSimple/DotNetSimple.csproj +++ b/src/demos/modules/DotNetSimple/DotNetSimple.csproj @@ -49,10 +49,13 @@ + - + + + + + + + + + + + + + + + - + - + + + + + - - - - diff --git a/src/server/Server.csproj b/src/server/Server.csproj index 171d50a..b9c3364 100644 --- a/src/server/Server.csproj +++ b/src/server/Server.csproj @@ -84,20 +84,29 @@ https://learn.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=v --> - - + + + + + + + + + + + + - + + + + - - - - @@ -177,7 +186,7 @@ https://learn.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=v diff --git a/src/demos/modules/DotNetSimple/DotNetSimple.csproj b/src/demos/modules/DotNetSimple/DotNetSimple.csproj index 9fa3940..0498e87 100644 --- a/src/demos/modules/DotNetSimple/DotNetSimple.csproj +++ b/src/demos/modules/DotNetSimple/DotNetSimple.csproj @@ -60,12 +60,12 @@ - - - + + + - + diff --git a/src/setup.sh b/src/setup.sh index 4cbbea8..374d535 100644 --- a/src/setup.sh +++ b/src/setup.sh @@ -518,7 +518,7 @@ function doModuleInstall () { writeLine "Installing Python ${pythonVersion}" setupPython if [ $? -gt 0 ]; then moduleInstallErrors="Unable to install Python ${pythonVersion}"; fi - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - ${moduleInstallErrors}\n"; fi + # if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - ${moduleInstallErrors}\n"; fi fi # Install the module, but only if there were no issues installing python @@ -529,7 +529,7 @@ function doModuleInstall () { source "${moduleDirPath}/install.sh" "install" if [ $? -gt 0 ] && [ "${moduleInstallErrors}" = "" ]; then moduleInstallErrors="failed to install"; fi - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleName}] ${moduleInstallErrors}\n"; fi + # if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleName}] ${moduleInstallErrors}\n"; fi fi # If a python version has been specified then we'll automatically look @@ -547,7 +547,7 @@ function doModuleInstall () { installRequiredPythonPackages if [ $? -gt 0 ]; then moduleInstallErrors="Unable to install Python packages"; fi - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleName}] ${moduleInstallErrors}\n"; fi + # if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleName}] ${moduleInstallErrors}\n"; fi # With the move to having modules include our SDK PyPi, we no longer need this. # writeLine "Installing Python packages for the CodeProject.AI Server SDK" @@ -571,7 +571,7 @@ function doModuleInstall () { source "${moduleDirPath}/post_install.sh" "post-install" if [ $? -gt 0 ]; then moduleInstallErrors="Error running post-install script"; fi - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleName}] ${moduleInstallErrors}\n"; fi + # if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleName}] ${moduleInstallErrors}\n"; fi fi fi @@ -657,7 +657,7 @@ function doModuleInstall () { fi # return result - echo "${moduleInstallErrors}" + # echo "${moduleInstallErrors}" } # import the utilities ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @@ -704,7 +704,7 @@ if [[ $(wget -h 2>&1 | grep -E 'waitretry|connect-timeout') ]]; then fi # pipFlags='--quiet --quiet' - not actually supported, even though docs say it is -pipFlags='' +pipFlags='-q -q -q' copyFlags='/NFL /NDL /NJH /NJS /nc /ns >/dev/null' unzipFlags='-o -qq' tarFlags='-xf' @@ -1071,7 +1071,7 @@ if [ "$setupMode" = 'SetupEverything' ]; then doModuleInstall "${moduleId}" "${moduleDirPath}" "Internal" - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleId}] ${moduleInstallErrors}\n"; fi + if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [Int: ${moduleId} @ $moduleDirPath] ${moduleInstallErrors}\n"; fi done if [ "$installExternalModules" = "true" ]; then @@ -1088,7 +1088,7 @@ if [ "$setupMode" = 'SetupEverything' ]; then moduleId=$(getModuleIdFromModuleSettings "${moduleDirPath}/modulesettings.json") doModuleInstall "${moduleId}" "${moduleDirPath}" "External" - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleId}] ${moduleInstallErrors}\n"; fi + if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [Ext: ${moduleId} @ $moduleDirPath] ${moduleInstallErrors}\n"; fi done else writeLine "No external modules found" "$color_mute" @@ -1133,7 +1133,7 @@ if [ "$setupMode" = 'SetupEverything' ]; then moduleId=$(getModuleIdFromModuleSettings "${moduleDirPath}/modulesettings.json") doModuleInstall "${moduleId}" "${moduleDirPath}" "Demo" - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleId}] ${moduleInstallErrors}\n"; fi + if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [Demo: ${moduleId} @ $moduleDirPath] ${moduleInstallErrors}\n"; fi done modulesDirPath="${oldModulesDirPath}" fi @@ -1202,7 +1202,7 @@ else moduleId=$(getModuleIdFromModuleSettings "${moduleDirPath}/modulesettings.json") doModuleInstall "${moduleId}" "${moduleDirPath}" "Demo" - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleId}] ${moduleInstallErrors}\n"; fi + if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [Demo: ${moduleId}] ${moduleInstallErrors}\n"; fi modulesDirPath="$oldModulesDirPath" @@ -1212,7 +1212,7 @@ else moduleId=$(getModuleIdFromModuleSettings "${moduleDirPath}/modulesettings.json") doModuleInstall "${moduleId}" "${moduleDirPath}" "External" - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleId}] ${moduleInstallErrors}\n"; fi + if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [Ext: ${moduleId}] ${moduleInstallErrors}\n"; fi else # Internal module @@ -1220,7 +1220,7 @@ else moduleId=$(getModuleIdFromModuleSettings "${moduleDirPath}/modulesettings.json") doModuleInstall "${moduleId}" "${moduleDirPath}" "Internal" - if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [${moduleId}] ${moduleInstallErrors}\n"; fi + if [ "${moduleInstallErrors}" != "" ]; then setupErrors="${setupErrors}\n - [Int: ${moduleId}] ${moduleInstallErrors}\n"; fi fi fi From 7d8f097640dd367dc6e6114159265b031a1e6566 Mon Sep 17 00:00:00 2001 From: Chris Maunder <4680553+ChrisMaunder@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:31:04 -0500 Subject: [PATCH 38/71] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index eaa8fe5..527fc98 100644 --- a/README.md +++ b/README.md @@ -132,3 +132,16 @@ The current release provides support for CPU on each platform, DirectML on Windo - [Running in Docker](https://codeproject.github.io/codeproject.ai/why/running_in_docker.html) - Setup or install issues? See [Common Errors](https://codeproject.github.io/codeproject.ai/devguide/common_errors.html) +I'll add this to the docs: + +## Latest Version changes: 2.9 + +- Updated to .NET 9 +- Support for Ubuntu 24.10 +- Improved CUDA 12 support +- Improvements to CUDA support in Windows and Linux +- Further Windows arm64 fixes +- Further macOS arm64 fixes +- General dev environment setup fixes +- Fixes for Windows installer when wget is missing + From bc876d3bc8328f02c83f9f7323f5b2ac248cb66f Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sat, 23 Nov 2024 14:10:08 -0500 Subject: [PATCH 39/71] Updated CodeProject.AI Server homepage --- utils/ParseJSON/test.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/ParseJSON/test.json b/utils/ParseJSON/test.json index 9581b58..c7b8e09 100644 --- a/utils/ParseJSON/test.json +++ b/utils/ParseJSON/test.json @@ -12,7 +12,7 @@ "License" : "AGPL-3.0", "LicenseUrl" : "https://www.gnu.org/licenses/agpl-3.0.en.html", "Author" : "Chris Maunder", - "Homepage" : "https://codeproject.com/ai", + "Homepage" : "https://https://github.com/codeproject/CodeProject.AI-Server/", "BasedOn" : "ultralytics", "BasedOnUrl" : "https://github.com/ultralytics/ultralytics" }, From d99790a9936fc98cb67f009e45f89b8b42e67864 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sat, 23 Nov 2024 14:13:40 -0500 Subject: [PATCH 40/71] Typo --- utils/ParseJSON/test.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/ParseJSON/test.json b/utils/ParseJSON/test.json index c7b8e09..7fa0c55 100644 --- a/utils/ParseJSON/test.json +++ b/utils/ParseJSON/test.json @@ -12,7 +12,7 @@ "License" : "AGPL-3.0", "LicenseUrl" : "https://www.gnu.org/licenses/agpl-3.0.en.html", "Author" : "Chris Maunder", - "Homepage" : "https://https://github.com/codeproject/CodeProject.AI-Server/", + "Homepage" : "https://github.com/codeproject/CodeProject.AI-Server/", "BasedOn" : "ultralytics", "BasedOnUrl" : "https://github.com/ultralytics/ultralytics" }, From 0d0e00dd680f85778e955fa0f57745dc36c14748 Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 24 Nov 2024 10:59:18 -0500 Subject: [PATCH 41/71] Corrected install script to test for .env --- src/setup.bat | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/setup.bat b/src/setup.bat index eaee308..f207302 100644 --- a/src/setup.bat +++ b/src/setup.bat @@ -268,8 +268,9 @@ set installScriptsDirPath=!rootDirPath!\devops\install set utilsScript=!utilsScriptsDirPath!\utils.bat :: Load vars in .env. This may update things like dotNetTarget -for /f "tokens=1,2 delims==" %%a in (!rootDirPath!\.env) do set %%a=%%b - +if exist "!rootDirPath!\.env" ( + for /f "tokens=1,2 delims==" %%a in ("!rootDirPath!\.env") do set %%a=%%b +) :: Helper vars for OS, Platform (see note below), and system name. systemName is :: a no-op here because nothing exciting happens on Windows. In the corresponding :: .sh setup files, systemName can be docker, Raspberry Pi, WSL - all sorts of fun From 8359a5aa2dcf0c5d255bf155ee57ba5c75017e7e Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 24 Nov 2024 21:26:02 -0500 Subject: [PATCH 42/71] Typos --- .vscode/launch.json | 4 ++-- .vscode/tasks.json | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 59bb104..e0a6dda 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -233,7 +233,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-yolo-net", - "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/9.0/ObjectDetectionYOLOv5Net", + "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/net9.0/ObjectDetectionYOLOv5Net.exe", "linux": { "program": "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net/bin/Debug/net9.0/ObjectDetectionYOLOv5Net.dll", }, @@ -335,7 +335,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build-parsejson", - "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/9.0/ParseJSON", + "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/net9.0/ParseJSON", "linux": { "program": "${workspaceFolder}/utils/ParseJSON/bin/Debug/net9.0/ParseJSON.dll", }, diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 38f5c1f..b73c14e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -96,7 +96,8 @@ "build", "${workspaceFolder}/modules/ObjectDetectionYOLOv5Net", "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" + "/consoleloggerparameters:NoSummary", + "--configuration", "Debug" ], "problemMatcher": "$msCompile" }, From fd215280cc506b974a15ef496889dbca0da0caac Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Sun, 24 Nov 2024 21:26:39 -0500 Subject: [PATCH 43/71] Re-org of SDK namespace / simplifying meshbuilder --- ...rker.cs => ObjectDetectionModuleRunner.cs} | 20 +-- .../ObjectDetectionYOLOv5Net.csproj | 5 +- .../ObjectDetector.cs | 3 +- modules/ObjectDetectionYOLOv5Net/Program.cs | 4 +- .../modulesettings.json | 5 +- src/SDK/NET/API/ModuleResponses.cs | 2 + src/SDK/NET/API/ServerResponses.cs | 8 +- src/SDK/NET/Backend/BackendClient.cs | 2 +- src/SDK/NET/Backend/BackendRequests.cs | 4 +- ...oduleWorkerBase.cs => ModuleRunnerBase.cs} | 48 ++++--- src/SDK/NET/Common/RequestFormFile.cs | 2 +- src/SDK/NET/Common/RequestPayload.cs | 2 +- src/SDK/NET/FrontEndClient/ExplorerUI.cs | 2 +- .../FrontEndClient/FaceProcessingClient.cs | 2 +- src/SDK/NET/FrontEndClient/FrontEndClient.cs | 3 +- .../FrontEndClient/ObjectDetectionClient.cs | 4 +- .../FrontEndClient/SceneClassifierClient.cs | 2 +- src/SDK/NET/FrontEndClient/Structures.cs | 2 +- src/SDK/NET/FrontEndClient/TextResponses.cs | 2 +- src/SDK/NET/FrontEndClient/VisionResponses.cs | 2 +- src/SDK/NET/Modules/ModuleBase.cs | 2 +- src/SDK/NET/Modules/ModuleDescription.cs | 2 +- src/SDK/NET/Modules/ProcessStatus.cs | 2 +- src/SDK/NET/NET.csproj | 10 +- .../DotNetLongProcessWorker.cs | 4 +- .../DotNetSimple/DotNetSimpleWorker.cs | 4 +- src/server/Backend/CommandDispatcher.cs | 3 +- src/server/Backend/QueueServices.cs | 2 +- src/server/Controllers/ModuleController.cs | 12 +- src/server/Controllers/ProxyController.cs | 4 +- src/server/Controllers/QueueController.cs | 1 + .../Mesh/IMeshServerBroadcastBuilder.cs | 15 -- src/server/Mesh/MeshImplementation.cs | 132 ------------------ src/server/Mesh/MeshManager.cs | 19 ++- src/server/Mesh/MeshMonitor.cs | 115 ++++++++++++--- src/server/Mesh/MeshSupportExtensions.cs | 3 +- src/server/Modules/LegacyModuleConfig.cs | 2 +- src/server/Modules/ModuleCollection.cs | 6 +- src/server/Modules/ModuleProcessServices.cs | 2 + src/server/Modules/ModuleRunner.cs | 4 +- src/server/Server.csproj | 6 +- src/server/version.json | 6 +- 42 files changed, 216 insertions(+), 264 deletions(-) rename modules/ObjectDetectionYOLOv5Net/{ObjectDetectionWorker.cs => ObjectDetectionModuleRunner.cs} (96%) rename src/SDK/NET/Backend/{ModuleWorkerBase.cs => ModuleRunnerBase.cs} (96%) delete mode 100644 src/server/Mesh/IMeshServerBroadcastBuilder.cs delete mode 100644 src/server/Mesh/MeshImplementation.cs diff --git a/modules/ObjectDetectionYOLOv5Net/ObjectDetectionWorker.cs b/modules/ObjectDetectionYOLOv5Net/ObjectDetectionModuleRunner.cs similarity index 96% rename from modules/ObjectDetectionYOLOv5Net/ObjectDetectionWorker.cs rename to modules/ObjectDetectionYOLOv5Net/ObjectDetectionModuleRunner.cs index 544aa52..61e9ff6 100644 --- a/modules/ObjectDetectionYOLOv5Net/ObjectDetectionWorker.cs +++ b/modules/ObjectDetectionYOLOv5Net/ObjectDetectionModuleRunner.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Dynamic; using System.IO; using System.Linq; @@ -9,12 +10,13 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Hosting; -using CodeProject.AI.SDK; using CodeProject.AI.SDK.API; +using CodeProject.AI.SDK.Backend; +using CodeProject.AI.SDK.Client; +using CodeProject.AI.SDK.Common; using CodeProject.AI.SDK.Utils; using Yolov5Net.Scorer; -using System.Dynamic; #pragma warning disable CS0162 // unreachable code @@ -27,7 +29,7 @@ namespace CodeProject.AI.Modules.ObjectDetection.YOLOv5 /// While intended for development and tests, this also demonstrates how a backend service can /// be created with the .NET Core framework. /// - public class ObjectDetectionWorker : ModuleWorkerBase + public class ObjectDetectionModuleRunner : ModuleRunnerBase { private const bool ShowTrace = false; @@ -49,20 +51,20 @@ public class ObjectDetectionWorker : ModuleWorkerBase /// The Logger. /// The app configuration values. /// The applicationLifetime object - public ObjectDetectionWorker(ILogger logger, IConfiguration config, + public ObjectDetectionModuleRunner(ILogger logger, IConfiguration config, IHostApplicationLifetime hostApplicationLifetime) : base(logger, config, hostApplicationLifetime) { _logger = logger; _mode = config.GetValue("MODEL_SIZE", "Medium") ?? "Medium"; - _modelDir = config.GetValue("MODELS_DIR", Path.Combine(moduleDirPath!, "assets")) ?? "assets"; - _customDir = config.GetValue("CUSTOM_MODELS_DIR", Path.Combine(moduleDirPath!, "custom-models")) ?? "custom-models"; + _modelDir = config.GetValue("MODELS_DIR", Path.Combine(ModuleDirPath!, "assets")) ?? "assets"; + _customDir = config.GetValue("CUSTOM_MODELS_DIR", Path.Combine(ModuleDirPath!, "custom-models")) ?? "custom-models"; - if (!_modelDir.EndsWith("/") || !_modelDir.EndsWith("\\")) + if (!_modelDir.EndsWith('/') || !_modelDir.EndsWith('\\')) _modelDir += "/"; - if (!_customDir.EndsWith("/") || !_customDir.EndsWith("\\")) + if (!_customDir.EndsWith('/') || !_customDir.EndsWith('\\')) _customDir += "/"; _modelDir = Text.FixSlashes(_modelDir); @@ -234,7 +236,7 @@ protected override int SelfTest() { RequestPayload payload = new RequestPayload("detect"); payload.SetValue("minconfidence", "0.4"); - payload.AddFile(Path.Combine(moduleDirPath!, "test/home-office.jpg")); + payload.AddFile(Path.Combine(ModuleDirPath!, "test/home-office.jpg")); var request = new BackendRequest(payload); ModuleResponse response = Process(request); diff --git a/modules/ObjectDetectionYOLOv5Net/ObjectDetectionYOLOv5Net.csproj b/modules/ObjectDetectionYOLOv5Net/ObjectDetectionYOLOv5Net.csproj index e2c5e27..f0d5700 100644 --- a/modules/ObjectDetectionYOLOv5Net/ObjectDetectionYOLOv5Net.csproj +++ b/modules/ObjectDetectionYOLOv5Net/ObjectDetectionYOLOv5Net.csproj @@ -80,10 +80,11 @@ - + + - + diff --git a/modules/ObjectDetectionYOLOv5Net/ObjectDetector.cs b/modules/ObjectDetectionYOLOv5Net/ObjectDetector.cs index 0ca9726..c488f0a 100644 --- a/modules/ObjectDetectionYOLOv5Net/ObjectDetector.cs +++ b/modules/ObjectDetectionYOLOv5Net/ObjectDetector.cs @@ -9,8 +9,9 @@ using SkiaSharp; using Yolov5Net.Scorer; using Yolov5Net.Scorer.Models; -using CodeProject.AI.SDK; + using CodeProject.AI.SDK.API; +using CodeProject.AI.SDK.Client; using CodeProject.AI.SDK.Utils; namespace CodeProject.AI.Modules.ObjectDetection.YOLOv5 diff --git a/modules/ObjectDetectionYOLOv5Net/Program.cs b/modules/ObjectDetectionYOLOv5Net/Program.cs index 1c9413c..d539d70 100644 --- a/modules/ObjectDetectionYOLOv5Net/Program.cs +++ b/modules/ObjectDetectionYOLOv5Net/Program.cs @@ -8,12 +8,12 @@ internal static class Program { static async Task Main(string[]? args) { - ObjectDetectionWorker.ProcessArguments(args); + ObjectDetectionModuleRunner.ProcessArguments(args); IHost host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { - services.AddHostedService(); + services.AddHostedService(); }) .Build(); diff --git a/modules/ObjectDetectionYOLOv5Net/modulesettings.json b/modules/ObjectDetectionYOLOv5Net/modulesettings.json index 0fb7ab9..34991c9 100644 --- a/modules/ObjectDetectionYOLOv5Net/modulesettings.json +++ b/modules/ObjectDetectionYOLOv5Net/modulesettings.json @@ -3,7 +3,7 @@ "ObjectDetectionYOLOv5Net": { "Name": "Object Detection (YOLOv5 .NET)", - "Version": "1.12.0", + "Version": "1.13.0", "PublishingInfo" : { "Description": "Provides Object Detection using YOLOv5 ONNX models with DirectML. This module is best for those on Windows and Linux without CUDA enabled GPUs", @@ -70,7 +70,8 @@ { "ModuleVersion": "1.10.1", "ServerVersionRange": [ "2.6.3", "2.7.0" ], "ReleaseDate": "2024-04-05", "ReleaseNotes": "Corrected reported Inference device" }, { "ModuleVersion": "1.10.2", "ServerVersionRange": [ "2.6.5", "2.7.0" ], "ReleaseDate": "2024-02-26", "ReleaseNotes": "Corrections for backwards compatibility for 2.6.5" }, { "ModuleVersion": "1.11.0", "ServerVersionRange": [ "2.8.0", "2.9.0" ], "ReleaseDate": "2024-08-02", "ReleaseNotes": "Updated for server 2.8" }, - { "ModuleVersion": "1.12.0", "ServerVersionRange": [ "2.9.1", "" ], "ReleaseDate": "2024-11-17", "ReleaseNotes": "Updated to .NET 9" } + { "ModuleVersion": "1.12.0", "ServerVersionRange": [ "2.9.1", "2.9.1" ], "ReleaseDate": "2024-11-17", "ReleaseNotes": "Updated to .NET 9" }, + { "ModuleVersion": "1.13.0", "ServerVersionRange": [ "2.9.2", "" ], "ReleaseDate": "2024-11-24", "ReleaseNotes": "Updated to reflect updated CodeProject.AI SDK" } ] }, diff --git a/src/SDK/NET/API/ModuleResponses.cs b/src/SDK/NET/API/ModuleResponses.cs index a112d34..4bdf200 100644 --- a/src/SDK/NET/API/ModuleResponses.cs +++ b/src/SDK/NET/API/ModuleResponses.cs @@ -2,6 +2,8 @@ using System.Threading; using System.Threading.Tasks; +using CodeProject.AI.SDK.Backend; + namespace CodeProject.AI.SDK.API { public delegate Task LongProcessMethod(BackendRequest request, diff --git a/src/SDK/NET/API/ServerResponses.cs b/src/SDK/NET/API/ServerResponses.cs index d5ca8ab..4fea9fc 100644 --- a/src/SDK/NET/API/ServerResponses.cs +++ b/src/SDK/NET/API/ServerResponses.cs @@ -1,10 +1,10 @@ -using System.Net; +using System; +using System.Collections.Generic; +using System.Net; using CodeProject.AI.SDK.Modules; +using CodeProject.AI.SDK.Client; using CodeProject.AI.SDK.Common; -using CodeProject.AI.SDK.Server; -using System.Collections.Generic; -using System; namespace CodeProject.AI.SDK.API { diff --git a/src/SDK/NET/Backend/BackendClient.cs b/src/SDK/NET/Backend/BackendClient.cs index 6e40e83..4b570ad 100644 --- a/src/SDK/NET/Backend/BackendClient.cs +++ b/src/SDK/NET/Backend/BackendClient.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; -namespace CodeProject.AI.SDK +namespace CodeProject.AI.SDK.Backend { /// /// Represents an HTTP client for modules that gets requests and returns responses to the diff --git a/src/SDK/NET/Backend/BackendRequests.cs b/src/SDK/NET/Backend/BackendRequests.cs index 0995f8c..78ea40f 100644 --- a/src/SDK/NET/Backend/BackendRequests.cs +++ b/src/SDK/NET/Backend/BackendRequests.cs @@ -1,7 +1,9 @@ using System; using System.Text.Json.Serialization; -namespace CodeProject.AI.SDK +using CodeProject.AI.SDK.Common; + +namespace CodeProject.AI.SDK.Backend { #pragma warning disable IDE1006 // Naming Styles diff --git a/src/SDK/NET/Backend/ModuleWorkerBase.cs b/src/SDK/NET/Backend/ModuleRunnerBase.cs similarity index 96% rename from src/SDK/NET/Backend/ModuleWorkerBase.cs rename to src/SDK/NET/Backend/ModuleRunnerBase.cs index 1d576bc..4956b52 100644 --- a/src/SDK/NET/Backend/ModuleWorkerBase.cs +++ b/src/SDK/NET/Backend/ModuleRunnerBase.cs @@ -8,25 +8,26 @@ using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; -using CodeProject.AI.SDK.API; -using CodeProject.AI.SDK.Utils; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -namespace CodeProject.AI.SDK +using CodeProject.AI.SDK.API; +using CodeProject.AI.SDK.Utils; + +namespace CodeProject.AI.SDK.Backend { /// /// The base class from which a module should be derived. /// - public abstract class ModuleWorkerBase : BackgroundService + public abstract class ModuleRunnerBase : BackgroundService { - private readonly string[] _doNotLogCommands = { + private readonly string[] _doNotLogCommands = [ "list-custom", "get_module_status", "status", "get_status", // status is deprecated alias "get_command_status" - }; + ]; private readonly TimeSpan _status_delay = TimeSpan.FromSeconds(2); @@ -61,7 +62,7 @@ public abstract class ModuleWorkerBase : BackgroundService /// /// Gets or sets the path to this Module /// - public string? moduleDirPath { get; set; } + public string? ModuleDirPath { get; set; } /// /// Gets or sets a value indicating whether or not this module supports GPU acceleration @@ -95,13 +96,13 @@ public abstract class ModuleWorkerBase : BackgroundService /// The Logger. /// The app configuration values. /// The applicationLifetime object - public ModuleWorkerBase(ILogger logger, IConfiguration configuration, + public ModuleRunnerBase(ILogger logger, IConfiguration configuration, IHostApplicationLifetime hostApplicationLifetime) { // _logger = logger; using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole()); - _logger = factory.CreateLogger(); + _logger = factory.CreateLogger(); _cancelled = false; _appLifetime = hostApplicationLifetime; @@ -112,23 +113,29 @@ public ModuleWorkerBase(ILogger logger, IConfiguration configuration, // TODO: We could load the settings directly from the modulesettings files rather than rely // rely environment variables: /* - // Load up the module's settings and start the module - var config = new ConfigurationBuilder(); - config.AddModuleSettingsConfigFiles(moduleDirPath, false); - IConfiguration configuration = config.Build(); + // Load up the modulesettings.*.json files + var configBuilder = new IConfigurationBuilder(); + configBuilder.AddModuleSettingsConfigFiles(ModuleDirPath, false); + IConfiguration config = configBuilder.Build(); // Bind the values in the configuration to a ModuleConfig object - string moduleId = [get module id from config] var moduleConfig = new ModuleConfig(); - configuration.Bind($"Modules:{moduleId}", moduleConfig); + try + { + config.Bind($"Modules:{moduleId}", moduleConfig); + } + catch (Exception) + { + moduleConfig = null; + } // Complete the ModuleConfig's setup. - if (moduleConfig.Initialise(moduleId, moduleDirPath, ModuleLocation.Internal)) + if (moduleConfig.Initialise(moduleId, ModuleDirPath, ModuleLocation.Internal)) */ _moduleId = configuration.GetValue("CPAI_MODULE_ID", null) ?? currentDirName; ModuleName = configuration.GetValue("CPAI_MODULE_NAME", null) ?? _moduleId; - moduleDirPath = configuration.GetValue("CPAI_MODULE_PATH", null) ?? currentModuleDirPath; + ModuleDirPath = configuration.GetValue("CPAI_MODULE_PATH", null) ?? currentModuleDirPath; _queueName = configuration.GetValue("CPAI_MODULE_QUEUENAME", null) ?? _moduleId.ToLower() + "_queue"; int port = configuration.GetValue("CPAI_PORT", 32168); @@ -638,8 +645,6 @@ protected string GetModuleDirectoryPath() string moduleDirPath = AppContext.BaseDirectory; DirectoryInfo? info = new DirectoryInfo(moduleDirPath); - // HACK: If we're running this server from the build output dir in dev environment - // then the root path will be wrong. if (SystemInfo.IsDevelopmentCode) { while (info != null) @@ -652,6 +657,11 @@ protected string GetModuleDirectoryPath() } } } + else + { + if (info?.Name.ToLower() == "bin") + info = info.Parent; + } if (info != null) return info.FullName; diff --git a/src/SDK/NET/Common/RequestFormFile.cs b/src/SDK/NET/Common/RequestFormFile.cs index 9b7c7e1..efcd918 100644 --- a/src/SDK/NET/Common/RequestFormFile.cs +++ b/src/SDK/NET/Common/RequestFormFile.cs @@ -2,7 +2,7 @@ using SkiaSharp; -namespace CodeProject.AI.SDK +namespace CodeProject.AI.SDK.Common { public class RequestFormFile { diff --git a/src/SDK/NET/Common/RequestPayload.cs b/src/SDK/NET/Common/RequestPayload.cs index a15d147..90b8636 100644 --- a/src/SDK/NET/Common/RequestPayload.cs +++ b/src/SDK/NET/Common/RequestPayload.cs @@ -4,7 +4,7 @@ using System.IO; using System.Linq; -namespace CodeProject.AI.SDK +namespace CodeProject.AI.SDK.Common { public class RequestPayload { diff --git a/src/SDK/NET/FrontEndClient/ExplorerUI.cs b/src/SDK/NET/FrontEndClient/ExplorerUI.cs index 29d889d..bc538b8 100644 --- a/src/SDK/NET/FrontEndClient/ExplorerUI.cs +++ b/src/SDK/NET/FrontEndClient/ExplorerUI.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace CodeProject.AI.SDK.Server +namespace CodeProject.AI.SDK.Client { /// /// Represents an option in a dropdown menu in the dashboard diff --git a/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs b/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs index 7224afb..3fdc1cd 100644 --- a/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs +++ b/src/SDK/NET/FrontEndClient/FaceProcessingClient.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using CodeProject.AI.SDK.API; -namespace CodeProject.AI.SDK.Server +namespace CodeProject.AI.SDK.Client { /// /// This is an example of a .NET client to call CodeProject.AI API Server. diff --git a/src/SDK/NET/FrontEndClient/FrontEndClient.cs b/src/SDK/NET/FrontEndClient/FrontEndClient.cs index 0a29c59..f6233af 100644 --- a/src/SDK/NET/FrontEndClient/FrontEndClient.cs +++ b/src/SDK/NET/FrontEndClient/FrontEndClient.cs @@ -2,9 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; + using CodeProject.AI.SDK.API; -namespace CodeProject.AI.SDK.Server +namespace CodeProject.AI.SDK.Client { /// /// This is an example of a .NET client to call CodeProject.AI API Server. diff --git a/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs b/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs index 1bd7478..2f0ed14 100644 --- a/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs +++ b/src/SDK/NET/FrontEndClient/ObjectDetectionClient.cs @@ -1,9 +1,9 @@  using System.Threading.Tasks; using CodeProject.AI.SDK.API; -using CodeProject.AI.SDK.Server; +using CodeProject.AI.SDK.Client; -namespace CodeProject.AI.Server.Clients +namespace CodeProject.AI.Server.Client { /// /// This is an example of a .NET client to call CodeProject.AI API Server. diff --git a/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs b/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs index 6fcadfb..a0f0551 100644 --- a/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs +++ b/src/SDK/NET/FrontEndClient/SceneClassifierClient.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using CodeProject.AI.SDK.API; -namespace CodeProject.AI.SDK.Server +namespace CodeProject.AI.SDK.Client { /// /// This is an example of a .NET client to call CodeProject.AI API Server. diff --git a/src/SDK/NET/FrontEndClient/Structures.cs b/src/SDK/NET/FrontEndClient/Structures.cs index db48e8f..1dbe175 100644 --- a/src/SDK/NET/FrontEndClient/Structures.cs +++ b/src/SDK/NET/FrontEndClient/Structures.cs @@ -1,4 +1,4 @@ -namespace CodeProject.AI.SDK.Server +namespace CodeProject.AI.SDK.Client { public class BoundingBox { diff --git a/src/SDK/NET/FrontEndClient/TextResponses.cs b/src/SDK/NET/FrontEndClient/TextResponses.cs index 0bb16ae..7243152 100644 --- a/src/SDK/NET/FrontEndClient/TextResponses.cs +++ b/src/SDK/NET/FrontEndClient/TextResponses.cs @@ -1,6 +1,6 @@ using CodeProject.AI.SDK.API; -namespace CodeProject.AI.SDK.Server +namespace CodeProject.AI.SDK.Client { /// /// The Response for a Text Summary request. diff --git a/src/SDK/NET/FrontEndClient/VisionResponses.cs b/src/SDK/NET/FrontEndClient/VisionResponses.cs index 65d9401..8f24be9 100644 --- a/src/SDK/NET/FrontEndClient/VisionResponses.cs +++ b/src/SDK/NET/FrontEndClient/VisionResponses.cs @@ -1,6 +1,6 @@ using CodeProject.AI.SDK.API; -namespace CodeProject.AI.SDK.Server +namespace CodeProject.AI.SDK.Client { /// /// The Response for a Face Detection Request. diff --git a/src/SDK/NET/Modules/ModuleBase.cs b/src/SDK/NET/Modules/ModuleBase.cs index 7a506a8..314f13e 100644 --- a/src/SDK/NET/Modules/ModuleBase.cs +++ b/src/SDK/NET/Modules/ModuleBase.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using System.Text.Json.Serialization; -using CodeProject.AI.SDK.API; + using CodeProject.AI.SDK.Common; using CodeProject.AI.SDK.Utils; diff --git a/src/SDK/NET/Modules/ModuleDescription.cs b/src/SDK/NET/Modules/ModuleDescription.cs index f331200..73f9930 100644 --- a/src/SDK/NET/Modules/ModuleDescription.cs +++ b/src/SDK/NET/Modules/ModuleDescription.cs @@ -163,7 +163,7 @@ public static class ModuleDescriptionExtensions /// ModuleDescription objects are typically created by deserialising a JSON file so we don't /// get a chance at create time to supply supplementary information or adjust values that /// may not have been set (eg moduleId). Specifically, this function will set the status and - /// the moduleDirPath / WorkingDirectory, as well as setting the latest compatible version + /// the ModuleDirPath / WorkingDirectory, as well as setting the latest compatible version /// from the module's ModuleRelease list. But this could change without notice. /// /// This module that requires initialisation diff --git a/src/SDK/NET/Modules/ProcessStatus.cs b/src/SDK/NET/Modules/ProcessStatus.cs index 9f22544..8ebfec0 100644 --- a/src/SDK/NET/Modules/ProcessStatus.cs +++ b/src/SDK/NET/Modules/ProcessStatus.cs @@ -4,7 +4,7 @@ using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Threading; -using CodeProject.AI.SDK.Server; +using CodeProject.AI.SDK.Client; namespace CodeProject.AI.SDK.Modules { diff --git a/src/SDK/NET/NET.csproj b/src/SDK/NET/NET.csproj index 06f6b16..c5d0ea8 100644 --- a/src/SDK/NET/NET.csproj +++ b/src/SDK/NET/NET.csproj @@ -54,12 +54,12 @@ - - - - + + + + - + diff --git a/src/demos/modules/DotNetLongProcess/DotNetLongProcessWorker.cs b/src/demos/modules/DotNetLongProcess/DotNetLongProcessWorker.cs index 656a828..a7e76dc 100644 --- a/src/demos/modules/DotNetLongProcess/DotNetLongProcessWorker.cs +++ b/src/demos/modules/DotNetLongProcess/DotNetLongProcessWorker.cs @@ -69,7 +69,7 @@ public DotNetLongProcessWorker(ILogger logger, // Get some values from environment variables _modelSize = config.GetValue("MODEL_SIZE", "Medium") ?? "Medium"; - _modelDir = config.GetValue("MODELS_DIR", Path.Combine(moduleDirPath!, "assets")) ?? "assets"; + _modelDir = config.GetValue("MODELS_DIR", Path.Combine(ModuleDirPath!, "assets")) ?? "assets"; } protected override void Initialize() @@ -217,7 +217,7 @@ protected override int SelfTest() // Setup the request and add some test data RequestPayload payload = new RequestPayload("command"); payload.SetValue("minconfidence", "0.4"); - payload.AddFile(Path.Combine(moduleDirPath!, "test/home-office.jpg")); + payload.AddFile(Path.Combine(ModuleDirPath!, "test/home-office.jpg")); var request = new BackendRequest(payload); diff --git a/src/demos/modules/DotNetSimple/DotNetSimpleWorker.cs b/src/demos/modules/DotNetSimple/DotNetSimpleWorker.cs index adf715a..e07c17a 100644 --- a/src/demos/modules/DotNetSimple/DotNetSimpleWorker.cs +++ b/src/demos/modules/DotNetSimple/DotNetSimpleWorker.cs @@ -65,7 +65,7 @@ public DotNetSimpleWorker(ILogger logger, _logger = logger; _modelSize = config.GetValue("MODEL_SIZE", "Medium") ?? "Medium"; - _modelDir = config.GetValue("MODELS_DIR", Path.Combine(moduleDirPath!, "assets")) ?? "assets"; + _modelDir = config.GetValue("MODELS_DIR", Path.Combine(ModuleDirPath!, "assets")) ?? "assets"; if (!_modelDir.EndsWith("/") || !_modelDir.EndsWith("\\")) _modelDir += "/"; @@ -209,7 +209,7 @@ protected override int SelfTest() { RequestPayload payload = new RequestPayload("detect"); payload.SetValue("minconfidence", "0.4"); - payload.AddFile(Path.Combine(moduleDirPath!, "test/home-office.jpg")); + payload.AddFile(Path.Combine(ModuleDirPath!, "test/home-office.jpg")); var request = new BackendRequest(payload); diff --git a/src/server/Backend/CommandDispatcher.cs b/src/server/Backend/CommandDispatcher.cs index 52cd3f6..1a42f9c 100644 --- a/src/server/Backend/CommandDispatcher.cs +++ b/src/server/Backend/CommandDispatcher.cs @@ -1,7 +1,8 @@ using System.Threading; using System.Threading.Tasks; -using CodeProject.AI.SDK; +using CodeProject.AI.SDK.Backend; +using CodeProject.AI.SDK.Common; namespace CodeProject.AI.Server.Backend { diff --git a/src/server/Backend/QueueServices.cs b/src/server/Backend/QueueServices.cs index 03a0597..b2f5be0 100644 --- a/src/server/Backend/QueueServices.cs +++ b/src/server/Backend/QueueServices.cs @@ -10,8 +10,8 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using CodeProject.AI.SDK; using CodeProject.AI.SDK.API; +using CodeProject.AI.SDK.Backend; namespace CodeProject.AI.Server.Backend { diff --git a/src/server/Controllers/ModuleController.cs b/src/server/Controllers/ModuleController.cs index c02a099..9e54d77 100644 --- a/src/server/Controllers/ModuleController.cs +++ b/src/server/Controllers/ModuleController.cs @@ -4,17 +4,17 @@ using System.Linq; using System.Threading.Tasks; -using CodeProject.AI.SDK.API; -using CodeProject.AI.SDK.Modules; -using CodeProject.AI.SDK.Server; -using CodeProject.AI.Server.Models; -using CodeProject.AI.Server.Modules; - using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using CodeProject.AI.SDK.API; +using CodeProject.AI.SDK.Client; +using CodeProject.AI.SDK.Modules; +using CodeProject.AI.Server.Models; +using CodeProject.AI.Server.Modules; + namespace CodeProject.AI.Server.Controllers { /// diff --git a/src/server/Controllers/ProxyController.cs b/src/server/Controllers/ProxyController.cs index 08bc0f5..06a5071 100644 --- a/src/server/Controllers/ProxyController.cs +++ b/src/server/Controllers/ProxyController.cs @@ -17,10 +17,10 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; -using CodeProject.AI.Server.Backend; -using CodeProject.AI.SDK; using CodeProject.AI.SDK.API; +using CodeProject.AI.SDK.Common; using CodeProject.AI.SDK.Utils; +using CodeProject.AI.Server.Backend; using CodeProject.AI.Server.Modules; using CodeProject.AI.Server.Mesh; diff --git a/src/server/Controllers/QueueController.cs b/src/server/Controllers/QueueController.cs index 08d0393..9fb9e58 100644 --- a/src/server/Controllers/QueueController.cs +++ b/src/server/Controllers/QueueController.cs @@ -12,6 +12,7 @@ using CodeProject.AI.Server.Backend; using CodeProject.AI.SDK.Utils; using CodeProject.AI.Server.Modules; +using CodeProject.AI.SDK.Backend; namespace CodeProject.AI.Server.Controllers { diff --git a/src/server/Mesh/IMeshServerBroadcastBuilder.cs b/src/server/Mesh/IMeshServerBroadcastBuilder.cs deleted file mode 100644 index 95d617a..0000000 --- a/src/server/Mesh/IMeshServerBroadcastBuilder.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace CodeProject.AI.Server.Mesh -{ - /// - /// This is used by the ServerMeshMonitor to build the status of the current node. - /// - public interface IMeshServerBroadcastBuilder where TStatus: MeshServerBroadcastData, new() - { - /// - /// Build the current node's status - /// - /// The current mesh monitor - /// The Mesh Node's status. - TStatus Build(BaseMeshMonitor meshMonitor); - } -} diff --git a/src/server/Mesh/MeshImplementation.cs b/src/server/Mesh/MeshImplementation.cs deleted file mode 100644 index 8a5705a..0000000 --- a/src/server/Mesh/MeshImplementation.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using Microsoft.Extensions.Options; -using Microsoft.Extensions.Logging; - -using CodeProject.AI.Server.Modules; -using CodeProject.AI.SDK.Utils; -using CodeProject.AI.SDK.Modules; - -// ------------------------------------------------------------------------------------------------- -// This file implements the BaseMeshMonitor class and the IMeshServerBroadcastBuilder interface. -// ------------------------------------------------------------------------------------------------- - -namespace CodeProject.AI.Server.Mesh -{ - /// - /// The Mesh for the Servers. - /// - public class MeshMonitor : BaseMeshMonitor - { - /// - /// Creates a new instance of the Mesh class. - /// - /// The Mesh Options - /// The mesh node status builder. - /// A logger. - public MeshMonitor(IOptionsMonitor meshConfig, - MeshServerBroadcastBuilder statusBuilder, - ILogger logger) - : base(meshConfig, statusBuilder, logger) - { - } - } - - /// - /// Gets the nodes status to send to the Mesh. - /// - /// - /// The 'Build' method is abstracted using an interface to allow easier mocking and testing - /// - public class MeshServerBroadcastBuilder : IMeshServerBroadcastBuilder - { - private readonly ModuleCollection _modules; - private readonly ModuleProcessServices _processServices; - private readonly IOptionsMonitor _monitoredMeshOptions; - - /// - /// Initializes a new instance of the MeshNodeStatusBuilder class. - /// - /// The installed modules. - /// The MeshOptions monitoring object. - /// The Module Process Services. - public MeshServerBroadcastBuilder(IOptions modules, - IOptionsMonitor monitoredMeshOptions, // TODO: handle config changes - ModuleProcessServices processServices) - { - _modules = modules.Value; - _processServices = processServices; - _monitoredMeshOptions = monitoredMeshOptions; - } - - /// - /// Build the current node's broadcast package for mesh availability announcements - /// - /// A object - /// - /// REVIEW: This has now served it's purpose and is to be moved as a simple function into - /// MeshMonitor - /// - public MeshServerBroadcastData Build(BaseMeshMonitor meshMonitor) - { - // Get the running modules - IOrderedEnumerable runningModulesIds = _processServices - .ListProcessStatuses() - .Where(p => p.Status == ProcessStatusType.Started) - .Select(p => p.ModuleId) - .Distinct() - .OrderBy(m => m); - IEnumerable runningModules = _modules.Values - .Where(m => runningModulesIds.Contains(m.ModuleId)); - - // Get their routes - List enabledRoutes; - enabledRoutes = runningModules - .SelectMany(m => m.RouteMaps.Where(r => r.MeshEnabled ?? true) - .Select(r => r.Route)) - .Distinct() - .OrderBy(s => s) - .ToList(); - - // Hostnames of known servers in the mesh - var knownHostnames = meshMonitor.DiscoveredServers.Values - .Where(s => !s.Status.Hostname.EqualsIgnoreCase(meshMonitor.LocalHostname)) - .Select(s => s.Status.Hostname); - - // Description and platform - string systemDescription = $"{SystemInfo.SystemName} ({SystemInfo.OSAndArchitecture})"; - if (SystemInfo.GPU is not null) - { - if (SystemInfo.GPU.HardwareVendor == "Apple" || - SystemInfo.GPU.HardwareVendor == "NVIDIA" || - SystemInfo.GPU.HardwareVendor == "Intel") - { - systemDescription += " " + (SystemInfo.GPU.Name ?? "GPU"); - } - } - - string platform = SystemInfo.Platform; - if (SystemInfo.IsDocker) - platform = "Docker"; - - // For other settings - MeshOptions meshOptions = _monitoredMeshOptions.CurrentValue; - - // Now build. - return new MeshServerBroadcastData - { - Hostname = SystemInfo.MachineName, - SystemDescription = systemDescription, - Platform = platform, - EnabledRoutes = enabledRoutes, - KnownHostnames = knownHostnames, - IsBroadcasting = meshOptions.EnableStatusBroadcast, - IsMonitoring = meshOptions.EnableStatusMonitoring, - AcceptForwardedRequests = meshOptions.AcceptForwardedRequests, - AllowRequestForwarding = meshOptions.AllowRequestForwarding - }; - } - } -} diff --git a/src/server/Mesh/MeshManager.cs b/src/server/Mesh/MeshManager.cs index 5eee79f..ceca5ed 100644 --- a/src/server/Mesh/MeshManager.cs +++ b/src/server/Mesh/MeshManager.cs @@ -7,7 +7,6 @@ using Microsoft.Extensions.Options; using CodeProject.AI.Server.Modules; -using CodeProject.AI.SDK.Common; using CodeProject.AI.SDK.Utils; /* ------------------------------------------------------------------------------------------------- @@ -31,11 +30,11 @@ namespace CodeProject.AI.Server.Mesh /// public class MeshManager { - private readonly MeshMonitor _meshMonitor; - private readonly IOptionsMonitor _meshOptions; - private readonly ServerSettingsJsonWriter _optionsJsonWriter; - private readonly ModuleProcessServices _processServices; - private readonly Task _updateRouteMetricsTask; + private readonly MeshMonitor _meshMonitor; + private readonly IOptionsMonitor _meshOptions; + private readonly ServerSettingsJsonWriter _optionsJsonWriter; + private readonly ModuleProcessServices _processServices; + private readonly Task _updateRouteMetricsTask; private readonly ConcurrentDictionary _routeMetrics = new(StringComparer.OrdinalIgnoreCase); @@ -68,10 +67,10 @@ public class MeshManager /// The Mesh Options Monitor /// Writes the Mesh JSON file. /// The process services. - public MeshManager(MeshMonitor meshMonitor, - IOptionsMonitor monitoredMeshOptions, - ServerSettingsJsonWriter optionsJsonWriter, - ModuleProcessServices processServices) + public MeshManager(MeshMonitor meshMonitor, + IOptionsMonitor monitoredMeshOptions, + ServerSettingsJsonWriter optionsJsonWriter, + ModuleProcessServices processServices) { _meshMonitor = meshMonitor; _meshOptions = monitoredMeshOptions; diff --git a/src/server/Mesh/MeshMonitor.cs b/src/server/Mesh/MeshMonitor.cs index c85a447..66e6c85 100644 --- a/src/server/Mesh/MeshMonitor.cs +++ b/src/server/Mesh/MeshMonitor.cs @@ -15,6 +15,8 @@ using CodeProject.AI.SDK.Utils; using CodeProject.AI.SDK.API; +using CodeProject.AI.Server.Modules; +using CodeProject.AI.SDK.Modules; namespace CodeProject.AI.Server.Mesh { @@ -42,8 +44,7 @@ namespace CodeProject.AI.Server.Mesh /// status class and custom status builder. /// /// The Type of the status data included in the HEARTBEAT message. - public class BaseMeshMonitor - where TStatus: MeshServerBroadcastData, new() + public class MeshMonitor where TStatus: MeshServerBroadcastData, new() { private const string HeartBeatId = "HEARTBEAT"; private const string GoodByeId = "GOODBYE"; @@ -52,10 +53,14 @@ public class BaseMeshMonitor private const char Separator = '|'; private const string HostnameEnvVar = "COMPUTERNAME"; + private readonly JsonSerializerOptions _jsonSerializerOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + // Network clients private UdpClient? _udpClient = null; - private ApiClient? _pingClient = null; - private readonly List _knownServers = new(); // An address of this machine that is connected to the internet. It may not be the only // address, though @@ -64,19 +69,23 @@ public class BaseMeshMonitor // All addresses found on this machine. private readonly List _localIPAddresses = new(); - // dependencies - private readonly IOptionsMonitor _monitoredMeshOptions; private MeshOptions _oldMeshOptions; - private readonly IMeshServerBroadcastBuilder _statusBuilder; - private readonly ILogger> _logger; - private readonly ConcurrentDictionary _discoveredServers = new(); + // dependencies + private readonly IOptionsMonitor _monitoredMeshOptions; + private readonly ModuleProcessServices _processServices; + private readonly ILogger> _logger; - private readonly JsonSerializerOptions _jsonSerializerOptions = new() - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - }; + // Currently running modules + private readonly ModuleCollection _modules; + + // Mesh servers we already know about + private readonly List _knownServers = new(); + // Mesh servers we've discovered + private readonly ConcurrentDictionary _discoveredServers = new(); + + // Process state private CancellationTokenSource? _cancellationTokenSource; private Task? _listenerTask; private Task? _pingServersTask; @@ -129,7 +138,7 @@ public class BaseMeshMonitor /// /// Gets the current mesh status /// - public TStatus MeshStatus => _statusBuilder.Build(this); + public MeshServerBroadcastData MeshStatus => GetMeshServerBroadcastData(); /// /// Gets the IPAddress of the local machine that we know is active. @@ -152,13 +161,15 @@ public class BaseMeshMonitor /// /// Creates a new instance of the BaseMeshMonitor class. /// - public BaseMeshMonitor(IOptionsMonitor meshConfig, - IMeshServerBroadcastBuilder statusBuilder, - ILogger> logger) + public MeshMonitor(IOptionsMonitor meshConfig, + IOptions modules, + ModuleProcessServices processServices, + ILogger> logger) { _monitoredMeshOptions = meshConfig; - _statusBuilder = statusBuilder; _logger = logger!; + _modules = modules.Value; + _processServices = processServices; _oldMeshOptions = meshConfig.CurrentValue; // Get the local address using a UDP socket. This is a better way to get the local @@ -206,6 +217,74 @@ public BaseMeshMonitor(IOptionsMonitor meshConfig, StartMonitoring(); } + /// + /// Build the current node's broadcast package for mesh availability announcements + /// + /// A object + /// + /// REVIEW: This has now served it's purpose and is to be moved as a simple function into + /// MeshMonitor + /// + public MeshServerBroadcastData GetMeshServerBroadcastData() + { + // Get the running modules + IOrderedEnumerable runningModulesIds = _processServices + .ListProcessStatuses() + .Where(p => p.Status == ProcessStatusType.Started) + .Select(p => p.ModuleId) + .Distinct() + .OrderBy(m => m); + IEnumerable runningModules = _modules.Values + .Where(m => runningModulesIds.Contains(m.ModuleId)); + + // Get their routes + List enabledRoutes; + enabledRoutes = runningModules + .SelectMany(m => m.RouteMaps.Where(r => r.MeshEnabled ?? true) + .Select(r => r.Route)) + .Distinct() + .OrderBy(s => s) + .ToList(); + + // Hostnames of known servers in the mesh + var knownHostnames = DiscoveredServers.Values + .Where(s => !s.Status.Hostname.EqualsIgnoreCase(LocalHostname)) + .Select(s => s.Status.Hostname); + + // Description and platform + string systemDescription = $"{SystemInfo.SystemName} ({SystemInfo.OSAndArchitecture})"; + if (SystemInfo.GPU is not null) + { + if (SystemInfo.GPU.HardwareVendor == "Apple" || + SystemInfo.GPU.HardwareVendor == "NVIDIA" || + SystemInfo.GPU.HardwareVendor == "Intel") + { + systemDescription += " " + (SystemInfo.GPU.Name ?? "GPU"); + } + } + + string platform = SystemInfo.Platform; + if (SystemInfo.IsDocker) + platform = "Docker"; + + // For other settings + MeshOptions meshOptions = _monitoredMeshOptions.CurrentValue; + + // Now build. + return new MeshServerBroadcastData + { + Hostname = SystemInfo.MachineName, + SystemDescription = systemDescription, + Platform = platform, + EnabledRoutes = enabledRoutes, + KnownHostnames = knownHostnames, + IsBroadcasting = meshOptions.EnableStatusBroadcast, + IsMonitoring = meshOptions.EnableStatusMonitoring, + AcceptForwardedRequests = meshOptions.AcceptForwardedRequests, + AllowRequestForwarding = meshOptions.AllowRequestForwarding + }; + } + /// /// Starts the service discovery and monitoring process. /// diff --git a/src/server/Mesh/MeshSupportExtensions.cs b/src/server/Mesh/MeshSupportExtensions.cs index c35e233..baa1d55 100644 --- a/src/server/Mesh/MeshSupportExtensions.cs +++ b/src/server/Mesh/MeshSupportExtensions.cs @@ -19,8 +19,7 @@ public static IServiceCollection AddMeshSupport(this IServiceCollection services { services.Configure(configuration.GetSection(nameof(MeshOptions))); - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton>(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/server/Modules/LegacyModuleConfig.cs b/src/server/Modules/LegacyModuleConfig.cs index 658c94a..fd2cf38 100644 --- a/src/server/Modules/LegacyModuleConfig.cs +++ b/src/server/Modules/LegacyModuleConfig.cs @@ -2,8 +2,8 @@ using System.Collections.Generic; using System.Text.Json.Serialization; +using CodeProject.AI.SDK.Client; using CodeProject.AI.SDK.Modules; -using CodeProject.AI.SDK.Server; namespace CodeProject.AI.Server.Modules { diff --git a/src/server/Modules/ModuleCollection.cs b/src/server/Modules/ModuleCollection.cs index e9715bb..08e6298 100644 --- a/src/server/Modules/ModuleCollection.cs +++ b/src/server/Modules/ModuleCollection.cs @@ -13,11 +13,11 @@ using Microsoft.Extensions.Configuration; using CodeProject.AI.SDK.API; +using CodeProject.AI.SDK.Client; using CodeProject.AI.SDK.Common; +using CodeProject.AI.SDK.Modules; using CodeProject.AI.SDK.Utils; using CodeProject.AI.Server.Models; -using CodeProject.AI.SDK.Server; -using CodeProject.AI.SDK.Modules; namespace CodeProject.AI.Server.Modules { @@ -271,7 +271,7 @@ public string? SettingsSummary return null; // Allow the module path to wrap. - // var path = moduleDirPath.Replace("\\", "\\"); + // var path = ModuleDirPath.Replace("\\", "\\"); // path = path.Replace("/", "/"); // or not... diff --git a/src/server/Modules/ModuleProcessServices.cs b/src/server/Modules/ModuleProcessServices.cs index 3aa496f..65230aa 100644 --- a/src/server/Modules/ModuleProcessServices.cs +++ b/src/server/Modules/ModuleProcessServices.cs @@ -15,6 +15,8 @@ using CodeProject.AI.Server.Backend; using CodeProject.AI.Server.Models; using CodeProject.AI.SDK.Modules; +using CodeProject.AI.SDK.Backend; +using CodeProject.AI.SDK.Common; namespace CodeProject.AI.Server.Modules { diff --git a/src/server/Modules/ModuleRunner.cs b/src/server/Modules/ModuleRunner.cs index b1057cc..5f66e61 100644 --- a/src/server/Modules/ModuleRunner.cs +++ b/src/server/Modules/ModuleRunner.cs @@ -52,7 +52,7 @@ public Dictionary? GlobalEnvironmentVariables /// public ModuleProcessServices ProcessService { get; } - private readonly MeshMonitor _meshMonitor; + private readonly MeshMonitor _meshMonitor; /// /// Gets a reference to the ModuleSettings object. @@ -83,7 +83,7 @@ public ModuleRunner(IOptions versionOptions, ModuleSettings moduleSettings, ModuleInstaller moduleInstaller, ModuleProcessServices processService, - MeshMonitor meshMonitor, + MeshMonitor meshMonitor, ILogger logger) { _versionConfig = versionOptions.Value; diff --git a/src/server/Server.csproj b/src/server/Server.csproj index b9c3364..a5f1490 100644 --- a/src/server/Server.csproj +++ b/src/server/Server.csproj @@ -79,9 +79,7 @@ https://learn.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=v - + @@ -103,7 +101,7 @@ https://learn.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=v diff --git a/src/server/version.json b/src/server/version.json index 76a5777..2f11a0a 100644 --- a/src/server/version.json +++ b/src/server/version.json @@ -3,12 +3,12 @@ "versionInfo": { "Major": 2, "Minor": 9, - "Patch": 2, + "Patch": 3, "Build": 0, "PreRelease": "", "SecurityUpdate": false, - "File": "CodeProject.AI-Server-win-x64-2.9.2.zip", - "ReleaseNotes": "Updated to .NET 9, Improvements to installers." + "File": "CodeProject.AI-Server-win-x64-2.9.3.zip", + "ReleaseNotes": "Updated to .NET 9, Improvements to installers, updates to .NET SDK." } } } \ No newline at end of file From 898546cd2ffc8a87f05c49229172d52eaacd99bd Mon Sep 17 00:00:00 2001 From: Chris Maunder Date: Mon, 25 Nov 2024 09:58:50 -0500 Subject: [PATCH 44/71] Corrections to module listings --- src/server/Modules/ModuleCollection.cs | 94 ++++++++++++++------------ src/server/wwwroot/assets/dashboard.js | 14 +++- src/server/wwwroot/assets/server.js | 25 +++++++ src/server/wwwroot/explorer.html | 6 +- src/server/wwwroot/index.html | 6 +- 5 files changed, 92 insertions(+), 53 deletions(-) diff --git a/src/server/Modules/ModuleCollection.cs b/src/server/Modules/ModuleCollection.cs index 08e6298..24f091f 100644 --- a/src/server/Modules/ModuleCollection.cs +++ b/src/server/Modules/ModuleCollection.cs @@ -985,10 +985,11 @@ public async static Task CreateModulesListing(this ModuleCollection module Directory.CreateDirectory(dir); var corrections = new dynamic [] { - new { OldModuleId = "ObjectDetectionNet", NewModuleId = "ObjectDetectionYOLOv5Net" }, - new { OldModuleId = "ObjectDetectionYolo", NewModuleId = "ObjectDetectionYOLOv5-6.2" }, - new { OldModuleId = "Yolov5-3.1", NewModuleId = "ObjectDetectionYOLOv5-3.1" }, - new { OldModuleId = "TrainingYoloV5", NewModuleId = "TrainingObjectDetectionYOLOv5" } + // No longer including renamed versions + // new { OldModuleId = "ObjectDetectionNet", NewModuleId = "ObjectDetectionYOLOv5Net" }, + // new { OldModuleId = "ObjectDetectionYolo", NewModuleId = "ObjectDetectionYOLOv5-6.2" }, + // new { OldModuleId = "Yolov5-3.1", NewModuleId = "ObjectDetectionYOLOv5-3.1" }, + // new { OldModuleId = "TrainingYoloV5", NewModuleId = "TrainingObjectDetectionYOLOv5" } }; var moduleList = modules.Values @@ -1008,54 +1009,57 @@ public async static Task CreateModulesListing(this ModuleCollection module Downloads = 0 }).ToList(); - // Add renamed modules, using their new (current) names, but listing only server revisions v2.4+ - foreach (var pair in corrections) + if (corrections.Length > 0) { - ModuleConfig? module = modules.Values.Where(m => m.ModuleId == pair.NewModuleId).FirstOrDefault(); - if (module is not null) + // Add renamed modules, using their new (current) names, but listing only server revisions v2.4+ + foreach (var pair in corrections) { - ModuleRelease[] post24Releases = module.InstallOptions!.ModuleReleases - .Where(r => string.IsNullOrWhiteSpace(r.ServerVersionRange?[0]) || - VersionInfo.Compare(r.ServerVersionRange[0], "2.4") >= 0) - .ToArray(); - moduleList.Add(new { - ModuleId = module.ModuleId, - Name = module.Name, - Version = module.Version, - PublishingInfo = module.PublishingInfo, - InstallOptions = new { - Platforms = module.InstallOptions.Platforms, - ModuleReleases = post24Releases - }, - Downloads = 0 - }); + ModuleConfig? module = modules.Values.Where(m => m.ModuleId == pair.NewModuleId).FirstOrDefault(); + if (module is not null) + { + ModuleRelease[] post24Releases = module.InstallOptions!.ModuleReleases + .Where(r => string.IsNullOrWhiteSpace(r.ServerVersionRange?[0]) || + VersionInfo.Compare(r.ServerVersionRange[0], "2.4") >= 0) + .ToArray(); + moduleList.Add(new { + ModuleId = module.ModuleId, + Name = module.Name, + Version = module.Version, + PublishingInfo = module.PublishingInfo, + InstallOptions = new { + Platforms = module.InstallOptions.Platforms, + ModuleReleases = post24Releases + }, + Downloads = 0 + }); + } } - } - // Add renamed modules, but with their old names, and only up to server v2.4 - foreach (var pair in corrections) - { - ModuleConfig? module = modules.Values.Where(m => m.ModuleId == pair.NewModuleId).FirstOrDefault(); - if (module is not null) + // Add renamed modules, but with their old names, and only up to server v2.4 + foreach (var pair in corrections) { - ModuleRelease[] pre24Releases = module.InstallOptions!.ModuleReleases - .Where(r => string.IsNullOrWhiteSpace(r.ServerVersionRange?[0]) || - VersionInfo.Compare(r.ServerVersionRange[0], "2.4") < 0) - .ToArray(); - moduleList.Add(new { - ModuleId = (string?)pair.OldModuleId, - Name = module.Name, - Version = module.Version, - PublishingInfo = module.PublishingInfo, - InstallOptions = new { - Platforms = module.InstallOptions.Platforms, - ModuleReleases = pre24Releases - }, - Downloads = 0 - }); + ModuleConfig? module = modules.Values.Where(m => m.ModuleId == pair.NewModuleId).FirstOrDefault(); + if (module is not null) + { + ModuleRelease[] pre24Releases = module.InstallOptions!.ModuleReleases + .Where(r => string.IsNullOrWhiteSpace(r.ServerVersionRange?[0]) || + VersionInfo.Compare(r.ServerVersionRange[0], "2.4") < 0) + .ToArray(); + moduleList.Add(new { + ModuleId = (string?)pair.OldModuleId, + Name = module.Name, + Version = module.Version, + PublishingInfo = module.PublishingInfo, + InstallOptions = new { + Platforms = module.InstallOptions.Platforms, + ModuleReleases = pre24Releases + }, + Downloads = 0 + }); + } } } - + var options = new JsonSerializerOptions { WriteIndented = true }; string configJson = JsonSerializer.Serialize(moduleList, options); diff --git a/src/server/wwwroot/assets/dashboard.js b/src/server/wwwroot/assets/dashboard.js index 42db449..8237c89 100755 --- a/src/server/wwwroot/assets/dashboard.js +++ b/src/server/wwwroot/assets/dashboard.js @@ -841,16 +841,25 @@ async function getDownloadableModules() { let basedOn = moduleInfo.publishingInfo.basedOn || ''; let basedOnUrl = moduleInfo.publishingInfo.basedOnUrl || ''; - let currentlyInstalled = moduleInfo.currentlyInstalled || ''; + let currentlyInstalled = moduleInfo.currentlyInstalled || ''; let latestVersion = moduleInfo.latestCompatibleRelease?.moduleVersion || ''; let latestReleased = moduleInfo.latestCompatibleRelease?.releaseDate || ''; let importance = moduleInfo.latestCompatibleRelease?.importance || ''; let updateAvailable = moduleInfo.updateAvailable; let status = moduleInfo.status; + // With the move from pre-chewed module listing to having to process the raw file, we + // need to be more careful about checking versions (the pre-chewed would take into + // account server version) + updateAvailable = compareVersion(currentVersion, latestVersion) < 0; + let downloadable = moduleInfo.isDownloadable? '' : '
Private
'; + // Show what's available if nothing installed + if (!currentlyInstalled && latestVersion) + currentlyInstalled = `${latestVersion}`; + let updateDesc = ''; if (updateAvailable && currentlyInstalled) { status = 'UpdateAvailable'; @@ -984,7 +993,8 @@ async function getDownloadableModules() { + `
${moduleName}
${downloadable}` + `
` - + `` + + `` + `` diff --git a/src/server/wwwroot/assets/server.js b/src/server/wwwroot/assets/server.js index ab3fdc6..6fe8c05 100644 --- a/src/server/wwwroot/assets/server.js +++ b/src/server/wwwroot/assets/server.js @@ -204,6 +204,31 @@ const copyToClipboard = (elmId) => { }); } +// Returns -1 if version1 < version2, 0 if equal, +1 if version1 > version2 +function compareVersion(version1, version2) { + // Split the version numbers by '.' and convert them into arrays of integers + const v1 = version1.split('.').map(num => parseInt(num, 10)); + const v2 = version2.split('.').map(num => parseInt(num, 10)); + + // Find the length of the longer version to compare all parts + const length = Math.max(v1.length, v2.length); + + // Compare each part of the version numbers + for (let i = 0; i < length; i++) { + const part1 = v1[i] || 0; // Default to 0 if part is missing + const part2 = v2[i] || 0; // Default to 0 if part is missing + + // If part1 is greater than part2, version1 is greater + if (part1 > part2) return 1; + + // If part2 is greater than part1, version2 is greater + if (part1 < part2) return -1; + } + + // If all parts are equal, the versions are the same + return 0; +} + // API operations ============================================================== /** diff --git a/src/server/wwwroot/explorer.html b/src/server/wwwroot/explorer.html index 434f4e9..47d032a 100644 --- a/src/server/wwwroot/explorer.html +++ b/src/server/wwwroot/explorer.html @@ -14,10 +14,10 @@ - + - - + + diff --git a/src/server/wwwroot/index.html b/src/server/wwwroot/index.html index 0d17c84..ad8edae 100644 --- a/src/server/wwwroot/index.html +++ b/src/server/wwwroot/index.html @@ -21,10 +21,10 @@ - + - - + +