Running your own owncloud is a great thing, having all your data on your own servers. However since all the data are now only on your servers you also have to take care to run a regular backup  especially for calendar and contact information that users store in your owncloud.I also have my "owncloud" and so I also came across the backup problem since I use calendars ans contacts stored in my owncloud version 9.

Several scripts I found were not capable of backing up owncloud 9 data and thats why I started to write my own script for home use owncloud servers. It should:

As a result of the requirements from above, all users for which either calendars or addressbooks should be backed up, have to share each calendar, each addressbook read only to the owncloud backup user which by default is named "backup" (see AUTHUSER Shellvariable).

The script is designed for small home owncloud installations, since the way the backup is done via one single backup user to which all owncloud users have to share their calendars and addressbooks for backup is certainly not well suited for an installation with hundreds of users.

Configuration

Configuration is quite simple. You have to set the Shell-Variables in the header of the script by which it is configured. Take a look at the script first (see below) then you can better understand the following explanations.

The calendar names and addressbook names you write into CALENDAR[], CONTACT[] are not the names you see in the web interface of owncloud. Instead you have to look at the URL of the calendar or addressbook by clicking on the chain-symbol in ownclouds web interface for calendars/addressbooks you want to back up. At the very end of the URL you will see the name owncloud uses for this addressebook. Usually this name is very similar just a lower case version of the name the user sees.

The script code

The script is a simple bash script. So just copy it into a file, make this file executable and then set the configuration shell variables in the scripts head.

#!/bin/bash
#
# Script that does a backup of owncloud 9 calendars and contacts for
# given users. In order to keep only one cleartext password
# in this script not one for each user, an owncloud backup user is used
# for authentification. You have to create this user (AUTHUSER) in owncloud
# and all users wishing a backup of their data have to share their calendars
# and contacts (read only) to this user.
#
# R. Krienke, This email address is being protected from spambots. You need JavaScript enabled to view it.
# Version 0.1, 2016-04-18

# owncloud users for which contacs/calendars should be backupped
USER="john jeff cathy"
#

# owncloud user used for authentication against owncloud server
# !!! All users above have to share their cals, contacts to this user (read only) !!!
AUTHUSER="backup"
# The password of the backup user in base64 encoding for a little obfuscation

# Create new password by: echo "MyPassword"|base64
AUTHPWENC="TXlQYXNzd29yZAo="
AUTHPW=`echo $AUTHPWENC|base64 --decode`
#
# Where to store backupdata

BACKUPROOT="/import/backup/owncloud/calcard"
#
# hostname or ip of owncloud server

OCSERVER="owncloud"
#
# Each backup is stored in one subdirectory in $BACKUPROOT with the todays date

# The latest $GENERATIONS directories are kept, older ones are deleted after each run
# of this script.
GENERATIONS=30

# For each user to backup tell the script which calendars of this user should be backupped
# The calendar names are not the ones you see in ownclouds webpage but those you
# see when looking at the cal name at the end of the URL for this calendar shown in ownlouds
# webpage for this calendar. Seperate multiple calendar names by space.
declare -A CALENDAR
CALENDAR[john]="persönlich geburtstage"
CALENDAR[jeff]="persoenlich geburtstage"
CALENDAR[cathy]="persoenlich"

# Addr books, same like above
declare -A CONTACT
CONTACT[jeff]="kontakte"
CONTACT[cathy]="kontakte"

### configuration ends here ######################################################

echo "$0 starting caldav/carddav backup ...."

umask 0077
trap "rm -f $HOME/.wgetrc" HUP KILL TERM ABRT STOP
cat <<EOF >$HOME/.wgetrc
http-password = $AUTHPW
http-user = $AUTHUSER
EOF
chmod 600 $HOME/.wgetrc


#
# get one calendar for one specific user
#
getcal () {
    local CALNAME="$1"
    local USER="$2"
    local BUSER="$3"
    local SERVER=$4
    local ROOT="$5"

    BACKUPFILE="$CALNAME.ics"
    TODAY=`date "+%Y-%m-%d"`
    BPATH="$ROOT/$TODAY/$USER"
    if [ -e "$BPATH/$CALNAME" ]; then
    rm -rf "$BPATH/$CALNAME"
    fi
    mkdir -p $BPATH 2>/dev/null

    wget  -q --no-check-certificate --auth-no-challenge --no-clobber \
    --http-user=$BUSER -O $BPATH/${BACKUPFILE} \
    "https://$SERVER/owncloud/remote.php/dav/calendars/$USER/${CALNAME}?export"

    STATUS=$?
    echo "Status wget: $?"


    if [ -e "$BPATH/$CALNAME" ]; then
        chmod 600 "$BPATH/$CALNAME"
    fi    
}

#
# get one addressbook for one specific user and addressbook
#
getcard() {
    local ADDRBOOKNAME="$1"
    local USER="$2"
    local BUSER="$3"
    local SERVER="$4"
    local ROOT="$5"

    BACKUPFILE="${ADDRBOOKNAME}.vcf"
    TODAY=`date "+%Y-%m-%d"`
    BPATH="$ROOT/$TODAY/$USER"
    if [ -e "$BPATH/$BACKUPFILE" ]; then
    rm -rf "$BPATH/$BACKUPFILE"
    fi
    mkdir -p $BPATH 2>/dev/null

    wget -q --no-check-certificate --auth-no-challenge --no-clobber \
         --http-user=backup --http-password=$AUTHPW   \
         -O "$BPATH/$BACKUPFILE"   \
         "$SERVER/owncloud/remote.php/carddav/addressbooks/$USER/${ADDRBOOKNAME}?export" \
    STATUS=$?
    echo "Status wget: $?"

    if [ -e "$BPATH/$BACKUPFILE" ]; then
        chmod 600 "$BPATH/$BACKUPFILE"
    fi    
}


#
# Backup all calendars
#
for i in $USER; do
   CALLIST=${CALENDAR[$i]}
   echo "$CALLIST"
   for j in $CALLIST; do
    echo "Getting cal  $i, $j"
        getcal "$j" "$i" "$AUTHUSER" "$OCSERVER" "$BACKUPROOT"
   done
done   

#
# Backup all addressbooks
#
for i in $USER; do
   CARDLIST=${CONTACT[$i]}
   echo "$CARDLIST"
   for j in $CARDLIST; do
    echo "Getting card  $i, $j"
        getcard  "$j" "$i" "$AUTHUSER" "$OCSERVER" "$BACKUPROOT"
   done
done   

#
# cleanup
#
echo "Cleaning up old backups ..."
cd $BACKUPROOT
if [ $? != 0 ]; then
  echo "$0: Cannot chdir into $BACKUPROOT. Stop"
  exit 1
fi

NUM="+$GENERATIONS"
for i in `ls -1|sort -r|tail -n ${NUM}`; do
    echo "Deleting: $BACKUPROOT/$i"
    rm -rf "$i"
done

kill -TERM  $$