Beispiel #1
0
    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))
Beispiel #2
0
    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)
        )
Beispiel #3
0
    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))
Beispiel #4
0
 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))
Beispiel #5
0
    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}"))
Beispiel #7
0
    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
Beispiel #8
0
    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)
Beispiel #9
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
Beispiel #10
0
    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
Beispiel #11
0
    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)
Beispiel #12
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