PageRenderTime 20ms CodeModel.GetById 6ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 0ms

/gdata/exif/__init__.py

http://radioappz.googlecode.com/
Python | 217 lines | 166 code | 7 blank | 44 comment | 2 complexity | b1f9439f014126422f0ff32b34fa592d MD5 | raw file
  1# -*-*- encoding: utf-8 -*-*-
  2#
  3# This is gdata.photos.exif, implementing the exif namespace in gdata
  4#
  5# $Id: __init__.py 81 2007-10-03 14:41:42Z havard.gulldahl $
  6#
  7# Copyright 2007 H?vard Gulldahl 
  8# Portions copyright 2007 Google Inc.
  9#
 10# Licensed under the Apache License, Version 2.0 (the "License");
 11# you may not use this file except in compliance with the License.
 12# You may obtain a copy of the License at
 13#
 14#      http://www.apache.org/licenses/LICENSE-2.0
 15#
 16# Unless required by applicable law or agreed to in writing, software
 17# distributed under the License is distributed on an "AS IS" BASIS,
 18# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 19# See the License for the specific language governing permissions and
 20# limitations under the License.
 21
 22"""This module maps elements from the {EXIF} namespace[1] to GData objects. 
 23These elements describe image data, using exif attributes[2].
 24
 25Picasa Web Albums uses the exif namespace to represent Exif data encoded 
 26in a photo [3].
 27
 28Picasa Web Albums uses the following exif elements:
 29exif:distance
 30exif:exposure
 31exif:flash
 32exif:focallength
 33exif:fstop
 34exif:imageUniqueID
 35exif:iso
 36exif:make
 37exif:model
 38exif:tags
 39exif:time
 40
 41[1]: http://schemas.google.com/photos/exif/2007. 
 42[2]: http://en.wikipedia.org/wiki/Exif
 43[3]: http://code.google.com/apis/picasaweb/reference.html#exif_reference
 44"""
 45
 46
 47__author__ = u'havard@gulldahl.no'# (H?vard Gulldahl)' #BUG: pydoc chokes on non-ascii chars in __author__
 48__license__ = 'Apache License v2'
 49
 50
 51import atom
 52import gdata
 53
 54EXIF_NAMESPACE = 'http://schemas.google.com/photos/exif/2007'
 55
 56class ExifBaseElement(atom.AtomBase):
 57  """Base class for elements in the EXIF_NAMESPACE (%s). To add new elements, you only need to add the element tag name to self._tag
 58  """ % EXIF_NAMESPACE
 59  
 60  _tag = ''
 61  _namespace = EXIF_NAMESPACE
 62  _children = atom.AtomBase._children.copy()
 63  _attributes = atom.AtomBase._attributes.copy()
 64
 65  def __init__(self, name=None, extension_elements=None,
 66      extension_attributes=None, text=None):
 67    self.name = name
 68    self.text = text
 69    self.extension_elements = extension_elements or []
 70    self.extension_attributes = extension_attributes or {}
 71
 72class Distance(ExifBaseElement):
 73  "(float) The distance to the subject, e.g. 0.0"
 74  
 75  _tag = 'distance'
 76def DistanceFromString(xml_string):
 77  return atom.CreateClassFromXMLString(Distance, xml_string)
 78  
 79class Exposure(ExifBaseElement):
 80  "(float) The exposure time used, e.g. 0.025 or 8.0E4"
 81  
 82  _tag = 'exposure'
 83def ExposureFromString(xml_string):
 84  return atom.CreateClassFromXMLString(Exposure, xml_string)
 85  
 86class Flash(ExifBaseElement):
 87  """(string) Boolean value indicating whether the flash was used.
 88  The .text attribute will either be `true' or `false'
 89
 90  As a convenience, this object's .bool method will return what you want,
 91  so you can say:
 92
 93  flash_used = bool(Flash)
 94
 95  """
 96  
 97  _tag = 'flash'
 98  def __bool__(self):
 99    if self.text.lower() in ('true','false'):
100      return self.text.lower() == 'true'
101def FlashFromString(xml_string):
102  return atom.CreateClassFromXMLString(Flash, xml_string)
103  
104class Focallength(ExifBaseElement):
105  "(float) The focal length used, e.g. 23.7"
106  
107  _tag = 'focallength'
108def FocallengthFromString(xml_string):
109  return atom.CreateClassFromXMLString(Focallength, xml_string)
110  
111class Fstop(ExifBaseElement):
112  "(float) The fstop value used, e.g. 5.0"
113  
114  _tag = 'fstop'
115def FstopFromString(xml_string):
116  return atom.CreateClassFromXMLString(Fstop, xml_string)
117  
118class ImageUniqueID(ExifBaseElement):
119  "(string) The unique image ID for the photo. Generated by Google Photo servers"
120  
121  _tag = 'imageUniqueID'
122def ImageUniqueIDFromString(xml_string):
123  return atom.CreateClassFromXMLString(ImageUniqueID, xml_string)
124  
125class Iso(ExifBaseElement):
126  "(int) The iso equivalent value used, e.g. 200"
127  
128  _tag = 'iso'
129def IsoFromString(xml_string):
130  return atom.CreateClassFromXMLString(Iso, xml_string)
131  
132class Make(ExifBaseElement):
133  "(string) The make of the camera used, e.g. Fictitious Camera Company"
134  
135  _tag = 'make'
136def MakeFromString(xml_string):
137  return atom.CreateClassFromXMLString(Make, xml_string)
138  
139class Model(ExifBaseElement):
140  "(string) The model of the camera used,e.g AMAZING-100D"
141  
142  _tag = 'model'
143def ModelFromString(xml_string):
144  return atom.CreateClassFromXMLString(Model, xml_string)
145  
146class Time(ExifBaseElement):
147  """(int) The date/time the photo was taken, e.g. 1180294337000.
148  Represented as the number of milliseconds since January 1st, 1970.
149  
150  The value of this element will always be identical to the value
151  of the <gphoto:timestamp>.
152
153  Look at this object's .isoformat() for a human friendly datetime string:
154
155  photo_epoch = Time.text # 1180294337000
156  photo_isostring = Time.isoformat() # '2007-05-27T19:32:17.000Z'
157
158  Alternatively: 
159  photo_datetime = Time.datetime() # (requires python >= 2.3)
160  """
161  
162  _tag = 'time'
163  def isoformat(self):
164    """(string) Return the timestamp as a ISO 8601 formatted string,
165    e.g. '2007-05-27T19:32:17.000Z'
166    """
167    import time
168    epoch = float(self.text)/1000
169    return time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime(epoch))
170  
171  def datetime(self):
172    """(datetime.datetime) Return the timestamp as a datetime.datetime object
173
174    Requires python 2.3
175    """
176    import datetime
177    epoch = float(self.text)/1000
178    return datetime.datetime.fromtimestamp(epoch)
179  
180def TimeFromString(xml_string):
181  return atom.CreateClassFromXMLString(Time, xml_string)
182  
183class Tags(ExifBaseElement):
184  """The container for all exif elements.
185  The <exif:tags> element can appear as a child of a photo entry.
186  """
187  
188  _tag = 'tags'
189  _children = atom.AtomBase._children.copy()
190  _children['{%s}fstop' % EXIF_NAMESPACE] = ('fstop', Fstop) 
191  _children['{%s}make' % EXIF_NAMESPACE] = ('make', Make) 
192  _children['{%s}model' % EXIF_NAMESPACE] = ('model', Model) 
193  _children['{%s}distance' % EXIF_NAMESPACE] = ('distance', Distance) 
194  _children['{%s}exposure' % EXIF_NAMESPACE] = ('exposure', Exposure) 
195  _children['{%s}flash' % EXIF_NAMESPACE] = ('flash', Flash) 
196  _children['{%s}focallength' % EXIF_NAMESPACE] = ('focallength', Focallength) 
197  _children['{%s}iso' % EXIF_NAMESPACE] = ('iso', Iso) 
198  _children['{%s}time' % EXIF_NAMESPACE] = ('time', Time) 
199  _children['{%s}imageUniqueID' % EXIF_NAMESPACE] = ('imageUniqueID', ImageUniqueID) 
200
201  def __init__(self, extension_elements=None, extension_attributes=None, text=None):
202    ExifBaseElement.__init__(self, extension_elements=extension_elements,
203                            extension_attributes=extension_attributes,
204                            text=text)
205    self.fstop=None
206    self.make=None
207    self.model=None
208    self.distance=None
209    self.exposure=None
210    self.flash=None
211    self.focallength=None
212    self.iso=None
213    self.time=None
214    self.imageUniqueID=None
215def TagsFromString(xml_string):
216  return atom.CreateClassFromXMLString(Tags, xml_string)
217