def ts_get_manifest(ts_path): """Reads in or makes up a manifest for the timestream at ``ts_path``, and returns it as a ``dict`` """ manifest = _ts_has_manifest(ts_path) if manifest: try: LOG.debug("Manifest for {} exists at {}".format(ts_path, manifest)) with open(manifest) as ifh: manifest = json.load(ifh) if isinstance(manifest, list): # it comes in as a list, we want a dict manifest = dict_unicode_to_str(manifest[0]) else: manifest = dict_unicode_to_str(manifest) manifest = validate_timestream_manifest(manifest) except (IOError, OSError, ValueError, MultipleInvalid): # We can't read manifest or it's invalid manifest = None if not manifest: LOG.debug("Manifest for {} doesn't exist (yet)".format(ts_path)) manifest = ts_guess_manifest(ts_path) manifest = validate_timestream_manifest(manifest) LOG.debug("Manifest for {} is {!r}".format(ts_path, manifest)) return manifest
def get_exif_tags(image, mode="silent"): """Get a dictionary of exif tags from image exif header :param str image: Path to image file. :param str mode: Behaviour on missing exif tag. If `"silent"`, `None` is returned. If `"raise"`, a `KeyError` is raised. :returns: dict -- The EXIF tag dictionary, or None :raises: ValueError """ if mode not in {"silent", "raise"}: raise ValueError("Bad get_exif_tags mode '{}'".format(mode)) with open(image, "rb") as fh: tags = er.process_file(fh, details=False) tags = dict_unicode_to_str(tags) # remove the first bit off the tags exif = {} for k, v in tags.items(): # Remove the EXIF/Image category from the keys k = " ".join(k.split(" ")[1:]) # weird exif tags in CR2s start with a 2/3, or have hex in them if k[0] in digits or "0x" in k: continue v = str(v) exif[k] = v return exif
def test_ucode2str_already_strs(self): """Test timestream.util.dict_unicode_to_str with non-unicode dict.""" res = dict_unicode_to_str(self.str_dict) self.assertDictEqual(res, self.str_dict) res_item = res.popitem() self.assertTrue(isinstance(res_item[0], str)) self.assertTrue(isinstance(res_item[1], str))
def test_jsonify_primitive_types(self): """Test jsonify_data with primitive data types only""" dct = {"a": 1, "b": "2", "1": True, "31": None, } res = jsonify_data(dct) self.assertEqual(res, json.dumps(dct)) back = dejsonify_data(res) self.assertDictEqual(dct, dict_unicode_to_str(back))
def test_ucode2str_nested(self): """Test timestream.util.dict_unicode_to_str with nested dict.""" res = dict_unicode_to_str(self.nested_dict) self.assertDictEqual(res, self.str_nested_dict) # check the list is still a list, and it's values have been converted res_item = res["list"] self.assertTrue(isinstance(res_item, list)) self.assertTrue(isinstance(res_item[0], str)) self.assertTrue(isinstance(res_item[1], str)) # Ditto, but with a tuple res_item = res["tuple"] self.assertTrue(isinstance(res_item, tuple)) self.assertTrue(isinstance(res_item[0], str)) self.assertTrue(isinstance(res_item[1], str)) # check the dict has been recusively processed res_item = res["dict"] self.assertTrue(isinstance(res_item, dict)) res_item = res_item.popitem() self.assertTrue(isinstance(res_item[0], str)) self.assertTrue(isinstance(res_item[1], str))
def get_exif_tags(image, mode="silent"): """Get a dictionary of exif tags from image exif header :param str image: Path to image file. :param str mode: Behaviour on missing exif tag. If `"silent"`, `None` is returned. If `"raise"`, a `KeyError` is raised. :returns: dict -- The EXIF tag dictionary, or None :raises: ValueError """ if mode not in {"silent", "raise"}: raise ValueError("Bad get_exif_tags mode '{}'".format(mode)) if library == "wand": # use the wand library, as either we've been told to or the faster # exifread isn't available from wand.image import Image with Image(filename=image) as img: exif = {k[5:]: v for k, v in img.metadata.items() if k.startswith("exif:")} elif library == "exifread": try: er.__doc__ except NameError: import exifread as er with open(image, "rb") as fh: tags = er.process_file(fh, details=False) tags = dict_unicode_to_str(tags) # remove the first bit off the tags exif = {} for k, v in tags.items(): # Remove the EXIF/Image category from the keys k = " ".join(k.split(" ")[1:]) # weird exif tags in CR2s start with a 2/3, or have hex in them if k[0] in digits or "0x" in k: continue v = str(v) exif[k] = v else: raise ValueError("Library '{}' not supported (only wand and exifread are".format(library)) return exif
def setUp(self): with open(helpers.FILES["basic_jpg_exif"]) as fh: self.exif_data_jpg = dict_unicode_to_str(json.load(fh)) with open(helpers.FILES["basic_tiff_exif"]) as fh: self.exif_data_tiff = dict_unicode_to_str(json.load(fh))