Skip to content

Instantly share code, notes, and snippets.

@bitifet
Last active July 12, 2018 17:43
Show Gist options
  • Select an option

  • Save bitifet/d4a365c2b4eb0e7e6e84eeaf21b79687 to your computer and use it in GitHub Desktop.

Select an option

Save bitifet/d4a365c2b4eb0e7e6e84eeaf21b79687 to your computer and use it in GitHub Desktop.
NextCloud Hacks
#!/usr/bin/env bash
/home/www/scripts/fixletime.sh --silent /home/www/nextcloud_data 1 \
&& php -f /home/www/nextcloud/occ files:scan --all -u
# m h dom mon dow command
# NextCloud Cron tasks:
*/15 * * * * php -f /var/www/nextcloud/cron.php
# Dayly batches:
0 0 * * * /home/www/scripts/batch.sh
#!/usr/bin/env bash
cmd=$(basename "${0}");
now=$(date "+%Y%m%d%H%M%S");
# Define file extensions to look for:
extensions="jpeg jpg png gif mp4 avi"
# function helpMessage()#{{{
function helpMessage() {
echo ""
echo "${cmd} - Fix file timestamps."
echo ""
echo "USAGE";
echo " ${cmd} [--silent] <path> [days]";
echo " ${cmd} -h";
echo ""
echo "DESCRIPTION"
echo " Fix media files ctime and mtime acording "
echo " exif headers or filename pattern."
echo ""
echo "ARGUMENTS"
echo " --silent Supress feedback output."
echo " <path> Path from which to search."
echo " [days] Maximum days ago of current file timestamp"
echo " to be re-checked (default: no limit)."
echo ""
}
#}}}
# function writetxt()#{{{
function writetxt() {
if [[ "${silentMode}" == "1" ]]; then return; fi;
echo $@
}
#}}}
# function smartident()#{{{
function smartident() {
# Do almost nothing but avoid time waste ;-)
local fpath="${1}";
if [[ "${fpath}" =~ \.mp4$ ]]; then
# Workarround issue with .mp4 files that identify seem to threat as
# (too many) image files and delay too much to finish. Also they seem
# to be temp files so their 'date:create:' 'date:modify:' headers become
# current time resulting in wrong result.
# FIX 1: Process in background and capture only first 1000 rows.
## Credits: https://stackoverflow.com/a/20018118/4243912
## DISABLED because the only timestamp source left was a 'Base
## filename' field in case it contains timestamp string.
## ...but later I checked that this is also generated by identify
## using current file name (so even not overcomes renamings).
##exec 3< <(identify -verbose "${fpath}")
##head -n 1000 <&3
# FIX 2: Just do nothing.
# Omitting identify output we save time and processing too
# and even hope in file name timestamp patterns if we are lucky.
# TODO: Find better way to gues mp4 header timestamps (if they really
# exists).
echo ""; # Fix bash 'if' stamment crying for nothint to do ;-)
else
identify -verbose "${fpath}";
fi;
}
#}}}
# function commonVars()#{{{
function commonVars() {
# Timestamp capturing regex:
regex_timestamp='
^ # String begin
(?:
.*?:\s* # Some label ended in ":" and optional spacing
|.*?\D # ...or anything up to some non numeric character
)? # ...or just nothing (beginnig of the string)
# Capture (YYYY)(MM)(DD) with optional "-" or ":" separators:
([12]\d{3})[:-]?(\d{2})[:-]?(\d{2})
# Capture additional (HH)(MM)[SS] (if given)
(?:[:_\s-]?(\d{2})[:-]?(\d{2})[:-]?(\d{2})?)?
# Followed by non-digit character or simply the end of the string:
(?:(\D.*))?$
# Capture whole string (to remove it) else case:
|.*
';
pl_capture_date="s/${regex_timestamp}/\$1\$2\$3/x";
pl_capture_time="s/${regex_timestamp}/\$4\$5\$6/x";
pl_capture_timestamp="s/${regex_timestamp}/\$1\$2\$3\$4\$5\$6/x";
}
#}}}
# function guessdate()#{{{
function guessdate() {
## REQUIRES commonVars ##
local fpath="${1}";
local fname=$(basename "${fpath}");
local ident=$(smartident "${fpath}");
# Calculate earliest reasonable time limit:
local filetimestamp=$( \
( \
echo "${now}";
stat --printf '%x\n%y' "${fpath}" \
) | sort -u \
| head -n 1 \
| perl -pe "${pl_capture_timestamp}" \
);
# Search time patterns against exif and non exif headers and filename:
local timestr=$( \
( \
echo "$ident" | grep -i 'exif:DateTimeOriginal:' \
|| echo "$ident" | grep -i 'exif:DateTimeDigitalized:' \
|| echo "$ident" | grep -i 'exif:DateTime:' \
|| echo "$ident" | grep -i 'date:create:' \
|| echo "$ident" | grep -i 'date:modify:' \
|| echo "$ident" | grep -i 'exif:GPSDateStamp:' \
|| echo "$fname" \
) \
| head -n 1 \
);
local datepart=$(echo "${timestr}" | perl -pe "${pl_capture_date}");
local timepart=$(echo "${timestr}" | perl -pe "${pl_capture_time}");
[[ -n "${timepart}" ]] || timepart="0000";
local t="${datepart}${timepart}";
local timestring="${t:0:4}-${t:4:2}-${t:6:2} ${t:8:2}:${t:10:2}";
[[ -n "${t:13:1}" ]] && timestring="${timestring}:${t:12:2}"; # Consider seconds if available.
# Check $t is valid and not after $filetimestamp.
[[ -n "${t}" ]] \
&& [[ "${t}" < "${filetimestamp}" ]] \
&& date -d "${timestring}" > /dev/null 2>&1
local time_err=$?
if [[ "${time_err}" -eq "0" ]]; then
# Got valid timestamp earlier than file time and not in the future.
###echo " * $fpath ---> $t";
local ttime="${t:0:12}";
[[ -n "${t:13:1}" ]] && ttime="${ttime}.${t:12:2}"; # Consider seconds in touch format
touch -c -t "${ttime}" "${fpath}"
writetxt -n '!'
else
writetxt -n '.'
fi;
}
#}}}
### ( Arguments processing ) ###
# Modifiers:
if [[ "${1}" == "-h" ]]; then
helpMessage;
exit 0;
fi;
silentMode="0";
if [[ "${1}" == "--silent" ]]; then
silentMode="1";
shift;
fi;
# Starting path
if ! [[ "${1}" =~ ^[0-9]*$ ]]; then
pathArg=$(realpath "${1}")
shift;
else
echo 'Path argument is mandatory!!'
echo ' Use "./" if you want to search from current path.'
echo ' Type "${cmd} -h" for help message.'
exit 1;
fi;
# Optional days to check (default infinite) argument
if [[ "${1}" =~ ^[0-9]+$ ]]; then
daysArg=" -a -mtime -${1}"
else
daysArg=""
fi;
### ( Main ) ###
patts="-iname '*.$(echo $extensions | perl -pe "s/ /' -o -iname '*./g")'"
listfilesCmd="find \"${pathArg}\" \( ${patts} \)${daysArg}"
writetxt -n "Processing:";
commonVars;
eval "${listfilesCmd}" | while read f; do
guessdate "${f}";
done;
writetxt '';
writetxt 'DONE!!';

My personal NextCloud hacks

fixletime.sh

Script to 'touch' media (photo / video) files to the time that they have been taken (according available information: exif headers, filename patterns..).

$ ./fixletime.sh -h

fixletime.sh - Fix file timestamps.

USAGE
    fixletime.sh [--silent] <path> [days]
    fixletime.sh -h

DESCRIPTION
    Fix media files ctime and mtime acording 
    exif headers or filename pattern.

ARGUMENTS
    --silent  Supress feedback output.
    <path>    Path from which to search.
    [days]    Maximum days ago of current file timestamp
              to be re-checked (default: no limit).

batch.sh and crontab

Automation stuff...

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