def test_write_new_struct_in_array(self):
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")

        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        prefix = xmp.get_prefix_for_namespace(NS_DC)

        xmp.append_array_item(NS_DC, prefix + 'creator', None, prop_value_is_struct=True)
        xmp.set_property(NS_DC, prefix + 'creator[2]/' + prefix + 'TestProp', '100')
        self.assertTrue(xmp.does_property_exist(NS_DC, prefix + 'creator[2]'))
        prop = xmp.get_property(NS_DC, prefix + 'creator[2]/%sTestProp' % prefix)
        self.assertEqual(prop, '100')

        xpath = prefix + 'creator'
        xmp.set_array_item(NS_DC, xpath, 3, None, prop_value_is_struct=True)
        xpath += '[3]/%sTestProp' % prefix
        xmp.set_property(NS_DC, xpath, '200')
        self.assertTrue(xmp.does_property_exist(NS_DC, xpath))
        prop = xmp.get_property(NS_DC, xpath)
        self.assertEqual(prop, '200')

        xpath = prefix + 'TestStruct/' + prefix + 'TestValue'
        xmp.set_property(NS_DC, xpath, '300')
        self.assertTrue(xmp.does_property_exist(NS_DC, xpath))
        prop = xmp.get_property(NS_DC, xpath)
        self.assertEqual(prop, '300')
    def test_count_array_items(self):
        """Tests XMPMeta method count_array_items."""
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")
        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        xmp.set_array_item(NS_DC, "creator", 2, "foo")
        xmp.append_array_item(NS_DC, "creator", "bar")
        xmp.append_array_item(NS_DC, "creator", "donuts")
        self.assertEqual(xmp.count_array_items(NS_DC, "creator"), 4)
Beispiel #3
0
    def test_count_array_items(self):
        """Tests XMPMeta method count_array_items."""
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")
        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        xmp.set_array_item(NS_DC, "creator", 2, "foo")
        xmp.append_array_item(NS_DC, "creator", "bar")
        xmp.append_array_item(NS_DC, "creator", "donuts")
        self.assertEqual(xmp.count_array_items(NS_DC, "creator"), 4)
    def test_does_array_item_exist(self):
        """Tests XMPMeta method does_array_item_exist.  Issue #03"""
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")
        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        xmp.set_array_item(NS_DC, "creator", 2, "foo")
        xmp.append_array_item(NS_DC, "creator", "bar")

        self.assertTrue(xmp.does_array_item_exist(NS_DC, "creator", "foo"))
        self.assertFalse(xmp.does_array_item_exist(NS_DC, "creator", "blah"))
Beispiel #5
0
    def test_does_array_item_exist(self):
        """Tests XMPMeta method does_array_item_exist.  Issue #03"""
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")
        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        xmp.set_array_item(NS_DC, "creator", 2, "foo")
        xmp.append_array_item(NS_DC, "creator", "bar")

        self.assertTrue(xmp.does_array_item_exist(NS_DC, "creator", "foo"))
        self.assertFalse(xmp.does_array_item_exist(NS_DC, "creator", "blah"))
Beispiel #6
0
def tag_images(docker_image):
    subprocess.call(['mkdir', '-p', 'figures'])
    subprocess.call("docker run --rm -v {}/figures:/figures "
    "{} make figures".format(os.getcwd(), docker_image), shell=True)

    figures = glob.glob('{}/figures/*.png'.format(os.getcwd()))
    for filename in figures:
        xmpfile = XMPFiles(file_path=filename, open_forupdate=True)
        xmp = xmpfile.get_xmp()
        if xmp == None:
            xmp = XMPMeta()
        xmp.append_array_item(libxmp.consts.XMP_NS_DC, 'creator', '{{ "im2sim" : "{}" }}'.format(docker_image), {'prop_array_is_ordered': True, 'prop_value_is_array': True})
        xmpfile.put_xmp(xmp)
        xmpfile.close_file()

    return None
def write_to_file():

    filename = fileEdit.text()
    
    if os.path.isfile(filename) == False:
        print("Error: Media file or reference file missing")
    else:
        xmpfile = XMPFiles( file_path=filename, open_forupdate=True)

        xmp = XMPMeta()

        # Write creator
        xmp.append_array_item(consts.XMP_NS_DC, 'creator', escape(str(creatorEdit.text())), {'prop_array_is_ordered': True, 'prop_value_is_array': True})

        # Write title
        xmp.append_array_item(consts.XMP_NS_DC, 'title', escape(str(titleEdit.text())), {'prop_array_is_ordered': True, 'prop_value_is_array': True})

        # Write sources
        for line in referencesEdit.toPlainText().split("\n"):
            if (len(line) > 1):
                xmp.append_array_item(consts.XMP_NS_DC, 'source', escape(str(line)), {'prop_array_is_ordered': True, 'prop_value_is_array': True})
        """
        if (xmpfile.can_put_xmp(xmp) == False):
            editLabel.setText ('Error: Cannot write metadata to file.')
        else:
        """
        xmpfile.put_xmp(xmp)
        xmpfile.close_file()
        editLabel.setText ('Success! Metadata written to file.')
Beispiel #8
0
    def test_write_new_struct_in_array(self):
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")

        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        prefix = xmp.get_prefix_for_namespace(NS_DC)

        xmp.append_array_item(NS_DC,
                              prefix + 'creator',
                              None,
                              prop_value_is_struct=True)
        xmp.set_property(NS_DC, prefix + 'creator[2]/' + prefix + 'TestProp',
                         '100')
        self.assertTrue(xmp.does_property_exist(NS_DC, prefix + 'creator[2]'))
        prop = xmp.get_property(NS_DC,
                                prefix + 'creator[2]/%sTestProp' % prefix)
        self.assertEqual(prop, '100')

        xpath = prefix + 'creator'
        xmp.set_array_item(NS_DC, xpath, 3, None, prop_value_is_struct=True)
        xpath += '[3]/%sTestProp' % prefix
        xmp.set_property(NS_DC, xpath, '200')
        self.assertTrue(xmp.does_property_exist(NS_DC, xpath))
        prop = xmp.get_property(NS_DC, xpath)
        self.assertEqual(prop, '200')

        xpath = prefix + 'TestStruct/' + prefix + 'TestValue'
        xmp.set_property(NS_DC, xpath, '300')
        self.assertTrue(xmp.does_property_exist(NS_DC, xpath))
        prop = xmp.get_property(NS_DC, xpath)
        self.assertEqual(prop, '300')
Beispiel #9
0
    def create_images():
        # actual image color: 255,0,0
        img = Image.new("RGB", (100, 20), color='red')
        text = ImageDraw.Draw(img)
        text.text((10, 10), "Hello World", fill=(0, 0, 0))
        image_wmeta = 'image_wmeta'

        # thumbnail color: 0,0,255
        o = io.BytesIO()
        secret_thumbnail = Image.new("RGB", (120, 20), color='blue')
        text = ImageDraw.Draw(secret_thumbnail)
        text.text((10, 10), "secret thumbnail", fill=(0, 0, 0))
        # transform it to bytes
        secret_thumbnail.save(o, "jpeg")
        secret_exif_thumbnail = o.getvalue()
        secret_thumbnail.close()

        # forbidden image_extension
        img.save(forbidden_img, "tiff")
        # bmp doesn't contain critical meta information
        img.save(image_wmeta + "_bmp" + '.bmp')

        # for some reasons some of these values don't match the relative specification:
        # rational numbers are separated at the comma, f.e. 13.37 is represented by [(13), (37)]
        # http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf#page=47 ...
        # http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf#page=87
        jpg_exif = {
            "0th": {
                piexif.ImageIFD.ImageDescription: u"description",
                piexif.ImageIFD.StripOffsets: 3,
                piexif.ImageIFD.Artist: u"artist",
                piexif.ImageIFD.Copyright: u"copyright holder",
                piexif.ImageIFD.DateTime: u"2012:01:08 10:09:01",
            },
            "Exif": {
                piexif.ExifIFD.DateTimeOriginal: u"2016:08:07 13:37:10",
                piexif.ExifIFD.DateTimeDigitized: u"2015:03:07 14:20:30",
                piexif.ExifIFD.OffsetTime: u"2017:05:09 08:04:04",
                piexif.ExifIFD.OffsetTimeOriginal: u"2017:04:12 18:15:00",
                piexif.ExifIFD.OffsetTimeDigitized: u"2016:02:10 11:10:03",
                piexif.ExifIFD.SubSecTime: u"2017:09:04 10:03:10",
                piexif.ExifIFD.SubSecTimeOriginal: u"2019:10:03 10:03:10",
                piexif.ExifIFD.SubSecTimeDigitized: u"2013:10:03 10:03:10",
                piexif.ExifIFD.CameraOwnerName: u"Cameraname",
                piexif.ExifIFD.BodySerialNumber: u"body serialnumber",
                piexif.ExifIFD.LensSerialNumber: u"lens serialnumber",
                piexif.ExifIFD.UserComment: b"secret comment",
            },
            "GPS": {
                piexif.GPSIFD.GPSLatitudeRef: u"N",
                piexif.GPSIFD.GPSLatitude: [(10, 1), (20, 1), (0, 0)],
                piexif.GPSIFD.GPSLongitudeRef: u"W",
                piexif.GPSIFD.GPSLongitude: [(10, 1), (20, 1), (0, 0)],
                piexif.GPSIFD.GPSAltitudeRef: 0,
                piexif.GPSIFD.GPSAltitude: (200, 1),
                piexif.GPSIFD.GPSTimeStamp: [(10), (3)],
                piexif.GPSIFD.GPSSatellites: u"satellites",
                piexif.GPSIFD.GPSStatus: u"A",
                piexif.GPSIFD.GPSMeasureMode: u"3",
                piexif.GPSIFD.GPSDOP: [(1), (4)],
                piexif.GPSIFD.GPSSpeedRef: u"K",
                piexif.GPSIFD.GPSSpeed: [(42), (10)],
                piexif.GPSIFD.GPSTrackRef: u"T",
                piexif.GPSIFD.GPSTrack: [(21), (123)],
                piexif.GPSIFD.GPSImgDirectionRef: u"T",
                piexif.GPSIFD.GPSImgDirection: [(10), (12)],
                piexif.GPSIFD.GPSMapDatum: u"today",
                piexif.GPSIFD.GPSDestLatitudeRef: u"N",
                piexif.GPSIFD.GPSDestLatitude: [(8, 1), (30, 1), (0, 0)],
                piexif.GPSIFD.GPSDestLongitudeRef: u"E",
                piexif.GPSIFD.GPSDestLongitude: [(8), (30)],
                piexif.GPSIFD.GPSDestBearingRef: u"T",
                piexif.GPSIFD.GPSDestBearing: [(1), (10)],
                piexif.GPSIFD.GPSDestDistanceRef: u"K",
                piexif.GPSIFD.GPSDestDistance: [(10), (3)],
                piexif.GPSIFD.GPSProcessingMethod: b"WLAN",
                piexif.GPSIFD.GPSAreaInformation: b"area",
                piexif.GPSIFD.GPSDateStamp: u"2015:10:03 10:03:10",
                piexif.GPSIFD.GPSDifferential: 1,
                piexif.GPSIFD.GPSHPositioningError: [(2), (0)],
            },
            "1st": {
                piexif.ImageIFD.ImageDescription: u"description",
                piexif.ImageIFD.StripOffsets: 3,
                piexif.ImageIFD.Artist: u"artist",
                piexif.ImageIFD.Copyright: u"copyright holder",
                piexif.ImageIFD.DateTime: u"2013:10:03 10:03:10",
            },
            "thumbnail": secret_exif_thumbnail
        }

        png_dict = {
            "ImageDescription": u"description",
            "StripOffsets": "3",
            "Artist": u"artist",
            "Copyright": u"copyright holder",
            "DateTime": u"2012:01:08 10:09:01",
            "DateTimeOriginal": u"2016:08:07 13:37:10",
            "DateTimeDigitized": u"2015:03:07 14:20:30",
            "OffsetTime": u"2017:05:09 08:04:04",
            "OffsetTimeOriginal": u"2017:04:12 18:15:00",
            "OffsetTimeDigitized": u"2016:02:10 11:10:03",
            "SubSecTime": u"2017:09:04 10:03:10",
            "SubSecTimeOriginal": u"2019:10:03 10:03:10",
            "SubSecTimeDigitized": u"2013:10:03 10:03:10",
            "CameraOwnerName": u"Cameraname",
            "BodySerialNumber": u"body serialnumber",
            "LensSerialNumber": u"lens serialnumber",
            "UserComment": b"secret comment",
            "GPSLatitudeRef": u"N",
            "GPSLatitude": "3 deg 20' 0.00",
            "GPSLongitudeRef": u"W",
            "GPSLongitude": "3 deg 20.1' 0.00",
            "GPSAltitudeRef": "0",
            "GPSAltitude": "200 m Above Sea Level",
            "GPSTimeStamp": "03:19:59.999999",
            "GPSSatellites": u"satellites",
            "GPSStatus": u"A",
            "GPSMeasureMode": u"3",
            "GPSSpeedRef": u"K",
            "GPSSpeed": "4.2",
            "GPSTrackRef": u"T",
            "GPSTrack": "0.1707317073",
            "GPSImgDirectionRef": u"T",
            "GPSImgDirection": "0.6333333333",
            "GPSMapDatum": u"today",
            "GPSDestLatitudeRef": u"N",
            "GPSDestLatitude": "3 deg 30' 0.00",
            "GPSDestLongitudeRef": u"E",
            "GPSDestLongitude": "0 deg 16' 0.00",
            "GPSDestBearingRef": u"T",
            "GPSDestBearing": "0.1",
            "GPSDestDistanceRef": u"K",
            "GPSDestDistance": "3.333333333",
            "GPSProcessingMethod": b"WLAN",
            "GPSAreaInformation": b"area",
            "GPSDateStamp": u"2015:10:03 10:03:10",
            "GPSDifferential": "1",
            "ImageDescription": u"description",
            "StripOffsets": "3",
            "Artist": u"artist",
            "Copyright": u"copyright holder",
            "DateTime": u"2013:10:03 10:03:10",
        }

        # jpg with exif
        img.save(image_wmeta + '_jpg' + '.jpg', exif=piexif.dump(jpg_exif))
        # copy jpg to jpe, jpeg
        copyfile(image_wmeta + '_jpg' + '.jpg', image_wmeta + '_jpe' + '.jpe')
        copyfile(image_wmeta + '_jpg' + '.jpg',
                 image_wmeta + '_jpeg' + '.jpeg')

        # png exif-part
        png_info = PngImagePlugin.PngInfo()
        # copy png metadata
        for k, v in png_dict.items():
            png_info.add_text(k, v, 0)
        img.save(image_wmeta + '_png' + '.png', "PNG", pnginfo=png_info)

        img.save(image_wmeta + '_gif' + '.gif')
        img.close()

        # xmp for gif and png
        xmp = XMPMeta()
        xmp.append_array_item(consts.XMP_NS_DC, 'secret', 'secret information',
                              {
                                  'prop_array_is_ordered': True,
                                  'prop_value_is_array': True
                              })

        # gif xmp
        # TODO BUG Exempi library version >= 2.5 does not work with GIF images created by Pillow.
        # TODO BUG The format gets not recognized by Exempi.
        # TODO BUG Maybe a newer Pillow or Exempi version will fix this...
        # gif_image = XMPFiles(file_path=image_wmeta + '_gif' + ".gif", open_forupdate=True)
        # gif_image.put_xmp(xmp)
        # gif_image.close_file()

        # png part 2
        png_image = XMPFiles(file_path=image_wmeta + '_png' + ".png",
                             open_forupdate=True)
        png_image.put_xmp(xmp)
        png_image.close_file()

        return ((image_wmeta + '_' + suffix + "." + suffix)
                for suffix in ALLOWED_IMG_EXTENSIONS)
    def test_exempi_core(self):
        """Corresponds to test_exempi.TestExempi.test_exempi_core"""
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")
        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        self.assertTrue(xmp.does_property_exist(NS_TIFF, 'Make'))
        self.assertFalse(xmp.does_property_exist(NS_TIFF, 'Foo'))

        prop = xmp.get_property(NS_TIFF, 'Make')
        self.assertEqual(prop, 'Canon')

        xmp.set_property(NS_TIFF, 'Make', 'Leica')
        prop = xmp.get_property(NS_TIFF, 'Make')
        self.assertEqual(prop, 'Leica')

        # Some tests correspond to option masks not currently returned via
        # this interface.
        item = xmp.get_localized_text(NS_DC, 'rights', None, 'x-default')
        self.assertEqual(item, "2006, Hubert Figuiere")

        xmp.set_localized_text(NS_DC, 'rights', 'en', 'en-CA', 'Foo bar')
        item = xmp.get_localized_text(NS_DC, 'rights', 'en', 'en-US')

        # Can't look at the actual lang, unlike the original test.
        self.assertEqual(item, 'Foo bar')

        xmp.delete_localized_text(NS_DC, 'rights', 'en', 'en-CA')
        self.assertFalse(xmp.does_property_exist(NS_DC, "rights[1]"))

        xmp.set_array_item(NS_DC, "creator", 2, "foo")
        xmp.append_array_item(NS_DC, "creator", "bar")

        prop = xmp.get_array_item(NS_DC, "creator", 3)
        self.assertEqual(prop, "bar")

        xmp.delete_property(NS_DC, "creator[3]")
        self.assertFalse(xmp.does_property_exist(NS_DC, "creator[3]"))

        prop = xmp.get_property(NS_EXIF, "DateTimeOriginal")
        self.assertEqual(prop, "2006-12-07T23:20:43-05:00")

        the_prop = xmp.get_property_datetime(NS_EXIF, "DateTimeOriginal")
        self.assertEqual(the_prop.year, 2006) 
        self.assertEqual(the_prop.minute, 20)
        self.assertEqual(the_prop.tzinfo, pytz.utc)

        prop = xmp.get_property(NS_XAP, "Rating")
        self.assertEqual(prop, "3")

        prop = xmp.get_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius")
        self.assertEqual(prop, 1.0)

        xmp.set_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius", 2.5)
        prop = xmp.get_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius")
        self.assertEqual(prop, 2.5)

        prop = xmp.get_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied")
        self.assertFalse(prop)
        xmp.set_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied", True)
        prop = xmp.get_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied")
        self.assertTrue(prop)

        prop = xmp.get_property_int(NS_EXIF, "MeteringMode")
        self.assertEqual(prop, 5)
        xmp.set_property_int(NS_EXIF, "MeteringMode", 10)
        prop = xmp.get_property_long(NS_EXIF, "MeteringMode")
        self.assertEqual(prop, 10)
        xmp.set_property_long(NS_EXIF, "MeteringMode", 32)
        prop = xmp.get_property_int(NS_EXIF, "MeteringMode")
        self.assertEqual(prop, 32)
Beispiel #11
0
def export_to_xmp_files(args):
    tmp_faces, img_labels = utils.load_img_labels(args.imgs_root)
    faces = utils.FACES(tmp_faces)

    if len(faces.dict_by_files) == 0:
        print('no faces loaded')
        exit()

    total_images = utils.get_images_in_dir_rec(args.imgs_root)

    for f in total_images:
        img_path = os.path.splitext(f)[0] + os.path.splitext(f)[1].lower()

        if os.path.dirname(
                img_path
        ) != args.mask_folder and args.mask_folder != None or img_path.lower(
        ).endswith('.png'):
            continue
        xmp_path = os.path.splitext(f)[0] + '.xmp'

        if os.path.exists(xmp_path):
            with open(xmp_path, 'r') as fptr:
                strbuffer = fptr.read()
            xmp = XMPMeta()
            xmp.parse_from_str(strbuffer)
        else:
            xmpfile = XMPFiles(file_path=f, open_forupdate=True)
            xmp = xmpfile.get_xmp()

        # print(f)
        kw_faces, kw_tags, kw_categories, kw_labels, kw_miscs = get_keywords(
            xmp)
        kw_tags = []
        kw_categories = []
        kw_miscs = []

        if img_path in faces.dict_by_files:
            names = faces.get_names(faces.dict_by_files[img_path])
            # remove detected, deleted and unknown
            unwanted_names = {'detected', 'deleted', 'unknown'}
            names = [ele for ele in names if ele not in unwanted_names]
            face_names = prepare_names(names, 'f ')
        else:
            # if not os.path.exists(xmp_path):
            #     continue
            face_names = []

        labels = []
        if img_path in img_labels:
            if len(img_labels[img_path].tags) != 0:
                labels += prepare_names([
                    t[0].lower()
                    for t in img_labels[img_path].tags if t[1] >= 30
                ], 'l ')

            if len(img_labels[img_path].categories) != 0:
                labels += prepare_names(
                    [c[0].lower() for c in img_labels[img_path].categories],
                    'l ')

            if hasattr(img_labels[img_path], 'gcloud_labels'):
                labels += prepare_names(
                    [l.lower() for l in img_labels[img_path].gcloud_labels],
                    'l ')
            if hasattr(img_labels[img_path], 'gcloud_objects'):
                labels += prepare_names(
                    [l.lower() for l in img_labels[img_path].gcloud_objects],
                    'l ')
            if hasattr(img_labels[img_path], 'gcloud_web'):
                labels += prepare_names(
                    [l.lower() for l in img_labels[img_path].gcloud_web], 'l ')

            if hasattr(img_labels[img_path], 'gcloud_landmarks'):
                labels += prepare_names([
                    l.lower()
                    for l in img_labels[img_path].gcloud_landmarks[::2]
                ], 'l ')

            labels = list(set(labels))

        if sorted(face_names) != sorted(kw_faces) or sorted(labels) != sorted(
                kw_labels) or not os.path.exists(xmp_path):
            xmp.delete_property(consts.XMP_NS_DC, 'subject')

            for face in face_names:
                xmp.append_array_item(consts.XMP_NS_DC, 'subject', face, {
                    'prop_array_is_ordered': True,
                    'prop_value_is_array': True
                })

            for l in labels:
                xmp.append_array_item(consts.XMP_NS_DC, 'subject', l, {
                    'prop_array_is_ordered': True,
                    'prop_value_is_array': True
                })

            print('exporting file: {}'.format(os.path.basename(xmp_path)))
            with open(xmp_path, 'w') as fptr:
                fptr.write(xmp.serialize_to_str(omit_packet_wrapper=True))
Beispiel #12
0
    def test_exempi_core(self):
        """Corresponds to test_exempi.TestExempi.test_exempi_core"""
        filename = pkg_resources.resource_filename(__name__,
                                                   "samples/test1.xmp")
        with open(filename, 'r') as fptr:
            strbuffer = fptr.read()

        xmp = XMPMeta()
        xmp.parse_from_str(strbuffer)

        self.assertTrue(xmp.does_property_exist(NS_TIFF, 'Make'))
        self.assertFalse(xmp.does_property_exist(NS_TIFF, 'Foo'))

        prop = xmp.get_property(NS_TIFF, 'Make')
        self.assertEqual(prop, 'Canon')

        xmp.set_property(NS_TIFF, 'Make', 'Leica')
        prop = xmp.get_property(NS_TIFF, 'Make')
        self.assertEqual(prop, 'Leica')

        # Some tests correspond to option masks not currently returned via
        # this interface.
        item = xmp.get_localized_text(NS_DC, 'rights', None, 'x-default')
        self.assertEqual(item, "2006, Hubert Figuiere")

        xmp.set_localized_text(NS_DC, 'rights', 'en', 'en-CA', 'Foo bar')
        item = xmp.get_localized_text(NS_DC, 'rights', 'en', 'en-US')

        # Can't look at the actual lang, unlike the original test.
        self.assertEqual(item, 'Foo bar')

        xmp.delete_localized_text(NS_DC, 'rights', 'en', 'en-CA')
        self.assertFalse(xmp.does_property_exist(NS_DC, "rights[1]"))

        xmp.set_array_item(NS_DC, "creator", 2, "foo")
        xmp.append_array_item(NS_DC, "creator", "bar")

        prop = xmp.get_array_item(NS_DC, "creator", 3)
        self.assertEqual(prop, "bar")

        xmp.delete_property(NS_DC, "creator[3]")
        self.assertFalse(xmp.does_property_exist(NS_DC, "creator[3]"))

        prop = xmp.get_property(NS_EXIF, "DateTimeOriginal")
        self.assertEqual(prop, "2006-12-07T23:20:43-05:00")

        the_prop = xmp.get_property_datetime(NS_EXIF, "DateTimeOriginal")
        self.assertEqual(the_prop.year, 2006)
        self.assertEqual(the_prop.minute, 20)
        self.assertEqual(the_prop.tzinfo, pytz.utc)

        prop = xmp.get_property(NS_XAP, "Rating")
        self.assertEqual(prop, "3")

        prop = xmp.get_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius")
        self.assertEqual(prop, 1.0)

        xmp.set_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius", 2.5)
        prop = xmp.get_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius")
        self.assertEqual(prop, 2.5)

        prop = xmp.get_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied")
        self.assertFalse(prop)
        xmp.set_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied", True)
        prop = xmp.get_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied")
        self.assertTrue(prop)

        prop = xmp.get_property_int(NS_EXIF, "MeteringMode")
        self.assertEqual(prop, 5)
        xmp.set_property_int(NS_EXIF, "MeteringMode", 10)
        prop = xmp.get_property_long(NS_EXIF, "MeteringMode")
        self.assertEqual(prop, 10)
        xmp.set_property_long(NS_EXIF, "MeteringMode", 32)
        prop = xmp.get_property_int(NS_EXIF, "MeteringMode")
        self.assertEqual(prop, 32)
def worker(filepath):
    # initialize saucenao
    saucenao_core = SauceNao(
        directory='directory',
        databases=9,
        # 999 by default, 5 for pixiv, 9 for booru.
        minimum_similarity=65,
        combine_api_types=False,
        api_key=saucenao_api_key,
        exclude_categories='',
        move_to_categories=False,
        use_author_as_category=False,
        output_type=SauceNao.API_JSON_TYPE,
        start_file='',
        log_level=logging.ERROR,
        title_minimum_similarity=90)
    # search image on saucenao
    try:
        result = search(saucenao_core, filepath)
    except requests.exceptions.ConnectionError:
        print("Failed to connect saucenao!")
        return -1
    except saucenao.exceptions.DailyLimitReachedException:
        print("Saucenao daily limit reached! try 1 hour later!")
        return -2
    if (len(result) is 0):
        print('Image not found on danbooru!')
        return 1
    else:
        danbooru_id = result[0]['data']['danbooru_id']
        print('Image Found, ID=' + str(danbooru_id))
        # GET danbooru tag json
        try:
            http = urllib3.PoolManager()
            # disable  https cert check warning
            urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
            url = 'https://danbooru.donmai.us/posts/' + str(
                danbooru_id) + '.json'
            headers = urllib3.util.make_headers(basic_auth=danbooru_login +
                                                ':' + danbooru_api_key)
            r = http.request('GET', url, headers=headers)
            r_data = r.data
            if isinstance(r_data, bytes):
                r_data = str(r_data, 'utf-8')
            tags = json.loads(r_data)['tag_string']
            taglist = tags.split()
        except requests.exceptions.ConnectionError:
            print('failed to GET tag data from danbooru')
            return -1
        # Write XMP Metadata to image
        xmpfile = XMPFiles(file_path=filepath, open_forupdate=True)
        xmp = xmpfile.get_xmp()
        # if image has no xmp data, create one
        if (xmp is None):
            xmp = XMPMeta()
        # write the tags
        for each in taglist:
            # check whether XMP includes 'subject' property,
            # if not, create a new one
            if (not xmp.does_property_exist(consts.XMP_NS_DC, 'subject')):
                xmp.append_array_item(consts.XMP_NS_DC, 'subject', each, {
                    'prop_array_is_ordered': True,
                    'prop_value_is_array': True
                })
            # check whether tag has been written to file
            if (not xmp.does_array_item_exist(consts.XMP_NS_DC, 'subject',
                                              each)):
                xmp.append_array_item(consts.XMP_NS_DC, 'subject', each)
        if (xmpfile.can_put_xmp(xmp)):
            xmpfile.put_xmp(xmp)
            xmpfile.close_file()
            return 0
        else:
            print('Unable to write XMP data!')
            return -1