2
3// Enhanced data extraction for individual books
4export async function enhanceBookData(book: Book): Promise<Book> {
5 try {
6 // Extract ASIN from product URL
26}
27
28async function fetchProductDetails(asin: string): Promise<Partial<Book>> {
29 try {
30 const url = `https://www.amazon.com/dp/${asin}`;
55}
56
57function extractAuthorFromProductPage(html: string): string | undefined {
58 const selectors = [
59 /<span[^>]*class="[^"]*author[^"]*"[^>]*>.*?<a[^>]*>([^<]+)<\/a>/i,
76}
77
78function extractPriceFromProductPage(html: string): string | undefined {
79 const selectors = [
80 /<span[^>]*class="[^"]*a-price-whole[^"]*"[^>]*>([^<]+)<\/span>/,
98}
99
100function extractRatingFromProductPage(html: string): number | undefined {
101 const selectors = [
102 /(\d+\.?\d*)\s*out\s*of\s*5\s*stars/i,
118}
119
120function extractReviewCountFromProductPage(html: string): number | undefined {
121 const selectors = [
122 /([\d,]+)\s*customer\s*reviews?/i,
138}
139
140function cleanText(text: string): string {
141 return text
142 .replace(/<[^>]*>/g, '')
8}
9
10function App() {
11 const [books, setBooks] = useState<BookHistory[]>([]);
12 const [loading, setLoading] = useState(false);
3import type { Book, BookHistory } from "../../shared/types.ts";
4
5export async function saveBooks(books: Book[]): Promise<void> {
6 const timestamp = new Date().toISOString();
7
25}
26
27export async function getLatestBooks(): Promise<BookHistory[]> {
28 const result = await sqlite.execute(
29 `SELECT * FROM ${TABLE_NAME}
46}
47
48export async function getBooksHistory(days: number = 30): Promise<BookHistory[]> {
49 const result = await sqlite.execute(
50 `SELECT * FROM ${TABLE_NAME}
67}
68
69export async function getScrapingDates(): Promise<string[]> {
70 const result = await sqlite.execute(
71 `SELECT DISTINCT scraped_at FROM ${TABLE_NAME} ORDER BY scraped_at DESC LIMIT 30`
3const TABLE_NAME = 'amazon_books_v1';
4
5export async function initializeDatabase() {
6 // Create the main books table
7 await sqlite.execute(`CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
2import { useState } from "https://esm.sh/react@18.2.0";
3
4export function App() {
5 const [clicked, setClicked] = useState(0);
6 return (
10}
11
12export default function App() {
13 const [todos, setTodos] = useState<Todo[]>([]);
14 const [newTodoText, setNewTodoText] = useState("");
9}
10
11export default function TodoItem({ todo, onUpdate, onDelete }: TodoItemProps) {
12 const [isEditing, setIsEditing] = useState(false);
13 const [editText, setEditText] = useState(todo.text);
3import type { Todo, CreateTodoRequest, UpdateTodoRequest } from "../../shared/types.ts";
4
5export async function getAllTodos(): Promise<Todo[]> {
6 const result = await sqlite.execute(`
7 SELECT id, text, completed, created_at
18}
19
20export async function createTodo(data: CreateTodoRequest): Promise<Todo> {
21 const result = await sqlite.execute(`
22 INSERT INTO ${TABLE_NAME} (text)
34}
35
36export async function updateTodo(id: number, data: UpdateTodoRequest): Promise<Todo | null> {
37 const updates: string[] = [];
38 const values: any[] = [];
74}
75
76export async function deleteTodo(id: number): Promise<boolean> {
77 const result = await sqlite.execute(`
78 DELETE FROM ${TABLE_NAME}
3export const TABLE_NAME = 'todos_v1';
4
5export async function initializeDatabase() {
6 await sqlite.execute(`
7 CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
24 * Process all incomplete book records
25 */
26export async function processIncompleteRecords(): Promise<ProcessingResult> {
27 const result: ProcessingResult = {
28 totalProcessed: 0,
126 }
127
128 // Include additional metadata for the update function to handle
129 // (it will try to update these separately and skip if properties don't exist)
130 if (metadata.subtitle) {
220 * Process a single book record by ID
221 */
222export async function processSingleRecord(recordId: string): Promise<ProcessingResult> {
223 // This would require fetching a single record from Notion
224 // For now, we'll process all and filter, but this could be optimized
A helper function to build a file's email
Simple functional CSS library for Val Town
import { OpenAI } from "https://esm.town/v/std/openai";
export default async function(req: Request): Promise<Response> {
if (req.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",
LangChain (https://langchain.com) Ambassador, KubeSphere (https://kubesphere.io) Ambassador, CNCF OpenFunction (https://openfunction.dev) TOC Member.