Home sweet home
Nav
hide
S1
S2
S3
Name: albumGenerate
Typ: bash
benötigt: diverse jquery-Geschichten, convert,exiftool,jhead
Tja, kann man das veröffentlichen? Für mich ist es nützlich, also tun wir es. Das Script ist das wahrscheinlich n-te Photo-Album-Generierungsscript.
Aus einem Verzeichnis heraus aufgerufen, generiert es aus allen Ordnern in diesem Verzeichnis und den darin enthaltenen Medien-Dateien ein Album im HTML-Format.
Hier ein kurzes Beispiel einer Anwendung.

2010-04-19: Und einen Fehler gefunden, unter IE lief es nicht, da ich in Javascript die for each Schleife genutzt habe. Diese gibt es ab Javascript 1.6/7, welches IE anscheinend nicht unterstützt. Hoffen wir, dass ich keine anderen Fehler eingebaut habe - ansonsten: Verwenden Sie firefox :-)

Ein Bug / ein Feature fiel noch auf. Die Bestellübersicht (s.u.) bietet nicht die Photo-Album Funktionalität.

Details: Das entstehende Album wird mittels jQuery und lightbox realisiert, es handelt sich um eine reine HTML/JavaScript Geschichte, eine serverseitige Sprache wird nach der Fertigstellung nicht mehr benötigt.
Um die Dateigrößen und damit die Ladezeichen für den Betrachter möglichst gering zu halten, werden alle Bild-Dateien mittels des Befehls convert (aus imagemagick) skaliert. Es existieren also nach dem Durchlauf des Scriptes die Original-Dateien, die Bilddateien welche vom Benutzer betrachtet werden können und die Thumbnails der diversen Übersichtsseiten.

Neben dem Betrachten der Gallerie ist es möglich, mit dem Programm eine Liste von Bildern zusammen zu stellen. Diese wird angzeigt und kann in Textform ausgegeben werden. Ich nutze dies um die Photos heraus zu suchen, von denen ich Abzüge machen möchte.

Einige Worte zur Anleitung.
Annahme: Wir haben die folgende Ordnerstruktur:

       Bilder
          |_ 2010
          |    |_ 01JanuarSchnee
          |    |_ 04Ostern
          |    |_ 07Urlaub
          |
          |_ 2009
          |    |_ ...
          |
          |_ 2008
               |_ ...
    

Das Script ruft man nun aus den Ordnern 2010 ... 2008 heraus auf. Prinzipiell sollte es auch aus dem Ordner Bilder heraus funktionieren, aber da für ein "Toplevel-Verzeichnis" eine index.html erzeugt wird, welche alle Daten aus den Unterverzeichnissen enthät wähle ich jeweils ein Jahr. Dies ist für meine Zwecke die richtige Größe.

In diese Ordner müssen dann noch manuell einige Verzeichnisse kopiert werden:
Verzeichnis css mit der Datei jquery.lightbox-0.5.css

Verzeichnis images mit den Dateien
lightbox-blank.gif , lightbox-btn-next.gif , lightbox-ico-loading.gif , lightbox-btn-close.gif , lightbox-btn-prev.gif und filmrolle.gif

Verzeichis sources mit den Dateien
jquery-1.4.2.min.js , jquery.cookie.js , jquery.lightbox-0.5.min.js , jquery.treeview.min.js

Es handelt sich dabei fast ausschließlich um jquery Sources/CSS und benötigte Bilder. Ein paar css werden erzeugt, ein Bild wird als Thumbnail für eine Filmdatei zusätzlich benötigt.

Die benötigten Verzeichnisse und Dateien liegen dem Download bei.

Das Ergebnis dieses Scriptes wird in den Ordnern abgelegt. Das hat den Vorteil, dass man evtl. durch eine Abwandlung einzelne Bilddateien zum Download anbieten kann. In diesem Fall sollten die originalen Bild-Dateien, nicht die reduzierten Dateien angeboten werden.
Will man dies nicht, so muss man sich die erzeugten Dateien in ein anderes Verzeichnis kopieren. Dies kann man mit ein paar Shell-Befehlen relativ schnell erledigen. Hier das Prinzip:
hide
copyAlbum
mkdir ../../../Album/2010-04-BeispielAlbumGenerate
 cp -a css/ images/ sources/ index.html ../../../Album/2010-04-BeispielAlbumGenerate
 find . -type d -name thumbs -exec cp -a --parents {}  ../../../Album/2010-04-BeispielAlbumGenerate/ \;
 find . -type d -name smaller -exec cp -a --parents {}  ../../../Album/2010-04-BeispielAlbumGenerate/ \;
Parsed using GeSHi 1.0.8.6
Neben dem reinen Betrachten kann man sich mit Hilfe der entstandenen HTML-Seite eine Liste von Fotos erstellen. Auf dieser Liste sind die Original-Dateien aufgeführt, so daß man diese verwenden kann um eine Bestellung zusammen zu stellen.
Konfiguration des Scriptes: Prinzipiell nicht zwingend, ein paar Einstellungen sind am Anfang des Quellcodes möglich.
Das Script habe ich für mich geschrieben, bei mir hat es geklappt, ich gebe keinerlei Gewährleistung. Von Photos sollte man sowieso mindestens ein Backup haben ...

Der Quelltext ist dann doch ein Monstrum geworden ... unten ein Link zum Download

show
albumGenerate.sh
	#!/bin/bash
#bugs, seltsamkeiten, die ich aktuell sehe und nicht reparieren moechte
#verzeichnis css und js muss haendig in das aktuelle Verzeichnis koppiert werden
#verzeichnisse die vom script verwendet werden sollten keine Bilder enthalten
#  //0 darf auch kein Verzeichnis heissen
#Bei zu vielen Verzeichnissen wird es langsam, liegt an der Bestell-Aufnahme (glaube ich :-)
#nehme das daher raus
cssDir=css # for css style-file, not as dir of photos
sourceDir=sources # for the jquery sources, -"- 
jquery=jquery-1.4.2.min.js                # jquery lib
jqueryLightBox=jquery.lightbox-0.5.min.js # jquery Light Box, photos
jqueryTree=jquery.treeview.min.js         # tree navigation
jqueryCookie=jquery.cookie.js             # weiss nicht ob noetig :-)
 
jqueryLightBoxCSS=jquery.lightbox-0.5.css
 
styleFile="albumStyle.css"
albumTmpList="albumTmpList"
movieTypes=( avi mpg mpeg mts mp4 ) #movies als normaler link
imageTypes=( jpg jpeg png )
 
#unterverzeichnisse und prefix  fuer thumbs und smaller images
thPrefix="thumb_"
smPrefix="smaller_"
thDir="thumbs"
smDir="smaller"
#-----------------------------------------
 
#groessen fuer die thumbs, smaller 
thumbDivWidth=220px
thumbHeight=120 # hier ohne px -> fuer convert
smallerHeight=500
 
 
#functions
#--------------------------------------
#die CSS
function generateStyles()
{  
  bestell=$1
  mkdir -p $cssDir
  cat << endStyle > $cssDir/$styleFile
  body {
    background-color:    #697ed1;
    color            :    #faebd7;   
  }
  a:link    { color:#200096; text-decoration:underline; font-style:italic; }
  a:visited { color:#200096; text-decoration:underline; font-style:normal; }
  a:active  { color:#200096; text-decoration:none; }  
  h1        { color:#ff0000;}
 
  .goon     { color:       #960096;
              background-color:  #798ee1; 
  }
  .treeview , .treeview ul {  
          margin-left   :  6px;
          padding-left  :  6px;
          list-style    :  none; 
  }
 
  .treeview li { 
      margin-bottom      :  2px ;
      cursor            :  pointer;            
  }
  .folder:hover   {
    background-color    :  #798ee1;
  }
 
 
  #divButtonNavigation{
    background-color    :  #697ee1;
    color                :  #faebd7;   
    position            :  fixed;
    top                  :  0px;
    left                : 0px;
    border-right        :  6px groove #697ee1;
    border-bottom        :  6px groove #697ee1;  
    z-index              :  10;
    padding              :  3px;
    cursor              :  pointer;
    display              :  none;
  }
  #divButtonNavigationHide{
    background-color    :  #697ee1;
    color                :  #faebd7;   
    border-left          :  6px groove #697ee1;
    border-right        :  6px groove #697ee1;
    border-bottom        :  6px groove #697ee1;  
    position            :  fixed;
    top                  :  0px;
    left                :  100px;
    z-index              :  10;
    display              :  block;
    padding              :  3px;
    cursor              :  pointer;
  }
 
  #divButtonBestellAuswahl {
    background-color    :  #697ee1;
    color                :  #faebd7;   
    border-left          :  6px groove #697ee1;
    border-right        :  6px groove #697ee1;
    border-bottom        :  6px groove #697ee1;  
    position            :  fixed;
    top                  :  0px;
    right                :  30px;
    z-index              :  10;
    display              :  none;
    padding              :  3px;
    cursor              :  pointer;
    width                : 200px;
    text-align          : center;
  }
 
  #divBestellung {
    background-color    :  #697ee1;
    color                :  #faebd7;   
    border-left          :  1px solid #ddd;
    border-right        :  1px solid #ddd;
    border-bottom        :  1px solid #ddd;
    position            :  fixed;
    top                  :  0px;
    right                :  270px;  
    display              :  inline-block;
    z-index              :  10;
    padding              :  3px;
    cursor              :  pointer;  
  }
 
  /* gebe diesen das Aussehen von Buttons */
  #divButtonNavigation,
  #divButtonNavigationHide,
  #divButtonBestellAuswahl,
  #divButtonBestellListe,
  #divButtonBestellUebersicht {
         display                   :   inline-block;
         background-color          :    #bbb;
         color                     :     #00A;
         padding                   :    2px;
         border                    :   3px outset #AAA;
  }
 
  #divButtonNavigation {display:none;}/*wieder ausblenden*/
 
  #divButtonNavigation:hover,
  #divButtonNavigationHide:hover,
  #divButtonBestellAuswahl:hover,
  #divButtonBestellListe:hover,
  #divButtonBestellUebersicht:hover
  {
        background-color           :    #CCC;         
        color                      :    #00F;  
        border                     :   3px inset #AAA; 
  }
 
 
 
  #divNavigation {
    background-color   :  #697ee1;
    color              :  #faebd7;   
    position           :  absolute;  
    top                :  0px;
    bottom	       :  0px; /* immer volle Hoehe */
    left               : 0px;
    padding-top        :  50px;
    padding-right      :  20px;
    min-width          :  200px;
    display            :  block;
    z-index            :  5;
    cursor             : text;
    position	       : fixed;
    overflow           : auto;
  }      
 
  #gallery {
      margin-top         :  50px;
      margin-left        :  100px;
      width             :  95%;
      margin-left       :  auto;
      margin-right      :  auto;
      border            :  1px solid #aaa;
      /* background-color    :  blue; */
  }
 
  #gallery  img {
      margin            : 10px;
      border            : 5px solid #3e3e3e;
      border-width      : 5px 5px 10px;
 
  }
  #gallery  a:hover img {
      border            : 5px solid #fff;
      border-width      : 5px 5px 10px;
      color             : #fff;
  }
  #gallery  a:hover { color: #fff; }
 
  .h {
      display           : none;
  }  
  .fileEntry  {
      /* color      :    yellow; */
      display           :    inline-block;
      width             :    $thumbDivWidth;
      /* border      :    1px solid; */
      text-align        :    center;
  }
   div.fileEntry > div { /* erster div mit dem Filenamen */
    font-family         :  sans-serif;    
    font-size           :  x-small;
    padding             :  0px 5px; /* oben unten 2. rechts links */
    border              : 0px solid;
    position            :  relative;
    top                 :  -5px;
   }
 
  .bestellung {
    font-family         :  sans-serif;
    font-size           :  x-small;
    text-align          :  center;            
  }
 
  .bestellung  input  {
    font-size           :  xx-small;
    text-align          :  right;    
  }
 
 
endStyle
 
	if [[ $bestell. != 'j.' ]]
	then
		  cat << endStyle >> $cssDir/$styleFile
  /* variante ohne Bestellung, einfach ausblenden :-) */
  #divBestellung,
  #divButtonBestellAuswahl,
  #divButtonBestellListe,
  #divButtonBestellUebersicht
  {
        display           :    none;         
	}		  
endStyle
	fi
}
#--------------------------------------------------
#write the main header to index.html
function generateIndexHead()
{
  bestell=$1
  rausA=rausE="" # leer, wird unten ggf. gesetzt
  echo "Generate Header of index.html in  main directory"
  cat << endIndex > index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta name="author" content="albumGenerate.sh by kr">    
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <link rel="stylesheet" type="text/css" href="$cssDir/$styleFile">
  <link rel="stylesheet" type="text/css" href="$cssDir/$jqueryLightBoxCSS">
  <script type="text/javascript" src="$sourceDir/$jquery" >        </script>
  <script type="text/javascript" src="$sourceDir/$jqueryLightBox" ></script>
  <script type="text/javascript" src="$sourceDir/$jqueryTree">     </script>
endIndex
 
	if [[ $bestell. != 'j.' ]]
	then
  cat << endIndex >> index.html
  <!-- Bestellmoeglichkeit wurde ausgeschaltet, daher in diesem Java-Script einiges Nutzlos
       beziehungsweise auskommentiert -->
endIndex
  rausA="/* (keine Bestellmoeglichkeit) "
  rausE=" (Ende keine Bestellmoeglichkeit) */"
  fi
	cat << endIndex >> index.html
  <script type="text/javascript">
    //globals
    //array, one entry for each directory, containing object of type fileEntry
    var allDirectories=new Array();
    var actualKey="-1"; //-1: nicht gegeben, "0": wir sind auf der Uebersicht
    var showBestellAufnahme = false;
    var bestellteFiles = new Array();
    $rausA
    function pruefeBestellteFiles(fEntry )
    {
      var found = false;
      var i,index = 0;
      //for each ( var entry in bestellteFiles)
      //Mist for each erst ab js1.7, IE 8 nicht, hier brauche ich
      //es eigentlich nicht 
      for (i = 0; i < bestellteFiles.length; ++i)
      {
        if (bestellteFiles[i] == fEntry)
        {
          found = true;                    
          break;
        }
      }
      index = i;
      if (!found && fEntry.bestellungen != "0")
      {
        bestellteFiles.push(fEntry); //anfuegen        
      }
      else if (found && fEntry.bestellungen == 0) 
      {
        bestellteFiles.splice(index,1); //eines loeschen
        //klappt auch aus der Mitte heraus, es wird neu 
        //nummeriert - scheint so 
      }      
    }
    $rausE
    \$(document).ready(function(){         //navigation als tree
      \$("#navigationTree").treeview({
          persist: "location",
          collapsed: true,
          unique: false
        });
    /*  \$("#divButtonNavigation").mouseenter( function () */
        \$("#divButtonNavigation").click( function ()   
        {
          \$(this).hide();
          \$("#divNavigation").slideDown("slow");
          \$("#divButtonNavigationHide").slideDown("slow");
          //get width of navigation
          var breite = \$("#divNavigation").width();
          breite+=20;
          breite+="px";
          //alert (breite);
          \$("#gallery").css("margin-left",breite); //galerie nach rechts
          });
     /* \$("#divButtonNavigationHide").mouseenter(function()*/
      \$("#divButtonNavigationHide").click(function()
         {
          \$("#divNavigation").slideUp("slow");
          \$("#divButtonNavigation").slideDown("slow");
          \$(this).hide()
          \$("#gallery").css("margin-left","auto"); //schiebt die Galerie wieder nach links
          });
     /* \$("#divButtonBestellAuswahl").mouseenter( function()*/
       $rausA
       \$("#divButtonBestellAuswahl").click( function()
        {        
        if (!showBestellAufnahme)
        {          
          \$(".fileEntry .bestellung").slideDown("slow");
          \$(this).html("Bestellauswahl ausblenden");
        }
        else
        {          
          \$(".fileEntry .bestellung").slideUp("slow");
          \$(this).html("Bestellauswahl einblenden");
        }
        showBestellAufnahme = ! showBestellAufnahme;
        });
       $rausE
      \$(".folder").click( function(){          
          var key=\$(this).find("span")[0];//first element of array      
          key=\$(key).text(); //und text heraus holen
          //fill the content-Div
          //\$("#gallery").text(key); geht prinzipiell
          //check actual key
          $rausA
          if (actualKey != "-1" )
          {
            var actualDir = bestellteFiles;
            if (actualKey != "0") //komme aus einem anderen Folder
               actualDir = allDirectories[actualKey];
 
            //get the contents of all input fields
            allInputs=\$("#gallery input"); //klappt
            //\$("#gallery input").css("border", "2px dotted blue")
            //alert (allInputs.length);
            for (i = 0; (i < allInputs.length)  && (i < actualDir.length ) ; ++i)
            {
               actualDir[i].bestellungen = allInputs[i].value; //sichern, reihenfolge müsste stimmen
               pruefeBestellteFiles(actualDir[i]);
            }            
          }
          actualKey=key;
					$rausE
          var anzahl = allDirectories[key].length;
          //alert (anzahl);
          content="";
          //-> should be the way          
          for ( i = 0; i <  anzahl; ++i)
          {
            content+=allDirectories[key][i].ToHTML(); 
          }
          \$("#gallery").html(content);//set all
          if (anzahl > 0) //sonst folder ohne Bild-Dateien
          {            
            \$('#gallery a.typeImage').lightBox(); // Select all links in object with gallery ID
                                         //which are of class typeImage
          }
          $rausA
          if (showBestellAufnahme)
          {
            \$(".fileEntry .bestellung").slideDown("slow");
            \$("#divButtonBestellAuswahl").html("Bestellauswahl ausblenden");
          }
          $rausE                    
        });
        $rausA
        \$(".fileEntry  .up").live("click",function() //for all future elements -> Event einhaengen 
          {
            var el=\$(this).siblings()[0];
            el.value = parseInt(el.value) + 1;                
          });
        \$(".fileEntry  .down").live("click",function() //for all future elements -> Event einhaengen 
          {
            var el=\$(this).siblings()[1];                
            if (parseInt(el.value) > 0)
              el.value = parseInt(el.value) - 1;                
          });              
      //buttons liste und übersicht
 
      \$("#divButtonBestellListe").click( function() 
        {
          if (actualKey != "-1")
          {
            var actualDir = bestellteFiles;
            if (actualKey != "0") //komme aus einem anderen Folder
               actualDir = allDirectories[actualKey];
 
            //get the contents of all input fields
            allInputs=\$("#gallery input"); //klappt
            for (i = 0; (i < allInputs.length)  && (i < actualDir.length ) ; ++i)
            {
               actualDir[i].bestellungen = allInputs[i].value; //sichern, reihenfolge müsste stimmen
               if (actualKey != 0)
                pruefeBestellteFiles(actualDir[i]);
            }            
          }
          actualKey = "-1"; 
          var bestellFenster = window.open();
          var datum = new Date();
          bestellFenster.document.write("<html><head><title>Bestellliste</title></head><body>\n");
          bestellFenster.document.write("<hr>\n");
          bestellFenster.document.write("Bestellung: " + datum + "<br>\n");
          bestellFenster.document.write(" bitte an mich, z.B. copy &amp; paste und mail :-) <br>\n");
          bestellFenster.document.write("<hr>\n");
 
            //for each  (var fEntry  in bestellteFiles ) erst ab js 1.7
            for ( var i = 0; i < bestellteFiles.length; ++i)
            {                            
                bestellFenster.document.write(bestellteFiles[i].getFullName());
                bestellFenster.document.write(" " + bestellteFiles[i].bestellungen + "</br>\n");
                //bestellFenster.document.write(fEntry.getFullName());
                //bestellFenster.document.write(" " + fEntry.bestellungen + "</br>\n");
            }            
 
          bestellFenster.document.write("</body></html>");
          bestellFenster.document.close();
          //alert("Liste");
        //alert("Liste");
        }); //end of bestellListe click
        //------------------------------------------------------------------------------- 
        \$("#divButtonBestellUebersicht").click( function ()
        {
          if (actualKey != "-1" )
          { //noch aktualisieren
 
            allInputs=\$("#gallery input"); //get the contents of all input fields
 
            var actualDir = bestellteFiles;
            if (actualKey != "0") //komme aus einem anderen Folder
               actualDir = allDirectories[actualKey];
            for (i = 0; (i < allInputs.length)  && (i < actualDir.length ) ; ++i)
            {
               actualDir[i].bestellungen = allInputs[i].value; //sichern, reihenfolge müsste stimmen               
               pruefeBestellteFiles(actualDir[i]);
            }            
          }
          actualKey = "0";
          var content="";
          var anzahl = bestellteFiles.length;
            //for each  (var fEntry  in bestellteFiles)
            for (var i = 0; i < anzahl; ++i)
            {                            
                content+= bestellteFiles[i].ToHTML(); 
            }            
          \$("#gallery").html(content);//set all
          if (showBestellAufnahme)
          {
            \$(".fileEntry .bestellung").slideDown("slow");
            \$("#divButtonBestellAuswahl").html("Bestellauswahl ausblenden");
          }
        }); //end of bestellUebersicht click
      \$("#divButtonBestellAuswahl").slideDown("slow");
		  $rausE
      //zum Schluss noch die Breite der gallerie anpassen
      var breite = \$("#divNavigation").width();
      breite+=20;
      breite+="px";
      //alert (breite);
      \$("#gallery").css("margin-left",breite); //galerie nach rechts
 
    });  //end of $.ready
  </script>
endIndex
}
 
#----------------------------------------------------------
#remove all directories which does not contain 
#files of allowed type
function removeEmptyDirs()
{
  dirCount=${#allDirectories[@]}
  declare -a markedForRemoval
  for (( i = 0 ; i < $dirCount ; i++ )) # loop over all directories
  do
    if [[ -e $albumTmpList ]]
    then
      rm -f $albumTmpList
    fi
    actualDir=${allDirectories[$i]}
    for type in ${imageTypes[*]}
    do
      find "$actualDir" -maxdepth 1 -type f -iname "*$type" | sort >> $albumTmpList
      #find all files in this dir, filename must match the type, caseinsesitive
    done
    for type in ${movieTypes[*]}
    do
      find "$actualDir" -maxdepth 1 -type f -iname "*$type" | sort >> $albumTmpList
      #find all files in this dir, filename must match the type, case insesitive
    done
    # read this file-names and strip the path 
 
    j=0
    files=( ) # empty array
    while read file
    do
      file=${file##*/}
      files[$j]=$file        
      let j++
    done < $albumTmpList
    #following check is complicated but should work. 
    #I have not build up a tree structure, so I check if there
    #are accepted files below this dir. 
    #if not this dir is a leaf dir or would become a leaf dir after removing
    #the dirs inside
    if [[ ${#files[@]} -eq 0  ]] #nothing found, check if dir is a tree leaf -> then remove
    then
      fileCount=0
      for type in ${imageTypes[*]}
      do
        tmpCounter=$(find "$actualDir" -type f -iname "*$type" | wc -l)
        let fileCount+=tmpCounter
      done
      for type in ${movieTypes[*]}
      do
        tmpCounter=$(find "$actualDir" -type f -iname "*$type" | wc -l)
        let fileCount+=tmpCounter
      done
      if [[ $fileCount -eq 0 ]]  # found nothing, this dir could be removed in array
      then 
        markedForRemoval=("${markedForRemoval[@]}" "$i" )        
        #echo "mark $actualDir" 
      fi
    fi 
    #check on leaf dir finished ------------------------------------------
    done #end of for loop throug all directories
    #remove directories whith no files of accepted types
    for removeIt in "${markedForRemoval[@]}"
    do
      echo "We kick: " "${allDirectories[$removeIt]}"
      unset allDirectories[$removeIt]  
    done
    allDirectories=("${allDirectories[@]}") # und array "eindampfen"
}
 
#-----------------------------------------------------------------
#read all directories and build global dirList
#build 2 dimensional associative array with the content
#of the directories - in javascript -> add to header
#dont use dir $thDir and $smDir (thumbs and smaller)
function readDirectories
{
  local i=0
  find . -type d | sort > $albumTmpList
  while read dir
  do
    lastPart=${dir##*/}
    #images beinhaltet lightbox-bilder
    if [[ $lastPart != $thDir && $lastPart != $smDir && $dir != "./images" ]] 
    then
    allDirectories[$i]=$dir
    let i++
    else
    echo "Skip $dir it is a dir with thumbs or smaller images"
    fi
  done < $albumTmpList
  #remove top level dir 
  unset allDirectories[0]
  allDirectories=("${allDirectories[@]}") # mit " erhält man auch leerzeichen in einem Array-Eintrag
  #for-loop -> auch mit Anfuehrungszeichen 
  #remove empty dirs
  removeEmptyDirs  
  #extend the header of the index.html - file
  cat << endObjectDefinition >> index.html
  <script type="text/javascript">
    //object for one file-Entry
    function fileEntry(name,dir, type)
    {
        //public attributes
      this.name       = name; 
      this.dir        = dir; 
      this.type       = type; //type is image or movie
      this.bestellungen = 0;
      //private attributes
      var fullName = this.dir + "/" + this.name; //double / doesn't matter
      var thumbName = this.dir + "/$thDir/$thPrefix"+this.name;
      var smallerName = this.dir + "/$smDir/$smPrefix"+this.name;
 
      //get html-Representation of element
      this.ToHTML = function ()  //public method of object fileEntry
      {
        var erg = "<div class='fileEntry'>\n";         
        if (type=="movie")
        {
          erg +=    "  <a class='typeMovie' href=\"" + fullName + "\">"; //private - ohne this.
          erg +=    "     <img class=\"thumb\" width='150px' src='images/filmrolle.gif'  alt=\"" + this.name + "\"></a>\n";
          erg +=    "  <div>" + this.name + "</div>\n"; //hier keine Bestellung
          erg +=    "  <div style='display:none' class='bestellung' >\n"  +  
              " Film, keine Bestellung </div>";         
 
 
        }
        else if (type=="image")
        {
          erg +=    "  <a class='typeImage' href=\"" + smallerName + "\">"; //private - ohne this.
          erg +=    "     <img class=\"thumb\" src=\"" + thumbName + "\" alt=\"" + this.name + "\"></a>\n";
          erg +=    "  <div>" + this.name + "</div>\n";
          erg +=    "  <div style='display:none' class='bestellung' >\n"  +  
              "    <span class='up' style='cursor: pointer; border:solid 1px;'>&nbsp;&and;&nbsp;</span>\n"         +
              "    <input class='inputBestellung' type='text' size='2' value='" + this.bestellungen +"' maxlength='2'>\n" +
              "    <span class='down' style='cursor: pointer; border:solid 1px;'>&nbsp;&or;&nbsp;</span>\n"          + 
              "  </div>";         
 
        }
        else 
          erg += "something went wrong";      
         erg +=    "</div>\n";
         return erg; 
      }
      this.getFullName = function ()
      {
        var fn = fullName.replace(/\/\//g,"/");
        return fn;
      }
 
    }
endObjectDefinition
  #get the files - maybe we could combine this with removeEmptyDirs
  #but this way should be clearer and cause I mix shell scripting and
  #javascript - I prefer this way
   echo "// empty Array possible, should be no problem" >> index.html      
  for actualDir in "${allDirectories[@]}" # " wichtig, falls leerzeichn
  do
    echo "allDirectories[\"$actualDir\"]=new Array() " >> index.html 
    #read the imageTypes
    for type in ${imageTypes[*]}
    do
      find "$actualDir" -maxdepth 1 -type f -iname "*$type" | sort > $albumTmpList
      while read file
      do        
        file=${file##*/} # name, now generate javascript entry for new file
        echo "allDirectories[\"$actualDir\"].push(new fileEntry(\"$file\",\"$actualDir\",'image'));" >> index.html
      done < $albumTmpList
    done
    #read the movieTypes
    for type in ${movieTypes[*]}
    do
      find "$actualDir" -maxdepth 1  -type f -iname "*$type" | sort> $albumTmpList
      while read file
      do        
        file=${file##*/} # name, now generate javascript entry for new file        
        echo "allDirectories[\"$actualDir\"].push(new fileEntry(\"$file\",\"$actualDir\",'movie'));" >> index.html
      done < $albumTmpList
    done    
  done
  echo "</script>" >> index.html
  echo "</head>" >> index.html
  echo "<body>" >> index.html
 
}
#----------------------------------------------------------
function generateNavigationTree()
{
  cat << eNavIntro >> index.html
  <div id="divButtonNavigation">
  Navigation<br>
  </div>
  <div id="divButtonBestellAuswahl">
  Bestellauswahl einblenden
  </div>
  <div id="divBestellung">
  <div id="divButtonBestellListe"> Bestell-Liste erzeugen </div>
  <div id="divButtonBestellUebersicht"> Bestell-&Uuml;bersicht </div>
  </div>
  <span id="divButtonNavigationHide">
     ausblenden
  </span>
  <!-- Liste zur Navigation, gebe den vollen Namen hidden mit, class h -->
  <div id="divNavigation">
  <ul id="navigationTree" class="filetree">
eNavIntro
  firstEntry=${allDirectories[0]##*/}
  fullFirst=${allDirectories[0]}
  indent="    "
  echo -n "$indent<li> <span class=\"folder\"> $firstEntry <span class="h" >$fullFirst</span></span> " >> index.html  
  prevAnzahl=$(echo ${allDirectories[0]} | sed 's/[^/]//g' | wc -L) # wieviele / -> tiefe
  dirCount=${#allDirectories[@]}
  lenIndent=${#indent}
  for (( i=1; i < $dirCount; i++))
  do
    lenIndent=${#indent}
    anzahl=$(echo ${allDirectories[$i]} | sed 's/[^/]//g' | wc -L)
      #ersetze alles ausser / und bestimme die Länge der Zeile
      #das ist die Anzahl der / in diesem directory
    #echo $anzahl $prevAnzahl
    if [ $anzahl -gt $prevAnzahl ] # eine Ebene tiefer, hier nur eine moeglihc
    then
      indent="$indent  " # haenge 2 an
      echo '<span class="goon">&raquo;</span>' >> index.html #kommen noch unterpunkte
      echo "$indent<ul>" >> index.html #neue unterliste in diesem listenpunkt
      indent="$indent  " # haenge 2 an
    elif [ $anzahl -lt $prevAnzahl ] #  Ebene hoeher
    then # Vorsicht, hier muss man ggf. mehrere Ebenen hoch
      hoeher=$prevAnzahl-$anzahl
      echo "</li>" >> index.html #erstmal etzten Punkt schließen
      for (( hZaehler=0 ; hZaehler < $hoeher ; hZaehler++ ))
      do 
        let lenIndent-=2;
        indent=${indent:0:$lenIndent} #von 0 bis len
        #echo "$indent"${#indent}
        echo "$indent</ul>" >> index.html # unterebene schließen 
        let lenIndent-=2;
        indent=${indent:0:$lenIndent} #0 bis len
        echo "$indent</li>" >> index.html  
      done  
    else 
      echo "</li>" >> index.html #listenpunkt schließen
    fi
    #folgendes auf jedem Fall, leading path removed
    aktName=${allDirectories[$i]}
    aktName=${aktName##*/}    
    echo -n "$indent<li> <span class=\"folder\"> $aktName <span class='h'>${allDirectories[$i]}</span> </span>" >> index.html
    prevAnzahl=$anzahl
  done
  let lenIndent-=2;
  indent=${indent:0:$lenIndent}
  echo "$indent</li>" >> index.html
  let lenIndent-=2;
  indent=${indent:0:$lenIndent} 
  echo "$indent</ul>"  >> index.html #end of List
  echo "</div>"   >> index.html 
  echo "<div id='gallery' >  <p style=\"text-align:center;\">Galerie</p> </div>">> index.html;
  echo "</body>"  >> index.html 
  echo "</html>"  >> index.html 
}
#----------------------------------------------------------
function convertToThumbsAndSmaller()
{
  rotiere=$1
  echo " do the thumbs and smaller images? (only skip if you have them) "
  echo "s: skip" 
  echo "a: ask for every dir" 
  echo "e: if file exist don't generate again"
  echo "Enter to generate thumbs and smaller"
  read doThumbs
  if [[ $doThumbs. != "s." ]]
  then  
    for actualDir in "${allDirectories[@]}" # " wichtig, falls leerzeichn
    do
      if [[ $doThumbs. == "a."  ]]
      then
        echo -n "images and thumbs for $actualDir (j/n) [n]: "
        read imgInDir      
      else
        imgInDir="j"
      fi
      if [[ $imgInDir. == "j." ]]
      then
        mkdir -p "$actualDir/$thDir"
        mkdir -p "$actualDir/$smDir"
        for type in ${imageTypes[*]}
        do
          find "$actualDir" -maxdepth 1 -type f -iname "*$type" | sort > $albumTmpList
          while read file
          do
            newThumb=${file%/*}"/$thDir/$thPrefix"${file##*/}
            newSmaller=${file%/*}"/$smDir/$smPrefix"${file##*/}
            #hier test ob file existiert, falls ja wird die konvertierung
            #nicht durchgefuehrt, wenn der user die Option e gewaehlt hat
            #pruefe nur newSmaller
            processFile=1
            if [[ -e $newSmaller && "$doThumbs" == "e" ]]
            then
               processFile=0
            fi
            if [[ "$processFile" -eq "1" ]]
            then
              # ggf test auf notwendigkeit des rotierens
              orient=1
              if [[ $rotiere. != 'n.'  ]]
              then
                orient=$(exiftool -q -s -s -s -n -Orientation "$file")
                if [[ $orient -ne 1  ]]
                then
                  #echo cp $file $file"_backUpBeforeRotation"
                  cp "$file" "$file""_backUpBeforeRotation"
                  jhead -autorot $file
                fi
              fi 
              convert -verbose -thumbnail x$thumbHeight "$file"  "$newThumb"
              convert -verbose -resize x$smallerHeight "$file"  "$newSmaller"         
              if [[ $orient -ne 1 ]]
              then
                mv "$file""_backUpBeforeRotation" "$file"
              fi
            else 
              echo "skip $file"
            fi
 
            #ende soll file bearbeitet werden
          done < $albumTmpList
        done
      fi  
    done
  fi
 
}
#----------------------------------------------------------
 
cat << endIntro
Erzeuge ein Album aus allen Verzeichnissen und Unterverzeichnissen
Das oberste Verzeichnis spielt eine Sonderrolle. 
Hier wird eine index.html erzeugt, die die Navigation für die Unterverzeichnisse
zur Verfügung stellt. 
Die Dateien $jquery, $jqueryLightBox und $jqueryTree 
müssen in das Verzeichnis $sourceDir kopiert werden. 
Ein Verzeichnis $cssDir und die Datei 
$cssDir/$styleFile  werden angelegt. 
In $cssDir ist noch die css Datei fuer lightbox notwendig
 
Die Datei $albumTmpList wird erzeugt bzw ueberschrieben.
 
Die Bilder koennen bei Bedarf automatisch gedreht werden, die Originale werden
dabei nicht veraendert. Dazu sind die Programme jhead, jpegtran und exiftools 
noetig und die Kamera muss die exif-Informationen zur Orientierung gespeichert haben. 
Optionen 
      Ctrl-C -> Abbruch
           j -> automatisch drehen (Voreinstellung)
           n -> nicht drehen 
endIntro
 
read rotiere
 
cat << endBestell
Urspruenglich habe ich mal eine Bestellannahme hinzugefuegt, damit man
die Files, von denen man einen Abzug machen moechte hier waehlen kann,
um eine Liste zu bekommen.
Das wird optional gemacht, da das resultierende Javascript bei 
grossen Hierarchien sonst zu langsam wird. 
 
Also - Bestell-Geschichte gewuenscht: n / (j) 
endBestell
 
read bestell
 
#Html-Datei index.html erzeugen, diese hatte im ersten entwurf einen frame
generateStyles $bestell #write style file
generateIndexHead $bestell # Kopf schreiben
readDirectories #read directory tree, used for navigation div
generateNavigationTree #div fuer die Navigation füllen
convertToThumbsAndSmaller $rotiere # if the thumbs are available we don't generate them
 
#leere Verzeichnisse entfernen
find . -ignore_readdir_race -type d -empty -name smaller -exec rmdir {} \;
find . -ignore_readdir_race -type d -empty -name thumbs -exec rmdir {} \; 
 
echo "Vergessen Sie nicht die fehlenden Dateien in das css Verzeichnis zu kopieren"
echo "Beachten Sie, dass sie auch das Verzeichnis sources im aktuellen Verzeichnis benoetigen"
 
Parsed using GeSHi 1.0.8.6
Download / View Source / Run it   (depends on file type)

Karsten Römke (k Ponkt roemke at gmx in de), Rechtliches, Datenschutz, etc.
Rein private Seite, lediglich eine Spielerei
Last modified: 2010-04-19
Created: 2010-04-13
Reason: –
Home sweet home