Search code examples
owncloud

Owncloud Calendar ICS Backup


I wanted to have a regular backup of my Owncloud calendars as ICS files, in case the server runs into a problem that I don't have time to fix right away. For this purpose I wrote a little script, which can be run as a cronjob.

Any feedback, improvements, alterations are welcome!


Solution

  • DISCLAIMER: I created this script for a little Owncloud instance that I run for myself and 1-2 other friends - it is not meant for any "serious business", so to speak. I used the scripts from this and this site as a starting point - thank you!

    To create ics backups of all the user calendars, I created an Owncloud user called "calendarBackup", who other users can share their calendars with. I wrote a little script, that loops through all those calendars and downloads the ics files. They are then put into a shared folder owned by the calendarBackup, and the backup is distributed across users. (An easy adjustment could be made, so that each user gets his own calendar files.)

    The advantage to this approach is that the script doesn't need to know all the user passwords.

    Here the code:

    #!/bin/bash
    
    #owncloud login data for calendar backup user
    OCuser=owncloudUserName
    OCpassword="owncloudUserPassword"
    OCpath="/var/www/owncloud/"
    OCbaseURL="https://localhost/owncloud/"
    OCdatabase="owncloudDatabaseName"
    
    #destination folder for calendar backups
    dest="/var/www/owncloud/data/owncloudUserName/files/Backup/"
    
    #mysql user data with access to owncloud database
    MSQLuser=owncloudMysqlUser
    MSQLpassword="owncloudMysqlUserPassword"
    
    #timestamp used as backup name
    timeStamp=$(date +%Y%m%d%H%M%S)
    archivePassword="passwordForArchivedCalendars"
    
    #apachee user and group
    apacheUser="apacheUser"
    apacheGroup="apacheGroup"
    
    #create folder for new backup files
    mkdir "$dest$timeStamp"
    
    #create array of calendar names from Owncloud database query
    calendars=($(mysql -B -N -u $MSQLuser -p$MSQLpassword -e "SELECT uri FROM $OCdatabase.oc_calendars"))
    calendarCount=${#calendars[@]}
    
    #create array of calendar owners from Owncloud database query
    owners=($(mysql -B -N -u $MSQLuser -p$MSQLpassword -e "SELECT principaluri FROM $OCdatabase.oc_calendars"))
    
    
    loopCount=0
    
    #loop through all calendars
    while [ $loopCount -lt $calendarCount ]
    do
        #see if owner starts with "principals/users/"
        #(this part of the script assumes that principaluri for normal users looks like this: principal/users/USERNAME )
        if [ "${owners[$loopCount]:0:17}" = "principals/users/" ]
        then
            #concatenate download url
            url=$OCbaseURL"remote.php/dav/calendars/$OCuser/${calendars[$loopCount]}_shared_by_${owners[$loopCount]:17}?export"
    
            #echo $url
    
            #download the ics files (if download fails, delete file)
            wget \
            --output-document="$dest$timeStamp/${owners[$loopCount]:17}${calendars[$loopCount]}.ics" \
            --no-check-certificate --auth-no-challenge \
            --http-user=$OCuser --http-password="$OCpassword" \
            "$url" || rm "$dest$timeStamp/${owners[$loopCount]:17}${calendars[$loopCount]}.ics"
    
            #echo ${owners[$loopCount]:17}
        fi
        #echo "${calendars[$loopCount]} ${owners[$loopCount]}" 
        loopCount=$(($loopCount + 1))
    done
    
    #zip backed up ics files and remove the folder (this could easily be left out, change the chown command though)
    zip -r -m -j -P $archivePassword "$dest$timeStamp" "$dest$timeStamp"
    rm -R $dest$timeStamp
    #chown needed so owncloud can access backup file
    chown $apacheUser:$apacheGroup "$dest$timeStamp.zip"
    
    #update owncloud database of calendar backup user
    sudo -u $apacheUser php "$OCpath"occ files:scan $OCuser
    

    A few notes on the script:

    • It is written for a Debian shell.
    • It works for Owncloud 9.1 with Mysql.
    • It assumes the download URL for a shared calendar looks like this:

      OwncloudURL/remote.php/dav/calendars/LoggedInOwncloudUser/CalendarName_shared_by_CalendarOwner?export

      To check for the correct URL, simply download a shared calendar in the web interface and check the download URL.

    • It assumes that the calendar names are stored in the column "uri" of the table "oc_calendars".

    • It assumes that the calendar owner is stored in the column "principaluri" of the table "oc_calendars" and that all normal users are prefixed with "principals/users/".

    • It needs sudo permission to update Owncloud file structure.

    • It needs zip to be installed.