Avatar

willthereader

24 public vals
Joined July 16, 2022
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/** @jsxImportSource https://esm.sh/hono@latest/jsx **/
import { Hono } from "npm:hono@3";
const app = new Hono();
app.get("/", (c) =>
c.html(
<html>
<head>
<title>Will Krouse</title>
<style
dangerouslySetInnerHTML={{
__html:
`:root{--slate1: hsl(200, 7%, 8.8%);--slate2: hsl(195, 7.1%, 11%);--slate3: hsl(197, 6.8%, 13.6%);--slate4: hsl(198, 6.6%, 15.8%);--slate5: hsl(199, 6.4%, 17.9%);--slate6: hsl(201, 6.2%, 20.5%);--slate7: hsl(203, 6%, 24.3%);--slate8: hsl(207,
}}
>
</style>
</head>
<body>
<h1>Will Krouse</h1>
<a href="https://twitter.com/Willthereader" target="_blank">Twitter</a>{" "}
<a href="https://github.com/wkrouse" target="_blank">Github</a>
<p>
Hi, I'm Will, a 24-year-old autistic individual in Florida. I love reading. I enjoy playing board games,
tennis, and pickleball.
</p>
<p>
I'm learning to code. My favorite part are the meta-skills. For example, the debugging mindset is always
useful for fixing problems.
</p>
<p>
I find the complexity of current events and politics really interesting. I enjoy articles that significantly
change my understanding. I really like{" "}
<a className="text-blue-500 hover:underline" href="https://www.readtangle.com">Tangle</a>{" "}
because it offers perspectives from all sides. I dislike when people assume the worst of their opponents and
when I can't tell who's right because no one addresses the best arguments from their opponents.
</p>
<p>
I am on the autism spectrum, so I sometimes misunderstand people's tones and vibes or send the wrong ones.
Your patience and feedback are appreciated!
</p>
<p>
I built{" "}
<a className="text-blue-500 hover:underline" href="https://www.val.town/v/willthereader/personalWebsite">
this site
</a>{" "}
on Val Town.
</p>
<h2>Projects</h2>
<div>
<div>
3/6/2024 -{" "}
<a href="https://news.ycombinator.com/item?id=39618062">
Bringing My OCD Online: Userscripts for Immersive Forum Browsing
</a>
</div>
</div>
<h2>Credit</h2>
<div>
<div>
<p>
I copied the formatting from{" "}
<a className="text-blue-500 hover:underline" href="https://vbud.dev/">Valjean Clark</a>{" "}
and was inspired by his design.
</p>
</div>
</div>
</body>
</html>,
));
app.get("/yeah", (c) => c.html("Routing!"));
export default app.fetch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Define a type for the results that will be fetched
type FeedResult = {
url: string;
isValid: boolean;
containsUsefulData: boolean; // Flag to check if the page contains specific useful data
};
// Extracts titles and generates URLs
function titleExtractor() {
const titleElements = document.querySelectorAll(".contentRow-title a[href*='threads/']");
const titles = Array.from(titleElements).map(anchor => anchor.href.trim());
// console.log("Extracted Titles:", titles); // Debugging log
return titles;
}
// Generates RSS feed links from a base URL
function urlGenerator(url: string) {
return [
`${url}threadmarks.rss?threadmark_category=13`,
`${url}threadmarks.rss?threadmark_category=16`,
];
}
// Utility function to delay execution
function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Verifies the validity of each feed URL by checking its contents
async function urlVerifier(feeds: string[]): Promise<string[]> {
const usefulUrls: string[] = [];
for (const feedUrl of feeds) {
try {
// Append a unique query parameter to bypass the cache
const cacheBustingUrl = `${feedUrl}&timestamp=${new Date().getTime()}`;
const response = await fetch(cacheBustingUrl, {
method: "GET",
headers: {
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0",
},
cache: "no-store", // Ensure no caching is involved
credentials: "omit",
redirect: "follow",
referrerPolicy: "no-referrer",
});
// Log detailed response headers for analysis
const headers: Record<string, string> = {};
response.headers.forEach((value, key) => {
headers[key] = value;
});
// console.log(`Response Headers for URL: ${feedUrl}`, JSON.stringify(headers));
if (!response.ok) {
console.error(`Failed to fetch URL: ${feedUrl} - Status: ${response.status}`);
continue;
}
const text = await response.text();
if (text.includes("threadmark_category=")) {
usefulUrls.push(feedUrl);
}
} catch (error) {
console.error(`Error fetching URL: ${feedUrl}`, error);
}
// Add a 1-second delay between requests
await delay(1000);
}
return usefulUrls;
}
async function fetchAndExtractWordCount(rssUrls: string[]): Promise<number[]> {
const results = await Promise.all(rssUrls.map(async (url) => {
try {
console.log(`Fetching URL: ${url}`);
const response = await fetch(url);
const xmlText = await response.text();
console.log(`Fetched XML for ${url}: ${xmlText}`);
const parser = new DOMParser();
const doc = parser.parseFromString(xmlText, "application/xml");
console.log(`Parsed Document for ${url}:`, doc);
// Log the entire document structure for detailed inspection
console.log(`Document Structure for ${url}:`, new XMLSerializer().serializeToString(doc));
// Attempt to get the 'words' elements with different methods
let wordsElements = doc.getElementsByTagName("words");
if (wordsElements.length === 0) {
wordsElements = doc.getElementsByTagNameNS("*", "words");
}
let totalWords = 0;
if (wordsElements.length > 0) {
for (let i = 0; i < wordsElements.length; i++) {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/** @jsxImportSource https://esm.sh/hono@latest/jsx **/
import { Hono } from "npm:hono@3";
const app = new Hono();
app.get("/", (c) =>
c.html(
<html>
<head>
<title>Will Krouse</title>
<style
dangerouslySetInnerHTML={{
__html:
`:root{--slate1: hsl(200, 7%, 8.8%);--slate2: hsl(195, 7.1%, 11%);--slate3: hsl(197, 6.8%, 13.6%);--slate4: hsl(198, 6.6%, 15.8%);--slate5: hsl(199, 6.4%, 17.9%);--slate6: hsl(201, 6.2%, 20.5%);--slate7: hsl(203, 6%, 24.3%);--slate8: hsl(207,
}}
>
</style>
</head>
<body>
<h1>Will Krouse</h1>
<a href="https://twitter.com/Willthereader" target="_blank">Twitter</a>{" "}
<a href="https://github.com/wkrouse" target="_blank">Github</a>
<p>
Hi, I'm Will, a 24-year-old autistic individual in Florida. I love reading. I enjoy playing board games,
tennis, and pickleball.
</p>
<p>
I'm learning to code. My favorite part are the meta-skills. For example, the debugging mindset is always
useful for fixing problems.
</p>
<p>
I find the complexity of current events and politics really interesting. I enjoy articles that significantly
change my understanding. I really like{" "}
<a className="text-blue-500 hover:underline" href="https://www.readtangle.com">Tangle</a>{" "}
because it offers perspectives from all sides. I dislike when people assume the worst of their opponents and
when I can't tell who's right because no one addresses the best arguments from their opponents.
</p>
<p>
I am on the autism spectrum, so I sometimes misunderstand people's tones and vibes or send the wrong ones.
Your patience and feedback are appreciated!
</p>
<p>
I built{" "}
<a className="text-blue-500 hover:underline" href="https://www.val.town/v/willthereader/personalWebsite">
this site
</a>{" "}
on Val Town.
</p>
<h2>Projects</h2>
<div>
<div>
3/6/2024 -{" "}
<a href="https://news.ycombinator.com/item?id=39618062">
Bringing My OCD Online: Userscripts for Immersive Forum Browsing
</a>
</div>
</div>
<h2>Credit</h2>
<div>
<div>
<p>
I copied the formatting from{" "}
<a className="text-blue-500 hover:underline" href="https://vbud.dev/">Valjean Clark</a>{" "}
and was inspired by his design.
</p>
</div>
</div>
</body>
</html>,
));
app.get("/yeah", (c) => c.html("Routing!"));
export default app.fetch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/** @jsxImportSource https://esm.sh/react */
import { renderToString } from 'npm:react-dom/server';
export const testWebsite = (request: Request) => {
// convert to Response
return new Response(renderToString(
<html>
<head>
<title>Page Title</title>
</head>
<body>
<span style={{ color: "red" }}>H</span> <span style={{ color: "blue" }}>e</span>{" "}
<span style={{ color: "green" }}>l</span> <span style={{ color: "red" }}>l</span>{" "}
<span style={{ color: "green" }}>o</span>
</body>
</html>), {
headers: { 'Content-Type': 'text/html' }
}
);
};

Returning HTML from the Val Town Web API

This just lets you use the standard Response object with our Web API to return an HTML response from this Val.

1
2
3
4
5
6
export const htmlExample = () =>
new Response("<h1>Hello, world</h1>", {
headers: {
"Content-Type": "text/html",
},
});

Response.json Example

This val produces the JSON { ok: true } at the URL: https://tmcw-jsonokexample.web.val.run/

1
export const jsonOkExample = () => Response.json({ ok: true });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { constructReadTangleUrl } from "https://esm.town/v/willthereader/constructReadTangleUrl";
import { fetchComments } from "https://esm.town/v/willthereader/fetchComments";
import { FilterCommentsVal } from "https://esm.town/v/willthereader/FilterCommentsVal";
import { formattingEmailContent } from "https://esm.town/v/willthereader/formattingEmailContent";
import { logMessage } from "https://esm.town/v/willthereader/logMessage";
import { post_idFetcher } from "https://esm.town/v/willthereader/post_idFetcher";
export async function Sendingemail() {
// console.log("Sendingemail function called");
try {
let lastRunDate = new Date("2023-11-10T19:27:25.547Z");
lastRunDate = new Date();
const post_ids = await post_idFetcher();
// console.log("post_ids: ", post_ids);
const firstTwoPost_ids = post_ids.slice(2, 3);
const ReadTangleUrl = await Promise.all(firstTwoPost_ids.map(constructReadTangleUrl));
// console.log("ReadTangleUrl: ", ReadTangleUrl);
// return ReadTangleUrl;
const Comments = await fetchComments(ReadTangleUrl);
// console.log("Comments: ", Comments);
return Comments;
// const formatedEmailContent = formattingEmailContent(Comments)
} catch (error) {
console.log("Caught an error:", error);
}
}
const urls = await Sendingemail();
// console.log(typeof urls);
console.log(urls);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { email } from "https://esm.town/v/std/email?v=9";
import { set } from "https://esm.town/v/std/set?v=11";
import { inkAndSwitchRssUrl } from "https://esm.town/v/stevekrouse/inkAndSwitchRssUrl";
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems";
import { pollRSSInkAndSwitch } from "https://esm.town/v/stevekrouse/pollRSSInkAndSwitch";
export async function pollRSSFeeds2() {
let items = await newRSSItems({
url: inkAndSwitchRssUrl,
lastRunAt: pollRSSInkAndSwitch,
});
if (items.length)
await email({
text: JSON.stringify(items, null, 2),
subject: `New RSS Item`,
});
return set("pollRSSInkAndSwitch", Date.now());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { untitled_blackCrayfish } from "https://esm.town/v/stevekrouse/untitled_blackCrayfish?v=1";
async function processFeed() {
let rssData = await untitled_blackCrayfish; // Line 1
console.log("Keys of rssData.rss:", Object.keys(rssData.rss)); // Log the keys of rssData.rss
// console.log("Keys of rssData.rss.channel:", Object.keys(rssData.rss.channel)); // Log the keys of rssData.rss.channel
// console.log("First item:", rssData.rss.channel.item[0]); // Log the first item
for (let item of rssData.rss.channel.item) {
console.log("link:", item.link);
}
let links = []; // Line 2
for (let i = 0; i < rssData.length; i++) { // Line 3
console.log(rssData[i]); // Add this line
if (rssData[i].link) { // Check if the item has a link property
console.log(rssData[i]); // Add this line
links.push(rssData[i].link); // If it does, push it into the links array
}
}
return links; // Line 5
}
processFeed().then(output => console.log(output)); // Call the function and print the output to the console
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// set by stevekrouse.testEmail2 at 2023-08-15T02:54:53.895Z
export let testEmails = [{
"from": "Steve Krouse <steve@val.town>",
"to": ["stevekrouse.testEmail@valtown.email"],
"subject": "Test 1",
"text": "It works yo!\r\n",
"html": "<div dir=\"ltr\">It works yo!</div>\r\n"
}, {
"from": "~redacted~",
"to": ["stevekrouse.testEmail@valtown.email"],
"subject": "hey!",
"text": "\r\n",
"html": "<div dir=\"ltr\"><br></div>\r\n"
}, {
"from": "~redacted~",
"to": ["stevekrouse.testEmail2@valtown.email"],
"subject": "Great Work with Val.Town",
"text": "Steve!\r\n\r\nJust wanted to drop you a note and tell you I love what you're doing with\r\nval.town and think it's going to be super impactful!\r\n\r\nGood luck!\r\n\r\n-Elijah\r\n",
"html": "<div dir=\"ltr\">Steve!<div><br></div><div>Just wanted to drop you a note and tell you I love what you&#39;re doing with val.town and think it&#39;s going to be super impactful!</div><div><br></div><div>Good luck!</div><div><br></div><div>-Elija
}, {
"from": "~redacted~",
"to": ["stevekrouse.testEmail2@valtown.email"],
"subject": "Howdy",
"text": "🤠\r\n",
"html": "<div dir=\"auto\">🤠</div>\r\n"
}, {
"from": "~redacted~",
"to": ["stevekrouse.testEmail2@valtown.email"],
"subject": "testing????",
"text": "-- \r\nhttp://arjun.is\r\n",
"html": "<div dir=\"ltr\"><br clear=\"all\"><div><br></div><span class=\"gmail_signature_prefix\">-- </span><br><div dir=\"ltr\" class=\"gmail_signature\" data-smartmail=\"gmail_signature\"><div dir=\"ltr\"><div><a href=\"http://arjun.is\" target=\"_blan
}, {
"from": "~redacted~",
"to": ["stevekrouse.testEmail2@valtown.email"],
"subject": "Fwd: Test",
"text": "Test!\r\n\r\n---------- Forwarded message ---------\r\nFrom: Steve Krouse <steve@val.town>\r\nDate: Mon, Aug 14, 2023, 10:54 PM\r\nSubject: Test\r\nTo: Steve Krouse <steve@val.town>\r\n",
"html": "<div dir=\"auto\">Test!</div><br><div class=\"gmail_quote\"><div dir=\"ltr\" class=\"gmail_attr\">---------- Forwarded message ---------<br>From: <strong class=\"gmail_sendername\" dir=\"auto\">Steve Krouse</strong> <span dir=\"auto\">&lt;steve@
}];