def test_can_put_xmp(self):
     for flg in open_flags:
         kwargs = {flg: True}
         for filename, fmt in zip(self.samplefiles, self.formats):
             # See test_exempi_error()
             if (((not self.flg_fmt_combi(flg, fmt))
                  and (not self.exempi_problem(flg, fmt)))):
                 xmpfile = XMPFiles()
                 xmpfile.open_file(filename, **kwargs)
                 xmp = xmpfile.get_xmp()
                 if flg == 'open_forupdate':
                     self.assertTrue(xmpfile.can_put_xmp(xmp))
                 else:
                     self.assertFalse(xmpfile.can_put_xmp(xmp))
示例#2
0
 def test_can_put_xmp(self):
     for flg in open_flags:
         kwargs = { flg: True }
         for filename, fmt in zip(self.samplefiles, self.formats):
             # See test_exempi_error()
             if (((not self.flg_fmt_combi(flg, fmt)) and
                  (not self.exempi_problem(flg, fmt)))):
                 xmpfile = XMPFiles()
                 xmpfile.open_file( filename, **kwargs )
                 xmp = xmpfile.get_xmp()
                 if flg == 'open_forupdate':
                     self.assertTrue( xmpfile.can_put_xmp( xmp ) )
                 else:
                     self.assertFalse( xmpfile.can_put_xmp( xmp ) )
    def exempi_error(self):
        """
        Test case that exposes an Exempi bug.

        Seems like xmp_files_can_put_xmp in exempi is missing a try/catch block.

        So loading a sidecar file and call can_put_xmp will kill python
        interpreter since a C++ exception is thrown.
        """
        filename = pkg.resource_filename(__name__, "samples/sig05-002a.xmp")
        xmpfile = XMPFiles()
        xmpfile.open_file(filename, open_forupdate = True )
        xmp = xmpfile.get_xmp()
        xmpfile.can_put_xmp( xmp )
    def exempi_error(self):
        """
        Test case that exposes an Exempi bug.

        Seems like xmp_files_can_put_xmp in exempi is missing a try/catch block.

        So loading a sidecar file and call can_put_xmp will kill python
        interpreter since a C++ exception is thrown.
        """
        filename = pkg.resource_filename(__name__, "samples/sig05-002a.xmp")
        xmpfile = XMPFiles()
        xmpfile.open_file(filename, open_forupdate=True)
        xmp = xmpfile.get_xmp()
        xmpfile.can_put_xmp(xmp)
def UpdateFileMetadata(filename, datetime):
    exif = GExiv2.Metadata(filename)
    if exif is not None:
        fileDate = GetDateFromExif(exif)
        if fileDate is not None:
            fileDate = datetime.strptime(fileDate, DATE_FORMAT)
            # date within acceptable limit. don't update
            if abs((fileDate - datetime).days) <= FILE_METADATA_DATE_TOLERANCE:
                return

    log('Updating exif: %s to date: %s', \
        filename, datetime.strftime(DATE_FORMAT))

    if DRY_RUN == False:
        if exif is not None:
            exif['Exif.Photo.DateTimeOriginal'] = datetime.strftime(
                DATE_FORMAT)
            exif['Exif.Photo.DateTimeDigitized'] = datetime.strftime(
                DATE_FORMAT)
            exif['Exif.Image.DateTime'] = datetime.strftime(DATE_FORMAT)
            exif['Exif.Image.DateTimeOriginal'] = datetime.strftime(
                DATE_FORMAT)
            exif.save_file()

        xmpfile = XMPFiles(file_path=filename, open_forupdate=True)
        xmp = xmpfile.get_xmp()
        if xmp is not None:
            for xmpConst in XMP_CONSTANTS:
                for dateConst in DATE_CONSTANTS:
                    if xmp.does_property_exist(xmpConst, dateConst):
                        xmp.set_property( \
                            xmpConst, dateConst, datetime.strftime(DATE_FORMAT_XMP))
            if (xmpfile.can_put_xmp(xmp)):
                xmpfile.put_xmp(xmp)
                xmpfile.close_file()
 def test_write_in_readonly(self):
     """If not "open_forupdate = True", should raise exception"""
     # Note, the file should have been opened with "open_forupdate = True"
     # so let's check if XMPMeta is raising an Exception.
     xmpfile = XMPFiles()
     filename = os.path.join(self.tempdir, 'sig05-002a.tif')
     xmpfile.open_file(filename)
     xmp_data = xmpfile.get_xmp()
     xmp_data.set_property(NS_PHOTOSHOP, 'Headline', "Some text")
     self.assertRaises(XMPError, xmpfile.put_xmp, xmp_data)
     self.assertEqual(xmpfile.can_put_xmp(xmp_data), False)
示例#7
0
 def test_write_in_readonly(self):
     """If not "open_forupdate = True", should raise exception"""
     # Note, the file should have been opened with "open_forupdate = True"
     # so let's check if XMPMeta is raising an Exception.
     xmpfile = XMPFiles()
     filename = os.path.join(self.tempdir, 'sig05-002a.tif')
     xmpfile.open_file(filename)
     xmp_data = xmpfile.get_xmp()
     xmp_data.set_property( NS_PHOTOSHOP, 'Headline', "Some text")
     self.assertRaises( XMPError, xmpfile.put_xmp, xmp_data )
     self.assertEqual( xmpfile.can_put_xmp( xmp_data ), False )
示例#8
0
def update_xmp(imgpath, keywords):
    """ updates the xmp data in the image, or creates a sidecar xmp """

    # Check if a sidecar file already exists
    if os.path.isfile(imgpath + '.xmp'):
        imgpath = imgpath + '.xmp'

    # NEF requires sidecar
    embeddedXmpFormats = ['jpg', 'png', 'tif', 'dng']

    if not imgpath.lower().endswith(tuple(embeddedXmpFormats)):
        # create and use sidecar file
        imgpath = imgpath + '.xmp'
        with open(imgpath, 'w+') as f:
            f.write(blank_xmp())
            print('wrote in' + imgpath)

    xmpfiledict = file_to_dict(imgpath)
    existing_keywords = []
    try:
        dc = []
        dc.append(xmpfiledict[consts.XMP_NS_DC])
        existing_keywords = [x[1] for x in dc]
    except:
        print('nothing')
    print('existing_keywords')
    print(existing_keywords)

    xmpfile = XMPFiles(file_path=imgpath, open_forupdate=True)
    xmp = xmpfile.get_xmp()
    print(xmp)
    keywords_to_add = [x for x in keywords if x not in existing_keywords]
    print('keywords to add')
    print(keywords_to_add)

    def add_keyword(k):
        """ helper func """
        xmp.append_array_item(consts.XMP_NS_DC, u'subject', k)

    _ = [add_keyword(x) for x in keywords_to_add]

    if xmpfile.can_put_xmp(xmp):
        xmpfile.put_xmp(xmp)

    else:
        xmpfile.close_file()
        raise Exception('Cannot write xmp to ' + imgpath)

    xmpfile.close_file()
    return 0
示例#9
0
def check_xmp_writable(file):
    # get xmp from file
    xmpfile = XMPFiles(file_path=file, open_forupdate=True)
    xmp = xmpfile.get_xmp()

    try:
        #if you can write new xmp
        if xmpfile.can_put_xmp(xmp) == True:
            xmpfile.close_file()
            return True
        else:
            xmpfile.close_file()
            return False
    except Exception as e:
        print("Error: " + str(e))
示例#10
0
    def mutate(self, info, input):
        abs_path = Path(BASE_DIR, input["path"])
        if not abs_path.exists():
            raise Exception("Image not found")

        if not (isinstance(input["rating"], int)
                and -1 <= input["rating"] <= 5):
            raise Exception("Rating must be an integer from 1 to 5")

        image = {"path": abs_path}
        xmpfile = XMPFiles(file_path=str(abs_path), open_forupdate=True)
        xmp = xmpfile.get_xmp()
        # WISHLIST don't write if rating didn't change
        xmp.set_property(XMP_NS_XMP, "xmp:Rating", str(input["rating"]))
        if not xmpfile.can_put_xmp(xmp):
            raise Exception("Can't write xmp metadata back to image")

        xmpfile.put_xmp(xmp)
        xmpfile.close_file()
        return SetRatingPayload(image=image)
示例#11
0
def embed_xmp(filename, dt):
    t = calendar.timegm(dt.timetuple())
    os.utime(filename, (t, t))
    os.system('SetFile -d "%s" "%s"' % (
        dt.strftime("%m/%d/%Y 00:00:00"),
        filename.encode('utf-8'),
    ))

    xmpfile = XMPFiles(file_path=filename, open_forupdate=True)
    xmp = xmpfile.get_xmp()

    xmp.set_property(consts.XMP_NS_XMP, "CreateDate", dt.isoformat())

    if xmpfile.can_put_xmp(xmp):
        xmpfile.put_xmp(xmp)
        xmpfile.close_file()
        return True
    else:
        xmpfile.close()
        return False
示例#12
0
def embed_xmp(filename, dt):
    t = calendar.timegm(dt.timetuple())
    os.utime(filename, (t, t))
    os.system('SetFile -d "%s" "%s"' % (
        dt.strftime("%m/%d/%Y 00:00:00"),
        filename.encode('utf-8'),
    ))

    xmpfile = XMPFiles(file_path=filename, open_forupdate=True)
    xmp = xmpfile.get_xmp()

    xmp.set_property(
        consts.XMP_NS_XMP,
        "CreateDate",
        dt.isoformat()
    )

    if xmpfile.can_put_xmp(xmp):
        xmpfile.put_xmp(xmp)
        xmpfile.close_file()
        return True
    else:
        xmpfile.close()
        return False
示例#13
0
def write_xmp(filename, field, value, sidecar=False):
    """Write a field into a files XMP store, if sidecar is True and the
    file format doesn't support writing inline a sidecar .xmp file
    will be created.

    Args:
      filename (str): The full path to file read to write XMP data into
      field (str|None)
      sidecar (bool): If True and the file doesn't support XMP inline a
          .xmp file with the same name as the ``filename`` will be
          created with an .xmp extension. Example: test.txt -> test.txt.xmp

    Returns:
      On success: The path to the file written
      On failure: False

    """
    xmpfile = XMPFiles(file_path=filename, open_forupdate=True)
    xmp = xmpfile.get_xmp()

    if xmp is None and sidecar:
        return write_xmp_sidecar(filename, field, value)
    elif xmp is None:
        return False

    if _read_xmp_field(xmp, field) == value:
        return filename

    xmp.set_property(consts.XMP_NS_DC, field, value)

    if xmpfile.can_put_xmp(xmp):
        xmpfile.put_xmp(xmp)
        xmpfile.close_file()
        return filename
    else:
        return False
xmp.get_prefix_for_namespace(NS_GPANO)
xmp.set_property_bool(NS_GPANO, 'UsePanaramaViewer', True)
xmp.set_property(NS_GPANO, 'CaptureSoftware', 'Photo Sphere')
xmp.set_property(NS_GPANO, 'StichingSoftware', 'Photo Sphere')
xmp.set_property(NS_GPANO, 'ProjectionType', 'equirectangular')
xmp.set_property_float(NS_GPANO, 'PoseHeadingDegrees', 350.0)
xmp.set_property_float(NS_GPANO, 'InitialViewHeadingDegrees', 90.0)
xmp.set_property_float(NS_GPANO, 'InitialViewPitchDegrees', 0.0)
xmp.set_property_float(NS_GPANO, 'InitialViewRollDegrees', 0.0)
xmp.set_property_float(NS_GPANO, 'InitialHorizontalFOVDegrees', 75.0)
xmp.set_property_int(NS_GPANO, 'CroppedAreaLeftPixels', 0)
xmp.set_property_int(NS_GPANO, 'CroppedAreaTopPixels', 0)
xmp.set_property_int(NS_GPANO, 'CroppedAreaImageWidthPixels', 5100)
xmp.set_property_int(NS_GPANO, 'CroppedAreaImageHeightPixels', 2550)
xmp.set_property_int(NS_GPANO, 'FullPanoWidthPixels', 5100)
xmp.set_property_int(NS_GPANO, 'FullPanoHeightPixels', 2550)

dt = datetime.datetime(2012, 11, 7, 21, 3, 13, 465000, tzinfo=pytz.utc)
xmp.set_property_datetime(NS_GPANO, 'FirstPhotoDate', dt)

dt = datetime.datetime(2012, 11, 7, 21, 4, 10, 897000, tzinfo=pytz.utc)
xmp.set_property_datetime(NS_GPANO, 'LastPhotoDate', dt)

xmp.set_property_int(NS_GPANO, 'SourcePhotosCount', 50)
xmp.set_property_bool(NS_GPANO, 'ExposureLockUsed', False)

print(xmp)
xmpfile.can_put_xmp(xmp)
xmpfile.put_xmp(xmp)
xmpfile.close_file()
print('Done!')
示例#15
0
XMP_GIMAGE = 'http://ns.google.com/photos/1.0/image/'
XMP_GPANO = 'http://ns.google.com/photos/1.0/panorama/'
XMPMeta.register_namespace(XMP_GIMAGE, 'GImage')
XMPMeta.register_namespace(XMP_GPANO, 'GPano')

# Set GPano properties
lxmp.set_property(XMP_GPANO, 'ProjectionType', 'equirectangular')
lxmp.set_property_int(XMP_GPANO, 'CroppedAreaLeftPixels', image_width/2)
lxmp.set_property_int(XMP_GPANO, 'CroppedAreaTopPixels', 0)
lxmp.set_property_int(XMP_GPANO, 'CroppedAreaImageWidthPixels', image_width)
lxmp.set_property_int(XMP_GPANO, 'CroppedAreaImageHeightPixels', image_height)
lxmp.set_property_int(XMP_GPANO, 'FullPanoWidthPixels', image_width*2)
lxmp.set_property_int(XMP_GPANO, 'FullPanoHeightPixels', image_height)
lxmp.set_property_int(XMP_GPANO, 'InitialViewHeadingDegrees', 180)

# Encode right image to BASE64
rimage_data = open(rimage_path, 'rt').read()
rimage_base64 = base64.b64encode(rimage_data)

# Set GImage properties
lxmp.set_property(XMP_GIMAGE, 'Mime', 'image/jpeg')
lxmp.set_property(XMP_GIMAGE, 'Data', rimage_base64)

# Put XMP.
if vrimage_file.can_put_xmp(lxmp):
    vrimage_file.put_xmp(lxmp)
    print(vrimage_file.get_xmp())
    print("Done!")

vrimage_file.close_file()
#import files
from libxmp import XMPFiles

#set image to add data to
image = "image.jpg"

#read file
xmpfile = XMPFiles(file_path=image, open_forupdate=True)

#set INSPONIZER URI
inspoURI = "https://www.claytondunavant.com/inspo"

#get xmp from file
xmp = xmpfile.get_xmp()

#register or update INSPO namespace URI
xmp.register_namespace(inspoURI, "INSPO")

#set shirt property to UNIQLO
xmp.set_property(inspoURI, u"shirt", u"Uniqlo U T-Shirt")

#if you can write new xmp, write it
if xmpfile.can_put_xmp(xmp) == True:
    xmpfile.put_xmp(xmp)

#close the file
xmpfile.close_file()
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