diff --git a/CHANGELOG.md b/CHANGELOG.md index 41895b842..7636f30e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the language localization for Catalan (`ca`) +### Fixed + +- Fixed an issue with the locale in the scraper configuration + ## 2.174.0 - 2025-06-24 ### Added diff --git a/apps/api/src/app/admin/admin.controller.ts b/apps/api/src/app/admin/admin.controller.ts index 82524ef9b..8531cf95c 100644 --- a/apps/api/src/app/admin/admin.controller.ts +++ b/apps/api/src/app/admin/admin.controller.ts @@ -17,7 +17,8 @@ import { AdminData, AdminMarketData, AdminUsers, - EnhancedSymbolProfile + EnhancedSymbolProfile, + ScraperConfiguration } from '@ghostfolio/common/interfaces'; import { permissions } from '@ghostfolio/common/permissions'; import type { @@ -222,13 +223,12 @@ export class AdminController { @Post('market-data/:dataSource/:symbol/test') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async testMarketData( - @Body() data: { scraperConfiguration: string }, + @Body() data: { scraperConfiguration: ScraperConfiguration }, @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ): Promise<{ price: number }> { try { - const scraperConfiguration = JSON.parse(data.scraperConfiguration); - const price = await this.manualService.test(scraperConfiguration); + const price = await this.manualService.test(data.scraperConfiguration); if (price) { return { price }; diff --git a/apps/api/src/services/data-provider/manual/manual.service.ts b/apps/api/src/services/data-provider/manual/manual.service.ts index 66e625e47..bcaa77a17 100644 --- a/apps/api/src/services/data-provider/manual/manual.service.ts +++ b/apps/api/src/services/data-provider/manual/manual.service.ts @@ -104,7 +104,7 @@ export class ManualService implements DataProviderInterface { } return historical; - } else if (selector === undefined || url === undefined) { + } else if (!selector || !url) { return {}; } @@ -162,7 +162,11 @@ export class ManualService implements DataProviderInterface { const symbolProfilesWithScraperConfigurationAndInstantMode = symbolProfiles.filter(({ scraperConfiguration }) => { - return scraperConfiguration?.mode === 'instant'; + return ( + scraperConfiguration?.mode === 'instant' && + scraperConfiguration?.selector && + scraperConfiguration?.url + ); }); const scraperResultPromises = diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index d9b344699..c52d9137d 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -11,6 +11,7 @@ import { AdminMarketDataDetails, AssetProfileIdentifier, LineChartItem, + ScraperConfiguration, User } from '@ghostfolio/common/interfaces'; import { translate } from '@ghostfolio/ui/i18n'; @@ -41,6 +42,7 @@ import { AssetClass, AssetSubClass, MarketData, + Prisma, SymbolProfile } from '@prisma/client'; import { format } from 'date-fns'; @@ -343,7 +345,10 @@ export class AssetProfileDialog implements OnDestroy, OnInit { public async onSubmitAssetProfileForm() { let countries = []; - let scraperConfiguration = {}; + let scraperConfiguration: ScraperConfiguration = { + selector: '', + url: '' + }; let sectors = []; let symbolMapping = {}; @@ -354,9 +359,9 @@ export class AssetProfileDialog implements OnDestroy, OnInit { try { scraperConfiguration = { defaultMarketPrice: - this.assetProfileForm.controls['scraperConfiguration'].controls[ + (this.assetProfileForm.controls['scraperConfiguration'].controls[ 'defaultMarketPrice' - ].value, + ].value as number) || undefined, headers: JSON.parse( this.assetProfileForm.controls['scraperConfiguration'].controls[ 'headers' @@ -365,10 +370,10 @@ export class AssetProfileDialog implements OnDestroy, OnInit { locale: this.assetProfileForm.controls['scraperConfiguration'].controls[ 'locale' - ].value, + ].value || undefined, mode: this.assetProfileForm.controls['scraperConfiguration'].controls[ 'mode' - ].value, + ].value as ScraperConfiguration['mode'], selector: this.assetProfileForm.controls['scraperConfiguration'].controls[ 'selector' @@ -377,6 +382,10 @@ export class AssetProfileDialog implements OnDestroy, OnInit { 'url' ].value }; + + if (!scraperConfiguration.selector || !scraperConfiguration.url) { + scraperConfiguration = undefined; + } } catch {} try { @@ -391,7 +400,6 @@ export class AssetProfileDialog implements OnDestroy, OnInit { const assetProfile: UpdateAssetProfileDto = { countries, - scraperConfiguration, sectors, symbolMapping, assetClass: this.assetProfileForm.get('assetClass').value, @@ -400,6 +408,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit { currency: this.assetProfileForm.get('currency').value, isActive: this.assetProfileForm.get('isActive').value, name: this.assetProfileForm.get('name').value, + scraperConfiguration: + scraperConfiguration as unknown as Prisma.InputJsonObject, url: this.assetProfileForm.get('url').value || null }; @@ -493,11 +503,10 @@ export class AssetProfileDialog implements OnDestroy, OnInit { this.adminService .testMarketData({ dataSource: this.data.dataSource, - scraperConfiguration: JSON.stringify({ - defaultMarketPrice: - this.assetProfileForm.controls['scraperConfiguration'].controls[ - 'defaultMarketPrice' - ].value, + scraperConfiguration: { + defaultMarketPrice: this.assetProfileForm.controls[ + 'scraperConfiguration' + ].controls['defaultMarketPrice'].value as number, headers: JSON.parse( this.assetProfileForm.controls['scraperConfiguration'].controls[ 'headers' @@ -506,7 +515,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit { locale: this.assetProfileForm.controls['scraperConfiguration'].controls[ 'locale' - ].value, + ].value || undefined, mode: this.assetProfileForm.controls['scraperConfiguration'].controls[ 'mode' ].value, @@ -517,7 +526,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit { url: this.assetProfileForm.controls['scraperConfiguration'].controls[ 'url' ].value - }), + }, symbol: this.data.symbol }) .pipe(