Browse Source

Bugfix/fix locale in scraper configuration (#5011)

* Fix locale in scraper configuration

* Update changelog
pull/5031/head
Thomas Kaul 6 days ago
committed by GitHub
parent
commit
a7a33eeb56
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 8
      apps/api/src/app/admin/admin.controller.ts
  3. 8
      apps/api/src/services/data-provider/manual/manual.service.ts
  4. 35
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts

4
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

8
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 };

8
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 =

35
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(

Loading…
Cancel
Save