Skip to content

Commit

Permalink
Add book cover image retrieval and update functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
bramses committed Mar 28, 2024
1 parent 21e6976 commit 25fc463
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 5 deletions.
99 changes: 99 additions & 0 deletions book-covers-db.js
@@ -0,0 +1,99 @@
/*
1. get all books in book DB
if cover_image_url_large is null, get book cover image from http://localhost:2000/bookcover?book_title=book+title&author_name=book+author which will return JSON in form
{
"url": "..."
}
2. insert book cover image into book DB
3. if not null, skip
*/

import { createClient } from "@supabase/supabase-js";
import dotenv from "dotenv";
import fs from "fs";

dotenv.config();

const supabaseUrl = process.env.SUPABASE_URL;
const supabaseKey = process.env.SUPABASE_KEY;
const supabase = createClient(supabaseUrl, supabaseKey, {
auth: {
persistSession: false,
},
});

const getBooks = async () => {
const { data, error } = await supabase
.from("books")
.select("*");

if (error) {
console.error(error);
return [];
}

return data;
};

const getBookCover = async (bookTitle, authorName) => {
// convert to url format
bookTitle = bookTitle.replace(" ", "+");
// convert any : or & etc
bookTitle = encodeURIComponent(bookTitle);
authorName = authorName.replace(" ", "+");
authorName = encodeURIComponent(authorName);

try {
const url = `http://localhost:2000/bookcover?book_title=${bookTitle}&author_name=${authorName}`;
const response = await fetch(url);
const data = await response.json();
if (data.error) {
console.log(url);
return { error: data.error };
}
return data.url;
} catch (err) {
console.error(err);
return { error: err };
}
}

const updateBookCover = async (bookId, bookCoverUrl) => {
const { data, error } = await supabase
.from("books")
.update({ cover_image_url_large: bookCoverUrl })
.eq("book_id", bookId);

if (error) {
console.error(error);
return false;
}

return true;
}

const main = async () => {
const books = await getBooks();
for (const book of books) {
if (book.cover_image_url_large === null) {
console.log(`Getting book cover image for ${book.title}.`);
const bookCoverUrl = await getBookCover(book.title, book.author);
console.log(bookCoverUrl);
if (bookCoverUrl === null || bookCoverUrl.error) {
console.error(`Failed to get book cover image for ${book.title}.`);
if (bookCoverUrl.error) {
console.error(bookCoverUrl.error);
}
continue;
}
await updateBookCover(book.book_id, bookCoverUrl);
console.log(`Book cover image for ${book.title} updated.`);
} else {
console.log(`Book cover image for ${book.title} already exists.`);
}
}
}

if (process.env.DEV) {
main();
}
67 changes: 62 additions & 5 deletions compile-quotes.js
Expand Up @@ -22,7 +22,7 @@ const openai = new OpenAIApi(configuration);

dotenv.config();

const BOOK_ID = "38531384";
const BOOK_ID = "38318378";

const supabaseUrl = process.env.SUPABASE_URL;
const supabaseKey = process.env.SUPABASE_KEY;
Expand Down Expand Up @@ -68,6 +68,20 @@ const compileQuotesFomID = async (bookID) => {
return quotes;
};

const getQuotes = async (bookId) => {
const { data, error } = await supabase
.from("highlights")
.select("*")
.eq("book_id", bookId);

if (error) {
console.error(error);
return [];
}

return data;
};

const assignTopicToCluster = async (cluster) => {
try {
const prompt = `Given the following quotes, what is a good topic for them? Return only the topic as a Markdown heading with no leading #. No bold (**) or italics (*) are needed.`;
Expand Down Expand Up @@ -104,6 +118,46 @@ const assignTopicToCluster = async (cluster) => {
}
};

const highlightQuote = async (quote, topic) => {
console.log(`Highlighting quote: ${quote} for topic: ${topic}`);
try {
const prompt = `Given the following quote, highlight the part related to the topic using ** (MD bold). Return the quote with the relevant part highlighted. Say nothing else. Do not include the topic in the response.`;

const completion = await openai.createChatCompletion({
messages: [
{
role: "system",
content: prompt,
},
{
role: "user",
content: `Quote: <start>${quote}<end>\n\nTopic: ${topic}\n\nHighlighted Quote (Verbatim):`,
},
],
model: "gpt-3.5-turbo",
});

const content = completion.data.choices[0].message.content;

console.log(content);

return content.trim();
} catch (err) {
console.log("START ERROR");
console.error(err);
console.error(err.response);
console.error(err.response.data);
console.error(err.response.data.error);
console.error(err.response.data.error.message);
console.error(err.response.data.error.code);
console.error(err.response.data.error.status);
console.error(err.response.data.error.request);
console.log("END ERROR");
throw err;
}
}


const summarizeCluster = async (cluster) => {
try {
const prompt = `Given the following quotes, summarize them into a two-three sentence summary. Return only the summary`;
Expand Down Expand Up @@ -213,14 +267,17 @@ const main = async () => {
markdown += `## ${topic}\n\n`;
markdown += `### Summary\n\n${summary}\n\n`;
markdown += `### Quotes\n\n`;
cluster.forEach((quote) => {
markdown += `- ${quote.text}\n`;
});
for (const quote of cluster) {
markdown += `- ${await highlightQuote(quote.text, topic)}\n`;
}
markdown += `\n\n`;
// markdown += `### Follow Up Questions\n\n${followUp}\n\n`;
}

fs.writeFileSync("output.md", markdown);
};

// main();
// if env var DEV exists, run main
if (process.env.DEV) {
main();
}

0 comments on commit 25fc463

Please sign in to comment.