Monday, December 1, 2008

Bash Script To Find Free Online Fiction and Non-Fiction Books

Hey There,

SPECIAL NOTE: Some of The University of Pennsylvania's Online Books require a special reader, which is totally free - no sign up or even giving your email. Download The Ebrary Reader here


For some reason, it's Monday again and time for another "online reference ripper" script. For this week's Monday Linux/Unix bash shell script we're going to do the (almost) exact opposite of what we've been doing for the past few weeks. Today, we're going to find free books on the Internet and, possibly, read them ;) And we don't just mean man pages and reference materials, etc. We'll be using the Online Book Pages at the University of Pennsylvania. They may not have the variety that Amazon.com does, but everything listed on their site is available for online reading (although it says nowhere - that I could find - that you can't just download the books). Best of all, you don't have to sign up for anything. It's absolutely free. And they actually have a book by Stephen King up there (If you recall his chapter-by-chapter pay-as-you-go online book distribution experiment, you may recognize the title :) It's 100% free now but, to clarify, Stephen King never actually charged for the online book; he made his book available to anyone who wanted to read it and only asked that they donated money if they liked it. So, either everybody hated it or not enough people donated enough money to keep him interested ;) No offense to Mr. King. Writing is his profession and he deserves to get paid for it.

As always, skip the next paragraph if you're a regular reader. It's a listing of all the other "online reference ripper" scripts we've done to date.

Our previous web-based Bash scripts, in backward chronological order, include about 500 posts on getting your dish, cable and local listings from the CLI, accessing Wikipedia, accessing the Farmer's Almanac, accessing the International Dictionary, checking out the world's weather, spewing out famous quotations on pretty much any subject, doing encyclopedia lookups, accessing the online Thesaurus, translating between different languages and, of course, using the online dictionary.

The script for this week is just about as easy to use as any other we've put out. It should work on Linux or Unix, and - if you don't know what arguments to pass to it - you can get the help screen with either the "-h" flag or by just invoking the command with no arguments, like:

host # ./onlinebooks.sh
Usage: ./onlinebooks.sh [-h for help]
Required args - either one or both
[-t title] [-a author]
Quote title and/or author if multi-word!


Below are some screen shots to show the various error conditions and, just for kicks, some successful output :)

Click the pix below and don't get too close to the screen ;)

Online Book Title Listings


Online Book Author Listings

There are some shortcomings that I haven't been able to get around yet. For instance, I've visually verified that really long listings of books don't print out properly. A search on Leo Tolstoy (also known as Tolstoi -- I just learned that today ;), for example, yields only one listing, while there about 40 books available on the actual site. I'll get around to that as soon as I can.

In the meantime, since this script relies on you using a terminal client that hyperlinks web addresses for you (like NuTTY or PuTTY), I have something in the hopper for you that I'm hoping you'll all enjoy. It has to do with this script and will be an interesting way (I think) to get in more reading at work ;)

Until then,

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/bin/bash

#
# onlinebooks.sh - Come On In, The Readin's Fine ;)
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>
#

function usage()
{
echo
echo "Usage: $0 [-h for help]"
echo "Required args - either one or both"
echo "[-t title] [-a author]"
echo "Quote title and/or author if multi-word!"
echo
exit 1
}

while getopts t:a:h option
do
case $option in
t)
opt_title="$OPTARG"
;;
a)
opt_author="$OPTARG"
;;
h)
usage
;;
*)
usage
;;
esac
done

wget=`which wget`
book_title=`echo $opt_title|sed 's/ /+/g'`
book_author=`echo $opt_author|sed 's/ /+/g'`
noexactmatch=0
authors=0
titles=0

echo

$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|grep -i "No items were found" >/dev/null 2>&1

notfound=$?

$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|grep -i "No exact match" >/dev/null 2>&1

nomatch=$?

$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|grep -i "Browsing Authors" >/dev/null 2>&1

nomatch=$?

$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|grep -i "you requested books" >/dev/null 2>&1

btitle=$?

$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|grep -i "online books by" >/dev/null 2>&1

bauthor=$?

if [ $notfound -eq 0 ]
then
book_title=`echo $opt_title|sed 's/+/ /g'`
book_author=`echo $opt_author|sed 's/+/ /g'`
echo
echo "No items found for $book_author $book_title"
echo
exit 2
elif [ $nomatch -eq 0 ]
then
book_title=`echo $opt_title|sed 's/+/ /g'`
book_author=`echo $opt_author|sed 's/+/ /g'`
echo "No exact match found for $book_author $book_title"
echo
echo "Give these suggestions a go:"
echo
noexactmatch=1
elif [ $btitle -eq 0 ]
then
book_title=`echo $opt_title|sed 's/+/ /g'`
book_author=`echo $opt_author|sed 's/+/ /g'`
echo
echo "Title matches found for $book_author $book_title"
echo
titles=1
elif [ $bauthor -eq 0 ]
then
book_title=`echo $opt_title|sed 's/+/ /g'`
book_author=`echo $opt_author|sed 's/+/ /g'`
echo
echo "Listing online Titles for $book_title $book_author"
echo
authors=1
else
echo "Should not have gotten here. Looks like we need to fix something!"
exit 3
fi

if [ $noexactmatch -eq 1 ]
then
$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|sed -e :a -e 's/<[^>]*>/ /g;/</N;//ba' -e 's/$/\n/'|egrep -v 'exact match|previous'|grep -i title 2>&1|grep -v URL
elif [ $titles -eq 1 ]
then
$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|grep "SEARCH RESULTS"|sed -e 's/[^<ul>]*<ul>//' -e 's/<\/ul>.*$//g' -e s'/<li>/\n/g' -e s'/<\/li>/\n/g' -e 's/<\/ul>.*$/\n/g' -e s'/<ul>//g' -e s'/<\/ul>/\n/g'|sed -e 's/^[^<]*<a href="//g' -e 's/">.*<cite>/ : /' -e 's/<\/cite><\/a>//g' -e 's/<\/cite>//g' -e s'/<\/a>//g' -e s'/">/ /g' -e 's/<a href="//g'|grep -v "SEARCH RESULTS"|awk -F":" '{ if ( NF >= 2 ) print $3 " --- " $1 ":" $2 "\n"}'
elif [ $authors -eq 1 ]
then
$wget -nv -O - "http://onlinebooks.library.upenn.edu/webbin/book/search?author=${book_author}&amode=start&title=${book_title}&tmode=start" 2>&1|sed -e 's/[^<ul>]*<ul>//' -e 's/<\/ul>.*$//g' -e s'/<li>/\n/g' -e s'/<\/li>/\n/g' -e 's/<\/ul>.*$/\n/g' -e s'/<ul>//g' -e s'/<\/ul>/\n/g'|sed -e 's/^[^<]*<a href="//g' -e 's/">.*<cite>/ : /' -e 's/<\/cite><\/a>//g' -e 's/<\/cite>//g' -e s'/<\/a>//g' -e s'/">/ /g' -e 's/<a href="//g'|awk -F":" '{ if ( NF >= 2 ) print $3 " --- " $1 ":" $2 "\n"}'|sed -e '/^\/\//d' -e '/^ ---.*OBP/,$d'
fi

exit 0


, Mike




Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.