There is a bookmark manager for Nextcloud that can be used with the floccus browser extension to synchronize bookmarks using Chrome, Firefox, and Opera. I will show you how to perform API calls to automate the backup process.
Prerequisites
Install curl
utility to perform API calls.
$ sudo apt-get install curl
Install jq
utility to parse JSON files.
$ sudo apt-get install jq
Create an application password
Create a Nextcloud application password, do not use your regular credentials.
Download Nextcloud bookmarks
This usage scenario use curl
and jq
to export bookmarks.
Shell script
#!/bin/bash # Download Nextcloud bookmarks # https://sleeplessbeastie.eu/2018/04/18/how-to-backup-and-restore-nextcloud-bookmarks/ # current date and time current_datetime="$(date +%Y%m%d_%H%M%S)" # usage info usage(){ echo "Usage:" echo " $0 -r nextcloud_url -u username -p passsword [-f filename|-t]" echo "" echo "Parameters:" echo " -r nextcloud_url : set Nextcloud URL (required)" echo " -u username : set username (required)" echo " -p password : set password (required)" echo " -f filename : set filename w/o suffix (optional)" echo " -t : add timestamp to output filename (optional)" echo "" } # parse parameters while getopts "r:u:p:f:t" option; do case $option in "r") param_nextcloud_address="${OPTARG}" param_nextcloud_address_defined=true ;; "u") param_username="${OPTARG}" param_username_defined=true ;; "p") param_password="${OPTARG}" param_password_defined=true ;; "f") param_filename="${OPTARG}" param_filename_defined=true ;; "t") param_date_prefix=true ;; \?|:|*) usage exit ;; esac done if [ "${param_nextcloud_address_defined}" = true ] && \ [ "${param_username_defined}" = true ] && \ [ "${param_password_defined}" = true ]; then if [ "${param_filename_defined}" = true ]; then filename="${param_filename}" else filename="nextcloud-bookmarks" fi if [ "${param_date_prefix}" = true ]; then filename="${filename}-${current_datetime}.html" else filename="${filename}.html" fi result=$(curl --silent --output - -X GET --user "${param_username}:${param_password}" --header "Accept: application/json" "${param_nextcloud_address}/apps/bookmarks/public/rest/v2/bookmark" | \ jq -r 'select(.status != "success") | .status') if [ -n "${result}" ]; then echo "There was an error \"${result}\' when downloading Nextcloud bookmarks for user ${param_username}. Skipping." else curl --silent --output "${filename}" -X GET --user "${param_username}:${param_password}" "${param_nextcloud_address}/apps/bookmarks/public/rest/v2/bookmark/export" echo "Downloaded Nextcloud bookmarks to file \"${filename}\"" fi else usage fi
Usage
Display usage information.
$ nextcloud_bookmarks_get.sh Usage: nextcloud_bookmarks_get.sh -r nextcloud_url -u username -p passsword [-f filename|-t] Parameters: -r nextcloud_url : set Nextcloud URL (required) -u username : set username (required) -p password : set password (required) -f filename : set filename w/o suffix (optional) -t : add timestamp to output filename (optional)
Export bookmarks.
$ nextcloud_bookmarks_get.sh -r https://cloud.example.org -u milosz -p "Mjdu3-kDnru-4UksA-fYs0w" Downloaded Nextcloud bookmarks to file "nextcloud-bookmarks.html"
Export bookmarks and append timestamp to the filename.
$ nextcloud_bookmarks_get.sh -r https://cloud.example.org -u milosz -p "Mjdu3-kDnru-4UksA-fYs0w" Downloaded Nextcloud bookmarks to file "nextcloud-bookmarks-20180416_214516.html"
Export bookmarks to the custom file with a timestamp.
$ nextcloud_bookmarks_get.sh -r https://cloud.example.org -u milosz -p "Mjdu3-kDnru-4UksA-fYs0w" -t -f milosz-bookmarks Downloaded Nextcloud bookmarks to file "milosz-bookmarks-20180416_214645.html"
Upload Nextcloud bookmarks
This usage scenario is more complicated as you need to extract and use the request token to pass CSRF verification.
Shell script
#!/bin/bash # Upload and restore Nextcloud bookmarks # https://sleeplessbeastie.eu/2018/04/18/how-to-backup-and-restore-nextcloud-bookmarks/ # temporary file to store cookie cookie_file=$(mktemp) # delete temporary file on exit trap "unlink $cookie_file" EXIT # usage info usage(){ echo "Usage:" echo " $0 -r nextcloud_url -u username -p passsword -f json_board_file" echo "" echo "Parameters:" echo " -r nextcloud_url : set Nextcloud URL (required)" echo " -u username : set username (required)" echo " -p password : set password (required)" echo " -f file : exported bookmarks (required)" echo "" } # parse parameters while getopts "r:u:p:f:" option; do case $option in "r") param_nextcloud_address="${OPTARG}" param_nextcloud_address_defined=true ;; "u") param_username="${OPTARG}" param_username_defined=true ;; "p") param_password="${OPTARG}" param_password_defined=true ;; "f") param_file="${OPTARG}" param_file_defined=true ;; \?|:|*) usage exit ;; esac done if [ "${param_nextcloud_address_defined}" = true ] && \ [ "${param_username_defined}" = true ] && \ [ "${param_password_defined}" = true ] && \ [ "${param_file_defined}" = true ] && \ [ -f "${param_file}" ]; then request_token=$(curl -c ${cookie_file} --silent --location -X GET --user "${param_username}:${param_password}" "${param_nextcloud_address}/apps/bookmarks/bookmark/" | grep "data-requesttoken" | sed "s/.*<head.*\"\(.*\)\">/\1/") result=$(curl -b ${cookie_file} --silent --header "OCS-REQUEST: true" --header "requesttoken: ${request_token}" -F "bm_import=@./${param_file};type=text/html" --location -X POST --user "${param_username}:${param_password}" --header 'Accept: application/json' "${param_nextcloud_address}/index.php/apps/bookmarks/bookmark/import" | jq -r 'select(.status != "success") | .status') if [ -n "${result}" ]; then echo "There was an error \"${result}\". Skipping." else echo "Uploaded Nextcloud bookmarks from file \"${param_file}\"" fi else usage fi
Usage
Display usage information.
$ nextcloud_bookmarks_put.sh Usage: nextcloud_bookmarks_put.sh -r nextcloud_url -u username -p passsword -f json_board_file Parameters: -r nextcloud_url : set Nextcloud URL (required) -u username : set username (required) -p password : set password (required) -f file : exported bookmarks (required)
Restore bookmarks from a file.
$ nextcloud_bookmarks_put.sh -r https://cloud.example.org -u milosz -p "Mjdu3-kDnru-4UksA-fYs0w" -f milosz-bookmarks-20180416_214645.html Uploaded Nextcloud bookmarks from file "milosz-bookmarks-20180416_214645.html"
Additional notes
The structure of the exported file.
<!DOCTYPE NETSCAPE-Bookmark-file-1> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <!-- This is an automatically generated file. It will be read and overwritten. Do Not Edit! --> <TITLE>Bookmarks</TITLE> <H1>Bookmarks</H1> <DL><p><DT><A HREF="https://sleeplessbeastie.eu/" TAGS="floccus:>Prywatne">sleeplessbeastie's notes</A> <DT><A HREF="https://sleeplessbeastie.eu/" TAGS="floccus:>Prywatne">sleeplessbeastie's home</A>
It is possible to use a single API request to import bookmarks, but it requires setting the @NoCSRFRequired
annotation before the importBookmark
controller method.
controller/rest/bookmarkcontroller.php @@ -330,6 +330,8 @@ public function clickBookmark($url = "") { * @return \OCP\AppFramework\Http\JSONResponse * * @NoAdminRequired + * @NoCSRFRequired + * @CORS */ public function importBookmark() { $full_input = $this->request->getUploadedFile("bm_import");
$ curl -F "bm_import=@./nextcloud-bookmarks.html;type=text/html" -L -X POST --user milosz:Mjdu3-kDnru-4UksA-fYs0w https://cloud.example.org/apps/bookmarks/public/rest/v2/bookmark/import {"status":"success"}
This modification will be available in the next application version, cool.
Please read Open Collaboration Services v2.0 and Nextcloud 13 Developer Manual.
Download source code.