1import { createTidbytWorkoutsImage } from "https://esm.town/v/andreterron/createTidbytWorkoutsImage";
2import { setTidbytImage } from "https://esm.town/v/andreterron/setTidbytImage";
3import { weekWorkoutIcons } from "https://esm.town/v/andreterron/weekWorkoutIcons";
4import { workedOutByDay } from "https://esm.town/v/andreterron/workedOutByDay";
18 const icons = weekWorkoutIcons(byDay, timezone);
19
20 // Don't update the image if it didn't change
21 let iconsCache: string[] | undefined;
22 try {
31 }
32
33 // img is the resulting jimp image
34 const img = await createTidbytWorkoutsImage(icons);
35
36 // Send the image to Tidbyt
37 await setTidbytImage({
38 image: (await img.getBufferAsync(img.getMIME())).toString("base64"),
39 });
40};
15 );
16 const code = await res.text();
17 const imageURL = await createScreenshot(code, query.theme);
18 return c.redirect(imageURL.href);
19});
20
22
23export async function createScreenshot(code: string, theme: string = "dark-plus"): Promise<URL> {
24 const apiUrl = "https://sourcecodeshots.com/api/image/permalink";
25 const { url } = await ky.post(apiUrl, {
26 json: {
1
2
3**You know how when you paste a URL in `Twitter` or `Slack` it shows you a nice preview?** This val gives you that data.
4Given a URL, this will return metadata about the website like `title`, `description`, `imageURL`, `image as base64` etc.
5
6**Sample input - paste this in your URL bar**
18 description: "Davis' not-so-secret stash",
19 imgUrl: "https://www.dvsj.in/cover-picture.png",
20 imgData: "data:image/png;base64,qwertyblahblah"
21}
22```
24**FAQ:**
25Why is `imgData` sent when `imgUrl` is already present?
26Because you shouldn't hotlink images from 3rd parties. Store the base64 image on your server and use it in your app.
27It's unfair to use their server bandwidth and could be a security issue for you if they change the content of the link later.
22### Pushover notifications
23
24
25
26
3View and interact with your Val Town SQLite data. It's based off Steve's excellent [SQLite Admin](https://www.val.town/v/stevekrouse/sqlite_admin?v=46) val, adding the ability to run SQLite queries directly in the interface. This new version has a revised UI and that's heavily inspired by [LibSQL Studio](https://github.com/invisal/libsql-studio) by [invisal](https://github.com/invisal). This is now more an SPA, with tables, queries and results showing up on the same page.
4
5
6
7## Install
23```
24
25## Images
26
27To send an image to ChatGPT, the easiest way is by converting it to a
28data URL, which is easiest to do with [@stevekrouse/fileToDataURL](https://www.val.town/v/stevekrouse/fileToDataURL).
29
30```ts title="Image Example" val
31import { fileToDataURL } from "https://esm.town/v/stevekrouse/fileToDataURL";
32
44 role: "user",
45 content: [{
46 type: "image_url",
47 image_url: {
48 url: dataURL,
49 },
6const app = new Hono();
7
8async function renderImage(s: string, color: string) {
9 const fontArrayBuf = await fetch(
10 "https://cdn.jsdelivr.net/npm/roboto-font@0.1.0/fonts/Roboto/roboto-regular-webfont.ttf",
70 }
71 }
72 return c.body(await renderImage(text, color), 200, { "Content-Type": "image/png" });
73});
74
78 <meta property="fc:frame" content="vNext" />
79 <meta
80 property="fc:frame:image"
81 content="https://nlnw-frame.web.val.run/satori"
82 />
97 <meta property="fc:frame" content="vNext" />
98 <meta
99 property="fc:frame:image"
100 content={`https://nlnw-frame.web.val.run/satori?button=${buttonIndex}`}
101 />
1Minimal val.town Farcaster Frame example. It supports dynamic image generation with Satori and ReSVG, and it's compatible with the Open Frames standard.
4
5async function createScreenshot(code: string) {
6 const apiUrl = "https://sourcecodeshots.com/api/image";
7 const resp = await fetch(apiUrl, {
8 method: "POST",
107 return new Response(screenshot, {
108 headers: {
109 "Content-Type": "image/png",
110 },
111 });
1# Inspector to browser json data in HTTP vals
2
3
4
5Live example: https://stevekrouse-weatherdescription.web.val.run/