Android WebDAV Bi-directional sync with Termux and Rclone

From Run Your Own
Revision as of 23:05, 18 March 2024 by 320x200 (talk | contribs)
Jump to navigation Jump to search

The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It's fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home screen. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it's ridiculous.

Warnings

  • This documentation makes some assumptions regarding WebDAV and its configuration that are described there.
  • Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.
  • This is not a Termux or Rclone tutorial, RTFM or GTFO :)

The Setup

Prerequisites

pkg upgrade
pkg install rclone
  • feel free to also install quality of life extras like tmux, neovim, etc
  • configure rclone to work with your WebDAV share, create ~/.config/rclone/rclone.conf
[library]
type = webdav
url = http://192.168.100.100/
vendor = other
user = turtleprincess
pass = SEE_BELOW
  • generate the password with this:
echo "heygirl" | rclone obscure -
  • test if it works with
rclone lsd library:some/folder

Preparing the local and remote folders

Here we will take as example that you want to maintain in sync two folders, the default Pictures folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance library:path/to/Pictures. Make sure to make a backup of your Android Pictures folder in case ${SOMETHING_B4D} happens. If you fuck it up, it's on you. Also follow these three steps below otherwise you will make things worse anyway.

  • First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides)
rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run
  • If this looks it's working fine, then times to stop pretending (drop --dry-run)
rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync
  • After that, no need to maintain dumb superset sync (drop --resync)
rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case

If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you're in public transport and you want to cosplay like you're breaking into a gibson. So let's use a script.

The script

shhhhhhh

The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:

  • they also exist on the remote WebDAV share
  • for each of these folders you have done the little 3-steps dance described above

The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it's cold outside anyway.

#!/data/data/com.termux/files/usr/bin/sh

set -e # exit on error

DAVIP="192.168.100.100"
DAVMAC="c0:de:d3:4d:c0:de"
DAVFOLDER="library:path/to"
ANDFOLDERS="DCIM Pictures Download Documents"
RETRY=0

kthxbye ()
{
  echo "Press a key to exit..."
  read REPLY 
  exit 0
}

syncit ()
{
  echo "library is open!\n"
  # ANSI art greetings (optional but you know you want it)
  #/data/data/com.termux/files/usr/bin/printf "$(cat ~/assets/tp.ans)"
  #echo
  #sleep 3s
  for ANDFOLDER in ${ANDFOLDERS}
  do
    echo "syncing ***${ANDFOLDER}***\n"
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \
     --create-empty-src-dirs --compare size --slow-hash-sync-only \
     --resilient -MvP --fix-case
  done
  kthxbye
}
 
gotolibrary ()
{
  if nc -w 2 -z ${DAVIP} 80 2>/dev/null
  then
    syncit
  else
    echo "library is silent, trying to wakeup turtle princess"
    if [ "${RETRY}" -eq 0 ] ; then wol ${DAVMAC} ; fi
    while [ "${RETRY}" -lt 20 ]
    do
      sleep 1s
      RETRY=$((RETRY+1))
      gotolibrary
    done
    echo "OK I give up, library is closed :("
    kthxbye
  fi
}

gotolibrary

Save it with the very original name sync.sh and you're good to go.

BUT WAIT THERE'S MORE

Widget

The script is cool but you know what's more cool? To be able to start it directly from the home launcher thing.

  • Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.
  • From Termux, move the script to a new special folder
mkdir .shortcuts
mv sync.sh .shortcuts
  • Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.
  • once dropped, sync.sh should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that
  • now you can call the script directly from the home screen.
  • The future is now.

Notes

  • files with ":" in their name won't sync because they can't be created on an Android fs
  • we can't use modtime as a criteria for detecting file changes so filesize is the main criteria. We can't use it because Android does not support this somehow. I'm a man of simple taste, I just need to sync 10GB of memes. Bitrot and tempering can only add value to such endeavor. Check Rclone bisync doc for more options if you find this proposal outrageous.
  • access to /sdcard can stop working sometimes, because Android. Just revoke Termux storage permission and enable them again
  • when the script is launched from the home screen it's nice to be able to use the whole height of the Android device to scroll back through all these error messages, but by default Termux puts a software keyboard in your face, you can politely decline by adding the following in .termux/termux.properties
hide-soft-keyboard-on-startup = true