redirecter for ao3 that adds opengraph metadata

more themes agenda

Changed files
+291 -63
src
app
series
[seriesId]
works
[workId]
icons
lib
+2
src/app/series/[seriesId]/opengraph-image.jsx
···
import { getSeries } from "@fujocoded/ao3.js"
import sanitizeData from "@/lib/sanitizeData.js"
import OGImage from "@/lib/ogimage.js"
+
import OGImage from "@/lib/ogimagelocked.js"
import baseFonts from "@/lib/baseFonts.js"
import titleFonts from "@/lib/titleFonts.js"
import defaults from "@/lib/ogdefaults.js"
···
const { seriesId } = await params
const addr = `series/${seriesId}`
const data = await getSeries({seriesId: seriesId})
+
if (data.locked) return OGImageLocked({theme: theme})
const imageParams = await sanitizeData({type: 'series', data: data, props: defaults})
const theme = imageParams.theme
console.log(theme)
+2
src/app/works/[workId]/chapters/[chapterId]/opengraph-image.jsx
···
import { getWork } from "@fujocoded/ao3.js"
import sanitizeData from "@/lib/sanitizeData.js"
import OGImage from "@/lib/ogimage.js"
+
import OGImageLocked from "@/lib/ogimagelocked.js"
import baseFonts from "@/lib/baseFonts.js"
import titleFonts from "@/lib/titleFonts.js"
import defaults from "@/lib/ogdefaults.js"
···
const { workId, chapterId } = await params
const addr = `works/${workId}/chapters/${chapterId}`
const data = await getWork({workId: workId, chapterId: chapterId})
+
if (data.locked) return OGImageLocked({theme: theme})
const imageParams = await sanitizeData({type: 'work', data: data, props: defaults})
const theme = imageParams.theme
const baseFont = baseFonts[imageParams.baseFont].displayName
+2
src/app/works/[workId]/opengraph-image.jsx
···
import { getWork } from "@fujocoded/ao3.js"
import sanitizeData from "@/lib/sanitizeData.js"
import OGImage from "@/lib/ogimage.js"
+
import OGImageLocked from "@/lib/ogimagelocked.js"
import baseFonts from "@/lib/baseFonts.js"
import titleFonts from "@/lib/titleFonts.js"
import defaults from "@/lib/ogdefaults.js"
···
const { workId } = await params
const addr = `works/${workId}`
const data = await getWork({workId: workId})
+
if (data.locked) return OGImageLocked({theme: theme})
const imageParams = await sanitizeData({type: 'work', data: data, props: defaults})
const theme = imageParams.theme
const baseFont = baseFonts[imageParams.baseFont].displayName
+8
src/icons/lock.js
···
+
export default function Lock ({bg, fg, width, height}) {
+
return (
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" width={width} height={height}>
+
<ellipse cx="320" cy="320" rx="320" ry="320" fill={bg} />
+
<path d="M256 160L256 224L384 224L384 160C384 124.7 355.3 96 320 96C284.7 96 256 124.7 256 160zM192 224L192 160C192 89.3 249.3 32 320 32C390.7 32 448 89.3 448 160L448 224C483.3 224 512 252.7 512 288L512 512C512 547.3 483.3 576 448 576L192 576C156.7 576 128 547.3 128 512L128 288C128 252.7 156.7 224 192 224z" fill={fg} />
+
</svg>
+
)
+
}
+27
src/lib/ogimagelocked.js
···
+
import { ImageResponse } from "next/og"
+
import General from "@/icons/locked.js"
+
+
export default async function OGImageLocked ({ theme }) {
+
return new ImageResponse(
+
(
+
<div
+
style={{
+
display: "flex",
+
flexDirection: "column",
+
justifyContent: "center",
+
alignItems: "center",
+
color: theme.color,
+
backgroundColor: theme.background,
+
fontFamily: baseFont,
+
fontSize: 24,
+
padding: 20,
+
width: "100%",
+
height: "100%",
+
}}
+
>
+
<Locked bg={theme.background} fg={theme.color} width={480} height={480} />
+
</div>
+
),
+
opts
+
)
+
}
+12 -5
src/lib/sanitizeData.js
···
-
import { getWork } from "@fujocoded/ao3.js"
import DOM from "fauxdom"
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
···
import baseFonts from '@/lib/baseFonts.js'
import titleFonts from '@/lib/titleFonts.js'
+
const getWork = async (workId) => {
+
const x = await fetch('https://veryroundbird.house')
+
const data = await fetch(`http://${process.env.DOMAIN}/api/works/${workId}`)
+
const work = await data.json()
+
return work
+
}
+
const getHighestRating = async (works) => {
const ratings = await Promise.all(works.map(async (w) => {
-
const work = await getWork({workId: w.id})
+
const work = await getWork(w.id)
return work.rating
}))
if (ratings.includes("Not Rated")) {
···
const getHighestWarning = async (works) => {
const warnings = await Promise.all(works.map(async (w) => {
-
const work = await getWork({workId: w.id})
+
const work = await getWork(w.id)
return work.tags.warnings
}))
+
console.log(warnings)
const warningsUnique = warnings.reduce((a, b) => { return a.concat(b) }).filter((w, i) => { return i === warnings.indexOf(w) })
if (warningsUnique.length === 1 && warningsUnique[0] === "Creator Chose Not To Use Archive Warnings") {
return "CNTW"
···
const getCategory = async (works) => {
const categories = await Promise.all(works.map(async (w) => {
-
const work = await getWork({workId: w.id})
+
const work = await getWork(w.id)
return work.category
}))
const categoriesJoined = categories.reduce((a, b) => { return a.concat(b) })
···
const titleFont = propsParsed.titleFont ? propsParsed.titleFont : process.env.DEFAULT_TITLE_FONT
const titleFontData = titleFonts[titleFont]
const themeData = propsParsed.theme ? themes[propsParsed.theme] : themes[process.env.DEFAULT_THEME]
-
const parentWork = type === 'work' && data.chapterInfo ? await getWork({workId: data.id}) : null
+
const parentWork = type === 'work' && data.chapterInfo ? await getWork(data.id) : null
const bfs = await Promise.all(baseFontData.defs.map(async (bf) => {
return {
name: baseFontData.displayName,
+238 -58
src/lib/themes.js
···
},
base2ToneEarth: {
name: 'Base2Tone Earth',
-
background: '',
-
color: '',
-
descBackground: '',
-
descColor: '',
-
accent: '',
-
accentColor: '',
-
accent2: '',
-
accent2Color: '',
-
accent3: '',
-
accent3Color: '',
-
accent4: '',
-
accent4Color: ''
+
background: '#322d29',
+
color: '#b5a9a1',
+
descBackground: '#3f3a37',
+
descColor: '#fff3eb',
+
accent: '#e6b84d',
+
accentColor: '#fff3eb',
+
accent2: '#d9b154',
+
accent2Color: '#fff3eb',
+
accent3: '#816d5f',
+
accent3Color: '#fff3eb',
+
accent4: '#b5a9a1',
+
accent4Color: '#fff3eb'
},
base2ToneEvening: {
name: 'Base2Tone Evening',
-
background: '',
-
color: '',
-
descBackground: '',
-
descColor: '',
-
accent: '',
-
accentColor: '',
-
accent2: '',
-
accent2Color: '',
-
accent3: '',
-
accent3Color: '',
-
accent4: '',
-
accent4Color: ''
+
background: '#2a2734',
+
color: '#a4a1b5',
+
descBackground: '#363342',
+
descColor: '#eeebff',
+
accent: '#8a75f5',
+
accentColor: '#eeebff',
+
accent2: '#ffad5c',
+
accent2Color: '#eeebff',
+
accent3: '#afa0fe',
+
accent3Color: '#eeebff',
+
accent4: '#a4a1b5',
+
accent4Color: '#eeebff'
},
base2ToneField: {
name: 'Base2Tone Field',
-
background: '',
-
color: '',
-
descBackground: '',
-
descColor: '',
-
accent: '',
-
accentColor: '',
-
accent2: '',
-
accent2Color: '',
-
accent3: '',
-
accent3Color: '',
-
accent4: '',
-
accent4Color: ''
+
background: '#18201e',
+
color: '#8ea4a0',
+
descBackground: '#242e2c',
+
descColor: '#a8fff1',
+
accent: '#0fbda0',
+
accentColor: '#242e2c',
+
accent2: '#3be381',
+
accent2Color: '#242e2c',
+
accent3: '#40ddc3',
+
accent3Color: '#242e2c',
+
accent4: '#8ea4a0',
+
accent4Color: '#242e2c'
},
base2ToneForest: {
name: 'Base2Tone Forest',
···
accent4: '#5b6080',
accent4Color: '#ebedff'
},
+
blueDolphin: {
+
name: "Blue Dolphin",
+
background: '#006984',
+
color: '#A3F7FF',
+
descBackground: '#006984',
+
descColor: '#FFFFFF',
+
accent: '#FF8288',
+
accentColor: '#292D3E',
+
accent2: '#B4E88D',
+
accent2Color: '#292D3E',
+
accent3: '#F4D69F',
+
accent3Color: '#292D3E',
+
accent4: '#82AAFF',
+
accent4Color: '#292D3E'
+
},
+
borland: {
+
name: "Borland",
+
background: '#0000a4',
+
color: '#FFFFB6',
+
descBackground: '#0000a4',
+
descColor: '#FFFFB6',
+
accent: '#FF6C60',
+
accentColor: '#292D3E',
+
accent2: '#B4E88D',
+
accent2Color: '#292D3E',
+
accent3: '#F4D69F',
+
accent3Color: '#292D3E',
+
accent4: '#82AAFF',
+
accent4Color: '#292D3E'
+
},
+
butrin: {
+
name: 'Butrin',
+
background: '#4b3b3c',
+
color: '#F2F2F2',
+
descBackground: '#4b3b3c',
+
descColor: '#F2F2F2',
+
accent: '#F2B1B1',
+
accentColor: '#4b3b3c',
+
accent2: '#B2D8B2',
+
accent2Color: '#4b3b3c',
+
accent3: '#87CEFA',
+
accent3Color: '#4b3b3c',
+
accent4: '#D8BFD8',
+
accent4Color: '#4b3b3c'
+
},
gruvbox: {
name: 'Gruvbox',
-
background: '#1e202f',
+
background: '#FBF1C7',
color: '#4f5472',
-
descBackground: '#292c3d',
-
descColor: '#ebedff',
-
accent: '#7586f5',
-
accentColor: '#ebedff',
-
accent2: '#fe81b5',
-
accent2Color: '#ebedff',
-
accent3: '#fb6fa9',
-
accent3Color: '#ebedff',
-
accent4: '#5b6080',
-
accent4Color: '#ebedff'
+
descBackground: '#FBF1C7',
+
descColor: '#3C3836',
+
accent: '#9D0006',
+
accentColor: '#4F4F4F',
+
accent2: '#A8FF60',
+
accent2Color: '#4F4F4F',
+
accent3: '#96CBFE',
+
accent3Color: '#4F4F4F',
+
accent4: '#FF73FD',
+
accent4Color: '#4F4F4F'
},
gruvboxDark: {
name: 'Gruvbox Dark',
-
background: '#1e202f',
-
color: '#4f5472',
-
descBackground: '#292c3d',
+
background: '#282828',
+
color: '#7C6F64',
+
descBackground: '#282828',
descColor: '#ebedff',
-
accent: '#7586f5',
-
accentColor: '#ebedff',
-
accent2: '#fe81b5',
-
accent2Color: '#ebedff',
-
accent3: '#fb6fa9',
-
accent3Color: '#ebedff',
-
accent4: '#5b6080',
-
accent4Color: '#ebedff'
+
accent: '#FB4934',
+
accentColor: '#282828',
+
accent2: '#B8BB26',
+
accent2Color: '#282828',
+
accent3: '#FABD2F',
+
accent3Color: '#282828',
+
accent4: '#83A598',
+
accent4Color: '#282828'
},
monoAmber: {
name: "Mono Amber",
···
accent3Color: '#403500',
accent4: '#FFD300',
accent4Color: '#403500'
+
},
+
seaShells: {
+
name: "Sea Shells",
+
background: '#09141b',
+
color: '#DEB88D',
+
descBackground: '#09141b',
+
descColor: '#FEE4CE',
+
accent: '#D15123',
+
accentColor: '#FEE4CE',
+
accent2: '#027C9B',
+
accent2Color: '#FEE4CE',
+
accent3: '#1E4950',
+
accent3Color: '#FEE4CE',
+
accent4: '#434B53',
+
accent4Color: '#FEE4CE'
+
},
+
seafoamPastel: {
+
name: "Seafoam Pastel",
+
background: '#243435',
+
color: '#E0E0E0',
+
descBackground: '#243435',
+
descColor: '#E0E0E0',
+
accent: '#825D4D',
+
accentColor: '#FEE4CE',
+
accent2: '#728C62',
+
accent2Color: '#FEE4CE',
+
accent3: '#ADA16D',
+
accent3Color: '#FEE4CE',
+
accent4: '#4D7B82',
+
accent4Color: '#FEE4CE'
+
},
+
seoul256: {
+
name: "Seoul 256",
+
background: '#3a3a3a',
+
color: '#e4e4e4',
+
descBackground: '#4e4e4e',
+
descColor: '#d0d0d0',
+
accent: '#d68787',
+
accentColor: '#4e4e4e',
+
accent2: '#87af87',
+
accent2Color: '#4e4e4e',
+
accent3: '#add4fb',
+
accent3Color: '#4e4e4e',
+
accent4: '#d7afaf',
+
accent4Color: '#4e4e4e'
+
},
+
seoul256Light: {
+
name: "Seoul 256 Light",
+
background: '#dadada',
+
color: '#4e4e4e',
+
descBackground: '#e4e4e4',
+
descColor: '#3a3a3a',
+
accent: '#870100',
+
accentColor: '#eeeeee',
+
accent2: '#d8865f',
+
accent2Color: '#eeeeee',
+
accent3: '#87025f',
+
accent3Color: '#eeeeee',
+
accent4: '#008787',
+
accent4Color: '#eeeeee'
+
},
+
shel: {
+
name: "Shel",
+
background: '#2C2423',
+
color: '#8FBAEC',
+
descBackground: '#2C2423',
+
descColor: '#F5EEEC',
+
accent: '#F588B9',
+
accentColor: '#F5EEEC',
+
accent2: '#AB6423',
+
accent2Color: '#F5EEEC',
+
accent3: '#2C64A2',
+
accent3Color: '#F5EEEC',
+
accent4: '#6C24A2',
+
accent4Color: '#F5EEEC'
+
},
+
slate: {
+
name: "Slate",
+
background: '#222222',
+
color: '#8CDFE0',
+
descBackground: '#222222',
+
descColor: '#E0E0E0',
+
accent: '#E2A8BF',
+
accentColor: '#222222',
+
accent2: '#81D778',
+
accent2Color: '#222222',
+
accent3: '#C4C9C0',
+
accent3Color: '#222222',
+
accent4: '#A481D3',
+
accent4Color: '#222222'
+
},
+
vaughn: {
+
name: "Vaughn",
+
background: '#25234F',
+
color: '#FFFFFF',
+
descBackground: '#25234F',
+
descColor: '#FFFFFF',
+
accent: '#60B48A',
+
accentColor: '#25234F',
+
accent2: '#DFAF8F',
+
accent2Color: '#25234F',
+
accent3: '#F08CC3',
+
accent3Color: '#25234F',
+
accent4: '#8CD0D3',
+
accent4Color: '#25234F'
+
},
+
warmNeon: {
+
name: "Warm Neon",
+
background: '#404040',
+
color: '#9CC090',
+
descBackground: '#404040',
+
descColor: '#FEFCFC',
+
accent: '#2ABBD4',
+
accentColor: '#FEFCFC',
+
accent2: '#39B13A',
+
accent2Color: '#FEFCFC',
+
accent3: '#4261C5',
+
accent3Color: '#FEFCFC',
+
accent4: '#F920FB',
+
accent4Color: '#FEFCFC'
+
},
+
website: {
+
name: "Website",
+
background: '#132f35',
+
color: '#ffd48f',
+
descBackground: '#183c44',
+
descColor: '#ffd48f',
+
accent: '#ff5757',
+
accentColor: '#235662',
+
accent2: '#ecff14',
+
accent2Color: '#235662',
+
accent3: '#4cbfff',
+
accent3Color: '#235662',
+
accent4: '#ff4cc2',
+
accent4Color: '#235662'
},
wryan: {
name: "Wryan",