From 4e1c62ac901d9d4f1a5a103baa8df1319ef8306a Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 7 Mar 2024 11:37:16 +0000 Subject: [PATCH] Fix opengraph --- .../Controllers/OpenGraphController.cs | 61 +++++++++++-------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/NostrServices/Controllers/OpenGraphController.cs b/NostrServices/Controllers/OpenGraphController.cs index eb83d32..01352b4 100644 --- a/NostrServices/Controllers/OpenGraphController.cs +++ b/NostrServices/Controllers/OpenGraphController.cs @@ -14,17 +14,8 @@ namespace NostrServices.Controllers; /// Add OpenGraph tags to html documents /// [Route("/api/v1/opengraph")] -public class OpenGraphController : Controller +public class OpenGraphController(ILogger logger, RedisStore redisStore) : Controller { - private readonly ILogger _logger; - private readonly RedisStore _redisStore; - - public OpenGraphController(ILogger logger, RedisStore redisStore) - { - _logger = logger; - _redisStore = redisStore; - } - /// /// Inject opengraph tags into provided html /// @@ -63,7 +54,7 @@ public class OpenGraphController : Controller { if (nid.Hrp is "nevent" or "note" or "naddr") { - var ev = await _redisStore.GetEvent(nid); + var ev = await redisStore.GetEvent(nid); if (ev != default) { var tags = MetaTagsToElements(await GetEventTags(ev)); @@ -75,7 +66,7 @@ public class OpenGraphController : Controller } else if (nid.Hrp is "nprofile" or "npub") { - var profile = await _redisStore.GetProfile(nid.Special); + var profile = await redisStore.GetProfile(nid.Special); var meta = await GetProfileMeta(profile); var tags = MetaTagsToElements([ @@ -98,7 +89,7 @@ public class OpenGraphController : Controller } catch (Exception ex) when (ex is not TaskCanceledException) { - _logger.LogWarning("Failed to inject event tags: {Message}", ex.ToString()); + logger.LogWarning("Failed to inject event tags: {Message}", ex.ToString()); } } @@ -109,17 +100,20 @@ public class OpenGraphController : Controller { var ret = new List>(); - var profile = await _redisStore.GetProfile(ev.PubKey.ToHex()); + var profile = await redisStore.GetProfile(ev.PubKey.ToHex()); var name = profile?.Name ?? "Nostrich"; switch (ev.Kind) { case (long)NostrKind.LiveEvent: { - var host = ev.Tags.FirstOrDefault(a => a.Key == "p" && a.Values[1] == "host")?.Values[0] ?? ev.PubKey.ToHex(); - var hostProfile = await _redisStore.GetProfile(host); + var host = ev.Tags.FirstOrDefault(a => a.Key == "p" && a.Values[^1] == "host") + ?.Values[0] ?? + ev.PubKey.ToHex(); + var hostProfile = await redisStore.GetProfile(host); var hostName = hostProfile?.Name ?? profile?.Name ?? "Nostrich"; var stream = ev.GetFirstTagValue("streaming") ?? ev.GetFirstTagValue("recording") ?? ""; - var image = ev.GetFirstTagValue("image") ?? hostProfile?.Picture ?? $"https://robohash.v0l.io/{ev.PubKey.ToHex()}.png"; + var image = ev.GetFirstTagValue("image") ?? + hostProfile?.Picture ?? $"https://robohash.v0l.io/{ev.PubKey.ToHex()}.png"; ret.AddRange(new KeyValuePair[] { new("og:type", "video.other"), @@ -145,7 +139,8 @@ public class OpenGraphController : Controller case 1_313: // stream clip { var stream = ev.GetFirstTagValue("r")!; - var image = ev.GetFirstTagValue("image") ?? profile?.Picture ?? $"https://robohash.v0l.io/{ev.PubKey.ToHex()}.png"; + var image = ev.GetFirstTagValue("image") ?? + profile?.Picture ?? $"https://robohash.v0l.io/{ev.PubKey.ToHex()}.png"; ret.AddRange(new KeyValuePair[] { new("og:type", "video.other"), @@ -212,15 +207,24 @@ public class OpenGraphController : Controller foreach (var ex in tags) { - var tag = doc.CreateElement(ex.Element); + IElement tag = doc.Head?.Children.FirstOrDefault(a => + { + if (ex.Element == "meta") + { + var metaPropertyA = a.Attributes.FirstOrDefault(b => b.Name == "property"); + var metaPropertyB = ex.Attributes.FirstOrDefault(b => b is { Key: "property" }); + return metaPropertyA?.Value == metaPropertyB.Value; + } + + return false; + }) ?? AddNewTag(ex); + foreach (var attr in ex.Attributes) { tag.SetAttribute(attr.Key, attr.Value); } - doc.Head?.AppendChild(tag); - - var isOgTitle = ex.Attributes.Any(a => a is {Key: "property", Value: "og:title"}); + var isOgTitle = ex.Attributes.Any(a => a is { Key: "property", Value: "og:title" }); if (isOgTitle && doc.Head != default) { var titleTag = doc.Head.QuerySelector("title"); @@ -238,7 +242,7 @@ public class OpenGraphController : Controller } } - var isOgDesc = ex.Attributes.Any(a => a is {Key: "property", Value: "og:description"}); + var isOgDesc = ex.Attributes.Any(a => a is { Key: "property", Value: "og:description" }); if (isOgDesc && doc.Head != default) { var ogDesc = ex.Attributes.FirstOrDefault(a => a.Key is "content"); @@ -256,6 +260,15 @@ public class OpenGraphController : Controller descriptionTag.SetAttribute("content", ogDesc.Value); } } + + continue; + + IElement AddNewTag(HeadElement he) + { + var tx = doc!.CreateElement(he.Element); + doc.Head?.AppendChild(tx); + return tx; + } } return doc; @@ -295,4 +308,4 @@ class CachedMeta [ProtoMember(5)] public CompactEvent? Event { get; init; } -} +} \ No newline at end of file