mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 03:19:46 +00:00
Code style changes
This commit is contained in:
parent
020736fd47
commit
72970bf480
4 changed files with 61 additions and 48 deletions
|
|
@ -250,8 +250,9 @@ class Conf {
|
|||
static get cronEnabled(): boolean {
|
||||
return optionalBooleanSchema.parse(Deno.env.get('CRON_ENABLED')) ?? true;
|
||||
}
|
||||
static get opengraphRouteRegex(): string {
|
||||
return Deno.env.get('OPENGRAPH_ROUTE_REGEX') ||
|
||||
/** Crawler User-Agent regex to render link previews to. */
|
||||
static get crawlerRegex(): string {
|
||||
return Deno.env.get('CRAWLER_REGEX') ||
|
||||
'googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp|mastodon|pleroma|Discordbot|AhrefsBot|SEMrushBot|MJ12bot|SeekportBot|Synapse|Matrix';
|
||||
}
|
||||
/** Path to the custom policy module. Must be an absolute path, https:, npm:, or jsr: URI. */
|
||||
|
|
|
|||
|
|
@ -21,30 +21,43 @@ const META_PLACEHOLDER = '<!--server-generated-meta-->' as const;
|
|||
async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenGraphTemplateOpts> {
|
||||
const store = await Storages.db();
|
||||
const meta = await getInstanceMetadata(store);
|
||||
|
||||
const res: OpenGraphTemplateOpts = {
|
||||
title: `View this page on ${meta.name}`,
|
||||
title: meta.name,
|
||||
type: 'article',
|
||||
description: meta.about,
|
||||
url,
|
||||
site: meta.name,
|
||||
image: {
|
||||
url: Conf.local('/favicon.ico'),
|
||||
w: 48,
|
||||
h: 48,
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
if (params.acct && !params.statusId) {
|
||||
if (params.statusId) {
|
||||
const { description, image, title } = await getStatusInfo(params.statusId);
|
||||
|
||||
res.description = description;
|
||||
res.title = title;
|
||||
|
||||
if (res.image) {
|
||||
res.image = image;
|
||||
}
|
||||
} else if (params.acct) {
|
||||
const key = /^[a-f0-9]{64}$/.test(params.acct) ? 'pubkey' : 'handle';
|
||||
let handle = '';
|
||||
try {
|
||||
const profile = await fetchProfile({ [key]: params.acct });
|
||||
handle = await getHandle(params.acct, profile);
|
||||
res.description = profile.meta.about || `@${handle}'s Nostr profile`;
|
||||
|
||||
res.description = profile.meta.about;
|
||||
|
||||
if (profile.meta.picture) {
|
||||
res.image = { url: profile.meta.picture, h: 150, w: 150 };
|
||||
res.image = {
|
||||
url: profile.meta.picture,
|
||||
};
|
||||
}
|
||||
} catch (_) {
|
||||
} catch {
|
||||
console.debug(`couldn't find kind 0 for ${params.acct}`);
|
||||
// @ts-ignore we don't want getHandle trying to do a lookup here
|
||||
// but we do want it to give us a nice pretty npub
|
||||
|
|
@ -52,14 +65,8 @@ async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenG
|
|||
res.description = `@${handle}'s Nostr profile`;
|
||||
}
|
||||
|
||||
Object.assign(res, {
|
||||
type: 'profile',
|
||||
title: `View @${handle}'s profile on Ditto`,
|
||||
});
|
||||
} else if (params.statusId) {
|
||||
const { description, image, title } = await getStatusInfo(params.statusId);
|
||||
Object.assign(res, { description, title });
|
||||
if (image) Object.assign(res, { image });
|
||||
res.type = 'profile';
|
||||
res.title = `View @${handle}'s profile on Ditto`;
|
||||
}
|
||||
} catch (e) {
|
||||
console.debug('Error getting OpenGraph metadata information:');
|
||||
|
|
@ -70,16 +77,17 @@ async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenG
|
|||
return res;
|
||||
}
|
||||
|
||||
const SHOULD_INJECT_RE = new RegExp(Conf.opengraphRouteRegex, 'i');
|
||||
|
||||
export const frontendController: AppMiddleware = async (c, next) => {
|
||||
try {
|
||||
const content = await Deno.readTextFile(new URL('../../public/index.html', import.meta.url));
|
||||
|
||||
const ua = c.req.header('User-Agent');
|
||||
console.debug('ua', ua);
|
||||
if (!SHOULD_INJECT_RE.test(ua || '')) {
|
||||
|
||||
if (!new RegExp(Conf.crawlerRegex, 'i').test(ua ?? '')) {
|
||||
return c.html(content);
|
||||
}
|
||||
|
||||
if (content.includes(META_PLACEHOLDER)) {
|
||||
const params = getPathParams(c.req.path);
|
||||
if (params) {
|
||||
|
|
@ -87,7 +95,7 @@ export const frontendController: AppMiddleware = async (c, next) => {
|
|||
const meta = metadataView(await buildTemplateOpts(params, Conf.local(c.req.path)));
|
||||
return c.html(content.replace(META_PLACEHOLDER, meta));
|
||||
} catch (e) {
|
||||
console.log(`Error in building meta tags: ${e}`);
|
||||
console.log(`Error building meta tags: ${e}`);
|
||||
return c.html(content);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { NostrEvent, NostrMetadata, NSchema as n } from '@nostrify/nostrify';
|
||||
import { getAuthor, getEvent } from '@/queries.ts';
|
||||
import { Stickynotes } from '@soapbox/stickynotes';
|
||||
import { nip19, nip27 } from 'nostr-tools';
|
||||
import { match } from 'path-to-regexp';
|
||||
|
||||
import { Stickynotes } from '@soapbox/stickynotes';
|
||||
import { getAuthor, getEvent } from '@/queries.ts';
|
||||
import { lookupPubkey } from '@/utils/lookup.ts';
|
||||
import { parseAndVerifyNip05 } from '@/utils/nip05.ts';
|
||||
import { parseNip05 } from '@/utils.ts';
|
||||
|
|
@ -15,7 +15,7 @@ export interface OpenGraphTemplateOpts {
|
|||
type: 'article' | 'profile' | 'website';
|
||||
url: string;
|
||||
image?: StatusInfo['image'];
|
||||
description: string;
|
||||
description?: string;
|
||||
site: string;
|
||||
}
|
||||
|
||||
|
|
@ -26,8 +26,8 @@ interface StatusInfo {
|
|||
description: string;
|
||||
image?: {
|
||||
url: string;
|
||||
w: number;
|
||||
h: number;
|
||||
w?: number;
|
||||
h?: number;
|
||||
alt?: string;
|
||||
};
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ const SSR_ROUTES = [
|
|||
|
||||
const SSR_ROUTE_MATCHERS = SSR_ROUTES.map((route) => match(route, { decode: decodeURIComponent }));
|
||||
|
||||
export function getPathParams(path: string) {
|
||||
export function getPathParams(path: string): PathParams | undefined {
|
||||
for (const matcher of SSR_ROUTE_MATCHERS) {
|
||||
const result = matcher(path);
|
||||
if (!result) continue;
|
||||
|
|
@ -144,7 +144,7 @@ export async function getHandle(id: string, acc?: ProfileInfo) {
|
|||
|
||||
export async function getStatusInfo(id: string): Promise<StatusInfo> {
|
||||
const event = await getEvent(id);
|
||||
if (!id || !event) throw new Error('Invalid post id supplied');
|
||||
if (!event) throw new Error('Invalid post id supplied');
|
||||
let title = 'View post on Ditto';
|
||||
try {
|
||||
const handle = await getHandle(event.pubkey);
|
||||
|
|
|
|||
|
|
@ -6,31 +6,35 @@ import { OpenGraphTemplateOpts } from '@/utils/og-metadata.ts';
|
|||
* @param opts the metadata to use to fill the template.
|
||||
* @returns the built OpenGraph metadata.
|
||||
*/
|
||||
export const metadataView = ({ title, type, url, image, description, site }: OpenGraphTemplateOpts): string => {
|
||||
const res = [];
|
||||
res.push(html`\
|
||||
<meta content="${title}" property="og:title">
|
||||
<meta content="${type}" property="og:type">
|
||||
<meta content="${url}" property="og:url">
|
||||
<meta content="${description}" property="og:description">
|
||||
<meta content="${site}" property="og:site_name">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="${title}">
|
||||
<meta name="twitter:description" content="${description}">
|
||||
`);
|
||||
export function metadataView({ title, type, url, image, description, site }: OpenGraphTemplateOpts): string {
|
||||
const res: string[] = [
|
||||
html` <meta content="${title}" property="og:title">`,
|
||||
html` <meta content="${type}" property="og:type">`,
|
||||
html` <meta content="${url}" property="og:url">`,
|
||||
html` <meta content="${site}" property="og:site_name">`,
|
||||
html` <meta name="twitter:card" content="summary">`,
|
||||
html` <meta name="twitter:title" content="${title}">`,
|
||||
];
|
||||
|
||||
if (description) {
|
||||
res.push(html`<meta content="${description}" property="og:description">`);
|
||||
res.push(html`<meta content="${description}" property="twitter:description">`);
|
||||
}
|
||||
|
||||
if (image) {
|
||||
res.push(html`\
|
||||
<meta content="${image.url}" property="og:image">
|
||||
<meta content="${image.w}" property="og:image:width">
|
||||
<meta content="${image.h}" property="og:image:height">
|
||||
<meta name="twitter:image" content="${image.url}">
|
||||
`);
|
||||
res.push(html`<meta content="${image.url}" property="og:image">`);
|
||||
res.push(html`<meta name="twitter:image" content="${image.url}">`);
|
||||
|
||||
if (image.w && image.h) {
|
||||
res.push(html`<meta content="${image.w}" property="og:image:width">`);
|
||||
res.push(html`<meta content="${image.h}" property="og:image:height">`);
|
||||
}
|
||||
|
||||
if (image.alt) {
|
||||
res.push(html`<meta content="${image.alt}" property="og:image:alt">`);
|
||||
res.push(html`<meta content="${image.alt}" property="twitter:image:alt">`);
|
||||
}
|
||||
}
|
||||
|
||||
return res.join('\n').replace(/\n+/g, '\n').replace(/^[ ]+/gm, '');
|
||||
};
|
||||
return res.join('');
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue