Browse Source

Refactoring

pull/2808/head
Thomas Kaul 2 years ago
parent
commit
1b7ec2f92c
  1. 23
      apps/api/src/app/admin/admin.controller.ts
  2. 62
      apps/api/src/services/data-provider/manual/manual.service.ts
  3. 33
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
  4. 2
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
  5. 13
      apps/client/src/app/services/admin.service.ts

23
apps/api/src/app/admin/admin.controller.ts

@ -32,6 +32,7 @@ import {
Get, Get,
HttpException, HttpException,
Inject, Inject,
Logger,
Param, Param,
Patch, Patch,
Post, Post,
@ -218,17 +219,29 @@ export class AdminController {
} }
@HasPermission(permissions.accessAdminControl) @HasPermission(permissions.accessAdminControl)
@Post('test-scraper') @Post('market-data/:dataSource/:symbol/test')
@UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async testScraper( public async testMarketData(
@Body() data: { config: string } @Body() data: { scraperConfiguration: string },
@Param('dataSource') dataSource: DataSource,
@Param('symbol') symbol: string
): Promise<{ price: number }> { ): Promise<{ price: number }> {
const { selector, url } = JSON.parse(data.config); try {
const price = await this.manualService.scrape(url, selector); const { headers, selector, url } = JSON.parse(data.scraperConfiguration);
const price = await this.manualService.test({ headers, selector, url });
if (price) {
return { price }; return { price };
} }
throw new Error('Could not parse the current market price');
} catch (error) {
Logger.error(error);
throw new HttpException(error.message, StatusCodes.BAD_REQUEST);
}
}
@HasPermission(permissions.accessAdminControl) @HasPermission(permissions.accessAdminControl)
@Post('market-data/:dataSource/:symbol') @Post('market-data/:dataSource/:symbol')
@UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseGuards(AuthGuard('jwt'), HasPermissionGuard)

62
apps/api/src/services/data-provider/manual/manual.service.ts

@ -97,7 +97,7 @@ export class ManualService implements DataProviderInterface {
return {}; return {};
} }
const value = await this.scrape(url, selector, headers); const value = await this.scrape({ headers, selector, url });
return { return {
[symbol]: { [symbol]: {
[format(getYesterday(), DATE_FORMAT)]: { [format(getYesterday(), DATE_FORMAT)]: {
@ -115,28 +115,6 @@ export class ManualService implements DataProviderInterface {
} }
} }
public async scrape(
url: string,
selector: string,
headers = {}
): Promise<number> {
const abortController = new AbortController();
setTimeout(() => {
abortController.abort();
}, this.configurationService.get('REQUEST_TIMEOUT'));
const { body } = await got(url, {
headers,
// @ts-ignore
signal: abortController.signal
});
const $ = cheerio.load(body);
return extractNumberFromString($(selector).first().text());
}
public getName(): DataSource { public getName(): DataSource {
return DataSource.MANUAL; return DataSource.MANUAL;
} }
@ -240,4 +218,42 @@ export class ManualService implements DataProviderInterface {
return { items }; return { items };
} }
public async test(params: any) {
return this.scrape({
headers: params.headers,
selector: params.selector,
url: params.url
});
}
private async scrape({
headers = {},
selector,
url
}: {
headers?: any;
selector: string;
url: string;
}): Promise<number> {
try {
const abortController = new AbortController();
setTimeout(() => {
abortController.abort();
}, this.configurationService.get('REQUEST_TIMEOUT'));
const { body } = await got(url, {
headers,
// @ts-ignore
signal: abortController.signal
});
const $ = cheerio.load(body);
return extractNumberFromString($(selector).first().text());
} catch (error) {
throw error;
}
}
} }

33
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts

@ -277,18 +277,31 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
}); });
} }
public onTestScraper() { public onTestMarketData() {
this.adminService this.adminService
.testScrapeConfig( .testMarketData({
this.assetProfileForm.controls['scraperConfiguration'].value dataSource: this.data.dataSource,
scraperConfiguration:
this.assetProfileForm.controls['scraperConfiguration'].value,
symbol: this.data.symbol
})
.pipe(
catchError(({ error }) => {
alert(`Error: ${error?.message}`);
return EMPTY;
}),
takeUntil(this.unsubscribeSubject)
) )
.pipe(takeUntil(this.unsubscribeSubject)) .subscribe(({ price }) => {
.subscribe((response) => { alert(
if (response?.price) { $localize`The current market price is` +
alert($localize`Current Market Price is:` + ' ' + response.price); ' ' +
} else { price +
alert($localize`Please try again.`); ' ' +
} (<Currency>(
(<unknown>this.assetProfileForm.controls['currency'].value)
))?.value
);
}); });
} }

2
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html

@ -256,7 +256,7 @@
mat-flat-button mat-flat-button
type="button" type="button"
[disabled]="assetProfileForm.controls['scraperConfiguration'].value === '{}'" [disabled]="assetProfileForm.controls['scraperConfiguration'].value === '{}'"
(click)="onTestScraper()" (click)="onTestMarketData()"
> >
<ng-container i18n>Test</ng-container> <ng-container i18n>Test</ng-container>
</button> </button>

13
apps/client/src/app/services/admin.service.ts

@ -260,7 +260,16 @@ export class AdminService {
return this.http.put<Tag>(`/api/v1/tag/${aTag.id}`, aTag); return this.http.put<Tag>(`/api/v1/tag/${aTag.id}`, aTag);
} }
public testScrapeConfig(config: string) { public testMarketData({
return this.http.post<any>(`/api/v1/admin/test-scraper`, { config }); dataSource,
scraperConfiguration,
symbol
}: UniqueAsset & UpdateAssetProfileDto['scraperConfiguration']) {
return this.http.post<any>(
`/api/v1/admin/market-data/${dataSource}/${symbol}/test`,
{
scraperConfiguration
}
);
} }
} }

Loading…
Cancel
Save