Browse Source

Refactoring

pull/2503/head
Thomas 2 years ago
parent
commit
9e5b729d28
  1. 2
      apps/api/src/app/account/account.module.ts
  2. 19
      apps/api/src/middlewares/html-template.middleware.ts
  3. 9
      apps/api/src/services/i18n/i18n.module.ts
  4. 35
      apps/api/src/services/i18n/i18n.service.ts

2
apps/api/src/app/account/account.module.ts

@ -11,7 +11,6 @@ import { Module } from '@nestjs/common';
import { AccountController } from './account.controller'; import { AccountController } from './account.controller';
import { AccountService } from './account.service'; import { AccountService } from './account.service';
import { I18nModule } from '@ghostfolio/api/services/i18n/i18n.module';
@Module({ @Module({
controllers: [AccountController], controllers: [AccountController],
@ -22,7 +21,6 @@ import { I18nModule } from '@ghostfolio/api/services/i18n/i18n.module';
DataProviderModule, DataProviderModule,
ExchangeRateDataModule, ExchangeRateDataModule,
ImpersonationModule, ImpersonationModule,
I18nModule,
PortfolioModule, PortfolioModule,
PrismaModule, PrismaModule,
RedisCacheModule, RedisCacheModule,

19
apps/api/src/middlewares/html-template.middleware.ts

@ -2,6 +2,7 @@ import * as fs from 'fs';
import { join } from 'path'; import { join } from 'path';
import { environment } from '@ghostfolio/api/environments/environment'; import { environment } from '@ghostfolio/api/environments/environment';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { import {
DEFAULT_LANGUAGE_CODE, DEFAULT_LANGUAGE_CODE,
DEFAULT_ROOT_URL, DEFAULT_ROOT_URL,
@ -11,20 +12,11 @@ import { DATE_FORMAT, interpolate } from '@ghostfolio/common/helper';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { NextFunction, Request, Response } from 'express'; import { NextFunction, Request, Response } from 'express';
const descriptions = {
de: 'Mit dem Finanz-Dashboard Ghostfolio können Sie Ihr Vermögen in Form von Aktien, ETFs oder Kryptowährungen verteilt über mehrere Finanzinstitute überwachen.',
en: 'Ghostfolio is a personal finance dashboard to keep track of your assets like stocks, ETFs or cryptocurrencies across multiple platforms.',
es: 'Ghostfolio es un dashboard de finanzas personales para hacer un seguimiento de tus activos como acciones, ETFs o criptodivisas a través de múltiples plataformas.',
fr: 'Ghostfolio est un dashboard de finances personnelles qui permet de suivre vos actifs comme les actions, les ETF ou les crypto-monnaies sur plusieurs plateformes.',
it: 'Ghostfolio è un dashboard di finanza personale per tenere traccia delle vostre attività come azioni, ETF o criptovalute su più piattaforme.',
nl: 'Ghostfolio is een persoonlijk financieel dashboard om uw activa zoals aandelen, ETF’s of cryptocurrencies over meerdere platforms bij te houden.',
pt: 'Ghostfolio é um dashboard de finanças pessoais para acompanhar os seus activos como acções, ETFs ou criptomoedas em múltiplas plataformas.',
tr: 'Ghostfolio, hisse senetleri, ETF’ler veya kripto para birimleri gibi varlıklarınızı birden fazla platformda takip etmenizi sağlayan bir kişisel finans panosudur.'
};
const title = 'Ghostfolio – Open Source Wealth Management Software'; const title = 'Ghostfolio – Open Source Wealth Management Software';
const titleShort = 'Ghostfolio'; const titleShort = 'Ghostfolio';
const i18nService = new I18nService();
let indexHtmlMap: { [languageCode: string]: string } = {}; let indexHtmlMap: { [languageCode: string]: string } = {};
try { try {
@ -130,7 +122,10 @@ export const HtmlTemplateMiddleware = async (
languageCode, languageCode,
path, path,
rootUrl, rootUrl,
description: descriptions[languageCode], description: i18nService.getTranslation({
id: 'metaDescription',
locale: languageCode
}),
featureGraphicPath: featureGraphicPath:
locales[path]?.featureGraphicPath ?? 'assets/cover.png', locales[path]?.featureGraphicPath ?? 'assets/cover.png',
title: locales[path]?.title ?? title title: locales[path]?.title ?? title

9
apps/api/src/services/i18n/i18n.module.ts

@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { I18nService } from './i18n.service';
@Module({
providers: [I18nService],
exports: [I18nService]
})
export class I18nModule {}

35
apps/api/src/services/i18n/i18n.service.ts

@ -1,12 +1,12 @@
import { readdirSync, readFileSync, existsSync } from 'fs'; import { readFileSync, readdirSync } from 'fs';
import { join } from 'path'; import { join } from 'path';
import { Injectable, Logger } from '@nestjs/common';
import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config';
import { Logger } from '@nestjs/common';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
@Injectable()
export class I18nService { export class I18nService {
private localesPath = join(__dirname, 'assets', 'locales'); private localesPath = join(__dirname, 'assets', 'locales');
private localeRegex = /^messages\.[a-z]{2}\.xlf$/;
private translations: { [locale: string]: cheerio.CheerioAPI } = {}; private translations: { [locale: string]: cheerio.CheerioAPI } = {};
public constructor() { public constructor() {
@ -21,15 +21,15 @@ export class I18nService {
locale: string; locale: string;
}): string { }): string {
const $ = this.translations[locale]; const $ = this.translations[locale];
if (!$) { if (!$) {
throw new Error(`Translation not found for locale '${locale}'`); Logger.warn(`Translation not found for locale '${locale}'`);
} }
const translatedText = $(`trans-unit[id="${id}"] > target`).text(); const translatedText = $(`trans-unit[id="${id}"] > target`).text();
if (!translatedText) { if (!translatedText) {
throw new Error( Logger.warn(`Translation not found for id '${id}' in locale '${locale}'`);
`Translation not found for id '${id}' in locale '${locale}'`
);
} }
return translatedText; return translatedText;
@ -38,22 +38,23 @@ export class I18nService {
private loadFiles() { private loadFiles() {
try { try {
const files = readdirSync(this.localesPath, 'utf-8'); const files = readdirSync(this.localesPath, 'utf-8');
for (const file of files) { for (const file of files) {
if (!this.localeRegex.test(file)) { const xmlData = readFileSync(join(this.localesPath, file), 'utf8');
continue; this.translations[this.parseLanguageCode(file)] =
} this.parseXml(xmlData);
if (!existsSync(join(this.localesPath, file))) {
throw new Error(`File: ${file} not found`);
} else {
const xmlData = readFileSync(join(this.localesPath, file), 'utf8');
this.translations[file.split('.')[1]] = this.parseXml(xmlData);
}
} }
} catch (error) { } catch (error) {
Logger.error(error, 'I18nService'); Logger.error(error, 'I18nService');
} }
} }
private parseLanguageCode(aFileName: string) {
const match = aFileName.match(/\.([a-zA-Z]+)\.xlf$/);
return match ? match[1] : DEFAULT_LANGUAGE_CODE;
}
private parseXml(xmlData: string): cheerio.CheerioAPI { private parseXml(xmlData: string): cheerio.CheerioAPI {
return cheerio.load(xmlData, { xmlMode: true }); return cheerio.load(xmlData, { xmlMode: true });
} }

Loading…
Cancel
Save