Skip to content

Instantly share code, notes, and snippets.

@vmx
Created May 7, 2021 14:56
Show Gist options
  • Save vmx/0eb472ce69c218960912906e21caaae7 to your computer and use it in GitHub Desktop.
Save vmx/0eb472ce69c218960912906e21caaae7 to your computer and use it in GitHub Desktop.
Seafile: copying directories that contain some files (for FOSSGIS 2021)
#!/bin/sh
#set -o xtrace
# SPDX-FileCopyrightText: Volker Mische <[email protected]>
# SPDX-License-Identifier: MIT
# Copies all sub-directories (direct ones, not deeper nested ones) which
# contain at least one file into another directory. It creates the target
# directory if it doesn't exist.
#
# You need to have the following utilities installed:
# curl, jo, jq
# You can get your auth token via
# curl -X POST --data "username=<your-username>&password=<your-password>" '<you-server>/api2/auth-token/'
if [ "${#}" -lt 5 ]; then
echo "Usage: $(basename "${0}") <base-url> <auth-token> <repo-id> <source-directory> <target-directory>"
echo ""
echo "Example: $(basename "${0}") https://example.org fe91e764226cc534811f0ba32c62a6ac41ad0d7b 280b593a-f868-0594-d97a-23d88822a35f source_dir target_dir"
exit 1
fi
base_url=${1}
token=${2}
repo_id=${3}
source_dir=${4}
target_dir=${5}
api_v20="${base_url}/api2"
api_v21="${base_url}/api/v2.1"
# Check if target directory exists, if not, create it
details_code=$(curl --silent -X GET --header "Authorization: Token ${token}" "${api_v21}/repos/${repo_id}/dir/detail/?path=/${target_dir}" --output /dev/null --write-out '%{http_code}')
if [ "${details_code}" = "404" ]
then
mkdir_ret=$(curl --silent -X POST --header "Authorization: Token ${token}" "${api_v20}/repos/${repo_id}/dir/?p=/${target_dir}" --data 'operation=mkdir')
if [ "${mkdir_ret}" != '"success"' ]
then
echo "Error: cannot create directory '${target_dir}'."
exit 1
fi
fi
# Get all directories with more than 1 file in it
list_dirs_ret=$(curl --silent -X GET --header "Authorization: Token ${token}" "${api_v20}/repos/${repo_id}/dir/?p=/${source_dir}&t=d"|jq --raw-output '.[].name')
dirs_to_copy=""
for dir_name in ${list_dirs_ret}
do
num_files=$(curl --silent -X GET --header "Authorization: Token ${token}" "${api_v20}/repos/${repo_id}/dir/?p=/${source_dir}/${dir_name}&t=f"|jq 'length')
# Print progress indicator to stderr, so that you can still pipe the
# expected output into a file.
echo "${dir_name} has ${num_files} files…" >&2
if [ "${num_files}" -gt 0 ]
then
dirs_to_copy="${dirs_to_copy} ${dir_name}"
fi
done
# Copy those directories
# shellcheck disable=SC2086 # We need word splitting here
src_dirents=$(jo -a ${dirs_to_copy})
copy_parameters=$(jo src_repo_id="${repo_id}" src_parent_dir="/${source_dir}/" src_dirents="${src_dirents}" dst_repo_id="${repo_id}" dst_parent_dir="/${target_dir}/")
echo "${copy_parameters}"
copy_ret=$(curl --silent -X POST --header 'Content-Type: application/json' --header "Authorization: Token ${token}" "${api_v21}/repos/sync-batch-copy-item/" -d "${copy_parameters}")
if [ "${copy_ret}" != "$(jo success=true)" ]
then
echo "Error: cannot copy from '${source_dir}' to '${target_dir}'."
exit 2
fi
echo "Copied files successfully from '${source_dir}' to '${target_dir}'."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment