Пример #1
0
    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")))
Пример #2
0
    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")))
Пример #3
0
    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
Пример #4
0
    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())]
Пример #5
0
    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())
                ]
Пример #6
0
    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