Annotation of scripts/pgallery/src/pgallery.sh, revision 1.17
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.17 ! as 8: # $Paefchen: scripts/pgallery/src/pgallery.sh,v 1.16 2012/08/29 14:15:50 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="© $(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> | <a href="$orig">original</a> | $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.17 ! as 492: echo $exifinfo | sed -E -e 's/ mm /mm /' -e 's/ se(c|k)./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