1// This tool uses the DBpedia Lookup API and SPARQL endpoint to find entities and their details, including images.
2// It provides a web interface and a JSON API endpoint for entity search, including hero images.
3
4// Helper function to strip HTML tags and decode HTML entities
73 "div",
74 { key: index, className: "border-b border-gray-200 pb-4 last:border-b-0 flex" },
75 result.image && React.createElement(
76 "div",
77 { className: "mr-4 flex-shrink-0" },
78 React.createElement("img", {
79 src: result.image,
80 alt: result.label,
81 className: "w-32 h-32 object-cover rounded"
134 const uri = doc.resource[0];
135 const sparqlQuery = `
136 SELECT ?abstract ?image
137 WHERE {
138 <${uri}> dbo:abstract ?abstract .
139 OPTIONAL { <${uri}> dbo:thumbnail ?image }
140 FILTER (lang(?abstract) = "en")
141 }
154 label: sanitizeHtml(doc.label[0]),
155 description: bindings?.abstract?.value ? sanitizeHtml(bindings.abstract.value) : "No description available",
156 image: bindings?.image?.value || null,
157 };
158 }));
1An API and basic interface for entity searching from DBPedia, enhanced with images
62 "User-Agent":
63 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
64 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
65 "Accept-Language": "en-US,en;q=0.5",
66 "Sec-Fetch-Site": "cross-site",
6const subreddits = ["IdiotsInCars"];
7
8const fetchWithImage = async (subreddit: string) => {
9 const { data: { children } } = await fetchJSON(
10 `https://www.reddit.com/r/${subreddit}.json`,
13 const posts = children
14 .map((child: any) => child.data)
15 .filter((post: any) => post.post_hint === "image")
16 .map((post: any) => ({
17 title: post.title,
25
26const fetchAllReddits = async () => {
27 const posts = (await Promise.all(subreddits.map(fetchWithImage))).flat();
28 return posts;
29};
30
31function ImageGrid({ posts }) {
32 return (
33 <div className="image-grid">
34 {posts.map((post, index) => (
35 <div key={index} className="image-item">
36 <img src={post.url} alt={post.title} />
37 </div>
51 return (
52 <div>
53 <ImageGrid posts={posts} />
54 </div>
55 );
93body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f0f0f0; }
94h1 { text-align: center; color: #333; }
95.image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; }
96.image-item { position: relative; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 8px rgba(0,0,0,0.1); transition: transform 0.3s ease; }
97.image-item:hover { transform: scale(1.05); }
98.image-item img { width: 100%; height: 250px; object-fit: cover; display: block; }
99`;
1Migrated from folder: ExamplesAndForks/redditImageGrab
6const subreddits = ["Battletops", "AverageBattlestations", "desksetup"];
7
8const fetchWithImage = async (subreddit: string) => {
9 const { data: { children } } = await fetchJSON(
10 `https://www.reddit.com/r/${subreddit}.json`,
13 const posts = children
14 .map((child: any) => child.data)
15 .filter((post: any) => post.post_hint === "image")
16 .map((post: any) => ({
17 title: post.title,
25
26const fetchAllReddits = async () => {
27 const posts = (await Promise.all(subreddits.map(fetchWithImage))).flat();
28 return posts;
29};
30
31function ImageGrid({ posts }) {
32 return (
33 <div className="image-grid">
34 {posts.map((post, index) => (
35 <div key={index} className="image-item">
36 <img src={post.url} alt={post.title} />
37 </div>
51 return (
52 <div>
53 <ImageGrid posts={posts} />
54 </div>
55 );
93body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f0f0f0; }
94h1 { text-align: center; color: #333; }
95.image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; }
96.image-item { position: relative; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 8px rgba(0,0,0,0.1); transition: transform 0.3s ease; }
97.image-item:hover { transform: scale(1.05); }
98.image-item img { width: 100%; height: 250px; object-fit: cover; display: block; }
99`;
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
3This Todo App is server rendered *and* client-hydrated React. This architecture is a lightweight alternative to NextJS, RemixJS, or other React metaframeworks with no compile or build step. The data is saved server-side in [Val Town SQLite](https://docs.val.town/std/sqlite/).
4
5
6
7## SSR React Mini Framework
3This is a lightweight Blob Admin interface to view and debug your Blob data.
4
5
6
7Use this button to install the val:
6 const url = new URL(req.url)
7 // console.log("url:", url)
8 const isImage = url.pathname.endsWith("/image")
9
10 if (isImage) {
11 const imageUrl = "https://charlypoly-httpapiscreenshotpageexample.web.val.run/?url=" + url.origin
12 // return Response.redirect(imageUrl, 302)
13 const res = await fetch(imageUrl)
14 const blob = await res.blob()
15 return new Response(blob, { headers: { "Content-Type": "image/png" } })
16 }
17
20 const baseUrl = url.origin
21 const homeFrame = {
22 image: `/${randomPostfix}/image`,
23 aspectRatio: "1:1",
24 buttons: [
31 <head>
32 <title>${title}</title>
33 <meta property="og:image" content="${url.origin}/${randomPostfix}/image" />
34 <meta property="og:image:width" content="800" />
35 <meta property="og:image:height" content="800" />
36 <meta name="twitter:card" content="summary_large_image" />
37 ${frameHtml(homeFrame, baseUrl)}
38 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.10.0/p5.min.js" integrity="sha512-lvddmeF7aHRJwdbJeYThWd5kWSjTrXBzCRF/jYROiHzmhMJ1dEXfGH5Q7ft0yhizXTopAETG03s5ajTflauijA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>