Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: Bash scriptje: photodrop  (gelezen 2199 keer)

Bash scriptje: photodrop
« Gepost op: 2010/10/06, 16:18:43 »
Ik ben bash aan het leren, en heb een scriptje geschreven. Wellicht vind iemand het leuk om te bekijken, verbeteren, e.d.

Het script maak een fotoalbum aan en 'kijkt' vervolgens of er in een map nieuwe plaatjes (of video's) worden gedropped. Is dat het geval, dan wordt de photoalbumwebsite dynamisch aangepast met de nieuwe plaatjes. Het is als het ware een drag and drop fotoalbum website. Als je digibeten als huisgenoot hebt, en je hebt een webservertje draaien kan je het zo heel eenvoudig maken om foto's te publiceren. Je voert het script uit op de server, en deelt de dropfolder met samba over het lokale netwerk. Je zorgt dat deze map gemount wordt op het bureaublad van de gebruiker. Dan kan deze gewoon foto's in die map folder droppen om ze op het net te publiceren. Veel makkelijker kan het haast niet, en een lokaal netwerk is lekker snel, dus uploaden gaat rap.

Waarschijnlijk bestaat zoiets al lang, en beter. :D Maar het is wel leuk om te zien wat je zoal met bash kan knutselen.

Het script maakt gebruik van ffmpeg (animated gifs maken voor filmpjes), inotify-tools (folder in de gaten houden) en imagemagick (plaatjes converteren naar jpg en verkleinen). Dus bijna alle plaatjes en videobestanden worden wel ondersteund.

http://paste.ubuntu.com/507281/

#!/bin/bash
# photodrop - This daemon script creates on the fly a dynamic html
# photoalbum website from photo's dropped in the "dropfolder"
# directory. This dropfolder directory is automaticly created in the
# main folder that was given as an argument when starting this
# script (when it doesn't exist yet). In the main folder can also be
# the automaticly created index.html file.
#
# A lot of image and file formats are supported. The script makes use
# of ffmpeg and imagemagick and notify-tools packages, these must be
# installed before using the script.
#
# Usage: photodrop path/to/photodrop/folder
# Then pictures can be dropped in the dropfolder. The script wil
# automaticly create and update a website that can be accessed with
# the index.html file in the main folder.

# ========= Function definitions ===================

# errout
function errout ()
{
    printf "%b\n" "$@"
} >&2

function usage ()
{
echo
echo 'After starting the script pictures may be dropped in the dropfolder that
was automaticly created by the script inside the main folder given as
an argument to the script. Inside the main folder the index.html file can
be found that gives access to the dynamicly created photoalbum website.
Video files are also suported and are shown as a animated gif thumb.
Clicking the refresh button will load any new pictures dropped in the
dropfolder.'
echo
}


# emit ()
function emit ()
{
cat <<EOF
<HTML>
<HEAD><TITLE>${dropfilename}</TITLE></HEAD>
<BODY>
<TABLE WIDTH="700">
  <TR>
  <TD WIDTH="56%" ALIGN="left"> ${dropfilename} </TD>
  <TD WIDTH="8%"> <A HREF="${firsthtmlfile}"> First </A> </TD>
  <TD WIDTH="8%"> <A HREF="${prevhtmlfile}"> Prev </A> </TD>
  <TD WIDTH="12%"> <A HREF="index.html"> Refresh </A> </TD>
  <TD WIDTH="8%"> <A HREF="${nexthtmlfile}"> Next </A> </TD>
  <TD WIDTH="8%"> <A HREF="${lasthtmlfile}"> Last </A> </TD>
  </TR>
</TABLE>
  <A HREF="../dropfolder/${dropfilename}">
  <IMG SRC="../images/${imagename}" alt="../images/${imagename}"
  BORDER="1" VSPACE="4" HSPACE="4"/>
  </A>
</BODY>
</HTML>
EOF
}

# indexfiles (filename)  Put files in array, and find index filename
function indexfiles ()
{
local temp
local count
count=0
filearray=( )
ifs="${IFS}"
IFS=$'\n'
for temp in $(ls "-1" "${thumbfolder}")
do
    (( count+=1 ))
    filearray[$count]="${temp%.*}"
    if [[ "${temp}" == "${imagename}" ]]
    then
        fileindex="$count"
        echo "count: ${count} ${temp} *"
    else
        echo "count: ${count} ${temp}"
    fi
done
currenthtmlfile="${filearray[$fileindex]}.html" 2>/dev/null
nexthtmlfile="${filearray[(($fileindex + 1))]:="${currenthtmlfile%.*}"}.html" 2>/dev/null
prevhtmlfile="${filearray[(($fileindex - 1))]:="${currenthtmlfile%.*}"}.html" 2>/dev/null
firsthtmlfile="${filearray[1]}.html" 2>/dev/null
lasthtmlfile="${filearray[$count]}.html" 2>/dev/null
filetotal=$count
#echo
#echo "first: $firsthtmlfile"
#echo "prev:  $prevhtmlfile"
#echo "cur:   $currenthtmlfile"
#echo "next:  $nexthtmlfile"
#echo "last:  $lasthtmlfile"
IFS="${ifs}"
}


# Create empty page for when no images are to be shown
function emptypage ()
{
cat <<EOF
<html>
<head><title>Photodrop</title></head>
<body onLoad=window.refresh>
<TABLE WIDTH="700">
  <TR>
    <TD ALIGN="left"> <H2> Photodrop </H2> </TD>
  </TR>
  <TR>
    <TD WIDTH="50%" ALIGN="left"> Waiting for files.. </TD>
    <TD WIDTH="50%" ALIGN="right"> <A HREF="index.html"> Refresh </A> </TD>
  </TR>
</TABLE>
</body>
</html>
EOF
}>"${webfolder}/index.html"

function indexpage ()
{
cat <<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Photodrop</title>
<meta http-equiv="REFRESH" content="0;url=./htmlfiles"></HEAD>
<BODY>
</BODY>
</HTML>
EOF
}>"${mainfolder}/index.html"

#============= Initialize ================
# get options
while getopts 'h(help)' option
do
    case $option in
    h)  echo "Usage: $(basename $0) path/to/photodrop/folder";usage;exit 0 ;;
    ?)  errout "Usage: $(basename $0) [path/to/photodrop/folder] [-h]";exit 1 ;;
    esac
done
shift $(($OPTIND -1))

# get argument
if [ $# -ne 1 ]
then
    errout "Usage: $(basename $0) [path/to/photodrop/folder] [-h]"
    usage
    exit 1
fi

# evaluate argument
if [ ! -d "$1" ]
then
    errout "Directory ${1} does not exist."
    exit 1
elif [ ! -w "$1" ]
then
    errout "Directory ${1} is not writable."
    exit 1
fi

# declare variables
temp="${1}"
mainfolder="${temp%/}"                  # place where index.html and subdirectories
dropfolder="${mainfolder}/dropfolder"   # "listening" folder, where files are dropped
webfolder="${mainfolder}/htmlfiles"     # folder where html pages are created and updated
thumbfolder="${mainfolder}/images"      # folder where resized images are stored
fileindex=""                            # place in array of current file
filetotal=""                            # total number of files
notifile=""                             # string with feedback inotifywait
dropfilefolder=""                       # folder in of dropped filee
dropfilename=""                         # name of dropped file
imagename=""                            # name of (identified) image
filebasename=""                         # name without extension and dot replaced by dash
currenthtmlfile=""                      # name of html file
nexthtmlfile=""
prevhtmlfile=""
firsthtmlfile=""
lasthtmlfile=""
filearray=("")
commandstatus=""                        # temp var to store exit status command

# make subdirectories if they do not exist
if [ ! -d "${thumbfolder}" ]
then
    mkdir "${thumbfolder}"
    chmod 777 "${thumbfolder}"
fi
if [ ! -d "${dropfolder}" ]
then
    mkdir "${dropfolder}"
    chmod 777 "${dropfolder}"
fi
if [ ! -d "${webfolder}" ]
then
    mkdir "${webfolder}"
    chmod 777 "${webfolder}"
fi

# create index.html
if [ ! -f "${webfolder}/index.html" ]
then
    emptypage
fi
indexpage

#============= Main loop =======================

# Watch for new images or deleted images
echo
echo 'Watching dropfolder for events..'
inotifywait -mq -e create,delete,move --format "%w%f:%e" "${dropfolder}" |\
while read notifile; do
    echo
    echo "${notifile}"
    temp="${notifile%:*}"
    dropfilefolder="${temp%/*}"
    dropfilename="${temp##*/}"
    # replace "." with "-" in name
    filebasename="${dropfilename%.*}-${dropfilename##*.}"
    # skip temporary files, hidden files, and files that are not in dropfolder subdirectories
    if [[ "${dropfilename}" == ~*.tmp || "${dropfilefolder}" != "${dropfolder}" || "${dropfilename}" =~ ^\..*$ ]]
    then
        echo 'Nothing done..'
        continue
    fi
    # check if event is newfile  or removed file and act accordingly
    if [[ "${notifile}" == *":CREATE" || "${notifile}" == *":MOVED_TO" ]]
    then
        # NEWFILE: MAKE THUMB
        #------------------------------------------------------------------------
        # check if file copy is completed
        printf "%s" "Waiting for file copy to finish."
        temp="y"
        temp2="x"
        while [[ "$temp2" != "$temp" ]]
        do
            { temp="$(stat -c %s "${dropfilefolder}/${dropfilename}")" ;} > /dev/null 2>&1
            # check if file is removed while copying
            if (( $? ))
            then
                break
            fi
            printf "%s" "."
            sleep 0.5
            { temp2="$(stat -c %s "${dropfilefolder}/${dropfilename}")" ;} > /dev/null 2>&1
            if (( $? ))
            then
                break
            fi
        done
        # skip rest if there was a problem with the file being copied..
        if [[ $temp != $temp2 ]]
        then
            echo 'nothing done (stat error during copy)..'
            continue
        fi
        printf "\n"
        # check if the dropped file is not an image
        if [[ ! "$(file "${dropfilefolder}/${dropfilename}")" =~ ^.*(PC bitmap|GIF|JPEG|Photoshop|PBM|PGM|PNG|PPM|Sun raster image|Targa image|TIFF|XCF).*$ ]]
        then
            # try to convert file with ffmpeg to animated gif
             ffmpeg -y -i "${dropfilefolder}/${dropfilename}" -pix_fmt rgb24 -r 2 -loop_output 0 -ss 0\
                    -t 5 -s 160x120 -f gif "${thumbfolder}/${filebasename}.gif" > /dev/null 2>&1
             commandstatus=$?
             # check if animated gif creation was a success
             if (( ! $commandstatus ))
             then
                 # set name of image to gif
                 imagename="${filebasename}.gif"
             else
                 imagename="${filebasename}.jpg"
                 # cleanup
                 rm -f "${thumbfolder}/${filebasename}.gif"
                 # try to convert to jpg with ffmpeg
                 ffmpeg -y -i "${dropfilefolder}/${dropfilename}" -f mjpeg -ss 0 -vframes 1\
                        -s 720x540 -an "${thumbfolder}/${imagename}" > /dev/null 2>&1
                 commandstatus=$?
             fi
        else
            imagename="${filebasename}.jpg"
            # if picture is an image, act as if ffmpeg conversion failed so that imagemagick conversion will be tried
            commandstatus=1
        fi
        # check if conversion with ffmpeg was not succesfull
        if (( ! $commandstatus ))
        then
            echo 'Converted by ffmpeg..'
        else
            rm -f "${thumbfolder}/${imagename}"
            # check if file can be converted with imagemagick
            identify "${dropfilefolder}/${dropfilename}" > /dev/null
            if (( $? ))
            then
                echo 'Nothing done..'
                continue
            else
                # convert file with imagemagick to jpg image
                convert "${dropfolder}/${dropfilename}[0]" -resize 720x540\> "${thumbfolder}/${imagename}"
                echo 'Converted by imagemagick..'
            fi
        fi
        # NEWFILE: MAKE HTML PAGE
        #------------------------------------------------------------------------
        # check if file copy is completed
        # create variables firsthtmlfile, prevhtmlfile, nexthtmlfile, lasthtmlfile, currenthtmlfile, fileindex, filetotal from files in images folder
        indexfiles
        # create new html file
        echo "New htmlfile created: ${currenthtmlfile}"
        emit "${imagename}" "${firsthtmlfile}" "${prevhtmlfile}" "${nexthtmlfile}" "${lasthtmlfile}">"${webfolder}/${currenthtmlfile}"
        # check if current is the first
if (( ${fileindex} == 1 ))
        then
            # the first file, update links to first in all html files, and update index.html
            sed -i "s:>.*Prev.*</TD>:> <A HREF=\"${currenthtmlfile}\"> Prev </A> </TD>:g" "${webfolder}/${nexthtmlfile}"
            sed -i "s:>.*First.*</TD>:> <A HREF=\"${currenthtmlfile}\"> First </A> </TD>:g" "${webfolder}"/*
            sed -i "s:>.*Prev.*</TD>:> Prev </A> </TD>:g" "${webfolder}/${currenthtmlfile}"
            sed -i "s:>.*First.*</TD>:> First </TD>:g" "${webfolder}/${currenthtmlfile}"
        else
            # not the first, update links in previous html file
            sed -i "s:>.*Next.*</TD>:> <A HREF=\"${currenthtmlfile}\"> Next </A> </TD>:g" "${webfolder}/${prevhtmlfile}"
        fi
        # check if current file is the last
        if (( ${fileindex} == ${filetotal} ))
        then
            # is lastfile, update links in all html files
            sed -i "s:>.*Next.*</TD>:> <A HREF=\"${currenthtmlfile}\"> Next </A> </TD>:g" "${webfolder}/${prevhtmlfile}"
            sed -i "s:>.*Last.*</TD>:> <A HREF=\"${currenthtmlfile}\"> Last </A> </TD>:g" "${webfolder}"/*
            sed -i "s:>.*Next.*</TD>:> Next </A> </TD>:g" "${webfolder}/${currenthtmlfile}"
            sed -i "s:>.*Last.*</TD>:> Last </TD>:g" "${webfolder}/${currenthtmlfile}"
        else
            # not lastfile, update links in next htmlfile
            sed -i "s:>.*Prev.*</TD>:> <A HREF=\"${currenthtmlfile}\"> Prev </A> </TD>:g" "${webfolder}/${nexthtmlfile}"
        fi
        # update index.html
          cp -f "${webfolder}/${firsthtmlfile}" "${webfolder}/index.html"
    # check if event is gone file and act accordingly
    elif [[ "${notifile}" == *":DELETE" || "${notifile}" == *":MOVED_FROM" ]]
    then
        # REMOVED FILE: CLEANUP
        # ----------------------------------------------------------------------------
        # check if a picture or video page from index is removed
        if [ -f "${thumbfolder}/${filebasename}.jpg" ]
        then
            imagename="${filebasename}.jpg"
        elif [ -f "${thumbfolder}/${filebasename}.gif" ]
        then
            imagename="${filebasename}.gif"
        else
            echo 'Nothing done..'
            continue
        fi
        echo "Image ${imagename} was removed, now cleaning up the rest.."
        # create variables firsthtmlfile, prevhtmlfile, nexthtmlfile, lasthtmlfile, currenthtmlfile, fileindex, filetotal from files in images folder
        indexfiles
        # check position of removed file
        if (( ${filetotal} == 1 ))
        then
            # only file removed, update links
            rm -f "${webfolder}/index.html"
            echo 'Empty indexpage created: index.html'
            emptypage
        elif  (( ${fileindex} == ${filetotal} ))
        then
            # last file removed, update links
            sed -i "s:>.*Last.*</TD>:> <A HREF=\"${prevhtmlfile}\"> Last </A> </TD>:g" "${webfolder}"/*
            sed -i "s:>.*Last.*</TD>:> Last </TD>:g" "${webfolder}/${prevhtmlfile}"
            sed -i "s:>.*Next.*</TD>:> Next </TD>:g" "${webfolder}/${prevhtmlfile}"
        elif (( ${fileindex} == 1 ))
        then
            # first file removed, update links
            sed -i "s:>.*Prev.*</TD>:> Prev </TD>:g" "${webfolder}/${nexthtmlfile}"
            sed -i "s:>.*First.*</TD>:> <A HREF=\"${nexthtmlfile}\"> First </A> </TD>:g" "${webfolder}"/*
            sed -i "s:>.*First.*</TD>:> First </TD>:g" "${webfolder}/${nexthtmlfile}"
            cp -f "${webfolder}/${nexthtmlfile}" "${webfolder}/index.html"
        else
            # middle file removed, update links
            sed -i "s:>.*Prev.*</TD>:> <A HREF=\"${prevhtmlfile}\"> Prev </A> </TD>:g" "${webfolder}/${nexthtmlfile}"
            sed -i "s:>.*Next.*</TD>:> <A HREF=\"${nexthtmlfile}\"> Next </A> </TD>:g" "${webfolder}/${prevhtmlfile}"
        fi
        # cleanup datafiles
        echo "Html file removed: ${currenthtmlfile}"
        rm -f "${webfolder}/${currenthtmlfile}" "${thumbfolder}/${imagename}"
    else
        # if no file was added or removed do nothing (directory events, temporarty files)
        echo 'Nothing done..'
    fi
    echo
    echo 'Watching dropfolder for events..'
#} &
done
exit 0

Offline Dave

  • Lid
Re: Bash scriptje: photodrop
« Reactie #1 Gepost op: 2010/10/06, 18:21:11 »
Klinkt stikgoed maar snap niet wat je verstaat onder photoalbumwebsite bijvoorbeeld en hoe ik me dat voor moet stellen.

Wel top dat je bezig bent met scripst want er wordt al jarenlang gevraagd naar een script om een standaard installatie af te maken voor derden

Re: Bash scriptje: photodrop
« Reactie #2 Gepost op: 2010/10/06, 20:23:40 »
@Dave:

#!/bin/bash
sudo apt-get install ubuntu-restricted-extras

Zo, installatie is klaar voor derden.
Nu weer ontopic.

Leuk scriptje Thomas, kan zeer handig zijn :)

Re: Bash scriptje: photodrop
« Reactie #3 Gepost op: 2010/10/06, 21:59:40 »
Klinkt stikgoed maar snap niet wat je verstaat onder photoalbumwebsite bijvoorbeeld en hoe ik me dat voor moet stellen.

Gewoon een foto per pagina met knopjes om naar de volgende foto te gaan. Fotoviewer is eigenlijk een betere benaming.

Re: Bash scriptje: photodrop
« Reactie #4 Gepost op: 2010/10/06, 22:07:51 »
.....
...... Maar het is wel leuk om te zien wat je zoal met bash kan knutselen.

....


Thomas,

Ziet er goed uit....
Wat je allemaal mat BASH (en eventueel met Zenity erbij) kan doen ... veel.

VB.
De installer van Slackware is een bash-script bestand.

MvG,
MauRice
Registered Linux user: 473556

Offline Dave

  • Lid
Re: Bash scriptje: photodrop
« Reactie #5 Gepost op: 2010/10/07, 13:13:45 »
@Dave:

#!/bin/bash
sudo apt-get install ubuntu-restricted-extras

Zo, installatie is klaar voor derden.
Nu weer ontopic.

Leuk scriptje Thomas, kan zeer handig zijn :)

Jij bedoeld dat die hele site van Pjotr maar nutteloos is dus?
Zijn de meningen over verdeeld dan.


Offline Dave

  • Lid
Re: Bash scriptje: photodrop
« Reactie #6 Gepost op: 2010/10/07, 13:15:54 »
Klinkt stikgoed maar snap niet wat je verstaat onder photoalbumwebsite bijvoorbeeld en hoe ik me dat voor moet stellen.

Gewoon een foto per pagina met knopjes om naar de volgende foto te gaan. Fotoviewer is eigenlijk een betere benaming.

ah oke zoals bij de meeste webalbums dus eigenlijk maar dan helemaal naar eigen inzicht.
Klinkt goed

Re: Bash scriptje: photodrop
« Reactie #7 Gepost op: 2010/10/07, 14:04:58 »
Jij bedoeld dat die hele site van Pjotr maar nutteloos is dus?
Zijn de meningen over verdeeld dan.

Idd. wel een aardig idee om daar een scriptje voor te maken. Zal er even een nieuwe draad voor openen.

http://forum.ubuntu-nl.org/programmeren/bash-scriptje-direct-na-het-installeren/

Re: Bash scriptje: photodrop
« Reactie #8 Gepost op: 2010/10/07, 20:24:45 »
@Dave: Volgens mij zie jij niet meer de humor in. Kom op zeg. Ik heb zelf voor Kubuntu ook een pagina voor wat te doen na het installeren op mijn website, dus ik weet heus wel dat de installatie niet zomaar af is met 1 commando hoor. Het was alleen maar een grapje, meer niet.

Vanaf hier weer ontopic, over Thomas zijn leuke scriptje :)

Offline Dave

  • Lid
Re: Bash scriptje: photodrop
« Reactie #9 Gepost op: 2010/10/08, 16:33:41 »
@Dave: Volgens mij zie jij niet meer de humor in. Kom op zeg. Ik heb zelf voor Kubuntu ook een pagina voor wat te doen na het installeren op mijn website, dus ik weet heus wel dat de installatie niet zomaar af is met 1 commando hoor. Het was alleen maar een grapje, meer niet.



oke ik zag dat inderdaad niet, dacht al hoe kunnen we zo simpel doen  :evil:
op een release party waren al eens cdroms die aangepast waren.
Zoiets moest eigenlijk bij iedere versie te realiseren/downloaden zijn.
Of zoals nu, een script wat aanpasbaar is, nog vele malen beter.
taalbestanden, softwarebronnen, de gebruikelijke extra bronnen, het herladen tussendoor en een veld waar je de gewenste extra pakketten invult enz.

Jaja tis nog wat vroeg voor het sinterklaaslijstje  =D