def upload_insert(self, client, album_id, options): """Uploads a new photo by inserting it into an album. """ if options.dryrun: return album_url = '%s/%s' % (_ALBUM_URL, album_id) new_photo = gdata.photos.PhotoEntry() new_photo.title = atom.Title(text=self.title) comment = imageutils.get_photo_caption(self.photo, options.captiontemplate) if comment: new_photo.summary = atom.Summary(text=comment, summary_type='text') new_photo.media = gdata.media.Group() new_photo.media.keywords = gdata.media.Keywords( text=', '.join(self.get_export_keywords(options))) if options.gps and self.photo.gps: new_photo.geo = gdata.geo.Where() new_photo.geo.Point = gdata.geo.Point() new_photo.geo.Point.pos = gdata.geo.Pos( text='%.6f %.6f' % (self.photo.gps.latitude, self.photo.gps.longitude)) # TODO(tilmansp): For some reason, this does not seem to work, and # all newly inserted images need a second update cycle to fix the # timestamp. if self.photo.date: new_photo.timestamp = gdata.photos.Timestamp( text=get_picasaweb_date(self.photo.date)) client.throttle() self.picasa_photo = client.gd_client.InsertPhoto( album_url, new_photo, self.photo.image_path, content_type=get_content_type(self.photo.image_path))
def upload_insert(self, client, album_id, options): """Uploads a new photo by inserting it into an album. """ if options.dryrun: return album_url = "%s/%s" % (_ALBUM_URL, album_id) new_photo = gdata.photos.PhotoEntry() new_photo.title = atom.Title(text=self.title) comment = imageutils.get_photo_caption(self.photo, options.captiontemplate) if comment: new_photo.summary = atom.Summary(text=comment, summary_type="text") new_photo.media = gdata.media.Group() new_photo.media.keywords = gdata.media.Keywords(text=", ".join(self.get_export_keywords(options))) if options.gps and self.photo.gps: new_photo.geo = gdata.geo.Where() new_photo.geo.Point = gdata.geo.Point() new_photo.geo.Point.pos = gdata.geo.Pos( text="%.6f %.6f" % (self.photo.gps.latitude, self.photo.gps.longitude) ) # TODO(tilmansp): For some reason, this does not seem to work, and # all newly inserted images need a second update cycle to fix the # timestamp. if self.photo.date: new_photo.timestamp = gdata.photos.Timestamp(text=get_picasaweb_date(self.photo.date)) client.throttle() self.picasa_photo = client.gd_client.InsertPhoto( album_url, new_photo, self.photo.image_path, content_type=get_content_type(self.photo.image_path) )
def upload_insert(self, client, album_id, options): """Uploads a new photo by inserting it into an album. """ if options.dryrun: return album_url = '%s/%s' % (_ALBUM_URL, album_id) new_photo = gdata.photos.PhotoEntry() new_photo.title = atom.Title(text=self.title) # Combine title and description because PicasaWeb does not show the # title anywhere. comment = imageutils.get_photo_caption(self.photo, options.captiontemplate) export_keywords = self.get_export_keywords(options) photo_gps = self.photo.gps if comment: new_photo.summary = atom.Summary(text=comment, summary_type='text') new_photo.media = gdata.media.Group() new_photo.media.keywords = gdata.media.Keywords( text=', '.join(export_keywords)) if options.gps and photo_gps: new_photo.geo = gdata.geo.Where() new_photo.geo.Point = gdata.geo.Point() new_photo.geo.Point.pos = gdata.geo.Pos( text='%.6f %.6f' % (photo_gps.latitude, photo_gps.longitude)) client.throttle() self.picasa_photo = client.gd_client.InsertPhoto( album_url, new_photo, self.photo.image_path, content_type=get_content_type(self.photo.image_path))
def upload_insert(self, client, album_id, options): """Uploads a new photo by inserting it into an album. """ if options.dryrun: return album_url = '%s/%s' % (_ALBUM_URL, album_id) new_photo = gdata.photos.PhotoEntry() new_photo.title = atom.Title(text=self.title) # Combine title and description because PicasaWeb does not show the # title anywhere. comment = imageutils.get_photo_caption(self.photo, options.captiontemplate) export_keywords = self.get_export_keywords(options) photo_gps = self.photo.gps if comment: new_photo.summary = atom.Summary(text=comment, summary_type='text') new_photo.media = gdata.media.Group() new_photo.media.keywords = gdata.media.Keywords( text=', '.join(export_keywords)) if options.gps and photo_gps: new_photo.geo = gdata.geo.Where() new_photo.geo.Point = gdata.geo.Point() new_photo.geo.Point.pos = gdata.geo.Pos(text='%.6f %.6f' % ( photo_gps.latitude, photo_gps.longitude)) client.throttle() self.picasa_photo = client.gd_client.InsertPhoto( album_url, new_photo, self.photo.image_path, content_type=get_content_type(self.photo.image_path))
def test_get_photo_caption(self): template = "-{title}-" image = self.TestImage('x', 'y') self.assertEqual(iu.get_photo_caption(image, template), '-x-') template = "-{description}-" image = self.TestImage('x', 'y') self.assertEqual(iu.get_photo_caption(image, template), '-y-') #template = "{dated_caption_description}" #image = self.TestImage('x', 'y') #self.assertEqual(iu.get_photo_caption(image, template), # 'x: y') #image = self.TestImage('x', '') #self.assertEqual(iu.get_photo_caption(image, template), # 'x') #image = self.TestImage('x', None) #self.assertEqual(iu.get_photo_caption(image, template), # 'x') #image = self.TestImage('20100510 Hello', 'y') #self.assertEqual(iu.get_photo_caption(image, template), # '2010/05/10 Hello: y') #image = self.TestImage('20100511 Hello - 31', 'y') #self.assertEqual(iu.get_photo_caption(image, template), # '2010/05/11 Hello: y') #image = self.TestImage('20100500 Hello - 31', 'y') #self.assertEqual(iu.get_photo_caption(image, template), # '2010/05 Hello: y') #image = self.TestImage('20100000 Hello - 31', 'y') #self.assertEqual(iu.get_photo_caption(image, template), # '2010 Hello: y') image = self.TestImage('x', 'y') self.assertEqual('//', iu.get_photo_caption(image, '{yyyy}/{mm}/{dd}')) image.date = datetime.datetime(2010, 12, 26, 11, 33, 15) self.assertEqual('2010/12/26', iu.get_photo_caption(image, '{yyyy}/{mm}/{dd}')) image = self.TestImage('tttt', 'dddd') self.assertEqual('tttt: dddd', iu.get_photo_caption(image, '{title_description}')) image = self.TestImage('tttt', '') self.assertEqual('tttt', iu.get_photo_caption(image, '{title_description}')) # Bad template. self.assertEqual('{badfield}', iu.get_photo_caption(image, '{badfield}'))
def test_get_photo_caption(self): template = "-{title}-" image = self.TestImage("x", "y") self.assertEqual(iu.get_photo_caption(image, template), "-x-") template = "-{description}-" image = self.TestImage("x", "y") self.assertEqual(iu.get_photo_caption(image, template), "-y-") # template = "{dated_caption_description}" # image = self.TestImage('x', 'y') # self.assertEqual(iu.get_photo_caption(image, template), # 'x: y') # image = self.TestImage('x', '') # self.assertEqual(iu.get_photo_caption(image, template), # 'x') # image = self.TestImage('x', None) # self.assertEqual(iu.get_photo_caption(image, template), # 'x') # image = self.TestImage('20100510 Hello', 'y') # self.assertEqual(iu.get_photo_caption(image, template), # '2010/05/10 Hello: y') # image = self.TestImage('20100511 Hello - 31', 'y') # self.assertEqual(iu.get_photo_caption(image, template), # '2010/05/11 Hello: y') # image = self.TestImage('20100500 Hello - 31', 'y') # self.assertEqual(iu.get_photo_caption(image, template), # '2010/05 Hello: y') # image = self.TestImage('20100000 Hello - 31', 'y') # self.assertEqual(iu.get_photo_caption(image, template), # '2010 Hello: y') image = self.TestImage("x", "y") self.assertEqual("//", iu.get_photo_caption(image, "{yyyy}/{mm}/{dd}")) image.date = datetime.datetime(2010, 12, 26, 11, 33, 15) self.assertEqual("2010/12/26", iu.get_photo_caption(image, "{yyyy}/{mm}/{dd}")) image = self.TestImage("tttt", "dddd") self.assertEqual("tttt: dddd", iu.get_photo_caption(image, "{title_description}")) image = self.TestImage("tttt", "") self.assertEqual("tttt", iu.get_photo_caption(image, "{title_description}")) # Bad template. self.assertEqual("{badfield}", iu.get_photo_caption(image, "{badfield}"))
def check_iptc_data(self, export_file, options, is_original=False): """Tests if a file has the proper keywords and caption in the meta data.""" if not su.getfileextension(export_file) in ("jpg", "tif", "tiff", "png", "nef", "cr2"): return False (file_keywords, file_caption, date_time_original, rating, gps, region_rectangles, region_names) = exiftool.get_iptc_data(export_file) if options.aperture: # Aperture maintains all these metadata in the preview files, and # does not even save all the information into the .xml file. new_caption = None new_keywords = None new_date = None new_rating = -1 new_gps = None else: new_caption = imageutils.get_photo_caption(self.photo, options.captiontemplate) if not su.equalscontent(file_caption, new_caption): su.pout('Updating IPTC for %s because it has Caption "%s" ' 'instead of "%s".' % (export_file, file_caption, new_caption)) else: new_caption = None new_keywords = self.get_export_keywords(options.face_keywords) if not imageutils.compare_keywords(new_keywords, file_keywords): su.pout("Updating IPTC for %s because of keywords (%s instead " "of %s)" % (export_file, ",".join(file_keywords), ",".join(new_keywords))) else: new_keywords = None new_date = None if self.photo.date and date_time_original != self.photo.date: su.pout("Updating IPTC for %s because of date (%s instead of " "%s)" % (export_file, date_time_original, self.photo.date)) new_date = self.photo.date new_rating = -1 if self.photo.rating != None and rating != self.photo.rating: su.pout( "Updating IPTC for %s because of rating (%d instead of " "%d)" % (export_file, rating, self.photo.rating)) new_rating = self.photo.rating new_gps = None if options.gps and self.photo.gps: if (not gps or not self.photo.gps.is_same(gps)): if gps: old_gps = gps else: old_gps = imageutils.GpsLocation() su.pout("Updating IPTC for %s because of GPS %s vs %s" % (export_file, old_gps.to_string(), self.photo.gps.to_string())) new_gps = self.photo.gps # Don't export the faces into the original file (could have been # cropped). do_faces = options.faces and not is_original (new_rectangles, new_persons) = self._check_person_iptc_data(export_file, region_rectangles, region_names, do_faces) if (new_caption != None or new_keywords != None or new_date or new_gps or new_rating != -1 or new_rectangles or new_persons): if not options.dryrun: exiftool.update_iptcdata(export_file, new_caption, new_keywords, new_date, new_rating, new_gps, new_rectangles, new_persons) return True return False
def generate_update(self, client, options): """Attempts to update a photo. If the media file needs updating, deletes it first, then adds it back in. Args: client - the PicasaWeb client album_id - the id of the album for this photo """ # check albumFile self.picasa_photo = check_media_update(client, self.picasa_photo, self.photo, self.export_file, options) picasa_photo = self.picasa_photo # Now check if any of the meta data needs to be updated. needs_update = False picasa_title = su.unicode_string(picasa_photo.title.text) if self.title != picasa_title: print( 'Updating meta data for %s because it has Caption "%s" ' 'instead of "%s".') % (su.fsenc( self.export_file), su.fsenc(picasa_title), su.fsenc(self.title)) picasa_photo.title.text = self.title needs_update = True # Combine title and description because PicasaWeb does not show the # title anywhere. comment = imageutils.get_photo_caption(self.photo, options.captiontemplate) online_summary = su.unicode_string(picasa_photo.summary.text) if not su.equalscontent(comment, online_summary): print("Updating meta data for " + su.fsenc(self.export_file) + ' because it has description "' + su.fsenc(online_summary) + '" instead of "' + su.fsenc(comment) + '".') picasa_photo.summary.text = comment.strip() needs_update = True if self.photo.date: photo_time = get_picasaweb_date(self.photo.date) if photo_time != picasa_photo.timestamp.text: print( 'Updating meta data for %s because it has timestamp "' '%s" instead of "%s"') % (su.fsenc( self.export_file), picasa_photo.timestamp.datetime(), self.photo.date) picasa_photo.timestamp.text = photo_time needs_update = True export_keywords = self.get_export_keywords(options) picasa_keywords = [] if (picasa_photo.media and picasa_photo.media.keywords and picasa_photo.media.keywords.text): picasa_keywords = su.unicode_string( picasa_photo.media.keywords.text).split(', ') else: picasa_keywords = [] if not imageutils.compare_keywords(export_keywords, picasa_keywords): print("Updating meta data for " + su.fsenc(self.export_file) + " because of keywords (" + su.fsenc(",".join(picasa_keywords)) + ") instead of (" + su.fsenc(",".join(export_keywords)) + ").") if not picasa_photo.media: picasa_photo.media = gdata.media.Group() if not picasa_photo.media.keywords: picasa_photo.media.keywords = gdata.media.Keywords() picasa_photo.media.keywords.text = ', '.join(export_keywords) needs_update = True if options.gps and self.photo.gps: if picasa_photo.geo and picasa_photo.geo.Point: picasa_location = imageutils.GpsLocation().from_gdata_point( picasa_photo.geo.Point) else: picasa_location = imageutils.GpsLocation() if not picasa_location.is_same(self.photo.gps): print("Updating meta data for " + su.fsenc(self.export_file) + " because of GPS " + picasa_location.to_string() + " vs " + self.photo.gps.to_string()) set_picasa_photo_pos(picasa_photo, self.photo.gps) needs_update = True if not needs_update: return if not options.update: print "Needs update: " + su.fsenc(self.export_file) + "." print "Use the -u option to update this file." return print("Updating metadata: " + self.export_file) if options.dryrun: return retry = 0 wait_time = 1.0 while True: try: client.throttle() picasa_photo = client.gd_client.UpdatePhotoMetadata( picasa_photo) return except gdata.photos.service.GooglePhotosException, e: retry += 1 if retry == 10: raise e if str(e).find("17 REJECTED_USER_LIMIT") == -1: raise e wait_time = wait_time * 2 print("Retrying after " + wait_time + "s because of " + str(e)) time.sleep(wait_time)
def check_iptc_data(self, export_file, options, is_original=False, file_updated=False): """Tests if a file has the proper keywords and caption in the meta data.""" if not su.getfileextension(export_file) in _EXIF_EXTENSIONS: return False messages = [] iptc_data = exiftool.get_iptc_data(export_file) new_caption = imageutils.get_photo_caption(self.photo, self.container, options.captiontemplate) if not su.equalscontent(iptc_data.caption, new_caption): messages.append(u' File caption: %s' % (su.nn_string(iptc_data.caption).strip())) messages.append(u' iPhoto caption: %s' % (new_caption)) else: new_caption = None new_keywords = None new_date = None new_rating = -1 new_keywords = self.get_export_keywords(options.face_keywords) if not imageutils.compare_keywords(new_keywords, iptc_data.keywords): messages.append(u' File keywords: %s' % (u','.join(iptc_data.keywords))) if new_keywords == None: messages.append(u' iPhoto keywords: <None>') else: messages.append(u' iPhoto keywords: %s' % (u','.join(new_keywords))) else: new_keywords = None if not options.aperture: #if self.photo.date and date_time_original != self.photo.date: # messages.append(u' File date: %s' % (date_time_original)) # messages.append(u' iPhoto date: %s' % (self.photo.date)) # new_date = self.photo.date if self.photo.rating != None and iptc_data.rating != self.photo.rating: messages.append(u' File rating: %d' % (iptc_data.rating)) messages.append(u' iPhoto rating: %d' % (self.photo.rating)) new_rating = self.photo.rating else: if options.face_keywords: merged_keywords = iptc_data.keywords[:] for keyword in self.photo.getfaces(): if not keyword in merged_keywords: merged_keywords.append(keyword) new_keywords = merged_keywords if iptc_data.hierarchical_subject and not options.reverse: messages.append(u' File subjects: %s' % (u','.join(iptc_data.hierarchical_subject))) new_gps = None if options.gps and self.photo.gps: if (not iptc_data.gps or not self.photo.gps.is_same(iptc_data.gps)): if iptc_data.gps: old_gps = iptc_data.gps else: old_gps = imageutils.GpsLocation() messages.append(u' File GPS: %s' % (old_gps.to_string())) messages.append(u' iPhoto GPS: %s' % (self.photo.gps.to_string())) new_gps = self.photo.gps # Don't export the faces into the original file (could have been # cropped). do_faces = options.faces and not is_original (new_rectangles, new_persons) = self._check_person_iptc_data( export_file, iptc_data.region_rectangles, iptc_data.region_names, do_faces, messages) if (new_caption != None or new_keywords != None or new_date or (not options.reverse and iptc_data.hierarchical_subject) or new_gps or new_rating != -1 or new_rectangles != None or new_persons != None): su.pout(u'Updating IPTC for %s because of\n%s' % (export_file, u'\n'.join(messages))) if (file_updated or imageutils.should_update(options)) and not options.dryrun: exiftool.update_iptcdata(export_file, new_caption, new_keywords, new_date, new_rating, new_gps, new_rectangles, new_persons, iptc_data.image_width, iptc_data.image_height, hierarchical_subject=[]) return True return False
def check_iptc_data(self, export_file, options, is_original=False): """Tests if a file has the proper keywords and caption in the meta data.""" if not su.getfileextension(export_file) in ("jpg", "tif", "tiff", "png", "nef", "cr2"): return False (file_keywords, file_caption, date_time_original, rating, gps, region_rectangles, region_names) = exiftool.get_iptc_data( export_file) if options.aperture: # Aperture maintains all these metadata in the preview files, and # does not even save all the information into the .xml file. new_caption = None new_keywords = None new_date = None new_rating = -1 new_gps = None else: new_caption = imageutils.get_photo_caption(self.photo, options.captiontemplate) if not su.equalscontent(file_caption, new_caption): su.pout('Updating IPTC for %s because it has Caption "%s" ' 'instead of "%s".' % (export_file, file_caption, new_caption)) else: new_caption = None new_keywords = self.get_export_keywords(options.face_keywords) if not imageutils.compare_keywords(new_keywords, file_keywords): su.pout("Updating IPTC for %s because of keywords (%s instead " "of %s)" % (export_file, ",".join(file_keywords), ",".join(new_keywords))) else: new_keywords = None new_date = None if self.photo.date and date_time_original != self.photo.date: su.pout("Updating IPTC for %s because of date (%s instead of " "%s)" % (export_file, date_time_original, self.photo.date)) new_date = self.photo.date new_rating = -1 if self.photo.rating != None and rating != self.photo.rating: su.pout("Updating IPTC for %s because of rating (%d instead of " "%d)" % (export_file, rating, self.photo.rating)) new_rating = self.photo.rating new_gps = None if options.gps and self.photo.gps: if (not gps or not self.photo.gps.is_same(gps)): if gps: old_gps = gps else: old_gps = imageutils.GpsLocation() su.pout("Updating IPTC for %s because of GPS %s vs %s" % (export_file, old_gps.to_string(), self.photo.gps.to_string())) new_gps = self.photo.gps # Don't export the faces into the original file (could have been # cropped). do_faces = options.faces and not is_original (new_rectangles, new_persons) = self._check_person_iptc_data( export_file, region_rectangles, region_names, do_faces) if (new_caption != None or new_keywords != None or new_date or new_gps or new_rating != -1 or new_rectangles or new_persons): if not options.dryrun: exiftool.update_iptcdata(export_file, new_caption, new_keywords, new_date, new_rating, new_gps, new_rectangles, new_persons) return True return False
def generate_update(self, client, options): """Attempts to update a photo. If the media file needs updating, deletes it first, then adds it back in. Args: client - the PicasaWeb client album_id - the id of the album for this photo """ # check albumFile self.picasa_photo = check_media_update(client, self.picasa_photo, self.photo, self.export_file, options) picasa_photo = self.picasa_photo # Now check if any of the meta data needs to be updated. needs_update = False picasa_title = su.unicode_string(picasa_photo.title.text) if self.title != picasa_title: print ('Updating meta data for %s because it has Caption "%s" ' 'instead of "%s".') % ( su.fsenc(self.export_file), su.fsenc(picasa_title), su.fsenc(self.title), ) picasa_photo.title.text = self.title needs_update = True # Combine title and description because PicasaWeb does not show the # title anywhere. comment = imageutils.get_photo_caption(self.photo, options.captiontemplate) online_summary = su.unicode_string(picasa_photo.summary.text) if not su.equalscontent(comment, online_summary): print ( "Updating meta data for " + su.fsenc(self.export_file) + ' because it has description "' + su.fsenc(online_summary) + '" instead of "' + su.fsenc(comment) + '".' ) picasa_photo.summary.text = comment.strip() needs_update = True if self.photo.date: photo_time = get_picasaweb_date(self.photo.date) if photo_time != picasa_photo.timestamp.text: print ('Updating meta data for %s because it has timestamp "' '%s" instead of "%s"') % ( su.fsenc(self.export_file), picasa_photo.timestamp.datetime(), self.photo.date, ) picasa_photo.timestamp.text = photo_time needs_update = True export_keywords = self.get_export_keywords(options) picasa_keywords = [] if picasa_photo.media and picasa_photo.media.keywords and picasa_photo.media.keywords.text: picasa_keywords = su.unicode_string(picasa_photo.media.keywords.text).split(", ") else: picasa_keywords = [] if not imageutils.compare_keywords(export_keywords, picasa_keywords): print ( "Updating meta data for " + su.fsenc(self.export_file) + " because of keywords (" + su.fsenc(",".join(picasa_keywords)) + ") instead of (" + su.fsenc(",".join(export_keywords)) + ")." ) if not picasa_photo.media: picasa_photo.media = gdata.media.Group() if not picasa_photo.media.keywords: picasa_photo.media.keywords = gdata.media.Keywords() picasa_photo.media.keywords.text = ", ".join(export_keywords) needs_update = True if options.gps and self.photo.gps: if picasa_photo.geo and picasa_photo.geo.Point: picasa_location = imageutils.GpsLocation().from_gdata_point(picasa_photo.geo.Point) else: picasa_location = imageutils.GpsLocation() if not picasa_location.is_same(self.photo.gps): print ( "Updating meta data for " + su.fsenc(self.export_file) + " because of GPS " + picasa_location.to_string() + " vs " + self.photo.gps.to_string() ) set_picasa_photo_pos(picasa_photo, self.photo.gps) needs_update = True if not needs_update: return if not options.update: print "Needs update: " + su.fsenc(self.export_file) + "." print "Use the -u option to update this file." return print ("Updating metadata: " + self.export_file) if options.dryrun: return retry = 0 wait_time = 1.0 while True: try: client.throttle() picasa_photo = client.gd_client.UpdatePhotoMetadata(picasa_photo) return except gdata.photos.service.GooglePhotosException, e: retry += 1 if retry == 10: raise e if str(e).find("17 REJECTED_USER_LIMIT") == -1: raise e wait_time = wait_time * 2 print ("Retrying after " + wait_time + "s because of " + str(e)) time.sleep(wait_time)
def check_iptc_data(self, export_file, options, is_original=False, file_updated=False): """Tests if a file has the proper keywords and caption in the meta data.""" if not su.getfileextension(export_file) in _EXIF_EXTENSIONS: return False messages = [] iptc_data = exiftool.get_iptc_data(export_file) new_caption = imageutils.get_photo_caption(self.photo, self.container, options.captiontemplate) if not su.equalscontent(iptc_data.caption, new_caption): messages.append(u' File caption: %s' % (su.nn_string(iptc_data.caption).strip())) messages.append(u' iPhoto caption: %s' % (new_caption)) else: new_caption = None new_keywords = None new_date = None new_rating = -1 new_keywords = self.get_export_keywords(options.face_keywords) if not imageutils.compare_keywords(new_keywords, iptc_data.keywords): messages.append(u' File keywords: %s' % (u','.join(iptc_data.keywords))) if new_keywords == None: messages.append(u' iPhoto keywords: <None>') else: messages.append(u' iPhoto keywords: %s' % (u','.join(new_keywords))) else: new_keywords = None if not options.aperture: #if self.photo.date and date_time_original != self.photo.date: # messages.append(u' File date: %s' % (date_time_original)) # messages.append(u' iPhoto date: %s' % (self.photo.date)) # new_date = self.photo.date if self.photo.rating != None and iptc_data.rating != self.photo.rating: messages.append(u' File rating: %d' % (iptc_data.rating)) messages.append(u' iPhoto rating: %d' % (self.photo.rating)) new_rating = self.photo.rating else: if options.face_keywords: merged_keywords = iptc_data.keywords[:] for keyword in self.photo.getfaces(): if not keyword in merged_keywords: merged_keywords.append(keyword) new_keywords = merged_keywords if iptc_data.hierarchical_subject and not options.reverse: messages.append(u' File subjects: %s' % (u','.join(iptc_data.hierarchical_subject))) new_gps = None if options.gps and self.photo.gps: if (not iptc_data.gps or not self.photo.gps.is_same(iptc_data.gps)): if iptc_data.gps: old_gps = iptc_data.gps else: old_gps = imageutils.GpsLocation() messages.append(u' File GPS: %s' % (old_gps.to_string())) messages.append(u' iPhoto GPS: %s' % (self.photo.gps.to_string())) new_gps = self.photo.gps # Don't export the faces into the original file (could have been # cropped). do_faces = options.faces and not is_original (new_rectangles, new_persons) = self._check_person_iptc_data( export_file, iptc_data.region_rectangles, iptc_data.region_names, do_faces, messages) if (new_caption != None or new_keywords != None or new_date or (not options.reverse and iptc_data.hierarchical_subject) or new_gps or new_rating != -1 or new_rectangles != None or new_persons != None): su.pout(u'Updating IPTC for %s because of\n%s' % (export_file, u'\n'.join(messages))) if (file_updated or imageutils.should_update(options)) and not options.dryrun: exiftool.update_iptcdata(export_file, new_caption, new_keywords, new_date, new_rating, new_gps, new_rectangles, new_persons, iptc_data.image_width, iptc_data.image_height, hierarchical_subject=[]) return True return False