def __init__(self, data, keyword_map, face_map, key): self.data = data self.key = key self._caption = sysutils.nn_string(data.get("Caption")).strip() self.comment = sysutils.nn_string(data.get("Comment")).strip() if data.has_key("DateAsTimerInterval"): self.date = applexml.getappletime(data.get("DateAsTimerInterval")) else: self.date = None self.mod_date = applexml.getappletime( data.get("ModDateAsTimerInterval")) self.image_path = data.get("ImagePath") if data.has_key("Rating"): self.rating = int(data.get("Rating")) else: self.rating = None if data.get("longitude"): latitude = float(data.get("latitude")) longitude = float(data.get("longitude")) self.gps = imageutils.GpsLocation(latitude, longitude) else: self.gps = None self.keywords = [] keyword_list = data.get("Keywords") if keyword_list is not None: for i in keyword_list: self.keywords.append(keyword_map.get(i)) self.originalpath = data.get("OriginalPath") self.roll = data.get("Roll") self.albums = [] # list of albums that this image belongs to self.faces = [] self.face_rectangles = [] self.event_name = '' # name of event (roll) that this image belongs to self.event_index = '' # index within event self.event_index0 = '' # index with event, left padded with 0 face_list = data.get("Faces") if face_list: for face_entry in face_list: face_key = face_entry.get("face key") face_name = face_map.get(face_key) if face_name: self.faces.append(face_name) # Rectangle is '{{x, y}, {width, height}}' as ratios, # referencing the lower left corner of the face rectangle. self.face_rectangles.append(parse_face_rectangle( face_entry.get("rectangle")))
def __init__(self, data, keyword_map, face_map): self.data = data self._caption = sysutils.nn_string(data.get("Caption")).strip() self.comment = sysutils.nn_string(data.get("Comment")).strip() if data.has_key("DateAsTimerInterval"): self.date = applexml.getappletime(data.get("DateAsTimerInterval")) else: self.date = None self.mod_date = applexml.getappletime( data.get("ModDateAsTimerInterval")) self.image_path = data.get("ImagePath") if data.has_key("Rating"): self.rating = int(data.get("Rating")) else: self.rating = None if data.get("longitude"): latitude = float(data.get("latitude")) longitude = float(data.get("longitude")) self.gps = imageutils.GpsLocation(latitude, longitude) else: self.gps = None self.keywords = [] keyword_list = data.get("Keywords") if keyword_list is not None: for i in keyword_list: self.keywords.append(keyword_map.get(i)) self.originalpath = data.get("OriginalPath") self.roll = data.get("Roll") self.albums = [] # list of albums that this image belongs to self.faces = [] self.face_rectangles = [] self.event_name = '' # name of event (roll) that this image belongs to self.event_index = '' # index within event self.event_index0 = '' # index with event, left padded with 0 face_list = data.get("Faces") if face_list: for face_entry in face_list: face_key = face_entry.get("face key") face_name = face_map.get(face_key) if face_name: self.faces.append(face_name) # Rectangle is '{{x, y}, {width, height}}' as ratios, # referencing the lower left corner of the face rectangle. self.face_rectangles.append( parse_face_rectangle(face_entry.get("rectangle")))
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 __init__(self, key, data, keyword_map, face_map, aperture_data): self.id = key self.data = data self._caption = su.nn_string(data.get("Caption")).strip() self.comment = su.nn_string(data.get("Comment")).strip() version = None if aperture_data: version = aperture_data.versions.get(key) if data.has_key("DateAsTimerInterval"): self.date = applexml.getappletime(data.get("DateAsTimerInterval")) elif version: self.date = version.image_date else: # Try to get the date from a the caption in "YYYYMMDD ..." format m = re.match(_CAPTION_PATTERN, self._caption) if m: year = int(m.group(1)) month = int(m.group(2)) if not month: month = 1 date = int(m.group(3)) if not date: date = 1 self.date = datetime.datetime(year, month, date) else: self.date = None self.mod_date = applexml.getappletime( data.get("ModDateAsTimerInterval")) self.image_path = data.get("ImagePath") if data.has_key("Rating"): self.rating = int(data.get("Rating")) elif version: self.rating = version.mainRating else: self.rating = None if data.get("longitude"): latitude = float(data.get("latitude")) longitude = float(data.get("longitude")) self.gps = imageutils.GpsLocation(latitude, longitude) elif version: self.gps = version.location else: self.gps = None self.keywords = [] keyword_list = data.get("Keywords") if keyword_list is not None: for i in keyword_list: self.keywords.append(keyword_map.get(i)) elif version: self.keywords = version.keywords if version: self.originalpath = None # This is just a placeholder... # Use the preview if there are adjustments. if (version.rotation or version.hasAdjustments or not su.getfileextension(version.master_image_path) in _JPG_EXTENSIONS): #if version.rotation: # su.pout(u"Rotated: %s (%d)" % (self._caption, version.rotation)) #if version.hasAdjustments: # su.pout(u"Adjustments: %s" % (self._caption)) #if not su.getfileextension(version.master_image_path) in _JPG_EXTENSIONS: # su.pout(u"Not JPEG: %s" % (self._caption)) self.originalpath = version.master_image_path if not version.imageProxy.fullSizePreviewPath: su.pout(u"No preview path for %s." % (self.caption)) else: self.image_path = version.imageProxy.fullSizePreviewPath else: self.image_path = version.master_image_path self.originalpath = None if not version.imageProxy.fullSizePreviewUpToDate: su.pout(u"%s: full size preview not up to date." % (self.caption)) else: self.originalpath = data.get("OriginalPath") self.roll = data.get("Roll") self.albums = [] # list of albums that this image belongs to self.faces = [] self.face_rectangles = [] self.event_name = '' # name of event (roll) that this image belongs to self.event_index = '' # index within event self.event_index0 = '' # index with event, left padded with 0 face_list = data.get("Faces") if face_list: for face_entry in face_list: face_key = face_entry.get("face key") face_name = face_map.get(face_key) if face_name: self.faces.append(face_name) # Rectangle is '{{x, y}, {width, height}}' as ratios, # referencing the lower left corner of the face rectangle, # with lower left corner of image as (0,0) rectangle = parse_face_rectangle(face_entry.get("rectangle")) # Convert to using center of area, relative to upper left corner of image rectangle[0] += rectangle[2] / 2.0 rectangle[1] = max(0.0, 1.0 - rectangle[1] - rectangle[3] / 2.0) self.face_rectangles.append(rectangle) # Other keys in face_entry: face index # Now sort the faces left to right. sorted_names = {} sorted_rectangles = {} for i in xrange(len(self.faces)): x = self.face_rectangles[i][0] while sorted_names.has_key(x): x += 0.00001 sorted_names[x] = self.faces[i] sorted_rectangles[x] = self.face_rectangles[i] self.faces = [sorted_names[x] for x in sorted(sorted_names.keys())] self.face_rectangles = [ sorted_rectangles[x] for x in sorted(sorted_rectangles.keys())]
def __init__(self, key, data, keyword_map, face_map, aperture_data): self.id = key self.data = data self._caption = su.nn_string(data.get("Caption")).strip() self.comment = su.nn_string(data.get("Comment")).strip() version = None if aperture_data: version = aperture_data.versions.get(key) if data.has_key("DateAsTimerInterval"): self.date = applexml.getappletime(data.get("DateAsTimerInterval")) elif version: self.date = version.image_date else: # Try to get the date from a the caption in "YYYYMMDD ..." format m = re.match(_CAPTION_PATTERN, self._caption) if m: year = int(m.group(1)) month = int(m.group(2)) if not month: month = 1 date = int(m.group(3)) if not date: date = 1 self.date = datetime.datetime(year, month, date) else: self.date = None self.mod_date = applexml.getappletime( data.get("ModDateAsTimerInterval")) self.image_path = data.get("ImagePath") if data.has_key("Rating"): self.rating = int(data.get("Rating")) elif version: self.rating = version.mainRating else: self.rating = None if data.get("longitude"): latitude = float(data.get("latitude")) longitude = float(data.get("longitude")) self.gps = imageutils.GpsLocation(latitude, longitude) elif version: self.gps = version.location else: self.gps = None self.keywords = [] keyword_list = data.get("Keywords") if keyword_list is not None: for i in keyword_list: self.keywords.append(keyword_map.get(i)) elif version: self.keywords = version.keywords if version: self.originalpath = None # This is just a placeholder... # Use the preview if there are adjustments. if (version.rotation or version.hasAdjustments or not su.getfileextension( version.master_image_path) in _JPG_EXTENSIONS): #if version.rotation: # su.pout(u"Rotated: %s (%d)" % (self._caption, version.rotation)) #if version.hasAdjustments: # su.pout(u"Adjustments: %s" % (self._caption)) #if not su.getfileextension(version.master_image_path) in _JPG_EXTENSIONS: # su.pout(u"Not JPEG: %s" % (self._caption)) self.originalpath = version.master_image_path if not version.imageProxy.fullSizePreviewPath: su.pout(u"No preview path for %s." % (self.caption)) else: self.image_path = version.imageProxy.fullSizePreviewPath else: self.image_path = version.master_image_path self.originalpath = None if not version.imageProxy.fullSizePreviewUpToDate: su.pout(u"%s: full size preview not up to date." % (self.caption)) else: self.originalpath = data.get("OriginalPath") self.roll = data.get("Roll") self.albums = [] # list of albums that this image belongs to self.faces = [] self.face_rectangles = [] self.event_name = '' # name of event (roll) that this image belongs to self.event_index = '' # index within event self.event_index0 = '' # index with event, left padded with 0 face_list = data.get("Faces") if face_list: for face_entry in face_list: face_key = face_entry.get("face key") face_name = face_map.get(face_key) if face_name: self.faces.append(face_name) # Rectangle is '{{x, y}, {width, height}}' as ratios, # referencing the lower left corner of the face rectangle, # with lower left corner of image as (0,0) rectangle = parse_face_rectangle( face_entry.get("rectangle")) # Convert to using center of area, relative to upper left corner of image rectangle[0] += rectangle[2] / 2.0 rectangle[1] = max(0.0, 1.0 - rectangle[1] - rectangle[3] / 2.0) self.face_rectangles.append(rectangle) # Other keys in face_entry: face index # Now sort the faces left to right. sorted_names = {} sorted_rectangles = {} for i in xrange(len(self.faces)): x = self.face_rectangles[i][0] while sorted_names.has_key(x): x += 0.00001 sorted_names[x] = self.faces[i] sorted_rectangles[x] = self.face_rectangles[i] self.faces = [ sorted_names[x] for x in sorted(sorted_names.keys()) ] self.face_rectangles = [ sorted_rectangles[x] for x in sorted(sorted_rectangles.keys()) ]