@@ -4,9 +4,12 @@ set -u # Treat unset variables as an error.
44
55FAILED_CONVERSIONS=" /config/failed_conversions"
66SUCCESSFUL_CONVERSIONS=" /config/successful_conversions"
7+ IGNORED_CONVERSIONS=" /config/ignored_conversion"
78
89HANDBRAKE_CLI=" /usr/bin/HandBrakeCLI --preset-import-file /config/ghb/presets.json"
910
11+ CONTAINER_INSTANCE_ID=" $( cat /config/machine-id) "
12+
1013# https://gist.github.com/aaomidi/0a3b5c9bd563c9e012518b495410dc0e
1114VIDEO_FILE_EXTENSIONS_INTERNAL_LIST=" \
1215 webm mkv flv vob ogv ogg rrc gifv mng mov avi qt wmv yuv rm asf amv mp4 \
@@ -42,6 +45,13 @@ log() {
4245 echo " $* "
4346}
4447
48+ is_dir_writable () {
49+ tmpfile=" $( mktemp " $1 " /.test_XXXXXX 2> /dev/null) "
50+ rc=$?
51+ rm -f " $tmpfile "
52+ return " $rc "
53+ }
54+
4555log_hb_encode_progress () {
4656 while read OUTPUT; do
4757 echo " Encoding $video : $OUTPUT "
@@ -121,6 +131,43 @@ get_video_titles() {
121131 return ${PIPESTATUS[0]}
122132}
123133
134+ get_video_lock_dname () {
135+ video=" $1 "
136+ wf=" $2 "
137+ lock_dname=" $( echo " $video " | sed " s|^$wf ||" | tr ' /' ' .' ) " .lock
138+ echo " $lock_dname "
139+ }
140+
141+ lock_video () {
142+ video=" $1 "
143+ wf=" $2 "
144+
145+ if ! is_dir_writable " $wf " ; then
146+ return 0
147+ fi
148+
149+ lock_dname=" $( get_video_lock_dname " $video " $" $wf " ) "
150+ err=" $( mkdir " $wf " /" $lock_dname " 2>&1 ) "
151+ rc=$?
152+ if [ " $rc " -eq 0 ]; then
153+ mkdir " $wf " /" $lock_dname " /" $CONTAINER_INSTANCE_ID "
154+ return 0
155+ else
156+ if echo " $err " | grep -iq " File exists" ; then
157+ return 1
158+ else
159+ return 2
160+ fi
161+ fi
162+ }
163+
164+ unlock_video () {
165+ video=" $1 "
166+ wf=" $2 "
167+ lock_dname=" $( get_video_lock_dname " $video " $" $wf " ) "
168+ rm -rf " $wf " /" $lock_dname "
169+ }
170+
124171process_video () {
125172 video=" $1 "
126173 wf=" $2 "
@@ -161,6 +208,24 @@ process_video() {
161208 return
162209 fi
163210
211+ # Skip video if it has been ignored.
212+ if [ -f " $IGNORED_CONVERSIONS " ] && grep -q -w " $hash " " $IGNORED_CONVERSIONS " ; then
213+ log " Skipping video '$video ' ($hash ): has been processed by another instance."
214+ return
215+ fi
216+
217+ # Skip video if it is being processed by another instance.
218+ lock_video " $video " " $wf "
219+ lock_rc=$?
220+ if [ " $lock_rc " -eq 1 ]; then
221+ echo " $video $hash " >> " $IGNORED_CONVERSIONS "
222+ log " Skipping '$video ': currently beging processed by another instance."
223+ return
224+ elif [ " $lock_rc " -eq 2 ]; then
225+ log " ERROR: Unable to acquire lock for video '${video} ' (${hash} )."
226+ return
227+ fi
228+
164229 # Set the output directory.
165230 case " $AC_OUTPUT_SUBDIR " in
166231 UNSET)
@@ -196,6 +261,7 @@ process_video() {
196261 # Get video titles.
197262 if $FILE_EXT_IN_VIDEO_LIST && $FILE_EXT_IN_NON_VIDEO_LIST ; then
198263 log " ERROR: File '${video} ' (${hash} ) has an extension defined as both a video and non-video file."
264+ unlock_video " $video " " $wf "
199265 return
200266 elif [ -n " $AC_VIDEO_FILE_EXTENSIONS " ] && ! $FILE_EXT_IN_VIDEO_LIST ; then
201267 log " File '${video} ' (${hash} ) has an extension not part of the inclusion list."
@@ -417,29 +483,34 @@ process_video() {
417483 fi
418484 echo " $video $hash " >> " $FAILED_CONVERSIONS "
419485 fi
486+
487+ unlock_video " $video " " $wf "
420488}
421489
422490process_watch_folder () {
423491 WF=" $1 "
424-
425492 NUM_PROCESSED_FILES=0
426493
494+ # Return now if the watch folder doesn't exist.
427495 [ -d " $WF " ] || return
496+
497+ # Remove any left-over locks for our own instance.
498+ find " $WF " -mindepth 1 -maxdepth 1 -type d -name " *.lock" | while read -r d; do
499+ if [ -e " $d " /" $CONTAINER_INSTANCE_ID " ]; then
500+ rm -rf " $d "
501+ fi
502+ done
503+
504+ # Return now if the watch folder didn't change.
428505 WATCHDIR_HASH_changed " $WF " || return
429506
430507 # Make sure the output directory is properly setup.
431508 if [ ! -d " $AC_OUTPUT_DIR " ]; then
432509 log " ERROR: Cannot process watch folder '$WF ', because the associated output directory '$AC_OUTPUT_DIR ' doesn't exist."
433510 return
434- else
435- TMPFILE=" $( mktemp " $AC_OUTPUT_DIR " /.test_XXXXXX 2> /dev/null) "
436- RC=$?
437- if [ " $RC " -eq 0 ]; then
438- rm " $TMPFILE "
439- else
440- log " ERROR: Cannot process watch folder '$WF ', because the associated output directory '$AC_OUTPUT_DIR ' is not writable."
441- return
442- fi
511+ elif ! is_dir_writable " $AC_OUTPUT_DIR " ; then
512+ log " ERROR: Cannot process watch folder '$WF ', because the associated output directory '$AC_OUTPUT_DIR ' is not writable."
513+ return
443514 fi
444515
445516 if WATCHDIR_HASH_isset " $WF " ; then
@@ -507,6 +578,7 @@ process_watch_folder() {
507578
508579[ -f " $FAILED_CONVERSIONS " ] || touch " $FAILED_CONVERSIONS "
509580[ -f " $SUCCESSFUL_CONVERSIONS " ] || touch " $SUCCESSFUL_CONVERSIONS "
581+ [ -f " $IGNORED_CONVERSIONS " ] || touch " $IGNORED_CONVERSIONS "
510582
511583while true ; do
512584 for i in $( seq 1 ${AUTOMATED_CONVERSION_MAX_WATCH_FOLDERS:- 5} ) ; do
0 commit comments