mirror of
https://git.v0l.io/Kieran/void.cat.git
synced 2025-03-17 23:02:22 +01:00
Inject tags to index.html
This commit is contained in:
parent
b9a9d7bd26
commit
c019dcb3fb
@ -24,3 +24,5 @@ LICENSE
|
||||
README.md
|
||||
**/appsettings.*.json
|
||||
**/data
|
||||
**/build
|
||||
**/dist
|
@ -1,6 +1,6 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using AngleSharp;
|
||||
using AngleSharp.Dom;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using VoidCat.Model;
|
||||
using VoidCat.Services.Abstractions;
|
||||
|
||||
@ -10,11 +10,13 @@ public class IndexController : Controller
|
||||
{
|
||||
private readonly IWebHostEnvironment _webHost;
|
||||
private readonly IFileMetadataStore _fileMetadata;
|
||||
private readonly VoidSettings _settings;
|
||||
|
||||
public IndexController(IFileMetadataStore fileMetadata, IWebHostEnvironment webHost)
|
||||
public IndexController(IFileMetadataStore fileMetadata, IWebHostEnvironment webHost, VoidSettings settings)
|
||||
{
|
||||
_fileMetadata = fileMetadata;
|
||||
_webHost = webHost;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -28,22 +30,57 @@ public class IndexController : Controller
|
||||
{
|
||||
id.TryFromBase58Guid(out var gid);
|
||||
|
||||
var manifestPath = Path.Combine(_webHost.WebRootPath, "asset-manifest.json");
|
||||
if (!System.IO.File.Exists(manifestPath)) return StatusCode(500);
|
||||
|
||||
// old format hash, return 404
|
||||
if (id.Length == 40 && Regex.IsMatch(id, @"[0-9a-z]{40}"))
|
||||
var ubDownload = new UriBuilder(_settings.SiteUrl)
|
||||
{
|
||||
Response.StatusCode = 404;
|
||||
Path = $"/d/{gid.ToBase58()}"
|
||||
};
|
||||
|
||||
var ubView = new UriBuilder(_settings.SiteUrl)
|
||||
{
|
||||
Path = $"/{gid.ToBase58()}"
|
||||
};
|
||||
|
||||
var indexPath = Path.Combine(_webHost.WebRootPath, "index.html");
|
||||
var indexContent = await System.IO.File.ReadAllTextAsync(indexPath);
|
||||
|
||||
var meta = (await _fileMetadata.Get(gid))?.ToMeta(false);
|
||||
var tags = new List<KeyValuePair<string, string>>()
|
||||
{
|
||||
new("site_name", "void.cat"),
|
||||
new("title", meta?.Name ?? ""),
|
||||
new("description", meta?.Description ?? ""),
|
||||
new("url", ubView.Uri.ToString()),
|
||||
};
|
||||
|
||||
var mime = meta?.MimeType;
|
||||
if (mime?.StartsWith("image/") ?? false)
|
||||
{
|
||||
tags.Add(new("type", "image"));
|
||||
tags.Add(new("image", ubDownload.Uri.ToString()));
|
||||
tags.Add(new("image:type", mime));
|
||||
}
|
||||
else if (mime?.StartsWith("video/") ?? false)
|
||||
{
|
||||
tags.Add(new("type", "video.other"));
|
||||
tags.Add(new("image", ""));
|
||||
tags.Add(new("video", ubDownload.Uri.ToString()));
|
||||
tags.Add(new("video:url", ubDownload.Uri.ToString()));
|
||||
tags.Add(new("video:secure_url", ubDownload.Uri.ToString()));
|
||||
tags.Add(new("video:type", mime));
|
||||
}
|
||||
else if (mime?.StartsWith("audio/") ?? false)
|
||||
{
|
||||
tags.Add(new("type", "audio.other"));
|
||||
tags.Add(new("audio", ubDownload.Uri.ToString()));
|
||||
tags.Add(new("audio:type", mime));
|
||||
}
|
||||
else
|
||||
{
|
||||
tags.Add(new("type", "website"));
|
||||
}
|
||||
|
||||
var jsonManifest = await System.IO.File.ReadAllTextAsync(manifestPath);
|
||||
return View("~/Pages/Index.cshtml", new IndexModel
|
||||
{
|
||||
Id = gid,
|
||||
Meta = (await _fileMetadata.Get(gid))?.ToMeta(false),
|
||||
Manifest = JsonConvert.DeserializeObject<AssetManifest>(jsonManifest)!
|
||||
});
|
||||
var injectedHtml = await InjectTags(indexContent, tags);
|
||||
return Content(injectedHtml?.ToHtml() ?? indexContent, "text/html");
|
||||
}
|
||||
|
||||
public class IndexModel
|
||||
@ -59,4 +96,41 @@ public class IndexController : Controller
|
||||
public Dictionary<string, string> Files { get; init; }
|
||||
public List<string> Entrypoints { get; init; }
|
||||
}
|
||||
|
||||
private async Task<IDocument?> InjectTags(string html, List<KeyValuePair<string, string>> tags)
|
||||
{
|
||||
var config = Configuration.Default;
|
||||
var context = BrowsingContext.New(config);
|
||||
var doc = await context.OpenAsync(c => c.Content(html));
|
||||
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
var ogTag = doc.CreateElement("meta");
|
||||
ogTag.SetAttribute("property", $"og:{tag.Key}");
|
||||
ogTag.SetAttribute("content", tag.Value);
|
||||
doc.Head?.AppendChild(ogTag);
|
||||
switch (tag.Key.ToLower())
|
||||
{
|
||||
case "title":
|
||||
{
|
||||
var titleTag = doc.Head?.QuerySelector("title");
|
||||
if (titleTag != default)
|
||||
{
|
||||
titleTag.TextContent = tag.Value;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "description":
|
||||
{
|
||||
var descriptionTag = doc.Head?.QuerySelector("meta[name='description']");
|
||||
descriptionTag?.SetAttribute("content", tag.Value);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
@using VoidCat.Model
|
||||
@model VoidCat.Controllers.IndexController.IndexModel
|
||||
@inject VoidSettings Settings
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta name="theme-color" content="#000000"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="apple-touch-icon" href="/logo.png"/>
|
||||
<link rel="manifest" href="/manifest.json"/>
|
||||
|
||||
@if (Model.Meta != default)
|
||||
{
|
||||
var ubDownload = new UriBuilder(Settings.SiteUrl)
|
||||
{
|
||||
Path = $"/d/{Model.Id.ToBase58()}"
|
||||
};
|
||||
var ubView = new UriBuilder(Settings.SiteUrl)
|
||||
{
|
||||
Path = $"/{Model.Id.ToBase58()}"
|
||||
};
|
||||
|
||||
<title>void.cat - @Model.Meta.Name</title>
|
||||
<meta name="description" content="@Model.Meta.Description"/>
|
||||
<meta property="og:site_name" content="void.cat"/>
|
||||
<meta property="og:title" content="@Model.Meta.Name"/>
|
||||
<meta property="og:description" content="@Model.Meta.Description"/>
|
||||
<meta property="og:url" content="@ubView"/>
|
||||
|
||||
var mime = Model.Meta.MimeType;
|
||||
if (!string.IsNullOrEmpty(mime))
|
||||
{
|
||||
if (mime.StartsWith("image/"))
|
||||
{
|
||||
<meta property="og:type" content="image"/>
|
||||
<meta property="og:image" content="@ubDownload"/>
|
||||
<meta property="og:image:type" content="@mime"/>
|
||||
}
|
||||
else if (mime.StartsWith("video/"))
|
||||
{
|
||||
<meta property="og:type" content="video.other"/>
|
||||
<meta property="og:image" content=""/>
|
||||
<meta property="og:video" content="@ubDownload"/>
|
||||
<meta property="og:video:url" content="@ubDownload"/>
|
||||
<meta property="og:video:secure_url" content="@ubDownload"/>
|
||||
<meta property="og:video:type" content="@mime"/>
|
||||
}
|
||||
else if (mime.StartsWith("audio/"))
|
||||
{
|
||||
<meta property="og:type" content="audio.other"/>
|
||||
<meta property="og:audio" content="@ubDownload"/>
|
||||
<meta property="og:audio:type" content="@mime"/>
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<title>void.cat</title>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta name="description" content="void.cat - free, simple file sharing."/>
|
||||
}
|
||||
|
||||
@foreach (var ep in Model.Manifest.Entrypoints)
|
||||
{
|
||||
switch (System.IO.Path.GetExtension(ep))
|
||||
{
|
||||
case ".css":
|
||||
{
|
||||
<link rel="stylesheet" href="@ep"/>
|
||||
break;
|
||||
}
|
||||
case ".js":
|
||||
{
|
||||
<script defer src="@ep"></script>
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
@ -13,6 +13,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AngleSharp" Version="1.0.7" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="3.7.103.41" />
|
||||
<PackageReference Include="BencodeNET" Version="5.0.0" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.21" />
|
||||
|
@ -27,8 +27,8 @@ export class VoidApi {
|
||||
readonly #uri: string;
|
||||
readonly #auth?: AuthHandler;
|
||||
|
||||
constructor(uri: string, auth?: AuthHandler) {
|
||||
this.#uri = uri;
|
||||
constructor(uri?: string, auth?: AuthHandler) {
|
||||
this.#uri = uri ?? "";
|
||||
this.#auth = auth;
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ export function FilePreview() {
|
||||
|
||||
useEffect(() => {
|
||||
if (info) {
|
||||
const fileLink = info.metadata?.url ?? `${import.meta.env.VITE_API_HOST}/d/${info.id}`;
|
||||
const fileLink = info.metadata?.url ?? `${import.meta.env.VITE_API_HOST ?? ""}/d/${info.id}`;
|
||||
setFileSize(info.metadata?.size ?? 0);
|
||||
|
||||
const order = window.localStorage.getItem(`payment-${info.id}`);
|
||||
|
@ -20,8 +20,9 @@ export default defineConfig({
|
||||
],
|
||||
assetsInclude: [],
|
||||
build: {
|
||||
outDir: "build",
|
||||
outDir: "build"
|
||||
},
|
||||
base: "/",
|
||||
clearScreen: false,
|
||||
resolve: {
|
||||
alias: {
|
||||
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"files": {
|
||||
"main.js": "/static/js/bundle.js",
|
||||
"index.html": "/index.html",
|
||||
"bundle.js.map": "/static/js/bundle.js.map",
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/bundle.js"
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user