Add fediverse:creator tag to pages
This commit is contained in:
parent
51cdd232ad
commit
5d701069e9
9 changed files with 22 additions and 137 deletions
11
README.md
11
README.md
|
@ -56,14 +56,3 @@ Then, if you're using rsync, after configuring the `gallerybm` host (or the name
|
||||||
```bash
|
```bash
|
||||||
rsync --delete-after -acP dist/ gallerybm:/home/public
|
rsync --delete-after -acP dist/ gallerybm:/home/public
|
||||||
```
|
```
|
||||||
|
|
||||||
Or if you prefer LFTP, create a `.env` file at the root of the project:
|
|
||||||
|
|
||||||
```env
|
|
||||||
DEPLOY_LFTP_HOST=https://example-webdav-server.com
|
|
||||||
DEPLOY_LFTP_USER=example_user
|
|
||||||
DEPLOY_LFTP_PASSWORD=sup3r_s3cr3t_password
|
|
||||||
DEPLOY_LFTP_TARGETFOLDER=sites/gallery.badmanners.xyz/
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run `npm run deploy-lftp`.
|
|
||||||
|
|
60
package-lock.json
generated
60
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "gallery.badmanners.xyz",
|
"name": "gallery.badmanners.xyz",
|
||||||
"version": "1.13.0",
|
"version": "1.13.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "gallery.badmanners.xyz",
|
"name": "gallery.badmanners.xyz",
|
||||||
"version": "1.13.0",
|
"version": "1.13.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/alpinejs": "^0.4.0",
|
"@astrojs/alpinejs": "^0.4.0",
|
||||||
|
@ -39,7 +39,6 @@
|
||||||
"@types/node": "^22.7.4",
|
"@types/node": "^22.7.4",
|
||||||
"@types/sanitize-html": "^2.13.0",
|
"@types/sanitize-html": "^2.13.0",
|
||||||
"commander": "^12.1.0",
|
"commander": "^12.1.0",
|
||||||
"dotenv-cli": "^7.4.2",
|
|
||||||
"fetch-retry": "^6.0.0",
|
"fetch-retry": "^6.0.0",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prettier-plugin-astro": "^0.14.1",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
|
@ -3107,9 +3106,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
|
@ -3297,45 +3296,6 @@
|
||||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
|
||||||
"version": "16.4.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
|
|
||||||
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://dotenvx.com"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dotenv-cli": {
|
|
||||||
"version": "7.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.4.2.tgz",
|
|
||||||
"integrity": "sha512-SbUj8l61zIbzyhIbg0FwPJq6+wjbzdn9oEtozQpZ6kW2ihCcapKVZj49oCT3oPM+mgQm+itgvUQcG5szxVrZTA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"cross-spawn": "^7.0.3",
|
|
||||||
"dotenv": "^16.3.0",
|
|
||||||
"dotenv-expand": "^10.0.0",
|
|
||||||
"minimist": "^1.2.6"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"dotenv": "cli.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dotenv-expand": {
|
|
||||||
"version": "10.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz",
|
|
||||||
"integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dset": {
|
"node_modules/dset": {
|
||||||
"version": "3.1.4",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz",
|
||||||
|
@ -5843,16 +5803,6 @@
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
|
||||||
"version": "1.2.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
|
||||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/minipass": {
|
"node_modules/minipass": {
|
||||||
"version": "7.1.2",
|
"version": "7.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "gallery.badmanners.xyz",
|
"name": "gallery.badmanners.xyz",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.13.0",
|
"version": "1.13.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "astro sync",
|
"postinstall": "astro sync",
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
|
@ -12,8 +12,7 @@
|
||||||
"check": "astro check",
|
"check": "astro check",
|
||||||
"astro": "astro",
|
"astro": "astro",
|
||||||
"prettier": "prettier --write .",
|
"prettier": "prettier --write .",
|
||||||
"export-story": "tsx scripts/export-story.ts",
|
"export-story": "tsx scripts/export-story.ts"
|
||||||
"deploy-lftp": "dotenv tsx scripts/deploy-lftp.ts --"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/alpinejs": "^0.4.0",
|
"@astrojs/alpinejs": "^0.4.0",
|
||||||
|
@ -46,7 +45,6 @@
|
||||||
"@types/node": "^22.7.4",
|
"@types/node": "^22.7.4",
|
||||||
"@types/sanitize-html": "^2.13.0",
|
"@types/sanitize-html": "^2.13.0",
|
||||||
"commander": "^12.1.0",
|
"commander": "^12.1.0",
|
||||||
"dotenv-cli": "^7.4.2",
|
|
||||||
"fetch-retry": "^6.0.0",
|
"fetch-retry": "^6.0.0",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prettier-plugin-astro": "^0.14.1",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
import { spawn } from "node:child_process";
|
|
||||||
import { join, normalize as n } from "node:path/posix";
|
|
||||||
import { program, Option } from "commander";
|
|
||||||
|
|
||||||
interface DeployLftpOptions {
|
|
||||||
host: string;
|
|
||||||
user: string;
|
|
||||||
password: string;
|
|
||||||
targetFolder: string;
|
|
||||||
sourceFolder: string;
|
|
||||||
assetsFolder: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deployLftp({ host, user, password, targetFolder, sourceFolder, assetsFolder }: DeployLftpOptions) {
|
|
||||||
const process = spawn(
|
|
||||||
"lftp",
|
|
||||||
[
|
|
||||||
"-c",
|
|
||||||
[
|
|
||||||
`open -u ${user},${password.replaceAll(/([ \t.,:;?!`'"^|*+#&$\(\)\[\]{}<>\\/-])/, "\\$1")} ${host}`,
|
|
||||||
`mirror --reverse --include-glob ${join(assetsFolder, "*")} --delete --only-missing --no-perms --verbose ${n(sourceFolder)} ${n(targetFolder)}`,
|
|
||||||
`mirror --reverse --exclude-glob ${join(assetsFolder, "*")} --delete --no-perms --verbose ${n(sourceFolder)} ${n(targetFolder)}`,
|
|
||||||
`bye`,
|
|
||||||
].join("\n"),
|
|
||||||
],
|
|
||||||
{
|
|
||||||
stdio: "inherit",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
process.on("close", (code) => (code === 0 ? resolve(0) : reject(`lftp failed with code ${code}`)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await program
|
|
||||||
.name("deploy-lftp")
|
|
||||||
.description("Deploy files to remote server with LFTP")
|
|
||||||
.addOption(
|
|
||||||
new Option("-h, --host <hostname>", "Hostname of the LFTP (i.e. WebDav, SCP, SFTP...) remote.").env(
|
|
||||||
"DEPLOY_LFTP_HOST",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.addOption(new Option("-u, --user <username>", "Username portion of the LFTP credentials").env("DEPLOY_LFTP_USER"))
|
|
||||||
.addOption(
|
|
||||||
new Option("-p, --password <pass>", "Password portion of the LFTP credentials").env("DEPLOY_LFTP_PASSWORD"),
|
|
||||||
)
|
|
||||||
.addOption(
|
|
||||||
new Option("-t, --target-folder <remoteDir>", "Folder to mirror files to in the LFTP remote").env(
|
|
||||||
"DEPLOY_LFTP_TARGETFOLDER",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.addOption(
|
|
||||||
new Option("-s, --source-folder <localDir>", "Folder to read files from in the local machine")
|
|
||||||
.env("DEPLOY_LFTP_SOURCEFOLDER")
|
|
||||||
.default("dist/"),
|
|
||||||
)
|
|
||||||
.addOption(
|
|
||||||
new Option("-a, --assets-folder <localDir>", "Directory inside of --source-folder of assets with hash-based names")
|
|
||||||
.env("DEPLOY_LFTP_ASSETSFOLDER")
|
|
||||||
.default("assets/"),
|
|
||||||
)
|
|
||||||
.action(deployLftp)
|
|
||||||
.parseAsync();
|
|
|
@ -1,11 +1,12 @@
|
||||||
# licenses.toml
|
file = "licenses.toml"
|
||||||
|
url = "https://gallery.badmanners.xyz/licenses.toml"
|
||||||
|
|
||||||
[copyright]
|
[copyright]
|
||||||
title = "gallery.badmanners.xyz"
|
title = "gallery.badmanners.xyz"
|
||||||
description = "Bad Manners's self-hosted gallery."
|
description = "Bad Manners's self-hosted gallery."
|
||||||
type = "website"
|
type = "website"
|
||||||
date = "2024"
|
date = "2024"
|
||||||
author = { name = "Bad Manners", url = "https://badmanners.xyz", email = "me@badmanners.xyz>" }
|
author = { name = "Bad Manners", url = "https://badmanners.xyz", email = "me@badmanners.xyz" }
|
||||||
source = "https://git.badmanners.xyz/badmanners/gallery.badmanners.xyz"
|
source = "https://git.badmanners.xyz/badmanners/gallery.badmanners.xyz"
|
||||||
license = { name = "MIT", url = "https://opensource.org/license/mit" }
|
license = { name = "MIT", url = "https://opensource.org/license/mit" }
|
||||||
notes = """All rights reserved. \
|
notes = """All rights reserved. \
|
||||||
|
@ -24,7 +25,7 @@ notes = """My characters, whether directly attributed to me or unattributed, are
|
||||||
type = "content"
|
type = "content"
|
||||||
description = "Content hosted on this website, i.e. the stories, games, and blog posts."
|
description = "Content hosted on this website, i.e. the stories, games, and blog posts."
|
||||||
date = "2022-2024"
|
date = "2022-2024"
|
||||||
author = { name = "Bad Manners", url = "https://badmanners.xyz", email = "me@badmanners.xyz>" }
|
author = { name = "Bad Manners", url = "https://badmanners.xyz", email = "me@badmanners.xyz" }
|
||||||
source = "https://git.badmanners.xyz/badmanners/gallery.badmanners.xyz/src/branch/main/src/content"
|
source = "https://git.badmanners.xyz/badmanners/gallery.badmanners.xyz/src/branch/main/src/content"
|
||||||
license = { name = "CC-BY-NC-ND-4.0", url = "https://creativecommons.org/licenses/by-nc-nd/4.0/" }
|
license = { name = "CC-BY-NC-ND-4.0", url = "https://creativecommons.org/licenses/by-nc-nd/4.0/" }
|
||||||
notes = "All rights reserved."
|
notes = "All rights reserved."
|
||||||
|
@ -60,7 +61,7 @@ notes = """All third-party copyrights and trademarks belong to their respective
|
||||||
[[attributions]]
|
[[attributions]]
|
||||||
description = "Edited icons for other websites."
|
description = "Edited icons for other websites."
|
||||||
type = "icons"
|
type = "icons"
|
||||||
author = { name = "Bad Manners", url = "https://badmanners.xyz", email = "me@badmanners.xyz>" }
|
author = { name = "Bad Manners", url = "https://badmanners.xyz", email = "me@badmanners.xyz" }
|
||||||
source = "https://git.badmanners.xyz/badmanners/badmanners.xyz/src/branch/main/src/components/icons/brands"
|
source = "https://git.badmanners.xyz/badmanners/badmanners.xyz/src/branch/main/src/components/icons/brands"
|
||||||
license = { name = "CC0 1.0 Universal", url = "https://creativecommons.org/publicdomain/zero/1.0/" }
|
license = { name = "CC0 1.0 Universal", url = "https://creativecommons.org/publicdomain/zero/1.0/" }
|
||||||
items = [
|
items = [
|
||||||
|
|
|
@ -47,6 +47,7 @@ const relatedBlogPosts = (await getEntries(props.relatedBlogPosts)).filter((post
|
||||||
relatedGames={relatedGames}
|
relatedGames={relatedGames}
|
||||||
relatedBlogPosts={relatedBlogPosts}
|
relatedBlogPosts={relatedBlogPosts}
|
||||||
posts={props.posts}
|
posts={props.posts}
|
||||||
|
authors={authorsList}
|
||||||
labelReturnTo={{ title: t(props.lang, "blog/return_to_blog_posts"), link: "/blog" }}
|
labelReturnTo={{ title: t(props.lang, "blog/return_to_blog_posts"), link: "/blog" }}
|
||||||
labelPreviousContent={t(props.lang, "blog/previous_post_aria_label")}
|
labelPreviousContent={t(props.lang, "blog/previous_post_aria_label")}
|
||||||
labelNextContent={t(props.lang, "blog/next_post_aria_label")}
|
labelNextContent={t(props.lang, "blog/next_post_aria_label")}
|
||||||
|
|
|
@ -44,6 +44,7 @@ const metaDescription = t(props.lang, "game/warnings", props.platforms, props.co
|
||||||
relatedGames={relatedGames}
|
relatedGames={relatedGames}
|
||||||
relatedBlogPosts={relatedBlogPosts}
|
relatedBlogPosts={relatedBlogPosts}
|
||||||
posts={props.posts}
|
posts={props.posts}
|
||||||
|
authors={authorsList}
|
||||||
labelReturnTo={{ title: t(props.lang, "game/return_to_games"), link: "/games" }}
|
labelReturnTo={{ title: t(props.lang, "game/return_to_games"), link: "/games" }}
|
||||||
labelPreviousContent={t(props.lang, "game/previous_game_aria_label")}
|
labelPreviousContent={t(props.lang, "game/previous_game_aria_label")}
|
||||||
labelNextContent={t(props.lang, "game/next_game_aria_label")}
|
labelNextContent={t(props.lang, "game/next_game_aria_label")}
|
||||||
|
|
|
@ -49,6 +49,7 @@ type Props = {
|
||||||
relatedGames?: CollectionEntry<"games">[];
|
relatedGames?: CollectionEntry<"games">[];
|
||||||
relatedBlogPosts?: CollectionEntry<"blog">[];
|
relatedBlogPosts?: CollectionEntry<"blog">[];
|
||||||
posts: Posts;
|
posts: Posts;
|
||||||
|
authors: CollectionEntry<"users">[];
|
||||||
|
|
||||||
/* Layout attributes */
|
/* Layout attributes */
|
||||||
publishedContentType: "story" | "game" | "blog post";
|
publishedContentType: "story" | "game" | "blog post";
|
||||||
|
@ -126,6 +127,12 @@ const returnTo = series
|
||||||
</Fragment>
|
</Fragment>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
props.authors
|
||||||
|
.map((user) => user.data.links.mastodon?.username)
|
||||||
|
.filter((value) => value)
|
||||||
|
.map((username) => <meta name="fediverse:creator" content={`@${username}`} />)
|
||||||
|
}
|
||||||
<slot name="head" />
|
<slot name="head" />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -55,6 +55,7 @@ const metaDescription = t(props.lang, "story/warnings", wordCount, props.content
|
||||||
relatedGames={relatedGames}
|
relatedGames={relatedGames}
|
||||||
relatedBlogPosts={relatedBlogPosts}
|
relatedBlogPosts={relatedBlogPosts}
|
||||||
posts={props.posts}
|
posts={props.posts}
|
||||||
|
authors={authorsList}
|
||||||
labelReturnTo={{ title: t(props.lang, "story/return_to_stories"), link: "/stories" }}
|
labelReturnTo={{ title: t(props.lang, "story/return_to_stories"), link: "/stories" }}
|
||||||
labelPreviousContent={t(props.lang, "story/previous_story_aria_label")}
|
labelPreviousContent={t(props.lang, "story/previous_story_aria_label")}
|
||||||
labelNextContent={t(props.lang, "story/next_story_aria_label")}
|
labelNextContent={t(props.lang, "story/next_story_aria_label")}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue