Created
September 19, 2023 22:39
-
-
Save xakpc/c4ab9c023ad031ed9a992c8ca8199212 to your computer and use it in GitHub Desktop.
Azure Function To Fix Hashnode Sitemap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Threading.Tasks; | |
using System.Web.Http; | |
using System.Xml.Serialization; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Azure.WebJobs; | |
using Microsoft.Azure.WebJobs.Extensions.Http; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.Extensions.Logging; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.Xml.Linq; | |
namespace ApiChat.Functions.OneTimeFunctions; | |
public static class HashnodeSitemapFunction | |
{ | |
[FunctionName("HashnodeSitemapFunction")] | |
public static async Task<IActionResult> Run( | |
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "sitemap-fix")] HttpRequest req, | |
ILogger log) | |
{ | |
log.LogInformation("C# HashnodeSitemapFunction processed a request."); | |
string url = req.Query["url"]; | |
if (string.IsNullOrEmpty(url)) | |
{ | |
return new BadRequestErrorMessageResult("url parameter is required"); | |
} | |
var client = new System.Net.Http.HttpClient(); | |
var response = await client.GetAsync(url); | |
response.EnsureSuccessStatusCode(); | |
// read response xml to string | |
var responseString = await response.Content.ReadAsStringAsync(); | |
// deserialize and rebuild | |
var sitemapNodes = new List<SitemapNode>(); | |
try | |
{ | |
var serializer = new XmlSerializer(typeof(UrlSet)); | |
var sitemap = (UrlSet)serializer.Deserialize(new StringReader(responseString)); | |
foreach (var urlSetUrl in sitemap.Urls) | |
{ | |
if (!Enum.TryParse<SitemapFrequency>(urlSetUrl.ChangeFreq, true, out var frequency)) | |
{ | |
frequency = SitemapFrequency.Never; | |
} | |
sitemapNodes.Add(new SitemapNode() | |
{ | |
Url = urlSetUrl.Loc, | |
Frequency = frequency, | |
LastModified = urlSetUrl.LastMod, | |
Priority = (double?)urlSetUrl.Priority | |
}); | |
} | |
} | |
catch (Exception e) | |
{ | |
log.LogError(e, "Failed to parse sitemap"); | |
return new BadRequestErrorMessageResult($"Failed to parse sitemap with error: {e.Message}"); | |
} | |
return new ContentResult | |
{ | |
Content = GetSitemapDocument(sitemapNodes), | |
ContentType = "application/xml", | |
StatusCode = 200 | |
}; | |
} | |
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")] | |
public class UrlSet | |
{ | |
[XmlElement("url")] | |
public List<Url> Urls { get; set; } | |
} | |
public class Url | |
{ | |
[XmlElement("loc")] | |
public string Loc { get; set; } | |
[XmlElement("changefreq")] | |
public string? ChangeFreq { get; set; } | |
[XmlElement("priority")] | |
public decimal? Priority { get; set; } | |
[XmlElement("lastmod")] | |
public DateTime? LastMod { get; set; } | |
} | |
internal class SitemapNode | |
{ | |
public SitemapFrequency? Frequency { get; set; } | |
public DateTime? LastModified { get; set; } | |
public double? Priority { get; set; } | |
public string Url { get; set; } | |
} | |
internal enum SitemapFrequency | |
{ | |
Never, | |
Yearly, | |
Monthly, | |
Weekly, | |
Daily, | |
Hourly, | |
Always | |
} | |
/// <summary> | |
/// Serializes to raw XML. | |
/// </summary> | |
private static string GetSitemapDocument(IEnumerable<SitemapNode> sitemapNodes) | |
{ | |
XNamespace xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9"; | |
var root = new XElement(xmlns + "urlset"); | |
foreach (var sitemapNode in sitemapNodes) | |
{ | |
var urlElement = new XElement( | |
xmlns + "url", | |
new XElement(xmlns + "loc", Uri.EscapeUriString(sitemapNode.Url)), | |
sitemapNode.Frequency == null | |
? null | |
: new XElement( | |
xmlns + "changefreq", | |
sitemapNode.Frequency.Value.ToString().ToLowerInvariant()), | |
sitemapNode.Priority == null | |
? null | |
: new XElement( | |
xmlns + "priority", | |
sitemapNode.Priority.Value.ToString("F1", CultureInfo.InvariantCulture)), | |
sitemapNode.LastModified == null | |
? null | |
: new XElement( | |
xmlns + "lastmod", | |
sitemapNode.LastModified.Value.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:sszzz"))); | |
root.Add(urlElement); | |
} | |
var document = new XDocument(root); | |
return document.ToString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment