gallery.py: Use Python-3-compatible exception syntax
[blog.git] / posts / gallery / gallery.py
index cac2ea6c49231cf99987fe7621ec91ea397ebf6c..1a3c958753c0093460e7e561c67c59227cfc88d5 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (C) 2010-2012 W. Trevor King <wking@drexel.edu>
+# Copyright (C) 2010-2013 W. Trevor King <wking@tremily.us>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -12,9 +12,8 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
 CGI gallery server for a picture directory organized along::
@@ -52,6 +51,8 @@ import os.path as _os_path
 import random as _random
 import re as _re
 import subprocess as _subprocess
+import urlparse as _urlparse
+import xml.sax.saxutils as _xml_sax_saxutils
 
 
 __version__ = '0.5'
@@ -113,7 +114,7 @@ def invoke(args, stdin=None, stdout=_subprocess.PIPE, stderr=_subprocess.PIPE,
     try :
         q = _subprocess.Popen(args, stdin=_subprocess.PIPE, stdout=stdout,
                               stderr=stderr, cwd=cwd)
-    except OSError, e:
+    except OSError as e:
         raise CommandError(args, status=e.args[0], stderr=e)
     stdout,stderr = q.communicate(input=stdin)
     status = q.wait()
@@ -238,6 +239,25 @@ class CGIGalleryServer (object):
         except ProcessingComplete:
             pass
 
+    def page_from_query(self, query=None, query_string=None):
+        """Extract the requested page from a query string
+
+        This is a helper method for CGIGalleryServer consumers.
+        Specify either query or query_string, but not both.
+        """
+        if query is None:
+            query = _urlparse.parse_qs(query_string)
+        page = 0
+        if 'pp' in query:
+            pp = query['pp']
+            if isinstance(pp, list):
+                pp = pp[0]
+            try:
+                page = int(pp) - 1
+            except ValueError:
+                pass
+        return page
+
     def relative_url(self, url):
         if url is None:
             return url
@@ -426,6 +446,7 @@ class CGIGalleryServer (object):
         else:
             content.append(img)
         if caption:
+            caption = _xml_sax_saxutils.escape(caption)
             content.append('<p>{}</p>'.format(caption))
         return content
 
@@ -461,7 +482,19 @@ class CGIGalleryServer (object):
     def _image(self, image, **kwargs):
         if kwargs:
             image_path,image_url = self._thumb(image, **kwargs)
-        return '<img src="{}" />'.format(image_url)
+        else:
+            image_url = image
+        sections = ['<img src="{}"'.format(image_url)]
+        caption = self._get_image_caption(path=image)
+        if caption:
+            caption = _xml_sax_saxutils.quoteattr(
+                caption.replace('\n', ' ').strip())
+            sections.extend([
+                    'title={}'.format(caption),
+                    'alt={}'.format(caption),
+                    ])
+        sections.append('/>')
+        return ' '.join(sections)
 
     def _image_page(self, image):
         return image_base(image) + '/'
@@ -670,47 +703,34 @@ def serve_cgi(server):
     import sys
 
     url=None
-    page=0
     cgitb.enable()
     #cgitb.enable(display=0, logdir="/tmp/")
     data = cgi.FieldStorage()
+    page = server.page_from_query(
+        query={key: data[key].getlist() for key in data.keys()})
     if 'p' in data:
         p = data['p']
         if isinstance(p, list):
             p = p[0]
         url = p.value
-    if 'pp' in data:
-        try:
-            page = int(data['pp'].value) - 1
-        except ValueError:
-            pass
     server.serve(url=url, page=page, stream=sys.stdout)
 
 def serve_scgi(server, host='localhost', port=4000):
     import scgi
     import scgi.scgi_server
-    import urlparse
 
     class GalleryHandler(scgi.scgi_server.SCGIHandler):
         def produce(self, env, bodysize, input, output):
             #LOG.info(HTTP_USER_AGENT REQUEST_METHOD REMOTE_ADDR REQUEST_URI
             url = env.get('DOCUMENT_URI', None)
-            page = 0
-            data = urlparse.parse_qs(env.get('QUERY_STRING', ''))
-            if 'pp' in data:
-                pp = data['pp']
-                if isinstance(pp, list):
-                    pp = pp[0]
-                try:
-                    page = int(pp) - 1
-                except ValueError:
-                    pass
+            page = server.page_from_query(
+                query_string=env.get('QUERY_STRING', ''))
             try:
                 try:
                     url = server.relative_url(url=url)
                 except HTTPError as e:
                     LOG.error(e.message)
-                    server._error(e.status, content=e.content, stream=stream)
+                    server._error(e.status, content=e.content, stream=output)
             except ProcessingComplete:
                 pass
             else: