feat: move the generated images to a static like url endpoint.

This commit is contained in:
Yufan Sheng 2024-11-28 13:56:27 +08:00
parent 7ad873c83c
commit 4aa0812342
Signed by: syhily
GPG Key ID: 9D18A22A7DCD5A9B
6 changed files with 48 additions and 27 deletions

View File

@ -50,7 +50,7 @@ const normalActions = {
handler: async ({ email }) => {
const id = await queryUserId(email);
const hash = id === null ? encodedEmail(email) : `${id}`;
return { avatar: urlJoin(import.meta.env.SITE, 'avatar', `${hash}.webp`) };
return { avatar: urlJoin(import.meta.env.SITE, 'images/avatar', `${hash}.webp`) };
},
}),
};

View File

@ -18,7 +18,7 @@ const { comment, depth, pending } = Astro.props;
<div class="comment-avatar flex-avatar">
<img
alt={comment.nick}
src={urlJoin(import.meta.env.SITE, 'avatar', `${comment.user_id}.webp`)}
src={urlJoin(import.meta.env.SITE, 'images/avatar', `${comment.user_id}.webp`)}
class="avatar avatar-40 photo"
height="40"
width="40"

View File

@ -1,26 +1,11 @@
---
import { urlJoin } from '@/helpers/tools';
import options from '@/options';
import { DateTime } from 'luxon';
import sharp from 'sharp';
const loadCalendarImage = async (): Promise<string> => {
const now = DateTime.now().setZone(options.settings.timeZone);
const link = `https://img.owspace.com/Public/uploads/Download/${now.year}/${now.toFormat('LLdd')}.jpg`;
const response = await fetch(link, {
referrer: '',
});
if (!response.ok) {
console.error(`Failed to fetch image ${link}`);
return '';
}
const encodedImage = (
await sharp(await response.arrayBuffer())
.extract({ width: 1096, height: 1550, left: 90, top: 110 })
.toBuffer()
).toString('base64');
return `data:image/jpeg;base64,${encodedImage}`;
const now = DateTime.now().setZone(options.settings.timeZone).setLocale(options.settings.locale);
return urlJoin(import.meta.env.SITE, 'images/calendar', `${now.year}`, `${now.toFormat('LLdd')}.jpg`);
};
const calendarImage = !options.settings.sidebar.calendar ? '' : await loadCalendarImage();
@ -30,7 +15,7 @@ const calendarImage = !options.settings.sidebar.calendar ? '' : await loadCalend
calendarImage !== '' && (
<div class="widget widget-owspace-calendar">
<div class="widget-title">单向历</div>
<img src={calendarImage} />
<img loading="lazy" src={calendarImage} />
</div>
)
}

View File

@ -22,3 +22,7 @@ export const urlJoin = (base: string, ...paths: string[]): string => {
export const encodedEmail = (email: string): string =>
crypto.createHash('md5').update(email.trim().toLowerCase()).digest('hex');
export const isNumeric = (str: string): boolean => {
return /^-?\d+$/.test(str);
};

View File

@ -1,5 +1,5 @@
import { queryEmail } from '@/helpers/db/query';
import { encodedEmail, urlJoin } from '@/helpers/tools';
import { encodedEmail, isNumeric, urlJoin } from '@/helpers/tools';
import options from '@/options';
import type { APIRoute, ValidRedirectStatus } from 'astro';
@ -7,10 +7,6 @@ const defaultAvatar = (): string => {
return urlJoin(options.assetsPrefix(), '/images/default-avatar.png');
};
function isNumeric(str: string) {
return /^-?\d+$/.test(str);
}
const avatarImage = async (
hash: string,
redirect: (path: string, status?: ValidRedirectStatus) => Response,
@ -29,7 +25,7 @@ const avatarImage = async (
return new Response(Buffer.from(await resp.arrayBuffer()), {
headers: {
'Content-Type': 'image/webp',
'Cache-control': 'max-age=604800',
'Cache-Control': 'public, max-age=604800',
},
});
};

View File

@ -0,0 +1,36 @@
import type { APIRoute } from 'astro';
import sharp from 'sharp';
const loadCalendarImage = async (year: string, time: string): Promise<Response> => {
const link = `https://img.owspace.com/Public/uploads/Download/${year}/${time}.jpg`;
const response = await fetch(link, {
referrer: '',
});
if (!response.ok) {
console.error(`Failed to fetch image ${link}`);
return response;
}
const croppedImage = await sharp(await response.arrayBuffer())
.extract({ width: 1096, height: 1550, left: 90, top: 110 })
.toBuffer();
return new Response(croppedImage, {
headers: {
'Content-Type': 'image/jpeg',
'Cache-Control': 'public, max-age=604800',
},
});
};
const timeRegex = /\d{4}/;
export const GET: APIRoute = async ({ params, redirect }) => {
const { year, time } = params;
if (year === undefined || !timeRegex.test(year) || time === undefined || !timeRegex.test(time)) {
return redirect('/404');
}
return loadCalendarImage(year, time);
};