2021-12-19 10:57:50 +01:00
|
|
|
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
|
2021-09-11 09:27:22 +02:00
|
|
|
import type { RequestWithUser } from '@ghostfolio/common/types';
|
2021-04-13 21:53:58 +02:00
|
|
|
import {
|
|
|
|
Controller,
|
2021-12-04 11:49:00 +01:00
|
|
|
DefaultValuePipe,
|
2021-04-13 21:53:58 +02:00
|
|
|
Get,
|
|
|
|
HttpException,
|
|
|
|
Inject,
|
|
|
|
Param,
|
2021-12-04 11:49:00 +01:00
|
|
|
ParseBoolPipe,
|
2021-04-13 21:53:58 +02:00
|
|
|
Query,
|
|
|
|
UseGuards
|
|
|
|
} from '@nestjs/common';
|
|
|
|
import { REQUEST } from '@nestjs/core';
|
|
|
|
import { AuthGuard } from '@nestjs/passport';
|
2021-12-19 10:57:50 +01:00
|
|
|
import { DataSource, MarketData } from '@prisma/client';
|
2021-04-13 21:53:58 +02:00
|
|
|
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
2021-12-19 10:57:50 +01:00
|
|
|
import { isDate, isEmpty } from 'lodash';
|
2021-04-13 21:53:58 +02:00
|
|
|
|
|
|
|
import { LookupItem } from './interfaces/lookup-item.interface';
|
|
|
|
import { SymbolItem } from './interfaces/symbol-item.interface';
|
|
|
|
import { SymbolService } from './symbol.service';
|
|
|
|
|
|
|
|
@Controller('symbol')
|
|
|
|
export class SymbolController {
|
|
|
|
public constructor(
|
|
|
|
private readonly symbolService: SymbolService,
|
|
|
|
@Inject(REQUEST) private readonly request: RequestWithUser
|
|
|
|
) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Must be before /:symbol
|
|
|
|
*/
|
|
|
|
@Get('lookup')
|
|
|
|
@UseGuards(AuthGuard('jwt'))
|
2021-05-20 20:36:08 +02:00
|
|
|
public async lookupSymbol(
|
|
|
|
@Query() { query = '' }
|
|
|
|
): Promise<{ items: LookupItem[] }> {
|
2021-04-13 21:53:58 +02:00
|
|
|
try {
|
2021-05-20 20:36:08 +02:00
|
|
|
const encodedQuery = encodeURIComponent(query.toLowerCase());
|
|
|
|
return this.symbolService.lookup(encodedQuery);
|
2021-04-13 21:53:58 +02:00
|
|
|
} catch {
|
|
|
|
throw new HttpException(
|
|
|
|
getReasonPhrase(StatusCodes.INTERNAL_SERVER_ERROR),
|
|
|
|
StatusCodes.INTERNAL_SERVER_ERROR
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Must be after /lookup
|
|
|
|
*/
|
2021-09-18 19:32:22 +02:00
|
|
|
@Get(':dataSource/:symbol')
|
2021-04-13 21:53:58 +02:00
|
|
|
@UseGuards(AuthGuard('jwt'))
|
2021-09-18 19:32:22 +02:00
|
|
|
public async getSymbolData(
|
|
|
|
@Param('dataSource') dataSource: DataSource,
|
2021-12-04 11:49:00 +01:00
|
|
|
@Param('symbol') symbol: string,
|
|
|
|
@Query('includeHistoricalData', new DefaultValuePipe(false), ParseBoolPipe)
|
|
|
|
includeHistoricalData: boolean
|
2021-09-18 19:32:22 +02:00
|
|
|
): Promise<SymbolItem> {
|
|
|
|
if (!DataSource[dataSource]) {
|
|
|
|
throw new HttpException(
|
|
|
|
getReasonPhrase(StatusCodes.NOT_FOUND),
|
|
|
|
StatusCodes.NOT_FOUND
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-12-04 11:49:00 +01:00
|
|
|
const result = await this.symbolService.get({
|
|
|
|
includeHistoricalData,
|
|
|
|
dataGatheringItem: { dataSource, symbol }
|
|
|
|
});
|
2021-08-30 18:08:21 +02:00
|
|
|
|
|
|
|
if (!result || isEmpty(result)) {
|
|
|
|
throw new HttpException(
|
|
|
|
getReasonPhrase(StatusCodes.NOT_FOUND),
|
|
|
|
StatusCodes.NOT_FOUND
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|
2021-12-19 10:57:50 +01:00
|
|
|
|
|
|
|
@Get(':dataSource/:symbol/:dateString')
|
|
|
|
@UseGuards(AuthGuard('jwt'))
|
|
|
|
public async gatherSymbolForDate(
|
|
|
|
@Param('dataSource') dataSource: DataSource,
|
|
|
|
@Param('dateString') dateString: string,
|
|
|
|
@Param('symbol') symbol: string
|
|
|
|
): Promise<IDataProviderHistoricalResponse> {
|
|
|
|
const date = new Date(dateString);
|
|
|
|
|
|
|
|
if (!isDate(date)) {
|
|
|
|
throw new HttpException(
|
|
|
|
getReasonPhrase(StatusCodes.BAD_REQUEST),
|
|
|
|
StatusCodes.BAD_REQUEST
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.symbolService.getForDate({
|
|
|
|
dataSource,
|
|
|
|
date,
|
|
|
|
symbol
|
|
|
|
});
|
|
|
|
}
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|