122app.notFound((c) => c.render(<NotFoundPage />));
123
124export default app.fetch;
1## Detect New Website Contents
2
3This val fetches a given publicly-accessible URL and detects whether its contents have changed. If they have, it sends an email to notify about the change.
4
5Changes are detected by computing a quick hash of the website's contents, storing the hash, and comparing against the previously stored hash on each request. Trivial changes to the website's contents will count as a change, which may not be desired for some use cases.
8
9export const detectNewWebsiteContents = async () => {
10 // Fetch contents
11 let contents;
12 try {
13 const res = await fetch(URL, { redirect: "follow" });
14 if (res.status !== 200) {
15 console.log(`bad status code: ${res.status}`);
17 contents = await res.text();
18 } catch (e) {
19 console.log(`couldn't fetch: ${e}`);
20 }
21
1import { email } from "https://esm.town/v/std/email";
2import { fetchText } from "https://esm.town/v/stevekrouse/fetchText?v=6";
3import { load } from "npm:cheerio";
4
5export default async (interval: Interval) => {
6 const html = await fetchText(Deno.env.get("rubbish_url"));
7 const $ = load(html);
8 const containers = $(".bin-collection-container");
1/** @jsxImportSource https://esm.sh/hono@latest/jsx **/
2
3import { modifyFetchHandler } from "https://esm.town/v/andreterron/codeOnValTown?v=50";
4import { iframeHandler } from "https://esm.town/v/nbbaier/iframeHandler";
5import { resetStyle } from "https://esm.town/v/nbbaier/resetStyle";
16import { verifyToken } from "https://esm.town/v/pomdtr/verifyToken";
17import { ResultSet, sqlite } from "https://esm.town/v/std/sqlite";
18import { reloadOnSaveFetchMiddleware } from "https://esm.town/v/stevekrouse/reloadOnSave";
19import { Hono } from "npm:hono";
20import type { FC } from "npm:hono/jsx";
175});
176
177export const handler = app.fetch;
178export default iframeHandler(modifyFetchHandler(passwordAuth(handler, { verifyPassword: verifyToken })));
90 prompt = document.getElementById("svgInput").value;
91 }
92 let resp = await fetch("/remix/" + id, { method: "POST", body: JSON.stringify({ prompt }) });
93 const reader = resp.body.getReader();
94 const decoder = new TextDecoder();
139 const buttonContainer = button.closest(".heart-button-container");
140 const buttonRect = button.getBoundingClientRect();
141 fetch(`/${button.attributes["data-id"].value}/heart`, { method: "POST" });
142 for (let i = 0; i < 10; i++) {
143 const heart = document.createElement("div");
516 return c.text("OK");
517});
518export default app.fetch;
144 });
145
146 for await (const event of fetchEventSource(req)) {
147 console.log(event);
148 }
149}
150
151async function* fetchEventSource(request: Request) {
152 const response = await fetch(request);
153 console.log(response.status, response.statusText);
154 if (!response.ok) {
83 console.log('Access token received');
84
85 async function fetchPlaylists() {
86 try {
87 const response = await axios.get('https://api.spotify.com/v1/me/playlists', {
94 const playlistEl = document.createElement('div');
95 playlistEl.className = 'bg-gray-800 rounded-lg p-4 mb-4 flex items-center cursor-pointer hover:bg-gray-700 transition-colors duration-300';
96 playlistEl.onclick = () => fetchTracks(playlist.id, playlist.name);
97 const imageUrl = playlist.images && playlist.images.length > 0 ? playlist.images[0].url : 'https://via.placeholder.com/60';
98 playlistEl.innerHTML = \`
106 });
107 } catch (error) {
108 console.error('Error fetching playlists:', error);
109 document.getElementById('error').textContent = 'Error fetching playlists: ' + error.message;
110 }
111 }
112
113 async function fetchTracks(playlistId, playlistName) {
114 try {
115 const response = await axios.get(\`https://api.spotify.com/v1/playlists/\${playlistId}/tracks\`, {
143 tracksDiv.scrollIntoView({ behavior: 'smooth' });
144 } catch (error) {
145 console.error('Error fetching tracks:', error);
146 document.getElementById('error').textContent = 'Error fetching tracks: ' + error.message;
147 }
148 }
149
150 fetchPlaylists();
151 }
152 </script>
165});
166
167export default app.fetch;
1// This val fetches the 10 most recent Mastodon posts using the Mastodon API.
2// It requires a Mastodon access token stored in the MASTODON_TOKEN environment variable.
3
33 }));
34
35 console.log(`Fetched ${posts.length} Mastodon posts`);
36
37 return Response.json(posts);
38 } catch (error) {
39 console.error("Error fetching Mastodon posts:", error);
40
41 let errorMessage = "An error occurred while fetching Mastodon posts";
42 if (axios.isAxiosError(error)) {
43 if (error.response) {
31 }));
32
33 console.log(`Fetched ${bookmarks.length} bookmarks`);
34
35 return Response.json(bookmarks);
36 } catch (error) {
37 console.error("Error fetching bookmarks:", error);
38
39 let errorMessage = "An error occurred while fetching bookmarks";
40 if (axios.isAxiosError(error)) {
41 if (error.response) {