OneConversorTemplate/OnlyOneAccessTemplate/Services/SiteConfigurationService .cs
2025-06-01 21:39:47 -03:00

328 lines
12 KiB
C#

using MongoDB.Driver;
using Microsoft.Extensions.Caching.Memory;
using System.Text;
using OnlyOneAccessTemplate.Models;
namespace OnlyOneAccessTemplate.Services
{
public class SiteConfigurationService : ISiteConfigurationService
{
private readonly IMongoDatabase _database;
private readonly IMongoCollection<SiteConfiguration> _configurations;
private readonly IMemoryCache _cache;
private readonly IConfiguration _config;
private readonly ILogger<SiteConfigurationService> _logger;
private readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(30);
public SiteConfigurationService(
IMongoDatabase database,
IMemoryCache cache,
IConfiguration config,
ILogger<SiteConfigurationService> logger)
{
_database = database;
_cache = cache;
_config = config;
_logger = logger;
_configurations = _database.GetCollection<SiteConfiguration>("site_configurations");
}
public async Task<SiteConfiguration> GetConfigurationAsync(string language)
{
var cacheKey = $"site_config_{language}";
if (_cache.TryGetValue(cacheKey, out SiteConfiguration? cachedConfig) && cachedConfig != null)
{
return cachedConfig;
}
try
{
var filter = Builders<SiteConfiguration>.Filter.Eq(x => x.Language, language);
var configuration = await _configurations.Find(filter).FirstOrDefaultAsync();
if (configuration == null)
{
configuration = await CreateDefaultConfigurationAsync(language);
}
_cache.Set(cacheKey, configuration, _cacheExpiration);
return configuration;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao buscar configuração para idioma {Language}", language);
return await CreateDefaultConfigurationAsync(language);
}
}
public SiteConfiguration GetConfiguration(string language)
{
var cacheKey = $"site_config_{language}";
if (_cache.TryGetValue(cacheKey, out SiteConfiguration? cachedConfig) && cachedConfig != null)
{
return cachedConfig;
}
try
{
var filter = Builders<SiteConfiguration>.Filter.Eq(x => x.Language, language);
var configuration = _configurations.Find(filter).FirstOrDefault();
if (configuration == null)
{
configuration = CreateDefaultConfiguration(language);
}
_cache.Set(cacheKey, configuration, _cacheExpiration);
return configuration;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao buscar configuração para idioma {Language}", language);
return CreateDefaultConfiguration(language);
}
}
public async Task<string> GenerateSitemapAsync()
{
var sb = new StringBuilder();
sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
sb.AppendLine("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">");
var baseUrl = _config.GetValue<string>("SEO:DefaultDomain") ?? "https://localhost";
var languages = await GetAvailableLanguagesAsync();
// Páginas principais para cada idioma
var mainPages = new[] { "", "about", "contact", "privacy", "terms" };
foreach (var page in mainPages)
{
foreach (var lang in languages)
{
var url = BuildUrl(baseUrl, lang, page);
var lastMod = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
var priority = page == "" ? "1.0" : "0.8";
sb.AppendLine(" <url>");
sb.AppendLine($" <loc>{url}</loc>");
sb.AppendLine($" <lastmod>{lastMod}</lastmod>");
sb.AppendLine($" <changefreq>weekly</changefreq>");
sb.AppendLine($" <priority>{priority}</priority>");
// Adicionar links alternativos (hreflang)
foreach (var altLang in languages)
{
var altUrl = BuildUrl(baseUrl, altLang, page);
sb.AppendLine($" <xhtml:link rel=\"alternate\" hreflang=\"{altLang}\" href=\"{altUrl}\" />");
}
sb.AppendLine(" </url>");
}
}
sb.AppendLine("</urlset>");
return sb.ToString();
}
public async Task<string> GenerateRobotsAsync()
{
var sb = new StringBuilder();
var baseUrl = _config.GetValue<string>("SEO:DefaultDomain") ?? "https://localhost";
sb.AppendLine("User-agent: *");
sb.AppendLine("Allow: /");
sb.AppendLine("");
sb.AppendLine("# Sitemaps");
sb.AppendLine($"Sitemap: {baseUrl}/sitemap.xml");
sb.AppendLine("");
sb.AppendLine("# Crawl delay");
sb.AppendLine("Crawl-delay: 1");
return sb.ToString();
}
public async Task UpdateConfigurationAsync(SiteConfiguration config)
{
try
{
config.UpdatedAt = DateTime.UtcNow;
var filter = Builders<SiteConfiguration>.Filter.Eq(x => x.Language, config.Language);
var options = new ReplaceOptions { IsUpsert = true };
await _configurations.ReplaceOneAsync(filter, config, options);
// Invalidar cache
var cacheKey = $"site_config_{config.Language}";
_cache.Remove(cacheKey);
_logger.LogInformation("Configuração atualizada para idioma {Language}", config.Language);
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao atualizar configuração para idioma {Language}", config.Language);
throw;
}
}
public async Task<List<string>> GetAvailableLanguagesAsync()
{
const string cacheKey = "available_languages";
if (_cache.TryGetValue(cacheKey, out List<string>? cachedLanguages) && cachedLanguages != null)
{
return cachedLanguages;
}
try
{
var projection = Builders<SiteConfiguration>.Projection.Include(x => x.Language);
var languages = await _configurations
.Find(Builders<SiteConfiguration>.Filter.Empty)
.Project<SiteConfiguration>(projection)
.ToListAsync();
var availableLanguages = languages.Select(x => x.Language).Distinct().ToList();
if (!availableLanguages.Any())
{
availableLanguages = new List<string> { "pt", "en", "es" };
}
_cache.Set(cacheKey, availableLanguages, TimeSpan.FromHours(1));
return availableLanguages;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao buscar idiomas disponíveis");
return new List<string> { "pt", "en", "es" };
}
}
private async Task<SiteConfiguration> CreateDefaultConfigurationAsync(string language)
{
var defaultConfig = CreateDefaultConfiguration(language);
try
{
await _configurations.InsertOneAsync(defaultConfig);
_logger.LogInformation("Configuração padrão criada para idioma {Language}", language);
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao criar configuração padrão para idioma {Language}", language);
}
return defaultConfig;
}
private SiteConfiguration CreateDefaultConfiguration(string language)
{
return language switch
{
"en" => new SiteConfiguration
{
Language = "en",
Currency = "USD",
CountryCode = "US",
SiteTitle = "Convert-it Online - Free Converters",
SiteDescription = "Convert your files online for free. PDF to Word, images, text and much more.",
SiteKeywords = "convert, converter, pdf, word, text, online, free",
HomePage = new HomePageContent
{
MainTitle = "Free Online Converters",
MainDescription = "Convert your files quickly and securely",
CallToAction = "Choose your converter"
}
},
"es" => new SiteConfiguration
{
Language = "es",
Currency = "EUR",
CountryCode = "ES",
SiteTitle = "Convert-it Online - Convertidores Gratuitos",
SiteDescription = "Convierte tus archivos en línea gratis. PDF a Word, imágenes, texto y mucho más.",
SiteKeywords = "convertir, convertidor, pdf, word, texto, en línea, gratis",
HomePage = new HomePageContent
{
MainTitle = "Convertidores en Línea Gratuitos",
MainDescription = "Convierte tus archivos rápidamente y con seguridad",
CallToAction = "Elige tu convertidor"
}
},
_ => new SiteConfiguration
{
Language = "pt",
Currency = "BRL",
CountryCode = "BR",
SiteTitle = "Convert-it Online - Conversores Gratuitos",
SiteDescription = "Converta seus arquivos online gratuitamente. PDF para Word, imagens, textos e muito mais.",
SiteKeywords = "converter, conversor, pdf, word, texto, online, grátis",
HomePage = new HomePageContent
{
MainTitle = "Conversores Online Gratuitos",
MainDescription = "Converta seus arquivos rapidamente e com segurança",
CallToAction = "Escolha seu conversor"
}
}
};
}
public async Task<bool> ConfigurationExistsAsync(string language)
{
try
{
var filter = Builders<SiteConfiguration>.Filter.Eq(x => x.Language, language);
var count = await _configurations.CountDocumentsAsync(filter);
return count > 0;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao verificar se configuração existe para idioma {Language}", language);
return false;
}
}
public async Task DeleteConfigurationAsync(string language)
{
try
{
var filter = Builders<SiteConfiguration>.Filter.Eq(x => x.Language, language);
await _configurations.DeleteOneAsync(filter);
// Invalidar cache
var cacheKey = $"site_config_{language}";
_cache.Remove(cacheKey);
_logger.LogInformation("Configuração deletada para idioma {Language}", language);
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao deletar configuração para idioma {Language}", language);
throw;
}
}
private string BuildUrl(string baseUrl, string language, string page)
{
var url = baseUrl.TrimEnd('/');
if (language != "pt") // português é o padrão
{
url += $"/{language}";
}
if (!string.IsNullOrEmpty(page))
{
url += $"/{page}";
}
return url;
}
}
}