ServiceModels.OgDetails GetOgDetails(HtmlDocument document) { var returnObject = new ServiceModels.OgDetails(); var titleNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:title']"); if (titleNode != null && titleNode.Attributes["content"] != null) { returnObject.Title = titleNode.Attributes["content"].Value.Trim(); } var descriptionNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:description']"); if (descriptionNode != null && descriptionNode.Attributes["content"] != null) { returnObject.Description = descriptionNode.Attributes["content"].Value.Trim(); } var siteNameNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:site_name']"); if (siteNameNode != null && siteNameNode.Attributes["content"] != null) { returnObject.SiteName = siteNameNode.Attributes["content"].Value.Trim(); } var imageNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:image']"); if (imageNode != null && imageNode.Attributes["content"] != null) { returnObject.Image = imageNode.Attributes["content"].Value.Trim(); } if (string.IsNullOrEmpty(returnObject.Title)) { return null; } return returnObject; }
ServiceModels.OgDetails GetOgDetails(HtmlDocument document) { var returnObject = new ServiceModels.OgDetails(); var titleNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:title']"); if (titleNode != null && titleNode.Attributes["content"] != null) { returnObject.Title = titleNode.Attributes["content"].Value.Trim(); } var descriptionNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:description']"); if (descriptionNode != null && descriptionNode.Attributes["content"] != null) { returnObject.Description = descriptionNode.Attributes["content"].Value.Trim(); } var siteNameNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:site_name']"); if (siteNameNode != null && siteNameNode.Attributes["content"] != null) { returnObject.SiteName = siteNameNode.Attributes["content"].Value.Trim(); } var imageNode = document.DocumentNode.SelectSingleNode(@"//meta[@property='og:image']"); if (imageNode != null && imageNode.Attributes["content"] != null) { returnObject.Image = imageNode.Attributes["content"].Value.Trim(); // Twitch og:image starts without a protocol. if (returnObject.Image.StartsWith("//")) { returnObject.Image = $"https:{returnObject.Image}"; } } if (string.IsNullOrEmpty(returnObject.Title)) { return(null); } return(returnObject); }
/// <summary> /// I really should make this async. Load a remote page by URL and attempt to get details about it. /// </summary> public async Task <ServiceModels.RemotePageDetails> GetRemotePageDetails(string remoteUrl) { var returnResult = new ServiceModels.RemotePageDetails { Title = remoteUrl, }; Uri uri; try { uri = new Uri(remoteUrl); } catch (UriFormatException ex) { var logUrl = remoteUrl.Substring(0, 255); Log.LogWarning(ex, $"{nameof(GetRemotePageDetails)} couldn't create a URI from -- {logUrl}"); return(returnResult); } var remoteUrlAuthority = uri.GetLeftPart(UriPartial.Authority); var domain = uri.Host.Replace("/www.", "/").ToLower(); var faviconPath = $"{remoteUrlAuthority}/favicon.ico"; var faviconStoragePath = await CacheFavicon(domain, uri.GetLeftPart(UriPartial.Path), faviconPath); var document = WebClient.DownloadDocument(remoteUrl); if (document is null) { return(returnResult); } var titleTag = document.DocumentNode.SelectSingleNode(@"//title"); if (titleTag != null && !string.IsNullOrEmpty(titleTag.InnerText.Trim())) { returnResult.Title = titleTag.InnerText.Trim(); } if (string.IsNullOrEmpty(faviconStoragePath)) { var element = document.DocumentNode.SelectSingleNode(@"//link[@rel='shortcut icon']"); if (element != null) { faviconPath = element.Attributes["href"].Value.Trim(); faviconStoragePath = await CacheFavicon(domain, uri.GetLeftPart(UriPartial.Path), faviconPath); } } if (string.IsNullOrEmpty(faviconStoragePath)) { var element = document.DocumentNode.SelectSingleNode(@"//link[@rel='icon']"); if (element != null) { faviconPath = element.Attributes["href"].Value.Trim(); faviconStoragePath = await CacheFavicon(domain, uri.GetLeftPart(UriPartial.Path), faviconPath); } } returnResult.Favicon = faviconStoragePath; ServiceModels.OgDetails ogDetails = null; if (domain == "warpstorm.com" || domain == "localhost") { ogDetails = GetWarpstormOgDetails(remoteUrl); } else { ogDetails = GetOgDetails(document); } if (ogDetails != null) { returnResult.Title = ogDetails.Title; if (!string.IsNullOrEmpty(ogDetails.Description)) { returnResult.Card += "<blockquote class='card hover-highlight' clickable-link-parent>"; if (!string.IsNullOrEmpty(ogDetails.Image)) { if (ogDetails.Image.StartsWith("/")) { ogDetails.Image = $"{remoteUrlAuthority}{ogDetails.Image}"; } returnResult.Card += $"<div class='card-image'><img src='{ogDetails.Image}' /></div>"; } returnResult.Card += "<div>"; returnResult.Card += $"<p class='card-title'><a target='_blank' href='{remoteUrl}'>{returnResult.Title}</a></p>"; var decodedDescription = WebUtility.HtmlDecode(ogDetails.Description); returnResult.Card += $"<p class='card-description'>{decodedDescription}</p>"; if (string.IsNullOrEmpty(ogDetails.SiteName)) { returnResult.Card += $"<p class='card-link'><a target='_blank' href='{remoteUrl}'>[Direct Link]</a></p>"; } else { returnResult.Card += $"<p class='card-link'><a target='_blank' href='{remoteUrl}'>[{ogDetails.SiteName}]</a></p>"; } returnResult.Card += "</div><br class='clear' /></blockquote>"; } } if (returnResult.Title.Contains(" - ")) { StripTitleSiteName(domain, returnResult); } return(returnResult); }