Skip to content

Instantly share code, notes, and snippets.

@yarwelp
Created March 15, 2012 04:47
Show Gist options
  • Save yarwelp/2041954 to your computer and use it in GitHub Desktop.
Save yarwelp/2041954 to your computer and use it in GitHub Desktop.
Upload eBooks as attachments to CouchDB
#!/usr/bin/env bash
# usage: ./upload.sh http[s]://user:pass@host:port/database directories...
# This script creates a new document for each directory and then uploads the
# contents of each directory as attachments to said document.
# The script was made for uploading eBooks to my CouchDB so that I can retrieve
# them no matter where I am or what device I am on, but it can easily be
# adapted to other content as well.
# I keep my ebooks organized the following way in the directory I am u/l from:
#
# ebooks/
# ISBN/
# book/
# name_of_book.ext
# [...]
# cover/
# thumb.gif
# cover.gif
# large.jpg
# I opted to keep this structure when uploading to CouchDB even though it
# means that there won't really be directories - CouchDB stores the files
# with slashes replaced by %2F, and when you download it to the browser,
# the files will most likely be named directory_filename.ext.
# Btw, if you're wondering - I have purchased these eBooks from
# publishers who provide them in DRM-free formats (O'Reilly, Leanpub,
# The Pragmatic Bookshelf), and the CouchDB they are uploaded to is only
# accessible by me. They are there for my own use and will never be
# "shared".
#STARTDIR=$(pwd)
COUCHDB=$1
PUBLISHER=$2
curl $COUCHDB
if [ $? -eq 0 ] ; then
for currbook in ${@:3} ; do
echo "Current book is $currbook" 1>&2
UUID=$(uuidgen | sed 's/-//g')
echo "Using UUID $UUID" 1>&2
DEST="$COUCHDB/$UUID"
DOCCREATE=$(curl -X PUT $DEST -d \
"{
\"type\":
[
\"digital assets\",
\"ebooks\"
],
\"isbn\":\"$currbook\",
\"tags\":
[
\"pending\"
],
\"publisher\":\"$PUBLISHER\"
}")
DOCCREATED=$( echo $DOCCREATE | grep '"ok":true' )
if [ $? -eq 0 ] ; then
find "$currbook" -type f \
\(\
-name "*.epub" \
-o -name "*.mobi" \
-o -name "*.pdf" \
-o -name "*.zip" \
-o -name "*.apk" \
-o -name "*.jpg" \
-o -name "*.gif" \
\) -print0 | while IFS= read -r -d $'\0' file; do
STOREAS=$( echo "$file" | sed -e "s,$currbook/\?,,g" -e "s, ,%20,g" )
REV=$( curl $DEST | egrep -o '"_rev":"[^"]*"' | sed 's/"_rev":"\(.*\)"/\1/' )
echo "Current document revision is at $REV" 1>&2
echo "Next file is $file" 1>&2
echo "Going to store as $STOREAS" 1>&2
FILETYPE=$( echo "$file" | egrep -o "\.[^\.]*$" | cut -c2- )
#MAYBE: Use `file' to check if file type is as expected?
ERROR=0
case $FILETYPE in
"epub")
MIMETYPE="application/epub+zip"
;;
"mobi")
MIMETYPE="application/x-mobipocket-ebook"
;;
"pdf")
MIMETYPE="application/pdf"
;;
"zip")
MIMETYPE="application/zip"
;;
"apk")
MIMETYPE="application/vnd.android.package-archive"
;;
"jpg")
MIMETYPE="image/jpeg"
;;
"gif")
MIMETYPE="image/gif"
;;
*)
echo "Unknown filetype :(" 1>&2
ERROR=1
;;
esac
if [ $ERROR -eq 0 ] ; then
curl -vX PUT "$DEST/$STOREAS?rev=$REV" --data-binary "@$file" \
-H "Content-Type: $MIMETYPE"
fi
done
else
echo $DOCCREATE 1>&2
fi
done
else
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment