I’ve been using Zen Quotes API for a while now. It’s a great app that provides quotes for my lockscreen. But to filter based on Author, I need to pay for the premium version. So I decided to create my own personal quote API.
First I needed a source of quotes. I found datasets of quotes on Kaggle Quotes Dataset and Quotes-500K. I think these datasets were created by scraping the web for quotes.
The Plan
- Create 
sqlitedatabase to store quotes. - Create table 
quoteswith columnsquote,author,tags. - Import quotes from the dataset.
 - Perform READ operations on the database. easy peasy.
 
The Implementation
The problem is that one dataset is in csv format and the other is in json format. We need a common format to import the quotes into the database. I decided to convert the json dataset to csv format. Time to flex my command-line-fu.
First, I opened the csv dataset in LibreOffice Calc and replaced ', ' with ' ' in categories column. Then renamed categories to tags. Saved the file as quotes.csv.
Next, I converted the json dataset to csv using shitty bash-fu.
jq '.[] | "\(.Quote)<merge>, \(.Author)<merge>, \(.Tags | join(" "))"' quotes.json \
| sed "s/<merge>, /\", \"/g" \
| sed -z "s/ \"\n/\"\n/g" >> quotes.csv
.[]selects each object in the array."\(.Quote)<merge>, \(.Author)<merge>, \(.Tags | join(" "))"formats the output asquote, author, tags. I could not find a way to insert double quotes around the fields injq. So I used keyword to replace with", "later.🤪sed "s/<merge>, /\", \"/g"replaces<merge>,with",.sed -z "s/ \"\n/\"\n/g"removes the trailing space before newline.
Now I have a csv file with quotes. Time to create the database.
sqlite3 ~/playground/quotes/quotes.db
-- Create a database to store quotes.
CREATE TABLE quotes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    quote TEXT,
    author TEXT,
    tags TEXT
);
-- Import quotes from the `csv` file.
.mode csv
.import quotes.csv quotes
-- Let's count the number of quotes in the database.
SELECT COUNT(*) FROM quotes;
-- 548102 😎
Get a random quote
sqlite3 ~/playground/quotes/quotes.db "SELECT quote FROM quotes ORDER BY RANDOM() LIMIT 1;"
Get a random quote from ‘Socrates’
sqlite3 ~/playground/quotes/quotes.db "SELECT quote FROM quotes WHERE author LIKE '%socrates%' ORDER BY RANDOM() LIMIT 1;"
Now I can get personalized quotes for my lockscreen.
#!/usr/bin/env bash
get_quote() {
    sqlite3 -separator " - " ~/playground/quotes/quotes.db \
        "SELECT quote, REPLACE(author, '\"', '') AS author FROM quotes \
        WHERE ( \
                  author LIKE '%socrates%' \
            OR    author LIKE '%plato%' \
            OR    author LIKE '%aristotle%' \
            OR    author LIKE '%seneca%' \
            OR    author LIKE '%epictetus%' \
            OR    author LIKE '%marcus aurelius%' \
            OR    author LIKE '%montaigne%' \
            OR    author LIKE '%schopenhauer%' \
            OR    author LIKE '%nietzsche%' \
            OR    author LIKE '%diogenes%' \
            OR    author LIKE '%kierkegaard%' \
            OR    author LIKE '%pythagoras%' \
        ) \
        AND LENGTH(quote) < 100 \
        ORDER BY RANDOM() LIMIT 1;"
}
if [ ! -f /tmp/__quote_data ]; then
    get_quote > /tmp/__quote_data
fi
if [ $(find /tmp/__quote_data -mmin +1) ]; then
    previous_quote_data=$(cat /tmp/__quote_data)
    rm /tmp/__quote_data
    get_quote > /tmp/__quote_data
fi
quote_data=$(cat /tmp/__quote_data)
echo "📜 $quote_data"