Feature/introduce data gathering progress (#467)
* Add data gathering progress * Update changelog
This commit is contained in:
parent
9df8541145
commit
a42700b9fe
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added a logo to the log on the server start
|
- Added a logo to the log on the server start
|
||||||
|
- Added the data gathering progress to the log and the admin control panel
|
||||||
|
|
||||||
## 1.74.0 - 11.11.2021
|
## 1.74.0 - 11.11.2021
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ export class AdminService {
|
|||||||
|
|
||||||
public async get(): Promise<AdminData> {
|
public async get(): Promise<AdminData> {
|
||||||
return {
|
return {
|
||||||
|
dataGatheringProgress:
|
||||||
|
await this.dataGatheringService.getDataGatheringProgress(),
|
||||||
exchangeRates: this.exchangeRateDataService
|
exchangeRates: this.exchangeRateDataService
|
||||||
.getCurrencies()
|
.getCurrencies()
|
||||||
.filter((currency) => {
|
.filter((currency) => {
|
||||||
@ -58,7 +60,7 @@ export class AdminService {
|
|||||||
return 'IN_PROGRESS';
|
return 'IN_PROGRESS';
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getUsersWithAnalytics(): Promise<AdminData['users']> {
|
private async getUsersWithAnalytics(): Promise<AdminData['users']> {
|
||||||
|
@ -18,7 +18,6 @@ import {
|
|||||||
|
|
||||||
import { ConfigurationService } from './configuration.service';
|
import { ConfigurationService } from './configuration.service';
|
||||||
import { DataProviderService } from './data-provider/data-provider.service';
|
import { DataProviderService } from './data-provider/data-provider.service';
|
||||||
import { GhostfolioScraperApiService } from './data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service';
|
|
||||||
import { DataEnhancerInterface } from './data-provider/interfaces/data-enhancer.interface';
|
import { DataEnhancerInterface } from './data-provider/interfaces/data-enhancer.interface';
|
||||||
import { ExchangeRateDataService } from './exchange-rate-data.service';
|
import { ExchangeRateDataService } from './exchange-rate-data.service';
|
||||||
import { IDataGatheringItem } from './interfaces/interfaces';
|
import { IDataGatheringItem } from './interfaces/interfaces';
|
||||||
@ -26,13 +25,14 @@ import { PrismaService } from './prisma.service';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DataGatheringService {
|
export class DataGatheringService {
|
||||||
|
private dataGatheringProgress: number;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly configurationService: ConfigurationService,
|
private readonly configurationService: ConfigurationService,
|
||||||
@Inject('DataEnhancers')
|
@Inject('DataEnhancers')
|
||||||
private readonly dataEnhancers: DataEnhancerInterface[],
|
private readonly dataEnhancers: DataEnhancerInterface[],
|
||||||
private readonly dataProviderService: DataProviderService,
|
private readonly dataProviderService: DataProviderService,
|
||||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||||
private readonly ghostfolioScraperApi: GhostfolioScraperApiService,
|
|
||||||
private readonly prismaService: PrismaService,
|
private readonly prismaService: PrismaService,
|
||||||
private readonly symbolProfileService: SymbolProfileService
|
private readonly symbolProfileService: SymbolProfileService
|
||||||
) {}
|
) {}
|
||||||
@ -204,8 +204,11 @@ export class DataGatheringService {
|
|||||||
|
|
||||||
public async gatherSymbols(aSymbolsWithStartDate: IDataGatheringItem[]) {
|
public async gatherSymbols(aSymbolsWithStartDate: IDataGatheringItem[]) {
|
||||||
let hasError = false;
|
let hasError = false;
|
||||||
|
let symbolCounter = 0;
|
||||||
|
|
||||||
for (const { dataSource, date, symbol } of aSymbolsWithStartDate) {
|
for (const { dataSource, date, symbol } of aSymbolsWithStartDate) {
|
||||||
|
this.dataGatheringProgress = symbolCounter / aSymbolsWithStartDate.length;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const historicalData = await this.dataProviderService.getHistoricalRaw(
|
const historicalData = await this.dataProviderService.getHistoricalRaw(
|
||||||
[{ dataSource, symbol }],
|
[{ dataSource, symbol }],
|
||||||
@ -263,6 +266,16 @@ export class DataGatheringService {
|
|||||||
hasError = true;
|
hasError = true;
|
||||||
Logger.error(error);
|
Logger.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbolCounter > 0 && symbolCounter % 100 === 0) {
|
||||||
|
Logger.log(
|
||||||
|
`Data gathering progress: ${(
|
||||||
|
this.dataGatheringProgress * 100
|
||||||
|
).toFixed(2)}%`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbolCounter += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.exchangeRateDataService.initialize();
|
await this.exchangeRateDataService.initialize();
|
||||||
@ -272,6 +285,16 @@ export class DataGatheringService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getDataGatheringProgress() {
|
||||||
|
const isInProgress = await this.getIsInProgress();
|
||||||
|
|
||||||
|
if (isInProgress) {
|
||||||
|
return this.dataGatheringProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public async getIsInProgress() {
|
public async getIsInProgress() {
|
||||||
return await this.prismaService.property.findUnique({
|
return await this.prismaService.property.findUnique({
|
||||||
where: { key: 'LOCKED_DATA_GATHERING' }
|
where: { key: 'LOCKED_DATA_GATHERING' }
|
||||||
|
@ -22,6 +22,7 @@ import { takeUntil } from 'rxjs/operators';
|
|||||||
})
|
})
|
||||||
export class AdminPageComponent implements OnDestroy, OnInit {
|
export class AdminPageComponent implements OnDestroy, OnInit {
|
||||||
public dataGatheringInProgress: boolean;
|
public dataGatheringInProgress: boolean;
|
||||||
|
public dataGatheringProgress: number;
|
||||||
public defaultDateFormat = DEFAULT_DATE_FORMAT;
|
public defaultDateFormat = DEFAULT_DATE_FORMAT;
|
||||||
public exchangeRates: { label1: string; label2: string; value: number }[];
|
public exchangeRates: { label1: string; label2: string; value: number }[];
|
||||||
public lastDataGathering: string;
|
public lastDataGathering: string;
|
||||||
@ -134,12 +135,14 @@ export class AdminPageComponent implements OnDestroy, OnInit {
|
|||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
.subscribe(
|
.subscribe(
|
||||||
({
|
({
|
||||||
|
dataGatheringProgress,
|
||||||
exchangeRates,
|
exchangeRates,
|
||||||
lastDataGathering,
|
lastDataGathering,
|
||||||
transactionCount,
|
transactionCount,
|
||||||
userCount,
|
userCount,
|
||||||
users
|
users
|
||||||
}) => {
|
}) => {
|
||||||
|
this.dataGatheringProgress = dataGatheringProgress;
|
||||||
this.exchangeRates = exchangeRates;
|
this.exchangeRates = exchangeRates;
|
||||||
this.users = users;
|
this.users = users;
|
||||||
|
|
||||||
|
@ -35,14 +35,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex my-3">
|
<div class="d-flex my-3">
|
||||||
<div class="w-50" i18n>Last Data Gathering</div>
|
<div class="w-50" i18n>Data Gathering</div>
|
||||||
<div class="w-50">
|
<div class="w-50">
|
||||||
<div>
|
<div>
|
||||||
<ng-container *ngIf="lastDataGathering"
|
<ng-container *ngIf="lastDataGathering"
|
||||||
>{{ lastDataGathering }}</ng-container
|
>{{ lastDataGathering }}</ng-container
|
||||||
>
|
>
|
||||||
<ng-container *ngIf="dataGatheringInProgress" i18n
|
<ng-container *ngIf="dataGatheringInProgress" i18n
|
||||||
>In Progress</ng-container
|
>In Progress ({{ dataGatheringProgress | percent : '1.2-2'
|
||||||
|
}})</ng-container
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 overflow-hidden">
|
<div class="mt-2 overflow-hidden">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export interface AdminData {
|
export interface AdminData {
|
||||||
|
dataGatheringProgress?: number;
|
||||||
exchangeRates: { label1: string; label2: string; value: number }[];
|
exchangeRates: { label1: string; label2: string; value: number }[];
|
||||||
lastDataGathering: Date | 'IN_PROGRESS';
|
lastDataGathering?: Date | 'IN_PROGRESS';
|
||||||
transactionCount: number;
|
transactionCount: number;
|
||||||
userCount: number;
|
userCount: number;
|
||||||
users: {
|
users: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user