This commit is contained in:
@@ -1,19 +1,11 @@
|
|||||||
import { rgbaToThumbHash } from "thumbhash";
|
import { rgbaToThumbHash } from "thumbhash";
|
||||||
import ExifReader from 'exifreader';
|
import ExifReader from "exifreader";
|
||||||
import type { ImageMetadata } from "astro";
|
import type { ImageMetadata } from "astro";
|
||||||
|
import sharp from "sharp";
|
||||||
|
|
||||||
let s: typeof import("sharp") | undefined;
|
export async function generateThumbHash(
|
||||||
async function getSharp(): Promise<typeof import("sharp") | undefined> {
|
image: ImageMetadata & { fsPath?: string },
|
||||||
if (s) return s;
|
) {
|
||||||
s = (await import("sharp")).default;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateThumbHash(image: ImageMetadata & { fsPath?: string }) {
|
|
||||||
|
|
||||||
const sharp = await getSharp();
|
|
||||||
if (!sharp) return;
|
|
||||||
|
|
||||||
const scaleFactor = 100 / Math.max(image.width, image.height);
|
const scaleFactor = 100 / Math.max(image.width, image.height);
|
||||||
|
|
||||||
const smallWidth = Math.floor(image.width * scaleFactor);
|
const smallWidth = Math.floor(image.width * scaleFactor);
|
||||||
@@ -30,10 +22,9 @@ export async function generateThumbHash(image: ImageMetadata & { fsPath?: string
|
|||||||
const buffer = rgbaToThumbHash(smallWidth, smallHeight, smallImg);
|
const buffer = rgbaToThumbHash(smallWidth, smallHeight, smallImg);
|
||||||
return Buffer.from(buffer).toString("base64");
|
return Buffer.from(buffer).toString("base64");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`Could not generate thumbhash for ${image.fsPath}`, error)
|
console.log(`Could not generate thumbhash for ${image.fsPath}`, error);
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const allowedExif = [
|
const allowedExif = [
|
||||||
@@ -54,11 +45,8 @@ const allowedExif = [
|
|||||||
|
|
||||||
export async function getExifData(image: ImageMetadata) {
|
export async function getExifData(image: ImageMetadata) {
|
||||||
if (image.format === "svg") return undefined; // SVGs don't have EXIF data")
|
if (image.format === "svg") return undefined; // SVGs don't have EXIF data")
|
||||||
const sharp = await getSharp();
|
|
||||||
if (!sharp) return;
|
|
||||||
const imagePath = (image as ImageMetadata & { fsPath: string }).fsPath;
|
const imagePath = (image as ImageMetadata & { fsPath: string }).fsPath;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const buffer = await sharp(imagePath).toBuffer();
|
const buffer = await sharp(imagePath).toBuffer();
|
||||||
|
|
||||||
const tags = await ExifReader.load(buffer, { async: true });
|
const tags = await ExifReader.load(buffer, { async: true });
|
||||||
@@ -74,9 +62,7 @@ export async function getExifData(image: ImageMetadata) {
|
|||||||
|
|
||||||
return hasExif ? out : undefined;
|
return hasExif ? out : undefined;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
console.log(`Error reading EXIF data from ${imagePath}`, error);
|
console.log(`Error reading EXIF data from ${imagePath}`, error);
|
||||||
return undefined
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
import MarkdownIt from 'markdown-it';
|
import MarkdownIt from "markdown-it";
|
||||||
const parser = new MarkdownIt();
|
const parser = new MarkdownIt();
|
||||||
|
|
||||||
export default function markdownToText(markdown: string): string {
|
export default function markdownToText(markdown: string = "<empty>"): string {
|
||||||
return parser
|
return parser
|
||||||
.render(markdown)
|
.render(markdown)
|
||||||
.split('\n')
|
.split("\n")
|
||||||
.map((str) => str.trim())
|
.map((str) => str.trim())
|
||||||
.map((str) => {
|
.map((str) => {
|
||||||
return str.replace(/<\/?[^>]+(>|$)/g, '').split('\n');
|
return str.replace(/<\/?[^>]+(>|$)/g, "").split("\n");
|
||||||
})
|
})
|
||||||
.flat()
|
.flat()
|
||||||
.filter((str) => !str.startsWith("import")
|
.filter((str) =>
|
||||||
&& !str.startsWith("export")
|
!str.startsWith("import") &&
|
||||||
&& !str.startsWith("#")
|
!str.startsWith("export") &&
|
||||||
&& !str.startsWith("const")
|
!str.startsWith("#") &&
|
||||||
&& !str.startsWith("function")
|
!str.startsWith("const") &&
|
||||||
&& !str.startsWith("export")
|
!str.startsWith("function") &&
|
||||||
&& !str.startsWith("import")
|
!str.startsWith("export") &&
|
||||||
&& !str.startsWith("<")
|
!str.startsWith("import") &&
|
||||||
&& !str.startsWith("let")
|
!str.startsWith("<") &&
|
||||||
&& str.length > 0
|
!str.startsWith("let") &&
|
||||||
|
str.length > 0
|
||||||
)
|
)
|
||||||
.join(' ');
|
.join(" ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ export async function listResource(
|
|||||||
}
|
}
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
console.log("Failed to get: ", url);
|
console.log("Failed to get: ", url);
|
||||||
console.log(_e);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ export async function getStaticPaths() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return paths.flat().filter(Boolean);
|
return paths.flat().filter(Boolean);
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const resource = await memorium.listResource(
|
const resource = await memorium.listResource(
|
||||||
`/${resourceType}/${resourceName}.md`,
|
`${resourceType}/${resourceName}.md`,
|
||||||
);
|
);
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ const resource = await memorium.listResource(
|
|||||||
<h2>Ingredients</h2>
|
<h2>Ingredients</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{
|
{
|
||||||
resource.content.recipeIngredient.map((ingredient) => (
|
resource?.content.recipeIngredient.map((ingredient) => (
|
||||||
<li>{markdownToText(ingredient)}</li>
|
<li>{markdownToText(ingredient)}</li>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ const resource = await memorium.listResource(
|
|||||||
<h2>Steps</h2>
|
<h2>Steps</h2>
|
||||||
<ol>
|
<ol>
|
||||||
{
|
{
|
||||||
resource.content.recipeInstructions.map((ingredient) => (
|
resource?.content.recipeInstructions.map((ingredient) => (
|
||||||
<li>{markdownToText(ingredient)}</li>
|
<li>{markdownToText(ingredient)}</li>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,15 @@ import { resources as resourceTypes } from "../resources.ts";
|
|||||||
|
|
||||||
const { resourceType } = Astro.params;
|
const { resourceType } = Astro.params;
|
||||||
|
|
||||||
const resources = await memorium.listResource(resourceType);
|
async function safeGetResource(resType) {
|
||||||
|
try {
|
||||||
|
return await memorium.listResource(resourceType);
|
||||||
|
} catch (error) {
|
||||||
|
return {content:[]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const resources = await safeGetResource(resourceType);
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return resourceTypes.map((type: any) => {
|
return resourceTypes.map((type: any) => {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ const collection = "resources";
|
|||||||
type Resource = {
|
type Resource = {
|
||||||
id: string;
|
id: string;
|
||||||
collection: string;
|
collection: string;
|
||||||
body: string;
|
|
||||||
data: {
|
data: {
|
||||||
title: string;
|
title: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
@@ -31,9 +30,8 @@ type Resource = {
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
const recipes = {
|
const recipes = {
|
||||||
id: "Recipes",
|
id: "recipes",
|
||||||
collection,
|
collection,
|
||||||
body: "Recipes",
|
|
||||||
data: {
|
data: {
|
||||||
title: "Recipes",
|
title: "Recipes",
|
||||||
icon: "🍲",
|
icon: "🍲",
|
||||||
|
|||||||
Reference in New Issue
Block a user