Feature/introduce admin setting to disable data gathering (#2981)
* Introduce setting to disable data gathering * Update changelog
This commit is contained in:
parent
f83e75df44
commit
ccaf06360a
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Introduced a setting to disable the data gathering in the admin control
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Harmonized the environment variables of various API keys
|
- Harmonized the environment variables of various API keys
|
||||||
|
@ -6,6 +6,7 @@ import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering/dat
|
|||||||
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
|
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
|
||||||
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
|
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
|
||||||
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
|
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
|
||||||
|
import { PropertyModule } from '@ghostfolio/api/services/property/property.module';
|
||||||
import { TwitterBotModule } from '@ghostfolio/api/services/twitter-bot/twitter-bot.module';
|
import { TwitterBotModule } from '@ghostfolio/api/services/twitter-bot/twitter-bot.module';
|
||||||
import {
|
import {
|
||||||
DEFAULT_LANGUAGE_CODE,
|
DEFAULT_LANGUAGE_CODE,
|
||||||
@ -73,6 +74,7 @@ import { UserModule } from './user/user.module';
|
|||||||
PlatformModule,
|
PlatformModule,
|
||||||
PortfolioModule,
|
PortfolioModule,
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
|
PropertyModule,
|
||||||
RedisCacheModule,
|
RedisCacheModule,
|
||||||
ScheduleModule.forRoot(),
|
ScheduleModule.forRoot(),
|
||||||
ServeStaticModule.forRoot({
|
ServeStaticModule.forRoot({
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
GATHER_ASSET_PROFILE_PROCESS,
|
GATHER_ASSET_PROFILE_PROCESS,
|
||||||
GATHER_ASSET_PROFILE_PROCESS_OPTIONS
|
GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
||||||
|
PROPERTY_IS_DATA_GATHERING_ENABLED
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
@ -8,6 +9,7 @@ import { Cron, CronExpression } from '@nestjs/schedule';
|
|||||||
|
|
||||||
import { DataGatheringService } from './data-gathering/data-gathering.service';
|
import { DataGatheringService } from './data-gathering/data-gathering.service';
|
||||||
import { ExchangeRateDataService } from './exchange-rate-data/exchange-rate-data.service';
|
import { ExchangeRateDataService } from './exchange-rate-data/exchange-rate-data.service';
|
||||||
|
import { PropertyService } from './property/property.service';
|
||||||
import { TwitterBotService } from './twitter-bot/twitter-bot.service';
|
import { TwitterBotService } from './twitter-bot/twitter-bot.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -17,12 +19,15 @@ export class CronService {
|
|||||||
public constructor(
|
public constructor(
|
||||||
private readonly dataGatheringService: DataGatheringService,
|
private readonly dataGatheringService: DataGatheringService,
|
||||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||||
|
private readonly propertyService: PropertyService,
|
||||||
private readonly twitterBotService: TwitterBotService
|
private readonly twitterBotService: TwitterBotService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Cron(CronExpression.EVERY_HOUR)
|
@Cron(CronExpression.EVERY_HOUR)
|
||||||
public async runEveryHour() {
|
public async runEveryHour() {
|
||||||
await this.dataGatheringService.gather7Days();
|
if (await this.isDataGatheringEnabled()) {
|
||||||
|
await this.dataGatheringService.gather7Days();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cron(CronExpression.EVERY_12_HOURS)
|
@Cron(CronExpression.EVERY_12_HOURS)
|
||||||
@ -37,22 +42,32 @@ export class CronService {
|
|||||||
|
|
||||||
@Cron(CronService.EVERY_SUNDAY_AT_LUNCH_TIME)
|
@Cron(CronService.EVERY_SUNDAY_AT_LUNCH_TIME)
|
||||||
public async runEverySundayAtTwelvePm() {
|
public async runEverySundayAtTwelvePm() {
|
||||||
const uniqueAssets = await this.dataGatheringService.getUniqueAssets();
|
if (await this.isDataGatheringEnabled()) {
|
||||||
|
const uniqueAssets = await this.dataGatheringService.getUniqueAssets();
|
||||||
|
|
||||||
await this.dataGatheringService.addJobsToQueue(
|
await this.dataGatheringService.addJobsToQueue(
|
||||||
uniqueAssets.map(({ dataSource, symbol }) => {
|
uniqueAssets.map(({ dataSource, symbol }) => {
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
dataSource,
|
dataSource,
|
||||||
symbol
|
symbol
|
||||||
},
|
},
|
||||||
name: GATHER_ASSET_PROFILE_PROCESS,
|
name: GATHER_ASSET_PROFILE_PROCESS,
|
||||||
opts: {
|
opts: {
|
||||||
...GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
...GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
||||||
jobId: getAssetProfileIdentifier({ dataSource, symbol })
|
jobId: getAssetProfileIdentifier({ dataSource, symbol })
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async isDataGatheringEnabled() {
|
||||||
|
return (await this.propertyService.getByKey(
|
||||||
|
PROPERTY_IS_DATA_GATHERING_ENABLED
|
||||||
|
)) === false
|
||||||
|
? false
|
||||||
|
: true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
|
|||||||
import {
|
import {
|
||||||
PROPERTY_COUPONS,
|
PROPERTY_COUPONS,
|
||||||
PROPERTY_CURRENCIES,
|
PROPERTY_CURRENCIES,
|
||||||
|
PROPERTY_IS_DATA_GATHERING_ENABLED,
|
||||||
PROPERTY_IS_READ_ONLY_MODE,
|
PROPERTY_IS_READ_ONLY_MODE,
|
||||||
PROPERTY_IS_USER_SIGNUP_ENABLED,
|
PROPERTY_IS_USER_SIGNUP_ENABLED,
|
||||||
PROPERTY_SYSTEM_MESSAGE,
|
PROPERTY_SYSTEM_MESSAGE,
|
||||||
@ -43,6 +44,7 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
|
|||||||
public hasPermissionForSystemMessage: boolean;
|
public hasPermissionForSystemMessage: boolean;
|
||||||
public hasPermissionToToggleReadOnlyMode: boolean;
|
public hasPermissionToToggleReadOnlyMode: boolean;
|
||||||
public info: InfoItem;
|
public info: InfoItem;
|
||||||
|
public isDataGatheringEnabled: boolean;
|
||||||
public permissions = permissions;
|
public permissions = permissions;
|
||||||
public systemMessage: SystemMessage;
|
public systemMessage: SystemMessage;
|
||||||
public transactionCount: number;
|
public transactionCount: number;
|
||||||
@ -168,6 +170,13 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onEnableDataGatheringChange(aEvent: MatSlideToggleChange) {
|
||||||
|
this.putAdminSetting({
|
||||||
|
key: PROPERTY_IS_DATA_GATHERING_ENABLED,
|
||||||
|
value: aEvent.checked ? undefined : false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public onFlushCache() {
|
public onFlushCache() {
|
||||||
const confirmation = confirm(
|
const confirmation = confirm(
|
||||||
$localize`Do you really want to flush the cache?`
|
$localize`Do you really want to flush the cache?`
|
||||||
@ -233,6 +242,10 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
|
|||||||
this.coupons = (settings[PROPERTY_COUPONS] as Coupon[]) ?? [];
|
this.coupons = (settings[PROPERTY_COUPONS] as Coupon[]) ?? [];
|
||||||
this.customCurrencies = settings[PROPERTY_CURRENCIES] as string[];
|
this.customCurrencies = settings[PROPERTY_CURRENCIES] as string[];
|
||||||
this.exchangeRates = exchangeRates;
|
this.exchangeRates = exchangeRates;
|
||||||
|
this.isDataGatheringEnabled =
|
||||||
|
settings[PROPERTY_IS_DATA_GATHERING_ENABLED] === false
|
||||||
|
? false
|
||||||
|
: true;
|
||||||
this.systemMessage = settings[
|
this.systemMessage = settings[
|
||||||
PROPERTY_SYSTEM_MESSAGE
|
PROPERTY_SYSTEM_MESSAGE
|
||||||
] as SystemMessage;
|
] as SystemMessage;
|
||||||
|
@ -128,6 +128,17 @@
|
|||||||
></mat-slide-toggle>
|
></mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="d-flex my-3">
|
||||||
|
<div class="w-50" i18n>Data Gathering</div>
|
||||||
|
<div class="w-50">
|
||||||
|
<mat-slide-toggle
|
||||||
|
color="primary"
|
||||||
|
hideIcon="true"
|
||||||
|
[checked]="isDataGatheringEnabled"
|
||||||
|
(change)="onEnableDataGatheringChange($event)"
|
||||||
|
></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div *ngIf="hasPermissionForSystemMessage" class="d-flex my-3">
|
<div *ngIf="hasPermissionForSystemMessage" class="d-flex my-3">
|
||||||
<div class="w-50" i18n>System Message</div>
|
<div class="w-50" i18n>System Message</div>
|
||||||
<div class="w-50">
|
<div class="w-50">
|
||||||
|
@ -97,6 +97,7 @@ export const PROPERTY_COUPONS = 'COUPONS';
|
|||||||
export const PROPERTY_CURRENCIES = 'CURRENCIES';
|
export const PROPERTY_CURRENCIES = 'CURRENCIES';
|
||||||
export const PROPERTY_DATA_SOURCE_MAPPING = 'DATA_SOURCE_MAPPING';
|
export const PROPERTY_DATA_SOURCE_MAPPING = 'DATA_SOURCE_MAPPING';
|
||||||
export const PROPERTY_DEMO_USER_ID = 'DEMO_USER_ID';
|
export const PROPERTY_DEMO_USER_ID = 'DEMO_USER_ID';
|
||||||
|
export const PROPERTY_IS_DATA_GATHERING_ENABLED = 'IS_DATA_GATHERING_ENABLED';
|
||||||
export const PROPERTY_IS_READ_ONLY_MODE = 'IS_READ_ONLY_MODE';
|
export const PROPERTY_IS_READ_ONLY_MODE = 'IS_READ_ONLY_MODE';
|
||||||
export const PROPERTY_IS_USER_SIGNUP_ENABLED = 'IS_USER_SIGNUP_ENABLED';
|
export const PROPERTY_IS_USER_SIGNUP_ENABLED = 'IS_USER_SIGNUP_ENABLED';
|
||||||
export const PROPERTY_SLACK_COMMUNITY_USERS = 'SLACK_COMMUNITY_USERS';
|
export const PROPERTY_SLACK_COMMUNITY_USERS = 'SLACK_COMMUNITY_USERS';
|
||||||
|
@ -12,6 +12,7 @@ export interface InfoItem {
|
|||||||
demoAuthToken: string;
|
demoAuthToken: string;
|
||||||
fearAndGreedDataSource?: string;
|
fearAndGreedDataSource?: string;
|
||||||
globalPermissions: string[];
|
globalPermissions: string[];
|
||||||
|
isDataGatheringEnabled?: string;
|
||||||
isReadOnlyMode?: boolean;
|
isReadOnlyMode?: boolean;
|
||||||
platforms: Platform[];
|
platforms: Platform[];
|
||||||
statistics: Statistics;
|
statistics: Statistics;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user