#!/bin/bash
#set -n		# read but do not execute commands (check on syntax errors)
#
# File: /usr/local/bin/movies-update
#
# Build all movie helper files.
#
#    Copyright (c) 2020 Juergen Kaesmann (JK)
#
##############################################################################
# GPL NOTICE
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
##############################################################################
# FIND
##############################################################################
# XARGS
##############################################################################
# FILTER
##############################################################################
# AWK
##############################################################################
# SED
##############################################################################
# TREE
##############################################################################
# RSYNC
##############################################################################
# DIALOG
##############################################################################
# EXIT CODES

##############################################################################
# SOURCE FILES
#
. /usr/local/etc/main.conf				# config main
#. $LLIBDIR/libfuncerr-sh				# functions error
. $LLIBDIR/libfuncstd-sh				# functions standard
#. $LLIBDIR/libfuncmath-sh				# functions math
#. $LLIBDIR/libfuncip-sh				# functions IP
. /usr/local/etc/multimedia.conf			# config multimedia

if [ ! -e ~/.multimediarc ]; then			# install config user
	update-multimedia
	err=$?
	if [ $err -eq 0 ]; then
		echo "User ~/.multimediarc installed. You should configure it."
		exit 0
	else
		Show_Err $err "From update-multimedia"
		exit $err
	fi
fi

if [ -e ~/.multimediarc ]; then
	. ~/.multimediarc				# config user
fi

##############################################################################
# DECLARATION OF STANDARD CONSTANTS AND VARIABLES
#
readonly package=Multimedia				# package name
readonly package_file=ksm-multimedia			# package file name
readonly vinfopath="/usr/local/share/$package_file"	# path to package dir
readonly version=$(/bin/cat $vinfopath/VERSION)		# package version
readonly release=$(/bin/cat $vinfopath/RELEASE)		# package release
readonly scriptname=$(basename $0)			# name of script
readonly tempfile=$TEMPDIR/$scriptname.$UID.tmp		# temporary file name
#tempfile=$(mktemp $TEMPDIR/$scriptname.$UID.XXXXXX)	# temporary file name
#readonly lockfile=$TEMPDIR/lock/$scriptname.$UID.lock	# lock file name
readonly debuglog="/usr/bin/logger -p user.debug -t $scriptname -- DEBUG:"	# log dbg msg
readonly errlog="/usr/bin/logger -p user.err -t $scriptname -- ERROR:"		# log err msg
readonly infolog="/usr/bin/logger -p user.info -t $scriptname -- INFO:"		# log inf msg
cmd=''							# sub command
debug=no						# debug=yes/no
verbose=''						# verbose=yes/''/no
err=0							# error code

##############################################################################
# USER FILL IN AT FIRST RUN
##############################################################################
# SYSTEM
##############################################################################
# VLC
##############################################################################
# USER-CONSTANTS
##############################################################################
# USER-VARIABLES
#
# STRINGS
# From multimedia.conf:
# Multimedia_Conf
# AudioDir
# MP3Dir
# VideoDir
# FilmDir
# CDDB_Dir
# UserGroup
# DynProf[0]
# DynProf[1]
# DynProf[2]
# DynProf[3]
# DynProf[4]
# DynProf[5]

# From .multimediarc:
# Multimedia_Rc
# AudioDir
# MP3Dir
# VideoDir
# FilmDir
# FilmCache
# CDDB_Dir
# CDListDir
# M3uDir
# FilmListDir
# OvFile
# M3uFile
# UserGroup

#volfile=$HOME/daten/musik/active-lists/all-volumes.html
#songfile=$HOME/daten/musik/active-lists/all-songs.html
fdir=$FilmDir
cachedir=$FilmCache
moviesfile=$FilmListDir/all-movies.html
moviedfile=$FilmListDir/all-movied.html
fidxdir=Index
fpersdir=Personen

#args=''				# all args from cmdline
arg1=''					# 1. arg from cmdline
#opt_o=''				# option -o (yes)
					# option --output (yes)
#opt_i=''				# option -i (arg)
					# option --infile (arg)
#opt_o=''				# option -o (arg)
					# option --outfile (arg)
#opt_p=''				# option -p (arg)
					# option --pages (arg)

# NUMBERS
#p_first=0				# first page
#p_last=0				# last page

# ARRAYS
# Indexed arrays are always zero based string arrays.
# If index starts with 1 and all members are assigned then
# count of members of array = last index of array
#declare -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array
#
##############################################################################
# LANGUAGE SUPPORT
##############################################################################
# SIGNAL HANDLING

##############################################################################
# FUNCTIONS
##############################################################################
#
##############################################################################
# HELP
#
#=============================================================================
function helptext ()
{
# Output helptext
# Uses cat, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG helptext: $# $@" >&2
	$debuglog helptext: $# $@
fi

cat <<EOT
NAME
$scriptname - Build all movie files.

SYNOPSIS
$scriptname [options] [cov]

DESCRIPTION
Build all movie files for the browser:

  If no cmd given or for cmds -a, -s do:
  - Build the moviedir file - $moviedfile
  - Build the movies file - $moviesfile

  For cmds -a, -s do:
  - If cmd -a given then
    (Re)Build The movies cache $cachedir:
    a) Clear cache dir.
    b) Copy all cover images from $fdir
       to $cachedir
    c) Scale all images symmetrically to fit in 50x50 pix
       'scale-image -a -s 50 50'
    d) Move all scaled files to the old ones
       mmv -d "n*" "#1"

  - If cmd -r given then
    Remove one cover image from the movies cache
    $cachedir
    No further action is done.

  - If cmd -s given then
    (Re)Build only one cover image to the movies cache
    $cachedir, than:
    a) Scale the image symmetrically to fit in 50x50 pix
       'scale-image -a -s 50 50'
    b) Move the scaled file to the old file
       mmv -d "n*" "#1"

OPTIONS
Gnu style options:

  -h|--help    = Output help, then exit.
  -V|--version = Output version info, then exit.
  -d|--debug   = Turn on DEBUG mode.
  -q|--quiet   = Be quiet.
  -v|--verbose = Be verbose.
  -a           = (Re)build the whole movies cache.
  -r           = Remove one cover from the movies cache. If you remove
                 the corresponding filmdir completely then it has to be
                 removed before.
  -s           = (Re)build only one cover to the movies cache.
  --           = End of options.

ARGUMENTS
Give if needed:

  cov = A cover (full pathname) from the filmdir.
        Format: <path>/<Name>.COV.jpg

EXIT STATUS
On program exit:

  Code 0 = OK

  See output of 'showerrmsg'.

FILES
Used directories and files:

  Config Global                 = /usr/local/etc/multimedia.conf
  Config User                   = ~/.multimediarc
  Film Dir                      = $fdir
  Cache Dir (writable for user) = $cachedir

SEE ALSO
Related manpages:

  showerrmsg(1), scale-image(1).

AUTHORS
Juergen Kaesmann <juergen@kaesmann-online.de>
EOT
#  -o|--output  = Output to STDOUT.
#  -i f         = Input from file <f>.
#  --infile=f   = Input from file <f>.
#  -o f         = Output to file <f>.
#  --outfile=f  = Output to file <f>.
#  -p s,e       = Pages s=START e=END.
#  --pages=s,e  = Pages s=START e=END.

#EXAMPLES
#For instance:
#
#  Do it:
#  $scriptname

return
}

#=============================================================================
function make_movies_file ()
{
# Build the movies file for the browser.
# Uses date, echo, logger, tree
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG make_movies_file: $# $@" >&2
	$debuglog make_movies_file: $# $@
fi

local fn="" l="" lf="" ll="" nl=""
local ret=0

#│   │   │   ├── <a href="/var/binaries/videos/filme/abenteuer/sonstige-abenteuer_a-n/Am_wilden_Fluss/Am_wilden_Fluss.COV.jpg">Am_wilden_Fluss.COV.jpg</a><br>
#
# sample insert
#<img src="/home/jk/tmp/Am_wilden_Fluss.COV.jpg">

# sample line
#	│   │   │   └── <a href="/var/binaries/videos/filme/abenteuer/sonstige-abenteuer_a-n/Am_wilden_Fluss/Am_wilden_Fluss_01.H4SD.mp4">Am_wilden_Fluss_01.H4SD.mp4</a><br>
#
# sample insert
#<img src="/home/jk/tmp/Am_wilden_Fluss.COV.jpg">

echo "Make $moviesfile"
cd $fdir
tree -F -I $fidxdir -H $fdir | grep -v "/$fpersdir/" | grep -v INFO.mp4 | grep -v .mcf | grep -v .volume > $tempfile
ret=$?

cp /dev/null $moviesfile
while read l; do
	#echo "$l" | grep -q mp4
	echo "$l" | grep -q COV.jpg
	ret=$?
	if [ $ret -eq 0 ]; then
		# get base file name
		fn=${l%.*}
		fn=${fn#*>}
		#fn=${fn%_01.*}

		# build new line
		lf=${l%%<*}
		ll=${l#*<}
		#nl="${lf}<img src=\"${cachedir}/${fn}.COV.jpg\"> <${ll}"
		nl="${lf}<img src=\"${cachedir}/${fn}.jpg\"> <${ll}"

		# write new line
		echo "$nl" >> $moviesfile
	else
		echo "$l" >> $moviesfile
	fi
done < $tempfile
date -R >> $moviesfile
ret=$?
rm -f $tempfile

return $ret
}

#=============================================================================
function make_movies_cache ()
{
# Build the movies cache.
# Uses date, echo, logger, tree
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG make_movies_cache: $# $@" >&2
	$debuglog make_movies_cache: $# $@
fi

local ret=0

# copy all film covers to cache dir
cd $fdir
rm -f $cachedir/*
find . -type f | awk "{gsub(/\.\//,\"\"); print}" | grep 'COV.jpg' | sort | \
	xargs -I{} cp -v '{}' $cachedir/
ret=$?

# scale all images down
cd $cachedir
scale-image -s -f .jpg -a 50 50
ret=$?

# overwrite all images with the down scaled imgs
mmv -d "n*" "#1"
ret=$?

return $ret
}

#=============================================================================
function add_to_movies_cache ()
{
# Re create a single cover in the movies cache.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG add_to_movies_cache: $# $@" >&2
	$debuglog add_to_movies_cache: $# $@
fi

local f=""
local ret=0

# copy one film cover to cache dir
cp $arg1 $cachedir/

# scale the image down
cd $cachedir
f="${arg1##*/}"
scale-image -s -f .jpg $f 50 50 n${f}
ret=$?

# overwrite the image with the down scaled img
mv n${f} $f
ret=$?

return $ret
}

#=============================================================================
function rm_from_movies_cache ()
{
# Rm a single cover from the movies cache.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG rm_from_movies_cache: $# $@" >&2
	$debuglog rm_from_movies_cache: $# $@
fi

local f=""
local ret=0

# rm the image
cd $cachedir
f="${arg1##*/}"
rm -f $f
ret=$?

return $ret
}

#=============================================================================
function mainproc ()
{
# Build the moviedfile and the moviesfile.
# Uses date, echo, logger, tree
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG mainproc: $# $@" >&2
	$debuglog mainproc: $# $@
fi

local ret=0
#local -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array

echo "Make $moviedfile"
cd $fdir
tree -P '' -H $fdir > $moviedfile
ret=$?
date -R >> $moviedfile
ret=$?
make_movies_file
ret=$?

return $ret
}

##############################################################################
# GET OPTIONS
##############################################################################
# Give 2 strings and all cmdline_args to func GetOpt
# (POSIX_options Gnu_long_options cmdline_args):
# GetOpt 'hVdqvi:m:' 'help version debug quiet verbose infile= myval=' $@
#
# A ':' after a POSIX option means this option needs an arg.
# A '=' after a Gnu long option means this option needs an arg.
#
# All cmd/options have to be initialised to ''!
#
# POSIX options are classified in 2 categories:
#   a) cmds (mutually exclusive). All cmds are given to var 'cmd'.
#   b) options (as many as you like). Each option is given to it's own var.
# As a general rule: If cmds/options are given multiple then last given wins.
#
# Options can take 1 argument (no whitespace in arg). If you want to give more
# than 1 arg or want to use multiple strings as 1 arg then concatenate them
# together with a delimiter like ',' or ';' or '.'
# Use a delimiter which will not be part of the arg:
# sampleprog -m val1,val2
# sampleprog --myval=val1,val2
# It's at the programmers responsibility to do meaningfull things with the
# content of the options.
#
# If err != 0 then all args are processed, else continue to look for options.
# When GetOpt finishes then all options are removed from cmdline.
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Parse Commandline: $# $@" >&2
	$debuglog Parse Commandline: $# $@
fi
#
err=${_ERR_OK_}
while [ "$err" -eq 0 ]; do
	GetOpt 'hVdqvars' 'help version debug quiet verbose' $@
	err=$?
	#echo "DEBUG GET OPTIONS: err=${err}  _OPTNAME_=${_OPTNAME_}  _OPTVAL_=${_OPTVAL_}  _OPTPOS_=${_OPTPOS_}  _OPTIDX_=${_OPTIDX_}" >&2
	if [ $err -eq 0 ]; then
		case "$_OPTNAME_" in
		    h|help)	cmd="-h";;
		    V|version)	cmd="-V";;
		    a)		cmd="-${_OPTNAME_}";;
		    r)		cmd="-${_OPTNAME_}";;
		    s)		cmd="-${_OPTNAME_}";;
		    d|debug)	debug=yes;;
		    q|quiet)	verbose=no;;
		    v|verbose)	verbose=yes;;
#		    o|output)	opt_o=yes;;
#		    i|infile)	opt_i="${_OPTVAL_}";;
#		    o|outfile)	opt_o="${_OPTVAL_}";;
#		    p|pages)	opt_p="${_OPTVAL_}";;
		    --)		break;;
		    :)	Show_Err ${_ERR_MISSING_ARG_FOR_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_MISSING_ARG_FOR_OPT_};;
		    ?)	Show_Err ${_ERR_UNKNOWN_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_OPT_};;
		    *)	Show_Err ${_ERR_UNKNOWN_ERR_} "_OPTNAME_=${_OPTNAME_} _OPTVAL_=${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_ERR_};;
		esac
	fi
done
err=${_ERR_OK_}
shift ${_OPTIDX_}				# rm all opts from cmdline
#
# Uncomment if giving a cmd is mandatory
#if [ -z "$cmd" ]; then					# error no cmd given
#	Show_Err ${_ERR_MISSING_SUB_CMD_} ""
#	exit ${_ERR_MISSING_SUB_CMD_}
#fi

##############################################################################
# CHECK LINK NAMES
##############################################################################
# CHECK OPTIONS
##############################################################################
# CHECK VERSION
##############################################################################
# CHECK ARGUMENTS
#
case "$cmd" in
#    '')
#	if [ "$#" -eq 1 ]; then				# parameter count ok
#		arg1="$1"
#		shift
#		#args="$@"
#		#shift $#
#	else						# error in param count
#		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
#		exit ${_ERR_WRONG_PAR_COUNT_}
#	fi
#	;;
    -r|-s)
	if [ "$#" -eq 1 ]; then				# parameter count ok
		arg1="$1"
		shift
	else						# error in param count
		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
		exit ${_ERR_WRONG_PAR_COUNT_}
	fi
	;;
    *)
	if [ "$#" -ne 0 ]; then				# error in param count
		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
		exit ${_ERR_WRONG_PAR_COUNT_}
	fi
	;;
esac
#
##############################################################################
# LOCK

##############################################################################
# MAINPROGRAM
##############################################################################
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Main: $# $@" >&2
	$debuglog Main: $# $@
fi

# Check what to do (sub commands, options and args are removed from cmdline)
case "$cmd" in
    '')
	mainproc				# make movied and movies files
	err=$?					# dont (re)build movies cache
	;;
    -h)
	helptext
	exit 0
	;;
    -V)
	echo "${scriptname}: (${package}) $package_file ${version}-${release}"
	exit 0
	;;
    -a)
	mainproc				# make movied and movies files
	err=$?
	make_movies_cache			# build whole movies cache
	err=$?
	;;
    -r)
	rm_from_movies_cache			# rm one cover from movies cache
	err=$?
	;;
    -s)
	mainproc				# make movied and movies files
	err=$?
	add_to_movies_cache			# add one cover to movies cache
	err=$?
	;;
    *)							# error
	Show_Err ${_ERR_SUB_CMD_NOT_FOUND_} ""
	err=${_ERR_SUB_CMD_NOT_FOUND_}
	;;
esac

#rm -f $lockfile

exit $err
