From 9aa6be0494f595023360131f0de643d7a0d26331 Mon Sep 17 00:00:00 2001 From: Michael Green <84688932+michael-j-green@users.noreply.github.com> Date: Sun, 22 Feb 2026 21:20:31 +1100 Subject: [PATCH] Move background processes out of process (#693) Introduce the gaseous library and process host projects, enabling out-of-process execution and enhancing task management. Implemented versioning support for AgeGroupMap downloads and improved status reporting for background tasks. Refactored various components for better integration and error handling. Updated configurations for inter-process communication and task initialization. --- .github/scripts/generate_glossary_table.sh | 2 +- .github/scripts/generate_locale_table.sh | 2 +- .github/workflows/language-coverage.yml | 4 +- .github/workflows/update-localisation-doc.yml | 2 +- .vscode/launch.json | 17 + .vscode/tasks.json | 5 +- Gaseous.sln | 64 ++ docs | 2 +- gaseous-cli/gaseous-cli.csproj | 2 +- .../gaseous-configurator.csproj | 2 +- .../Classes/Auth/Classes/IdentityRole.cs | 0 .../Classes/Auth/Classes/IdentityUser.cs | 0 .../Classes/Auth/Classes/RoleStore.cs | 0 .../Classes/Auth/Classes/RoleTable.cs | 0 .../Classes/UserAuthenticatorKeysTable.cs | 0 .../Classes/Auth/Classes/UserClaimsTable.cs | 0 .../Classes/Auth/Classes/UserLoginsTable.cs | 0 .../Auth/Classes/UserRecoveryCodesTable.cs | 0 .../Classes/Auth/Classes/UserRoleTable.cs | 0 .../Classes/Auth/Classes/UserStore.cs | 0 .../Classes/Auth/Classes/UserTable.cs | 0 .../Classes/Auth/Models/AccountViewModels.cs | 0 .../Auth/Models/AddPhoneNumberViewModel.cs | 0 .../Auth/Models/ChangePasswordViewModel.cs | 0 .../Models/DisplayRecoveryCodesViewModel.cs | 0 .../Classes/Auth/Models/IndexViewModel.cs | 0 .../Auth/Models/ManageLoginsViewModel.cs | 0 .../Classes/Auth/Models/ProfileViewModel.cs | 0 .../Auth/Models/RemoveLoginViewModel.cs | 0 .../Auth/Models/SecurityProfileViewModel.cs | 0 .../Classes/Auth/Models/SendCodeViewModel.cs | 0 .../Auth/Models/SetPasswordViewModel.cs | 0 .../Classes/Auth/Models/TwoFactorModels.cs | 0 .../Auth/Models/UseRecoveryCodeViewModel.cs | 0 .../Auth/Models/UserPreferenceViewModels.cs | 0 .../Classes/Auth/Models/UserViewModel.cs | 0 .../VerifyAuthenticatorCodeViewModel.cs | 0 .../Auth/Models/VerifyCodeViewModel.cs | 0 .../Auth/Models/VerifyPhoneNumberViewModel.cs | 0 .../Classes/Bios.cs | 0 .../Classes/CRC32.cs | 0 gaseous-lib/Classes/Collections.cs | 982 ++++++++++++++++++ .../Classes/Common.cs | 0 .../Classes/Config.cs | 61 +- .../Classes/ContentManager.cs | 0 .../Classes/Database/Database.cs | 2 +- .../Classes/Database/DatabaseMigration.cs | 6 +- .../Classes/Database/MemoryCache.cs | 0 .../Classes/Favourites.cs | 0 .../Classes/Filters.cs | 0 .../Classes/GameLibrary.cs | 7 +- .../Classes/HTTPComms.cs | 0 .../Classes/HashObject.cs | 0 .../Classes/ImportGames.cs | 0 .../Classes/Localisation.cs | 6 +- .../Classes/Logging.cs | 0 .../Classes/Maintenance.cs | 0 .../Classes/Metadata/AgeGroups.cs | 3 +- .../Classes/Metadata/AgeRating.cs | 0 .../Classes/Metadata/AgeRatingCategory.cs | 0 .../AgeRatingContentDescriptionsV2.cs | 0 .../Classes/Metadata/AgeRatingOrganization.cs | 0 .../Classes/Metadata/AlternativeNames.cs | 0 .../Classes/Metadata/Artworks.cs | 0 .../Classes/Metadata/ClearLogo.cs | 0 .../Classes/Metadata/Collections.cs | 0 .../Classes/Metadata/Company.cs | 0 .../Classes/Metadata/CompanyLogos.cs | 0 .../Classes/Metadata/Covers.cs | 0 .../Classes/Metadata/ExternalGames.cs | 0 .../Classes/Metadata/Franchises.cs | 0 .../Classes/Metadata/GameLocalisations.cs | 0 .../Classes/Metadata/GameModes.cs | 0 .../Classes/Metadata/GameVideos.cs | 0 .../Classes/Metadata/Games.cs | 0 .../Classes/Metadata/Genres.cs | 0 .../Classes/Metadata/Hasheous.cs | 0 .../Classes/Metadata/Images.cs | 0 .../Classes/Metadata/InvolvedCompany.cs | 0 .../Classes/Metadata/Metadata.cs | 0 .../Classes/Metadata/MultiplayerModes.cs | 0 .../Classes/Metadata/PlatformLogos.cs | 0 .../Classes/Metadata/PlatformVersions.cs | 0 .../Classes/Metadata/Platforms.cs | 0 .../Classes/Metadata/PlayerPerspectives.cs | 0 .../Classes/Metadata/Regions.cs | 0 .../Classes/Metadata/ReleaseDates.cs | 0 .../Classes/Metadata/Screenshots.cs | 0 .../Classes/Metadata/Themes.cs | 0 .../Classes/Metadata/Utility.cs | 0 .../Classes/MetadataManagement.cs | 2 +- .../FileSignatures/Decompression/un7zip.cs | 0 .../FileSignatures/Decompression/unrar.cs | 0 .../FileSignatures/Decompression/unzip.cs | 0 .../Plugins/FileSignatures/FileSignature.cs | 0 .../FileSignaturePlugins/Database.cs | 0 .../FileSignaturePlugins/Hasheous.cs | 0 .../FileSignaturePlugins/InspectFile.cs | 0 .../FileSignatures/IDecompressPlugin.cs | 0 .../FileSignatures/IFileSignaturePlugin.cs | 0 .../Plugins/LogProviders/ConsoleProvider.cs | 0 .../Plugins/LogProviders/DatabaseProvider.cs | 0 .../Plugins/LogProviders/ILogProvider.cs | 0 .../Plugins/LogProviders/TextFileProvider.cs | 0 .../LogProviders/WindowsEventLogProvider.cs | 0 .../MetadataProviders/IMetadataProvider.cs | 0 .../MetadataProviders/IProxyProvider.cs | 0 .../MetadataProviders/MetadataModels.cs | 0 .../MetadataProviderPlugins/IGDBProvider.cs | 0 .../MetadataProviderPlugins/NoneProvider.cs | 0 .../TheGamesDBProvider.cs | 0 .../HasheousIGDBProxyProvider.cs | 0 .../Plugins/MetadataProviders/Storage.cs | 0 .../Classes/Plugins/Plugins.cs | 0 .../ProcessQueue/BackgroundTaskItem.cs | 400 +++++++ .../Classes/ProcessQueue/ITaskPlugin.cs | 3 - .../Classes/ProcessQueue/ProcessQueue.cs | 222 +++- .../Classes/ProcessQueue/QueueItemStatus.cs | 112 ++ .../Classes/ProcessQueue/Tasks.cs | 17 +- .../Tasks/BackgroundDatabaseUpgrade.cs | 0 .../ProcessQueue/Tasks/CollectionCompiler.cs | 2 +- .../ProcessQueue/Tasks/DailyMaintainer.cs | 0 .../Tasks/ImportQueueProcessor.cs | 0 .../Classes/ProcessQueue/Tasks/LibraryScan.cs | 2 +- .../ProcessQueue/Tasks/MediaGroupCompiler.cs | 0 .../ProcessQueue/Tasks/MetadataRefresh.cs | 6 +- .../ProcessQueue/Tasks/OrganiseLibrary.cs | 0 .../ProcessQueue/Tasks/SignatureIngestor.cs | 12 +- .../Classes/ProcessQueue/Tasks/TempCleanup.cs | 0 .../ProcessQueue/Tasks/TitleIngestor.cs | 0 .../ProcessQueue/Tasks/WeeklyMaintainer.cs | 0 .../Classes/ProcessQueue/Timer.cs | 25 +- .../Classes/RomMediaGroup.cs | 0 .../Classes/Roms.cs | 0 .../Classes/SignatureIngestors/XML.cs | 16 +- .../Classes/SignatureManagement.cs | 0 .../Classes/Statistics.cs | 0 gaseous-lib/Classes/SystemInfo.cs | 20 + .../Classes/UserProfile.cs | 0 .../Configuration/ConfigFile_v1.cs | 22 + .../Configuration/Models/Database.cs | 0 .../Configuration/Models/Library.cs | 0 .../Configuration/Models/Logging.cs | 0 .../Configuration/Models/MetadataAPI.cs | 0 .../Configuration/Models/Providers/IGDB.cs | 0 .../Models/Security/ReversProxy.cs | 0 .../Models/Security/SocialAuth.cs | 0 .../Models/ClearLogoItem.cs | 0 .../Models/ContentModel.cs | 0 .../Models/ContentUploadForms.cs | 0 .../Models/GameSave.cs | 0 .../Models/GameState.cs | 0 .../Models/GaseousGame.cs | 0 .../Models/ImageItem.cs | 0 .../Models/ImportState.cs | 0 .../Models/LocaleFileModel.cs | 0 .../Models/LocaleSummaryModel.cs | 0 .../Models/MetadataMap.cs | 0 .../Models/MetadataModel.cs | 0 .../Models/PlatformMapping.cs | 5 +- .../Models/Signatures_Games.cs | 0 .../Models/Signatures_Sources.cs | 0 .../Models/Signatures_Status.cs | 0 .../Models/StatisticsModel.cs | 0 gaseous-lib/Models/SystemInfo.cs | 147 +++ .../Models/UserProfile.cs | 0 .../Support}/AgeGroupMap.json | 0 .../Support/Country.txt | 0 .../Support/Database/MySQL/gaseous-1000.sql | 0 .../Support/Database/MySQL/gaseous-1001.sql | 0 .../Support/Database/MySQL/gaseous-1002.sql | 0 .../Support/Database/MySQL/gaseous-1003.sql | 0 .../Support/Database/MySQL/gaseous-1004.sql | 0 .../Support/Database/MySQL/gaseous-1005.sql | 0 .../Support/Database/MySQL/gaseous-1006.sql | 0 .../Support/Database/MySQL/gaseous-1007.sql | 0 .../Support/Database/MySQL/gaseous-1008.sql | 0 .../Support/Database/MySQL/gaseous-1009.sql | 0 .../Support/Database/MySQL/gaseous-1010.sql | 0 .../Support/Database/MySQL/gaseous-1011.sql | 0 .../Support/Database/MySQL/gaseous-1012.sql | 0 .../Support/Database/MySQL/gaseous-1013.sql | 0 .../Support/Database/MySQL/gaseous-1014.sql | 0 .../Support/Database/MySQL/gaseous-1015.sql | 0 .../Support/Database/MySQL/gaseous-1016.sql | 0 .../Support/Database/MySQL/gaseous-1017.sql | 0 .../Support/Database/MySQL/gaseous-1018.sql | 0 .../Support/Database/MySQL/gaseous-1019.sql | 0 .../Support/Database/MySQL/gaseous-1020.sql | 0 .../Support/Database/MySQL/gaseous-1021.sql | 0 .../Support/Database/MySQL/gaseous-1022.sql | 0 .../Support/Database/MySQL/gaseous-1023.sql | 0 .../Support/Database/MySQL/gaseous-1024.sql | 0 .../Support/Database/MySQL/gaseous-1025.sql | 0 .../Support/Database/MySQL/gaseous-1026.sql | 0 .../Support/Database/MySQL/gaseous-1027.sql | 0 .../Support/Database/MySQL/gaseous-1028.sql | 0 .../Support/Database/MySQL/gaseous-1029.sql | 0 .../Support/Database/MySQL/gaseous-1030.sql | 0 .../Support/Database/MySQL/gaseous-1031.sql | 0 .../Support/Database/MySQL/gaseous-1032.sql | 0 .../Support/Database/MySQL/gaseous-1033.sql | 0 .../Support/Database/MySQL/gaseous-1034.sql | 0 .../Support/Database/MySQL/gaseous-1035.sql | 0 .../Support/Database/MySQL/gaseous-1036.sql | 0 .../Support/Database/MySQL/gaseous-1037.sql | 2 + .../Database/MySQL/gaseous-fix-1005.sql | 0 .../Support/DefaultPlatformLogo.svg | 0 .../Support/Language.txt | 0 .../Support/Localisation/de-AT.json | 0 .../Support/Localisation/de-CH.json | 0 .../Support/Localisation/de-DE.json | 0 .../Support/Localisation/de-LI.json | 0 .../Support/Localisation/de-LU.json | 0 .../Support/Localisation/de.json | 0 .../Support/Localisation/en-AU.json | 0 .../Support/Localisation/en-CA.json | 0 .../Support/Localisation/en-GB.json | 0 .../Support/Localisation/en-HK.json | 0 .../Support/Localisation/en-IE.json | 0 .../Support/Localisation/en-IN.json | 0 .../Support/Localisation/en-NZ.json | 0 .../Support/Localisation/en-SG.json | 0 .../Support/Localisation/en-US.json | 0 .../Support/Localisation/en-ZA.json | 0 .../Support/Localisation/en.json | 0 .../Support/Localisation/es-419.json | 0 .../Support/Localisation/es-AR.json | 0 .../Support/Localisation/es-BO.json | 0 .../Support/Localisation/es-CL.json | 0 .../Support/Localisation/es-CO.json | 0 .../Support/Localisation/es-CR.json | 0 .../Support/Localisation/es-CU.json | 0 .../Support/Localisation/es-DO.json | 0 .../Support/Localisation/es-EC.json | 0 .../Support/Localisation/es-ES.json | 0 .../Support/Localisation/es-GT.json | 0 .../Support/Localisation/es-HN.json | 0 .../Support/Localisation/es-MX.json | 0 .../Support/Localisation/es-NI.json | 0 .../Support/Localisation/es-PA.json | 0 .../Support/Localisation/es-PE.json | 0 .../Support/Localisation/es-PR.json | 0 .../Support/Localisation/es-PY.json | 0 .../Support/Localisation/es-SV.json | 0 .../Support/Localisation/es-UY.json | 0 .../Support/Localisation/es-VE.json | 0 .../Support/Localisation/es.json | 0 .../Support/Localisation/fr-BE.json | 0 .../Support/Localisation/fr-CA.json | 0 .../Support/Localisation/fr-CH.json | 0 .../Support/Localisation/fr-CI.json | 0 .../Support/Localisation/fr-CM.json | 0 .../Support/Localisation/fr-DZ.json | 0 .../Support/Localisation/fr-FR.json | 0 .../Support/Localisation/fr-GF.json | 0 .../Support/Localisation/fr-GP.json | 0 .../Support/Localisation/fr-HT.json | 0 .../Support/Localisation/fr-LU.json | 0 .../Support/Localisation/fr-MA.json | 0 .../Support/Localisation/fr-MC.json | 0 .../Support/Localisation/fr-NC.json | 0 .../Support/Localisation/fr-PF.json | 0 .../Support/Localisation/fr-RE.json | 0 .../Support/Localisation/fr-SN.json | 0 .../Support/Localisation/fr-TN.json | 0 .../Support/Localisation/fr.json | 0 .../Support/Localisation/it-CH.json | 0 .../Support/Localisation/it-IT.json | 0 .../Support/Localisation/it-SM.json | 0 .../Support/Localisation/it-VA.json | 0 .../Support/Localisation/it.json | 0 .../Support/Localisation/ja-JP.json | 0 .../Support/Localisation/ja.json | 0 .../Support/Localisation/ko-KR.json | 0 .../Support/Localisation/ko.json | 0 .../Support/Localisation/nl-BE.json | 0 .../Support/Localisation/nl-NL.json | 0 .../Support/Localisation/nl.json | 0 .../Support/Localisation/pt-AO.json | 0 .../Support/Localisation/pt-BR.json | 0 .../Support/Localisation/pt-CV.json | 0 .../Support/Localisation/pt-GW.json | 0 .../Support/Localisation/pt-MO.json | 0 .../Support/Localisation/pt-MZ.json | 0 .../Support/Localisation/pt-PT.json | 0 .../Support/Localisation/pt-ST.json | 0 .../Support/Localisation/pt.json | 0 .../Support/Localisation/ru-BY.json | 0 .../Support/Localisation/ru-KG.json | 0 .../Support/Localisation/ru-KZ.json | 0 .../Support/Localisation/ru-RU.json | 0 .../Support/Localisation/ru-UA.json | 0 .../Support/Localisation/ru.json | 0 .../Support/Localisation/zh-CN.json | 0 .../Support/Localisation/zh-HK.json | 0 .../Support/Localisation/zh-MO.json | 0 .../Support/Localisation/zh-SG.json | 0 .../Support/Localisation/zh-TW.json | 0 .../Support/Localisation/zh.json | 0 .../Support/PlatformMap.json | 0 gaseous-lib/gaseous-lib.csproj | 82 ++ gaseous-processhost/Classes/CLIHelp.cs | 46 + gaseous-processhost/Program.cs | 109 ++ .../gaseous-processhost.csproj | 15 + gaseous-server/Classes/Collections.cs | 982 ------------------ .../Classes/ProcessQueue/QueueItemStatus.cs | 59 -- .../V1.0/AgeGroupMapsController.cs | 60 ++ .../V1.0/BackgroundTasksController.cs | 153 ++- .../Controllers/V1.0/CollectionsController.cs | 646 ++++++------ .../Controllers/V1.0/PlatformsController.cs | 6 +- .../Controllers/V1.0/SystemController.cs | 544 +--------- .../Controllers/V1.1/FirstSetupController.cs | 3 +- gaseous-server/Program.cs | 25 +- gaseous-server/StartupInitializer.cs | 3 + gaseous-server/gaseous-server.csproj | 91 +- gaseous-server/wwwroot/index.html | 2 +- gaseous-server/wwwroot/scripts/preferences.js | 2 +- 318 files changed, 2947 insertions(+), 2065 deletions(-) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/IdentityRole.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/IdentityUser.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/RoleStore.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/RoleTable.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/UserAuthenticatorKeysTable.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/UserClaimsTable.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/UserLoginsTable.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/UserRecoveryCodesTable.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/UserRoleTable.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/UserStore.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Classes/UserTable.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/AccountViewModels.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/AddPhoneNumberViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/ChangePasswordViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/DisplayRecoveryCodesViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/IndexViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/ManageLoginsViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/ProfileViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/RemoveLoginViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/SecurityProfileViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/SendCodeViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/SetPasswordViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/TwoFactorModels.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/UseRecoveryCodeViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/UserPreferenceViewModels.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/UserViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/VerifyAuthenticatorCodeViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/VerifyCodeViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Auth/Models/VerifyPhoneNumberViewModel.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Bios.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/CRC32.cs (100%) create mode 100644 gaseous-lib/Classes/Collections.cs rename {gaseous-server => gaseous-lib}/Classes/Common.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Config.cs (93%) rename {gaseous-server => gaseous-lib}/Classes/ContentManager.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Database/Database.cs (99%) rename {gaseous-server => gaseous-lib}/Classes/Database/DatabaseMigration.cs (99%) rename {gaseous-server => gaseous-lib}/Classes/Database/MemoryCache.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Favourites.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Filters.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/GameLibrary.cs (97%) rename {gaseous-server => gaseous-lib}/Classes/HTTPComms.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/HashObject.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ImportGames.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Localisation.cs (98%) rename {gaseous-server => gaseous-lib}/Classes/Logging.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Maintenance.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/AgeGroups.cs (98%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/AgeRating.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/AgeRatingCategory.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/AgeRatingContentDescriptionsV2.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/AgeRatingOrganization.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/AlternativeNames.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Artworks.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/ClearLogo.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Collections.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Company.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/CompanyLogos.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Covers.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/ExternalGames.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Franchises.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/GameLocalisations.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/GameModes.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/GameVideos.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Games.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Genres.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Hasheous.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Images.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/InvolvedCompany.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Metadata.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/MultiplayerModes.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/PlatformLogos.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/PlatformVersions.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Platforms.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/PlayerPerspectives.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Regions.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/ReleaseDates.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Screenshots.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Themes.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Metadata/Utility.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/MetadataManagement.cs (99%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/Decompression/un7zip.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/Decompression/unrar.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/Decompression/unzip.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/FileSignature.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/FileSignaturePlugins/Database.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/FileSignaturePlugins/Hasheous.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/FileSignaturePlugins/InspectFile.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/IDecompressPlugin.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/FileSignatures/IFileSignaturePlugin.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/LogProviders/ConsoleProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/LogProviders/DatabaseProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/LogProviders/ILogProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/LogProviders/TextFileProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/LogProviders/WindowsEventLogProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/IMetadataProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/IProxyProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/MetadataModels.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/IGDBProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/NoneProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/TheGamesDBProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/ProxyProviderPlugins/HasheousIGDBProxyProvider.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/MetadataProviders/Storage.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Plugins/Plugins.cs (100%) create mode 100644 gaseous-lib/Classes/ProcessQueue/BackgroundTaskItem.cs rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/ITaskPlugin.cs (96%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/ProcessQueue.cs (74%) create mode 100644 gaseous-lib/Classes/ProcessQueue/QueueItemStatus.cs rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks.cs (93%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/BackgroundDatabaseUpgrade.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/CollectionCompiler.cs (88%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/DailyMaintainer.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/ImportQueueProcessor.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/LibraryScan.cs (94%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/MediaGroupCompiler.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/MetadataRefresh.cs (92%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/OrganiseLibrary.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/SignatureIngestor.cs (79%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/TempCleanup.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/TitleIngestor.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Tasks/WeeklyMaintainer.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/ProcessQueue/Timer.cs (83%) rename {gaseous-server => gaseous-lib}/Classes/RomMediaGroup.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Roms.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/SignatureIngestors/XML.cs (96%) rename {gaseous-server => gaseous-lib}/Classes/SignatureManagement.cs (100%) rename {gaseous-server => gaseous-lib}/Classes/Statistics.cs (100%) create mode 100644 gaseous-lib/Classes/SystemInfo.cs rename {gaseous-server => gaseous-lib}/Classes/UserProfile.cs (100%) rename {gaseous-server => gaseous-lib}/Configuration/ConfigFile_v1.cs (85%) rename {gaseous-server => gaseous-lib}/Configuration/Models/Database.cs (100%) rename {gaseous-server => gaseous-lib}/Configuration/Models/Library.cs (100%) rename {gaseous-server => gaseous-lib}/Configuration/Models/Logging.cs (100%) rename {gaseous-server => gaseous-lib}/Configuration/Models/MetadataAPI.cs (100%) rename {gaseous-server => gaseous-lib}/Configuration/Models/Providers/IGDB.cs (100%) rename {gaseous-server => gaseous-lib}/Configuration/Models/Security/ReversProxy.cs (100%) rename {gaseous-server => gaseous-lib}/Configuration/Models/Security/SocialAuth.cs (100%) rename {gaseous-server => gaseous-lib}/Models/ClearLogoItem.cs (100%) rename {gaseous-server => gaseous-lib}/Models/ContentModel.cs (100%) rename {gaseous-server => gaseous-lib}/Models/ContentUploadForms.cs (100%) rename {gaseous-server => gaseous-lib}/Models/GameSave.cs (100%) rename {gaseous-server => gaseous-lib}/Models/GameState.cs (100%) rename {gaseous-server => gaseous-lib}/Models/GaseousGame.cs (100%) rename {gaseous-server => gaseous-lib}/Models/ImageItem.cs (100%) rename {gaseous-server => gaseous-lib}/Models/ImportState.cs (100%) rename {gaseous-server => gaseous-lib}/Models/LocaleFileModel.cs (100%) rename {gaseous-server => gaseous-lib}/Models/LocaleSummaryModel.cs (100%) rename {gaseous-server => gaseous-lib}/Models/MetadataMap.cs (100%) rename {gaseous-server => gaseous-lib}/Models/MetadataModel.cs (100%) rename {gaseous-server => gaseous-lib}/Models/PlatformMapping.cs (99%) rename {gaseous-server => gaseous-lib}/Models/Signatures_Games.cs (100%) rename {gaseous-server => gaseous-lib}/Models/Signatures_Sources.cs (100%) rename {gaseous-server => gaseous-lib}/Models/Signatures_Status.cs (100%) rename {gaseous-server => gaseous-lib}/Models/StatisticsModel.cs (100%) create mode 100644 gaseous-lib/Models/SystemInfo.cs rename {gaseous-server => gaseous-lib}/Models/UserProfile.cs (100%) rename {gaseous-server/wwwroot/images/Ratings => gaseous-lib/Support}/AgeGroupMap.json (100%) rename {gaseous-server => gaseous-lib}/Support/Country.txt (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1000.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1001.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1002.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1003.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1004.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1005.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1006.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1007.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1008.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1009.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1010.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1011.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1012.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1013.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1014.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1015.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1016.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1017.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1018.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1019.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1020.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1021.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1022.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1023.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1024.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1025.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1026.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1027.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1028.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1029.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1030.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1031.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1032.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1033.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1034.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1035.sql (100%) rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-1036.sql (100%) create mode 100644 gaseous-lib/Support/Database/MySQL/gaseous-1037.sql rename {gaseous-server => gaseous-lib}/Support/Database/MySQL/gaseous-fix-1005.sql (100%) rename {gaseous-server => gaseous-lib}/Support/DefaultPlatformLogo.svg (100%) rename {gaseous-server => gaseous-lib}/Support/Language.txt (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/de-AT.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/de-CH.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/de-DE.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/de-LI.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/de-LU.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/de.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-AU.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-CA.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-GB.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-HK.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-IE.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-IN.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-NZ.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-SG.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-US.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en-ZA.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/en.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-419.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-AR.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-BO.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-CL.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-CO.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-CR.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-CU.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-DO.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-EC.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-ES.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-GT.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-HN.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-MX.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-NI.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-PA.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-PE.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-PR.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-PY.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-SV.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-UY.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es-VE.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/es.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-BE.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-CA.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-CH.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-CI.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-CM.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-DZ.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-FR.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-GF.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-GP.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-HT.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-LU.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-MA.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-MC.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-NC.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-PF.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-RE.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-SN.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr-TN.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/fr.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/it-CH.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/it-IT.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/it-SM.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/it-VA.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/it.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ja-JP.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ja.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ko-KR.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ko.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/nl-BE.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/nl-NL.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/nl.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-AO.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-BR.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-CV.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-GW.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-MO.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-MZ.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-PT.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt-ST.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/pt.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ru-BY.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ru-KG.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ru-KZ.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ru-RU.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ru-UA.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/ru.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/zh-CN.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/zh-HK.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/zh-MO.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/zh-SG.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/zh-TW.json (100%) rename {gaseous-server => gaseous-lib}/Support/Localisation/zh.json (100%) rename {gaseous-server => gaseous-lib}/Support/PlatformMap.json (100%) create mode 100644 gaseous-lib/gaseous-lib.csproj create mode 100644 gaseous-processhost/Classes/CLIHelp.cs create mode 100644 gaseous-processhost/Program.cs create mode 100644 gaseous-processhost/gaseous-processhost.csproj delete mode 100644 gaseous-server/Classes/Collections.cs delete mode 100644 gaseous-server/Classes/ProcessQueue/QueueItemStatus.cs create mode 100644 gaseous-server/Controllers/V1.0/AgeGroupMapsController.cs diff --git a/.github/scripts/generate_glossary_table.sh b/.github/scripts/generate_glossary_table.sh index 2b8fae5..efd664c 100644 --- a/.github/scripts/generate_glossary_table.sh +++ b/.github/scripts/generate_glossary_table.sh @@ -7,7 +7,7 @@ set -euo pipefail # Falls back to hard-coded mapping if specific concept not represented as a direct key. GLOSSARY_FILE="docs/Localisation-Glossary.md" -LOCALE_DIR="gaseous-server/Support/Localisation" +LOCALE_DIR="gaseous-lib/Support/Localisation" START_MARKER="" END_MARKER="" diff --git a/.github/scripts/generate_locale_table.sh b/.github/scripts/generate_locale_table.sh index 0f19eba..1b92476 100644 --- a/.github/scripts/generate_locale_table.sh +++ b/.github/scripts/generate_locale_table.sh @@ -6,7 +6,7 @@ set -euo pipefail # Requires: jq DOC_FILE="docs/Localisation.md" -LOCALE_DIR="gaseous-server/Support/Localisation" +LOCALE_DIR="gaseous-lib/Support/Localisation" START_MARKER="" END_MARKER="" diff --git a/.github/workflows/language-coverage.yml b/.github/workflows/language-coverage.yml index 98993c8..0afcc7c 100644 --- a/.github/workflows/language-coverage.yml +++ b/.github/workflows/language-coverage.yml @@ -7,7 +7,7 @@ permissions: on: pull_request: paths: - - 'gaseous-server/Support/Localisation/*.json' + - 'gaseous-lib/Support/Localisation/*.json' - '.github/workflows/language-coverage.yml' jobs: @@ -29,7 +29,7 @@ jobs: const fs = require('fs'); const path = require('path'); - const locDir = path.join(process.env.GITHUB_WORKSPACE, 'gaseous-server/Support/Localisation'); + const locDir = path.join(process.env.GITHUB_WORKSPACE, 'gaseous-lib/Support/Localisation'); const enPath = path.join(locDir, 'en.json'); const en = JSON.parse(fs.readFileSync(enPath, 'utf8')); const enStrings = Object.keys(en.strings || {}); diff --git a/.github/workflows/update-localisation-doc.yml b/.github/workflows/update-localisation-doc.yml index 746e0ec..15e4278 100644 --- a/.github/workflows/update-localisation-doc.yml +++ b/.github/workflows/update-localisation-doc.yml @@ -5,7 +5,7 @@ on: branches-ignore: - main paths: - - 'gaseous-server/Support/Localisation/*.json' + - 'gaseous-lib/Support/Localisation/*.json' - 'docs/Localisation.md' - 'docs/Localisation-Glossary.md' - '.github/scripts/generate_locale_table.sh' diff --git a/.vscode/launch.json b/.vscode/launch.json index f418354..2c85382 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -70,6 +70,23 @@ "name": ".NET Core Attach", "type": "coreclr", "request": "attach" + }, + { + "name": "Process Host", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "full-rebuild", + "program": "${workspaceFolder}/gaseous-processhost/bin/Debug/net10.0/gaseous-processhost.dll", + "args": [ + "--service", + "SignatureIngestor", + "--reportingserver", + "https://localhost:5197", + "--correlationid", + "00000000-0000-0000-0000-000000000000" + ], + "cwd": "${workspaceFolder}/gaseous-processhost", + "stopAtEntry": false } ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9ae35fc..88e1655 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -17,7 +17,7 @@ "type": "process", "args": [ "clean", - "${workspaceFolder}/gaseous-server/gaseous-server.csproj", + "${workspaceFolder}/Gaseous.sln", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -49,7 +49,8 @@ "type": "process", "args": [ "build", - "${workspaceFolder}/gaseous-server/gaseous-server.csproj", + "${workspaceFolder}/Gaseous.sln", + "/t:Rebuild", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], diff --git a/Gaseous.sln b/Gaseous.sln index 782d162..4c326f8 100644 --- a/Gaseous.sln +++ b/Gaseous.sln @@ -27,28 +27,92 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "gaseous-configurator", "gas EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-server.Tests", "gaseous-server.Tests\gaseous-server.Tests.csproj", "{A476D629-DC6F-4C78-9084-8F910429AFB3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-processhost", "gaseous-processhost\gaseous-processhost.csproj", "{CFCDA316-2CBA-497D-87AC-EFB86E2705AE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-lib", "gaseous-lib\gaseous-lib.csproj", "{E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|x64.ActiveCfg = Debug|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|x64.Build.0 = Debug|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|x86.ActiveCfg = Debug|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|x86.Build.0 = Debug|Any CPU {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.ActiveCfg = Release|Any CPU {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.Build.0 = Release|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|x64.ActiveCfg = Release|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|x64.Build.0 = Release|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|x86.ActiveCfg = Release|Any CPU + {A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|x86.Build.0 = Release|Any CPU {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|Any CPU.Build.0 = Debug|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|x64.ActiveCfg = Debug|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|x64.Build.0 = Debug|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|x86.ActiveCfg = Debug|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|x86.Build.0 = Debug|Any CPU {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|Any CPU.ActiveCfg = Release|Any CPU {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|Any CPU.Build.0 = Release|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|x64.ActiveCfg = Release|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|x64.Build.0 = Release|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|x86.ActiveCfg = Release|Any CPU + {419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|x86.Build.0 = Release|Any CPU {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Debug|x64.ActiveCfg = Debug|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Debug|x64.Build.0 = Debug|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Debug|x86.ActiveCfg = Debug|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Debug|x86.Build.0 = Debug|Any CPU {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Release|Any CPU.ActiveCfg = Release|Any CPU {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Release|Any CPU.Build.0 = Release|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Release|x64.ActiveCfg = Release|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Release|x64.Build.0 = Release|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Release|x86.ActiveCfg = Release|Any CPU + {C6A3A0D2-76AA-4C14-9A7B-7A8E6D7C9A11}.Release|x86.Build.0 = Release|Any CPU {A476D629-DC6F-4C78-9084-8F910429AFB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A476D629-DC6F-4C78-9084-8F910429AFB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Debug|x64.ActiveCfg = Debug|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Debug|x64.Build.0 = Debug|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Debug|x86.ActiveCfg = Debug|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Debug|x86.Build.0 = Debug|Any CPU {A476D629-DC6F-4C78-9084-8F910429AFB3}.Release|Any CPU.ActiveCfg = Release|Any CPU {A476D629-DC6F-4C78-9084-8F910429AFB3}.Release|Any CPU.Build.0 = Release|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Release|x64.ActiveCfg = Release|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Release|x64.Build.0 = Release|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Release|x86.ActiveCfg = Release|Any CPU + {A476D629-DC6F-4C78-9084-8F910429AFB3}.Release|x86.Build.0 = Release|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Debug|x64.ActiveCfg = Debug|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Debug|x64.Build.0 = Debug|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Debug|x86.ActiveCfg = Debug|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Debug|x86.Build.0 = Debug|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Release|Any CPU.Build.0 = Release|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Release|x64.ActiveCfg = Release|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Release|x64.Build.0 = Release|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Release|x86.ActiveCfg = Release|Any CPU + {CFCDA316-2CBA-497D-87AC-EFB86E2705AE}.Release|x86.Build.0 = Release|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Debug|x64.ActiveCfg = Debug|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Debug|x64.Build.0 = Debug|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Debug|x86.ActiveCfg = Debug|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Debug|x86.Build.0 = Debug|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Release|Any CPU.Build.0 = Release|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Release|x64.ActiveCfg = Release|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Release|x64.Build.0 = Release|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Release|x86.ActiveCfg = Release|Any CPU + {E6B7DDA6-BD74-436D-BAC5-8E42D1AC6E2F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/docs b/docs index f7962c2..82d1a8b 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit f7962c29b6e0cfc12e915e01eb57bca8728be900 +Subproject commit 82d1a8b9394c8fd68ea0d7c7567aa340be34926d diff --git a/gaseous-cli/gaseous-cli.csproj b/gaseous-cli/gaseous-cli.csproj index 0fdca1b..efa8a4a 100644 --- a/gaseous-cli/gaseous-cli.csproj +++ b/gaseous-cli/gaseous-cli.csproj @@ -24,6 +24,6 @@ - + diff --git a/gaseous-configurator/gaseous-configurator.csproj b/gaseous-configurator/gaseous-configurator.csproj index 1a87cc3..1fee9c6 100644 --- a/gaseous-configurator/gaseous-configurator.csproj +++ b/gaseous-configurator/gaseous-configurator.csproj @@ -11,6 +11,6 @@ win-x64;win-arm64 - + diff --git a/gaseous-server/Classes/Auth/Classes/IdentityRole.cs b/gaseous-lib/Classes/Auth/Classes/IdentityRole.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/IdentityRole.cs rename to gaseous-lib/Classes/Auth/Classes/IdentityRole.cs diff --git a/gaseous-server/Classes/Auth/Classes/IdentityUser.cs b/gaseous-lib/Classes/Auth/Classes/IdentityUser.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/IdentityUser.cs rename to gaseous-lib/Classes/Auth/Classes/IdentityUser.cs diff --git a/gaseous-server/Classes/Auth/Classes/RoleStore.cs b/gaseous-lib/Classes/Auth/Classes/RoleStore.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/RoleStore.cs rename to gaseous-lib/Classes/Auth/Classes/RoleStore.cs diff --git a/gaseous-server/Classes/Auth/Classes/RoleTable.cs b/gaseous-lib/Classes/Auth/Classes/RoleTable.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/RoleTable.cs rename to gaseous-lib/Classes/Auth/Classes/RoleTable.cs diff --git a/gaseous-server/Classes/Auth/Classes/UserAuthenticatorKeysTable.cs b/gaseous-lib/Classes/Auth/Classes/UserAuthenticatorKeysTable.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/UserAuthenticatorKeysTable.cs rename to gaseous-lib/Classes/Auth/Classes/UserAuthenticatorKeysTable.cs diff --git a/gaseous-server/Classes/Auth/Classes/UserClaimsTable.cs b/gaseous-lib/Classes/Auth/Classes/UserClaimsTable.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/UserClaimsTable.cs rename to gaseous-lib/Classes/Auth/Classes/UserClaimsTable.cs diff --git a/gaseous-server/Classes/Auth/Classes/UserLoginsTable.cs b/gaseous-lib/Classes/Auth/Classes/UserLoginsTable.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/UserLoginsTable.cs rename to gaseous-lib/Classes/Auth/Classes/UserLoginsTable.cs diff --git a/gaseous-server/Classes/Auth/Classes/UserRecoveryCodesTable.cs b/gaseous-lib/Classes/Auth/Classes/UserRecoveryCodesTable.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/UserRecoveryCodesTable.cs rename to gaseous-lib/Classes/Auth/Classes/UserRecoveryCodesTable.cs diff --git a/gaseous-server/Classes/Auth/Classes/UserRoleTable.cs b/gaseous-lib/Classes/Auth/Classes/UserRoleTable.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/UserRoleTable.cs rename to gaseous-lib/Classes/Auth/Classes/UserRoleTable.cs diff --git a/gaseous-server/Classes/Auth/Classes/UserStore.cs b/gaseous-lib/Classes/Auth/Classes/UserStore.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/UserStore.cs rename to gaseous-lib/Classes/Auth/Classes/UserStore.cs diff --git a/gaseous-server/Classes/Auth/Classes/UserTable.cs b/gaseous-lib/Classes/Auth/Classes/UserTable.cs similarity index 100% rename from gaseous-server/Classes/Auth/Classes/UserTable.cs rename to gaseous-lib/Classes/Auth/Classes/UserTable.cs diff --git a/gaseous-server/Classes/Auth/Models/AccountViewModels.cs b/gaseous-lib/Classes/Auth/Models/AccountViewModels.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/AccountViewModels.cs rename to gaseous-lib/Classes/Auth/Models/AccountViewModels.cs diff --git a/gaseous-server/Classes/Auth/Models/AddPhoneNumberViewModel.cs b/gaseous-lib/Classes/Auth/Models/AddPhoneNumberViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/AddPhoneNumberViewModel.cs rename to gaseous-lib/Classes/Auth/Models/AddPhoneNumberViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/ChangePasswordViewModel.cs b/gaseous-lib/Classes/Auth/Models/ChangePasswordViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/ChangePasswordViewModel.cs rename to gaseous-lib/Classes/Auth/Models/ChangePasswordViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/DisplayRecoveryCodesViewModel.cs b/gaseous-lib/Classes/Auth/Models/DisplayRecoveryCodesViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/DisplayRecoveryCodesViewModel.cs rename to gaseous-lib/Classes/Auth/Models/DisplayRecoveryCodesViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/IndexViewModel.cs b/gaseous-lib/Classes/Auth/Models/IndexViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/IndexViewModel.cs rename to gaseous-lib/Classes/Auth/Models/IndexViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/ManageLoginsViewModel.cs b/gaseous-lib/Classes/Auth/Models/ManageLoginsViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/ManageLoginsViewModel.cs rename to gaseous-lib/Classes/Auth/Models/ManageLoginsViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/ProfileViewModel.cs b/gaseous-lib/Classes/Auth/Models/ProfileViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/ProfileViewModel.cs rename to gaseous-lib/Classes/Auth/Models/ProfileViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/RemoveLoginViewModel.cs b/gaseous-lib/Classes/Auth/Models/RemoveLoginViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/RemoveLoginViewModel.cs rename to gaseous-lib/Classes/Auth/Models/RemoveLoginViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/SecurityProfileViewModel.cs b/gaseous-lib/Classes/Auth/Models/SecurityProfileViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/SecurityProfileViewModel.cs rename to gaseous-lib/Classes/Auth/Models/SecurityProfileViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/SendCodeViewModel.cs b/gaseous-lib/Classes/Auth/Models/SendCodeViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/SendCodeViewModel.cs rename to gaseous-lib/Classes/Auth/Models/SendCodeViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/SetPasswordViewModel.cs b/gaseous-lib/Classes/Auth/Models/SetPasswordViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/SetPasswordViewModel.cs rename to gaseous-lib/Classes/Auth/Models/SetPasswordViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/TwoFactorModels.cs b/gaseous-lib/Classes/Auth/Models/TwoFactorModels.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/TwoFactorModels.cs rename to gaseous-lib/Classes/Auth/Models/TwoFactorModels.cs diff --git a/gaseous-server/Classes/Auth/Models/UseRecoveryCodeViewModel.cs b/gaseous-lib/Classes/Auth/Models/UseRecoveryCodeViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/UseRecoveryCodeViewModel.cs rename to gaseous-lib/Classes/Auth/Models/UseRecoveryCodeViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/UserPreferenceViewModels.cs b/gaseous-lib/Classes/Auth/Models/UserPreferenceViewModels.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/UserPreferenceViewModels.cs rename to gaseous-lib/Classes/Auth/Models/UserPreferenceViewModels.cs diff --git a/gaseous-server/Classes/Auth/Models/UserViewModel.cs b/gaseous-lib/Classes/Auth/Models/UserViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/UserViewModel.cs rename to gaseous-lib/Classes/Auth/Models/UserViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/VerifyAuthenticatorCodeViewModel.cs b/gaseous-lib/Classes/Auth/Models/VerifyAuthenticatorCodeViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/VerifyAuthenticatorCodeViewModel.cs rename to gaseous-lib/Classes/Auth/Models/VerifyAuthenticatorCodeViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/VerifyCodeViewModel.cs b/gaseous-lib/Classes/Auth/Models/VerifyCodeViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/VerifyCodeViewModel.cs rename to gaseous-lib/Classes/Auth/Models/VerifyCodeViewModel.cs diff --git a/gaseous-server/Classes/Auth/Models/VerifyPhoneNumberViewModel.cs b/gaseous-lib/Classes/Auth/Models/VerifyPhoneNumberViewModel.cs similarity index 100% rename from gaseous-server/Classes/Auth/Models/VerifyPhoneNumberViewModel.cs rename to gaseous-lib/Classes/Auth/Models/VerifyPhoneNumberViewModel.cs diff --git a/gaseous-server/Classes/Bios.cs b/gaseous-lib/Classes/Bios.cs similarity index 100% rename from gaseous-server/Classes/Bios.cs rename to gaseous-lib/Classes/Bios.cs diff --git a/gaseous-server/Classes/CRC32.cs b/gaseous-lib/Classes/CRC32.cs similarity index 100% rename from gaseous-server/Classes/CRC32.cs rename to gaseous-lib/Classes/CRC32.cs diff --git a/gaseous-lib/Classes/Collections.cs b/gaseous-lib/Classes/Collections.cs new file mode 100644 index 0000000..a6894ee --- /dev/null +++ b/gaseous-lib/Classes/Collections.cs @@ -0,0 +1,982 @@ +// using System; +// using System.Data; +// using System.IO.Compression; +// using System.Reflection; +// using System.Runtime.InteropServices; +// using System.Security.Cryptography; +// using Authentication; +// using gaseous_server.Classes.Metadata; +// using gaseous_server.Controllers; +// using gaseous_server.Controllers.v1_1; +// using gaseous_server.Models; +// using gaseous_server.Classes.Plugins.MetadataProviders.MetadataTypes; +// using Microsoft.AspNetCore.Identity; +// using Microsoft.AspNetCore.Mvc.Filters; +// using Newtonsoft.Json; +// using SharpCompress.Common; +// using static gaseous_server.Classes.Metadata.Games; + +// namespace gaseous_server.Classes +// { +// public class Collections +// { +// public static List GetCollections(string userid) +// { +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); +// string sql = "SELECT * FROM RomCollections WHERE OwnedBy=@ownedby ORDER BY `Name`"; +// Dictionary dbDict = new Dictionary{ +// { "ownedby", userid } +// }; +// DataTable data = db.ExecuteCMD(sql, dbDict); + +// List collectionItems = new List(); + +// foreach (DataRow row in data.Rows) +// { +// collectionItems.Add(BuildCollectionItem(row)); +// } + +// return collectionItems; +// } + +// public static CollectionItem GetCollection(long Id, string userid) +// { +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); +// string sql; +// if (userid == "") +// { +// // reserved for internal operations +// sql = "SELECT * FROM RomCollections WHERE Id = @id ORDER BY `Name`"; +// } +// else +// { +// // instigated by a user +// sql = "SELECT * FROM RomCollections WHERE Id = @id AND OwnedBy = @ownedby ORDER BY `Name`"; +// } +// Dictionary dbDict = new Dictionary +// { +// { "id", Id }, +// { "ownedby", userid } +// }; +// DataTable romDT = db.ExecuteCMD(sql, dbDict); + +// if (romDT.Rows.Count > 0) +// { +// DataRow row = romDT.Rows[0]; +// CollectionItem collectionItem = BuildCollectionItem(row); + +// return collectionItem; +// } +// else +// { +// throw new Exception("Unknown Collection Id"); +// } +// } + +// public static CollectionItem NewCollection(CollectionItem item, string userid) +// { +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); +// string sql = "INSERT INTO RomCollections (`Name`, Description, Platforms, Genres, Players, PlayerPerspectives, Themes, MinimumRating, MaximumRating, MaximumRomsPerPlatform, MaximumBytesPerPlatform, MaximumCollectionSizeInBytes, FolderStructure, IncludeBIOSFiles, ArchiveType, AlwaysInclude, BuiltStatus, OwnedBy) VALUES (@name, @description, @platforms, @genres, @players, @playerperspectives, @themes, @minimumrating, @maximumrating, @maximumromsperplatform, @maximumbytesperplatform, @maximumcollectionsizeinbytes, @folderstructure, @includebiosfiles, @archivetype, @alwaysinclude, @builtstatus, @ownedby); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; +// Dictionary dbDict = new Dictionary +// { +// { "name", item.Name }, +// { "description", item.Description }, +// { "platforms", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Platforms, new List())) }, +// { "genres", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Genres, new List())) }, +// { "players", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Players, new List())) }, +// { "playerperspectives", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.PlayerPerspectives, new List())) }, +// { "themes", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Themes, new List())) }, +// { "minimumrating", Common.ReturnValueIfNull(item.MinimumRating, -1) }, +// { "maximumrating", Common.ReturnValueIfNull(item.MaximumRating, -1) }, +// { "maximumromsperplatform", Common.ReturnValueIfNull(item.MaximumRomsPerPlatform, -1) }, +// { "maximumbytesperplatform", Common.ReturnValueIfNull(item.MaximumBytesPerPlatform, -1) }, +// { "maximumcollectionsizeinbytes", Common.ReturnValueIfNull(item.MaximumCollectionSizeInBytes, -1) }, +// { "folderstructure", Common.ReturnValueIfNull(item.FolderStructure, CollectionItem.FolderStructures.Gaseous) }, +// { "includebiosfiles", Common.ReturnValueIfNull(item.IncludeBIOSFiles, 0) }, +// { "archivetype", Common.ReturnValueIfNull(item.ArchiveType, CollectionItem.ArchiveTypes.Zip) }, +// { "alwaysinclude", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.AlwaysInclude, new List())) }, +// { "builtstatus", CollectionItem.CollectionBuildStatus.WaitingForBuild }, +// { "ownedby", userid } +// }; +// DataTable romDT = db.ExecuteCMD(sql, dbDict); +// long CollectionId = (long)romDT.Rows[0][0]; + +// CollectionItem collectionItem = GetCollection(CollectionId, userid); + +// StartCollectionItemBuild(CollectionId, userid); + +// return collectionItem; +// } + +// public static CollectionItem EditCollection(long Id, CollectionItem item, string userid, bool ForceRebuild = true) +// { +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); +// string sql = "UPDATE RomCollections SET `Name`=@name, Description=@description, Platforms=@platforms, Genres=@genres, Players=@players, PlayerPerspectives=@playerperspectives, Themes=@themes, MinimumRating=@minimumrating, MaximumRating=@maximumrating, MaximumRomsPerPlatform=@maximumromsperplatform, MaximumBytesPerPlatform=@maximumbytesperplatform, MaximumCollectionSizeInBytes=@maximumcollectionsizeinbytes, FolderStructure=@folderstructure, IncludeBIOSFiles=@includebiosfiles, ArchiveType=@archivetype, AlwaysInclude=@alwaysinclude, BuiltStatus=@builtstatus WHERE Id=@id AND OwnedBy=@ownedby"; +// Dictionary dbDict = new Dictionary +// { +// { "id", Id }, +// { "name", item.Name }, +// { "description", item.Description }, +// { "platforms", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Platforms, new List())) }, +// { "genres", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Genres, new List())) }, +// { "players", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Players, new List())) }, +// { "playerperspectives", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.PlayerPerspectives, new List())) }, +// { "themes", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Themes, new List())) }, +// { "minimumrating", Common.ReturnValueIfNull(item.MinimumRating, -1) }, +// { "maximumrating", Common.ReturnValueIfNull(item.MaximumRating, -1) }, +// { "maximumromsperplatform", Common.ReturnValueIfNull(item.MaximumRomsPerPlatform, -1) }, +// { "maximumbytesperplatform", Common.ReturnValueIfNull(item.MaximumBytesPerPlatform, -1) }, +// { "maximumcollectionsizeinbytes", Common.ReturnValueIfNull(item.MaximumCollectionSizeInBytes, -1) }, +// { "folderstructure", Common.ReturnValueIfNull(item.FolderStructure, CollectionItem.FolderStructures.Gaseous) }, +// { "includebiosfiles", Common.ReturnValueIfNull(item.IncludeBIOSFiles, 0) }, +// { "alwaysinclude", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.AlwaysInclude, new List())) }, +// { "archivetype", Common.ReturnValueIfNull(item.ArchiveType, CollectionItem.ArchiveTypes.Zip) }, +// { "ownedby", userid } +// }; + +// string CollectionZipFile = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + item.ArchiveExtension); +// if (ForceRebuild == true) +// { +// dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.WaitingForBuild); +// if (File.Exists(CollectionZipFile)) +// { +// Logging.LogKey(Logging.LogType.Warning, "process.collections", "collections.deleting_existing_build", null, new string[] { item.Name }); +// File.Delete(CollectionZipFile); +// } +// } +// else +// { +// if (File.Exists(CollectionZipFile)) +// { +// dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.Completed); +// } +// else +// { +// dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.NoStatus); +// } +// } +// db.ExecuteCMD(sql, dbDict); + +// CollectionItem collectionItem = GetCollection(Id, userid); + +// if (collectionItem.BuildStatus == CollectionItem.CollectionBuildStatus.WaitingForBuild) +// { +// StartCollectionItemBuild(Id, userid); +// } + +// return collectionItem; +// } + +// public static void DeleteCollection(long Id, string userid) +// { +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); +// string sql = "DELETE FROM RomCollections WHERE Id=@id AND OwnedBy=@ownedby"; +// Dictionary dbDict = new Dictionary +// { +// { "id", Id }, +// { "ownedby", userid } +// }; +// db.ExecuteCMD(sql, dbDict); + +// string CollectionZipFile = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ".zip"); +// if (File.Exists(CollectionZipFile)) +// { +// File.Delete(CollectionZipFile); +// } +// } + +// public static void StartCollectionItemBuild(long Id, string userid) +// { +// // send blank user id to getcollection as this is not a user initiated process +// CollectionItem collectionItem = GetCollection(Id, userid); + +// if (collectionItem.BuildStatus != CollectionItem.CollectionBuildStatus.Building) +// { +// // set collection item to waitingforbuild +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); +// string sql = "UPDATE RomCollections SET BuiltStatus=@bs WHERE Id=@id"; +// Dictionary dbDict = new Dictionary(); +// dbDict.Add("id", Id); +// dbDict.Add("bs", CollectionItem.CollectionBuildStatus.WaitingForBuild); +// db.ExecuteCMD(sql, dbDict); + +// // start background task +// ProcessQueue.QueueProcessor.QueueItem queueItem = new ProcessQueue.QueueProcessor.QueueItem(ProcessQueue.QueueItemType.CollectionCompiler, 1, false, true); +// queueItem.Options = new Dictionary{ +// { "Id", Id }, +// { "UserId", userid } +// }; +// queueItem.ForceExecute(); +// ProcessQueue.QueueProcessor.QueueItems.Add(queueItem); +// } +// } + +// public static CollectionContents GetCollectionContent(CollectionItem collectionItem, string userid) +// { +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); + +// // get age ratings for specified user +// List UserAgeGroupings = new List(); +// bool UserAgeGroupIncludeUnrated = true; +// ApplicationUser? user = null; +// if (userid != "") +// { +// Authentication.UserTable userTable = new UserTable(db); +// user = userTable.GetUserById(userid); + +// if (user.SecurityProfile.AgeRestrictionPolicy.IncludeUnrated == false) +// { +// UserAgeGroupIncludeUnrated = false; +// } + +// foreach (AgeGroups.AgeRestrictionGroupings ageGrouping in Enum.GetValues(typeof(AgeGroups.AgeRestrictionGroupings))) +// { +// if (ageGrouping <= user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction && ageGrouping != AgeGroups.AgeRestrictionGroupings.Unclassified) +// { +// UserAgeGroupings.Add(ageGrouping); +// } +// } +// } + +// List collectionPlatformItems = new List(); + +// // get platforms +// List platformids = new List(); +// platformids.AddRange(collectionItem.Platforms); + +// List? DynamicPlatforms = new List(); +// DynamicPlatforms.AddRange(collectionItem.Platforms); + +// List platforms = new List(); + +// // add platforms with an inclusion status +// foreach (CollectionItem.AlwaysIncludeItem alwaysIncludeItem in collectionItem.AlwaysInclude) +// { +// if ( +// alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude || +// alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude +// ) +// { +// if (!platformids.Contains(alwaysIncludeItem.PlatformId)) +// { +// platformids.Add(alwaysIncludeItem.PlatformId); +// } +// } +// } + +// // add dynamic platforms +// if (DynamicPlatforms.Count > 0) +// { +// foreach (long PlatformId in platformids) +// { +// platforms.Add(Platforms.GetPlatform(PlatformId).Result); +// } +// } +// else +// { +// // get all platforms to pull from +// Dictionary> FilterDict = Filters.Filter(AgeGroups.AgeRestrictionGroupings.Adult, true).Result; +// List filteredPlatforms = (List)FilterDict["platforms"]; +// foreach (Filters.FilterItem filterItem in filteredPlatforms) +// { +// platforms.Add(Platforms.GetPlatform((long)filterItem.Id).Result); +// } +// } + +// // age ratings +// AgeGroups.AgeRestrictionGroupings AgeGrouping = AgeGroups.AgeRestrictionGroupings.Unclassified; +// bool ContainsUnclassifiedAgeGroup = false; + +// // build collection +// List platformItems = new List(); + +// foreach (Platform platform in platforms) +// { +// long TotalRomSize = 0; +// long TotalGameCount = 0; + +// bool isDynamic = false; +// if (DynamicPlatforms.Contains((long)platform.Id)) +// { +// isDynamic = true; +// } +// else if (DynamicPlatforms.Count == 0) +// { +// isDynamic = true; +// } + +// Controllers.v1_1.GamesController.GameReturnPackage games = new Controllers.v1_1.GamesController.GameReturnPackage(); +// if (isDynamic == true) +// { +// Controllers.v1_1.GamesController.GameSearchModel searchModel = new Controllers.v1_1.GamesController.GameSearchModel +// { +// Name = "", +// Platform = new List{ +// platform.Id.ToString() +// }, +// Genre = collectionItem.Genres.ConvertAll(s => s.ToString()), +// GameMode = collectionItem.Players.ConvertAll(s => s.ToString()), +// PlayerPerspective = collectionItem.PlayerPerspectives.ConvertAll(s => s.ToString()), +// Theme = collectionItem.Themes.ConvertAll(s => s.ToString()), +// GameRating = new Controllers.v1_1.GamesController.GameSearchModel.GameRatingItem +// { +// MinimumRating = collectionItem.MinimumRating, +// MaximumRating = collectionItem.MaximumRating +// }, +// GameAgeRating = new Controllers.v1_1.GamesController.GameSearchModel.GameAgeRatingItem +// { +// AgeGroupings = UserAgeGroupings, +// IncludeUnrated = UserAgeGroupIncludeUnrated +// } +// }; +// games = Controllers.v1_1.GamesController.GetGames(searchModel, user).Result; + +// } + +// CollectionContents.CollectionPlatformItem collectionPlatformItem = new CollectionContents.CollectionPlatformItem(platform); +// collectionPlatformItem.Games = new List(); + +// // add titles with an inclusion status +// foreach (CollectionItem.AlwaysIncludeItem alwaysIncludeItem in collectionItem.AlwaysInclude) +// { +// if ( +// ( +// alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude || +// alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude +// ) && alwaysIncludeItem.PlatformId == platform.Id +// ) +// { +// MinimalGameItem AlwaysIncludeGame = new MinimalGameItem(Games.GetGame(FileSignature.MetadataSources.IGDB, alwaysIncludeItem.GameId).Result); +// CollectionContents.CollectionPlatformItem.CollectionGameItem gameItem = new CollectionContents.CollectionPlatformItem.CollectionGameItem(AlwaysIncludeGame); +// gameItem.InclusionStatus = new CollectionItem.AlwaysIncludeItem(); +// gameItem.InclusionStatus.PlatformId = alwaysIncludeItem.PlatformId; +// gameItem.InclusionStatus.GameId = alwaysIncludeItem.GameId; +// gameItem.InclusionStatus.InclusionState = alwaysIncludeItem.InclusionState; + +// // execute Roms.GetRomsAsync and wait for it to finish +// // this is a blocking call +// gameItem.Roms = Task.Run(async () => +// { +// var result = await Roms.GetRomsAsync((long)gameItem.Id, (long)platform.Id); +// return result.GameRomItems; +// }).Result; + +// collectionPlatformItem.Games.Add(gameItem); +// } +// } + +// foreach (MinimalGameItem game in games.Games) +// { +// bool gameAlreadyInList = false; +// foreach (CollectionContents.CollectionPlatformItem.CollectionGameItem existingGame in collectionPlatformItem.Games) +// { +// if (existingGame.Id == game.Id) +// { +// gameAlreadyInList = true; +// } +// } + +// if (gameAlreadyInList == false) +// { +// CollectionContents.CollectionPlatformItem.CollectionGameItem collectionGameItem = new CollectionContents.CollectionPlatformItem.CollectionGameItem(game); + +// // Retrieve ROMs for the game synchronously +// List gameRoms = Task.Run(async () => +// { +// var result = await Roms.GetRomsAsync((long)game.Id, (long)platform.Id); +// return result.GameRomItems; +// }).Result; + +// // Calculate total ROM size for the game +// long GameRomSize = gameRoms.Sum(r => (long)r.Size); + +// bool AddGame = false; +// if (collectionItem.MaximumBytesPerPlatform > 0) +// { +// if ((TotalRomSize + GameRomSize) < collectionItem.MaximumBytesPerPlatform) +// { +// AddGame = true; +// } +// } +// else +// { +// AddGame = true; +// } + +// if (AddGame == true) +// { +// TotalRomSize += GameRomSize; + +// bool AddRoms = false; + +// if (collectionItem.MaximumRomsPerPlatform > 0) +// { +// if (TotalGameCount < collectionItem.MaximumRomsPerPlatform) +// { +// AddRoms = true; +// } +// } +// else +// { +// AddRoms = true; +// } + +// if (AddRoms == true) +// { +// TotalGameCount += 1; +// collectionGameItem.Roms = gameRoms; +// collectionPlatformItem.Games.Add(collectionGameItem); +// } +// } +// } + +// // handle age grouping +// List gameAgeRatings = game.AgeRatings.Select(s => (AgeRating)s).ToList(); +// AgeGroups.AgeRestrictionGroupings CurrentAgeGroup = AgeGroups.GetAgeGroupFromAgeRatings(gameAgeRatings); +// if (CurrentAgeGroup > AgeGrouping) +// { +// AgeGrouping = CurrentAgeGroup; +// } +// if (CurrentAgeGroup == AgeGroups.AgeRestrictionGroupings.Unclassified) +// { +// ContainsUnclassifiedAgeGroup = true; +// } +// } + +// collectionPlatformItem.Games.Sort((x, y) => x.Name.CompareTo(y.Name)); + +// if (collectionPlatformItem.Games.Count > 0) +// { +// bool AddPlatform = false; +// if (collectionItem.MaximumCollectionSizeInBytes > 0) +// { +// if (TotalRomSize < collectionItem.MaximumCollectionSizeInBytes) +// { +// AddPlatform = true; +// } +// } +// else +// { +// AddPlatform = true; +// } + +// if (AddPlatform == true) +// { +// collectionPlatformItems.Add(collectionPlatformItem); +// } +// } +// } + +// collectionPlatformItems.Sort((x, y) => x.Name.CompareTo(y.Name)); + +// CollectionContents collectionContents = new CollectionContents +// { +// Collection = collectionPlatformItems, +// AgeGroup = AgeGrouping, +// ContainsUnclassifiedAgeGroup = ContainsUnclassifiedAgeGroup +// }; + +// return collectionContents; +// } + +// public static void CompileCollections(long CollectionId, string userid) +// { +// Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); + +// CollectionItem collectionItem = GetCollection(CollectionId, userid); +// if (collectionItem.BuildStatus == CollectionItem.CollectionBuildStatus.WaitingForBuild) +// { +// Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.beginning_build", null, new string[] { collectionItem.Name }); + +// CollectionContents collectionContents = GetCollectionContent(collectionItem, userid); + +// // set starting +// string sql = "UPDATE RomCollections SET BuiltStatus=@bs, AgeGroup=@ag, AgeGroupUnclassified=@agu WHERE Id=@id"; +// Dictionary dbDict = new Dictionary +// { +// { "id", collectionItem.Id }, +// { "bs", CollectionItem.CollectionBuildStatus.Building }, +// { "ag", collectionContents.AgeGroup }, +// { "agu", collectionContents.ContainsUnclassifiedAgeGroup } +// }; +// db.ExecuteCMD(sql, dbDict); + +// List collectionPlatformItems = collectionContents.Collection; +// string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, collectionItem.Id + collectionItem.ArchiveExtension); +// string ZipFileTempPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, collectionItem.Id.ToString()); + +// try +// { + +// // clean up if needed +// if (File.Exists(ZipFilePath)) +// { +// Logging.LogKey(Logging.LogType.Warning, "process.collections", "collections.deleting_existing_build", null, new string[] { collectionItem.Name }); +// File.Delete(ZipFilePath); +// } + +// if (Directory.Exists(ZipFileTempPath)) +// { +// Directory.Delete(ZipFileTempPath, true); +// } + +// // gather collection files +// Directory.CreateDirectory(ZipFileTempPath); +// string ZipBiosPath = Path.Combine(ZipFileTempPath, "BIOS"); + +// // get the games +// foreach (CollectionContents.CollectionPlatformItem collectionPlatformItem in collectionPlatformItems) +// { +// // get platform bios files if present +// if (collectionItem.IncludeBIOSFiles == true) +// { +// List bios = Bios.GetBios(collectionPlatformItem.Id, true).Result; +// if (!Directory.Exists(ZipBiosPath)) +// { +// Directory.CreateDirectory(ZipBiosPath); +// } + +// foreach (Bios.BiosItem biosItem in bios) +// { +// if (File.Exists(biosItem.biosPath)) +// { +// Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.copying_bios_file", null, new string[] { biosItem.filename }); +// File.Copy(biosItem.biosPath, Path.Combine(ZipBiosPath, biosItem.filename), true); +// } +// } +// } + +// // create platform directory +// string ZipPlatformPath = ""; +// switch (collectionItem.FolderStructure) +// { +// case CollectionItem.FolderStructures.Gaseous: +// ZipPlatformPath = Path.Combine(ZipFileTempPath, collectionPlatformItem.Slug); +// break; + +// case CollectionItem.FolderStructures.RetroPie: +// try +// { +// PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(collectionPlatformItem.Id).Result; +// ZipPlatformPath = Path.Combine(ZipFileTempPath, "roms", platformMapItem.RetroPieDirectoryName); +// } +// catch +// { +// ZipPlatformPath = Path.Combine(ZipFileTempPath, collectionPlatformItem.Slug); +// } + +// break; + +// } +// if (!Directory.Exists(ZipPlatformPath)) +// { +// Directory.CreateDirectory(ZipPlatformPath); +// } + +// foreach (CollectionContents.CollectionPlatformItem.CollectionGameItem collectionGameItem in collectionPlatformItem.Games) +// { +// bool includeGame = false; +// if (collectionGameItem.InclusionStatus == null) +// { +// includeGame = true; +// } +// else +// { +// if (collectionGameItem.InclusionStatus.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude) +// { +// includeGame = true; +// } +// } + +// if (includeGame == true) +// { +// string ZipGamePath = ""; +// switch (collectionItem.FolderStructure) +// { +// case CollectionItem.FolderStructures.Gaseous: +// // create game directory +// ZipGamePath = Path.Combine(ZipPlatformPath, collectionGameItem.Slug); +// if (!Directory.Exists(ZipGamePath)) +// { +// Directory.CreateDirectory(ZipGamePath); +// } +// break; + +// case CollectionItem.FolderStructures.RetroPie: +// ZipGamePath = ZipPlatformPath; +// break; +// } + +// // copy in roms +// foreach (Roms.GameRomItem gameRomItem in collectionGameItem.Roms) +// { +// if (File.Exists(gameRomItem.Path)) +// { +// Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.copying_rom", null, new string[] { gameRomItem.Name }); +// File.Copy(gameRomItem.Path, Path.Combine(ZipGamePath, gameRomItem.Name), true); +// } +// } +// } +// } +// } + +// // compress to zip +// Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.compressing_collection"); +// switch (collectionItem.ArchiveType) +// { +// case CollectionItem.ArchiveTypes.Zip: +// ZipFile.CreateFromDirectory(ZipFileTempPath, ZipFilePath, CompressionLevel.SmallestSize, false); +// break; + +// case CollectionItem.ArchiveTypes.RAR: + +// break; + +// case CollectionItem.ArchiveTypes.SevenZip: + +// break; +// } + + +// // clean up +// if (Directory.Exists(ZipFileTempPath)) +// { +// Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.cleaning_up"); +// Directory.Delete(ZipFileTempPath, true); +// } + +// // set completed +// dbDict["bs"] = CollectionItem.CollectionBuildStatus.Completed; +// db.ExecuteCMD(sql, dbDict); +// } +// catch (Exception ex) +// { +// // clean up +// if (Directory.Exists(ZipFileTempPath)) +// { +// Directory.Delete(ZipFileTempPath, true); +// } + +// if (File.Exists(ZipFilePath)) +// { +// File.Delete(ZipFilePath); +// } + +// // set failed +// dbDict["bs"] = CollectionItem.CollectionBuildStatus.Failed; +// db.ExecuteCMD(sql, dbDict); + +// Logging.LogKey(Logging.LogType.Critical, "process.collection_builder", "collections.build_failed", null, null, ex); +// } +// } +// } + +// private static CollectionItem BuildCollectionItem(DataRow row) +// { +// string strPlatforms = (string)Common.ReturnValueIfNull(row["Platforms"], "[ ]"); +// string strGenres = (string)Common.ReturnValueIfNull(row["Genres"], "[ ]"); +// string strPlayers = (string)Common.ReturnValueIfNull(row["Players"], "[ ]"); +// string strPlayerPerspectives = (string)Common.ReturnValueIfNull(row["PlayerPerspectives"], "[ ]"); +// string strThemes = (string)Common.ReturnValueIfNull(row["Themes"], "[ ]"); +// string strAlwaysInclude = (string)Common.ReturnValueIfNull(row["AlwaysInclude"], "[ ]"); + +// CollectionItem item = new CollectionItem(); +// item.Id = (long)row["Id"]; +// item.Name = (string)row["Name"]; +// item.Description = (string)row["Description"]; +// item.Platforms = Newtonsoft.Json.JsonConvert.DeserializeObject>(strPlatforms); +// item.Genres = Newtonsoft.Json.JsonConvert.DeserializeObject>(strGenres); +// item.Players = Newtonsoft.Json.JsonConvert.DeserializeObject>(strPlayers); +// item.PlayerPerspectives = Newtonsoft.Json.JsonConvert.DeserializeObject>(strPlayerPerspectives); +// item.Themes = Newtonsoft.Json.JsonConvert.DeserializeObject>(strThemes); +// item.MinimumRating = (int)Common.ReturnValueIfNull(row["MinimumRating"], -1); +// item.MaximumRating = (int)Common.ReturnValueIfNull(row["MaximumRating"], -1); +// item.MaximumRomsPerPlatform = (int)Common.ReturnValueIfNull(row["MaximumRomsPerPlatform"], (int)-1); +// item.MaximumBytesPerPlatform = (long)Common.ReturnValueIfNull(row["MaximumBytesPerPlatform"], (long)-1); +// item.MaximumCollectionSizeInBytes = (long)Common.ReturnValueIfNull(row["MaximumCollectionSizeInBytes"], (long)-1); +// item.FolderStructure = (CollectionItem.FolderStructures)(int)Common.ReturnValueIfNull(row["FolderStructure"], 0); +// item.IncludeBIOSFiles = (bool)row["IncludeBIOSFiles"]; +// item.ArchiveType = (CollectionItem.ArchiveTypes)(int)Common.ReturnValueIfNull(row["ArchiveType"], 0); +// item.AlwaysInclude = Newtonsoft.Json.JsonConvert.DeserializeObject>(strAlwaysInclude); +// item.BuildStatus = (CollectionItem.CollectionBuildStatus)(int)Common.ReturnValueIfNull(row["BuiltStatus"], 0); + +// return item; +// } + +// public class CollectionItem +// { +// public CollectionItem() +// { + +// } + +// public long Id { get; set; } +// public string Name { get; set; } +// public string Description { get; set; } +// public List? Platforms { get; set; } +// public List? Genres { get; set; } +// public List? Players { get; set; } +// public List? PlayerPerspectives { get; set; } +// public List? Themes { get; set; } +// public int MinimumRating { get; set; } +// public int MaximumRating { get; set; } +// public int? MaximumRomsPerPlatform { get; set; } +// public long? MaximumBytesPerPlatform { get; set; } +// public long? MaximumCollectionSizeInBytes { get; set; } +// public FolderStructures FolderStructure { get; set; } = FolderStructures.Gaseous; +// public bool IncludeBIOSFiles { get; set; } = true; +// public ArchiveTypes ArchiveType { get; set; } = CollectionItem.ArchiveTypes.Zip; +// public string ArchiveExtension +// { +// get +// { +// if (ArchiveType != null) +// { +// switch (ArchiveType) +// { +// case ArchiveTypes.Zip: +// default: +// return ".zip"; + +// case ArchiveTypes.RAR: +// return ".rar"; + +// case ArchiveTypes.SevenZip: +// return ".7z"; +// } +// } +// else +// { +// return ".zip"; +// } +// } +// } +// public List AlwaysInclude { get; set; } + +// [JsonIgnore] +// public CollectionBuildStatus BuildStatus +// { +// get +// { +// if (_BuildStatus == CollectionBuildStatus.Completed) +// { +// if (File.Exists(Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ArchiveExtension))) +// { +// return CollectionBuildStatus.Completed; +// } +// else +// { +// return CollectionBuildStatus.NoStatus; +// } +// } +// else +// { +// return _BuildStatus; +// } +// } +// set +// { +// _BuildStatus = value; +// } +// } +// private CollectionBuildStatus _BuildStatus { get; set; } + +// [JsonIgnore] +// public long CollectionBuiltSizeBytes +// { +// get +// { +// if (BuildStatus == CollectionBuildStatus.Completed) +// { +// string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ArchiveExtension); +// if (File.Exists(ZipFilePath)) +// { +// FileInfo fi = new FileInfo(ZipFilePath); +// return fi.Length; +// } +// else +// { +// return 0; +// } +// } +// else +// { +// return 0; +// } +// } +// } + +// public enum CollectionBuildStatus +// { +// NoStatus = 0, +// WaitingForBuild = 1, +// Building = 2, +// Completed = 3, +// Failed = 4 +// } + +// public enum FolderStructures +// { +// Gaseous = 0, +// RetroPie = 1 +// } + +// public enum ArchiveTypes +// { +// Zip = 0, +// RAR = 1, +// SevenZip = 2 +// } + +// public class AlwaysIncludeItem +// { +// public long PlatformId { get; set; } +// public long GameId { get; set; } +// public AlwaysIncludeStatus InclusionState { get; set; } +// } + +// public enum AlwaysIncludeStatus +// { +// None = 0, +// AlwaysInclude = 1, +// AlwaysExclude = 2 +// } +// } + +// public class CollectionContents +// { +// [JsonIgnore] +// public List Collection { get; set; } + +// [JsonIgnore] +// public long CollectionProjectedSizeBytes +// { +// get +// { +// long CollectionSize = 0; + +// List collectionPlatformItems = new List(); + +// if (Collection != null) +// { +// collectionPlatformItems = Collection; +// } + +// foreach (CollectionPlatformItem platformItem in collectionPlatformItems) +// { +// CollectionSize += platformItem.RomSize; +// } + +// return CollectionSize; +// } +// } + +// public AgeGroups.AgeRestrictionGroupings AgeGroup { get; set; } +// public bool ContainsUnclassifiedAgeGroup { get; set; } + +// public class CollectionPlatformItem +// { +// public CollectionPlatformItem(Platform platform) +// { +// string[] PropertyWhitelist = new string[] { "Id", "Name", "Slug" }; + +// PropertyInfo[] srcProperties = typeof(Platform).GetProperties(); +// PropertyInfo[] dstProperties = typeof(CollectionPlatformItem).GetProperties(); +// foreach (PropertyInfo srcProperty in srcProperties) +// { +// if (PropertyWhitelist.Contains(srcProperty.Name)) +// { +// foreach (PropertyInfo dstProperty in dstProperties) +// { +// if (srcProperty.Name == dstProperty.Name) +// { +// dstProperty.SetValue(this, srcProperty.GetValue(platform)); +// } +// } +// } +// } +// } + +// public long Id { get; set; } +// public string Name { get; set; } +// public string Slug { get; set; } + +// public List Games { get; set; } + +// public int RomCount +// { +// get +// { +// int Counter = 0; +// foreach (CollectionGameItem Game in Games) +// { +// Counter += 1; +// } + +// return Counter; +// } +// } + +// public long RomSize +// { +// get +// { +// long Size = 0; +// foreach (CollectionGameItem Game in Games) +// { +// foreach (Roms.GameRomItem Rom in Game.Roms) +// { +// Size += (long)Rom.Size; +// } +// } + +// return Size; +// } +// } + +// public class CollectionGameItem : MinimalGameItem +// { +// public CollectionGameItem(MinimalGameItem gameObject) +// { +// this.Id = gameObject.Id; +// this.Name = gameObject.Name; +// this.Slug = gameObject.Slug; +// this.TotalRating = gameObject.TotalRating; +// this.TotalRatingCount = gameObject.TotalRatingCount; +// this.Cover = gameObject.Cover; +// this.Artworks = gameObject.Artworks; +// this.FirstReleaseDate = gameObject.FirstReleaseDate; +// this.AgeRatings = gameObject.AgeRatings; +// } + +// public AgeGroups.AgeRestrictionGroupings AgeGrouping +// { +// get +// { +// List gameAgeRatings = this.AgeRatings.Select(s => (AgeRating)s).ToList(); +// return AgeGroups.GetAgeGroupFromAgeRatings(gameAgeRatings); +// } +// } + +// public CollectionItem.AlwaysIncludeItem InclusionStatus { get; set; } + +// public List Roms { get; set; } + +// public long RomSize +// { +// get +// { +// long Size = 0; +// foreach (Roms.GameRomItem Rom in Roms) +// { +// Size += (long)Rom.Size; +// } + +// return Size; +// } +// } +// } +// } +// } +// } +// } \ No newline at end of file diff --git a/gaseous-server/Classes/Common.cs b/gaseous-lib/Classes/Common.cs similarity index 100% rename from gaseous-server/Classes/Common.cs rename to gaseous-lib/Classes/Common.cs diff --git a/gaseous-server/Classes/Config.cs b/gaseous-lib/Classes/Config.cs similarity index 93% rename from gaseous-server/Classes/Config.cs rename to gaseous-lib/Classes/Config.cs index 2981eb3..896da59 100644 --- a/gaseous-server/Classes/Config.cs +++ b/gaseous-lib/Classes/Config.cs @@ -40,6 +40,15 @@ namespace gaseous_server.Classes set { _config.ServerPort = value; } } + /// + /// The port used for local communication between the main server process and the out-of-process task host. This is used for sending commands and receiving status updates from the out-of-process task host when executing long-running tasks. The default value is 5197, but it can be overridden with the "localcommsport" environment variable or by changing the value in the config file. When running in a container, the environment variable will take precedence over the config file value to allow for easy configuration without needing to modify the config file. + /// + public static int LocalCommsPort + { + get { return _config.LocalCommsPort; } + set { _config.LocalCommsPort = value; } + } + /// /// The default language/locale the server uses for responses and localisation. This is in the format of a standard locale string, e.g. "en-US" or "fr-FR". The default is "en-US". Can be overridden by setting the "serverlanguage" environment variable or by changing the value in the config file. When running in a container, the environment variable will take precedence over the config file value to allow for easy configuration without needing to modify the config file. /// @@ -229,6 +238,13 @@ namespace gaseous_server.Classes return "2"; } } + + /// + /// Whether the background task processing system is enabled. This can be used to disable background task processing if needed (e.g. for troubleshooting or if the feature is not desired). When disabled, the timer that processes the queue will not execute any tasks. + /// This is a runtime option to prevent running processes until the server is fully up and running. + /// + public static bool BackgroundTasksEnabled { get; set; } = false; + #endregion Configuration Accessors /// @@ -439,42 +455,22 @@ namespace gaseous_server.Classes { Logging.LogKey(Logging.LogType.Debug, "process.database", "database.reading_setting", null, new string[] { SettingName }); - if (Database.schema_version >= 1016) - { - sql = "SELECT Value, ValueDate FROM Settings WHERE Setting = @SettingName"; + sql = "SELECT Value, ValueDate FROM Settings WHERE Setting = @SettingName"; - dbResponse = db.ExecuteCMD(sql, dbDict); - Type type = typeof(T); - if (dbResponse.Rows.Count == 0) - { - // no value with that name stored - respond with the default value - SetSetting(SettingName, DefaultValue); - return DefaultValue; - } - else - { - if (type.ToString() == "System.DateTime") - { - AppSettings.Add(SettingName, (T)dbResponse.Rows[0]["ValueDate"]); - return (T)dbResponse.Rows[0]["ValueDate"]; - } - else - { - AppSettings.Add(SettingName, (T)dbResponse.Rows[0]["Value"]); - return (T)dbResponse.Rows[0]["Value"]; - } - } + dbResponse = db.ExecuteCMD(sql, dbDict); + Type type = typeof(T); + if (dbResponse.Rows.Count == 0) + { + // no value with that name stored - respond with the default value + SetSetting(SettingName, DefaultValue); + return DefaultValue; } else { - sql = "SELECT Value FROM Settings WHERE Setting = @SettingName"; - - dbResponse = db.ExecuteCMD(sql, dbDict); - if (dbResponse.Rows.Count == 0) + if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(Nullable)) { - // no value with that name stored - respond with the default value - SetSetting(SettingName, DefaultValue); - return DefaultValue; + AppSettings.Add(SettingName, (T)dbResponse.Rows[0]["ValueDate"]); + return (T)dbResponse.Rows[0]["ValueDate"]; } else { @@ -532,8 +528,7 @@ namespace gaseous_server.Classes if (Database.schema_version >= 1016) { sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)"; - Type type = typeof(T); - if (type.ToString() == "System.DateTime") + if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(Nullable)) { dbDict = new Dictionary { diff --git a/gaseous-server/Classes/ContentManager.cs b/gaseous-lib/Classes/ContentManager.cs similarity index 100% rename from gaseous-server/Classes/ContentManager.cs rename to gaseous-lib/Classes/ContentManager.cs diff --git a/gaseous-server/Classes/Database/Database.cs b/gaseous-lib/Classes/Database/Database.cs similarity index 99% rename from gaseous-server/Classes/Database/Database.cs rename to gaseous-lib/Classes/Database/Database.cs index 9ce193e..0dadde3 100644 --- a/gaseous-server/Classes/Database/Database.cs +++ b/gaseous-lib/Classes/Database/Database.cs @@ -143,7 +143,7 @@ namespace gaseous_server.Classes for (int i = OuterSchemaVer; i < 10000; i++) { - string resourceName = "gaseous_server.Support.Database.MySQL.gaseous-" + i + ".sql"; + string resourceName = "gaseous_lib.Support.Database.MySQL.gaseous-" + i + ".sql"; string dbScript = ""; string[] resources = Assembly.GetExecutingAssembly().GetManifestResourceNames(); diff --git a/gaseous-server/Classes/Database/DatabaseMigration.cs b/gaseous-lib/Classes/Database/DatabaseMigration.cs similarity index 99% rename from gaseous-server/Classes/Database/DatabaseMigration.cs rename to gaseous-lib/Classes/Database/DatabaseMigration.cs index 392f114..46995ed 100644 --- a/gaseous-server/Classes/Database/DatabaseMigration.cs +++ b/gaseous-lib/Classes/Database/DatabaseMigration.cs @@ -44,7 +44,7 @@ namespace gaseous_server.Classes { Logging.LogKey(Logging.LogType.Information, "process.database", "database.schema_version_requires_missing_table", null, new[] { TargetSchemaVersion.ToString() }); - string resourceName = "gaseous_server.Support.Database.MySQL.gaseous-fix-1005.sql"; + string resourceName = "gaseous_lib.Support.Database.MySQL.gaseous-fix-1005.sql"; string dbScript = ""; string[] resources = Assembly.GetExecutingAssembly().GetManifestResourceNames(); @@ -186,7 +186,7 @@ namespace gaseous_server.Classes // load country list Logging.LogKey(Logging.LogType.Information, "process.database", "database.adding_country_lookup_table_contents"); - string countryResourceName = "gaseous_server.Support.Country.txt"; + string countryResourceName = "gaseous_lib.Support.Country.txt"; using (Stream stream = assembly.GetManifestResourceStream(countryResourceName)) using (StreamReader reader = new StreamReader(stream)) { @@ -206,7 +206,7 @@ namespace gaseous_server.Classes // load language list Logging.LogKey(Logging.LogType.Information, "process.database", "database.adding_language_lookup_table_contents"); - string languageResourceName = "gaseous_server.Support.Language.txt"; + string languageResourceName = "gaseous_lib.Support.Language.txt"; using (Stream stream = assembly.GetManifestResourceStream(languageResourceName)) using (StreamReader reader = new StreamReader(stream)) { diff --git a/gaseous-server/Classes/Database/MemoryCache.cs b/gaseous-lib/Classes/Database/MemoryCache.cs similarity index 100% rename from gaseous-server/Classes/Database/MemoryCache.cs rename to gaseous-lib/Classes/Database/MemoryCache.cs diff --git a/gaseous-server/Classes/Favourites.cs b/gaseous-lib/Classes/Favourites.cs similarity index 100% rename from gaseous-server/Classes/Favourites.cs rename to gaseous-lib/Classes/Favourites.cs diff --git a/gaseous-server/Classes/Filters.cs b/gaseous-lib/Classes/Filters.cs similarity index 100% rename from gaseous-server/Classes/Filters.cs rename to gaseous-lib/Classes/Filters.cs diff --git a/gaseous-server/Classes/GameLibrary.cs b/gaseous-lib/Classes/GameLibrary.cs similarity index 97% rename from gaseous-server/Classes/GameLibrary.cs rename to gaseous-lib/Classes/GameLibrary.cs index 4671605..d58627a 100644 --- a/gaseous-server/Classes/GameLibrary.cs +++ b/gaseous-lib/Classes/GameLibrary.cs @@ -3,6 +3,7 @@ using System.Data; using System.Threading.Tasks; using gaseous_server.Classes; using gaseous_server.Classes.Metadata; +using gaseous_server.Models; using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow; namespace gaseous_server @@ -83,7 +84,7 @@ namespace gaseous_server LibraryItem library = new LibraryItem((int)row["Id"], (string)row["Name"], (string)row["Path"], (long)row["DefaultPlatform"], Convert.ToBoolean((int)row["DefaultLibrary"])); if (GetStorageInfo == true) { - library.PathInfo = Controllers.SystemController.GetDisk(library.Path); + library.PathInfo = SystemInfo.GetDisk(library.Path); } libraryItems.Add(library); @@ -198,7 +199,7 @@ namespace gaseous_server if (GetStorageInfo == true) { - library.PathInfo = Controllers.SystemController.GetDisk(library.Path); + library.PathInfo = SystemInfo.GetDisk(library.Path); } return library; @@ -273,7 +274,7 @@ namespace gaseous_server } public bool IsDefaultLibrary => _IsDefaultLibrary; - public Controllers.SystemController.SystemInfo.PathItem? PathInfo { get; set; } + public SystemInfoModel.PathItem? PathInfo { get; set; } } } } \ No newline at end of file diff --git a/gaseous-server/Classes/HTTPComms.cs b/gaseous-lib/Classes/HTTPComms.cs similarity index 100% rename from gaseous-server/Classes/HTTPComms.cs rename to gaseous-lib/Classes/HTTPComms.cs diff --git a/gaseous-server/Classes/HashObject.cs b/gaseous-lib/Classes/HashObject.cs similarity index 100% rename from gaseous-server/Classes/HashObject.cs rename to gaseous-lib/Classes/HashObject.cs diff --git a/gaseous-server/Classes/ImportGames.cs b/gaseous-lib/Classes/ImportGames.cs similarity index 100% rename from gaseous-server/Classes/ImportGames.cs rename to gaseous-lib/Classes/ImportGames.cs diff --git a/gaseous-server/Classes/Localisation.cs b/gaseous-lib/Classes/Localisation.cs similarity index 98% rename from gaseous-server/Classes/Localisation.cs rename to gaseous-lib/Classes/Localisation.cs index a952c73..7fc6f74 100644 --- a/gaseous-server/Classes/Localisation.cs +++ b/gaseous-lib/Classes/Localisation.cs @@ -470,9 +470,9 @@ namespace gaseous_server.Classes var resourceNames = assembly.GetManifestResourceNames(); foreach (var resourceName in resourceNames) { - if (resourceName.StartsWith("gaseous_server.Support.Localisation.") && resourceName.EndsWith(".json")) + if (resourceName.StartsWith("gaseous_lib.Support.Localisation.") && resourceName.EndsWith(".json")) { - string localeCode = resourceName.Substring("gaseous_server.Support.Localisation.".Length); + string localeCode = resourceName.Substring("gaseous_lib.Support.Localisation.".Length); localeCode = localeCode.Substring(0, localeCode.Length - ".json".Length); try { @@ -519,7 +519,7 @@ namespace gaseous_server.Classes private static LocaleFileModel LoadLocaleFromResources(string locale) { - string resourceName = "gaseous_server.Support.Localisation." + locale + ".json"; + string resourceName = "gaseous_lib.Support.Localisation." + locale + ".json"; using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) { if (stream == null) diff --git a/gaseous-server/Classes/Logging.cs b/gaseous-lib/Classes/Logging.cs similarity index 100% rename from gaseous-server/Classes/Logging.cs rename to gaseous-lib/Classes/Logging.cs diff --git a/gaseous-server/Classes/Maintenance.cs b/gaseous-lib/Classes/Maintenance.cs similarity index 100% rename from gaseous-server/Classes/Maintenance.cs rename to gaseous-lib/Classes/Maintenance.cs diff --git a/gaseous-server/Classes/Metadata/AgeGroups.cs b/gaseous-lib/Classes/Metadata/AgeGroups.cs similarity index 98% rename from gaseous-server/Classes/Metadata/AgeGroups.cs rename to gaseous-lib/Classes/Metadata/AgeGroups.cs index fe22451..6fefafd 100644 --- a/gaseous-server/Classes/Metadata/AgeGroups.cs +++ b/gaseous-lib/Classes/Metadata/AgeGroups.cs @@ -307,7 +307,8 @@ namespace gaseous_server.Classes.Metadata } else { - using Stream? stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("gaseous_server.wwwroot.images.Ratings.AgeGroupMap.json"); + // using Stream? stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("gaseous_server.wwwroot.images.Ratings.AgeGroupMap.json"); + using Stream? stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("gaseous_lib.Support.AgeGroupMap.json"); if (stream != null) { using StreamReader reader = new StreamReader(stream); diff --git a/gaseous-server/Classes/Metadata/AgeRating.cs b/gaseous-lib/Classes/Metadata/AgeRating.cs similarity index 100% rename from gaseous-server/Classes/Metadata/AgeRating.cs rename to gaseous-lib/Classes/Metadata/AgeRating.cs diff --git a/gaseous-server/Classes/Metadata/AgeRatingCategory.cs b/gaseous-lib/Classes/Metadata/AgeRatingCategory.cs similarity index 100% rename from gaseous-server/Classes/Metadata/AgeRatingCategory.cs rename to gaseous-lib/Classes/Metadata/AgeRatingCategory.cs diff --git a/gaseous-server/Classes/Metadata/AgeRatingContentDescriptionsV2.cs b/gaseous-lib/Classes/Metadata/AgeRatingContentDescriptionsV2.cs similarity index 100% rename from gaseous-server/Classes/Metadata/AgeRatingContentDescriptionsV2.cs rename to gaseous-lib/Classes/Metadata/AgeRatingContentDescriptionsV2.cs diff --git a/gaseous-server/Classes/Metadata/AgeRatingOrganization.cs b/gaseous-lib/Classes/Metadata/AgeRatingOrganization.cs similarity index 100% rename from gaseous-server/Classes/Metadata/AgeRatingOrganization.cs rename to gaseous-lib/Classes/Metadata/AgeRatingOrganization.cs diff --git a/gaseous-server/Classes/Metadata/AlternativeNames.cs b/gaseous-lib/Classes/Metadata/AlternativeNames.cs similarity index 100% rename from gaseous-server/Classes/Metadata/AlternativeNames.cs rename to gaseous-lib/Classes/Metadata/AlternativeNames.cs diff --git a/gaseous-server/Classes/Metadata/Artworks.cs b/gaseous-lib/Classes/Metadata/Artworks.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Artworks.cs rename to gaseous-lib/Classes/Metadata/Artworks.cs diff --git a/gaseous-server/Classes/Metadata/ClearLogo.cs b/gaseous-lib/Classes/Metadata/ClearLogo.cs similarity index 100% rename from gaseous-server/Classes/Metadata/ClearLogo.cs rename to gaseous-lib/Classes/Metadata/ClearLogo.cs diff --git a/gaseous-server/Classes/Metadata/Collections.cs b/gaseous-lib/Classes/Metadata/Collections.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Collections.cs rename to gaseous-lib/Classes/Metadata/Collections.cs diff --git a/gaseous-server/Classes/Metadata/Company.cs b/gaseous-lib/Classes/Metadata/Company.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Company.cs rename to gaseous-lib/Classes/Metadata/Company.cs diff --git a/gaseous-server/Classes/Metadata/CompanyLogos.cs b/gaseous-lib/Classes/Metadata/CompanyLogos.cs similarity index 100% rename from gaseous-server/Classes/Metadata/CompanyLogos.cs rename to gaseous-lib/Classes/Metadata/CompanyLogos.cs diff --git a/gaseous-server/Classes/Metadata/Covers.cs b/gaseous-lib/Classes/Metadata/Covers.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Covers.cs rename to gaseous-lib/Classes/Metadata/Covers.cs diff --git a/gaseous-server/Classes/Metadata/ExternalGames.cs b/gaseous-lib/Classes/Metadata/ExternalGames.cs similarity index 100% rename from gaseous-server/Classes/Metadata/ExternalGames.cs rename to gaseous-lib/Classes/Metadata/ExternalGames.cs diff --git a/gaseous-server/Classes/Metadata/Franchises.cs b/gaseous-lib/Classes/Metadata/Franchises.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Franchises.cs rename to gaseous-lib/Classes/Metadata/Franchises.cs diff --git a/gaseous-server/Classes/Metadata/GameLocalisations.cs b/gaseous-lib/Classes/Metadata/GameLocalisations.cs similarity index 100% rename from gaseous-server/Classes/Metadata/GameLocalisations.cs rename to gaseous-lib/Classes/Metadata/GameLocalisations.cs diff --git a/gaseous-server/Classes/Metadata/GameModes.cs b/gaseous-lib/Classes/Metadata/GameModes.cs similarity index 100% rename from gaseous-server/Classes/Metadata/GameModes.cs rename to gaseous-lib/Classes/Metadata/GameModes.cs diff --git a/gaseous-server/Classes/Metadata/GameVideos.cs b/gaseous-lib/Classes/Metadata/GameVideos.cs similarity index 100% rename from gaseous-server/Classes/Metadata/GameVideos.cs rename to gaseous-lib/Classes/Metadata/GameVideos.cs diff --git a/gaseous-server/Classes/Metadata/Games.cs b/gaseous-lib/Classes/Metadata/Games.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Games.cs rename to gaseous-lib/Classes/Metadata/Games.cs diff --git a/gaseous-server/Classes/Metadata/Genres.cs b/gaseous-lib/Classes/Metadata/Genres.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Genres.cs rename to gaseous-lib/Classes/Metadata/Genres.cs diff --git a/gaseous-server/Classes/Metadata/Hasheous.cs b/gaseous-lib/Classes/Metadata/Hasheous.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Hasheous.cs rename to gaseous-lib/Classes/Metadata/Hasheous.cs diff --git a/gaseous-server/Classes/Metadata/Images.cs b/gaseous-lib/Classes/Metadata/Images.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Images.cs rename to gaseous-lib/Classes/Metadata/Images.cs diff --git a/gaseous-server/Classes/Metadata/InvolvedCompany.cs b/gaseous-lib/Classes/Metadata/InvolvedCompany.cs similarity index 100% rename from gaseous-server/Classes/Metadata/InvolvedCompany.cs rename to gaseous-lib/Classes/Metadata/InvolvedCompany.cs diff --git a/gaseous-server/Classes/Metadata/Metadata.cs b/gaseous-lib/Classes/Metadata/Metadata.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Metadata.cs rename to gaseous-lib/Classes/Metadata/Metadata.cs diff --git a/gaseous-server/Classes/Metadata/MultiplayerModes.cs b/gaseous-lib/Classes/Metadata/MultiplayerModes.cs similarity index 100% rename from gaseous-server/Classes/Metadata/MultiplayerModes.cs rename to gaseous-lib/Classes/Metadata/MultiplayerModes.cs diff --git a/gaseous-server/Classes/Metadata/PlatformLogos.cs b/gaseous-lib/Classes/Metadata/PlatformLogos.cs similarity index 100% rename from gaseous-server/Classes/Metadata/PlatformLogos.cs rename to gaseous-lib/Classes/Metadata/PlatformLogos.cs diff --git a/gaseous-server/Classes/Metadata/PlatformVersions.cs b/gaseous-lib/Classes/Metadata/PlatformVersions.cs similarity index 100% rename from gaseous-server/Classes/Metadata/PlatformVersions.cs rename to gaseous-lib/Classes/Metadata/PlatformVersions.cs diff --git a/gaseous-server/Classes/Metadata/Platforms.cs b/gaseous-lib/Classes/Metadata/Platforms.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Platforms.cs rename to gaseous-lib/Classes/Metadata/Platforms.cs diff --git a/gaseous-server/Classes/Metadata/PlayerPerspectives.cs b/gaseous-lib/Classes/Metadata/PlayerPerspectives.cs similarity index 100% rename from gaseous-server/Classes/Metadata/PlayerPerspectives.cs rename to gaseous-lib/Classes/Metadata/PlayerPerspectives.cs diff --git a/gaseous-server/Classes/Metadata/Regions.cs b/gaseous-lib/Classes/Metadata/Regions.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Regions.cs rename to gaseous-lib/Classes/Metadata/Regions.cs diff --git a/gaseous-server/Classes/Metadata/ReleaseDates.cs b/gaseous-lib/Classes/Metadata/ReleaseDates.cs similarity index 100% rename from gaseous-server/Classes/Metadata/ReleaseDates.cs rename to gaseous-lib/Classes/Metadata/ReleaseDates.cs diff --git a/gaseous-server/Classes/Metadata/Screenshots.cs b/gaseous-lib/Classes/Metadata/Screenshots.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Screenshots.cs rename to gaseous-lib/Classes/Metadata/Screenshots.cs diff --git a/gaseous-server/Classes/Metadata/Themes.cs b/gaseous-lib/Classes/Metadata/Themes.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Themes.cs rename to gaseous-lib/Classes/Metadata/Themes.cs diff --git a/gaseous-server/Classes/Metadata/Utility.cs b/gaseous-lib/Classes/Metadata/Utility.cs similarity index 100% rename from gaseous-server/Classes/Metadata/Utility.cs rename to gaseous-lib/Classes/Metadata/Utility.cs diff --git a/gaseous-server/Classes/MetadataManagement.cs b/gaseous-lib/Classes/MetadataManagement.cs similarity index 99% rename from gaseous-server/Classes/MetadataManagement.cs rename to gaseous-lib/Classes/MetadataManagement.cs index 2701673..831d677 100644 --- a/gaseous-server/Classes/MetadataManagement.cs +++ b/gaseous-lib/Classes/MetadataManagement.cs @@ -2,7 +2,6 @@ using System.Data; using System.Threading.Tasks; using gaseous_server.Classes.Metadata; -using gaseous_server.Controllers; using gaseous_server.Models; using System.Linq; using HasheousClient.Models; @@ -175,6 +174,7 @@ namespace gaseous_server.Classes /// /// /// The unique identifier for the data source as provided by the automatic metadata fetcher. + /// /// /// If the metadata source is preferred, all other metadata sources for the same metadata map will be set to not preferred. /// diff --git a/gaseous-server/Classes/Plugins/FileSignatures/Decompression/un7zip.cs b/gaseous-lib/Classes/Plugins/FileSignatures/Decompression/un7zip.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/Decompression/un7zip.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/Decompression/un7zip.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/Decompression/unrar.cs b/gaseous-lib/Classes/Plugins/FileSignatures/Decompression/unrar.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/Decompression/unrar.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/Decompression/unrar.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/Decompression/unzip.cs b/gaseous-lib/Classes/Plugins/FileSignatures/Decompression/unzip.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/Decompression/unzip.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/Decompression/unzip.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/FileSignature.cs b/gaseous-lib/Classes/Plugins/FileSignatures/FileSignature.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/FileSignature.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/FileSignature.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/FileSignaturePlugins/Database.cs b/gaseous-lib/Classes/Plugins/FileSignatures/FileSignaturePlugins/Database.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/FileSignaturePlugins/Database.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/FileSignaturePlugins/Database.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/FileSignaturePlugins/Hasheous.cs b/gaseous-lib/Classes/Plugins/FileSignatures/FileSignaturePlugins/Hasheous.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/FileSignaturePlugins/Hasheous.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/FileSignaturePlugins/Hasheous.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/FileSignaturePlugins/InspectFile.cs b/gaseous-lib/Classes/Plugins/FileSignatures/FileSignaturePlugins/InspectFile.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/FileSignaturePlugins/InspectFile.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/FileSignaturePlugins/InspectFile.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/IDecompressPlugin.cs b/gaseous-lib/Classes/Plugins/FileSignatures/IDecompressPlugin.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/IDecompressPlugin.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/IDecompressPlugin.cs diff --git a/gaseous-server/Classes/Plugins/FileSignatures/IFileSignaturePlugin.cs b/gaseous-lib/Classes/Plugins/FileSignatures/IFileSignaturePlugin.cs similarity index 100% rename from gaseous-server/Classes/Plugins/FileSignatures/IFileSignaturePlugin.cs rename to gaseous-lib/Classes/Plugins/FileSignatures/IFileSignaturePlugin.cs diff --git a/gaseous-server/Classes/Plugins/LogProviders/ConsoleProvider.cs b/gaseous-lib/Classes/Plugins/LogProviders/ConsoleProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/LogProviders/ConsoleProvider.cs rename to gaseous-lib/Classes/Plugins/LogProviders/ConsoleProvider.cs diff --git a/gaseous-server/Classes/Plugins/LogProviders/DatabaseProvider.cs b/gaseous-lib/Classes/Plugins/LogProviders/DatabaseProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/LogProviders/DatabaseProvider.cs rename to gaseous-lib/Classes/Plugins/LogProviders/DatabaseProvider.cs diff --git a/gaseous-server/Classes/Plugins/LogProviders/ILogProvider.cs b/gaseous-lib/Classes/Plugins/LogProviders/ILogProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/LogProviders/ILogProvider.cs rename to gaseous-lib/Classes/Plugins/LogProviders/ILogProvider.cs diff --git a/gaseous-server/Classes/Plugins/LogProviders/TextFileProvider.cs b/gaseous-lib/Classes/Plugins/LogProviders/TextFileProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/LogProviders/TextFileProvider.cs rename to gaseous-lib/Classes/Plugins/LogProviders/TextFileProvider.cs diff --git a/gaseous-server/Classes/Plugins/LogProviders/WindowsEventLogProvider.cs b/gaseous-lib/Classes/Plugins/LogProviders/WindowsEventLogProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/LogProviders/WindowsEventLogProvider.cs rename to gaseous-lib/Classes/Plugins/LogProviders/WindowsEventLogProvider.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/IMetadataProvider.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/IMetadataProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/IMetadataProvider.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/IMetadataProvider.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/IProxyProvider.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/IProxyProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/IProxyProvider.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/IProxyProvider.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/MetadataModels.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/MetadataModels.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/MetadataModels.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/MetadataModels.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/IGDBProvider.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/IGDBProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/IGDBProvider.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/IGDBProvider.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/NoneProvider.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/NoneProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/NoneProvider.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/NoneProvider.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/TheGamesDBProvider.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/TheGamesDBProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/TheGamesDBProvider.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/MetadataProviderPlugins/TheGamesDBProvider.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/ProxyProviderPlugins/HasheousIGDBProxyProvider.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/ProxyProviderPlugins/HasheousIGDBProxyProvider.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/ProxyProviderPlugins/HasheousIGDBProxyProvider.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/ProxyProviderPlugins/HasheousIGDBProxyProvider.cs diff --git a/gaseous-server/Classes/Plugins/MetadataProviders/Storage.cs b/gaseous-lib/Classes/Plugins/MetadataProviders/Storage.cs similarity index 100% rename from gaseous-server/Classes/Plugins/MetadataProviders/Storage.cs rename to gaseous-lib/Classes/Plugins/MetadataProviders/Storage.cs diff --git a/gaseous-server/Classes/Plugins/Plugins.cs b/gaseous-lib/Classes/Plugins/Plugins.cs similarity index 100% rename from gaseous-server/Classes/Plugins/Plugins.cs rename to gaseous-lib/Classes/Plugins/Plugins.cs diff --git a/gaseous-lib/Classes/ProcessQueue/BackgroundTaskItem.cs b/gaseous-lib/Classes/ProcessQueue/BackgroundTaskItem.cs new file mode 100644 index 0000000..9f00dd4 --- /dev/null +++ b/gaseous-lib/Classes/ProcessQueue/BackgroundTaskItem.cs @@ -0,0 +1,400 @@ +using System.Reflection; +using gaseous_server.Classes; + +namespace gaseous_server.ProcessQueue +{ + public class BackgroundTaskItem + { + public BackgroundTaskItem() + { + + } + + public BackgroundTaskItem(ProcessQueue.QueueItemType TaskName) + { + this.Task = TaskName.ToString(); + this.TaskEnum = TaskName; + + switch (TaskName) + { + case ProcessQueue.QueueItemType.SignatureIngestor: + this._UserManageable = true; + this._SaveLastRunTime = true; + this.DefaultInterval = 60; + this.MinimumAllowedInterval = 20; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this.RunInProcess = false; + break; + + case ProcessQueue.QueueItemType.TitleIngestor: + this._UserManageable = true; + this._SaveLastRunTime = true; + this.DefaultInterval = 1; + this.MinimumAllowedInterval = 1; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this._Blocks = new List{ + ProcessQueue.QueueItemType.OrganiseLibrary, + ProcessQueue.QueueItemType.LibraryScan, + ProcessQueue.QueueItemType.LibraryScanWorker, + ProcessQueue.QueueItemType.MetadataRefresh + }; + this.RunInProcess = true; + break; + + case ProcessQueue.QueueItemType.MetadataRefresh: + this._UserManageable = true; + this._SaveLastRunTime = true; + this.DefaultInterval = 1440; + this.MinimumAllowedInterval = 1440; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this._Blocks = new List + { + ProcessQueue.QueueItemType.OrganiseLibrary, + ProcessQueue.QueueItemType.LibraryScan, + ProcessQueue.QueueItemType.LibraryScanWorker, + ProcessQueue.QueueItemType.TitleIngestor + }; + this.RunInProcess = false; + break; + + case ProcessQueue.QueueItemType.OrganiseLibrary: + this._UserManageable = true; + this._SaveLastRunTime = true; + this.DefaultInterval = 1440; + this.MinimumAllowedInterval = 120; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this._Blocks = new List{ + ProcessQueue.QueueItemType.LibraryScan, + ProcessQueue.QueueItemType.LibraryScanWorker, + ProcessQueue.QueueItemType.TitleIngestor, + ProcessQueue.QueueItemType.MetadataRefresh + }; + this.RunInProcess = true; + break; + + case ProcessQueue.QueueItemType.LibraryScan: + this._UserManageable = true; + this._SaveLastRunTime = true; + this.DefaultInterval = 1440; + this.MinimumAllowedInterval = 120; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this._Blocks = new List{ + ProcessQueue.QueueItemType.OrganiseLibrary, + ProcessQueue.QueueItemType.MetadataRefresh + }; + this.RunInProcess = false; + break; + + case ProcessQueue.QueueItemType.DailyMaintainer: + this._UserManageable = true; + this._SaveLastRunTime = true; + this.DefaultInterval = 1440; + this.MinimumAllowedInterval = 1440; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 1; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 5; + this.DefaultAllowedEndMinutes = 59; + this._Blocks = new List{ + ProcessQueue.QueueItemType.All + }; + this.RunInProcess = false; + break; + + case ProcessQueue.QueueItemType.WeeklyMaintainer: + this._UserManageable = true; + this._SaveLastRunTime = true; + this.DefaultInterval = 10080; + this.MinimumAllowedInterval = 10080; + this.DefaultAllowedDays = new List{ + DayOfWeek.Monday + }; + this.DefaultAllowedStartHours = 1; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 5; + this.DefaultAllowedEndMinutes = 59; + this._Blocks = new List{ + ProcessQueue.QueueItemType.All + }; + this.RunInProcess = false; + break; + + case ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade: + this._UserManageable = false; + this.DefaultInterval = 1; + this.MinimumAllowedInterval = 1; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this._Blocks.Add(ProcessQueue.QueueItemType.All); + this.RunInProcess = true; + break; + + case ProcessQueue.QueueItemType.TempCleanup: + this._UserManageable = true; + this.DefaultInterval = 1; + this.MinimumAllowedInterval = 1; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this.RunInProcess = false; + break; + + default: + this._UserManageable = false; + this.DefaultAllowedDays = new List{ + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + this.DefaultAllowedStartHours = 0; + this.DefaultAllowedStartMinutes = 0; + this.DefaultAllowedEndHours = 23; + this.DefaultAllowedEndMinutes = 59; + this.RunInProcess = true; + break; + } + } + + public string Task { get; set; } + public ProcessQueue.QueueItemType TaskEnum { get; set; } + public bool Enabled + { + get + { + if (_UserManageable == true) + { + return bool.Parse(Config.ReadSetting("Enabled_" + Task, true.ToString())); + } + else + { + return true; + } + } + set + { + if (_UserManageable == true) + { + Config.SetSetting("Enabled_" + Task, value.ToString()); + } + } + } + private bool _UserManageable; + public bool UserManageable => _UserManageable; + private bool _SaveLastRunTime; + public bool SaveLastRunTime => _SaveLastRunTime; + public int Interval + { + get + { + int setInterval = int.Parse(Config.ReadSetting("Interval_" + Task, DefaultInterval.ToString())); + if (setInterval < MinimumAllowedInterval) + { + return DefaultInterval; + } + + return setInterval; + } + } + public int DefaultInterval { get; set; } + public int MinimumAllowedInterval { get; set; } + public bool RunInProcess { get; set; } + public List AllowedDays + { + get + { + string jsonDefaultAllowedDays = Newtonsoft.Json.JsonConvert.SerializeObject(DefaultAllowedDays); + return Newtonsoft.Json.JsonConvert.DeserializeObject>(Config.ReadSetting("AllowedDays_" + Task, jsonDefaultAllowedDays)); + } + } + public int AllowedStartHours + { + get + { + return int.Parse(Config.ReadSetting("AllowedStartHours_" + Task, DefaultAllowedStartHours.ToString())); + } + } + public int AllowedStartMinutes + { + get + { + return int.Parse(Config.ReadSetting("AllowedStartMinutes_" + Task, DefaultAllowedStartMinutes.ToString())); + } + } + public int AllowedEndHours + { + get + { + return int.Parse(Config.ReadSetting("AllowedEndHours_" + Task, DefaultAllowedEndHours.ToString())); + } + } + public int AllowedEndMinutes + { + get + { + return int.Parse(Config.ReadSetting("AllowedEndMinutes_" + Task, DefaultAllowedEndMinutes.ToString())); + } + } + public List DefaultAllowedDays { get; set; } + public int DefaultAllowedStartHours { get; set; } + public int DefaultAllowedStartMinutes { get; set; } + public int DefaultAllowedEndHours { get; set; } + public int DefaultAllowedEndMinutes { get; set; } + private List _Blocks = new List(); + public List Blocks + { + get + { + if (_Blocks.Contains(ProcessQueue.QueueItemType.All)) + { + List blockList = new List(); + List skipBlockItems = new List{ + ProcessQueue.QueueItemType.All, + ProcessQueue.QueueItemType.NotConfigured, + this.TaskEnum + }; + foreach (ProcessQueue.QueueItemType blockType in Enum.GetValues(typeof(ProcessQueue.QueueItemType))) + { + if (!skipBlockItems.Contains(blockType)) + { + blockList.Add(blockType); + } + } + return blockList; + } + else + { + return _Blocks; + } + } + } + public List BlockedBy + { + get + { + List blockedBy = new List(); + + foreach (ProcessQueue.QueueItemType blockType in Enum.GetValues(typeof(ProcessQueue.QueueItemType))) + { + if (blockType != this.TaskEnum) + { + BackgroundTaskItem taskItem = new BackgroundTaskItem(blockType); + if (taskItem.Blocks.Contains(this.TaskEnum)) + { + if (!blockedBy.Contains(blockType)) + { + blockedBy.Add(blockType); + } + } + } + } + + return blockedBy; + } + } + } + + public class BackgroundTaskSettingsItem + { + public string Task { get; set; } + public bool Enabled { get; set; } + public int Interval { get; set; } + public List AllowedDays { get; set; } + public int AllowedStartHours { get; set; } + public int AllowedStartMinutes { get; set; } + public int AllowedEndHours { get; set; } + public int AllowedEndMinutes { get; set; } + } +} \ No newline at end of file diff --git a/gaseous-server/Classes/ProcessQueue/ITaskPlugin.cs b/gaseous-lib/Classes/ProcessQueue/ITaskPlugin.cs similarity index 96% rename from gaseous-server/Classes/ProcessQueue/ITaskPlugin.cs rename to gaseous-lib/Classes/ProcessQueue/ITaskPlugin.cs index 2261044..ed34101 100644 --- a/gaseous-server/Classes/ProcessQueue/ITaskPlugin.cs +++ b/gaseous-lib/Classes/ProcessQueue/ITaskPlugin.cs @@ -1,6 +1,3 @@ -using gaseous_server.Controllers; -using Microsoft.Build.Framework; - namespace gaseous_server.ProcessQueue.Plugins { /// diff --git a/gaseous-server/Classes/ProcessQueue/ProcessQueue.cs b/gaseous-lib/Classes/ProcessQueue/ProcessQueue.cs similarity index 74% rename from gaseous-server/Classes/ProcessQueue/ProcessQueue.cs rename to gaseous-lib/Classes/ProcessQueue/ProcessQueue.cs index e46bf04..480c442 100644 --- a/gaseous-server/Classes/ProcessQueue/ProcessQueue.cs +++ b/gaseous-lib/Classes/ProcessQueue/ProcessQueue.cs @@ -5,7 +5,6 @@ using System.Text.Json.Serialization; using System.Threading.Tasks; using gaseous_server.Classes; using gaseous_server.Classes.Metadata; -using gaseous_server.Controllers; using gaseous_server.Models; using gaseous_server.ProcessQueue.Plugins; using gaseous_server.Classes.Plugins.MetadataProviders.MetadataTypes; @@ -42,6 +41,7 @@ namespace gaseous_server.ProcessQueue AllowedStartMinutes = defaultItem.AllowedStartMinutes; AllowedEndHours = defaultItem.AllowedEndHours; AllowedEndMinutes = defaultItem.AllowedEndMinutes; + _RunInProcess = defaultItem.RunInProcess; AttachPlugin(); } @@ -65,6 +65,7 @@ namespace gaseous_server.ProcessQueue AllowedStartMinutes = defaultItem.AllowedStartMinutes; AllowedEndHours = defaultItem.AllowedEndHours; AllowedEndMinutes = defaultItem.AllowedEndMinutes; + _RunInProcess = defaultItem.RunInProcess; AttachPlugin(); } @@ -128,36 +129,78 @@ namespace gaseous_server.ProcessQueue [Newtonsoft.Json.JsonIgnore] [System.Text.Json.Serialization.JsonIgnore] public List SubTasks { get; set; } = new List(); - public Guid AddSubTask(QueueItemSubTasks TaskType, string TaskName, object? Settings, bool RemoveWhenCompleted) + public async Task AddSubTask(QueueItemSubTasks TaskType, string TaskName, object? Settings, bool RemoveWhenCompleted, string CorrelationId = "") { // check if the task already exists SubTask? existingTask = SubTasks.FirstOrDefault(x => x.TaskType == TaskType && x.TaskName == TaskName); if (existingTask == null) { // generate a new correlation id - Guid correlationId = Guid.NewGuid(); + Guid correlationId = string.IsNullOrEmpty(CorrelationId) ? Guid.NewGuid() : Guid.Parse(CorrelationId); // add the task to the list SubTask subTask = new SubTask(this, TaskType, TaskName, Settings, correlationId); subTask.RemoveWhenStopped = RemoveWhenCompleted; SubTasks.Add(subTask); - Logging.LogKey( - Logging.LogType.Information, - "process.queue_item", - "queue.added_subtask", - null, - new[] { TaskName, TaskType.ToString(), correlationId.ToString() }, - null, - false, - new Dictionary + // send the creation of the new subtask to the reporting server + var outProcessData = CallContext.GetData("OutProcess"); + if (outProcessData != null && bool.TryParse(outProcessData.ToString(), out bool isOutProcess) && isOutProcess) + { + // structure data for reporting server + Dictionary data = new Dictionary { + { "TaskType", TaskType.ToString() }, + { "TaskName", TaskName }, + { "Settings", Settings }, + { "RemoveWhenCompleted", RemoveWhenCompleted }, + { "CorrelationId", correlationId.ToString() } + }; + + string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(data); + var reportingServerUrlData = CallContext.GetData("ReportingServerUrl"); + if (reportingServerUrlData != null) + { + string reportingServerUrl = reportingServerUrlData.ToString(); + if (!string.IsNullOrEmpty(reportingServerUrl)) + { + // send the data to the reporting server + try + { + using (var client = new System.Net.Http.HttpClient()) + { + var content = new System.Net.Http.StringContent(jsonOutput, System.Text.Encoding.UTF8, "application/json"); + var response = client.PostAsync($"{reportingServerUrl}/api/v1.1/BackgroundTasks/{_CorrelationId}/SubTask/", content).Result; + if (!response.IsSuccessStatusCode) + { + Logging.LogKey(Logging.LogType.Warning, "process.queue_item", "queue.failed_to_report_subtask_status", null, new[] { TaskName, TaskType.ToString(), correlationId.ToString(), reportingServerUrl }, null); + } + } + } + catch (Exception ex) + { + Logging.LogKey(Logging.LogType.Warning, "process.queue_item", "queue.error_reporting_subtask_status", null, new[] { TaskName, TaskType.ToString(), correlationId.ToString(), reportingServerUrl }, exceptionValue: ex); + } + } + } + } + + Logging.LogKey( + Logging.LogType.Information, + "process.queue_item", + "queue.added_subtask", + null, + new[] { TaskName, TaskType.ToString(), correlationId.ToString() }, + null, + false, + new Dictionary + { { "ParentQueueItem", _ItemType.ToString() }, { "SubTaskType", TaskType.ToString() }, { "SubTaskName", TaskName }, { "SubTaskCorrelationId", correlationId.ToString() } - } - ); + } + ); return correlationId; } @@ -213,6 +256,10 @@ namespace gaseous_server.ProcessQueue { return _State; } + set + { + _State = value; + } } private QueueItemState _State = QueueItemState.NeverStarted; public bool AllowConcurrentExecution @@ -264,6 +311,13 @@ namespace gaseous_server.ProcessQueue } } private object? _ParentObject = null; + public string ParentCorrelationId + { + get + { + return ParentObject != null ? ((QueueItem)ParentObject).CorrelationId : ""; + } + } public SubTask(object? ParentObject, QueueItemSubTasks TaskType, string TaskName, object? Settings, Guid CorrelationId = default) { _ParentObject = ParentObject; @@ -348,6 +402,36 @@ namespace gaseous_server.ProcessQueue { parent.SubTasks.Remove(this); } + + // remove the subtask from the reporting server + var outProcessData = CallContext.GetData("OutProcess"); + if (outProcessData != null && bool.TryParse(outProcessData.ToString(), out bool isOutProcess) && isOutProcess) + { + var reportingServerUrlData = CallContext.GetData("ReportingServerUrl"); + if (reportingServerUrlData != null) + { + string reportingServerUrl = reportingServerUrlData.ToString(); + if (!string.IsNullOrEmpty(reportingServerUrl)) + { + // send the data to the reporting server + try + { + using (var client = new System.Net.Http.HttpClient()) + { + var response = client.DeleteAsync($"{reportingServerUrl}/api/v1.1/BackgroundTasks/{ParentCorrelationId}/SubTask/?SubTaskId={_CorrelationId}").Result; + if (!response.IsSuccessStatusCode) + { + Logging.LogKey(Logging.LogType.Warning, "process.queue_item", "queue.failed_to_report_subtask_removal", null, new[] { TaskName, TaskType.ToString(), _CorrelationId.ToString(), reportingServerUrl }, null); + } + } + } + catch (Exception ex) + { + Logging.LogKey(Logging.LogType.Warning, "process.queue_item", "queue.error_reporting_subtask_removal", null, new[] { TaskName, TaskType.ToString(), _CorrelationId.ToString(), reportingServerUrl }, exceptionValue: ex); + } + } + } + } } } } @@ -381,6 +465,14 @@ namespace gaseous_server.ProcessQueue return _ForceExecute; } } + private bool _RunInProcess = true; + public bool RunInProcess + { + get + { + return _RunInProcess; + } + } private bool _AllowManualStart = true; private bool _RemoveWhenStopped = false; private bool _IsBlocked = false; @@ -517,7 +609,17 @@ namespace gaseous_server.ProcessQueue public object? Options { get; set; } = null; public string CurrentState { get; set; } = ""; public string CurrentStateProgress { get; set; } = ""; - public string CorrelationId => _CorrelationId; + public string CorrelationId + { + get + { + return _CorrelationId; + } + set + { + _CorrelationId = value; + } + } [System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonIgnore] @@ -539,37 +641,91 @@ namespace gaseous_server.ProcessQueue _LastError = null; // set the correlation id - Guid correlationId = Guid.NewGuid(); - _CorrelationId = correlationId.ToString(); - CallContext.SetData("CorrelationId", correlationId); + if (string.IsNullOrEmpty(_CorrelationId)) + { + Guid correlationId = Guid.NewGuid(); + _CorrelationId = correlationId.ToString(); + CallContext.SetData("CorrelationId", correlationId); + } CallContext.SetData("CallingProcess", _ItemType.ToString()); CallContext.SetData("CallingUser", "System"); // log the start Logging.LogKey(Logging.LogType.Debug, "process.timered_event", "timered_event.executing_item_with_correlation_id", null, new[] { _ItemType.ToString(), _CorrelationId }); - try + string? OutProcessData = CallContext.GetData("OutProcess")?.ToString(); + bool isOutProcess = false; + // isOutProcess is only true if we're launched from the process host with the intention to run out of process, if the value is not set, or is not a valid boolean, then we should default to running in process + if (bool.TryParse(OutProcessData, out bool outProcessValue)) { - if (Task != null) + isOutProcess = outProcessValue; + } + + DateTime startTime = DateTime.UtcNow; + + if (isOutProcess == false && this.RunInProcess == false) + { + // if the task is configured to run out of process, but we're currently running in process, then we should launch a new instance of the process host to run the task, rather than running it in the current process + string[] args = new string[] { - // execute the task plugin - DateTime startTime = DateTime.UtcNow; - await Task.Execute(); - _LastRunDuration = (DateTime.UtcNow - startTime).TotalSeconds; + "gaseous-processhost.dll", + "--service", _ItemType.ToString(), + "--correlationid", _CorrelationId, + "--reportingserver", $"http://localhost:{Config.LocalCommsPort}" + }; + using var process = new System.Diagnostics.Process + { + StartInfo = new System.Diagnostics.ProcessStartInfo + { + FileName = "dotnet", + WorkingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), + Arguments = string.Join(" ", args), + UseShellExecute = false, + RedirectStandardOutput = false, + RedirectStandardError = false, + CreateNoWindow = true + } + }; + + Console.WriteLine(string.Join(" ", args)); + + process.Start(); + await process.WaitForExitAsync(); + + if (process.ExitCode != 0) + { + throw new Exception("Service-host exited with code " + process.ExitCode); } - // execute sub tasks - if (SubTasks != null) + // clear all subtasks as they were executed in the out of process instance + SubTasks.Clear(); + } + else + { + // execute the task in this process + try { - SubTaskExecute(); + if (Task != null) + { + // execute the task plugin + await Task.Execute(); + } + + // execute sub tasks + if (SubTasks != null) + { + SubTaskExecute(); + } + } + catch (Exception ex) + { + Logging.LogKey(Logging.LogType.Warning, "process.timered_event", "timered_event.error_occurred", null, null, ex); + _LastResult = ""; + _LastError = ex.ToString(); } } - catch (Exception ex) - { - Logging.LogKey(Logging.LogType.Warning, "process.timered_event", "timered_event.error_occurred", null, null, ex); - _LastResult = ""; - _LastError = ex.ToString(); - } + + _LastRunDuration = (DateTime.UtcNow - startTime).TotalSeconds; _ForceExecute = false; if (_DisableWhenComplete == false) diff --git a/gaseous-lib/Classes/ProcessQueue/QueueItemStatus.cs b/gaseous-lib/Classes/ProcessQueue/QueueItemStatus.cs new file mode 100644 index 0000000..f08f75f --- /dev/null +++ b/gaseous-lib/Classes/ProcessQueue/QueueItemStatus.cs @@ -0,0 +1,112 @@ +namespace gaseous_server.Classes +{ + public class QueueItemStatus + { + internal object? CallingQueueItem = null; + + private int _CurrentItemNumber = 0; + private int _MaxItemsNumber = 0; + private string _StatusText = ""; + + public int CurrentItemNumber => _CurrentItemNumber; + public int MaxItemsNumber => _MaxItemsNumber; + public string StatusText => _StatusText; + + public void SetStatus(int CurrentItemNumber, int MaxItemsNumber, string StatusText) + { + this._CurrentItemNumber = CurrentItemNumber; + this._MaxItemsNumber = MaxItemsNumber; + this._StatusText = StatusText; + + SetCallingItemState(_CurrentItemNumber + " of " + _MaxItemsNumber + ": " + _StatusText, _CurrentItemNumber + " of " + _MaxItemsNumber); + } + + public void ClearStatus() + { + this._CurrentItemNumber = 0; + this._MaxItemsNumber = 0; + this._StatusText = ""; + + // SetCallingItemState("", ""); + } + + private void SetCallingItemState(string state, string progress) + { + if (CallingQueueItem != null) + { + // get object type of CallingQueueItem + string type = CallingQueueItem.GetType().ToString(); + + // check if type is QueueItem + switch (type) + { + case "gaseous_server.ProcessQueue.QueueProcessor+QueueItem": + // set CallingQueueItem to QueueItem + ProcessQueue.QueueProcessor.QueueItem callingQueueItem = (ProcessQueue.QueueProcessor.QueueItem)CallingQueueItem; + callingQueueItem.CurrentState = state; + callingQueueItem.CurrentStateProgress = progress; + break; + case "gaseous_server.ProcessQueue.QueueProcessor+QueueItem+SubTask": + // set CallingQueueItem to QueueItem.SubTask + ProcessQueue.QueueProcessor.QueueItem.SubTask callingSubTask = (ProcessQueue.QueueProcessor.QueueItem.SubTask)CallingQueueItem; + callingSubTask.CurrentState = state; + callingSubTask.CurrentStateProgress = progress; + break; + } + + SendStatusToReportingServer(CallingQueueItem.GetType(), state, progress); + } + } + + private void SendStatusToReportingServer(Type type, string state, string progress) + { + var outProcessData = CallContext.GetData("OutProcess"); + if (CallingQueueItem != null && outProcessData != null && bool.TryParse(outProcessData.ToString(), out bool isOutProcess) && isOutProcess) + { + // structure data for reporting server + Dictionary data = new Dictionary + { + { "CurrentState", state }, + { "CurrentStateProgress", progress } + }; + + string url = ""; + if (type == typeof(ProcessQueue.QueueProcessor.QueueItem)) + { + url = $"/api/v1.1/BackgroundTasks/{((ProcessQueue.QueueProcessor.QueueItem)CallingQueueItem).CorrelationId}/"; + } + else if (type == typeof(ProcessQueue.QueueProcessor.QueueItem.SubTask)) + { + url = $"/api/v1.1/BackgroundTasks/{((ProcessQueue.QueueProcessor.QueueItem.SubTask)CallingQueueItem).ParentCorrelationId}/SubTask/{((ProcessQueue.QueueProcessor.QueueItem.SubTask)CallingQueueItem).CorrelationId}/"; + } + + string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(data); + var reportingServerUrlData = CallContext.GetData("ReportingServerUrl"); + if (reportingServerUrlData != null) + { + string reportingServerUrl = reportingServerUrlData.ToString(); + if (!string.IsNullOrEmpty(reportingServerUrl)) + { + // send the data to the reporting server + try + { + using (var client = new System.Net.Http.HttpClient()) + { + var content = new System.Net.Http.StringContent(jsonOutput, System.Text.Encoding.UTF8, "application/json"); + + string sendUrl = $"{reportingServerUrl}{url}"; + + var response = client.PutAsync(sendUrl, content).Result; + } + } + catch (Exception ex) + { + // swallow the error + Console.WriteLine(ex.ToString()); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/gaseous-server/Classes/ProcessQueue/Tasks.cs b/gaseous-lib/Classes/ProcessQueue/Tasks.cs similarity index 93% rename from gaseous-server/Classes/ProcessQueue/Tasks.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks.cs index 2360482..7337e37 100644 --- a/gaseous-server/Classes/ProcessQueue/Tasks.cs +++ b/gaseous-lib/Classes/ProcessQueue/Tasks.cs @@ -90,30 +90,35 @@ namespace gaseous_server.ProcessQueue /// Processes items in the import queue. /// ImportQueueProcessor, - + /// /// Refreshes platform-related metadata. /// MetadataRefresh_Platform, - + /// /// Refreshes signature metadata. /// MetadataRefresh_Signatures, - + /// /// Refreshes game metadata. /// MetadataRefresh_Game, - + /// /// Executes database migration 1031. /// DatabaseMigration_1031, - + /// /// Performs work for the library scan task. /// - LibraryScanWorker + LibraryScanWorker, + + /// + /// Import signatures from a specific parser type - set the options attribute to the parser type to use + /// + SignatureIngest } } \ No newline at end of file diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/BackgroundDatabaseUpgrade.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/BackgroundDatabaseUpgrade.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/BackgroundDatabaseUpgrade.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/BackgroundDatabaseUpgrade.cs diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/CollectionCompiler.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/CollectionCompiler.cs similarity index 88% rename from gaseous-server/Classes/ProcessQueue/Tasks/CollectionCompiler.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/CollectionCompiler.cs index 782410c..bdb337b 100644 --- a/gaseous-server/Classes/ProcessQueue/Tasks/CollectionCompiler.cs +++ b/gaseous-lib/Classes/ProcessQueue/Tasks/CollectionCompiler.cs @@ -23,7 +23,7 @@ namespace gaseous_server.ProcessQueue.Plugins if (ParentQueueItem.Options != null) { Dictionary collectionOptions = (Dictionary)ParentQueueItem.Options; - Classes.Collections.CompileCollections((long)collectionOptions["Id"], (string)collectionOptions["UserId"]); + // Classes.Collections.CompileCollections((long)collectionOptions["Id"], (string)collectionOptions["UserId"]); } } } diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/DailyMaintainer.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/DailyMaintainer.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/DailyMaintainer.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/DailyMaintainer.cs diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/ImportQueueProcessor.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/ImportQueueProcessor.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/ImportQueueProcessor.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/ImportQueueProcessor.cs diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/LibraryScan.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/LibraryScan.cs similarity index 94% rename from gaseous-server/Classes/ProcessQueue/Tasks/LibraryScan.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/LibraryScan.cs index b1e4a5d..9369ac2 100644 --- a/gaseous-server/Classes/ProcessQueue/Tasks/LibraryScan.cs +++ b/gaseous-lib/Classes/ProcessQueue/Tasks/LibraryScan.cs @@ -29,7 +29,7 @@ namespace gaseous_server.ProcessQueue.Plugins // process each library foreach (GameLibrary.LibraryItem library in libraries) { - Guid childCorrelationId = ParentQueueItem.AddSubTask(QueueItemSubTasks.LibraryScanWorker, library.Name, library, true); + Guid childCorrelationId = await ParentQueueItem.AddSubTask(QueueItemSubTasks.LibraryScanWorker, library.Name, library, true); Logging.LogKey(Logging.LogType.Information, "process.library_scan", "libraryscan.queuing_library_for_scanning_with_correlation_id", null, new[] { library.Name, childCorrelationId.ToString() }); } } diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/MediaGroupCompiler.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/MediaGroupCompiler.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/MediaGroupCompiler.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/MediaGroupCompiler.cs diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/MetadataRefresh.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/MetadataRefresh.cs similarity index 92% rename from gaseous-server/Classes/ProcessQueue/Tasks/MetadataRefresh.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/MetadataRefresh.cs index eee9154..ab5ff2b 100644 --- a/gaseous-server/Classes/ProcessQueue/Tasks/MetadataRefresh.cs +++ b/gaseous-lib/Classes/ProcessQueue/Tasks/MetadataRefresh.cs @@ -32,9 +32,9 @@ namespace gaseous_server.ProcessQueue.Plugins } // set up metadata refresh subtasks - ParentQueueItem.AddSubTask(QueueItemSubTasks.MetadataRefresh_Platform, "Platform Metadata", null, true); - ParentQueueItem.AddSubTask(QueueItemSubTasks.MetadataRefresh_Signatures, "Signature Metadata", null, true); - ParentQueueItem.AddSubTask(QueueItemSubTasks.MetadataRefresh_Game, "Game Metadata", null, true); + _ = ParentQueueItem.AddSubTask(QueueItemSubTasks.MetadataRefresh_Platform, "Platform Metadata", null, true); + _ = ParentQueueItem.AddSubTask(QueueItemSubTasks.MetadataRefresh_Signatures, "Signature Metadata", null, true); + _ = ParentQueueItem.AddSubTask(QueueItemSubTasks.MetadataRefresh_Game, "Game Metadata", null, true); } /// diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/OrganiseLibrary.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/OrganiseLibrary.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/OrganiseLibrary.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/OrganiseLibrary.cs diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/SignatureIngestor.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/SignatureIngestor.cs similarity index 79% rename from gaseous-server/Classes/ProcessQueue/Tasks/SignatureIngestor.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/SignatureIngestor.cs index 31258f0..9f965b8 100644 --- a/gaseous-server/Classes/ProcessQueue/Tasks/SignatureIngestor.cs +++ b/gaseous-lib/Classes/ProcessQueue/Tasks/SignatureIngestor.cs @@ -5,7 +5,7 @@ namespace gaseous_server.ProcessQueue.Plugins /// /// Represents a plugin for ingesting signature items. /// - public class SignatureIngestor : ITaskPlugin + public class SignatureIngestor : QueueItemStatus, ITaskPlugin { /// public QueueItemType ItemType => QueueItemType.SignatureIngestor; @@ -25,8 +25,15 @@ namespace gaseous_server.ProcessQueue.Plugins CallingQueueItem = ParentQueueItem }; - foreach (int i in Enum.GetValues(typeof(gaseous_signature_parser.parser.SignatureParser))) + // Set CallingQueueItem for status updates + CallingQueueItem = ParentQueueItem; + + var parserTypes = Enum.GetValues(typeof(gaseous_signature_parser.parser.SignatureParser)); + int counter = 0; + foreach (int i in parserTypes) { + counter++; + SetStatus(counter, parserTypes.Length, "Processing " + ((gaseous_signature_parser.parser.SignatureParser)i).ToString() + " signature files"); gaseous_signature_parser.parser.SignatureParser parserType = (gaseous_signature_parser.parser.SignatureParser)i; if ( parserType != gaseous_signature_parser.parser.SignatureParser.Auto && @@ -51,6 +58,7 @@ namespace gaseous_server.ProcessQueue.Plugins tIngest.Import(SignaturePath, SignatureProcessedPath, parserType); } } + ClearStatus(); } } } \ No newline at end of file diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/TempCleanup.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/TempCleanup.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/TempCleanup.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/TempCleanup.cs diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/TitleIngestor.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/TitleIngestor.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/TitleIngestor.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/TitleIngestor.cs diff --git a/gaseous-server/Classes/ProcessQueue/Tasks/WeeklyMaintainer.cs b/gaseous-lib/Classes/ProcessQueue/Tasks/WeeklyMaintainer.cs similarity index 100% rename from gaseous-server/Classes/ProcessQueue/Tasks/WeeklyMaintainer.cs rename to gaseous-lib/Classes/ProcessQueue/Tasks/WeeklyMaintainer.cs diff --git a/gaseous-server/Classes/ProcessQueue/Timer.cs b/gaseous-lib/Classes/ProcessQueue/Timer.cs similarity index 83% rename from gaseous-server/Classes/ProcessQueue/Timer.cs rename to gaseous-lib/Classes/ProcessQueue/Timer.cs index 24b1dec..d7c8eaf 100644 --- a/gaseous-server/Classes/ProcessQueue/Timer.cs +++ b/gaseous-lib/Classes/ProcessQueue/Timer.cs @@ -1,19 +1,13 @@ using System; using gaseous_server.Classes; +using Microsoft.Extensions.Hosting; namespace gaseous_server { // see: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0&tabs=visual-studio-mac#timed-background-tasks-1 public class TimedHostedService : IHostedService, IDisposable { - private int executionCount = 0; - //private readonly ILogger _logger; - private Timer _timer; - - //public TimedHostedService(ILogger logger) - //{ - // _logger = logger; - //} + private Timer? _timer = null; public Task StartAsync(CancellationToken stoppingToken) { @@ -28,7 +22,11 @@ namespace gaseous_server private void DoWork(object state) { - var count = Interlocked.Increment(ref executionCount); + // if background tasks are disabled, do not execute any tasks in the queue + if (!Config.BackgroundTasksEnabled) + { + return; + } // don't execute if the server first run state is not up to date if (Config.FirstRunStatus != Config.FirstRunStatusWhenSet) @@ -68,6 +66,15 @@ namespace gaseous_server // execute queued process _ = Task.Run(() => qi.Execute()); + // Wait for the state to change to Running or timeout after 500ms + // This prevents race conditions where the next task checks before this one sets its state + var startWait = DateTime.UtcNow; + while (qi.ItemState != ProcessQueue.QueueProcessor.QueueItemState.Running && + (DateTime.UtcNow - startWait).TotalMilliseconds < 500) + { + Thread.Sleep(10); // Small delay to avoid busy waiting + } + if (qi.RemoveWhenStopped == true && qi.ItemState == ProcessQueue.QueueProcessor.QueueItemState.Stopped) { ProcessQueue.QueueProcessor.QueueItems.Remove(qi); diff --git a/gaseous-server/Classes/RomMediaGroup.cs b/gaseous-lib/Classes/RomMediaGroup.cs similarity index 100% rename from gaseous-server/Classes/RomMediaGroup.cs rename to gaseous-lib/Classes/RomMediaGroup.cs diff --git a/gaseous-server/Classes/Roms.cs b/gaseous-lib/Classes/Roms.cs similarity index 100% rename from gaseous-server/Classes/Roms.cs rename to gaseous-lib/Classes/Roms.cs diff --git a/gaseous-server/Classes/SignatureIngestors/XML.cs b/gaseous-lib/Classes/SignatureIngestors/XML.cs similarity index 96% rename from gaseous-server/Classes/SignatureIngestors/XML.cs rename to gaseous-lib/Classes/SignatureIngestors/XML.cs index 48327db..7ed6182 100644 --- a/gaseous-server/Classes/SignatureIngestors/XML.cs +++ b/gaseous-lib/Classes/SignatureIngestors/XML.cs @@ -385,6 +385,20 @@ namespace gaseous_server.SignatureIngestors.XML dbDict.Add("metadatasource", romObject.SignatureSource); dbDict.Add("ingestorversion", 3); + Dictionary? countries = new Dictionary(); + if (romObject.Country != null) + { + countries = romObject.Country; + } + dbDict.Add("countries", Newtonsoft.Json.JsonConvert.SerializeObject(countries)); + + Dictionary? languages = new Dictionary(); + if (romObject.Language != null) + { + languages = romObject.Language; + } + dbDict.Add("languages", Newtonsoft.Json.JsonConvert.SerializeObject(languages)); + sigDB = db.ExecuteCMD(sql, dbDict); if (sigDB.Rows.Count == 0) { @@ -411,7 +425,7 @@ namespace gaseous_server.SignatureIngestors.XML } // update the rom entry - sql = "UPDATE Signatures_Roms SET `GameId`=@gameid, `Name`=@name, `Size`=@size,`DevelopmentStatus`=@developmentstatus, `Attributes`=@attributes, `RomType`=@romtype, `RomTypeMedia`=@romtypemedia, `MediaLabel`=@medialabel, `MetadataSource`=@metadatasource, `Countries`=@countries, `Languages`=@languages WHERE `Id`=@romid;"; + sql = "UPDATE Signatures_Roms SET `GameId`=@gameid, `Name`=@name, `Size`=@size,`DevelopmentStatus`=@developmentstatus, `Attributes`=@attributes, `RomType`=@romtype, `RomTypeMedia`=@romtypemedia, `MediaLabel`=@medialabel, `MetadataSource`=@metadatasource WHERE `Id`=@romid;"; db.ExecuteCMD(sql, dbDict); } diff --git a/gaseous-server/Classes/SignatureManagement.cs b/gaseous-lib/Classes/SignatureManagement.cs similarity index 100% rename from gaseous-server/Classes/SignatureManagement.cs rename to gaseous-lib/Classes/SignatureManagement.cs diff --git a/gaseous-server/Classes/Statistics.cs b/gaseous-lib/Classes/Statistics.cs similarity index 100% rename from gaseous-server/Classes/Statistics.cs rename to gaseous-lib/Classes/Statistics.cs diff --git a/gaseous-lib/Classes/SystemInfo.cs b/gaseous-lib/Classes/SystemInfo.cs new file mode 100644 index 0000000..4c0e173 --- /dev/null +++ b/gaseous-lib/Classes/SystemInfo.cs @@ -0,0 +1,20 @@ +using gaseous_server.Models; + +namespace gaseous_server.Classes +{ + public class SystemInfo + { + public static SystemInfoModel.PathItem GetDisk(string Path) + { + SystemInfoModel.PathItem pathItem = new SystemInfoModel.PathItem + { + LibraryPath = Path, + SpaceUsed = Common.DirSize(new DirectoryInfo(Path)), + SpaceAvailable = new DriveInfo(Path).AvailableFreeSpace, + TotalSpace = new DriveInfo(Path).TotalSize + }; + + return pathItem; + } + } +} \ No newline at end of file diff --git a/gaseous-server/Classes/UserProfile.cs b/gaseous-lib/Classes/UserProfile.cs similarity index 100% rename from gaseous-server/Classes/UserProfile.cs rename to gaseous-lib/Classes/UserProfile.cs diff --git a/gaseous-server/Configuration/ConfigFile_v1.cs b/gaseous-lib/Configuration/ConfigFile_v1.cs similarity index 85% rename from gaseous-server/Configuration/ConfigFile_v1.cs rename to gaseous-lib/Configuration/ConfigFile_v1.cs index e2966bb..eb330e8 100644 --- a/gaseous-server/Configuration/ConfigFile_v1.cs +++ b/gaseous-lib/Configuration/ConfigFile_v1.cs @@ -77,6 +77,28 @@ namespace gaseous_server.Classes } } + private static int _LocalCommsPort + { + get + { + try + { + var env = Environment.GetEnvironmentVariable("localcommsport"); + if (!string.IsNullOrWhiteSpace(env) && int.TryParse(env, out var p)) return p; + } + catch + { + // errors can be ignored as we'll just return the default port if there's an issue with the environment variable + } + return 5197; + } + } + + /// + /// The port used for local inter-process communication between the main server process and any child processes (e.g. for task execution in the process host). This is used in the setup of the local communication channel to determine which port to use for sending messages between processes. The default value is 5197, but it can be overridden with the "localcommsport" environment variable when running in Docker for easy configuration without modifying the config file. This allows users running in Docker to specify the desired local communication port through environment variables, while still providing a sensible default for users running outside of Docker. + /// + public int LocalCommsPort = _LocalCommsPort; + /// /// The language that the server uses for its responses and localization. This is used throughout the codebase wherever localized strings are needed, and is loaded from the config file on initialization of this class. The default value is determined by the "serverlanguage" environment variable when running in Docker, allowing for easy configuration of the server language without modifying the config file. If the environment variable is not set, it falls back to the default locale defined in the Localisation class. This allows users to specify their preferred server language through environment variables when running in Docker, while still providing a sensible default for users running outside of Docker. /// diff --git a/gaseous-server/Configuration/Models/Database.cs b/gaseous-lib/Configuration/Models/Database.cs similarity index 100% rename from gaseous-server/Configuration/Models/Database.cs rename to gaseous-lib/Configuration/Models/Database.cs diff --git a/gaseous-server/Configuration/Models/Library.cs b/gaseous-lib/Configuration/Models/Library.cs similarity index 100% rename from gaseous-server/Configuration/Models/Library.cs rename to gaseous-lib/Configuration/Models/Library.cs diff --git a/gaseous-server/Configuration/Models/Logging.cs b/gaseous-lib/Configuration/Models/Logging.cs similarity index 100% rename from gaseous-server/Configuration/Models/Logging.cs rename to gaseous-lib/Configuration/Models/Logging.cs diff --git a/gaseous-server/Configuration/Models/MetadataAPI.cs b/gaseous-lib/Configuration/Models/MetadataAPI.cs similarity index 100% rename from gaseous-server/Configuration/Models/MetadataAPI.cs rename to gaseous-lib/Configuration/Models/MetadataAPI.cs diff --git a/gaseous-server/Configuration/Models/Providers/IGDB.cs b/gaseous-lib/Configuration/Models/Providers/IGDB.cs similarity index 100% rename from gaseous-server/Configuration/Models/Providers/IGDB.cs rename to gaseous-lib/Configuration/Models/Providers/IGDB.cs diff --git a/gaseous-server/Configuration/Models/Security/ReversProxy.cs b/gaseous-lib/Configuration/Models/Security/ReversProxy.cs similarity index 100% rename from gaseous-server/Configuration/Models/Security/ReversProxy.cs rename to gaseous-lib/Configuration/Models/Security/ReversProxy.cs diff --git a/gaseous-server/Configuration/Models/Security/SocialAuth.cs b/gaseous-lib/Configuration/Models/Security/SocialAuth.cs similarity index 100% rename from gaseous-server/Configuration/Models/Security/SocialAuth.cs rename to gaseous-lib/Configuration/Models/Security/SocialAuth.cs diff --git a/gaseous-server/Models/ClearLogoItem.cs b/gaseous-lib/Models/ClearLogoItem.cs similarity index 100% rename from gaseous-server/Models/ClearLogoItem.cs rename to gaseous-lib/Models/ClearLogoItem.cs diff --git a/gaseous-server/Models/ContentModel.cs b/gaseous-lib/Models/ContentModel.cs similarity index 100% rename from gaseous-server/Models/ContentModel.cs rename to gaseous-lib/Models/ContentModel.cs diff --git a/gaseous-server/Models/ContentUploadForms.cs b/gaseous-lib/Models/ContentUploadForms.cs similarity index 100% rename from gaseous-server/Models/ContentUploadForms.cs rename to gaseous-lib/Models/ContentUploadForms.cs diff --git a/gaseous-server/Models/GameSave.cs b/gaseous-lib/Models/GameSave.cs similarity index 100% rename from gaseous-server/Models/GameSave.cs rename to gaseous-lib/Models/GameSave.cs diff --git a/gaseous-server/Models/GameState.cs b/gaseous-lib/Models/GameState.cs similarity index 100% rename from gaseous-server/Models/GameState.cs rename to gaseous-lib/Models/GameState.cs diff --git a/gaseous-server/Models/GaseousGame.cs b/gaseous-lib/Models/GaseousGame.cs similarity index 100% rename from gaseous-server/Models/GaseousGame.cs rename to gaseous-lib/Models/GaseousGame.cs diff --git a/gaseous-server/Models/ImageItem.cs b/gaseous-lib/Models/ImageItem.cs similarity index 100% rename from gaseous-server/Models/ImageItem.cs rename to gaseous-lib/Models/ImageItem.cs diff --git a/gaseous-server/Models/ImportState.cs b/gaseous-lib/Models/ImportState.cs similarity index 100% rename from gaseous-server/Models/ImportState.cs rename to gaseous-lib/Models/ImportState.cs diff --git a/gaseous-server/Models/LocaleFileModel.cs b/gaseous-lib/Models/LocaleFileModel.cs similarity index 100% rename from gaseous-server/Models/LocaleFileModel.cs rename to gaseous-lib/Models/LocaleFileModel.cs diff --git a/gaseous-server/Models/LocaleSummaryModel.cs b/gaseous-lib/Models/LocaleSummaryModel.cs similarity index 100% rename from gaseous-server/Models/LocaleSummaryModel.cs rename to gaseous-lib/Models/LocaleSummaryModel.cs diff --git a/gaseous-server/Models/MetadataMap.cs b/gaseous-lib/Models/MetadataMap.cs similarity index 100% rename from gaseous-server/Models/MetadataMap.cs rename to gaseous-lib/Models/MetadataMap.cs diff --git a/gaseous-server/Models/MetadataModel.cs b/gaseous-lib/Models/MetadataModel.cs similarity index 100% rename from gaseous-server/Models/MetadataModel.cs rename to gaseous-lib/Models/MetadataModel.cs diff --git a/gaseous-server/Models/PlatformMapping.cs b/gaseous-lib/Models/PlatformMapping.cs similarity index 99% rename from gaseous-server/Models/PlatformMapping.cs rename to gaseous-lib/Models/PlatformMapping.cs index 9dd8a3f..72457f7 100644 --- a/gaseous-server/Models/PlatformMapping.cs +++ b/gaseous-lib/Models/PlatformMapping.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using System.Web; using gaseous_server.Classes; using gaseous_server.Classes.Metadata; -using gaseous_server.Controllers; using gaseous_server.Classes.Plugins.MetadataProviders.MetadataTypes; using Newtonsoft.Json; using gaseous_server.Classes.Plugins.MetadataProviders; @@ -28,7 +27,7 @@ namespace gaseous_server.Models /// public static async Task ExtractPlatformMap(bool ResetToDefault = false) { - using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("gaseous_server.Support.PlatformMap.json")) + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("gaseous_lib.Support.PlatformMap.json")) using (StreamReader reader = new StreamReader(stream)) { string rawJson = await reader.ReadToEndAsync(); @@ -123,7 +122,7 @@ namespace gaseous_server.Models return platform; } - // + /// /// Gets the list of supported file extensions. /// public static List SupportedFileExtensions { get; } = new List(); diff --git a/gaseous-server/Models/Signatures_Games.cs b/gaseous-lib/Models/Signatures_Games.cs similarity index 100% rename from gaseous-server/Models/Signatures_Games.cs rename to gaseous-lib/Models/Signatures_Games.cs diff --git a/gaseous-server/Models/Signatures_Sources.cs b/gaseous-lib/Models/Signatures_Sources.cs similarity index 100% rename from gaseous-server/Models/Signatures_Sources.cs rename to gaseous-lib/Models/Signatures_Sources.cs diff --git a/gaseous-server/Models/Signatures_Status.cs b/gaseous-lib/Models/Signatures_Status.cs similarity index 100% rename from gaseous-server/Models/Signatures_Status.cs rename to gaseous-lib/Models/Signatures_Status.cs diff --git a/gaseous-server/Models/StatisticsModel.cs b/gaseous-lib/Models/StatisticsModel.cs similarity index 100% rename from gaseous-server/Models/StatisticsModel.cs rename to gaseous-lib/Models/StatisticsModel.cs diff --git a/gaseous-lib/Models/SystemInfo.cs b/gaseous-lib/Models/SystemInfo.cs new file mode 100644 index 0000000..37e98ed --- /dev/null +++ b/gaseous-lib/Models/SystemInfo.cs @@ -0,0 +1,147 @@ +using System.Reflection; +using gaseous_server.Classes; + +namespace gaseous_server.Models +{ + public class SystemInfoModel + { + public Version ApplicationVersion + { + get + { + return Assembly.GetExecutingAssembly().GetName().Version; + } + } + public List? Paths { get; set; } + public long DatabaseSize { get; set; } + public List? PlatformStatistics { get; set; } + + public class PathItem + { + public string Name { get; set; } + public string LibraryPath { get; set; } + public long SpaceUsed { get; set; } + public long SpaceAvailable { get; set; } + public long TotalSpace { get; set; } + } + + public class PlatformStatisticsItem + { + public string Platform { get; set; } + public long RomCount { get; set; } + public long TotalSize { get; set; } + } + } + + public class SystemSettingsModel + { + public bool AlwaysLogToDisk { get; set; } + public int MinimumLogRetentionPeriod { get; set; } + public bool EmulatorDebugMode { get; set; } + public SignatureSourceItem SignatureSource { get; set; } + public List MetadataSources { get; set; } + + public class SignatureSourceItem + { + public HasheousClient.Models.MetadataModel.SignatureSources Source { get; set; } + public string HasheousHost { get; set; } + public string HasheousAPIKey { get; set; } + public bool HasheousSubmitFixes { get; set; } + } + + public class MetadataSourceItem + { + public MetadataSourceItem() + { + + } + + public MetadataSourceItem(FileSignature.MetadataSources source, bool useHasheousProxy, string clientId, string secret, FileSignature.MetadataSources defaultSource) + { + Source = source; + UseHasheousProxy = useHasheousProxy; + ClientId = clientId; + Secret = secret; + if (Source == defaultSource) + { + Default = true; + } + else + { + Default = false; + } + } + + public FileSignature.MetadataSources Source { get; set; } + public bool UseHasheousProxy { get; set; } + public string ClientId { get; set; } + public string Secret { get; set; } + public bool Default { get; set; } + public bool? Configured + { + get + { + switch (Source) + { + case FileSignature.MetadataSources.None: + return true; + case FileSignature.MetadataSources.IGDB: + if ((!String.IsNullOrEmpty(ClientId) && !String.IsNullOrEmpty(Secret)) || UseHasheousProxy == true) + { + return true; + } + else + { + return false; + } + case FileSignature.MetadataSources.TheGamesDb: + if ((!String.IsNullOrEmpty(ClientId) && !String.IsNullOrEmpty(Secret)) || UseHasheousProxy == true) + { + return true; + } + else + { + return false; + } + default: + return false; + } + } + } + public bool? UsesProxy + { + get + { + switch (Source) + { + case FileSignature.MetadataSources.None: + return false; + case FileSignature.MetadataSources.IGDB: + return true; + case FileSignature.MetadataSources.TheGamesDb: + return true; + default: + return false; + } + } + } + public bool? UsesClientIdAndSecret + { + get + { + switch (Source) + { + case FileSignature.MetadataSources.None: + return false; + case FileSignature.MetadataSources.IGDB: + return true; + case FileSignature.MetadataSources.TheGamesDb: + return false; + default: + return false; + } + } + } + } + } +} \ No newline at end of file diff --git a/gaseous-server/Models/UserProfile.cs b/gaseous-lib/Models/UserProfile.cs similarity index 100% rename from gaseous-server/Models/UserProfile.cs rename to gaseous-lib/Models/UserProfile.cs diff --git a/gaseous-server/wwwroot/images/Ratings/AgeGroupMap.json b/gaseous-lib/Support/AgeGroupMap.json similarity index 100% rename from gaseous-server/wwwroot/images/Ratings/AgeGroupMap.json rename to gaseous-lib/Support/AgeGroupMap.json diff --git a/gaseous-server/Support/Country.txt b/gaseous-lib/Support/Country.txt similarity index 100% rename from gaseous-server/Support/Country.txt rename to gaseous-lib/Support/Country.txt diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1000.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1000.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1000.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1000.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1001.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1001.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1001.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1001.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1002.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1002.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1002.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1002.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1003.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1003.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1003.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1003.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1004.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1004.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1004.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1004.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1005.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1005.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1005.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1005.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1006.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1006.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1006.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1006.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1007.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1007.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1007.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1007.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1008.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1008.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1008.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1008.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1009.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1009.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1009.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1009.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1010.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1010.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1010.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1010.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1011.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1011.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1011.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1011.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1012.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1012.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1012.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1012.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1013.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1013.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1013.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1013.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1014.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1014.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1014.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1014.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1015.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1015.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1015.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1015.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1016.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1016.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1016.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1016.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1017.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1017.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1017.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1017.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1018.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1018.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1018.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1018.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1019.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1019.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1019.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1019.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1020.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1020.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1020.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1020.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1021.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1021.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1021.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1021.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1022.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1022.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1022.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1022.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1023.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1023.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1023.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1023.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1024.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1024.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1024.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1024.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1025.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1025.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1025.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1025.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1026.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1026.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1026.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1026.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1027.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1027.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1027.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1027.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1028.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1028.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1028.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1028.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1029.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1029.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1029.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1029.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1030.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1030.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1030.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1030.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1031.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1031.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1031.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1031.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1032.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1032.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1032.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1032.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1033.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1033.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1033.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1033.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1034.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1034.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1034.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1034.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1035.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1035.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1035.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1035.sql diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1036.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1036.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-1036.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-1036.sql diff --git a/gaseous-lib/Support/Database/MySQL/gaseous-1037.sql b/gaseous-lib/Support/Database/MySQL/gaseous-1037.sql new file mode 100644 index 0000000..016d892 --- /dev/null +++ b/gaseous-lib/Support/Database/MySQL/gaseous-1037.sql @@ -0,0 +1,2 @@ +ALTER TABLE `Metadata_GameVideo` +CHANGE `VideoId` `VideoId` varchar(128) DEFAULT NULL; \ No newline at end of file diff --git a/gaseous-server/Support/Database/MySQL/gaseous-fix-1005.sql b/gaseous-lib/Support/Database/MySQL/gaseous-fix-1005.sql similarity index 100% rename from gaseous-server/Support/Database/MySQL/gaseous-fix-1005.sql rename to gaseous-lib/Support/Database/MySQL/gaseous-fix-1005.sql diff --git a/gaseous-server/Support/DefaultPlatformLogo.svg b/gaseous-lib/Support/DefaultPlatformLogo.svg similarity index 100% rename from gaseous-server/Support/DefaultPlatformLogo.svg rename to gaseous-lib/Support/DefaultPlatformLogo.svg diff --git a/gaseous-server/Support/Language.txt b/gaseous-lib/Support/Language.txt similarity index 100% rename from gaseous-server/Support/Language.txt rename to gaseous-lib/Support/Language.txt diff --git a/gaseous-server/Support/Localisation/de-AT.json b/gaseous-lib/Support/Localisation/de-AT.json similarity index 100% rename from gaseous-server/Support/Localisation/de-AT.json rename to gaseous-lib/Support/Localisation/de-AT.json diff --git a/gaseous-server/Support/Localisation/de-CH.json b/gaseous-lib/Support/Localisation/de-CH.json similarity index 100% rename from gaseous-server/Support/Localisation/de-CH.json rename to gaseous-lib/Support/Localisation/de-CH.json diff --git a/gaseous-server/Support/Localisation/de-DE.json b/gaseous-lib/Support/Localisation/de-DE.json similarity index 100% rename from gaseous-server/Support/Localisation/de-DE.json rename to gaseous-lib/Support/Localisation/de-DE.json diff --git a/gaseous-server/Support/Localisation/de-LI.json b/gaseous-lib/Support/Localisation/de-LI.json similarity index 100% rename from gaseous-server/Support/Localisation/de-LI.json rename to gaseous-lib/Support/Localisation/de-LI.json diff --git a/gaseous-server/Support/Localisation/de-LU.json b/gaseous-lib/Support/Localisation/de-LU.json similarity index 100% rename from gaseous-server/Support/Localisation/de-LU.json rename to gaseous-lib/Support/Localisation/de-LU.json diff --git a/gaseous-server/Support/Localisation/de.json b/gaseous-lib/Support/Localisation/de.json similarity index 100% rename from gaseous-server/Support/Localisation/de.json rename to gaseous-lib/Support/Localisation/de.json diff --git a/gaseous-server/Support/Localisation/en-AU.json b/gaseous-lib/Support/Localisation/en-AU.json similarity index 100% rename from gaseous-server/Support/Localisation/en-AU.json rename to gaseous-lib/Support/Localisation/en-AU.json diff --git a/gaseous-server/Support/Localisation/en-CA.json b/gaseous-lib/Support/Localisation/en-CA.json similarity index 100% rename from gaseous-server/Support/Localisation/en-CA.json rename to gaseous-lib/Support/Localisation/en-CA.json diff --git a/gaseous-server/Support/Localisation/en-GB.json b/gaseous-lib/Support/Localisation/en-GB.json similarity index 100% rename from gaseous-server/Support/Localisation/en-GB.json rename to gaseous-lib/Support/Localisation/en-GB.json diff --git a/gaseous-server/Support/Localisation/en-HK.json b/gaseous-lib/Support/Localisation/en-HK.json similarity index 100% rename from gaseous-server/Support/Localisation/en-HK.json rename to gaseous-lib/Support/Localisation/en-HK.json diff --git a/gaseous-server/Support/Localisation/en-IE.json b/gaseous-lib/Support/Localisation/en-IE.json similarity index 100% rename from gaseous-server/Support/Localisation/en-IE.json rename to gaseous-lib/Support/Localisation/en-IE.json diff --git a/gaseous-server/Support/Localisation/en-IN.json b/gaseous-lib/Support/Localisation/en-IN.json similarity index 100% rename from gaseous-server/Support/Localisation/en-IN.json rename to gaseous-lib/Support/Localisation/en-IN.json diff --git a/gaseous-server/Support/Localisation/en-NZ.json b/gaseous-lib/Support/Localisation/en-NZ.json similarity index 100% rename from gaseous-server/Support/Localisation/en-NZ.json rename to gaseous-lib/Support/Localisation/en-NZ.json diff --git a/gaseous-server/Support/Localisation/en-SG.json b/gaseous-lib/Support/Localisation/en-SG.json similarity index 100% rename from gaseous-server/Support/Localisation/en-SG.json rename to gaseous-lib/Support/Localisation/en-SG.json diff --git a/gaseous-server/Support/Localisation/en-US.json b/gaseous-lib/Support/Localisation/en-US.json similarity index 100% rename from gaseous-server/Support/Localisation/en-US.json rename to gaseous-lib/Support/Localisation/en-US.json diff --git a/gaseous-server/Support/Localisation/en-ZA.json b/gaseous-lib/Support/Localisation/en-ZA.json similarity index 100% rename from gaseous-server/Support/Localisation/en-ZA.json rename to gaseous-lib/Support/Localisation/en-ZA.json diff --git a/gaseous-server/Support/Localisation/en.json b/gaseous-lib/Support/Localisation/en.json similarity index 100% rename from gaseous-server/Support/Localisation/en.json rename to gaseous-lib/Support/Localisation/en.json diff --git a/gaseous-server/Support/Localisation/es-419.json b/gaseous-lib/Support/Localisation/es-419.json similarity index 100% rename from gaseous-server/Support/Localisation/es-419.json rename to gaseous-lib/Support/Localisation/es-419.json diff --git a/gaseous-server/Support/Localisation/es-AR.json b/gaseous-lib/Support/Localisation/es-AR.json similarity index 100% rename from gaseous-server/Support/Localisation/es-AR.json rename to gaseous-lib/Support/Localisation/es-AR.json diff --git a/gaseous-server/Support/Localisation/es-BO.json b/gaseous-lib/Support/Localisation/es-BO.json similarity index 100% rename from gaseous-server/Support/Localisation/es-BO.json rename to gaseous-lib/Support/Localisation/es-BO.json diff --git a/gaseous-server/Support/Localisation/es-CL.json b/gaseous-lib/Support/Localisation/es-CL.json similarity index 100% rename from gaseous-server/Support/Localisation/es-CL.json rename to gaseous-lib/Support/Localisation/es-CL.json diff --git a/gaseous-server/Support/Localisation/es-CO.json b/gaseous-lib/Support/Localisation/es-CO.json similarity index 100% rename from gaseous-server/Support/Localisation/es-CO.json rename to gaseous-lib/Support/Localisation/es-CO.json diff --git a/gaseous-server/Support/Localisation/es-CR.json b/gaseous-lib/Support/Localisation/es-CR.json similarity index 100% rename from gaseous-server/Support/Localisation/es-CR.json rename to gaseous-lib/Support/Localisation/es-CR.json diff --git a/gaseous-server/Support/Localisation/es-CU.json b/gaseous-lib/Support/Localisation/es-CU.json similarity index 100% rename from gaseous-server/Support/Localisation/es-CU.json rename to gaseous-lib/Support/Localisation/es-CU.json diff --git a/gaseous-server/Support/Localisation/es-DO.json b/gaseous-lib/Support/Localisation/es-DO.json similarity index 100% rename from gaseous-server/Support/Localisation/es-DO.json rename to gaseous-lib/Support/Localisation/es-DO.json diff --git a/gaseous-server/Support/Localisation/es-EC.json b/gaseous-lib/Support/Localisation/es-EC.json similarity index 100% rename from gaseous-server/Support/Localisation/es-EC.json rename to gaseous-lib/Support/Localisation/es-EC.json diff --git a/gaseous-server/Support/Localisation/es-ES.json b/gaseous-lib/Support/Localisation/es-ES.json similarity index 100% rename from gaseous-server/Support/Localisation/es-ES.json rename to gaseous-lib/Support/Localisation/es-ES.json diff --git a/gaseous-server/Support/Localisation/es-GT.json b/gaseous-lib/Support/Localisation/es-GT.json similarity index 100% rename from gaseous-server/Support/Localisation/es-GT.json rename to gaseous-lib/Support/Localisation/es-GT.json diff --git a/gaseous-server/Support/Localisation/es-HN.json b/gaseous-lib/Support/Localisation/es-HN.json similarity index 100% rename from gaseous-server/Support/Localisation/es-HN.json rename to gaseous-lib/Support/Localisation/es-HN.json diff --git a/gaseous-server/Support/Localisation/es-MX.json b/gaseous-lib/Support/Localisation/es-MX.json similarity index 100% rename from gaseous-server/Support/Localisation/es-MX.json rename to gaseous-lib/Support/Localisation/es-MX.json diff --git a/gaseous-server/Support/Localisation/es-NI.json b/gaseous-lib/Support/Localisation/es-NI.json similarity index 100% rename from gaseous-server/Support/Localisation/es-NI.json rename to gaseous-lib/Support/Localisation/es-NI.json diff --git a/gaseous-server/Support/Localisation/es-PA.json b/gaseous-lib/Support/Localisation/es-PA.json similarity index 100% rename from gaseous-server/Support/Localisation/es-PA.json rename to gaseous-lib/Support/Localisation/es-PA.json diff --git a/gaseous-server/Support/Localisation/es-PE.json b/gaseous-lib/Support/Localisation/es-PE.json similarity index 100% rename from gaseous-server/Support/Localisation/es-PE.json rename to gaseous-lib/Support/Localisation/es-PE.json diff --git a/gaseous-server/Support/Localisation/es-PR.json b/gaseous-lib/Support/Localisation/es-PR.json similarity index 100% rename from gaseous-server/Support/Localisation/es-PR.json rename to gaseous-lib/Support/Localisation/es-PR.json diff --git a/gaseous-server/Support/Localisation/es-PY.json b/gaseous-lib/Support/Localisation/es-PY.json similarity index 100% rename from gaseous-server/Support/Localisation/es-PY.json rename to gaseous-lib/Support/Localisation/es-PY.json diff --git a/gaseous-server/Support/Localisation/es-SV.json b/gaseous-lib/Support/Localisation/es-SV.json similarity index 100% rename from gaseous-server/Support/Localisation/es-SV.json rename to gaseous-lib/Support/Localisation/es-SV.json diff --git a/gaseous-server/Support/Localisation/es-UY.json b/gaseous-lib/Support/Localisation/es-UY.json similarity index 100% rename from gaseous-server/Support/Localisation/es-UY.json rename to gaseous-lib/Support/Localisation/es-UY.json diff --git a/gaseous-server/Support/Localisation/es-VE.json b/gaseous-lib/Support/Localisation/es-VE.json similarity index 100% rename from gaseous-server/Support/Localisation/es-VE.json rename to gaseous-lib/Support/Localisation/es-VE.json diff --git a/gaseous-server/Support/Localisation/es.json b/gaseous-lib/Support/Localisation/es.json similarity index 100% rename from gaseous-server/Support/Localisation/es.json rename to gaseous-lib/Support/Localisation/es.json diff --git a/gaseous-server/Support/Localisation/fr-BE.json b/gaseous-lib/Support/Localisation/fr-BE.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-BE.json rename to gaseous-lib/Support/Localisation/fr-BE.json diff --git a/gaseous-server/Support/Localisation/fr-CA.json b/gaseous-lib/Support/Localisation/fr-CA.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-CA.json rename to gaseous-lib/Support/Localisation/fr-CA.json diff --git a/gaseous-server/Support/Localisation/fr-CH.json b/gaseous-lib/Support/Localisation/fr-CH.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-CH.json rename to gaseous-lib/Support/Localisation/fr-CH.json diff --git a/gaseous-server/Support/Localisation/fr-CI.json b/gaseous-lib/Support/Localisation/fr-CI.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-CI.json rename to gaseous-lib/Support/Localisation/fr-CI.json diff --git a/gaseous-server/Support/Localisation/fr-CM.json b/gaseous-lib/Support/Localisation/fr-CM.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-CM.json rename to gaseous-lib/Support/Localisation/fr-CM.json diff --git a/gaseous-server/Support/Localisation/fr-DZ.json b/gaseous-lib/Support/Localisation/fr-DZ.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-DZ.json rename to gaseous-lib/Support/Localisation/fr-DZ.json diff --git a/gaseous-server/Support/Localisation/fr-FR.json b/gaseous-lib/Support/Localisation/fr-FR.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-FR.json rename to gaseous-lib/Support/Localisation/fr-FR.json diff --git a/gaseous-server/Support/Localisation/fr-GF.json b/gaseous-lib/Support/Localisation/fr-GF.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-GF.json rename to gaseous-lib/Support/Localisation/fr-GF.json diff --git a/gaseous-server/Support/Localisation/fr-GP.json b/gaseous-lib/Support/Localisation/fr-GP.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-GP.json rename to gaseous-lib/Support/Localisation/fr-GP.json diff --git a/gaseous-server/Support/Localisation/fr-HT.json b/gaseous-lib/Support/Localisation/fr-HT.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-HT.json rename to gaseous-lib/Support/Localisation/fr-HT.json diff --git a/gaseous-server/Support/Localisation/fr-LU.json b/gaseous-lib/Support/Localisation/fr-LU.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-LU.json rename to gaseous-lib/Support/Localisation/fr-LU.json diff --git a/gaseous-server/Support/Localisation/fr-MA.json b/gaseous-lib/Support/Localisation/fr-MA.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-MA.json rename to gaseous-lib/Support/Localisation/fr-MA.json diff --git a/gaseous-server/Support/Localisation/fr-MC.json b/gaseous-lib/Support/Localisation/fr-MC.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-MC.json rename to gaseous-lib/Support/Localisation/fr-MC.json diff --git a/gaseous-server/Support/Localisation/fr-NC.json b/gaseous-lib/Support/Localisation/fr-NC.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-NC.json rename to gaseous-lib/Support/Localisation/fr-NC.json diff --git a/gaseous-server/Support/Localisation/fr-PF.json b/gaseous-lib/Support/Localisation/fr-PF.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-PF.json rename to gaseous-lib/Support/Localisation/fr-PF.json diff --git a/gaseous-server/Support/Localisation/fr-RE.json b/gaseous-lib/Support/Localisation/fr-RE.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-RE.json rename to gaseous-lib/Support/Localisation/fr-RE.json diff --git a/gaseous-server/Support/Localisation/fr-SN.json b/gaseous-lib/Support/Localisation/fr-SN.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-SN.json rename to gaseous-lib/Support/Localisation/fr-SN.json diff --git a/gaseous-server/Support/Localisation/fr-TN.json b/gaseous-lib/Support/Localisation/fr-TN.json similarity index 100% rename from gaseous-server/Support/Localisation/fr-TN.json rename to gaseous-lib/Support/Localisation/fr-TN.json diff --git a/gaseous-server/Support/Localisation/fr.json b/gaseous-lib/Support/Localisation/fr.json similarity index 100% rename from gaseous-server/Support/Localisation/fr.json rename to gaseous-lib/Support/Localisation/fr.json diff --git a/gaseous-server/Support/Localisation/it-CH.json b/gaseous-lib/Support/Localisation/it-CH.json similarity index 100% rename from gaseous-server/Support/Localisation/it-CH.json rename to gaseous-lib/Support/Localisation/it-CH.json diff --git a/gaseous-server/Support/Localisation/it-IT.json b/gaseous-lib/Support/Localisation/it-IT.json similarity index 100% rename from gaseous-server/Support/Localisation/it-IT.json rename to gaseous-lib/Support/Localisation/it-IT.json diff --git a/gaseous-server/Support/Localisation/it-SM.json b/gaseous-lib/Support/Localisation/it-SM.json similarity index 100% rename from gaseous-server/Support/Localisation/it-SM.json rename to gaseous-lib/Support/Localisation/it-SM.json diff --git a/gaseous-server/Support/Localisation/it-VA.json b/gaseous-lib/Support/Localisation/it-VA.json similarity index 100% rename from gaseous-server/Support/Localisation/it-VA.json rename to gaseous-lib/Support/Localisation/it-VA.json diff --git a/gaseous-server/Support/Localisation/it.json b/gaseous-lib/Support/Localisation/it.json similarity index 100% rename from gaseous-server/Support/Localisation/it.json rename to gaseous-lib/Support/Localisation/it.json diff --git a/gaseous-server/Support/Localisation/ja-JP.json b/gaseous-lib/Support/Localisation/ja-JP.json similarity index 100% rename from gaseous-server/Support/Localisation/ja-JP.json rename to gaseous-lib/Support/Localisation/ja-JP.json diff --git a/gaseous-server/Support/Localisation/ja.json b/gaseous-lib/Support/Localisation/ja.json similarity index 100% rename from gaseous-server/Support/Localisation/ja.json rename to gaseous-lib/Support/Localisation/ja.json diff --git a/gaseous-server/Support/Localisation/ko-KR.json b/gaseous-lib/Support/Localisation/ko-KR.json similarity index 100% rename from gaseous-server/Support/Localisation/ko-KR.json rename to gaseous-lib/Support/Localisation/ko-KR.json diff --git a/gaseous-server/Support/Localisation/ko.json b/gaseous-lib/Support/Localisation/ko.json similarity index 100% rename from gaseous-server/Support/Localisation/ko.json rename to gaseous-lib/Support/Localisation/ko.json diff --git a/gaseous-server/Support/Localisation/nl-BE.json b/gaseous-lib/Support/Localisation/nl-BE.json similarity index 100% rename from gaseous-server/Support/Localisation/nl-BE.json rename to gaseous-lib/Support/Localisation/nl-BE.json diff --git a/gaseous-server/Support/Localisation/nl-NL.json b/gaseous-lib/Support/Localisation/nl-NL.json similarity index 100% rename from gaseous-server/Support/Localisation/nl-NL.json rename to gaseous-lib/Support/Localisation/nl-NL.json diff --git a/gaseous-server/Support/Localisation/nl.json b/gaseous-lib/Support/Localisation/nl.json similarity index 100% rename from gaseous-server/Support/Localisation/nl.json rename to gaseous-lib/Support/Localisation/nl.json diff --git a/gaseous-server/Support/Localisation/pt-AO.json b/gaseous-lib/Support/Localisation/pt-AO.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-AO.json rename to gaseous-lib/Support/Localisation/pt-AO.json diff --git a/gaseous-server/Support/Localisation/pt-BR.json b/gaseous-lib/Support/Localisation/pt-BR.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-BR.json rename to gaseous-lib/Support/Localisation/pt-BR.json diff --git a/gaseous-server/Support/Localisation/pt-CV.json b/gaseous-lib/Support/Localisation/pt-CV.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-CV.json rename to gaseous-lib/Support/Localisation/pt-CV.json diff --git a/gaseous-server/Support/Localisation/pt-GW.json b/gaseous-lib/Support/Localisation/pt-GW.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-GW.json rename to gaseous-lib/Support/Localisation/pt-GW.json diff --git a/gaseous-server/Support/Localisation/pt-MO.json b/gaseous-lib/Support/Localisation/pt-MO.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-MO.json rename to gaseous-lib/Support/Localisation/pt-MO.json diff --git a/gaseous-server/Support/Localisation/pt-MZ.json b/gaseous-lib/Support/Localisation/pt-MZ.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-MZ.json rename to gaseous-lib/Support/Localisation/pt-MZ.json diff --git a/gaseous-server/Support/Localisation/pt-PT.json b/gaseous-lib/Support/Localisation/pt-PT.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-PT.json rename to gaseous-lib/Support/Localisation/pt-PT.json diff --git a/gaseous-server/Support/Localisation/pt-ST.json b/gaseous-lib/Support/Localisation/pt-ST.json similarity index 100% rename from gaseous-server/Support/Localisation/pt-ST.json rename to gaseous-lib/Support/Localisation/pt-ST.json diff --git a/gaseous-server/Support/Localisation/pt.json b/gaseous-lib/Support/Localisation/pt.json similarity index 100% rename from gaseous-server/Support/Localisation/pt.json rename to gaseous-lib/Support/Localisation/pt.json diff --git a/gaseous-server/Support/Localisation/ru-BY.json b/gaseous-lib/Support/Localisation/ru-BY.json similarity index 100% rename from gaseous-server/Support/Localisation/ru-BY.json rename to gaseous-lib/Support/Localisation/ru-BY.json diff --git a/gaseous-server/Support/Localisation/ru-KG.json b/gaseous-lib/Support/Localisation/ru-KG.json similarity index 100% rename from gaseous-server/Support/Localisation/ru-KG.json rename to gaseous-lib/Support/Localisation/ru-KG.json diff --git a/gaseous-server/Support/Localisation/ru-KZ.json b/gaseous-lib/Support/Localisation/ru-KZ.json similarity index 100% rename from gaseous-server/Support/Localisation/ru-KZ.json rename to gaseous-lib/Support/Localisation/ru-KZ.json diff --git a/gaseous-server/Support/Localisation/ru-RU.json b/gaseous-lib/Support/Localisation/ru-RU.json similarity index 100% rename from gaseous-server/Support/Localisation/ru-RU.json rename to gaseous-lib/Support/Localisation/ru-RU.json diff --git a/gaseous-server/Support/Localisation/ru-UA.json b/gaseous-lib/Support/Localisation/ru-UA.json similarity index 100% rename from gaseous-server/Support/Localisation/ru-UA.json rename to gaseous-lib/Support/Localisation/ru-UA.json diff --git a/gaseous-server/Support/Localisation/ru.json b/gaseous-lib/Support/Localisation/ru.json similarity index 100% rename from gaseous-server/Support/Localisation/ru.json rename to gaseous-lib/Support/Localisation/ru.json diff --git a/gaseous-server/Support/Localisation/zh-CN.json b/gaseous-lib/Support/Localisation/zh-CN.json similarity index 100% rename from gaseous-server/Support/Localisation/zh-CN.json rename to gaseous-lib/Support/Localisation/zh-CN.json diff --git a/gaseous-server/Support/Localisation/zh-HK.json b/gaseous-lib/Support/Localisation/zh-HK.json similarity index 100% rename from gaseous-server/Support/Localisation/zh-HK.json rename to gaseous-lib/Support/Localisation/zh-HK.json diff --git a/gaseous-server/Support/Localisation/zh-MO.json b/gaseous-lib/Support/Localisation/zh-MO.json similarity index 100% rename from gaseous-server/Support/Localisation/zh-MO.json rename to gaseous-lib/Support/Localisation/zh-MO.json diff --git a/gaseous-server/Support/Localisation/zh-SG.json b/gaseous-lib/Support/Localisation/zh-SG.json similarity index 100% rename from gaseous-server/Support/Localisation/zh-SG.json rename to gaseous-lib/Support/Localisation/zh-SG.json diff --git a/gaseous-server/Support/Localisation/zh-TW.json b/gaseous-lib/Support/Localisation/zh-TW.json similarity index 100% rename from gaseous-server/Support/Localisation/zh-TW.json rename to gaseous-lib/Support/Localisation/zh-TW.json diff --git a/gaseous-server/Support/Localisation/zh.json b/gaseous-lib/Support/Localisation/zh.json similarity index 100% rename from gaseous-server/Support/Localisation/zh.json rename to gaseous-lib/Support/Localisation/zh.json diff --git a/gaseous-server/Support/PlatformMap.json b/gaseous-lib/Support/PlatformMap.json similarity index 100% rename from gaseous-server/Support/PlatformMap.json rename to gaseous-lib/Support/PlatformMap.json diff --git a/gaseous-lib/gaseous-lib.csproj b/gaseous-lib/gaseous-lib.csproj new file mode 100644 index 0000000..5885f4f --- /dev/null +++ b/gaseous-lib/gaseous-lib.csproj @@ -0,0 +1,82 @@ + + + + net10.0 + gaseous_lib + enable + enable + + + 4 + bin\Debug\net10.0\gaseous-lib.xml + + + 4 + bin\Release\net10.0\gaseous-lib.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + PreserveNewest + + + + + + + + + diff --git a/gaseous-processhost/Classes/CLIHelp.cs b/gaseous-processhost/Classes/CLIHelp.cs new file mode 100644 index 0000000..f7b1cb6 --- /dev/null +++ b/gaseous-processhost/Classes/CLIHelp.cs @@ -0,0 +1,46 @@ + + +using gaseous_server.ProcessQueue; + +namespace GaseousServerHost.Classes.CLI +{ + /// + /// Provides methods for displaying command-line help information for the Gaseous Server Host. + /// + public class Help + { + /// + /// Displays command-line help information for the Hasheous Server Host. + /// + public static void DisplayHelp() + { + Console.WriteLine("Gaseous Server - Process Host"); + Console.WriteLine("This program is used to run various background services for the Gaseous server."); + Console.WriteLine("It is normally called by the server."); + Console.WriteLine(""); + Console.WriteLine("Usage: gaseous-processhost [options]"); + Console.WriteLine("Options:"); + Console.WriteLine(" --help Display this help message"); + Console.WriteLine(" --version Display the version of the service"); + Console.WriteLine(" --service Specify the service name to run"); + Console.WriteLine(" --reportingserver Specify the reporting server URL"); + Console.WriteLine(" --processid Specify the process ID for the service instance"); + Console.WriteLine(" --correlationid Specify a correlation ID for logging"); + Console.WriteLine(""); + Console.WriteLine("Available services:"); + foreach (var service in Enum.GetNames(typeof(QueueItemType))) + { + if (service != "All" && service != "NotConfigured") + { + Console.WriteLine($" {service}"); + } + } + Console.WriteLine(""); + Console.WriteLine("Examples:"); + Console.WriteLine(" gaseous-processhost --service SignatureIngestor --reportingserver https://localhost"); + Console.WriteLine(" gaseous-processhost --version"); + Console.WriteLine(" gaseous-processhost --help"); + Environment.Exit(0); + } + } +} \ No newline at end of file diff --git a/gaseous-processhost/Program.cs b/gaseous-processhost/Program.cs new file mode 100644 index 0000000..d8dc590 --- /dev/null +++ b/gaseous-processhost/Program.cs @@ -0,0 +1,109 @@ +// start command line parser +using gaseous_server.Classes; +using gaseous_server.ProcessQueue; +using gaseous_server.ProcessQueue.Plugins; +using GaseousServerHost.Classes.CLI; + +string[] cmdArgs = Environment.GetCommandLineArgs(); + +// Parse the command line arguments +if (cmdArgs.Length == 1 || cmdArgs.Contains("--help")) +{ + // No arguments provided, display usage + Help.DisplayHelp(); + return; +} + +// Check for version argument +if (cmdArgs.Contains("--version")) +{ + Console.WriteLine("Gaseous Server Host Version " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); + return; +} + +// process other command line arguments +string serviceName = null; +string reportingServerUrl = null; +string correlationId = null; + +for (int i = 0; i < cmdArgs.Length; i++) +{ + if (cmdArgs[i] == "--service" && i + 1 < cmdArgs.Length) + { + serviceName = cmdArgs[i + 1]; + } + else if (cmdArgs[i] == "--reportingserver" && i + 1 < cmdArgs.Length) + { + reportingServerUrl = cmdArgs[i + 1]; + } + else if (cmdArgs[i] == "--correlationid" && i + 1 < cmdArgs.Length) + { + correlationId = cmdArgs[i + 1]; + } +} + +// If no service name is provided, display help +if (string.IsNullOrEmpty(serviceName)) +{ + Console.WriteLine("Error: No service name provided."); + Help.DisplayHelp(); + return; +} + +// verify the service name can be parsed as Classes.ProcessQueue.QueueItemType, and is not "All" or "NotConfigured" +if (!Enum.TryParse(serviceName, out QueueItemType taskType) || taskType == QueueItemType.All || taskType == QueueItemType.NotConfigured) +{ + Console.WriteLine($"Error: Invalid service name '{serviceName}'."); + Help.DisplayHelp(); + return; +} + +// If no reporting server URL is provided, abort +if (string.IsNullOrEmpty(reportingServerUrl)) +{ + Console.WriteLine("Error: No reporting server URL provided."); + Help.DisplayHelp(); + return; +} + +// If a correlation ID is provided, set it in the CallContext +if (string.IsNullOrEmpty(correlationId)) +{ + // If no correlation ID is provided, generate a new one + correlationId = Guid.NewGuid().ToString(); +} +CallContext.SetData("CorrelationId", correlationId); +CallContext.SetData("CallingProcess", taskType.ToString()); +CallContext.SetData("CallingUser", "System"); +CallContext.SetData("ReportingServerUrl", reportingServerUrl); +CallContext.SetData("OutProcess", true); + +// Initialize the service with the provided configuration +gaseous_server.ProcessQueue.QueueProcessor.QueueItem Task = new QueueProcessor.QueueItem(taskType, false, false) +{ + CorrelationId = correlationId +}; +Task.ForceExecute(); + +// start the task +try +{ + // Settings + Config.InitSettings(); + + // API metadata source + HasheousClient.WebApp.HttpHelper.BaseUri = Config.MetadataConfiguration.HasheousHost; + + Console.WriteLine($"Starting service '{serviceName}' with reporting server '{reportingServerUrl}' and correlation ID '{correlationId}'."); + await Task.Execute(); +} +catch (Exception ex) +{ + Console.WriteLine($"An error occurred while executing service: {ex.Message}"); + // terminate the application with a non-zero exit code + Environment.Exit(1); +} + +// Log the successful completion of the service +Console.WriteLine("Service completed successfully."); +Environment.Exit(0); // exit with success code \ No newline at end of file diff --git a/gaseous-processhost/gaseous-processhost.csproj b/gaseous-processhost/gaseous-processhost.csproj new file mode 100644 index 0000000..6256693 --- /dev/null +++ b/gaseous-processhost/gaseous-processhost.csproj @@ -0,0 +1,15 @@ + + + + Exe + net10.0 + gaseous_processhost + enable + enable + + + + + + + diff --git a/gaseous-server/Classes/Collections.cs b/gaseous-server/Classes/Collections.cs deleted file mode 100644 index 16dd281..0000000 --- a/gaseous-server/Classes/Collections.cs +++ /dev/null @@ -1,982 +0,0 @@ -using System; -using System.Data; -using System.IO.Compression; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Security.Cryptography; -using Authentication; -using gaseous_server.Classes.Metadata; -using gaseous_server.Controllers; -using gaseous_server.Controllers.v1_1; -using gaseous_server.Models; -using gaseous_server.Classes.Plugins.MetadataProviders.MetadataTypes; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Mvc.Filters; -using Newtonsoft.Json; -using SharpCompress.Common; -using static gaseous_server.Classes.Metadata.Games; - -namespace gaseous_server.Classes -{ - public class Collections - { - public static List GetCollections(string userid) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "SELECT * FROM RomCollections WHERE OwnedBy=@ownedby ORDER BY `Name`"; - Dictionary dbDict = new Dictionary{ - { "ownedby", userid } - }; - DataTable data = db.ExecuteCMD(sql, dbDict); - - List collectionItems = new List(); - - foreach (DataRow row in data.Rows) - { - collectionItems.Add(BuildCollectionItem(row)); - } - - return collectionItems; - } - - public static CollectionItem GetCollection(long Id, string userid) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql; - if (userid == "") - { - // reserved for internal operations - sql = "SELECT * FROM RomCollections WHERE Id = @id ORDER BY `Name`"; - } - else - { - // instigated by a user - sql = "SELECT * FROM RomCollections WHERE Id = @id AND OwnedBy = @ownedby ORDER BY `Name`"; - } - Dictionary dbDict = new Dictionary - { - { "id", Id }, - { "ownedby", userid } - }; - DataTable romDT = db.ExecuteCMD(sql, dbDict); - - if (romDT.Rows.Count > 0) - { - DataRow row = romDT.Rows[0]; - CollectionItem collectionItem = BuildCollectionItem(row); - - return collectionItem; - } - else - { - throw new Exception("Unknown Collection Id"); - } - } - - public static CollectionItem NewCollection(CollectionItem item, string userid) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "INSERT INTO RomCollections (`Name`, Description, Platforms, Genres, Players, PlayerPerspectives, Themes, MinimumRating, MaximumRating, MaximumRomsPerPlatform, MaximumBytesPerPlatform, MaximumCollectionSizeInBytes, FolderStructure, IncludeBIOSFiles, ArchiveType, AlwaysInclude, BuiltStatus, OwnedBy) VALUES (@name, @description, @platforms, @genres, @players, @playerperspectives, @themes, @minimumrating, @maximumrating, @maximumromsperplatform, @maximumbytesperplatform, @maximumcollectionsizeinbytes, @folderstructure, @includebiosfiles, @archivetype, @alwaysinclude, @builtstatus, @ownedby); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; - Dictionary dbDict = new Dictionary - { - { "name", item.Name }, - { "description", item.Description }, - { "platforms", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Platforms, new List())) }, - { "genres", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Genres, new List())) }, - { "players", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Players, new List())) }, - { "playerperspectives", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.PlayerPerspectives, new List())) }, - { "themes", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Themes, new List())) }, - { "minimumrating", Common.ReturnValueIfNull(item.MinimumRating, -1) }, - { "maximumrating", Common.ReturnValueIfNull(item.MaximumRating, -1) }, - { "maximumromsperplatform", Common.ReturnValueIfNull(item.MaximumRomsPerPlatform, -1) }, - { "maximumbytesperplatform", Common.ReturnValueIfNull(item.MaximumBytesPerPlatform, -1) }, - { "maximumcollectionsizeinbytes", Common.ReturnValueIfNull(item.MaximumCollectionSizeInBytes, -1) }, - { "folderstructure", Common.ReturnValueIfNull(item.FolderStructure, CollectionItem.FolderStructures.Gaseous) }, - { "includebiosfiles", Common.ReturnValueIfNull(item.IncludeBIOSFiles, 0) }, - { "archivetype", Common.ReturnValueIfNull(item.ArchiveType, CollectionItem.ArchiveTypes.Zip) }, - { "alwaysinclude", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.AlwaysInclude, new List())) }, - { "builtstatus", CollectionItem.CollectionBuildStatus.WaitingForBuild }, - { "ownedby", userid } - }; - DataTable romDT = db.ExecuteCMD(sql, dbDict); - long CollectionId = (long)romDT.Rows[0][0]; - - CollectionItem collectionItem = GetCollection(CollectionId, userid); - - StartCollectionItemBuild(CollectionId, userid); - - return collectionItem; - } - - public static CollectionItem EditCollection(long Id, CollectionItem item, string userid, bool ForceRebuild = true) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "UPDATE RomCollections SET `Name`=@name, Description=@description, Platforms=@platforms, Genres=@genres, Players=@players, PlayerPerspectives=@playerperspectives, Themes=@themes, MinimumRating=@minimumrating, MaximumRating=@maximumrating, MaximumRomsPerPlatform=@maximumromsperplatform, MaximumBytesPerPlatform=@maximumbytesperplatform, MaximumCollectionSizeInBytes=@maximumcollectionsizeinbytes, FolderStructure=@folderstructure, IncludeBIOSFiles=@includebiosfiles, ArchiveType=@archivetype, AlwaysInclude=@alwaysinclude, BuiltStatus=@builtstatus WHERE Id=@id AND OwnedBy=@ownedby"; - Dictionary dbDict = new Dictionary - { - { "id", Id }, - { "name", item.Name }, - { "description", item.Description }, - { "platforms", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Platforms, new List())) }, - { "genres", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Genres, new List())) }, - { "players", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Players, new List())) }, - { "playerperspectives", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.PlayerPerspectives, new List())) }, - { "themes", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.Themes, new List())) }, - { "minimumrating", Common.ReturnValueIfNull(item.MinimumRating, -1) }, - { "maximumrating", Common.ReturnValueIfNull(item.MaximumRating, -1) }, - { "maximumromsperplatform", Common.ReturnValueIfNull(item.MaximumRomsPerPlatform, -1) }, - { "maximumbytesperplatform", Common.ReturnValueIfNull(item.MaximumBytesPerPlatform, -1) }, - { "maximumcollectionsizeinbytes", Common.ReturnValueIfNull(item.MaximumCollectionSizeInBytes, -1) }, - { "folderstructure", Common.ReturnValueIfNull(item.FolderStructure, CollectionItem.FolderStructures.Gaseous) }, - { "includebiosfiles", Common.ReturnValueIfNull(item.IncludeBIOSFiles, 0) }, - { "alwaysinclude", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.AlwaysInclude, new List())) }, - { "archivetype", Common.ReturnValueIfNull(item.ArchiveType, CollectionItem.ArchiveTypes.Zip) }, - { "ownedby", userid } - }; - - string CollectionZipFile = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + item.ArchiveExtension); - if (ForceRebuild == true) - { - dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.WaitingForBuild); - if (File.Exists(CollectionZipFile)) - { - Logging.LogKey(Logging.LogType.Warning, "process.collections", "collections.deleting_existing_build", null, new string[] { item.Name }); - File.Delete(CollectionZipFile); - } - } - else - { - if (File.Exists(CollectionZipFile)) - { - dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.Completed); - } - else - { - dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.NoStatus); - } - } - db.ExecuteCMD(sql, dbDict); - - CollectionItem collectionItem = GetCollection(Id, userid); - - if (collectionItem.BuildStatus == CollectionItem.CollectionBuildStatus.WaitingForBuild) - { - StartCollectionItemBuild(Id, userid); - } - - return collectionItem; - } - - public static void DeleteCollection(long Id, string userid) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "DELETE FROM RomCollections WHERE Id=@id AND OwnedBy=@ownedby"; - Dictionary dbDict = new Dictionary - { - { "id", Id }, - { "ownedby", userid } - }; - db.ExecuteCMD(sql, dbDict); - - string CollectionZipFile = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ".zip"); - if (File.Exists(CollectionZipFile)) - { - File.Delete(CollectionZipFile); - } - } - - public static void StartCollectionItemBuild(long Id, string userid) - { - // send blank user id to getcollection as this is not a user initiated process - CollectionItem collectionItem = GetCollection(Id, userid); - - if (collectionItem.BuildStatus != CollectionItem.CollectionBuildStatus.Building) - { - // set collection item to waitingforbuild - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - string sql = "UPDATE RomCollections SET BuiltStatus=@bs WHERE Id=@id"; - Dictionary dbDict = new Dictionary(); - dbDict.Add("id", Id); - dbDict.Add("bs", CollectionItem.CollectionBuildStatus.WaitingForBuild); - db.ExecuteCMD(sql, dbDict); - - // start background task - ProcessQueue.QueueProcessor.QueueItem queueItem = new ProcessQueue.QueueProcessor.QueueItem(ProcessQueue.QueueItemType.CollectionCompiler, 1, false, true); - queueItem.Options = new Dictionary{ - { "Id", Id }, - { "UserId", userid } - }; - queueItem.ForceExecute(); - ProcessQueue.QueueProcessor.QueueItems.Add(queueItem); - } - } - - public static CollectionContents GetCollectionContent(CollectionItem collectionItem, string userid) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - - // get age ratings for specified user - List UserAgeGroupings = new List(); - bool UserAgeGroupIncludeUnrated = true; - ApplicationUser? user = null; - if (userid != "") - { - Authentication.UserTable userTable = new UserTable(db); - user = userTable.GetUserById(userid); - - if (user.SecurityProfile.AgeRestrictionPolicy.IncludeUnrated == false) - { - UserAgeGroupIncludeUnrated = false; - } - - foreach (AgeGroups.AgeRestrictionGroupings ageGrouping in Enum.GetValues(typeof(AgeGroups.AgeRestrictionGroupings))) - { - if (ageGrouping <= user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction && ageGrouping != AgeGroups.AgeRestrictionGroupings.Unclassified) - { - UserAgeGroupings.Add(ageGrouping); - } - } - } - - List collectionPlatformItems = new List(); - - // get platforms - List platformids = new List(); - platformids.AddRange(collectionItem.Platforms); - - List? DynamicPlatforms = new List(); - DynamicPlatforms.AddRange(collectionItem.Platforms); - - List platforms = new List(); - - // add platforms with an inclusion status - foreach (CollectionItem.AlwaysIncludeItem alwaysIncludeItem in collectionItem.AlwaysInclude) - { - if ( - alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude || - alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude - ) - { - if (!platformids.Contains(alwaysIncludeItem.PlatformId)) - { - platformids.Add(alwaysIncludeItem.PlatformId); - } - } - } - - // add dynamic platforms - if (DynamicPlatforms.Count > 0) - { - foreach (long PlatformId in platformids) - { - platforms.Add(Platforms.GetPlatform(PlatformId).Result); - } - } - else - { - // get all platforms to pull from - Dictionary> FilterDict = Filters.Filter(AgeGroups.AgeRestrictionGroupings.Adult, true).Result; - List filteredPlatforms = (List)FilterDict["platforms"]; - foreach (Filters.FilterItem filterItem in filteredPlatforms) - { - platforms.Add(Platforms.GetPlatform((long)filterItem.Id).Result); - } - } - - // age ratings - AgeGroups.AgeRestrictionGroupings AgeGrouping = AgeGroups.AgeRestrictionGroupings.Unclassified; - bool ContainsUnclassifiedAgeGroup = false; - - // build collection - List platformItems = new List(); - - foreach (Platform platform in platforms) - { - long TotalRomSize = 0; - long TotalGameCount = 0; - - bool isDynamic = false; - if (DynamicPlatforms.Contains((long)platform.Id)) - { - isDynamic = true; - } - else if (DynamicPlatforms.Count == 0) - { - isDynamic = true; - } - - Controllers.v1_1.GamesController.GameReturnPackage games = new Controllers.v1_1.GamesController.GameReturnPackage(); - if (isDynamic == true) - { - Controllers.v1_1.GamesController.GameSearchModel searchModel = new Controllers.v1_1.GamesController.GameSearchModel - { - Name = "", - Platform = new List{ - platform.Id.ToString() - }, - Genre = collectionItem.Genres.ConvertAll(s => s.ToString()), - GameMode = collectionItem.Players.ConvertAll(s => s.ToString()), - PlayerPerspective = collectionItem.PlayerPerspectives.ConvertAll(s => s.ToString()), - Theme = collectionItem.Themes.ConvertAll(s => s.ToString()), - GameRating = new Controllers.v1_1.GamesController.GameSearchModel.GameRatingItem - { - MinimumRating = collectionItem.MinimumRating, - MaximumRating = collectionItem.MaximumRating - }, - GameAgeRating = new Controllers.v1_1.GamesController.GameSearchModel.GameAgeRatingItem - { - AgeGroupings = UserAgeGroupings, - IncludeUnrated = UserAgeGroupIncludeUnrated - } - }; - games = Controllers.v1_1.GamesController.GetGames(searchModel, user).Result; - - } - - CollectionContents.CollectionPlatformItem collectionPlatformItem = new CollectionContents.CollectionPlatformItem(platform); - collectionPlatformItem.Games = new List(); - - // add titles with an inclusion status - foreach (CollectionItem.AlwaysIncludeItem alwaysIncludeItem in collectionItem.AlwaysInclude) - { - if ( - ( - alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude || - alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude - ) && alwaysIncludeItem.PlatformId == platform.Id - ) - { - MinimalGameItem AlwaysIncludeGame = new MinimalGameItem(Games.GetGame(FileSignature.MetadataSources.IGDB, alwaysIncludeItem.GameId).Result); - CollectionContents.CollectionPlatformItem.CollectionGameItem gameItem = new CollectionContents.CollectionPlatformItem.CollectionGameItem(AlwaysIncludeGame); - gameItem.InclusionStatus = new CollectionItem.AlwaysIncludeItem(); - gameItem.InclusionStatus.PlatformId = alwaysIncludeItem.PlatformId; - gameItem.InclusionStatus.GameId = alwaysIncludeItem.GameId; - gameItem.InclusionStatus.InclusionState = alwaysIncludeItem.InclusionState; - - // execute Roms.GetRomsAsync and wait for it to finish - // this is a blocking call - gameItem.Roms = Task.Run(async () => - { - var result = await Roms.GetRomsAsync((long)gameItem.Id, (long)platform.Id); - return result.GameRomItems; - }).Result; - - collectionPlatformItem.Games.Add(gameItem); - } - } - - foreach (MinimalGameItem game in games.Games) - { - bool gameAlreadyInList = false; - foreach (CollectionContents.CollectionPlatformItem.CollectionGameItem existingGame in collectionPlatformItem.Games) - { - if (existingGame.Id == game.Id) - { - gameAlreadyInList = true; - } - } - - if (gameAlreadyInList == false) - { - CollectionContents.CollectionPlatformItem.CollectionGameItem collectionGameItem = new CollectionContents.CollectionPlatformItem.CollectionGameItem(game); - - // Retrieve ROMs for the game synchronously - List gameRoms = Task.Run(async () => - { - var result = await Roms.GetRomsAsync((long)game.Id, (long)platform.Id); - return result.GameRomItems; - }).Result; - - // Calculate total ROM size for the game - long GameRomSize = gameRoms.Sum(r => (long)r.Size); - - bool AddGame = false; - if (collectionItem.MaximumBytesPerPlatform > 0) - { - if ((TotalRomSize + GameRomSize) < collectionItem.MaximumBytesPerPlatform) - { - AddGame = true; - } - } - else - { - AddGame = true; - } - - if (AddGame == true) - { - TotalRomSize += GameRomSize; - - bool AddRoms = false; - - if (collectionItem.MaximumRomsPerPlatform > 0) - { - if (TotalGameCount < collectionItem.MaximumRomsPerPlatform) - { - AddRoms = true; - } - } - else - { - AddRoms = true; - } - - if (AddRoms == true) - { - TotalGameCount += 1; - collectionGameItem.Roms = gameRoms; - collectionPlatformItem.Games.Add(collectionGameItem); - } - } - } - - // handle age grouping - List gameAgeRatings = game.AgeRatings.Select(s => (AgeRating)s).ToList(); - AgeGroups.AgeRestrictionGroupings CurrentAgeGroup = AgeGroups.GetAgeGroupFromAgeRatings(gameAgeRatings); - if (CurrentAgeGroup > AgeGrouping) - { - AgeGrouping = CurrentAgeGroup; - } - if (CurrentAgeGroup == AgeGroups.AgeRestrictionGroupings.Unclassified) - { - ContainsUnclassifiedAgeGroup = true; - } - } - - collectionPlatformItem.Games.Sort((x, y) => x.Name.CompareTo(y.Name)); - - if (collectionPlatformItem.Games.Count > 0) - { - bool AddPlatform = false; - if (collectionItem.MaximumCollectionSizeInBytes > 0) - { - if (TotalRomSize < collectionItem.MaximumCollectionSizeInBytes) - { - AddPlatform = true; - } - } - else - { - AddPlatform = true; - } - - if (AddPlatform == true) - { - collectionPlatformItems.Add(collectionPlatformItem); - } - } - } - - collectionPlatformItems.Sort((x, y) => x.Name.CompareTo(y.Name)); - - CollectionContents collectionContents = new CollectionContents - { - Collection = collectionPlatformItems, - AgeGroup = AgeGrouping, - ContainsUnclassifiedAgeGroup = ContainsUnclassifiedAgeGroup - }; - - return collectionContents; - } - - public static void CompileCollections(long CollectionId, string userid) - { - Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - - CollectionItem collectionItem = GetCollection(CollectionId, userid); - if (collectionItem.BuildStatus == CollectionItem.CollectionBuildStatus.WaitingForBuild) - { - Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.beginning_build", null, new string[] { collectionItem.Name }); - - CollectionContents collectionContents = GetCollectionContent(collectionItem, userid); - - // set starting - string sql = "UPDATE RomCollections SET BuiltStatus=@bs, AgeGroup=@ag, AgeGroupUnclassified=@agu WHERE Id=@id"; - Dictionary dbDict = new Dictionary - { - { "id", collectionItem.Id }, - { "bs", CollectionItem.CollectionBuildStatus.Building }, - { "ag", collectionContents.AgeGroup }, - { "agu", collectionContents.ContainsUnclassifiedAgeGroup } - }; - db.ExecuteCMD(sql, dbDict); - - List collectionPlatformItems = collectionContents.Collection; - string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, collectionItem.Id + collectionItem.ArchiveExtension); - string ZipFileTempPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, collectionItem.Id.ToString()); - - try - { - - // clean up if needed - if (File.Exists(ZipFilePath)) - { - Logging.LogKey(Logging.LogType.Warning, "process.collections", "collections.deleting_existing_build", null, new string[] { collectionItem.Name }); - File.Delete(ZipFilePath); - } - - if (Directory.Exists(ZipFileTempPath)) - { - Directory.Delete(ZipFileTempPath, true); - } - - // gather collection files - Directory.CreateDirectory(ZipFileTempPath); - string ZipBiosPath = Path.Combine(ZipFileTempPath, "BIOS"); - - // get the games - foreach (CollectionContents.CollectionPlatformItem collectionPlatformItem in collectionPlatformItems) - { - // get platform bios files if present - if (collectionItem.IncludeBIOSFiles == true) - { - List bios = Bios.GetBios(collectionPlatformItem.Id, true).Result; - if (!Directory.Exists(ZipBiosPath)) - { - Directory.CreateDirectory(ZipBiosPath); - } - - foreach (Bios.BiosItem biosItem in bios) - { - if (File.Exists(biosItem.biosPath)) - { - Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.copying_bios_file", null, new string[] { biosItem.filename }); - File.Copy(biosItem.biosPath, Path.Combine(ZipBiosPath, biosItem.filename), true); - } - } - } - - // create platform directory - string ZipPlatformPath = ""; - switch (collectionItem.FolderStructure) - { - case CollectionItem.FolderStructures.Gaseous: - ZipPlatformPath = Path.Combine(ZipFileTempPath, collectionPlatformItem.Slug); - break; - - case CollectionItem.FolderStructures.RetroPie: - try - { - PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(collectionPlatformItem.Id).Result; - ZipPlatformPath = Path.Combine(ZipFileTempPath, "roms", platformMapItem.RetroPieDirectoryName); - } - catch - { - ZipPlatformPath = Path.Combine(ZipFileTempPath, collectionPlatformItem.Slug); - } - - break; - - } - if (!Directory.Exists(ZipPlatformPath)) - { - Directory.CreateDirectory(ZipPlatformPath); - } - - foreach (CollectionContents.CollectionPlatformItem.CollectionGameItem collectionGameItem in collectionPlatformItem.Games) - { - bool includeGame = false; - if (collectionGameItem.InclusionStatus == null) - { - includeGame = true; - } - else - { - if (collectionGameItem.InclusionStatus.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude) - { - includeGame = true; - } - } - - if (includeGame == true) - { - string ZipGamePath = ""; - switch (collectionItem.FolderStructure) - { - case CollectionItem.FolderStructures.Gaseous: - // create game directory - ZipGamePath = Path.Combine(ZipPlatformPath, collectionGameItem.Slug); - if (!Directory.Exists(ZipGamePath)) - { - Directory.CreateDirectory(ZipGamePath); - } - break; - - case CollectionItem.FolderStructures.RetroPie: - ZipGamePath = ZipPlatformPath; - break; - } - - // copy in roms - foreach (Roms.GameRomItem gameRomItem in collectionGameItem.Roms) - { - if (File.Exists(gameRomItem.Path)) - { - Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.copying_rom", null, new string[] { gameRomItem.Name }); - File.Copy(gameRomItem.Path, Path.Combine(ZipGamePath, gameRomItem.Name), true); - } - } - } - } - } - - // compress to zip - Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.compressing_collection"); - switch (collectionItem.ArchiveType) - { - case CollectionItem.ArchiveTypes.Zip: - ZipFile.CreateFromDirectory(ZipFileTempPath, ZipFilePath, CompressionLevel.SmallestSize, false); - break; - - case CollectionItem.ArchiveTypes.RAR: - - break; - - case CollectionItem.ArchiveTypes.SevenZip: - - break; - } - - - // clean up - if (Directory.Exists(ZipFileTempPath)) - { - Logging.LogKey(Logging.LogType.Information, "process.collections", "collections.cleaning_up"); - Directory.Delete(ZipFileTempPath, true); - } - - // set completed - dbDict["bs"] = CollectionItem.CollectionBuildStatus.Completed; - db.ExecuteCMD(sql, dbDict); - } - catch (Exception ex) - { - // clean up - if (Directory.Exists(ZipFileTempPath)) - { - Directory.Delete(ZipFileTempPath, true); - } - - if (File.Exists(ZipFilePath)) - { - File.Delete(ZipFilePath); - } - - // set failed - dbDict["bs"] = CollectionItem.CollectionBuildStatus.Failed; - db.ExecuteCMD(sql, dbDict); - - Logging.LogKey(Logging.LogType.Critical, "process.collection_builder", "collections.build_failed", null, null, ex); - } - } - } - - private static CollectionItem BuildCollectionItem(DataRow row) - { - string strPlatforms = (string)Common.ReturnValueIfNull(row["Platforms"], "[ ]"); - string strGenres = (string)Common.ReturnValueIfNull(row["Genres"], "[ ]"); - string strPlayers = (string)Common.ReturnValueIfNull(row["Players"], "[ ]"); - string strPlayerPerspectives = (string)Common.ReturnValueIfNull(row["PlayerPerspectives"], "[ ]"); - string strThemes = (string)Common.ReturnValueIfNull(row["Themes"], "[ ]"); - string strAlwaysInclude = (string)Common.ReturnValueIfNull(row["AlwaysInclude"], "[ ]"); - - CollectionItem item = new CollectionItem(); - item.Id = (long)row["Id"]; - item.Name = (string)row["Name"]; - item.Description = (string)row["Description"]; - item.Platforms = Newtonsoft.Json.JsonConvert.DeserializeObject>(strPlatforms); - item.Genres = Newtonsoft.Json.JsonConvert.DeserializeObject>(strGenres); - item.Players = Newtonsoft.Json.JsonConvert.DeserializeObject>(strPlayers); - item.PlayerPerspectives = Newtonsoft.Json.JsonConvert.DeserializeObject>(strPlayerPerspectives); - item.Themes = Newtonsoft.Json.JsonConvert.DeserializeObject>(strThemes); - item.MinimumRating = (int)Common.ReturnValueIfNull(row["MinimumRating"], -1); - item.MaximumRating = (int)Common.ReturnValueIfNull(row["MaximumRating"], -1); - item.MaximumRomsPerPlatform = (int)Common.ReturnValueIfNull(row["MaximumRomsPerPlatform"], (int)-1); - item.MaximumBytesPerPlatform = (long)Common.ReturnValueIfNull(row["MaximumBytesPerPlatform"], (long)-1); - item.MaximumCollectionSizeInBytes = (long)Common.ReturnValueIfNull(row["MaximumCollectionSizeInBytes"], (long)-1); - item.FolderStructure = (CollectionItem.FolderStructures)(int)Common.ReturnValueIfNull(row["FolderStructure"], 0); - item.IncludeBIOSFiles = (bool)row["IncludeBIOSFiles"]; - item.ArchiveType = (CollectionItem.ArchiveTypes)(int)Common.ReturnValueIfNull(row["ArchiveType"], 0); - item.AlwaysInclude = Newtonsoft.Json.JsonConvert.DeserializeObject>(strAlwaysInclude); - item.BuildStatus = (CollectionItem.CollectionBuildStatus)(int)Common.ReturnValueIfNull(row["BuiltStatus"], 0); - - return item; - } - - public class CollectionItem - { - public CollectionItem() - { - - } - - public long Id { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public List? Platforms { get; set; } - public List? Genres { get; set; } - public List? Players { get; set; } - public List? PlayerPerspectives { get; set; } - public List? Themes { get; set; } - public int MinimumRating { get; set; } - public int MaximumRating { get; set; } - public int? MaximumRomsPerPlatform { get; set; } - public long? MaximumBytesPerPlatform { get; set; } - public long? MaximumCollectionSizeInBytes { get; set; } - public FolderStructures FolderStructure { get; set; } = FolderStructures.Gaseous; - public bool IncludeBIOSFiles { get; set; } = true; - public ArchiveTypes ArchiveType { get; set; } = CollectionItem.ArchiveTypes.Zip; - public string ArchiveExtension - { - get - { - if (ArchiveType != null) - { - switch (ArchiveType) - { - case ArchiveTypes.Zip: - default: - return ".zip"; - - case ArchiveTypes.RAR: - return ".rar"; - - case ArchiveTypes.SevenZip: - return ".7z"; - } - } - else - { - return ".zip"; - } - } - } - public List AlwaysInclude { get; set; } - - [JsonIgnore] - public CollectionBuildStatus BuildStatus - { - get - { - if (_BuildStatus == CollectionBuildStatus.Completed) - { - if (File.Exists(Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ArchiveExtension))) - { - return CollectionBuildStatus.Completed; - } - else - { - return CollectionBuildStatus.NoStatus; - } - } - else - { - return _BuildStatus; - } - } - set - { - _BuildStatus = value; - } - } - private CollectionBuildStatus _BuildStatus { get; set; } - - [JsonIgnore] - public long CollectionBuiltSizeBytes - { - get - { - if (BuildStatus == CollectionBuildStatus.Completed) - { - string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ArchiveExtension); - if (File.Exists(ZipFilePath)) - { - FileInfo fi = new FileInfo(ZipFilePath); - return fi.Length; - } - else - { - return 0; - } - } - else - { - return 0; - } - } - } - - public enum CollectionBuildStatus - { - NoStatus = 0, - WaitingForBuild = 1, - Building = 2, - Completed = 3, - Failed = 4 - } - - public enum FolderStructures - { - Gaseous = 0, - RetroPie = 1 - } - - public enum ArchiveTypes - { - Zip = 0, - RAR = 1, - SevenZip = 2 - } - - public class AlwaysIncludeItem - { - public long PlatformId { get; set; } - public long GameId { get; set; } - public AlwaysIncludeStatus InclusionState { get; set; } - } - - public enum AlwaysIncludeStatus - { - None = 0, - AlwaysInclude = 1, - AlwaysExclude = 2 - } - } - - public class CollectionContents - { - [JsonIgnore] - public List Collection { get; set; } - - [JsonIgnore] - public long CollectionProjectedSizeBytes - { - get - { - long CollectionSize = 0; - - List collectionPlatformItems = new List(); - - if (Collection != null) - { - collectionPlatformItems = Collection; - } - - foreach (CollectionPlatformItem platformItem in collectionPlatformItems) - { - CollectionSize += platformItem.RomSize; - } - - return CollectionSize; - } - } - - public AgeGroups.AgeRestrictionGroupings AgeGroup { get; set; } - public bool ContainsUnclassifiedAgeGroup { get; set; } - - public class CollectionPlatformItem - { - public CollectionPlatformItem(Platform platform) - { - string[] PropertyWhitelist = new string[] { "Id", "Name", "Slug" }; - - PropertyInfo[] srcProperties = typeof(Platform).GetProperties(); - PropertyInfo[] dstProperties = typeof(CollectionPlatformItem).GetProperties(); - foreach (PropertyInfo srcProperty in srcProperties) - { - if (PropertyWhitelist.Contains(srcProperty.Name)) - { - foreach (PropertyInfo dstProperty in dstProperties) - { - if (srcProperty.Name == dstProperty.Name) - { - dstProperty.SetValue(this, srcProperty.GetValue(platform)); - } - } - } - } - } - - public long Id { get; set; } - public string Name { get; set; } - public string Slug { get; set; } - - public List Games { get; set; } - - public int RomCount - { - get - { - int Counter = 0; - foreach (CollectionGameItem Game in Games) - { - Counter += 1; - } - - return Counter; - } - } - - public long RomSize - { - get - { - long Size = 0; - foreach (CollectionGameItem Game in Games) - { - foreach (Roms.GameRomItem Rom in Game.Roms) - { - Size += (long)Rom.Size; - } - } - - return Size; - } - } - - public class CollectionGameItem : MinimalGameItem - { - public CollectionGameItem(MinimalGameItem gameObject) - { - this.Id = gameObject.Id; - this.Name = gameObject.Name; - this.Slug = gameObject.Slug; - this.TotalRating = gameObject.TotalRating; - this.TotalRatingCount = gameObject.TotalRatingCount; - this.Cover = gameObject.Cover; - this.Artworks = gameObject.Artworks; - this.FirstReleaseDate = gameObject.FirstReleaseDate; - this.AgeRatings = gameObject.AgeRatings; - } - - public AgeGroups.AgeRestrictionGroupings AgeGrouping - { - get - { - List gameAgeRatings = this.AgeRatings.Select(s => (AgeRating)s).ToList(); - return AgeGroups.GetAgeGroupFromAgeRatings(gameAgeRatings); - } - } - - public CollectionItem.AlwaysIncludeItem InclusionStatus { get; set; } - - public List Roms { get; set; } - - public long RomSize - { - get - { - long Size = 0; - foreach (Roms.GameRomItem Rom in Roms) - { - Size += (long)Rom.Size; - } - - return Size; - } - } - } - } - } - } -} \ No newline at end of file diff --git a/gaseous-server/Classes/ProcessQueue/QueueItemStatus.cs b/gaseous-server/Classes/ProcessQueue/QueueItemStatus.cs deleted file mode 100644 index 836ef72..0000000 --- a/gaseous-server/Classes/ProcessQueue/QueueItemStatus.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace gaseous_server.Classes -{ - public class QueueItemStatus - { - internal object? CallingQueueItem = null; - - private int _CurrentItemNumber = 0; - private int _MaxItemsNumber = 0; - private string _StatusText = ""; - - public int CurrentItemNumber => _CurrentItemNumber; - public int MaxItemsNumber => _MaxItemsNumber; - public string StatusText => _StatusText; - - public void SetStatus(int CurrentItemNumber, int MaxItemsNumber, string StatusText) - { - this._CurrentItemNumber = CurrentItemNumber; - this._MaxItemsNumber = MaxItemsNumber; - this._StatusText = StatusText; - - SetCallingItemState(_CurrentItemNumber + " of " + _MaxItemsNumber + ": " + _StatusText, _CurrentItemNumber + " of " + _MaxItemsNumber); - } - - public void ClearStatus() - { - this._CurrentItemNumber = 0; - this._MaxItemsNumber = 0; - this._StatusText = ""; - - // SetCallingItemState("", ""); - } - - private void SetCallingItemState(string state, string progress) - { - if (CallingQueueItem != null) - { - // get object type of CallingQueueItem - string type = CallingQueueItem.GetType().ToString(); - - // check if type is QueueItem - switch (type) - { - case "gaseous_server.ProcessQueue.QueueProcessor+QueueItem": - // set CallingQueueItem to QueueItem - ProcessQueue.QueueProcessor.QueueItem callingQueueItem = (ProcessQueue.QueueProcessor.QueueItem)CallingQueueItem; - callingQueueItem.CurrentState = state; - callingQueueItem.CurrentStateProgress = progress; - break; - case "gaseous_server.ProcessQueue.QueueProcessor+QueueItem+SubTask": - // set CallingQueueItem to QueueItem.SubTask - ProcessQueue.QueueProcessor.QueueItem.SubTask callingSubTask = (ProcessQueue.QueueProcessor.QueueItem.SubTask)CallingQueueItem; - callingSubTask.CurrentState = state; - callingSubTask.CurrentStateProgress = progress; - break; - } - } - } - } -} \ No newline at end of file diff --git a/gaseous-server/Controllers/V1.0/AgeGroupMapsController.cs b/gaseous-server/Controllers/V1.0/AgeGroupMapsController.cs new file mode 100644 index 0000000..94fc9ef --- /dev/null +++ b/gaseous-server/Controllers/V1.0/AgeGroupMapsController.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using gaseous_server.Classes.Metadata; +using gaseous_server.Models; +using gaseous_server.Classes; +using IGDB.Models; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.CodeAnalysis.Scripting; +using Microsoft.AspNetCore.Authorization; +using System.Text; +using Asp.Versioning; + +namespace gaseous_server.Controllers +{ + [Route("api/v{version:apiVersion}/[controller]")] + [ApiVersion("1.0", Deprecated = true)] + [ApiVersion("1.1")] + [ApiController] + public class AgeGroupMapsController : Controller + { + [MapToApiVersion("1.0")] + [MapToApiVersion("1.1")] + [HttpGet] + [Route("AgeGroupMap.json")] + [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult DownloadAgeGroupMap() + { + try + { + string srcJson = Newtonsoft.Json.JsonConvert.SerializeObject(AgeGroups.AgeGroupMap, Newtonsoft.Json.Formatting.Indented); + + string filename = "AgeGroupMap.json"; + byte[] bytes = Encoding.UTF8.GetBytes(srcJson); + string contentType = "application/json"; + + var cd = new System.Net.Mime.ContentDisposition + { + FileName = filename, + Inline = true, + DispositionType = "attachment" + }; + + Response.Headers.Add("Content-Disposition", cd.ToString()); + + return File(bytes, contentType); + } + catch (Exception ex) + { + return StatusCode(StatusCodes.Status500InternalServerError, new { error = ex.Message }); + } + } + } +} diff --git a/gaseous-server/Controllers/V1.0/BackgroundTasksController.cs b/gaseous-server/Controllers/V1.0/BackgroundTasksController.cs index 98f7174..177cbd5 100644 --- a/gaseous-server/Controllers/V1.0/BackgroundTasksController.cs +++ b/gaseous-server/Controllers/V1.0/BackgroundTasksController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Asp.Versioning; using Microsoft.AspNetCore.Mvc.Infrastructure; +using System.Net; namespace gaseous_server.Controllers { @@ -13,13 +14,13 @@ namespace gaseous_server.Controllers [Route("api/v{version:apiVersion}/[controller]")] [ApiVersion("1.0", Deprecated = true)] [ApiVersion("1.1")] - [Authorize(Roles = "Admin,Gamer,Player")] public class BackgroundTasksController : Controller { [MapToApiVersion("1.0")] [MapToApiVersion("1.1")] [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] + [Authorize(Roles = "Admin,Gamer,Player")] public List GetQueue() { return ProcessQueue.QueueProcessor.QueueItems; @@ -51,5 +52,155 @@ namespace gaseous_server.Controllers return NotFound(); } + + /// + /// Updates the status of a background task identified by its correlation ID. The updated status information is provided in the request body as a QueueItem object. The method checks if the request is coming from the local machine for security reasons, then searches for the background task with the specified correlation ID and updates its current state and progress accordingly. If the task is found and updated, it returns an Ok response; if not found, it returns a NotFound response; if the request is not from the local machine, it returns a Forbid response. + /// + /// The correlation ID of the background task. + /// The updated status information for the background task. + /// Returns Ok if the task was found and updated, NotFound otherwise, Forbid if the request is not from the local machine. + [MapToApiVersion("1.0")] + [MapToApiVersion("1.1")] + [HttpPut] + [Route("{CorrelationId}/")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public IActionResult UpdateStatus(string CorrelationId, [FromBody] Dictionary UpdatedStatus) + { + var remoteIp = HttpContext.Connection.RemoteIpAddress; + if (remoteIp == null || !IPAddress.IsLoopback(remoteIp)) + { + return Forbid(); + } + + foreach (ProcessQueue.QueueProcessor.QueueItem qi in ProcessQueue.QueueProcessor.QueueItems) + { + if (qi.CorrelationId == CorrelationId) + { + qi.CurrentState = UpdatedStatus.ContainsKey("CurrentState") ? UpdatedStatus["CurrentState"].ToString() : qi.CurrentState; + qi.CurrentStateProgress = UpdatedStatus.ContainsKey("CurrentStateProgress") ? UpdatedStatus["CurrentStateProgress"].ToString() : qi.CurrentStateProgress; + return Ok(); + } + } + + return NotFound(); + } + + /// + /// Submits a subtask to a background task identified by its correlation ID. + /// + /// The correlation ID of the background task. + /// The subtask to add to the background task. + /// Returns Ok if the task was found and subtask added, NotFound otherwise. + [MapToApiVersion("1.0")] + [MapToApiVersion("1.1")] + [HttpPost] + [Route("{CorrelationId}/SubTask/")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task SubmitSubTask(string CorrelationId, [FromBody] Dictionary SubTask) + { + var remoteIp = HttpContext.Connection.RemoteIpAddress; + if (remoteIp == null || !IPAddress.IsLoopback(remoteIp)) + { + return Forbid(); + } + + ProcessQueue.QueueItemSubTasks? subTaskType = SubTask.ContainsKey("TaskType") ? Enum.Parse(SubTask["TaskType"].ToString()) : null; + if (subTaskType == null) + { + return BadRequest("SubTask must contain TaskType"); + } + + string taskName = SubTask.ContainsKey("TaskName") ? SubTask["TaskName"].ToString() : string.Empty; + object? settings = SubTask.ContainsKey("Settings") ? SubTask["Settings"] : null; + bool removeWhenCompleted = SubTask.ContainsKey("RemoveWhenCompleted") ? bool.Parse(SubTask["RemoveWhenCompleted"].ToString()) : false; + string correlationId = SubTask.ContainsKey("CorrelationId") ? SubTask["CorrelationId"].ToString() : ""; + + foreach (ProcessQueue.QueueProcessor.QueueItem qi in ProcessQueue.QueueProcessor.QueueItems) + { + if (qi.CorrelationId == CorrelationId) + { + await qi.AddSubTask(subTaskType.Value, taskName, settings, removeWhenCompleted, correlationId); + return Ok(); + } + } + + return NotFound(); + } + + /// + /// Updates a subtask within a background task identified by its correlation ID. + /// + /// The correlation ID of the background task. + /// The correlation ID of the subtask to update. + /// The updated subtask information containing the new state and progress. + /// Returns Ok if the task and subtask were found and updated, NotFound otherwise. + [MapToApiVersion("1.0")] + [MapToApiVersion("1.1")] + [HttpPut] + [Route("{CorrelationId}/SubTask/{SubTaskId}/")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task UpdateSubTask(string CorrelationId, string SubTaskId, [FromBody] Dictionary UpdatedSubTask) + { + var remoteIp = HttpContext.Connection.RemoteIpAddress; + if (remoteIp == null || !IPAddress.IsLoopback(remoteIp)) + { + return Forbid(); + } + + foreach (ProcessQueue.QueueProcessor.QueueItem qi in ProcessQueue.QueueProcessor.QueueItems) + { + if (qi.CorrelationId == CorrelationId) + { + if (qi.SubTasks != null) + { + ProcessQueue.QueueProcessor.QueueItem.SubTask? subTask = qi.SubTasks.FirstOrDefault(st => st.CorrelationId == SubTaskId); + if (subTask != null) + { + subTask.CurrentState = UpdatedSubTask.ContainsKey("CurrentState") ? UpdatedSubTask["CurrentState"] : subTask.CurrentState; + subTask.CurrentStateProgress = UpdatedSubTask.ContainsKey("CurrentStateProgress") ? UpdatedSubTask["CurrentStateProgress"] : subTask.CurrentStateProgress; + return Ok(); + } + } + } + } + + return NotFound(); + } + + [MapToApiVersion("1.0")] + [MapToApiVersion("1.1")] + [HttpDelete] + [Route("{CorrelationId}/SubTask/")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public IActionResult RemoveSubTask(string CorrelationId, string SubTaskId) + { + var remoteIp = HttpContext.Connection.RemoteIpAddress; + if (remoteIp == null || !IPAddress.IsLoopback(remoteIp)) + { + return Forbid(); + } + + foreach (ProcessQueue.QueueProcessor.QueueItem qi in ProcessQueue.QueueProcessor.QueueItems) + { + if (qi.CorrelationId == CorrelationId) + { + if (qi.SubTasks != null) + { + ProcessQueue.QueueProcessor.QueueItem.SubTask? subTask = qi.SubTasks.FirstOrDefault(st => st.CorrelationId == SubTaskId); + if (subTask != null) + { + qi.SubTasks.Remove(subTask); + return Ok(); + } + } + } + } + + return NotFound(); + } } } \ No newline at end of file diff --git a/gaseous-server/Controllers/V1.0/CollectionsController.cs b/gaseous-server/Controllers/V1.0/CollectionsController.cs index e5eacd6..2505b80 100644 --- a/gaseous-server/Controllers/V1.0/CollectionsController.cs +++ b/gaseous-server/Controllers/V1.0/CollectionsController.cs @@ -1,348 +1,348 @@ -using System; -using System.Collections.Generic; -using System.IO.Compression; -using System.Linq; -using System.Threading.Tasks; -using Authentication; -using gaseous_server.Classes; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Mvc; -using Asp.Versioning; +// using System; +// using System.Collections.Generic; +// using System.IO.Compression; +// using System.Linq; +// using System.Threading.Tasks; +// using Authentication; +// using gaseous_server.Classes; +// using Microsoft.AspNetCore.Authorization; +// using Microsoft.AspNetCore.Identity; +// using Microsoft.AspNetCore.Mvc; +// using Asp.Versioning; -namespace gaseous_server.Controllers -{ - [ApiController] - [Route("api/v{version:apiVersion}/[controller]")] - [ApiVersion("1.0", Deprecated = true)] - [ApiVersion("1.1")] - [Authorize] - public class CollectionsController : Controller - { - private readonly UserManager _userManager; - private readonly SignInManager _signInManager; +// namespace gaseous_server.Controllers +// { +// [ApiController] +// [Route("api/v{version:apiVersion}/[controller]")] +// [ApiVersion("1.0", Deprecated = true)] +// [ApiVersion("1.1")] +// [Authorize] +// public class CollectionsController : Controller +// { +// private readonly UserManager _userManager; +// private readonly SignInManager _signInManager; - public CollectionsController( - UserManager userManager, - SignInManager signInManager) - { - _userManager = userManager; - _signInManager = signInManager; - } +// public CollectionsController( +// UserManager userManager, +// SignInManager signInManager) +// { +// _userManager = userManager; +// _signInManager = signInManager; +// } - /// - /// Gets all ROM collections - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpGet] - [ProducesResponseType(StatusCodes.Status200OK)] - public async Task GetCollectionsAsync() - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Gets all ROM collections +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpGet] +// [ProducesResponseType(StatusCodes.Status200OK)] +// public async Task GetCollectionsAsync() +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - return Ok(Classes.Collections.GetCollections(user.Id)); - } +// if (user != null) +// { +// return Ok(Classes.Collections.GetCollections(user.Id)); +// } - return NotFound(); - } +// return NotFound(); +// } - /// - /// Gets a specific ROM collection - /// - /// - /// Set to true to begin the collection build process - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpGet] - [Route("{CollectionId}")] - [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCollection(long CollectionId, bool Build = false) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Gets a specific ROM collection +// /// +// /// +// /// Set to true to begin the collection build process +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpGet] +// [Route("{CollectionId}")] +// [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status404NotFound)] +// public async Task GetCollection(long CollectionId, bool Build = false) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - if (Build == true) - { - Classes.Collections.StartCollectionItemBuild(CollectionId, user.Id); - } +// if (user != null) +// { +// try +// { +// if (Build == true) +// { +// Classes.Collections.StartCollectionItemBuild(CollectionId, user.Id); +// } - return Ok(Classes.Collections.GetCollection(CollectionId, user.Id)); - } - catch - { - return NotFound(); - } - } - else - { - return NotFound(); - } - } +// return Ok(Classes.Collections.GetCollection(CollectionId, user.Id)); +// } +// catch +// { +// return NotFound(); +// } +// } +// else +// { +// return NotFound(); +// } +// } - /// - /// Gets the contents of the specified ROM collection - /// - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpGet] - [Route("{CollectionId}/Roms")] - [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCollectionRoms(long CollectionId) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Gets the contents of the specified ROM collection +// /// +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpGet] +// [Route("{CollectionId}/Roms")] +// [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status404NotFound)] +// public async Task GetCollectionRoms(long CollectionId) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - Classes.Collections.CollectionItem collectionItem = Classes.Collections.GetCollection(CollectionId, user.Id); - return Ok(Classes.Collections.GetCollectionContent(collectionItem, user.Id)); - } - catch - { - return NotFound(); - } - } - else - { - return NotFound(); - } - } +// if (user != null) +// { +// try +// { +// Classes.Collections.CollectionItem collectionItem = Classes.Collections.GetCollection(CollectionId, user.Id); +// return Ok(Classes.Collections.GetCollectionContent(collectionItem, user.Id)); +// } +// catch +// { +// return NotFound(); +// } +// } +// else +// { +// return NotFound(); +// } +// } - /// - /// Gets a preview of the provided collection item - /// - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpPost] - [Route("Preview")] - [Authorize(Roles = "Admin,Gamer")] - [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCollectionRomsPreview(Classes.Collections.CollectionItem Item) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Gets a preview of the provided collection item +// /// +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpPost] +// [Route("Preview")] +// [Authorize(Roles = "Admin,Gamer")] +// [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status404NotFound)] +// public async Task GetCollectionRomsPreview(Classes.Collections.CollectionItem Item) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - return Ok(Classes.Collections.GetCollectionContent(Item, user.Id)); - } - catch (Exception ex) - { - return NotFound(ex); - } - } - else - { - return NotFound(); - } - } +// if (user != null) +// { +// try +// { +// return Ok(Classes.Collections.GetCollectionContent(Item, user.Id)); +// } +// catch (Exception ex) +// { +// return NotFound(ex); +// } +// } +// else +// { +// return NotFound(); +// } +// } - /// - /// Gets ROM collection in zip format - /// - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpGet] - [Route("{CollectionId}/Roms/Zip")] - [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetCollectionRomsZip(long CollectionId) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Gets ROM collection in zip format +// /// +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpGet] +// [Route("{CollectionId}/Roms/Zip")] +// [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status404NotFound)] +// public async Task GetCollectionRomsZip(long CollectionId) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - Classes.Collections.CollectionItem collectionItem = Classes.Collections.GetCollection(CollectionId, user.Id); +// if (user != null) +// { +// try +// { +// Classes.Collections.CollectionItem collectionItem = Classes.Collections.GetCollection(CollectionId, user.Id); - string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, CollectionId + ".zip"); +// string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, CollectionId + ".zip"); - if (System.IO.File.Exists(ZipFilePath)) - { - var stream = new FileStream(ZipFilePath, FileMode.Open); - return File(stream, "application/zip", collectionItem.Name + ".zip"); - } - else - { - return NotFound(); - } - } - catch - { - return NotFound(); - } - } - else - { - return NotFound(); - } - } +// if (System.IO.File.Exists(ZipFilePath)) +// { +// var stream = new FileStream(ZipFilePath, FileMode.Open); +// return File(stream, "application/zip", collectionItem.Name + ".zip"); +// } +// else +// { +// return NotFound(); +// } +// } +// catch +// { +// return NotFound(); +// } +// } +// else +// { +// return NotFound(); +// } +// } - /// - /// Creates a new ROM collection - /// - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpPost] - [Authorize(Roles = "Admin,Gamer")] - [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task NewCollectionAsync(Classes.Collections.CollectionItem Item) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Creates a new ROM collection +// /// +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpPost] +// [Authorize(Roles = "Admin,Gamer")] +// [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status400BadRequest)] +// public async Task NewCollectionAsync(Classes.Collections.CollectionItem Item) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - return Ok(Classes.Collections.NewCollection(Item, user.Id)); - } - catch (Exception ex) - { - return BadRequest(ex); - } - } - else - { - return NotFound(); - } - } +// if (user != null) +// { +// try +// { +// return Ok(Classes.Collections.NewCollection(Item, user.Id)); +// } +// catch (Exception ex) +// { +// return BadRequest(ex); +// } +// } +// else +// { +// return NotFound(); +// } +// } - /// - /// Edits an existing collection - /// - /// - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpPatch] - [Route("{CollectionId}")] - [Authorize(Roles = "Admin,Gamer")] - [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task EditCollection(long CollectionId, Classes.Collections.CollectionItem Item) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Edits an existing collection +// /// +// /// +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpPatch] +// [Route("{CollectionId}")] +// [Authorize(Roles = "Admin,Gamer")] +// [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status404NotFound)] +// public async Task EditCollection(long CollectionId, Classes.Collections.CollectionItem Item) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - return Ok(Classes.Collections.EditCollection(CollectionId, Item, user.Id, true)); - } - catch - { - return NotFound(); - } - } - else - { - return NotFound(); - } - } +// if (user != null) +// { +// try +// { +// return Ok(Classes.Collections.EditCollection(CollectionId, Item, user.Id, true)); +// } +// catch +// { +// return NotFound(); +// } +// } +// else +// { +// return NotFound(); +// } +// } - /// - /// Edits an existing collection - /// - /// - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpPatch] - [Authorize(Roles = "Admin,Gamer")] - [Route("{CollectionId}/AlwaysInclude")] - [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task EditCollectionAlwaysInclude(long CollectionId, [FromQuery] bool Rebuild, [FromBody] Collections.CollectionItem.AlwaysIncludeItem Inclusion) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Edits an existing collection +// /// +// /// +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpPatch] +// [Authorize(Roles = "Admin,Gamer")] +// [Route("{CollectionId}/AlwaysInclude")] +// [ProducesResponseType(typeof(Classes.Collections.CollectionItem), StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status404NotFound)] +// public async Task EditCollectionAlwaysInclude(long CollectionId, [FromQuery] bool Rebuild, [FromBody] Collections.CollectionItem.AlwaysIncludeItem Inclusion) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - Collections.CollectionItem collectionItem = Classes.Collections.GetCollection(CollectionId, user.Id); - bool ItemFound = false; - foreach (Collections.CollectionItem.AlwaysIncludeItem includeItem in collectionItem.AlwaysInclude) - { - if (includeItem.PlatformId == Inclusion.PlatformId && includeItem.GameId == Inclusion.GameId) - { - ItemFound = true; - } - } - if (ItemFound == false) - { - collectionItem.AlwaysInclude.Add(Inclusion); - } +// if (user != null) +// { +// try +// { +// Collections.CollectionItem collectionItem = Classes.Collections.GetCollection(CollectionId, user.Id); +// bool ItemFound = false; +// foreach (Collections.CollectionItem.AlwaysIncludeItem includeItem in collectionItem.AlwaysInclude) +// { +// if (includeItem.PlatformId == Inclusion.PlatformId && includeItem.GameId == Inclusion.GameId) +// { +// ItemFound = true; +// } +// } +// if (ItemFound == false) +// { +// collectionItem.AlwaysInclude.Add(Inclusion); +// } - return Ok(Classes.Collections.EditCollection(CollectionId, collectionItem, user.Id, Rebuild)); - } - catch - { - return NotFound(); - } - } - else - { - return NotFound(); - } - } +// return Ok(Classes.Collections.EditCollection(CollectionId, collectionItem, user.Id, Rebuild)); +// } +// catch +// { +// return NotFound(); +// } +// } +// else +// { +// return NotFound(); +// } +// } - /// - /// Deletes the specified ROM collection - /// - /// - [MapToApiVersion("1.0")] - [MapToApiVersion("1.1")] - [HttpDelete] - [Authorize(Roles = "Admin,Gamer")] - [Route("{CollectionId}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task DeleteCollection(long CollectionId) - { - var user = await _userManager.GetUserAsync(User); +// /// +// /// Deletes the specified ROM collection +// /// +// /// +// [MapToApiVersion("1.0")] +// [MapToApiVersion("1.1")] +// [HttpDelete] +// [Authorize(Roles = "Admin,Gamer")] +// [Route("{CollectionId}")] +// [ProducesResponseType(StatusCodes.Status200OK)] +// [ProducesResponseType(StatusCodes.Status404NotFound)] +// public async Task DeleteCollection(long CollectionId) +// { +// var user = await _userManager.GetUserAsync(User); - if (user != null) - { - try - { - Classes.Collections.DeleteCollection(CollectionId, user.Id); - return Ok(); - } - catch - { - return NotFound(); - } - } - else - { - return NotFound(); - } - } - } -} \ No newline at end of file +// if (user != null) +// { +// try +// { +// Classes.Collections.DeleteCollection(CollectionId, user.Id); +// return Ok(); +// } +// catch +// { +// return NotFound(); +// } +// } +// else +// { +// return NotFound(); +// } +// } +// } +// } \ No newline at end of file diff --git a/gaseous-server/Controllers/V1.0/PlatformsController.cs b/gaseous-server/Controllers/V1.0/PlatformsController.cs index b3e6b23..bae0426 100644 --- a/gaseous-server/Controllers/V1.0/PlatformsController.cs +++ b/gaseous-server/Controllers/V1.0/PlatformsController.cs @@ -282,9 +282,9 @@ namespace gaseous_server.Controllers private ActionResult GetDummyImage() { // return resource named DefaultPlatformLogo.svg - var assembly = Assembly.GetExecutingAssembly(); - string resourceName = "gaseous_server.Support.DefaultPlatformLogo.svg"; - string[] resources = Assembly.GetExecutingAssembly().GetManifestResourceNames(); + var assembly = Assembly.Load("gaseous-lib"); + string resourceName = "gaseous_lib.Support.DefaultPlatformLogo.svg"; + string[] resources = assembly.GetManifestResourceNames(); if (resources.Contains(resourceName)) { string svgData = ""; diff --git a/gaseous-server/Controllers/V1.0/SystemController.cs b/gaseous-server/Controllers/V1.0/SystemController.cs index 45a38c1..a1b4aeb 100644 --- a/gaseous-server/Controllers/V1.0/SystemController.cs +++ b/gaseous-server/Controllers/V1.0/SystemController.cs @@ -14,6 +14,8 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Razor.Hosting; using RestEase; using Asp.Versioning; +using gaseous_server.ProcessQueue; +using gaseous_server.Models; namespace gaseous_server.Controllers { @@ -28,11 +30,11 @@ namespace gaseous_server.Controllers [MapToApiVersion("1.1")] [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] - public SystemInfo GetSystemStatus() + public SystemInfoModel GetSystemStatus() { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); - SystemInfo ReturnValue = new SystemInfo(); + SystemInfoModel ReturnValue = new SystemInfoModel(); // // disk size // List Disks = new List(); @@ -65,10 +67,10 @@ FROM GROUP BY Platform.`Name` ORDER BY Platform.`Name`; "; dbResponse = db.ExecuteCMD(sql); - ReturnValue.PlatformStatistics = new List(); + ReturnValue.PlatformStatistics = new List(); foreach (DataRow dr in dbResponse.Rows) { - SystemInfo.PlatformStatisticsItem platformStatisticsItem = new SystemInfo.PlatformStatisticsItem + SystemInfoModel.PlatformStatisticsItem platformStatisticsItem = new SystemInfoModel.PlatformStatisticsItem { Platform = (string)dr["name"], RomCount = (long)dr["Count"], @@ -450,539 +452,5 @@ ORDER BY Platform.`Name`; "; return Ok(); } - - public static SystemInfo.PathItem GetDisk(string Path) - { - SystemInfo.PathItem pathItem = new SystemInfo.PathItem - { - LibraryPath = Path, - SpaceUsed = Common.DirSize(new DirectoryInfo(Path)), - SpaceAvailable = new DriveInfo(Path).AvailableFreeSpace, - TotalSpace = new DriveInfo(Path).TotalSize - }; - - return pathItem; - } - - public class SystemInfo - { - public Version ApplicationVersion - { - get - { - return Assembly.GetExecutingAssembly().GetName().Version; - } - } - public List? Paths { get; set; } - public long DatabaseSize { get; set; } - public List? PlatformStatistics { get; set; } - - public class PathItem - { - public string Name { get; set; } - public string LibraryPath { get; set; } - public long SpaceUsed { get; set; } - public long SpaceAvailable { get; set; } - public long TotalSpace { get; set; } - } - - public class PlatformStatisticsItem - { - public string Platform { get; set; } - public long RomCount { get; set; } - public long TotalSize { get; set; } - } - } - } - - public class BackgroundTaskItem - { - public BackgroundTaskItem() - { - - } - - public BackgroundTaskItem(ProcessQueue.QueueItemType TaskName) - { - this.Task = TaskName.ToString(); - this.TaskEnum = TaskName; - - switch (TaskName) - { - case ProcessQueue.QueueItemType.SignatureIngestor: - this._UserManageable = true; - this._SaveLastRunTime = true; - this.DefaultInterval = 60; - this.MinimumAllowedInterval = 20; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - break; - - case ProcessQueue.QueueItemType.TitleIngestor: - this._UserManageable = true; - this._SaveLastRunTime = true; - this.DefaultInterval = 1; - this.MinimumAllowedInterval = 1; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - this._Blocks = new List{ - ProcessQueue.QueueItemType.OrganiseLibrary, - ProcessQueue.QueueItemType.LibraryScan, - ProcessQueue.QueueItemType.LibraryScanWorker, - ProcessQueue.QueueItemType.MetadataRefresh - }; - break; - - case ProcessQueue.QueueItemType.MetadataRefresh: - this._UserManageable = true; - this._SaveLastRunTime = true; - this.DefaultInterval = 1440; - this.MinimumAllowedInterval = 1440; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - this._Blocks = new List - { - ProcessQueue.QueueItemType.OrganiseLibrary, - ProcessQueue.QueueItemType.LibraryScan, - ProcessQueue.QueueItemType.LibraryScanWorker, - ProcessQueue.QueueItemType.TitleIngestor - }; - break; - - case ProcessQueue.QueueItemType.OrganiseLibrary: - this._UserManageable = true; - this._SaveLastRunTime = true; - this.DefaultInterval = 1440; - this.MinimumAllowedInterval = 120; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - this._Blocks = new List{ - ProcessQueue.QueueItemType.LibraryScan, - ProcessQueue.QueueItemType.LibraryScanWorker, - ProcessQueue.QueueItemType.TitleIngestor, - ProcessQueue.QueueItemType.MetadataRefresh - }; - break; - - case ProcessQueue.QueueItemType.LibraryScan: - this._UserManageable = true; - this._SaveLastRunTime = true; - this.DefaultInterval = 1440; - this.MinimumAllowedInterval = 120; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - this._Blocks = new List{ - ProcessQueue.QueueItemType.OrganiseLibrary, - ProcessQueue.QueueItemType.MetadataRefresh - }; - break; - - case ProcessQueue.QueueItemType.DailyMaintainer: - this._UserManageable = true; - this._SaveLastRunTime = true; - this.DefaultInterval = 1440; - this.MinimumAllowedInterval = 1440; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 1; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 5; - this.DefaultAllowedEndMinutes = 59; - this._Blocks = new List{ - ProcessQueue.QueueItemType.All - }; - break; - - case ProcessQueue.QueueItemType.WeeklyMaintainer: - this._UserManageable = true; - this._SaveLastRunTime = true; - this.DefaultInterval = 10080; - this.MinimumAllowedInterval = 10080; - this.DefaultAllowedDays = new List{ - DayOfWeek.Monday - }; - this.DefaultAllowedStartHours = 1; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 5; - this.DefaultAllowedEndMinutes = 59; - this._Blocks = new List{ - ProcessQueue.QueueItemType.All - }; - break; - - case ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade: - this._UserManageable = false; - this.DefaultInterval = 1; - this.MinimumAllowedInterval = 1; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - this._Blocks.Add(ProcessQueue.QueueItemType.All); - break; - - case ProcessQueue.QueueItemType.TempCleanup: - this._UserManageable = true; - this.DefaultInterval = 1; - this.MinimumAllowedInterval = 1; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - break; - - default: - this._UserManageable = false; - this.DefaultAllowedDays = new List{ - DayOfWeek.Sunday, - DayOfWeek.Monday, - DayOfWeek.Tuesday, - DayOfWeek.Wednesday, - DayOfWeek.Thursday, - DayOfWeek.Friday, - DayOfWeek.Saturday - }; - this.DefaultAllowedStartHours = 0; - this.DefaultAllowedStartMinutes = 0; - this.DefaultAllowedEndHours = 23; - this.DefaultAllowedEndMinutes = 59; - break; - } - } - - public string Task { get; set; } - public ProcessQueue.QueueItemType TaskEnum { get; set; } - public bool Enabled - { - get - { - if (_UserManageable == true) - { - return bool.Parse(Config.ReadSetting("Enabled_" + Task, true.ToString())); - } - else - { - return true; - } - } - set - { - if (_UserManageable == true) - { - Config.SetSetting("Enabled_" + Task, value.ToString()); - } - } - } - private bool _UserManageable; - public bool UserManageable => _UserManageable; - private bool _SaveLastRunTime; - public bool SaveLastRunTime => _SaveLastRunTime; - public int Interval - { - get - { - return int.Parse(Config.ReadSetting("Interval_" + Task, DefaultInterval.ToString())); - } - } - public int DefaultInterval { get; set; } - public int MinimumAllowedInterval { get; set; } - public List AllowedDays - { - get - { - string jsonDefaultAllowedDays = Newtonsoft.Json.JsonConvert.SerializeObject(DefaultAllowedDays); - return Newtonsoft.Json.JsonConvert.DeserializeObject>(Config.ReadSetting("AllowedDays_" + Task, jsonDefaultAllowedDays)); - } - } - public int AllowedStartHours - { - get - { - return int.Parse(Config.ReadSetting("AllowedStartHours_" + Task, DefaultAllowedStartHours.ToString())); - } - } - public int AllowedStartMinutes - { - get - { - return int.Parse(Config.ReadSetting("AllowedStartMinutes_" + Task, DefaultAllowedStartMinutes.ToString())); - } - } - public int AllowedEndHours - { - get - { - return int.Parse(Config.ReadSetting("AllowedEndHours_" + Task, DefaultAllowedEndHours.ToString())); - } - } - public int AllowedEndMinutes - { - get - { - return int.Parse(Config.ReadSetting("AllowedEndMinutes_" + Task, DefaultAllowedEndMinutes.ToString())); - } - } - public List DefaultAllowedDays { get; set; } - public int DefaultAllowedStartHours { get; set; } - public int DefaultAllowedStartMinutes { get; set; } - public int DefaultAllowedEndHours { get; set; } - public int DefaultAllowedEndMinutes { get; set; } - private List _Blocks = new List(); - public List Blocks - { - get - { - if (_Blocks.Contains(ProcessQueue.QueueItemType.All)) - { - List blockList = new List(); - List skipBlockItems = new List{ - ProcessQueue.QueueItemType.All, - ProcessQueue.QueueItemType.NotConfigured, - this.TaskEnum - }; - foreach (ProcessQueue.QueueItemType blockType in Enum.GetValues(typeof(ProcessQueue.QueueItemType))) - { - if (!skipBlockItems.Contains(blockType)) - { - blockList.Add(blockType); - } - } - return blockList; - } - else - { - return _Blocks; - } - } - } - public List BlockedBy - { - get - { - List blockedBy = new List(); - - List backgroundTaskItems = new List(); - foreach (ProcessQueue.QueueItemType blockType in Enum.GetValues(typeof(ProcessQueue.QueueItemType))) - { - if (blockType != this.TaskEnum) - { - BackgroundTaskItem taskItem = new BackgroundTaskItem(blockType); - if (taskItem.Blocks.Contains(this.TaskEnum)) - { - if (!blockedBy.Contains(blockType)) - { - blockedBy.Add(blockType); - } - } - } - } - - return blockedBy; - } - } - } - - public class BackgroundTaskSettingsItem - { - public string Task { get; set; } - public bool Enabled { get; set; } - public int Interval { get; set; } - public List AllowedDays { get; set; } - public int AllowedStartHours { get; set; } - public int AllowedStartMinutes { get; set; } - public int AllowedEndHours { get; set; } - public int AllowedEndMinutes { get; set; } - } - - public class SystemSettingsModel - { - public bool AlwaysLogToDisk { get; set; } - public int MinimumLogRetentionPeriod { get; set; } - public bool EmulatorDebugMode { get; set; } - public SignatureSourceItem SignatureSource { get; set; } - public List MetadataSources { get; set; } - - public class SignatureSourceItem - { - public HasheousClient.Models.MetadataModel.SignatureSources Source { get; set; } - public string HasheousHost { get; set; } - public string HasheousAPIKey { get; set; } - public bool HasheousSubmitFixes { get; set; } - } - - public class MetadataSourceItem - { - public MetadataSourceItem() - { - - } - - public MetadataSourceItem(FileSignature.MetadataSources source, bool useHasheousProxy, string clientId, string secret, FileSignature.MetadataSources defaultSource) - { - Source = source; - UseHasheousProxy = useHasheousProxy; - ClientId = clientId; - Secret = secret; - if (Source == defaultSource) - { - Default = true; - } - else - { - Default = false; - } - } - - public FileSignature.MetadataSources Source { get; set; } - public bool UseHasheousProxy { get; set; } - public string ClientId { get; set; } - public string Secret { get; set; } - public bool Default { get; set; } - public bool? Configured - { - get - { - switch (Source) - { - case FileSignature.MetadataSources.None: - return true; - case FileSignature.MetadataSources.IGDB: - if ((!String.IsNullOrEmpty(ClientId) && !String.IsNullOrEmpty(Secret)) || UseHasheousProxy == true) - { - return true; - } - else - { - return false; - } - case FileSignature.MetadataSources.TheGamesDb: - if ((!String.IsNullOrEmpty(ClientId) && !String.IsNullOrEmpty(Secret)) || UseHasheousProxy == true) - { - return true; - } - else - { - return false; - } - default: - return false; - } - } - } - public bool? UsesProxy - { - get - { - switch (Source) - { - case FileSignature.MetadataSources.None: - return false; - case FileSignature.MetadataSources.IGDB: - return true; - case FileSignature.MetadataSources.TheGamesDb: - return true; - default: - return false; - } - } - } - public bool? UsesClientIdAndSecret - { - get - { - switch (Source) - { - case FileSignature.MetadataSources.None: - return false; - case FileSignature.MetadataSources.IGDB: - return true; - case FileSignature.MetadataSources.TheGamesDb: - return false; - default: - return false; - } - } - } - } } } \ No newline at end of file diff --git a/gaseous-server/Controllers/V1.1/FirstSetupController.cs b/gaseous-server/Controllers/V1.1/FirstSetupController.cs index 0e7d520..da80ecf 100644 --- a/gaseous-server/Controllers/V1.1/FirstSetupController.cs +++ b/gaseous-server/Controllers/V1.1/FirstSetupController.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Asp.Versioning; +using gaseous_server.Models; namespace gaseous_server.Controllers { @@ -102,7 +103,7 @@ namespace gaseous_server.Controllers [Authorize(Roles = "Admin")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult SetupDatasources(SystemSettingsModel model) + public ActionResult SetupDatasources(gaseous_server.Models.SystemSettingsModel model) { if (Config.ReadSetting("FirstRunStatus", "0") == "1") { diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs index 76e97a9..fb90f6c 100644 --- a/gaseous-server/Program.cs +++ b/gaseous-server/Program.cs @@ -37,12 +37,6 @@ if (OperatingSystem.IsWindows()) options.ServiceName = "GaseousServer"; }); - // Bind Kestrel to the configured HTTP port - builder.WebHost.ConfigureKestrel(options => - { - options.ListenAnyIP(Config.ServerPort); - }); - // When running as a Windows Service there is no console; route logs to Windows Event Log too. // Suppress CA1416 analyzer as this is guarded by a runtime OS check. #pragma warning disable CA1416 @@ -50,6 +44,25 @@ if (OperatingSystem.IsWindows()) #pragma warning restore CA1416 } +// Bind Kestrel to the configured HTTP port +builder.WebHost.ConfigureKestrel(options => +{ + options.ListenLocalhost(Config.LocalCommsPort); // for local inter-process communication (e.g. with the process host) + + if (builder.Environment.IsDevelopment()) + { + // In development mode, also listen on localhost HTTPS (port 5199 from launchSettings) + options.ListenAnyIP(5198, listenOptions => + { + listenOptions.UseHttps(); + }); + } + else + { + options.ListenAnyIP(Config.ServerPort); // for incoming API requests; ListenAnyIP allows external access when not running in a container, and still works with Docker's port forwarding when running in a container + } +}); + // Add services to the container. builder.Services.AddControllers().AddJsonOptions(x => { diff --git a/gaseous-server/StartupInitializer.cs b/gaseous-server/StartupInitializer.cs index 6446497..10d47c6 100644 --- a/gaseous-server/StartupInitializer.cs +++ b/gaseous-server/StartupInitializer.cs @@ -106,6 +106,9 @@ namespace gaseous_server ProcessQueue.QueueProcessor.QueueItems.Add(new ProcessQueue.QueueProcessor.QueueItem(ProcessQueue.QueueItemType.WeeklyMaintainer)); ProcessQueue.QueueProcessor.QueueItems.Add(new ProcessQueue.QueueProcessor.QueueItem(ProcessQueue.QueueItemType.TempCleanup)); + // enable the timer after all startup tasks have been queued to prevent any race conditions with the timer trying to execute tasks before they have been added to the queue + Config.BackgroundTasksEnabled = true; + Logging.WriteToDiskOnly = false; Logging.LogKey(Logging.LogType.Information, "process.startup", "startup.initialization_complete"); } diff --git a/gaseous-server/gaseous-server.csproj b/gaseous-server/gaseous-server.csproj index e1ca21d..f96e59b 100644 --- a/gaseous-server/gaseous-server.csproj +++ b/gaseous-server/gaseous-server.csproj @@ -19,26 +19,8 @@ bin\Release\net10.0\gaseous-server.xml - - - - - - - - - - - - - - - - - - - - + + @@ -76,19 +58,36 @@ - - - true - PreserveNewest - - - - - - - + + + + + + $(MSBuildProjectDirectory)/../gaseous-lib/bin/$(Configuration)/net10.0/ + + + + + + + + + + + + + $(MSBuildProjectDirectory)/../gaseous-processhost/bin/$(Configuration)/net10.0/ + + + + + + + + + @@ -109,8 +108,34 @@ - - + + + + $(MSBuildProjectDirectory)/../gaseous-lib/bin/$(Configuration)/net10.0/ + + + + + + + + + + + + + $(MSBuildProjectDirectory)/../gaseous-processhost/bin/$(Configuration)/net10.0/ + + + + + + + + + + + $(PublishDir) diff --git a/gaseous-server/wwwroot/index.html b/gaseous-server/wwwroot/index.html index 39d3bef..218407c 100644 --- a/gaseous-server/wwwroot/index.html +++ b/gaseous-server/wwwroot/index.html @@ -317,7 +317,7 @@ supportedMetadataSources = versionFile.SupportedMetadataSources; // load age rating mappings - AgeRatingMappings = await fetch('/images/Ratings/AgeGroupMap.json') + AgeRatingMappings = await fetch('/api/v1.1/AgeGroupMaps/AgeGroupMap.json') .then(response => { if (response.ok) { return response.json(); diff --git a/gaseous-server/wwwroot/scripts/preferences.js b/gaseous-server/wwwroot/scripts/preferences.js index 269fc5e..b8f4d07 100644 --- a/gaseous-server/wwwroot/scripts/preferences.js +++ b/gaseous-server/wwwroot/scripts/preferences.js @@ -27,7 +27,7 @@ class PreferencesWindow { }); // load age rating mappings - this.AgeRatingMappings = await fetch('/images/Ratings/AgeGroupMap.json') + this.AgeRatingMappings = await fetch('/api/v1.1/AgeGroupMaps/AgeGroupMap.json') .then(async response => { if (response.ok) { return await response.json();