Annotation of scripts/pgallery/src/pgallery.sh, revision 1.16

1.1       as          1: #!/bin/sh
                      2: #
                      3: # THE BEER-WARE LICENSE 2012
                      4: # <as@paefchen.net> wrote this file. As long as you retain this notice you
                      5: # can do whatever you want with this stuff. If we meet some day, and you think
                      6: # this stuff is worth it, you can buy me a beer in return Aron Schlesinger
                      7: #
1.16    ! as          8: # $Paefchen: scripts/pgallery/src/pgallery.sh,v 1.15 2012/08/29 14:15:12 as Exp $
1.1       as          9: #
                     10: 
                     11: ARG_TITLE="PGallery"
                     12: ARG_FILES=
                     13: ARG_FILETYPES="jpg jpeg png gif tif tiff"
                     14: ARG_TNSIZE="180"
                     15: ARG_TNQALITY="70"
                     16: ARG_BIGSIZE="950"
                     17: ARG_BIGQALITY="90"
                     18: ARG_INDEX="index.html"
                     19: ARG_DIR="."
                     20: ARG_UPDATE=1
                     21: ARG_COPYRIGHT="&copy; $(date +%Y)"
1.6       as         22: ARG_INFOFILE=""
                     23: ARG_MAILTO=""
                     24: ARG_MAILFROM="PGallery <${USER}@${HOST}>"
                     25: ARG_URL=
1.7       as         26: ARG_EXIF="0x920a 0x829d 0x829a ISO 0x8827 / 0x010f - 0x0110"
1.1       as         27: 
                     28: BIN_CONVERT="/usr/local/bin/convert"
                     29: BIN_EXIFAUTOTRAN="/usr/local/bin/exifautotran"
                     30: BIN_IMGINFO="/usr/local/bin/imginfo"
1.6       as         31: BIN_SENDMAIL="/usr/sbin/sendmail"
1.7       as         32: BIN_EXIFTRAN="/usr/local/bin/exiftran"
                     33: BIN_EXIF="/usr/local/bin/exif"
1.1       as         34: 
                     35: MKAKEFILE=".htmakefile"
1.16    ! as         36: VERSION="pgallery-1.3"
1.1       as         37: 
                     38: #
                     39: # usage()
                     40: #
                     41: usage()
                     42: {
                     43:        cat <<USAGE
                     44: usage $0: ( [-f <files>] | [-s <suffix>] ) [-d <dir>] [-n <name>]
                     45:                 [-t <thumbnail_size>] [-u <thumbnail_quality>]
1.7       as         46:                 [-b <big_size>] [-c <big_quality>] [-l link] [-e <exif>]
1.6       as         47:                 [-i <index>] [-C <copyright>] [-F <mailfrom>] [-T <mailto>]
                     48:                 [-U] | -h | -v
1.1       as         49: Options:
                     50:   -b size       size from big images in pixel (default: $ARG_BIGSIZE)
                     51:   -c quality    quality from big images 0-100% (default: $ARG_BIGQALITY)
                     52:   -d dir        gallery dir (default: $ARG_DIR)
1.7       as         53:   -e exif       list of tags in hex. (default: $ARG_EXIF)
                     54:                 see: http://www.exiv2.org/tags.html
1.1       as         55:   -f files      gallery images
                     56:   -h            this page
                     57:   -i name       index file name (default: $ARG_INDEX)
1.6       as         58:   -l url        gallery link
1.1       as         59:   -n name       page title (default: $ARG_TITLE)
                     60:   -s suffix     list of suffix. if no \`\`-f'' defined, used to find images
                     61:                 in \`\`-d'' directoy. case insensitive
                     62:                 (default: $ARG_FILETYPES)
                     63:   -t size       size from thumbnail images in pixel (default: $ARG_TNSIZE)
                     64:   -u quality    quality from thumbnail images 0-100% (default: $ARG_BIGQALITY)
1.4       as         65:   -v            print version
                     66:   -C copyright  copyright (html) string (default: $ARG_COPYRIGHT)
1.6       as         67:   -F from       mail sender (default: $ARG_MAILFROM)
1.5       as         68:   -I file       info text file for pgallery. info file paras prefered.
                     69:                 the syntax of the file is MAKE(1)
1.6       as         70:                 supported variable: TITLE COPYRIGHT INDEX FILETYPES TNSIZE URL
                     71:                                     TNQALITY BIGSIZE BIGQALITY MAILTO MAILFROM
1.7       as         72:                                     EXIF
1.6       as         73:   -T mailto     send update infos to this address. if not set, no mail delivery
1.1       as         74:   -U            no update, new calculation of all images.
                     75:                 normally only new and modified images will calculated
                     76: USAGE
                     77:        exit
                     78: }
                     79: 
                     80: #
                     81: # get_my_path()
                     82: #
                     83: get_my_path()
                     84: {
                     85:        current=$(pwd)
                     86:        cd $(dirname $0)
                     87:        echo $(pwd)/$(basename $0)
                     88:        cd "$current"
                     89: }
                     90: 
                     91: #
                     92: # html_header()
                     93: #
                     94: html_header()
                     95: {
                     96:        cat <<HTML
1.15      as         97: <?xml version="1.0" encoding="utf-8"?>
1.1       as         98: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1.15      as         99:        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1.1       as        100: <html xmlns="http://www.w3.org/1999/xhtml">
                    101: <head>
                    102:        <title>$ARG_TITLE</title>
1.15      as        103:        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
                    104:        <style type="text/css">
                    105:        <!--
1.1       as        106: body {
                    107:        background-color: #464646;
                    108:        background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFgAAABYB\
                    109: AMAAACDuy0HAAAAG1BMVEX+/v4BAQH///8KCgoDAwN/f3/19fWAgID8/PzhDwT2AAAACXRSTlMFBQUFBQU\
                    110: FBQWHDtP9AAALwklEQVR4Xg3KOWOyWhAA0Bn2ci57eXEvQY1JCZp8sQTjVoJLTAkaE0swbj/7ve4UB37FL\
                    111: W4q86Lwwlh86J/ASAkpWaj+Krbb31HzH0Kjc2tIl7SADaWbpZBPE5dds6jJNyNdjAyKWqdroIixWRQIY6E\
                    112: /kOY7hIciL/ZfrAO3XP/06AuUJ3mSd/z95OB9vIal0DPlaZWHP7RE6DIXjmKqKkuGr+xNZylOnj1GSlUKv\
                    113: nxZDBOIzTfMe0fJgJ7c/GIIOdUuKxYyBFUOzvY6AC5AXx8R+o5O4S0j0wqBND3ErIYm/XHFbQjtH1MXD5d\
                    114: Ubp19OFdjkDlys+HSwrBgHRvL9wVN/pi8ViOIwcv/D1GRW6UuDvJLLQA5lCI17iUdsKYpOuYfMATGnpn/Z\
                    115: s3W6gov51G+/Vs9Ay//we5kh8uwvEPum6o5HkDMDb3ZWunwtq+UzENU8NphDdbvNtKM3knx5gi6UMSQl+e\
                    116: Gs+27mraDtxeWdH+T62Us/GylEtr7Ct8jlbeXKvAf5onx8D2uVt1J/GblV+XQyKUInOUG44fqjcszK266y\
                    117: HWAAYG9ekhvy4l4Maa44jYVyV2RFEuS54e2HcswtmNdqR/+V4P0O9e4XnpWgxVSQkNXpYMCxJ4Vel0lmi5\
                    118: 6jnYIIJAQMndF+zTEiyuj92r3ijJT1O0alPQnLWJvJLR7Xx7Xg9fm9QOqFu8o29m3QQqFwZN4bki/RoprN\
                    119: tMKKtEET9iMsJyKpkiguAorn2yzkv0wG3M1EEVDJP5VN7muLjYCglzdGQ7boYGgRmorzhRDq83gglgylC+\
                    120: hBLEyy6ZQWNwCmmqt6PvExAqGEA9V2XIT4/fS+I2cx1n5td85kOCjHfPWTg72FJ/+vKOyggt+rytFbEDJW\
                    121: L+mPwpgw6HtFLIHmq4o2m1nZ9saKwiKEOTVZtWlnqHODPu949VfKD+zzpfynd/ZZU5IWZ0dgnqRHC4uOBp\
                    122: BsT8N7YbFJzADiW2eo/T979OKFxY8zk/+HR/NNEkzgSBsmA35Sayz1m/ubxgmYQOmffyRh9gdx42mUVX51\
                    123: 2oqWkfxAzyuSCxx1cywx3jIXuXJEEbssymo0xMy7SskJW9C5IPYroPwQunt7f5FEPPXJLWRbGHcL4Q3sx3\
                    124: TLAN6W672r/I5CKkL6zSwwk0AI8+iBCSv1Y7QQP5RSoLE227uy8vn22Y6dhLBgEsRh18cTGjIv3y+60Kmt\
                    125: 3YAZQX8qf3bJDUc/5pdjti+KwAZ9GzzQzd23d1JBAnSvWkWB8YfsIGlspHitNiMPYPFfR+OecRuPyxgfoP\
                    126: 9/HkR3cR27IohiaDXCk/3VNP6lIxP9TBnsMeAAUZloq6P8KURLBsNFuiA3LsN/d9qpCeKKIBgSzsN5k+rd\
                    127: h3uh0VbvMuOIomJD1fBOiCqIsvklS5bOQhMaahJC+Rc+6lz+Uvxmq05Py+LoGIQlLKvlcaHsFG9Ui66H/q\
                    128: dHz67sPRGho+ruC92QgN5JEMmLsZREEiJu78FJbyzT8FsdK90XoEcezn2R5iLUzZhczJmf1yNY3gJNJUQv\
                    129: bpTznTAbnV5J8iL4q2OWuhJEndWVTyEr8M5VGTWtvOmUo1DsnOsqXE5ZzKE8K4/8cl8+c1XArp1RUKz+iK\
                    130: P96j2FcUmA+v0HnEr0iUdSrRK5duAj1FQamvpiaXR2JddD6g8n4SyFx/fjT4LkC+ghJckj1e1wP+DrHrpI\
                    131: iMaPH5F1rcaRvwZWfEn6fx+/C7PdXABGLNKjr1USZ5XyHjsafXMEoXtguAfjykMioMMHISXVAc9yQY5o5Q\
                    132: g8MM0nhWCA2HoiEgBc1EH+warLjxH3Ln68M/ciFqI1bG0mBOxiNreOuShEf/9pIzhm1Bh2cbYVxn2IYQ7e\
                    133: ljYpab/5EdPF2PSmcy+62j6e2HBPNbe+8JVMuRQBrWdL9uBh4bYbQaQJ07FyfcpCuvSuxUyYjP6avvw9gT\
                    134: cAj0uTVohSwOHDDaHTs8nyachMBcWoVDWp3/lWgqeCLMneAUhSuhD2RJpufLOSi7emxOVhYsOGomV2JCEK\
                    135: jWu7kuqwueyFEmDgVhR0l4oHn8W87UZuxb8id54SxHWiSnPKnMyAhzdhi2wN/AoH3OYwLajuybB8h/QeJJ\
                    136: iX1gIt+dfij+gr0CJRXQ2Y04Q6q8xHzfWm9FIgchiW0+X86tIotIGzRG1gENaKokQkLn+FXZ2x3KUcp7d/\
                    137: NUsmOmFCG/i03YB8pi0eiNS4LUIfA06AKvfQmP/VAXS1AP2kzJ+9LAaTafvFyO7bz8U9OCpld2q1eHGts+\
                    138: ZFrt04AmIlubOPP7Xayfi/r0tiX2aaPT9Dz4+TVPBoXsjHDzWfrmawOsZfmBT/k2+c6sz/hvD5wjrjT7Xg\
                    139: RlnEzPuZermi1jqfUrE3q7VdFfJu5oT9Ad+VUh1fIwIFhBy8TmMuhIeX2XpmogmvS1C3ZuwiyR87ZSrj0J\
                    140: v1DpEAYkbcL3RpjZXmZpPV4mXH8z8Nh8CS+R+PpcTnkhyr5UJaSiz0wjK22Ewl+zS+pTug0PQ0CSnJQ5Lf\
                    141: dR77vVZufgjkQ/ydf4V5zpEaNq+JZmrQK6WdZBacmMHL9RmLnPUs0/MYwYFzoyrXYQMTHGAUJOfumR5r79\
                    142: MZO28DIEXQVT5wGw99TY1T0GOCC/BzWv8READwICd0LjUNKnE6ORVa0lOnqhoO0v33lwWcwF0ynTgTpFxy\
                    143: +0OKdphNDWJlH8ubKoG6WJXtKxAwbsilpBJB+GBwimvTsCrv1R7LSX9ExkAw44ZEcxU3L50OHnKAyKZNe1\
                    144: fih+hVqItRGCDf7shuvme+lTWteX5oYuc58NrCaqjYIrIV0PFyQeh2ZzZEqNS60LuhnP5wweMkkaU93pDA\
                    145: /RWPNeGpPCBgiUeDvV0L1NfdRP/Hn5i7rUK7kftlIWeIUIYbtzzFl9nlIeaNfoX+x/qyWzIABLTZDbeq/h\
                    146: DZpxg2gkh+ICfSU8OUpJ8yWY17uQ5EGa+GGWFmnrBd9vX3KOteYkJaMpPwJ4TjzDjbhkOMKmWKClzVJ2g8\
                    147: 1YGFl/c0xPIKncgJGdUKvZoUUJu0gYaIAh6E0xNeQ15qpJXzNITgf4W+w/oUaKOM54EMUi1j5yvOCsEe8J\
                    148: YpwVGj53lNiPMY9Rltgd4icp82fvN69zkSBUI40nJSRTeHz7h1IX42Cr0klWjxjO05MSX1IaTeDmTRGEeK\
                    149: vAvtaaBaLQnjftGJz+4cjFyy6/iCjLGF2/gW+jQhEUxbEBPyQzXi+Bb4kc9wK4jIwNLWbwQAOtYKRLaipD\
                    150: H+X4TPPOG8DCNY4IC9yBk1qcibjhUgRnDcf35pl9d5otbvQjOIXlEu5dVtm5LRaK5KWcD/PX6LaGd25CuN\
                    151: HG/vgeIB1kcpCme+J8idlcjfBALAJSggznsGHGOAJgdGduMnZg+bAaeGASGV9bh/X2wPsVTmBLxmTTQsBG\
                    152: FkEOkZJTsGAm+HrtMDbWwvTXOutX1u7BxIq9Xib6DkFMbUitNdrYsULkahsAhBEh9FjdzL9BNARxTSr7T3\
                    153: u1rE+IWUmCIpwTZHZCu5l9THCuCcOhZqfekuQxjQ7EoyGUJAwCv/q1JOuJeCc/3lknb76zAquO/DAQhK/6\
                    154: 2cP8X2s3+IBLIhvL8RHopoHpIArJysYTTmMMeubPXh8W760AvMVH67jqgg06+/ne5MZ631z6yROhloh3dP\
                    155: QirZoEpr80wgt/cEbhbAQTmRLtGh8lxCwDBBb5OeJ4aEq25XBNMT2rzWedW2zIzj+CCDKlnlyJBzT81qBW\
                    156: p69h7vlb3TmEV+DNm2rqj1iT7BQuwVVsuPkwq1e5P8tgNjVbIlMzwXeM11kZqjx3KKFOJzc3CAyFVhi8fx\
                    157: VZ5FvhdAM5mM6kS6OgKu16MFglq3/b/QVIwdw7HUCyeW04JPjC5dO+GC9OfqfB4VX+wwuift+ths2Ss3i6\
                    158: nkOE+JFyD+wKFL+WMX6nwwDva0S1/O8Mlnida69Ph96fuFvCoRMvXnCfsLPPmC/hA5RnMNE4fDK0pVOQ4B\
                    159: HLaErzv/wD99ABmjNZk0AAAAABJRU5ErkJggg==");
                    160:        margin: 10px auto;
                    161:        font-family: Geneva,Arial,sans-serif;
                    162:        font-size: 12px;
1.2       as        163:        text-shadow: 1px 1px 1px #000;
1.7       as        164:        color: #808080;
1.1       as        165: }
                    166: div.tn {
                    167:        float: left;
                    168:        width: ${ARG_TNSIZE}px;
                    169:        height: ${ARG_TNSIZE}px;
                    170:        vertical-align:text-top;
                    171:        text-align: center;
                    172:        margin: 4px;
                    173: }
                    174: div.tn a {
                    175:        position: relative;
                    176:        display: inline-block;
                    177:        height: ${ARG_TNSIZE}px;
                    178: }
                    179: div.tn, div.big {
                    180:        background-color: black;
                    181:        border-width: 1px;
                    182:        border-style: solid;
                    183:        border-color: gray;
                    184:        box-shadow: 1px 1px 2px #000;
                    185:        padding: 1px;
1.4       as        186:        border-radius: 3px;
1.1       as        187: }
                    188: div.tn:hover {
                    189:        background-color: #222;
                    190: }
                    191: div.big {
                    192:        display: inline-block;
                    193:        width: ${ARG_BIGSIZE}px;
                    194: }
                    195: div.over {
                    196:        width: ${ARG_BIGSIZE}px;
                    197:        position: absolute;
                    198:        top: 30px;
                    199:        padding: 1px;
                    200: }
                    201: div.over a.left, div.over a.right {
                    202:        display: block;
1.2       as        203:        /* shell fuck of: missing CTLARI (shouldn't happen) - WTF?! */
                    204:        width: $(($ARG_BIGSIZE / 2))px;
1.1       as        205:        position: relative;
                    206:        top: 1px;
                    207:        left: 1px;
                    208:        background-repeat: no-repeat;
                    209: }
                    210: div.over a.left:hover {
                    211:        background-position: 5% center;
                    212:        background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAwC\
                    213: AYAAADtoXHnAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAh9JREFUeNrE2L1Lw0A\
                    214: UAHATSivSZii0ldpBnMU6SgYJpQUJDlk7dLV+LTqIiIv4B7kLolBKQRA6GLqUDMEhqKAlhUIR4125SHo0b\
                    215: XJ51x68pDSX+3G5I/dyguM4S/MuMfeHIAiQ7Yo+//+OocAYPm+jWEXxg8JC8erCgvt4AXrqgkkUJRRZ6jq\
                    216: G71EMRcAeil6wWq2uGYZx1ul0jjRNy5Jey6PauKcRJ5NIhklCoaE4QODNYDCwHVJ6vd5HIpE4xNdQxKOiM\
                    217: 0G3FIvFc4Imo6CBQV3XXwioje5jREOBkiQdE3SLFWUFFXJfaJQVLP2DIWdvFDA+9pYKiMKBAVFYMAAKD85\
                    218: A+YBTUH6gD8oXnIDyB31QviCFzgekUPxYVe4ghW7ixhRFueQKUmgZN9hut1s0aNv2V6FQOAUBqRvT+IAaX\
                    219: 6crWZb1hsqQJFfPkPnpJz6YpmnQlXK5XD6TycRIcrUDib7jQ71ev+v3+9/eSqlUKt1qtU4IvIFid2x9jDC\
                    220: muJE9PG6qql7jcaTHttvt6gh2J1MZYva6ees+d9jnjcQXnoDyh31WGb7wlPWUHzwjc+ADB8iR4OGA2SAsH\
                    221: CLvhYNDZvgwMMO3THSY8auNBS6xfrVFhZUoaGjYk+qA7DkEgmu12i1Bs1C7K1NhvLviecTLEOhEuFKpXDW\
                    222: bzcdGo/Egy/KFZzKJPHbMVsiEyVPXTRRPeMdMWMQuqLi0gPInwACOBcZx3lRFMwAAAABJRU5ErkJggg==");
                    223: }
                    224: div.over a.right:hover {
                    225:        background-position: 95% center;
                    226:        background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAwC\
                    227: AYAAADtoXHnAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAiJJREFUeNrE2D1Lw0A\
                    228: YAOAmlNbBdii0FVM6OEu7SgcJpRUJDlk7dE21uuggIi7iD/IX+AGlFAXBDqVLyVCCBBW0JFhwMN7JHRxnY\
                    229: 5PcnX3hhSM58nB3+Xhzkud5sf8OiWjLPn2+eGF4gHEChLkOcgUdt0E+isAlhCVAbiGQjGeQ1yBdHjAeKZ7\
                    230: SCgR1Xc8Nh8M90zQPG42GAo7lQFZBLhOzwSXgKI1kMrk7mUxePBTT6dQB8Dk8B1IHmUbTLrOMFI8WjsIol\
                    231: 8tHHhW8YRKV0QWNwWDwIBKm0RK8aDqdbouEaRReQBUNkygJV0XCNBojnldh8CxUOOyHCoX/QoXB81AhcBC\
                    232: UOxwU5QqHQbnBYVFWODLKDEdFo8IanGYWNBSsquoJgkus6C+4UCgcOI7zRsP9fv8OoTWM8qh57mHlaFnWp\
                    233: 23bFn1SUZQiambm1bphYgMWddlsNp7P51fpk+Px2ETNV1YUf383Qa5BsNfr7adSqQzZyXXd91ardUmUs8x\
                    234: rWYNrBcD2aDQa0GsJ11fTtDO0ntssd28UcAfXzSxvpLBg5DcSKyhH/cowgVG+p8xg2MqBCximRuIGBq0Gu\
                    235: YJB6l7u4LwKXwjo9y8jFPT7a6uKBGehqmiQRhO45BAJ0ijcQTGazeaFSJBGl/DUkrsrvMFZa/pzE1UqleN\
                    236: Op3PV7XZv6vX6KU+QRMkdM3gzFal+TyBvQX7w3DGTFrELKscWEN8CDADBm8pgcciwqgAAAABJRU5ErkJgg\
                    237: g=="); 
                    238: }
                    239: div.big a {
                    240:        position: relative;
                    241:        display: inline-block;
                    242:        width: ${ARG_BIGSIZE}px;
                    243: }
                    244: div.box {
                    245:        text-align: center;
                    246:        width: ${ARG_BIGSIZE}px;
                    247:        margin: auto;
                    248: }
1.7       as        249: div.box div.d {
                    250:        width: ${ARG_BIGSIZE}px;
                    251:        padding: 5px;
                    252:        text-align: center;
                    253: }
                    254: div.box div.i {
1.1       as        255:        width: ${ARG_BIGSIZE}px;
                    256:        font-size: 90%;
                    257:        height: 25px;
                    258:        line-height: 25px;
                    259:        position: relative;
                    260: }
                    261: body > div.c {
                    262:        text-align: center;
                    263:        font-size: 90%;
                    264:        height: 25px;
                    265:        line-height: 25px;
                    266:        position: relative;
                    267:        margin: 4px;
                    268: }
                    269: a img {
                    270:        border-width: 0;
                    271: }
                    272: a {
                    273: }
                    274: div.nav {
                    275:        width: ${ARG_BIGSIZE}px;
                    276:        height: 20px;
                    277: }
                    278: div.nav a {
                    279:        color: #FFF;
                    280:        text-decoration: none;
                    281: }
                    282: div.nav a:hover {
                    283:        text-decoration: underline;
                    284: }
                    285: div.nav div.top {
                    286:        position: absolute;
                    287:        text-align: center;
1.2       as        288:        width: $(($ARG_BIGSIZE - 100))px;
                    289:        margin: 0 50px;
1.1       as        290: }
                    291: .left {
                    292:        float: left;
                    293: }
                    294: .right {
                    295:        float: right;
                    296: }
                    297: .clear {
                    298:        clear: both;
                    299: }
                    300:                -->
                    301:                </style>
                    302:        </head>
                    303: <body>
                    304: HTML
                    305: }
                    306: 
                    307: #
                    308: # html_footer()
                    309: #
                    310: html_footer()
                    311: {
                    312:        cat <<HTML
                    313: </body></html>
                    314: HTML
                    315: }
                    316: 
                    317: #
                    318: # html_tn()
                    319: #
                    320: html_tn()
                    321: {
                    322:        tn=$1
                    323:        link=$2
                    324: 
                    325:        info=$($BIN_IMGINFO -f $tn)
                    326:        width=$(echo $info | awk '{print $3}')
                    327:        height=$(echo $info | awk '{print $4}')
                    328:        top=$(($(($ARG_TNSIZE - $height)) / 2))
                    329: 
                    330:        cat <<HTML
                    331: <div class="tn">
                    332:        <a href="$link" style="top:${top}px">
                    333:                <img alt="$tn" width="$width" height="$height" src="$tn" />
                    334:        </a>
                    335: </div>
                    336: HTML
                    337: }
                    338: 
                    339: #
                    340: # html_img()
                    341: #
                    342: html_img()
                    343: {
1.7       as        344:        orig=$1
1.12      as        345:        num=$2
                    346:        all=$3
                    347:        img=$4
                    348:        link=$5
                    349:        linkb=$6
                    350:        linkn=$7
1.1       as        351: 
1.3       as        352:        info=$($BIN_IMGINFO -f $img)
                    353:        width=$(echo $info | awk '{print $3}')
                    354:        height=$(echo $info | awk '{print $4}')
1.1       as        355: 
1.7       as        356:        desc=$(get_exif_desc $orig)
                    357:        if [ "$desc" != "" ]
                    358:        then
                    359:                desc="<div class='d'>$desc</div>"
                    360:        fi
                    361: 
1.1       as        362:        if [ "$linkb" != "" ]
                    363:        then
1.14      as        364:                hlinkb="<a href='$linkb'>prev</a>"
1.1       as        365:                olinkb="<a class='left' style='height:${height}px' href='$linkb'></a>"
                    366:        fi
                    367: 
                    368:        if [ "$linkn" != "" ]
                    369:        then
1.14      as        370:                hlinkn="<a href="$linkn">next</a>"
1.1       as        371:                olinkn="<a class='right' style='height:${height}px' href='$linkn'></a>"
                    372:        fi
                    373: 
                    374:        cat <<HTML
                    375: <div class="box">
                    376:        <div class="nav">
1.12      as        377:                <div class="top">
1.14      as        378:                        <a href="$link">index</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="$orig">original</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;$num/$all
1.12      as        379:                </div>
1.1       as        380:                <div class="left">$hlinkb</div>
                    381:                <div class="right">$hlinkn</div>
                    382:        </div>
                    383:        <div class="big">
1.3       as        384:                <img alt="$img" width="$width" height="$height" src="$img" />
1.1       as        385:        </div>
1.7       as        386:        $desc
                    387:        <div class="i">
                    388:                <div class="left">$(get_exif_info $orig)</div>
                    389:                <div class="right">$ARG_TITLE $ARG_COPYRIGHT</div>
1.1       as        390:        </div>
                    391:        <div class="over" style='height:${height}px'>
                    392:                $olinkb
                    393:                $olinkn
                    394:        </div>
                    395: </div>
                    396: HTML
                    397: }
                    398: 
                    399: #
                    400: # err
                    401: #
                    402: err()
                    403: {
                    404:        echo "$1" >&2
                    405:        exit 1
                    406: }
                    407: 
1.6       as        408: #
                    409: # mysendmail()
                    410: #
                    411: mysendmail()
                    412: {
                    413:        subject=$1
                    414:        (
                    415:                cat <<MAIL
                    416: From: $ARG_MAILFROM
                    417: To: $ARG_MAILTO
                    418: Subject: $subject
                    419: Content-Type: text/plain; charset=iso-8859-1
                    420: X-Mailer: $VERSION
                    421: 
                    422: $(cat)
                    423: MAIL
                    424:        ) | $BIN_SENDMAIL -t
                    425: }
1.1       as        426: 
1.7       as        427: #
                    428: # get_exif_desc()
                    429: #
                    430: get_exif_desc()
                    431: {
                    432:        img=$1
1.15      as        433:        $BIN_EXIF --ifd=0 --tag=0x010e -m $img 2> /dev/null | while read line
1.7       as        434:        do
                    435:                echo "$line<br />"
                    436:        done
                    437: }
                    438: 
                    439: #
1.12      as        440: # get_exif_ts()
                    441: #
                    442: get_exif_ts()
                    443: {
                    444:        img=$1
                    445:        date=$($BIN_EXIF --ifd=EXIF --tag=0x9003 -m $img 2> /dev/null)
1.13      as        446:        if [ "$date" = "" ]
                    447:        then
                    448:                echo "-1"
                    449:                return 1
                    450:        fi
1.12      as        451:        date -j -f "%Y:%m:%d %T" "$date" "+%s"
                    452: }
                    453: 
                    454: #
                    455: # get_exif_date()
                    456: #
                    457: get_exif_date()
                    458: {
                    459:        img=$1
                    460:        ts=$(get_exif_ts $img) && date -r $ts "+%d.%m.%Y %H:%M" || echo ""
                    461: }
                    462: 
                    463: #
1.7       as        464: # get_exif_value()
                    465: #
                    466: get_exif_value()
                    467: {
                    468:        img=$1
                    469:        hex=$2
                    470:        $BIN_EXIFTRAN -d $img | grep $hex | sed -E 's/^.{45}//'
                    471: }
                    472: 
                    473: #
                    474: # get_exif_info()
                    475: #
                    476: get_exif_info()
                    477: {
                    478:        img=$1
1.12      as        479: 
1.7       as        480:        exifinfo=
1.12      as        481:        created=$(get_exif_date $img) && exifinfo="$created / "
                    482: 
1.7       as        483:        for exif in $ARG_EXIF
                    484:        do
                    485:                if echo $exif | grep -q -E '0x[[:alnum:]]{4}'
                    486:                then
                    487:                        exifinfo="$exifinfo$(get_exif_value $img $exif) "
                    488:                else
                    489:                        exifinfo="$exifinfo$exif "
                    490:                fi
                    491:        done
1.12      as        492:        echo $exifinfo | sed -E -e 's/ mm /mm /' -e 's/ sec./s/' -e 's/ ISO / ISO/' -e 's/ ISO(\/| )/ \1/'
1.7       as        493: }
                    494: 
1.11      as        495: #
                    496: # is_in_list()
                    497: #
                    498: is_in_list()
                    499: {
                    500:        list=$1
                    501:        value=$2
                    502:        for entry in $list
                    503:        do
                    504:                test "$entry" = "$value" && return 0
                    505:        done
                    506:        return 1
                    507: }
                    508: 
1.1       as        509: # parse args
                    510: while [ "$1" != "" ]
                    511: do
                    512:        arg=$1
                    513:        shift
                    514:        case $arg in
                    515:                -h)
1.6       as        516:                        usage;;
1.1       as        517:                -n)
                    518:                        ARG_TITLE=$1
1.6       as        519:                        shift;;
1.1       as        520:                -t)
                    521:                        ARG_TNSIZE=$1
1.6       as        522:                        shift;;
1.1       as        523:                -u)
                    524:                        ARG_TNQALITY=$1
1.6       as        525:                        shift;;
1.1       as        526:                -b)
                    527:                        ARG_BIGSIZE=$1
1.6       as        528:                        shift;;
1.1       as        529:                -c)
                    530:                        ARG_BIGQALITY=$1
1.6       as        531:                        shift;;
1.1       as        532:                -f)
                    533:                        ARG_FILES=$1
1.6       as        534:                        shift;;
                    535:                -l)
                    536:                        ARG_URL=$1
                    537:                        shift;;
1.1       as        538:                -s)
                    539:                        ARG_FILETYPES=$1
1.6       as        540:                        shift;;
1.1       as        541:                -d)
                    542:                        ARG_DIR=$1
1.6       as        543:                        shift;;
1.7       as        544:                -e)
                    545:                        ARG_EXIF=$1
                    546:                        shift;;
1.1       as        547:                -C)
                    548:                        ARG_COPYRIGHT=$1
1.6       as        549:                        shift;;
                    550:                -F)
                    551:                        ARG_MAILFROM=$1
                    552:                        shift;;
1.5       as        553:                -I)
                    554:                        ARG_INFOFILE=$1
1.6       as        555:                        shift;;
                    556:                -T)
                    557:                        ARG_MAILTO=$1
                    558:                        shift;;
1.1       as        559:                -U)
1.6       as        560:                        ARG_UPDATE=0;;
1.1       as        561:                -v)
                    562:                        echo $VERSION
1.6       as        563:                        exit;;
1.1       as        564:                *)
                    565:                        echo "unknown argument $arg"
                    566:                        exit
                    567:        esac
                    568: done
                    569: 
1.14      as        570: # go to gallery directory
                    571: MY=$(get_my_path)
                    572: cd "$ARG_DIR" || exit 1
                    573: 
1.5       as        574: # parese info file
                    575: if [ "$ARG_INFOFILE" != "" ]
                    576: then
                    577:        test -f $ARG_INFOFILE || err "info file not found \`\`$ARG_INFOFILE''"
1.6       as        578:        for n in TITLE COPYRIGHT INDEX FILETYPES TNSIZE TNQALITY BIGSIZE \
1.7       as        579:                BIGQALITY MAILTO MAILFROM URL EXIF
1.5       as        580:        do
                    581:                v=$(make -f $ARG_INFOFILE -V$n)
                    582:                test "$v" = "" && continue
                    583:                eval "ARG_$n='$v'"
                    584:        done    
                    585: fi
                    586: 
1.15      as        587: # paras from iso to utf-8
                    588: for n in $(set | awk -F= '{print $1}')
                    589: do
                    590:        echo "$n" | grep -q '^ARG_' || continue
                    591:        eval "$n=\"\$(echo \"\$$n\" | iconv -f ISO-8859-1 -t UTF-8)\""
                    592: done
                    593: 
1.6       as        594: # fix url
                    595: if [ "$ARG_URL" != "" ]
                    596: then
                    597:        echo "$ARG_URL" | grep -q '/$' || ARG_URL="${ARG_URL}/"
                    598: fi
                    599: 
1.1       as        600: # if no images defined, find files
                    601: if [ "$ARG_FILES" = "" -a "$ARG_FILETYPES" != "" ]
                    602: then
                    603:        match=
                    604:        for type in $ARG_FILETYPES
                    605:        do
                    606:                match="$match *.$(echo $type | tr '[:lower:]' '[:upper:]')"
                    607:                match="$match *.$(echo $type | tr '[:upper:]' '[:lower:]')"
                    608:        done
                    609:        ARG_FILES=$(cd $ARG_DIR && ls $match 2>/dev/null)
                    610: fi
                    611: 
                    612: # Filter big and thumbnails
                    613: echo -n "find images"
                    614: FLIST=
                    615: for file in $ARG_FILES
                    616: do
                    617:        test $(echo $file | grep -E '\.(tn|big)\.jpg$') && continue
                    618:        FLIST="$FLIST $file"
                    619:        echo -n " $file"
                    620: done
                    621: echo 
                    622: 
                    623: test $(echo $FLIST | wc -w) -eq 0 && err "error: no image found in \`\`$ARG_DIR''"
                    624: 
1.13      as        625: # use exif createtime to order images
                    626: FLIST=$(
                    627:        (
                    628:                for file in $FLIST
                    629:                do
                    630:                        echo "$(get_exif_ts $file) $file"
                    631:                done
                    632:        ) | sort -n | awk '{print $2}'
                    633: )
                    634: 
1.5       as        635: # find new and to update images
                    636: FLIST_NEW=
                    637: FLIST_UPDATE=
                    638: echo "all: tns" > $MKAKEFILE
                    639: targets=""
                    640: for file in $FLIST
                    641: do
                    642:        tn="${file}.tn.jpg"
                    643:        if [ ! -f $tn ]
                    644:        then
                    645:                FLIST_NEW="$FLIST_NEW $file"
                    646:                continue
                    647:        fi
                    648: 
                    649:        targets="$targets $tn"
                    650:        (
                    651:                cat <<MAKE
                    652: $tn: $file
                    653:        @echo ${file}
                    654: MAKE
                    655:        ) >> $MKAKEFILE
                    656: done
                    657: echo "tns: $targets" >> $MKAKEFILE
                    658: FLIST_UPDATE=$(make -f $MKAKEFILE)
                    659: rm $MKAKEFILE
                    660: 
                    661: # update and no new and update images found
                    662: if [ $ARG_UPDATE -eq 1 -a "$FLIST_NEW" = "" -a "$FLIST_UPDATE" = "" ]
                    663: then
                    664:        echo nothing to do
                    665:        exit 1
                    666: fi
                    667: 
                    668: if [ $ARG_UPDATE -eq 1 ]
                    669: then
                    670:        echo new images: $FLIST_NEW
                    671:        echo update images: $FLIST_UPDATE
                    672: fi
                    673: 
1.1       as        674: # Create make file to rotate und convert all big and thumbnails.
                    675: # Is needed to define the new real image sizes.
                    676: echo "all: tns" > $MKAKEFILE
                    677: targets=""
                    678: for file in $FLIST
                    679: do
                    680:        tn="${file}.tn.jpg"
                    681:        big="${file}.big.jpg"
                    682:        targets="$targets $tn"
                    683: 
                    684:        target=
                    685:        if [ $ARG_UPDATE -eq 1 ]
                    686:        then
                    687:                target="$tn: $ME $file"
                    688:        else
                    689:                target="$tn::"
                    690:        fi
                    691: 
                    692:        (
1.5       as        693:                cat <<MAKE
1.1       as        694: $target
                    695:        $BIN_EXIFAUTOTRAN $file
                    696:        $BIN_CONVERT -verbose -thumbnail ${ARG_TNSIZE}x${ARG_TNSIZE} -quality $ARG_TNQALITY $file $tn
                    697:        $BIN_CONVERT -verbose -thumbnail ${ARG_BIGSIZE}x${ARG_BIGSIZE} -quality $ARG_BIGQALITY $file $big
                    698: MAKE
                    699:        ) >> $MKAKEFILE
                    700: done
                    701: echo "tns: $targets" >> $MKAKEFILE
                    702: 
1.16    ! as        703: make -f $MKAKEFILE
1.1       as        704: rm $MKAKEFILE
                    705: 
1.10      as        706: # create html index
                    707: index=""
                    708: for file in $FLIST
                    709: do
                    710:        tn="${file}.tn.jpg"
                    711:        imglink="${file}.html"
                    712:        index="$index $(html_tn $tn $imglink)"
                    713: done
                    714: echo create html index
                    715: (
                    716:        html_header
                    717:        echo $index
                    718:        echo "<div class='clear'></div>"
                    719:        echo "<div class='c'>$ARG_TITLE $ARG_COPYRIGHT</div>"
                    720:        html_footer
                    721: ) > $ARG_INDEX
                    722: 
1.1       as        723: # create single html files
1.11      as        724: #test $ARG_UPDATE -eq 1 && FLIST="$FLIST_NEW $FLIST_UPDATE"
1.1       as        725: i=0
1.12      as        726: all=$(echo $FLIST | wc -w)
1.1       as        727: echo -n "create single html files "
                    728: for file in $FLIST
                    729: do
                    730:        h=$i
                    731:        i=$(($i + 1))
                    732:        j=$(($i + 1))
                    733: 
1.11      as        734:        # is update mod and no new images founded
                    735:        if [ $ARG_UPDATE -eq 1 -a "$FLIST_NEW" = "" ]
                    736:        then
                    737:                is_in_list "$FLIST_UPDATE" "$file" || continue
                    738:        fi
                    739: 
1.1       as        740:        big="${file}.big.jpg"
                    741:        imglink="${file}.html"
                    742: 
                    743:        if [ $i -ne 1 ]
                    744:        then
                    745:                linkb=$(echo $FLIST | awk "{print \$$h}").html
                    746:        fi
                    747:        linkn=$(echo $FLIST | awk "{print \$$j}")
                    748:        test "$linkn" != "" && linkn="$linkn.html"
                    749: 
                    750:        echo -n .
                    751:        (
                    752:                html_header
1.12      as        753:                html_img $file $i $all $big $ARG_INDEX "$linkb" "$linkn"
1.1       as        754:                html_footer
                    755:        ) > $imglink
                    756: done
                    757: echo
                    758: 
1.15      as        759: # .htaccess
                    760: if [ -f .htaccess ]
                    761: then
                    762:        grep -q 'AddCharset UTF-8 .html' < .htaccess || echo "AddCharset UTF-8 .html" >> .htaccess
                    763: else
                    764:        echo "AddCharset UTF-8 .html" > .htaccess
                    765: fi
                    766: 
1.6       as        767: test "$ARG_MAILTO" = "" && exit 0
                    768: 
                    769: # send info mail
                    770: if [ "$FLIST_NEW" != "" -o "$FLIST_UPDATE" != "" ]
                    771: then
                    772:        echo "send mail to $ARG_MAILTO"
                    773:        (
                    774:                echo "Hallo,"
                    775:                echo
                    776:                echo -n "the gallery $ARG_TITLE has been updated"
                    777:                if [ "$ARG_URL" != "" ]
                    778:                then
                    779:                        echo ":"
                    780:                        echo $ARG_URL
                    781:                else
                    782:                        echo "."
                    783:                fi
                    784: 
                    785:                suffix=
                    786:                test "$ARG_URL" != "" && suffix=.html
                    787: 
                    788:                if [ "$FLIST_NEW" != "" ]
                    789:                then
                    790:                        echo
                    791:                        echo "add pictures:"
                    792:                        for file in $FLIST_NEW
                    793:                        do
                    794:                                echo "- ${ARG_URL}${file}${suffix}"
                    795:                        done
                    796:                fi
                    797: 
                    798:                if [ "$FLIST_UPDATE" != "" ]
                    799:                then
                    800:                        echo
                    801:                        echo "update pictures:"
                    802:                        for file in $FLIST_UPDATE
                    803:                        do
                    804:                                echo "- ${ARG_URL}${file}${suffix}"
                    805:                        done
                    806:                fi
                    807:        ) | mysendmail "PGallery Update: $ARG_TITLE"
                    808: fi