BCards/src/BCards.Web/Controllers/SitemapController.cs
Ricardo Carneiro b9714598b5
All checks were successful
BCards Multi-Tenant Deployment Pipeline / Run Tests (push) Successful in 10s
BCards Multi-Tenant Deployment Pipeline / PR Validation (push) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Run Tests (pull_request) Successful in 5s
BCards Multi-Tenant Deployment Pipeline / PR Validation (pull_request) Successful in 1s
BCards Multi-Tenant Deployment Pipeline / Build and Push Image (push) Successful in 9m22s
BCards Multi-Tenant Deployment Pipeline / Build and Push Image (pull_request) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deploy bcards.site (pull_request) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deploy spicylinks.site (pull_request) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deploy luslinks.site (pull_request) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deploy to Release Swarm (ARM) (pull_request) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Cleanup Old Resources (pull_request) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deploy bcards.site (push) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deploy spicylinks.site (push) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deploy luslinks.site (push) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deployment Summary (pull_request) Successful in 0s
BCards Multi-Tenant Deployment Pipeline / Deploy to Release Swarm (ARM) (push) Successful in 2m11s
BCards Multi-Tenant Deployment Pipeline / Cleanup Old Resources (push) Has been skipped
BCards Multi-Tenant Deployment Pipeline / Deployment Summary (push) Successful in 1s
feat: multitenant
2026-03-29 18:36:07 -03:00

142 lines
5.9 KiB
C#

using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Xml.Linq;
using BCards.Web.Services;
using BCards.Web.Areas.Tutoriais.Services;
using BCards.Web.Repositories;
namespace BCards.Web.Controllers;
public class SitemapController : Controller
{
private readonly IUserPageService _userPageService;
private readonly ILivePageService _livePageService;
private readonly IMarkdownService _markdownService;
private readonly ICategoryRepository _categoryRepository;
private readonly ILogger<SitemapController> _logger;
public SitemapController(
IUserPageService userPageService,
ILivePageService livePageService,
IMarkdownService markdownService,
ICategoryRepository categoryRepository,
ILogger<SitemapController> logger)
{
_userPageService = userPageService;
_livePageService = livePageService;
_markdownService = markdownService;
_categoryRepository = categoryRepository;
_logger = logger;
}
[Route("sitemap.xml")]
[ResponseCache(Duration = 86400)] // Cache for 24 hours
public async Task<IActionResult> Index()
{
try
{
XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
var livePages = await _livePageService.GetAllActiveAsync();
// Artigos
var artigos = await _markdownService.GetAllArticlesAsync("Artigos", "pt-BR");
// Tutoriais por categoria
var categories = await _categoryRepository.GetAllActiveAsync();
var tutorialUrls = new List<XElement>();
foreach (var cat in categories)
{
var tutorials = await _markdownService.GetArticlesByCategoryAsync(cat.Slug, "pt-BR");
foreach (var t in tutorials)
{
tutorialUrls.Add(new XElement(ns + "url",
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/tutoriais/{cat.Slug}/{t.Slug}"),
new XElement(ns + "lastmod", t.LastMod.ToString("yyyy-MM-dd")),
new XElement(ns + "changefreq", "monthly"),
new XElement(ns + "priority", "0.7")
));
}
}
var dynamicUrls = livePages.Select(page =>
new XElement(ns + "url",
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/page/{page.Category?.Replace(" ", "-")?.ToLower()}/{page.Slug}"),
new XElement(ns + "lastmod", page.LastSyncAt.ToString("yyyy-MM-dd")),
new XElement(ns + "changefreq", "weekly"),
new XElement(ns + "priority", "0.8")
)
).ToList();
var artigoUrls = artigos.Select(a =>
new XElement(ns + "url",
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/artigos/{a.Slug}"),
new XElement(ns + "lastmod", a.LastMod.ToString("yyyy-MM-dd")),
new XElement(ns + "changefreq", "monthly"),
new XElement(ns + "priority", "0.7")
)
).ToList();
var sitemap = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(ns + "urlset",
new XElement(ns + "url",
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/"),
new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
new XElement(ns + "changefreq", "daily"),
new XElement(ns + "priority", "1.0")
),
new XElement(ns + "url",
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/Home/Pricing"),
new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
new XElement(ns + "changefreq", "weekly"),
new XElement(ns + "priority", "0.9")
),
new XElement(ns + "url",
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/artigos"),
new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
new XElement(ns + "changefreq", "weekly"),
new XElement(ns + "priority", "0.8")
),
new XElement(ns + "url",
new XElement(ns + "loc", $"{Request.Scheme}://{Request.Host}/tutoriais"),
new XElement(ns + "lastmod", DateTime.UtcNow.ToString("yyyy-MM-dd")),
new XElement(ns + "changefreq", "weekly"),
new XElement(ns + "priority", "0.8")
),
artigoUrls,
tutorialUrls,
dynamicUrls
)
);
_logger.LogInformation("Generated sitemap with {LivePages} live pages, {Artigos} artigos, {Tutoriais} tutoriais",
livePages.Count, artigos.Count, tutorialUrls.Count);
return Content(sitemap.ToString(SaveOptions.DisableFormatting), "application/xml", Encoding.UTF8);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error generating sitemap");
return StatusCode(500, "Error generating sitemap");
}
}
[Route("robots.txt")]
[ResponseCache(Duration = 86400)] // Cache for 24 hours
public IActionResult RobotsTxt()
{
var robotsTxt = $@"User-agent: *
Allow: /
Allow: /page/
Disallow: /Admin/
Disallow: /Auth/
Disallow: /Payment/
Disallow: /api/
Sitemap: {Request.Scheme}://{Request.Host}/sitemap.xml";
return Content(robotsTxt, "text/plain", Encoding.UTF8);
}
}