├── .gitignore ├── src ├── usr │ └── local │ │ └── wget-sync │ │ ├── rcS_payload.txt │ │ ├── usb_payload.txt │ │ ├── refresh_library.sh │ │ ├── virtual_sd.sh │ │ ├── udev_program.sh │ │ ├── udev_usb_program.sh │ │ ├── config.sh │ │ ├── ping-test.sh │ │ ├── own_rcS.sh │ │ ├── install_app.sh │ │ ├── config_template.txt │ │ └── sync.sh └── etc │ └── udev │ └── rules.d │ └── 98-wget-sync.rules ├── package.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | build 3 | -------------------------------------------------------------------------------- /src/usr/local/wget-sync/rcS_payload.txt: -------------------------------------------------------------------------------- 1 | /usr/local/wget-sync/own_rcS.sh & -------------------------------------------------------------------------------- /src/usr/local/wget-sync/usb_payload.txt: -------------------------------------------------------------------------------- 1 | /usr/local/wget-sync/udev_usb_program.sh -------------------------------------------------------------------------------- /src/usr/local/wget-sync/refresh_library.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mountpoint -q /mnt/sd 3 | if [ $? != 0 ]; then 4 | echo "$0, ERROR: /mnt/sd is not mounted. Can't refresh library." 5 | exit 1; 6 | fi 7 | echo sd add /dev/mmcblk1p1 >> /tmp/nickel-hardware-status -------------------------------------------------------------------------------- /src/etc/udev/rules.d/98-wget-sync.rules: -------------------------------------------------------------------------------- 1 | KERNEL=="eth*", RUN+="/usr/local/wget-sync/udev_program.sh" 2 | KERNEL=="wlan*", RUN+="/usr/local/wget-sync/udev_program.sh" 3 | KERNEL=="usb_host", RUN+="/usr/local/wget-sync/udev_usb_program.sh" 4 | KERNEL=="usb_plug", RUN+="/usr/local/wget-sync/udev_usb_program.sh" 5 | 6 | -------------------------------------------------------------------------------- /src/usr/local/wget-sync/virtual_sd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # create virtual SD card by bind mounting it to folder inside onboard SD. 4 | mkdir -p $wget_sync_settings/sd/ 5 | mountpoint -q /mnt/sd 6 | if [ $? -eq 0 ]; then 7 | echo "$0: /mnt/sd is already mounted. Nothing done." 8 | exit 1; 9 | fi 10 | echo "$0: Creating bind mount." 11 | mount --bind $wget_sync_settings/sd /mnt/sd -------------------------------------------------------------------------------- /src/usr/local/wget-sync/udev_program.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # http://www.reactivated.net/writing_udev_rules.html#example-netif 4 | 5 | if [ "$ACTION" != "add" ]; then 6 | exit 1; 7 | fi 8 | 9 | BASEDIR=$(dirname $0) 10 | . $BASEDIR/config.sh 11 | 12 | # some line might rely that settings directory exists 13 | mkdir -p $wget_sync_settings 14 | 15 | $BASEDIR/sync.sh &> $wget_sync_settings/last-wget-sync.txt & -------------------------------------------------------------------------------- /src/usr/local/wget-sync/udev_usb_program.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # note: in firmware 2.3.1 this is not always executed by udev, but also by nickel (maybe) 4 | 5 | BASEDIR=$(dirname $0) 6 | . $BASEDIR/config.sh 7 | 8 | if [ "$ACTION" == "remove" ]; then 9 | { 10 | date 11 | echo "$0: USB removed. Checking virtual SD." 12 | $wget_sync_home/virtual_sd.sh 13 | } &> $wget_sync_settings/last-usb-remove.txt 14 | fi -------------------------------------------------------------------------------- /src/usr/local/wget-sync/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This config script is used with sourcing so don't call exit 4 | 5 | # wget_sync_home is also defined in /etc/udev/rules.d/99-wget-sync.rules and rcS_payload.txt 6 | 7 | wget_sync_settings=/mnt/onboard/.wget-sync 8 | wget_sync_home=/usr/local/wget-sync 9 | wget_sync_libfolder=/mnt/onboard/.wget-sync/sd 10 | 11 | export wget_sync_settings wget_sync_home wget_sync_libfolder -------------------------------------------------------------------------------- /src/usr/local/wget-sync/ping-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | i=0 4 | pingValue=1 5 | while [ $pingValue != 0 ] && [ $i -le 10 ] 6 | do 7 | ping -c 1 -w 3 $1 8 | pingValue=$? 9 | # echo "loop $i" 10 | if [ $pingValue != 0 ]; then 11 | # echo "sleep" 12 | sleep 3 13 | fi 14 | i=`expr $i + 1` 15 | done 16 | 17 | if [ $pingValue != 0 ]; then 18 | exit 1; 19 | fi -------------------------------------------------------------------------------- /src/usr/local/wget-sync/own_rcS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BASEDIR=$(dirname $0) 4 | 5 | # export variables 6 | . $BASEDIR/config.sh 7 | 8 | # ensure that SD card is ready or create virtual SD card 9 | $wget_sync_home/virtual_sd.sh 10 | 11 | # refresh library at boot only if real SD is not connected and sync is used 12 | # if real SD card is connected firmware handles sync 13 | # koboExtStorage is created when sync is used 14 | if [ ! -e /dev/mmcblk1p1 ] && [ -d /mnt/sd/koboExtStorage ]; then 15 | $wget_sync_home/refresh_library.sh 16 | fi -------------------------------------------------------------------------------- /src/usr/local/wget-sync/install_app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | target=/etc/init.d/rcS 3 | payload=$wget_sync_home/rcS_payload.txt 4 | 5 | grep -q -F -f $payload $target 6 | if [ $? != 0 ]; then 7 | cat $payload >> $target 8 | fi 9 | 10 | target=/usr/local/Kobo/udev/usb 11 | payload=$wget_sync_home/usb_payload.txt 12 | 13 | grep -q -F -f $payload $target 14 | if [ $? != 0 ]; then 15 | cat $payload >> $target 16 | fi 17 | 18 | target=$wget_sync_settings/config.sh 19 | payload=$wget_sync_home/config_template.txt 20 | if [ ! -f $target ]; then 21 | cat $payload > $target 22 | fi -------------------------------------------------------------------------------- /src/usr/local/wget-sync/config_template.txt: -------------------------------------------------------------------------------- 1 | ################## 2 | #### Configuration 3 | 4 | ## Comment or uncomment "url" if you wish this script to run or not. 5 | ## Set to the http(s) server running an nginx or apache file listing. 6 | #url="https://fullurl.com/some/dir%20dir" 7 | 8 | ## Set to a comma seperated list of allowed extensions 9 | exts="epub,mobi,cbz,cbr,pdf" 10 | 11 | ###Extras: 12 | 13 | ## HTTP authentication, keep commented if not needed 14 | #http_username="user" 15 | #http_password="pass" 16 | 17 | ### Custom CA certificate. If using SSL supply the certificate in ".wget-settings/cert.crt" on your kobo root while mounted. 18 | ### The format is PEM 19 | -------------------------------------------------------------------------------- /package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #create build directory 3 | mkdir -p build/KoboRoot 4 | 5 | #see http://maemo.org/packages/package_instance/view/diablo_extras_free_armel/wget/1.10.2-2osso2/ 6 | wgeturl="http://repository.maemo.org/extras/pool/diablo/free/w/wget/wget_1.10.2-2osso2_armel.deb" 7 | localmd5="cd89139a3148b9f4a2b55d712059f106" 8 | 9 | if [ ! -f build/wget.deb ]; 10 | then 11 | wget "$wgeturl" -O build/wget.deb 12 | fi 13 | md5=`md5sum build/wget.deb | awk '{ print $1 }'` 14 | if [ $localmd5 != $md5 ] 15 | then 16 | echo "Bad wget." 17 | exit 1 18 | fi 19 | 20 | cd build 21 | ar -vx wget.deb 22 | #create clean KoboRoot with just wget 23 | tar -zxvf data.tar.gz -C KoboRoot 24 | #add our wgetsync to it. 25 | cp -r ../src/* KoboRoot 26 | #package it 27 | tar cvzf KoboRoot.tgz -C KoboRoot . -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | kobo-wget-sync 2 | =============== 3 | 4 | Forked from https://github.com/softapalvelin/kobo-grive-sync/. 5 | Thanks so much for the good work! Unfortunately, it does not seem to work for latter versions of kobo firmware. 6 | 7 | So, instead of using grive, this uses wget instead which is pre-compiled for armel architecture and downloaded by the package script. 8 | 9 | Purpose 10 | --------------- 11 | When you have multiple kobo's and do not wish to keep connecting your kobo to your PC then this is for you. 12 | By serving a directory with _nginx_ or _apache2_ with a file listing (with authentication), you can serve files in your local network to be synced to all your kobo devices. 13 | The sync script mirrors and spiders the various indexes of your web-url and only downloads the file extensions specified by you in the `.wget-sync/config.sh`. 14 | 15 | After installing and configuring, you activate wifi (a quick way to activate wifi is to press `Sync`) and it will fetch new files from your webserver. 16 | Additionally, because I use this for weekly news digests, it also deletes files that are no longer present on your webserver. 17 | So be **careful!** 18 | 19 | It also supports ssl and http authentication for obvious reasons. 20 | 21 | Install 22 | --------------- 23 | 24 | 1. To build simply run the package script. 25 | 26 | ``` 27 | ./package.sh 28 | ``` 29 | 30 | Then copy the `build/KoboRoot.tgz` to your kobo's /.kobo directory and disconnect the kobo. 31 | You will see it updating and restart. 32 | 33 | 2. Press `Sync` or activate wifi to start the script. (It watches the activation of wifi through udev rules) 34 | 3. Connect your kobo again and a dir called `.wget-sync` should be created that contains `config.sh` 35 | 4. Edit `config.sh` by setting the url and other options. 36 | 5. Disconnect usb, activate wifi and your kobo should sync with the webserver file listing. If it does not go well you can check the log in `.wget-sync` to check what went wrong. 37 | 38 | 39 | FAQ 40 | -------------- 41 | ``` 42 | Q: For what Kobo versions does this work? 43 | A: I only tested this with the Kobo Glo with the latest firmware to date `2.10.0`. Please tell me if this works for you. 44 | 45 | Q: Where are the books downloaded? 46 | A: On onboard memory in /.wget-sync/sd/ 47 | 48 | Q: After the initial sync going well, my second sync doesn't work! 49 | A: This script doesn't work on the "Sync" button, but rather on the activation of Wifi. So disabling and enabling wifi again will initialize the script. 50 | 51 | Q: I have an external sd-card, can I still use this? 52 | A: The script softapalvelin created uses an virtual sd card to trick kobo into thinking you inserted new content. So, maybe? 53 | 54 | Q: Will you long-term support this? 55 | A: No. 56 | ``` 57 | 58 | Disclaimer 59 | --------------- 60 | My bash scripting skills are not that good, so backup everything and test this thuroughly if you wan to use it. And if you decide to use it, know that I will not be responsible for epubs or books lost. 61 | 62 | 63 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/wernerb/kobo-wget-sync/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 64 | 65 | -------------------------------------------------------------------------------- /src/usr/local/wget-sync/sync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # (I know config is called from udev_program.sh) keep config also here so it's easy to dev 4 | BASEDIR=$(dirname $0) 5 | . $BASEDIR/config.sh 6 | 7 | # some line might rely that settings directory exists 8 | mkdir -p $wget_sync_settings 9 | 10 | # ensure that application is installed 11 | $wget_sync_home/install_app.sh 12 | 13 | # wait that internet connection is established 14 | date 15 | echo "$0: connecting..." 16 | $wget_sync_home/ping-test.sh www.google.com 17 | if [ $? != 0 ]; then 18 | echo "$0: no connection" 19 | exit 1; 20 | fi 21 | echo "$0: connected" 22 | # ensure that SD card is ready or create virtual SD card 23 | $wget_sync_home/virtual_sd.sh 24 | 25 | cd $wget_sync_libfolder 26 | # check if we should reset authentication code 27 | if [ -e $wget_sync_settings/config.sh ]; then 28 | echo "$0: Loading config.sh."; 29 | source $wget_sync_settings/config.sh 30 | else 31 | echo "Did not find $wget_sync_settings/config.sh. Exiting" 32 | exit 1 33 | fi 34 | 35 | #check configuration 36 | if [ -z "${url+xxx}" ] || [ -z "${exts+xxx}" ]; then 37 | echo "Incomplete configuration. Please edit $wget_sync_settings/config.sh. Make sure url and exts are defined. Exiting" 38 | exit 1 39 | fi 40 | 41 | #If ssl certificate exists 42 | if [ -e "$wget_sync_settings/cert.crt" ]; then 43 | ssl_auth="--ca-certificate=$wget_sync_settings/cert.crt" 44 | fi 45 | 46 | #synchronize 47 | echo "$0: Starting Sync"; 48 | pwd 49 | 50 | mkdir -p "$wget_sync_libfolder" 51 | numdirs=$(($(echo "$url" | grep -o "/" | wc -l) - 2)) 52 | #get everything with wget, if this fails then everything fails.. 53 | wgetoutput=$(wget --user="$http_username" --password="$http_password" --mirror "$ssl_auth" --cut-dirs=$numdirs -P "$wget_sync_libfolder" --no-parent --no-host-directories --accept "$exts" "$url/" 2>&1 ) 54 | #TODO: exit status doesn't work apparently.. 55 | wgetstatus=$? 56 | if [ $wgetstatus -ne 0 ]; then 57 | echo "Something went wrong. Stopping." 58 | exit 1 59 | fi 60 | echo "$wgetoutput" 61 | #catch the rejections to subtract from total downloads. 62 | urllength=${#url} 63 | urllength=$((urllength+1)) 64 | log1loc=$(echo "$wgetoutput" | grep -Eio https://.+ | cut -c $urllength- | grep -v '.*/$') 65 | fixurls () 66 | { 67 | echo "$log1loc" | while read line 68 | do name="$wget_sync_libfolder$(echo -e "$line" | sed 's % \\\\x g' | xargs printf )" 69 | echo "$name" 70 | done 71 | } 72 | result=$(fixurls) 73 | echo "$result" 74 | numindexes=$(echo "$wgetoutput" | grep -o "since it should be rejected." | wc -l) 75 | wgetresult=$(echo "$wgetoutput" | tail -1) 76 | numdownloads=$(echo "$wgetresult" | grep -o '[0-9]\+\sfiles' | grep -o '[0-9]\+') 77 | echo "----" 78 | echo "Start removing files:" 79 | currentfiles=$(find "$wget_sync_libfolder" -type f -print ! -iname ".*" -o \( -path $grive_sync_libfolder/Digital\ Editions -prune \) -type f -o \( -path $grive_sync_libfolder/koboExtStorage -prune \) -type f) 80 | dostuff () 81 | { 82 | echo "$currentfiles" | while read i; do 83 | echo "$result" | grep -qF "$i" 84 | if [ $? -ne 0 ] 85 | then 86 | echo "@Removing $i..\n" 87 | rm "$i" 88 | if [ $? -ne 0 ]; then 89 | echo "Could not delete $i. Stopping" 90 | exit 1 91 | fi 92 | fi 93 | done 94 | } 95 | removefiles=$(dostuff) 96 | echo $removefiles 97 | echo $removefiles | grep -qF "@Removing" 98 | deletestatus=$? 99 | find "$wget_sync_libfolder" -depth -mindepth 1 -type d -exec rmdir --ignore-fail-on-non-empty '{}' + 100 | echo "Done removing files" 101 | echo "----" 102 | numrealdownloads=$((numdownloads - numindexes)) 103 | echo "Num indexes: $numindexes | Num downloads: $numrealdownloads" 104 | echo "----" 105 | echo "Sync complete" 106 | echo "----" 107 | if [ $numrealdownloads -ne 0 ] || [ $deletestatus -eq 0 ]; then 108 | echo "$0: $modified_files_count new file(s). Refresh library."; 109 | $wget_sync_home/refresh_library.sh 110 | else 111 | echo "$0: No new files. Skip library refresh."; 112 | fi 113 | --------------------------------------------------------------------------------