BASH 脚本, 生成 Web 浏览的 gallery

用到了一点点Javascript, 没有怎么测试.
#!/bin/bash
#
# generate a gallery for web usage.

# useage: title dir
#
# Ref jiangzuoyan.blogspot.com
# date: 2007-03-03 13:04:43


TITLE=${1:-View}

DIR=${2:-./}

parse_dir()
{
   local dir=$1 fn images  subdirs title aimgs aaimgs
   images=''

   subdirs=' '
   title=''
   local oldp=`pwd`
   cd "$dir" || return 3;
   pwd

   for fn in * ;
   do
       if  [ -d "$fn" ] ; then

           echo "[dir $fn ..."
           parse_dir "$fn"
           echo "end $fn]"
           subdirs="$subdirs <a href='$fn/index.html'>$fn</a>"

       else
           file -b -i "$fn" | grep "image/" > /dev/null  &&  {
               if [ "$images" ] ; then

                   images="$images,\"$fn\""
               else
                   mkdir -p ".cache"
                   images="\"$fn\""

               fi
               if [ ".cache/$fn" -ot "$fn" ] ; then

                   convert -resize 90x90 "$fn" ".cache/$fn"
               fi
           }
       fi
   done


   title=`basename $dir`
   title=${2:-$title}
   set_index "$subdirs" "$title" "$images"

   cd $oldp
}

set_index()
{
   local IMAGES SUBDIRS TITLE
   IMAGES=${3:-null}

   SUBDIRS=${1:- }
   TITLE=$2
cat > index.html <<EOF_INDEX_TPL

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<title>$TITLE</title>

</head>
<body>
<style>
.simgc{width:100px;height:100px;float:left;}
.aimg, .simg{max-width:90px;max-height:90px;margin:5px;}
</style>

  <a href="../index.html" style="float:right;">Up</a>
<h1>$TITLE</h1>
<div id="vd"></div>


<script>

var Class = {
 create: function() {
   return function() {

     this.initialize.apply(this, arguments);
   }
 }
}

Object.extend = function(destination, source) {

 for (var property in source) {
   destination[property] = source[property];
 }

 return destination;
}


Function.prototype.bindAsEventListener = function(object) {
 var __method = this;
 return function(event) {

   return __method.call(object, event || window.event);
 }
}

var ImageView=Class.create();
ImageView.prototype={

  options:{base_src:'./',
           pageSize: 50},

  initialize:function(obj, options){

     Object.extend(this.options, options||{});
     this.obj=document.getElementById(obj);
     this.showContainer=document.createElement('div');
     document.body.appendChild(this.showContainer);
     this.showContainer.style.display='none';
     this.showContainer.style.zIndex="10000";
     this.showContainer.style.position="absolute";
     this.showContainer.style.background="green";
     this.showContainer.style.overflow="auto";
     this.showContainer.style.margin="0px";
  },


  viewImage:function(imgsrc){
     var s='';
     s+='<div class="simgc">'

        +'<img src="'+this.options.base_src+".cache/"+imgsrc+'" class="simg" />'
        +'</div>';
     return s;
  },


  viewImages:function(imgs){
     var s='';
     for(var i=0;i<imgs.length;++i){

         s+=this.viewImage(imgs[i]);
     }
     return s;
  },


  slideTo:function(ith){
     if(ith<0 || ith>=this.images.length)

        return ;
     this.cur_slide=ith;
     this.cur_images=this.images.slice(ith, ith+this.options.pageSize);
  },

  slideLink:function(){

     var pith=-1, nith=-1, pl, nl;
     nith=this.cur_slide+this.options.pageSize;
     pith=this.cur_slide-this.options.pageSize;
     if(pith<0) {

        if(this.cur_slide==0) pith=-1;
        else pith=0;
     }

     if(nith>=this.images.length){ nith=-1;}
     if(pith>-1) pl=this.setSlideAction(pith);
     if(nith>-1) nl=this.setSlideAction(nith);
     return [pl, nl];
  },


  setSlideAction:function(ith){
     var sp=document.createElement('span');
     sp._pt_ith=ith;
     sp._pt_viewer=this;
     sp.onclick=function(){

        this._pt_viewer.slideTo(sp._pt_ith);
        this._pt_viewer.view();
     };
     return sp;
  },


  view:function(){
     if(!this.cur_images)
        this.slideTo(0);
     var s=this.viewImages(this.cur_images);
     this.obj.innerHTML=s;
     var dpn=document.createElement('div');
     dpn.style.clear="both";
     dpn.style.textAlign="center";
     if(this.cur_slide>0){

        var f=this.setSlideAction(0);
        f.innerHTML="first | "
        dpn.appendChild(f);
     }

     var pnl=this.slideLink();
     if(pnl[0]){
        pnl[0].innerHTML="<<";
        dpn.appendChild(pnl[0]);
     }

     var t=document.createTextNode(" | "+this.cur_slide+" | ");
     dpn.appendChild(t);
     if(pnl[1]){

        pnl[1].innerHTML=">>";
        dpn.appendChild(pnl[1]);
     }

     if(this.cur_slide+this.options.pageSize<this.images.length){
        var e=this.setSlideAction(this.images.length-this.options.pageSize);
        e.innerHTML="  | end";
        dpn.appendChild(e);
     }

     this.obj.appendChild(dpn);

     var imgs=this.obj.getElementsByTagName('img');
     for(var i=0;i<imgs.length;++i){

        imgs[i].onclick=this.imgOnclick.bindAsEventListener(imgs[i]);
        imgs[i]._pt_viewer=this;
     }

  },

  imgOnclick:function(e){
     var v=this._pt_viewer;
     v.toggle(this);
  },


  toggle:function(img){
     if(this.curshow){
        if(this.curshow==img){

           if(img.className=='aimg'){
              img.className='simg';
              this.unshow(img);
           }

           else
              alert('toogle, why this happend?');
           this.curshow=null;
           return;
        }
        else {

           this.curshow.className='simg';
        }
     }
     this.curshow=img;
     this.show(img);
     img.className='aimg';
  },


  posShow:function(){
     var x=this.docScrollLeft(), y=this.docScrollTop();
     var m=this.showContainer;
     m.style.left=x+"px";
     m.style.top=y+"px";
     m.style.display="block";
  },


  show:function(img){
     this.showContainer.innerHTML='<img src="'+this.getBigsrc(img.src)+'" alt="'+img.src+'"/>';
     this.showContainer.onclick=img.onclick
     this.posShow();
  },


  getBigsrc:function(imgsrc){
     var idx=imgsrc.lastIndexOf("/.cache/");
     if(idx<0) return imgsrc;
     return imgsrc.slice(0, idx)

           +imgsrc.slice(idx+".cache/".length);
  },

  unshow:function(img){

     this.showContainer.style.display="none";
  },

  // pick form RicoUtil ....
  docScrollLeft: function() {
     if ( window.pageXOffset )

        return window.pageXOffset;
     else if ( document.documentElement && document.documentElement.scrollLeft )
        return document.documentElement.scrollLeft;
     else if ( document.body )

        return document.body.scrollLeft;
     else
        return 0;
  },

  docScrollTop: function() {

     if ( window.pageYOffset )
        return window.pageYOffset;
     else if ( document.documentElement && document.documentElement.scrollTop )

        return document.documentElement.scrollTop;
     else if ( document.body )
        return document.body.scrollTop;
     else

        return 0;
  }
};
var images=[$IMAGES];
var iv=new ImageView('vd');
iv.images=images;
iv.view();

</script>
<hr>
<div>
$SUBDIRS
</div>
</body>
</html>

EOF_INDEX_TPL
}


umask 022
parse_dir $DIR $TITLE

No comments: