Skip to content

Instantly share code, notes, and snippets.

@syhily
Last active January 9, 2023 08:01
Show Gist options
  • Star 39 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save syhily/9feb936bcaebf2beec567733810f4666 to your computer and use it in GitHub Desktop.
Save syhily/9feb936bcaebf2beec567733810f4666 to your computer and use it in GitHub Desktop.
Download all the books from a talebook website. The https://curl.se/ and https://stedolan.github.io/jq/ are required for using this script.
#!/usr/bin/env bash
# Download metadata, modify these as your needs.
## The directory to save the downloaded files.
download_directory="/volume1/Download/EPUB"
## The website you want to visit.
calibre_site="http://soulseeker.myds.me:25788"
## The formats you want to download. We only download the first present format.
## All the formats should be upper case.
allow_formats=( EPUB MOBI AZW3 )
################################################################
#
# Don't modify the scripts below.
#
################################################################
## Clean up the user provided variables.
download_directory=${download_directory%/}
calibre_site=${calibre_site%/}
## Variables when execute the script.
minimal_size=10240
index_file="$download_directory/startIndex"
cookie_file="$download_directory/cookie.txt"
start=0
end=0
register_account() {
echo "Start register account on site <$calibre_site>"
read -p "Enter the username: " username
times=0
while [ $times -eq 0 ] || [ "$password" != "$repassword" ];
do
if [ $times -gt 0 ]; then
echo "The two password didn't match. Please try again"
fi
read -sp "Enter the password: " password
echo ""
read -sp "Enter the password (again): " repassword
echo ""
times=$((times + 1))
done
read -p "Enter the nickname: " nickname
read -p "Enter the email: " email
## Register account
curl -X POST -d "username=$username" -d "password=$password" -d "nickname=$nickname" -d "email=$email" $calibre_site/api/user/sign_up
## Jump to account login.
echo "Successful registered account, jump to login."
login_account
}
login_account() {
touch $cookie_file
read -p "Enter your username, please: " username
read -sp "Enter your password, please: " password
echo ""
curl -c - --silent --output /dev/null -X POST -d "username=$username" -d "password=$password" "$calibre_site/api/user/sign_in" > $cookie_file
echo "Get cookie from $calibre_site:"
echo ""
echo "`cat $cookie_file`"
echo ""
echo ""
}
loading_cookie() {
while true; do
read -p "Do you have account for <${calibre_site}>? [Y/n] " have_account
have_account=${have_account:-y}
case $have_account in
[Yy]* ) login_account; break;;
[Nn]* ) register_account; break;;
* ) echo "Please answer y or n.";;
esac
done
}
query_start_index() {
if [ ! -f "$index_file" ]; then
touch $index_file
echo 1 > $index_file
fi
start=$(cat $index_file)
echo "Start to download from $start"
}
query_maximum_index() {
end=`curl -b $cookie_file -c $cookie_file "$calibre_site/api/recent" | jq '.books[0].id'`
echo "The last book id is $end"
}
download_file() {
## Receive arguments.
file_id=$1
file_format=$2
## Generate file path and download link.
file_path=$download_directory/$file_id.$(echo "$file_format" | awk '{print tolower($0)}')
file_url=$calibre_site/api/book/$file_id.$file_format
## Download file.
echo "Start downloading $file_url"
curl -b $cookie_file -c $cookie_file "$file_url" --output "$file_path"
echo "Finish download $file_url"
## Remove the file which could be too small (in lower condition).
file_size=`ls -l $file_path | awk '{print $5}'`
if [ $file_size -lt $minimal_size ]; then
echo "$file_path is a blank file, remove it."
rm -rf $file_path
fi
}
try_download_file() {
echo "Try to query file info from <$calibre_site>"
file_id=$1
file_info=`curl -b $cookie_file -c $cookie_file "$calibre_site/api/book/$file_id"`
exists=`jq -r '.err' <<< "$file_info"`
if [ "$exists" == "ok" ]; then
## Find the available format one by one.
for format in "${allow_formats[@]}"
do
echo "Try to find $format format for book $file_id."
format_info=`jq -r ".book.files[] | select(.format | contains(\"$format\"))" <<< "$file_info"`
if [ -z "$format_info" ]; then
echo "Couldn't find $format format for book $file_id"
else
download_file $file_id $format
break
fi
done
else
echo "Error in query file formats, message: $exists"
fi
}
# The beginning of the script logic.
## Check the required command line tools.
command -v curl >/dev/null 2>&1 || { echo >&2 "Require curl but it's not installed. Aborting."; exit 1; }
command -v jq >/dev/null 2>&1 || { echo >&2 "Require https://stedolan.github.io/jq/ but it's not installed. Aborting."; exit 1; }
## Load the cookie.
loading_cookie
## Query the start index from cache.
query_start_index
## Query the stop index from website.
query_maximum_index
for((i=$start;i<=$end;i++));
do
## Try to download file from allowed formats.
try_download_file $i
## Record file id to index file.
echo $i > $index_file
done
@syhily
Copy link
Author

syhily commented Apr 3, 2022

@syhily
Copy link
Author

syhily commented Apr 3, 2022

@syhily
Copy link
Author

syhily commented Apr 3, 2022

@syhily
Copy link
Author

syhily commented Apr 3, 2022

@syhily
Copy link
Author

syhily commented Apr 3, 2022

@syhily
Copy link
Author

syhily commented Apr 3, 2022

@hellojukay
Copy link

挺好的,我用 golang 重写了一遍 https://github.com/hellojukay/dl-talebook

@jianyun8023
Copy link

@syhily
Copy link
Author

syhily commented Apr 22, 2022

@syhily
Copy link
Author

syhily commented Jan 9, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment