Example #1
0
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
Example #2
0
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
Example #3
0
 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))
Example #4
0
 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))
Example #5
0
 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))
Example #6
0
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))