feat: move the generated images to a static like url endpoint.
This commit is contained in:
parent
7ad873c83c
commit
4aa0812342
@ -50,7 +50,7 @@ const normalActions = {
|
|||||||
handler: async ({ email }) => {
|
handler: async ({ email }) => {
|
||||||
const id = await queryUserId(email);
|
const id = await queryUserId(email);
|
||||||
const hash = id === null ? encodedEmail(email) : `${id}`;
|
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`) };
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@ const { comment, depth, pending } = Astro.props;
|
|||||||
<div class="comment-avatar flex-avatar">
|
<div class="comment-avatar flex-avatar">
|
||||||
<img
|
<img
|
||||||
alt={comment.nick}
|
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"
|
class="avatar avatar-40 photo"
|
||||||
height="40"
|
height="40"
|
||||||
width="40"
|
width="40"
|
||||||
|
@ -1,26 +1,11 @@
|
|||||||
---
|
---
|
||||||
|
import { urlJoin } from '@/helpers/tools';
|
||||||
import options from '@/options';
|
import options from '@/options';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import sharp from 'sharp';
|
|
||||||
|
|
||||||
const loadCalendarImage = async (): Promise<string> => {
|
const loadCalendarImage = async (): Promise<string> => {
|
||||||
const now = DateTime.now().setZone(options.settings.timeZone);
|
const now = DateTime.now().setZone(options.settings.timeZone).setLocale(options.settings.locale);
|
||||||
const link = `https://img.owspace.com/Public/uploads/Download/${now.year}/${now.toFormat('LLdd')}.jpg`;
|
return urlJoin(import.meta.env.SITE, 'images/calendar', `${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 calendarImage = !options.settings.sidebar.calendar ? '' : await loadCalendarImage();
|
const calendarImage = !options.settings.sidebar.calendar ? '' : await loadCalendarImage();
|
||||||
@ -30,7 +15,7 @@ const calendarImage = !options.settings.sidebar.calendar ? '' : await loadCalend
|
|||||||
calendarImage !== '' && (
|
calendarImage !== '' && (
|
||||||
<div class="widget widget-owspace-calendar">
|
<div class="widget widget-owspace-calendar">
|
||||||
<div class="widget-title">单向历</div>
|
<div class="widget-title">单向历</div>
|
||||||
<img src={calendarImage} />
|
<img loading="lazy" src={calendarImage} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -22,3 +22,7 @@ export const urlJoin = (base: string, ...paths: string[]): string => {
|
|||||||
|
|
||||||
export const encodedEmail = (email: string): string =>
|
export const encodedEmail = (email: string): string =>
|
||||||
crypto.createHash('md5').update(email.trim().toLowerCase()).digest('hex');
|
crypto.createHash('md5').update(email.trim().toLowerCase()).digest('hex');
|
||||||
|
|
||||||
|
export const isNumeric = (str: string): boolean => {
|
||||||
|
return /^-?\d+$/.test(str);
|
||||||
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { queryEmail } from '@/helpers/db/query';
|
import { queryEmail } from '@/helpers/db/query';
|
||||||
import { encodedEmail, urlJoin } from '@/helpers/tools';
|
import { encodedEmail, isNumeric, urlJoin } from '@/helpers/tools';
|
||||||
import options from '@/options';
|
import options from '@/options';
|
||||||
import type { APIRoute, ValidRedirectStatus } from 'astro';
|
import type { APIRoute, ValidRedirectStatus } from 'astro';
|
||||||
|
|
||||||
@ -7,10 +7,6 @@ const defaultAvatar = (): string => {
|
|||||||
return urlJoin(options.assetsPrefix(), '/images/default-avatar.png');
|
return urlJoin(options.assetsPrefix(), '/images/default-avatar.png');
|
||||||
};
|
};
|
||||||
|
|
||||||
function isNumeric(str: string) {
|
|
||||||
return /^-?\d+$/.test(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
const avatarImage = async (
|
const avatarImage = async (
|
||||||
hash: string,
|
hash: string,
|
||||||
redirect: (path: string, status?: ValidRedirectStatus) => Response,
|
redirect: (path: string, status?: ValidRedirectStatus) => Response,
|
||||||
@ -29,7 +25,7 @@ const avatarImage = async (
|
|||||||
return new Response(Buffer.from(await resp.arrayBuffer()), {
|
return new Response(Buffer.from(await resp.arrayBuffer()), {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'image/webp',
|
'Content-Type': 'image/webp',
|
||||||
'Cache-control': 'max-age=604800',
|
'Cache-Control': 'public, max-age=604800',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
36
src/pages/images/calendar/[year]/[time].jpg.ts
Normal file
36
src/pages/images/calendar/[year]/[time].jpg.ts
Normal 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);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user