testing new features
This commit is contained in:
+350
@@ -0,0 +1,350 @@
|
||||
import os
|
||||
|
||||
_TRANSLATIONS: dict[str, dict[str, str]] = {}
|
||||
|
||||
|
||||
def _r(key: str, text: str) -> str:
|
||||
_TRANSLATIONS.setdefault("ru", {})[key] = text
|
||||
return text
|
||||
|
||||
|
||||
def _e(key: str, text: str) -> str:
|
||||
_TRANSLATIONS.setdefault("en", {})[key] = text
|
||||
return text
|
||||
|
||||
|
||||
# ── app ────────────────────────────────────────────────────────
|
||||
|
||||
_r("app.help", "CashFlow Forecast — личная финансовая модель")
|
||||
|
||||
# ── cmd.init ───────────────────────────────────────────────────
|
||||
|
||||
_r("cmd.init.help", "Создать пустую финансовую модель")
|
||||
_r("cmd.init.ok", "Пустая модель создана в {path}")
|
||||
|
||||
# ── cmd.forecast ───────────────────────────────────────────────
|
||||
|
||||
_r("cmd.forecast.help", "Запустить прогноз денежных потоков")
|
||||
_r("cmd.forecast.opt.months", "Количество месяцев прогноза")
|
||||
_r("cmd.forecast.opt.currency", "Валюта отображения (по умолчанию — базовая валюта модели)")
|
||||
_r("cmd.forecast.title", "Прогноз на {months} мес. ({currency})")
|
||||
_r("cmd.forecast.col.account", "Счёт")
|
||||
_r("cmd.forecast.col.month", "Месяц")
|
||||
_r("cmd.forecast.col.balance", "Баланс")
|
||||
_r("cmd.forecast.col.income", "Доход")
|
||||
_r("cmd.forecast.col.expenses", "Расход")
|
||||
_r("cmd.forecast.total", "Итог: Баланс: {balance} | Доход: {income} | Расход: {expenses}")
|
||||
|
||||
# ── cmd.scenario ──────────────────────────────────────────────
|
||||
|
||||
_r("cmd.scenario.help", "Применить сценарий и показать прогноз")
|
||||
_r("cmd.scenario.arg.name", "Имя сценария: baseline, optimistic, pessimistic")
|
||||
_r("cmd.scenario.opt.months", "Количество месяцев")
|
||||
_r("cmd.scenario.err.unknown", "Неизвестный сценарий: {name}")
|
||||
_r("cmd.scenario.err.available", "Доступны: {scenarios}")
|
||||
_r("cmd.scenario.label", "Сценарий")
|
||||
_r("cmd.scenario.label.balance", "Баланс")
|
||||
_r("cmd.scenario.label.income", "Доход")
|
||||
_r("cmd.scenario.label.expenses", "Расход")
|
||||
|
||||
# ── cmd.whatif ────────────────────────────────────────────────
|
||||
|
||||
_r("cmd.whatif.help", "What-if анализ с произвольными множителями")
|
||||
_r("cmd.whatif.opt.income", "Множитель дохода")
|
||||
_r("cmd.whatif.opt.expense", "Множитель расхода")
|
||||
_r("cmd.whatif.opt.growth", "Множитель роста активов")
|
||||
_r("cmd.whatif.opt.months", "Количество месяцев")
|
||||
_r("cmd.whatif.title", "What-if анализ")
|
||||
_r("cmd.whatif.params", "Доход x{income} | Расход x{expense} | Рост x{growth}")
|
||||
|
||||
# ── cmd.compare ───────────────────────────────────────────────
|
||||
|
||||
_r("cmd.compare.help", "Сравнить все сценарии")
|
||||
_r("cmd.compare.opt.months", "Количество месяцев")
|
||||
_r("cmd.compare.title", "Сравнение сценариев ({currency})")
|
||||
_r("cmd.compare.col.scenario", "Сценарий")
|
||||
|
||||
# ── cmd.import ────────────────────────────────────────────────
|
||||
|
||||
_r("cmd.import.help", "Импорт данных из Excel")
|
||||
_r("cmd.import.arg.path", "Путь к .xlsx файлу")
|
||||
_r("cmd.import.ok",
|
||||
"Импортировано: {accounts} счетов, {transactions} транзакций, "
|
||||
"{recurring} регулярных платежей, {assets} активов, {liabilities} обязательств")
|
||||
_r("cmd.import.base_currency", "Базовая валюта: {currency}")
|
||||
_r("cmd.import.err", "Ошибка импорта: {error}")
|
||||
|
||||
# ── cmd.export ────────────────────────────────────────────────
|
||||
|
||||
_r("cmd.export.help", "Экспорт модели в Excel")
|
||||
_r("cmd.export.arg.path", "Путь для .xlsx файла")
|
||||
_r("cmd.export.ok", "Модель экспортирована в {path}")
|
||||
_r("cmd.export.err", "Ошибка экспорта: {error}")
|
||||
|
||||
# ── cmd.analyze ───────────────────────────────────────────────
|
||||
|
||||
_r("cmd.analyze.help", "AI-анализ финансовой модели")
|
||||
_r("cmd.analyze.opt.months", "Количество месяцев для анализа")
|
||||
_r("cmd.analyze.title.prompt", "Промпт для AI")
|
||||
_r("cmd.analyze.title.summary", "Сводка")
|
||||
_r("cmd.analyze.base_currency", "Базовая валюта: {currency}")
|
||||
_r("cmd.analyze.stub", "AI-ответ: заглушка. Подключите реальный API в ai/assistant.py")
|
||||
|
||||
# ── cmd.info ──────────────────────────────────────────────────
|
||||
|
||||
_r("cmd.info.help", "Сводка всей финансовой модели")
|
||||
_r("cmd.info.metadata", "Метаданные")
|
||||
_r("cmd.info.base_currency", "Базовая валюта: {currency} ({symbol})")
|
||||
_r("cmd.info.accounts", "Счетов: {count}")
|
||||
_r("cmd.info.transactions", "Транзакций: {count}")
|
||||
_r("cmd.info.recurring", "Регулярных платежей: {count}")
|
||||
_r("cmd.info.assets", "Активов: {count}")
|
||||
_r("cmd.info.liabilities", "Обязательств: {count}")
|
||||
_r("cmd.info.rates", "Курсов валют: {count}")
|
||||
_r("cmd.info.more", "... и ещё {count} транзакций")
|
||||
|
||||
# ── table headers ─────────────────────────────────────────────
|
||||
|
||||
_r("table.accounts.title", "Счета")
|
||||
_r("table.accounts_config.title", "Счета")
|
||||
_r("table.accounts.col.name", "Название")
|
||||
_r("table.accounts.col.currency", "Валюта")
|
||||
_r("table.accounts.col.balance", "Баланс")
|
||||
|
||||
_r("table.transactions.title", "Транзакции")
|
||||
_r("table.transactions.col.date", "Дата")
|
||||
_r("table.transactions.col.category", "Категория")
|
||||
_r("table.transactions.col.amount", "Сумма")
|
||||
_r("table.transactions.col.description", "Описание")
|
||||
|
||||
_r("table.recurring.title", "Регулярные платежи")
|
||||
_r("table.recurring.col.period", "Период")
|
||||
_r("table.recurring.col.amount", "Сумма")
|
||||
_r("table.recurring.col.category", "Категория")
|
||||
_r("table.recurring.col.id", "ID")
|
||||
_r("table.recurring.col.start", "Начало")
|
||||
_r("table.recurring.col.end", "Конец")
|
||||
|
||||
_r("table.assets.title", "Активы")
|
||||
_r("table.assets.col.id", "ID")
|
||||
_r("table.assets.col.name", "Название")
|
||||
_r("table.assets.col.value", "Стоимость")
|
||||
_r("table.assets.col.growth", "Рост (%)")
|
||||
|
||||
_r("table.liabilities.title", "Обязательства")
|
||||
_r("table.liabilities.col.id", "ID")
|
||||
_r("table.liabilities.col.name", "Название")
|
||||
_r("table.liabilities.col.balance", "Долг")
|
||||
_r("table.liabilities.col.rate", "Ставка")
|
||||
_r("table.liabilities.col.payment", "Платёж")
|
||||
|
||||
_r("table.rates.title", "Курсы валют")
|
||||
_r("table.rates.col.from", "Из")
|
||||
_r("table.rates.col.to", "В")
|
||||
_r("table.rates.col.rate", "Курс")
|
||||
|
||||
_r("table.accounts_config.col.id", "ID")
|
||||
_r("table.accounts_config.col.name", "Название")
|
||||
_r("table.accounts_config.col.currency", "Валюта")
|
||||
_r("table.accounts_config.col.balance", "Баланс")
|
||||
|
||||
# ── config ────────────────────────────────────────────────────
|
||||
|
||||
_r("config.help", "Управление моделью (счета, транзакции, валюты...)")
|
||||
|
||||
_r("cmd.config.base_currency.help", "Показать или установить базовую валюту модели")
|
||||
_r("cmd.config.base_currency.arg", "Код валюты (RUB, USD, EUR...)")
|
||||
_r("cmd.config.base_currency.ok", "Базовая валюта установлена: {currency}")
|
||||
_r("cmd.config.base_currency.show", "Базовая валюта: {currency}")
|
||||
|
||||
_r("cmd.config.rate_set.help", "Добавить или обновить курс валюты")
|
||||
_r("cmd.config.rate_set.arg.from", "Из валюты")
|
||||
_r("cmd.config.rate_set.arg.to", "В валюту")
|
||||
_r("cmd.config.rate_set.arg.rate", "Курс")
|
||||
_r("cmd.config.rate_set.ok", "Курс {fc} → {tc} = {rate}")
|
||||
|
||||
_r("cmd.config.rate_list.help", "Список курсов валют")
|
||||
_r("cmd.config.rate_list.empty", "Курсы не заданы")
|
||||
|
||||
_r("cmd.config.rate_remove.help", "Удалить курс валюты")
|
||||
_r("cmd.config.rate_remove.ok", "Курс {fc} → {tc} удалён")
|
||||
_r("cmd.config.rate_remove.err", "Курс {fc} → {tc} не найден")
|
||||
|
||||
_r("cmd.config.account_add.help", "Добавить счёт")
|
||||
_r("cmd.config.account_add.opt.name", "Название счёта")
|
||||
_r("cmd.config.account_add.opt.balance", "Начальный баланс")
|
||||
_r("cmd.config.account_add.opt.currency", "Валюта счёта")
|
||||
_r("cmd.config.account_add.ok", "Счёт '{name}' добавлен (баланс: {balance}, валюта: {currency})")
|
||||
|
||||
_r("cmd.config.account_list.help", "Список счетов")
|
||||
_r("cmd.config.account_list.empty", "Счета не добавлены")
|
||||
|
||||
_r("cmd.config.account_remove.help", "Удалить счёт по ID или названию")
|
||||
_r("cmd.config.account_remove.arg", "ID или название счёта")
|
||||
_r("cmd.config.account_remove.ok", "Счёт '{id}' удалён")
|
||||
_r("cmd.config.account_remove.err", "Счёт '{id}' не найден")
|
||||
|
||||
_r("cmd.config.transaction_add.help", "Добавить транзакцию")
|
||||
_r("cmd.config.transaction_add.opt.account", "ID или название счёта")
|
||||
_r("cmd.config.transaction_add.opt.amount", "Сумма (доход/расход)")
|
||||
_r("cmd.config.transaction_add.opt.category", "Категория")
|
||||
_r("cmd.config.transaction_add.opt.description", "Описание")
|
||||
_r("cmd.config.transaction_add.opt.date", "Дата (YYYY-MM-DD)")
|
||||
_r("cmd.config.transaction_add.ok", "Транзакция '{kind}' на {amount:.2f} (счёт: {account})")
|
||||
_r("cmd.config.transaction_add.kind.income", "доход")
|
||||
_r("cmd.config.transaction_add.kind.expense", "расход")
|
||||
_r("cmd.config.transaction_add.err", "Счёт '{account}' не найден")
|
||||
|
||||
_r("cmd.config.transaction_list.help", "Список транзакций")
|
||||
_r("cmd.config.transaction_list.empty", "Транзакции не добавлены")
|
||||
|
||||
_r("cmd.config.transaction_remove.help", "Удалить транзакцию по ID")
|
||||
_r("cmd.config.transaction_remove.arg", "ID транзакции")
|
||||
_r("cmd.config.transaction_remove.ok", "Транзакция '{id}' удалена")
|
||||
_r("cmd.config.transaction_remove.err", "Транзакция '{id}' не найдена")
|
||||
|
||||
_r("cmd.config.recurring_add.help", "Добавить регулярный платёж")
|
||||
_r("cmd.config.recurring_add.opt.amount", "Сумма")
|
||||
_r("cmd.config.recurring_add.opt.category", "Категория")
|
||||
_r("cmd.config.recurring_add.opt.frequency", "Периодичность")
|
||||
_r("cmd.config.recurring_add.opt.start", "Дата начала (YYYY-MM-DD)")
|
||||
_r("cmd.config.recurring_add.opt.end", "Дата окончания (YYYY-MM-DD)")
|
||||
_r("cmd.config.recurring_add.ok", "Регулярный платёж на {amount:.2f} ({frequency})")
|
||||
|
||||
_r("cmd.config.recurring_list.help", "Список регулярных платежей")
|
||||
_r("cmd.config.recurring_list.empty", "Регулярные платежи не добавлены")
|
||||
|
||||
_r("cmd.config.recurring_remove.help", "Удалить регулярный платёж по ID")
|
||||
_r("cmd.config.recurring_remove.arg", "ID регулярного платежа")
|
||||
_r("cmd.config.recurring_remove.ok", "Регулярный платёж '{id}' удалён")
|
||||
_r("cmd.config.recurring_remove.err", "Регулярный платёж '{id}' не найден")
|
||||
|
||||
_r("cmd.config.asset_add.help", "Добавить актив")
|
||||
_r("cmd.config.asset_add.opt.name", "Название актива")
|
||||
_r("cmd.config.asset_add.opt.value", "Стоимость")
|
||||
_r("cmd.config.asset_add.opt.growth", "Годовой рост (%)")
|
||||
_r("cmd.config.asset_add.ok", "Актив '{name}' добавлен (стоимость: {value})")
|
||||
|
||||
_r("cmd.config.asset_list.help", "Список активов")
|
||||
_r("cmd.config.asset_list.empty", "Активы не добавлены")
|
||||
|
||||
_r("cmd.config.asset_remove.help", "Удалить актив по ID или названию")
|
||||
_r("cmd.config.asset_remove.arg", "ID или название актива")
|
||||
_r("cmd.config.asset_remove.ok", "Актив '{id}' удалён")
|
||||
_r("cmd.config.asset_remove.err", "Актив '{id}' не найден")
|
||||
|
||||
_r("cmd.config.liability_add.help", "Добавить обязательство")
|
||||
_r("cmd.config.liability_add.opt.name", "Название")
|
||||
_r("cmd.config.liability_add.opt.balance", "Остаток долга")
|
||||
_r("cmd.config.liability_add.opt.interest", "Процентная ставка (%)")
|
||||
_r("cmd.config.liability_add.opt.payment", "Ежемесячный платёж")
|
||||
_r("cmd.config.liability_add.ok", "Обязательство '{name}' добавлено (долг: {balance})")
|
||||
|
||||
_r("cmd.config.liability_list.help", "Список обязательств")
|
||||
_r("cmd.config.liability_list.empty", "Обязательства не добавлены")
|
||||
|
||||
_r("cmd.config.liability_remove.help", "Удалить обязательство по ID или названию")
|
||||
_r("cmd.config.liability_remove.arg", "ID или название обязательства")
|
||||
_r("cmd.config.liability_remove.ok", "Обязательство '{id}' удалено")
|
||||
_r("cmd.config.liability_remove.err", "Обязательство '{id}' не найдено")
|
||||
|
||||
# ── global ─────────────────────────────────────────────────────
|
||||
|
||||
_r("global.ok", "OK")
|
||||
|
||||
# ── prompts ───────────────────────────────────────────────────
|
||||
|
||||
_r("prompt.analyze", (
|
||||
"Ты — финансовый AI-ассистент. Проанализируй финансовую модель пользователя.\n"
|
||||
"\n"
|
||||
"### Модель (JSON):\n"
|
||||
"{model_json}\n"
|
||||
"\n"
|
||||
"### Прогноз на {months} месяцев:\n"
|
||||
"{forecast_json}\n"
|
||||
"\n"
|
||||
"### Валюта:\n"
|
||||
"Базовая валюта модели: {base_currency}\n"
|
||||
"Отображаемая валюта: {display_currency}\n"
|
||||
"\n"
|
||||
"Дай анализ по пунктам:\n"
|
||||
"1. Общее финансовое состояние\n"
|
||||
"2. Тренд денежного потока (рост/падение)\n"
|
||||
"3. Достаточность ликвидности\n"
|
||||
"4. Рекомендации по улучшению"
|
||||
))
|
||||
|
||||
_r("prompt.advice", (
|
||||
"Ты — финансовый AI-ассистент. Дай персональные рекомендации.\n"
|
||||
"\n"
|
||||
"### Модель:\n"
|
||||
"{model_json}\n"
|
||||
"\n"
|
||||
"### Прогноз:\n"
|
||||
"{forecast_json}\n"
|
||||
"\n"
|
||||
"### Валюта:\n"
|
||||
"Базовая валюта модели: {base_currency}\n"
|
||||
"Отображаемая валюта: {display_currency}\n"
|
||||
"\n"
|
||||
"Вопрос пользователя: {question}\n"
|
||||
"\n"
|
||||
"Ответь как опытный финансовый консультант."
|
||||
))
|
||||
|
||||
_r("prompt.scenario_comparison", (
|
||||
"Ты — финансовый AI-ассистент. Сравни сценарии прогноза.\n"
|
||||
"\n"
|
||||
"### Результаты сценариев:\n"
|
||||
"{scenarios_json}\n"
|
||||
"\n"
|
||||
"### Валюта:\n"
|
||||
"Базовая валюта модели: {base_currency}\n"
|
||||
"Отображаемая валюта: {display_currency}\n"
|
||||
"\n"
|
||||
"Дай рекомендацию: какой сценарий наиболее вероятен и почему."
|
||||
))
|
||||
|
||||
|
||||
_current_lang = "ru"
|
||||
|
||||
|
||||
class Translator:
|
||||
def __init__(self, lang: str | None = None):
|
||||
self.lang = lang or _current_lang
|
||||
if self.lang not in _TRANSLATIONS:
|
||||
_TRANSLATIONS[self.lang] = {}
|
||||
|
||||
def t(self, key: str, **kwargs) -> str:
|
||||
src = _TRANSLATIONS.get(self.lang) or _TRANSLATIONS.get("ru") or {}
|
||||
if key in src:
|
||||
template = src[key]
|
||||
elif "ru" in _TRANSLATIONS and key in _TRANSLATIONS["ru"]:
|
||||
template = _TRANSLATIONS["ru"][key]
|
||||
else:
|
||||
return key
|
||||
return template.format(**kwargs) if kwargs else template
|
||||
|
||||
|
||||
_GLOBAL = Translator()
|
||||
|
||||
|
||||
def setup_i18n() -> None:
|
||||
lang = os.environ.get("CF_LANG", "ru")
|
||||
if lang not in _TRANSLATIONS:
|
||||
_TRANSLATIONS[lang] = {}
|
||||
_GLOBAL.lang = lang
|
||||
|
||||
|
||||
def set_lang(lang: str) -> None:
|
||||
if lang not in _TRANSLATIONS:
|
||||
_TRANSLATIONS[lang] = {}
|
||||
_GLOBAL.lang = lang
|
||||
|
||||
|
||||
def get_lang() -> str:
|
||||
return _GLOBAL.lang
|
||||
|
||||
|
||||
def t(key: str, **kwargs) -> str:
|
||||
return _GLOBAL.t(key, **kwargs)
|
||||
Reference in New Issue
Block a user