degal/exif.py
changeset 120 55cb7fc9c8fb
child 121 3bed35e79f41
equal deleted inserted replaced
119:e7855eefb4c7 120:55cb7fc9c8fb
       
     1 """
       
     2     The various Exif backends that we have
       
     3 """
       
     4 
       
     5 from __future__ import with_statement
       
     6 
       
     7 import utils
       
     8 
       
     9 class ExifHandler (object) :
       
    10     """
       
    11         Our generic interface for Exif data
       
    12     """
       
    13 
       
    14     def __init__ (self, file) :
       
    15         """
       
    16             Load Exif data from the given File.
       
    17         """
       
    18 
       
    19         self.file = file
       
    20     
       
    21     def image_tag (self, tag, default=None) :
       
    22         """
       
    23             Load and return the human-readable unicode-safe value for the given main image tag.
       
    24         """
       
    25 
       
    26         abstract
       
    27 
       
    28     def image_tags (self, tags) :
       
    29         """
       
    30             Load and return the given tags for the main image as a sequence of (tag, value) tuples , following the same
       
    31             rules as image_tag, except there should mainly be only one call to this function, encompassing all the
       
    32             relevant tags.
       
    33 
       
    34             The returned list should omit those values which were not found.
       
    35         """
       
    36     
       
    37         for tag in tags :
       
    38             # try and fetch value
       
    39             value = self.image_tag(tag)
       
    40 
       
    41             # filter out default not-found
       
    42             if value is not None :
       
    43                 yield tag, value
       
    44 
       
    45 try :
       
    46     import pyexiv2
       
    47 
       
    48 except ImportError :
       
    49     PyExiv2_Handler = None
       
    50 
       
    51 else :
       
    52     class PyExiv2_Handler (ExifHandler) :
       
    53         NAME = 'pyexiv2'
       
    54 
       
    55         def __init__ (self, file) :
       
    56             """
       
    57                 Load as pyexiv2.Image
       
    58             """
       
    59             
       
    60             # create
       
    61             self.image = pyexiv2.Image(file.path)
       
    62 
       
    63             # load
       
    64             self.image.readMetadata()
       
    65         
       
    66         def image_tag (self, tag, default=None) :
       
    67             try :
       
    68                 # XXX: this is wrong
       
    69                 return self.image.interpretedExifValue("Exif.Photo.%s" % tag)
       
    70             
       
    71             except (IndexError, KeyError) :
       
    72                 return default
       
    73     
       
    74 try :
       
    75     from lib import EXIF
       
    76 
       
    77 except ImportError :
       
    78     EXIF_Handler = None
       
    79 
       
    80 else :
       
    81     class EXIF_Handler (ExifHandler) :
       
    82         NAME = 'EXIFpy'
       
    83 
       
    84         def __init__ (self, file) :
       
    85             """
       
    86                 Load using EXIF.process_file
       
    87             """
       
    88             
       
    89             with file.open('rb') as fh :
       
    90                 self.tags = EXIF.process_file(fh)
       
    91         
       
    92         def image_tag (self, tag, default=None) :
       
    93             # XXX: this is wrong
       
    94             return self.tags.get('Image %s' % (tag, ), default)
       
    95 
       
    96 # ExifHandler implementations to use, in preference order
       
    97 EXIF_HANDLERS = [
       
    98     # reasonably fast, but requires the native library and extension module
       
    99     PyExiv2_Handler,
       
   100 
       
   101     # pure-python, but very, very slow
       
   102     EXIF_Handler,
       
   103 ]
       
   104 
       
   105 # default ExifHandler to use
       
   106 EXIF_HANDLER = utils.first(EXIF_HANDLERS)
       
   107 
       
   108 # ExifHandler implementations by name
       
   109 EXIF_HANDLERS_BY_NAME = dict((h.NAME, h) for h in EXIF_HANDLERS)
       
   110 
       
   111 def load (config, file) :
       
   112     """
       
   113         Load Exif data using the configured Exif handler, and return the instance.
       
   114 
       
   115         Returns None if there wasn't any Exif handler available for use.
       
   116     """
       
   117 
       
   118     if config.exif_handler :
       
   119         # explicit
       
   120         exif_handler = config.exif_handler
       
   121 
       
   122     elif config.exif_handler_name :
       
   123         # by name
       
   124         exif_handler = EXIF_HANDLERS_BY_NAME[config.exif_handler_name]
       
   125 
       
   126     else :
       
   127         # default
       
   128         exif_handler = EXIF_HANDLER
       
   129     
       
   130     if exif_handler :
       
   131         # found one, use it
       
   132         return exif_handler(file)
       
   133 
       
   134     else :
       
   135         # nothing :(
       
   136         return None
       
   137