daily_digest/Services/DigestBuilderService.cs

113 lines
6.1 KiB
C#
Raw Normal View History

using DailyDigestWorker.Models;
using System.Globalization;
using System.Text;
namespace DailyDigestWorker.Services
{
public class DigestBuilderService : IDigestBuilderService
{
private readonly ILogger<DigestBuilderService> _logger;
public DigestBuilderService(ILogger<DigestBuilderService> logger)
{
_logger = logger;
}
public string BuildDigestText(CurrencyData? currency, CryptoData? crypto, WeatherData? weather, string? newsSummary)
{
_logger.LogInformation("Начало формирования улучшенного текста дайджеста...");
var sb = new StringBuilder();
var culture = CultureInfo.GetCultureInfo("ru-RU");
var nl = Environment.NewLine; // Используем системный перенос строки для читаемости кода
// --- Заголовок ---
sb.Append("🗓️ *").Append(DateTime.Now.ToString("dd MMMM yyyy", culture)).Append("*").AppendLine(" | Ежедневный Дайджест (Новокузнецк)");
sb.AppendLine("--------------------------------------"); // Разделитель
// --- Блок Погоды (перенесем наверх) ---
if (weather != null)
{
sb.Append(weather.Emoji).Append(" *Погода:* ");
sb.Append(weather.TemperatureC.ToString("F0", culture)).Append("°C ");
sb.Append($"_(ощущ. {weather.FeelsLikeC.ToString("F0", culture)}°C)_ ");
sb.Append("| ").Append(CultureInfo.CurrentCulture.TextInfo.ToTitleCase(weather.Description));
sb.AppendLine(); // Перенос строки после погоды
}
else
{
sb.AppendLine("☁️ *Погода:* _(Не удалось получить данные)_");
}
sb.AppendLine(); // Доп. отступ
// --- Блок Валют ---
sb.AppendLine("💰 *Курсы Валют*");
if (currency != null)
{
sb.AppendLine($"_(на {currency.Date:dd.MM})_");
foreach (var rate in currency.Rates.OrderBy(r => r.Key)) // Сортируем для порядка (EUR, USD)
{
string symbol = rate.Key == "USD" ? "🇺🇸" : (rate.Key == "EUR" ? "🇪🇺" : "▪️");
sb.AppendLine($" {symbol} {rate.Key}: `{rate.Value.ToString("N2", culture)} ₽`"); // Используем моноширинный шрифт для чисел
}
}
else
{
sb.AppendLine(" _(Не удалось получить данные)_");
}
sb.AppendLine();
// --- Блок Криптовалют ---
sb.AppendLine("₿ *Криптовалюты*");
if (crypto != null && crypto.CryptoRates.Any())
{
foreach (var cryptoPair in crypto.CryptoRates.OrderBy(p => p.Key)) // Сортируем (Bitcoin, Ethereum)
{
string cryptoName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(cryptoPair.Key);
var ratesText = new List<string>();
// Сортируем валюты (RUB, USD)
foreach (var ratePair in cryptoPair.Value.OrderBy(r => r.Key == "USD" ? 0 : 1))
{
string format = ratePair.Key.ToLower() == "usd" ? "N0" : "N2";
string symbol = ratePair.Key.ToLower() == "usd" ? "$" : "₽";
ratesText.Add($"{symbol}{ratePair.Value.ToString(format, culture)}"); // Убрали (USD/RUB) для краткости
}
sb.AppendLine($" 📈 {cryptoName}: `{string.Join(" / ", ratesText)}`"); // Используем моноширинный
}
}
else
{
sb.AppendLine(" _(Не удалось получить данные)_");
}
sb.AppendLine();
// --- Блок Новостей ---
if (!string.IsNullOrWhiteSpace(newsSummary))
{
_logger.LogDebug("Добавление блока новостей в дайджест.");
sb.AppendLine("📰 *Сводка новостей за сутки*");
// Добавляем саммари, предполагая, что Gemini вернул Markdown-список
// Убираем лишние пустые строки из ответа Gemini, если они есть
var summaryLines = newsSummary.Trim().Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in summaryLines)
{
// Добавляем небольшой отступ к каждой строке новости для лучшего вида
sb.Append(" ").AppendLine(line.Trim());
}
// sb.AppendLine("---"); // Убрал разделитель после новостей, блок последний
}
else
{
_logger.LogDebug("Саммари новостей пустое или не получено, блок новостей не добавляется.");
// sb.AppendLine("📰 *Сводка новостей за сутки*");
// sb.AppendLine(" _(Нет новостей или не удалось обработать)_");
}
// sb.AppendLine(); // Убрал лишний отступ в конце
string result = sb.ToString().TrimEnd();
_logger.LogInformation("Текст дайджеста успешно сформирован (улучшенный).");
_logger.LogDebug("Итоговый текст дайджеста:\n{DigestText}", result);
return result;
}
}
}