# -*- coding: utf-8 -*- """ Misc utilities. """ from fractions import Fraction try: StringCls = basestring except NameError: StringCls = str def ord_(dta): if isinstance(dta, str): return ord(dta) return dta def make_string(seq): """ Don't throw an exception when given an out of range character. """ string = '' for char in seq: # Screen out non-printing characters try: if 32 <= char < 256: string += chr(char) except TypeError: pass # If no printing chars if not string: return str(seq) return string def make_string_uc(seq): """ Special version to deal with the code in the first 8 bytes of a user comment. First 8 bytes gives coding system e.g. ASCII vs. JIS vs Unicode. """ if not isinstance(seq, StringCls): seq = seq[8:] # Of course, this is only correct if ASCII, and the standard explicitly # allows JIS and Unicode. return make_string(seq) def get_gps_coords(tags): lng_ref_tag_name = 'GPS GPSLongitudeRef' lng_tag_name = 'GPS GPSLongitude' lat_ref_tag_name = 'GPS GPSLatitudeRef' lat_tag_name = 'GPS GPSLatitude' # Check if these tags are present gps_tags = [lng_ref_tag_name, lng_tag_name, lat_tag_name, lat_tag_name] for tag in gps_tags: if not tag in tags.keys(): return None lng_ref_val = tags[lng_ref_tag_name].values lng_coord_val = [c.decimal() for c in tags[lng_tag_name].values] lat_ref_val = tags[lat_ref_tag_name].values lat_coord_val = [c.decimal() for c in tags[lat_tag_name].values] lng_coord = sum([c/60**i for i, c in enumerate(lng_coord_val)]) lng_coord *= (-1) ** (lng_ref_val == 'W') lat_coord = sum([c/60**i for i, c in enumerate(lat_coord_val)]) lat_coord *= (-1) ** (lat_ref_val == 'S') return (lat_coord, lng_coord) class Ratio(Fraction): """ Ratio object that eventually will be able to reduce itself to lowest common denominator for printing. """ # We're immutable, so use __new__ not __init__ def __new__(cls, numerator=0, denominator=None): try: self = super(Ratio, cls).__new__(cls, numerator, denominator) except ZeroDivisionError: self = super(Ratio, cls).__new__(cls) self._numerator = numerator self._denominator = denominator return self __new__.doc = Fraction.__new__.__doc__ def __repr__(self): return str(self) @property def num(self): return self.numerator @property def den(self): return self.denominator def decimal(self): return float(self)