Skip to content

Instantly share code, notes, and snippets.

@jamesstout
Last active June 8, 2021 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesstout/f7cbe3def672f00a9bd6a7b008d7704f to your computer and use it in GitHub Desktop.
Save jamesstout/f7cbe3def672f00a9bd6a7b008d7704f to your computer and use it in GitHub Desktop.
Cleanup conflicted Nextcloud files
#!/usr/bin/env bash
# shellcheck shell=bash
# set -x
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Header logging
e_header() {
printf "\n$(tput setaf 7)%s$(tput sgr0)\n" "$@"
}
# debug logging
e_debug() {
printf "$(tput setaf 2)%s$(tput sgr0)\n" "$@"
}
# Success logging
e_success() {
printf "$(tput setaf 64)✓ %s$(tput sgr0)\n" "$@"
}
# Error logging
e_error() {
printf "$(tput setaf 1)x %s$(tput sgr0)\n" "$@"
}
# Warning logging
e_warning() {
printf "$(tput setaf 136)! %s$(tput sgr0)\n" "$@"
}
dir_exists() {
if [ -d "$1" ]; then
return 0
fi
return 1
}
file_exists() {
if [ -e "$1" ]; then
return 0
fi
return 1
}
function check_ext {
fullpath="$1"
filename="${fullpath##*/}" # Strip longest match of */ from start
dir="${fullpath:0:${#fullpath} - ${#filename}}" # Substring from 0 thru pos of filename
base="${filename%.[^.]*}" # Strip shortest match of . plus at least one non-dot char from end
ext="${filename:${#base} + 1}" # Substring from len of base thru end
if [[ -z "$base" && -n "$ext" ]]; then # If we have an extension and no base, it's really the base
base=".$ext"
ext=""
fi
corrected_base=$(echo "$base" | cut -d' ' -f1)
# echo -e "$fullpath:\n\tdir = \"$dir\"\n\tbase = \"$base\"\n\text = \"$ext\"\n\tcorrected = \"$corrected_base\""
if [[ -n "$ext" ]]; then
ext=".$ext"
fi
echo "$dir$corrected_base$ext"
}
DRY_RUN=1
INDEX_FILE="$DIR/index.txt"
INDEX_ARRAY=[]
count=0
DIRECTORY_OPTION=""
# I want a file with the files in for reference
function add_file_to_index {
echo "$1" >> "$INDEX_FILE"
}
function add_directory_to_index {
find "$DIRECTORY_OPTION" -name '*conflict*' -type f -print0 | while read -d '' -r file; do
add_file_to_index "$file"
done
}
function clean {
rm "$INDEX_FILE"
touch "$INDEX_FILE"
}
function parse_index {
IFS=$'\n' read -d '' -r -a INDEX_ARRAY < "$INDEX_FILE"
TOTAL_IMAGES=${#INDEX_ARRAY[@]}
}
function usage {
echo 'Usage: cleanup-conflicts.sh [-e] -d /path/to/files'
}
function process_files {
for conflicted_file in "${INDEX_ARRAY[@]}"; do
echo
e_debug "conflicted_file: $conflicted_file"
ORIG_FILENAME=$(check_ext "$conflicted_file")
e_debug "orig = $ORIG_FILENAME"
# stat -f"%m" gives you the modification time on OSX
e_debug "stat conflicted"
CONFLICTED_FILE_MOD_TIME=$(stat -f"%m" "$conflicted_file")
e_debug "stat orig"
ORIG_FILE_MOD_TIME=$(stat -f"%m" "$ORIG_FILENAME")
if [[ CONFLICTED_FILE_MOD_TIME -gt ORIG_FILE_MOD_TIME ]]; then
e_success "conflicted_file is newer"
# so we want to remove the original file and
# replace it with the conflited file with the right name
if [ "$DRY_RUN" = 1 ]; then
e_warning "would exec rm $ORIG_FILENAME"
e_warning "would exec mv $conflicted_file $ORIG_FILENAME"
else
rm "$ORIG_FILENAME"
mv "$conflicted_file" "$ORIG_FILENAME"
((count++))
fi
fi
done
}
while [ "$1" != "" ]; do
case $1 in
-d | --directory )
shift;
DIRECTORY_OPTION="$1"
;;
-e | --execute )
DRY_RUN=0
;;
-h | --help )
usage;
exit 0
;;
* )
usage
exit 1
esac
shift
done
if ! dir_exists "$DIRECTORY_OPTION"; then
e_error "$DIRECTORY_OPTION does not exist, did you set the -d param correctly?"
exit 255
fi
e_header "Starting conflicting file cleanup"
clean
add_directory_to_index
parse_index
process_files
e_debug "TOTAL CONFLICTS: $TOTAL_IMAGES"
e_debug "TOTAL FIXED: $count"
@rugk
Copy link

rugk commented Jun 8, 2021

BTW to make it work on Unix/Linux, you need to use stat -c %Y instead of stat -f"%m". Just change that and it should work. (It could also be made really portable/cross-platform compatible with an if as shown in the Stackexchange answer, FYI.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment