Adding -1/--one-pageand --exclude options, and various tweaks

Wed, 24 Apr 2013 10:37:45 +0200

author
Andy Buckley <andy@insectnation.org>
date
Wed, 24 Apr 2013 10:37:45 +0200
changeset 24
02f21810d43d
parent 23
4e1d30c61d0e
child 25
fb778c6b6d4b

Adding -1/--one-pageand --exclude options, and various tweaks

emin file | annotate | diff | comparison | revisions
setup.py file | annotate | diff | comparison | revisions
     1.1 --- a/emin	Thu Apr 04 16:53:49 2013 +0200
     1.2 +++ b/emin	Wed Apr 24 10:37:45 2013 +0200
     1.3 @@ -5,20 +5,27 @@
     1.4  
     1.5  emin - a static web gallery builder
     1.6  
     1.7 -by Andy Buckley
     1.8 -http://www.insectnation.org
     1.9 +emin makes static Web pages for presenting lots of imagey things: photos, PDFs,
    1.10 +graphs with thumbnails as well as links to the image/doc file proper.
    1.11  
    1.12 -This is a weeny script for making static sets of Web pages for presenting lots
    1.13 -of imagey things: photos, PDFs, graphs...
    1.14 +It's primarily intended for making Web photo galleries for the sorts of people
    1.15 +who don't want to install some PHP monstrosity just to put their photos
    1.16 +online. On the assumption that most people will want to tweak their gallery's
    1.17 +appearance, the output is fully customisable using the Cheetah templating
    1.18 +engine.
    1.19  
    1.20 -As for the name, this is a program to make pretty crappy galleries, so it's
    1.21 +Supported image formats are JPEG, PNG, GIF, TIFF, PDF and EPS, with the latter
    1.22 +two being converted to PNG for Web display.  Image resizing, renaming and
    1.23 +thumbnailing is supported, as is building a zip file to download the whole
    1.24 +set. Large image sets can be split over several pages.
    1.25 +
    1.26 +As for the name, this is a program to make pretty simple galleries, so it's
    1.27  named after a pretty crappy artist. And, thankfully, e-m-i-n is not many
    1.28 -characters to type (and they're all close together on the Colemak keyboard
    1.29 -layout) --- trebles all round!
    1.30 +characters to type.
    1.31  
    1.32  TODO:
    1.33 - * Make Cheetah templating optional
    1.34 - * Try to import BeautifulSoup for validating/pretty-printing the output
    1.35 + * Make Cheetah templating optional, or use Genshi/Jinja/Mako?
    1.36 + * Try to validate the HTML output
    1.37   * Add all on one page option
    1.38   * Resize option
    1.39   * Rename option
    1.40 @@ -26,14 +33,17 @@
    1.41   * Auto-rotate by EXIF orientation
    1.42   * Copy Lightbox stuff into place
    1.43   * Allow complete rollback if any failure (or on demand?)
    1.44 +
    1.45 +Author: Andy Buckley, http://www.insectnation.org\
    1.46  """
    1.47  
    1.48 -__version__ = "0.3.3"
    1.49 +__author__ = "Andy Buckley <andy@insectnation.org>"
    1.50 +__version__ = "0.3.4"
    1.51  
    1.52  
    1.53  import logging
    1.54  from optparse import OptionParser, OptionGroup
    1.55 -parser = OptionParser(usage=__doc__, version="%prog " + __version__)
    1.56 +parser = OptionParser(usage=__doc__, version=__version__)
    1.57  parser.add_option("-t", "--title", dest="TITLE", default="",
    1.58                    help="title of this gallery")
    1.59  parser.add_option("--template", dest="TEMPLATE", default=None,
    1.60 @@ -43,15 +53,18 @@
    1.61  parser.add_option("--no-zipfile", action="store_false",
    1.62                    dest="WRITE_ZIPFILE", default=True,
    1.63                    help="disable writing out of a zipped archive of photos from this gallery")
    1.64 -## TODO: Add all on one page option
    1.65 -parser.add_option("-c", "--num-cols", dest="NUM_COLS", default=5, type=int,
    1.66 -                  help="max number of thumbnail columns on one page (default: 5)")
    1.67 -parser.add_option("-r", "--num-rows", dest="NUM_ROWS", default=6, type=int,
    1.68 -                  help="max number of thumbnail rows on one page (default: 6). Set < 1 for unlimited (i.e. all on one page)")
    1.69 +parser.add_option("-1", "--one-page", dest="ONE_PAGE", action="store_true", default=False,
    1.70 +                  help="put all thumbnails on one page (default: %default)")
    1.71 +parser.add_option("-c", "--num-cols", "--cols", dest="NUM_COLS", default=5, type=int,
    1.72 +                  help="max number of thumbnail columns on one page (default: %default)")
    1.73 +parser.add_option("-r", "--num-rows", "--rows", dest="NUM_ROWS", default=6, type=int,
    1.74 +                  help="max number of thumbnail rows on one page (default: %default). Set < 1 for unlimited (i.e. all on one page)")
    1.75  parser.add_option("--thumb-height", dest="THUMB_HEIGHT", default=150, type=int,
    1.76 -                  help="thumbnail height, in pixels (default: 100)")
    1.77 +                  help="thumbnail height, in pixels (default: %default)")
    1.78  parser.add_option("--max-imgsize", dest="MAX_IMGSIZE", default=800, type=int,
    1.79 -                  help="max large image dimension in pixels (default: 800)")
    1.80 +                  help="max large image dimension in pixels (default: %default)")
    1.81 +parser.add_option("--exclude", dest="EXCLUDE", default=None,
    1.82 +                  help="a regex pattern specifying image files to be excludes (default: %default)")
    1.83  parser.add_option("--no-js", dest="USE_JS", action="store_false", default=True,
    1.84                    help="disable use of funky JavaScript display stuff")
    1.85  parser.add_option("--force", dest="FORCE", action="store_true", default=False,
    1.86 @@ -68,19 +81,23 @@
    1.87  logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
    1.88  
    1.89  
    1.90 -## More stdlib imports
    1.91 -import sys, os, glob, re, commands, math, shutil
    1.92 -import traceback
    1.93 -
    1.94 -
    1.95 -## TODO: These should be options...
    1.96 -opts.RENAME = False
    1.97 -opts.CONVERT = False
    1.98 +## More imports
    1.99 +import sys, os, glob, re, math, shutil, fnmatch
   1.100 +try:
   1.101 +    from Cheetah.Template import Template
   1.102 +except Exception, e:
   1.103 +    logging.error("Couldn't import required Cheetah package")
   1.104 +    exit(1)
   1.105 +try:
   1.106 +    import PIL.Image as PILI
   1.107 +except Exception, e:
   1.108 +    logging.error("Couldn't import required Python Imaging Library package")
   1.109 +    exit(1)
   1.110  
   1.111  
   1.112  ## Set processing/output dir
   1.113  if len(args) < 1 or len(args) > 2:
   1.114 -    print parser.show_usage()
   1.115 +    parser.print_usage()
   1.116      exit(1)
   1.117  if len(args) >= 1:
   1.118      opts.SRCDIR = os.path.normpath(args[0])
   1.119 @@ -89,19 +106,12 @@
   1.120      opts.OUTDIR = os.path.normpath(args[1])
   1.121  
   1.122  
   1.123 -## Try to import Cheetah templating
   1.124 -try:
   1.125 -    from Cheetah.Template import Template
   1.126 -except Exception, e:
   1.127 -    logging.error("Couldn't import required Cheetah package")
   1.128 -    exit(1)
   1.129 -
   1.130 -## Try to import Python Imaging Library
   1.131 -try:
   1.132 -    import PIL.Image as PILI
   1.133 -except Exception, e:
   1.134 -    logging.error("Couldn't import required Python Imaging Library package")
   1.135 -    exit(1)
   1.136 +## Deal with consequences of interacting optional settings
   1.137 +if opts.ONE_PAGE:
   1.138 +    opts.NUM_ROWS = -1
   1.139 +# TODO: These should be options...
   1.140 +opts.RENAME = False
   1.141 +opts.CONVERT = False
   1.142  
   1.143  
   1.144  def safeencode(s):
   1.145 @@ -109,6 +119,7 @@
   1.146      newstr = s.replace(" ", "-").replace(",", "").replace("/", "").replace(".", "")
   1.147      return newstr
   1.148  
   1.149 +
   1.150  logging.debug("Title: %s" % opts.TITLE)
   1.151  logging.debug("Thumb height: %d" % opts.THUMB_HEIGHT)
   1.152  
   1.153 @@ -139,7 +150,6 @@
   1.154          os.makedirs(opts.OUTDIR)
   1.155      except Exception, e:
   1.156          logging.error("Problem when making output dir %s... exiting" % opts.OUTDIR)
   1.157 -        #traceback.print_exc()
   1.158          exit(1)
   1.159  
   1.160  
   1.161 @@ -152,26 +162,27 @@
   1.162          os.makedirs(THUMBDIR)
   1.163  except Exception, e:
   1.164      logging.error("Problem when making thumbnails dir... exiting")
   1.165 -    #traceback.print_exc()
   1.166      exit(1)
   1.167  
   1.168  
   1.169  ## Build the list of pictures to display
   1.170 -## TODO: types: PNG/GIF, JPEG, PDF
   1.171 -## TODO: match formats & store thumb filenames
   1.172 +# TODO: types: PNG/GIF, JPEG, PDF
   1.173 +# TODO: match formats & store thumb filenames
   1.174  EXTENSIONS = \
   1.175      ["*.jpg", "*.jpeg"] + \
   1.176      ["*.png", "*.gif"]  + \
   1.177      ["*.tif", "*.tiff"] + \
   1.178      ["*.eps", "*.pdf"]
   1.179  imgs = []
   1.180 -import fnmatch
   1.181  for img in os.listdir(opts.SRCDIR):
   1.182      for e in EXTENSIONS:
   1.183 -        if fnmatch.fnmatch(img.lower(), e):
   1.184 -            imgpath = os.path.join(opts.SRCDIR, img)
   1.185 -            imgs.append(imgpath)
   1.186 -            break
   1.187 +        if not fnmatch.fnmatch(img.lower(), e):
   1.188 +            continue
   1.189 +        if opts.EXCLUDE and re.search(opts.EXCLUDE, img):
   1.190 +            continue
   1.191 +        imgpath = os.path.join(opts.SRCDIR, img)
   1.192 +        imgs.append(imgpath)
   1.193 +        break
   1.194  
   1.195  ## Count the pictures
   1.196  logging.debug("Number of pictures = %d" % len(imgs))
   1.197 @@ -231,6 +242,7 @@
   1.198      ## Do the conversion
   1.199      if convcmd:
   1.200          try:
   1.201 +            # TODO: threading / multiprocessing for speed-up?
   1.202              import subprocess
   1.203              subprocess.check_call(convcmd)
   1.204          except:
   1.205 @@ -261,7 +273,6 @@
   1.206          info.thumbsize = thumbimg.size
   1.207      except Exception, e:
   1.208          logging.warning("Problem when making thumbnail from %s... exiting" % picpath)
   1.209 -        #traceback.print_exc()
   1.210          exit(1)
   1.211  
   1.212      ## Store info
   1.213 @@ -272,9 +283,16 @@
   1.214  
   1.215  
   1.216  ## Calculate how many pages will be needed
   1.217 -## TODO: allow all on one page
   1.218 -NUM_PER_PAGE = opts.NUM_ROWS * opts.NUM_COLS
   1.219 -NUM_PAGES = int(math.ceil( len(imgs)/float(NUM_PER_PAGE) ))
   1.220 +if opts.NUM_ROWS >= 1:
   1.221 +    NUM_PER_PAGE = opts.NUM_ROWS * opts.NUM_COLS
   1.222 +    NUM_PAGES = int(math.ceil( len(imgs)/float(NUM_PER_PAGE) ))
   1.223 +else:
   1.224 +    NUM_PER_PAGE = len(imgs)
   1.225 +    NUM_PAGES = 1
   1.226 +
   1.227 +
   1.228 +if NUM_PAGES > 1:
   1.229 +    logging.warn("%d gallery pages will be made. If you just want one page, use the -1 or --one-page option")
   1.230  
   1.231  
   1.232  ## TODO: Move HTML extension-setting to option parser
   1.233 @@ -341,7 +359,7 @@
   1.234          logging.warning("No zip file made because zip filename is empty")
   1.235  
   1.236  
   1.237 -## Copy Lightbox stuff into place
   1.238 +## Copy Lightbox stuff into ZIP
   1.239  #if opts.USE_JS:
   1.240  #    from zipfile import ZipFile
   1.241  #    zf = ZipFile(os.path.join(opts.OUTDIR, "lightbox.zip"), "r")
   1.242 @@ -352,7 +370,7 @@
   1.243  
   1.244  ## Default template
   1.245  tmplstr = \
   1.246 -"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   1.247 +'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   1.248          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
   1.249  <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
   1.250    <head>
   1.251 @@ -416,7 +434,7 @@
   1.252      #end if
   1.253    </body>
   1.254  </html>
   1.255 -"""
   1.256 +'''
   1.257  
   1.258  
   1.259  ## Override default template with a template file
   1.260 @@ -468,7 +486,6 @@
   1.261      tdict = {}
   1.262      tdict["NUM_PAGES"] = NUM_PAGES
   1.263      tdict["NUM_PER_PAGE"] = NUM_PER_PAGE
   1.264 -    tdict["NUM_ROWS"] = opts.NUM_ROWS
   1.265      tdict["NUM_COLS"] = opts.NUM_COLS
   1.266      tdict["PAGEPICS"] = PAGEPICS
   1.267      tdict["PAGENUM"] = PAGENUM
     2.1 --- a/setup.py	Thu Apr 04 16:53:49 2013 +0200
     2.2 +++ b/setup.py	Wed Apr 24 10:37:45 2013 +0200
     2.3 @@ -1,28 +1,43 @@
     2.4  #! /usr/bin/env python
     2.5  
     2.6  """\
     2.7 -emin is a script used to make static HTML-based galleries of
     2.8 -photos, PDFs, diagrams... anything, really. It's primarily
     2.9 -intended for making Web photo galleries for the sorts of
    2.10 -people who don't want to install some PHP monstrosity just
    2.11 -to put their photos online. On the assumption that most people
    2.12 -will want to tweak their gallery's appearance, the output is
    2.13 -fully customisable using the Cheetah templating engine.
    2.14 +emin makes static Web pages for presenting lots of imagey things: photos, PDFs,
    2.15 +graphs with thumbnails as well as links to the image/doc file proper.
    2.16  
    2.17 -Supported image formats are JPEG, PNG, GIF, TIFF, PDF and EPS,
    2.18 -with the latter two being converted to PNG for Web display.
    2.19 -Image resizing, renaming and thumbnailing is supported, as is
    2.20 -building a zip file to download the whole set. Large image sets
    2.21 -can be split over several pages.
    2.22 +It's primarily intended for making Web photo galleries for the sorts of people
    2.23 +who don't want to install some PHP monstrosity just to put their photos
    2.24 +online. On the assumption that most people will want to tweak their gallery's
    2.25 +appearance, the output is fully customisable using the Cheetah templating
    2.26 +engine.
    2.27 +
    2.28 +Supported image formats are JPEG, PNG, GIF, TIFF, PDF and EPS, with the latter
    2.29 +two being converted to PNG for Web display.  Image resizing, renaming and
    2.30 +thumbnailing is supported, as is building a zip file to download the whole
    2.31 +set. Large image sets can be split over several pages.
    2.32  """
    2.33  
    2.34  ## Get setuptools stuff
    2.35  from distutils.core import setup
    2.36  
    2.37  
    2.38 +## Try to import Cheetah templating
    2.39 +try:
    2.40 +    from Cheetah.Template import Template
    2.41 +except Exception, e:
    2.42 +    logging.error("Couldn't import required Cheetah package: please install Cheetah first")
    2.43 +    exit(1)
    2.44 +
    2.45 +## Try to import Python Imaging Library
    2.46 +try:
    2.47 +    import PIL.Image
    2.48 +except Exception, e:
    2.49 +    logging.error("Couldn't import required Python Imaging Library package: please install PIL first")
    2.50 +    exit(1)
    2.51 +
    2.52 +
    2.53  ## Setup definition
    2.54  setup(name = 'emin',
    2.55 -      version = "0.3.3",
    2.56 +      version = "0.3.4",
    2.57        scripts = ['emin'],
    2.58        requires = ["Cheetah", "PIL"],
    2.59        author = 'Andy Buckley',

mercurial