示例#1
0
    def scan_originals(self, folder, options):
        """Scan a folder of Original images, and delete obsolete ones."""
        file_list = os.listdir(folder)
        if not file_list:
            return

        for f in file_list:
            # We won't touch some files.
            if imageutils.is_ignore(f):
                continue

            originalfile = unicodedata.normalize("NFC", os.path.join(folder, f))
            if os.path.isdir(originalfile):
                delete_album_file(originalfile, self.albumdirectory,
                                  "Obsolete export Originals directory",
                                  options)
                continue

            base_name = unicodedata.normalize("NFC",
                                              su.getfilebasename(originalfile))
            master_file = self.files.get(base_name.lower())

            # everything else must have a master, or will have to go
            if (not master_file or
                originalfile != master_file.original_export_file or
                master_file.photo.rotation_is_only_edit):
                delete_album_file(originalfile, originalfile,
                                  "Obsolete Original", options)
示例#2
0
    def scan_originals(self, folder, options):
        """Scan a folder of Original images, and delete obsolete ones."""
        file_list = os.listdir(folder)
        if not file_list:
            return

        for f in file_list:
            # We won't touch some files.
            if imageutils.is_ignore(f):
                continue

            originalfile = unicodedata.normalize("NFC",
                                                 os.path.join(folder, f))
            if os.path.isdir(originalfile):
                delete_album_file(originalfile, self.albumdirectory,
                                  "Obsolete export Originals directory",
                                  options)
                continue

            base_name = unicodedata.normalize("NFC",
                                              su.getfilebasename(originalfile))
            master_file = self.files.get(base_name)

            # everything else must have a master, or will have to go
            if (not master_file
                    or originalfile != master_file.original_export_file
                    or master_file.photo.rotation_is_only_edit):
                delete_album_file(originalfile, originalfile,
                                  "Obsolete Original", options)
示例#3
0
 def find_aperture_original(self):
     """Attempts to locate the Aperture Master image. Works only for .jpg
        masters that are stored in the Aperture library. Saves the result as
        originalpath."""
     master_path = _get_aperture_master_path(self.image_path)
     if not os.path.exists(master_path):
         return
     basename = su.getfilebasename(self.image_path)
     file_name = os.path.join(master_path, basename + '.jpg')
     if os.path.exists(file_name):
         self.originalpath = file_name
         return
     path = self._search_for_file(master_path, basename + '.')
     if path:
         self.originalpath = path
         return
     su.pout(u"No master for %s" % (self.image_path))
示例#4
0
 def find_aperture_original(self):
     """Attempts to locate the Aperture Master image. Works only for .jpg
        masters that are stored in the Aperture library. Saves the result as
        originalpath."""
     master_path = _get_aperture_master_path(self.image_path)
     if not os.path.exists(master_path):
         return
     basename = su.getfilebasename(self.image_path)
     file_name = os.path.join(master_path, basename + '.jpg')
     if os.path.exists(file_name):
         self.originalpath = file_name
         return
     path = self._search_for_file(master_path, basename + '.')
     if path:
         self.originalpath = path
         return
     su.pout(u"No master for %s" % (self.image_path))
示例#5
0
    def load_album(self, options):
        """walks the album directory tree, and scans it for existing files."""
        if not os.path.exists(self.albumdirectory):
            su.pout("Creating folder " + self.albumdirectory)
            if not options.dryrun:
                os.makedirs(self.albumdirectory)
            else:
                return
        file_list = os.listdir(self.albumdirectory)
        if file_list is None:
            return

        for f in sorted(file_list):
            # we won't touch some files
            if imageutils.is_ignore(f):
                continue

            album_file = unicodedata.normalize("NFC",
                                               os.path.join(self.albumdirectory,
                                                            f))
            if os.path.isdir(album_file):
                if (options.originals and
                    (f == "Originals" or (options.picasa and
                                          f == ".picasaoriginals"))):
                    self.scan_originals(album_file, options)
                    continue
                else:
                    delete_album_file(album_file, self.albumdirectory,
                                      "Obsolete export directory", options)
                    continue

            base_name = unicodedata.normalize("NFC",
                                              su.getfilebasename(album_file))
            master_file = self.files.get(base_name.lower())

            # everything else must have a master, or will have to go
            if master_file is None or not master_file.is_part_of(album_file):
                delete_album_file(album_file, self.albumdirectory,
                                  "Obsolete exported file", options)
示例#6
0
    def load_album(self, options):
        """walks the album directory tree, and scans it for existing files."""
        if not os.path.exists(self.albumdirectory):
            su.pout("Creating folder " + self.albumdirectory)
            if not options.dryrun:
                os.makedirs(self.albumdirectory)
            else:
                return
        file_list = os.listdir(self.albumdirectory)
        if file_list is None:
            return

        for f in sorted(file_list):
            # we won't touch some files
            if imageutils.is_ignore(f):
                continue

            album_file = unicodedata.normalize("NFC",
                                               os.path.join(self.albumdirectory,
                                                            f))
            if os.path.isdir(album_file):
                if (options.originals and
                    (f == "Originals" or (options.picasa and
                                          f == ".picasaoriginals"))):
                    self.scan_originals(album_file, options)
                    continue
                else:
                    delete_album_file(album_file, self.albumdirectory,
                                      "Obsolete export directory", options)
                    continue

            base_name = unicodedata.normalize("NFC",
                                              su.getfilebasename(album_file))
            master_file = self.files.get(base_name.lower())

            # everything else must have a master, or will have to go
            if master_file is None or not master_file.is_part_of(album_file):
                delete_album_file(album_file, self.albumdirectory,
                                  "Obsolete exported file", options)
示例#7
0
class PicasaAlbum(object):
    """Tracks an album folder in the export location."""
    def __init__(self, name, iphoto_container):
        self.name = name
        self.iphoto_container = iphoto_container
        self.files = {}  # name -> PicasaFile
        self.online_album = None
        self.image_suffix = re.compile(
            r'\.(jpeg|jpg|mpg|mpeg|mov|png|tif|tiff)$', re.IGNORECASE)

    def add_iphoto_images(self, images, options):
        """Works through an image folder tree, and builds data for exporting."""
        entries = 0
        template = options.nametemplate

        if images is not None:
            entry_digits = len(str(len(images)))
            for image in images:
                if image.ismovie() and not options.movies:
                    continue
                if _NOUPLOAD_KEYWORD in image.keywords:
                    continue
                entries += 1
                image_basename = self.make_album_basename(
                    image, entries,
                    str(entries).zfill(entry_digits), template)
                picture_file = PicasaFile(image, self.name, image_basename,
                                          options)
                self.files[image_basename] = picture_file
        return len(self.files)

    def make_album_basename(self, photo, index, padded_index, name_template):
        """creates unique file name."""
        base_name = imageutils.format_photo_name(photo,
                                                 self.iphoto_container.name,
                                                 index, padded_index,
                                                 name_template)
        index = 0
        while True:
            album_basename = base_name
            if index > 0:
                album_basename += "_%d" % (index)
            if self.files.get(album_basename) is None:
                return album_basename
            index += 1
        return base_name

    def load_album(self, client, online_albums, options):
        """Walks the album directory tree, and scans it for existing files."""

        if options.verbose:
            print 'Reading online album ' + self.name
        comments = self.iphoto_container.getcommentwithouthints().strip()
        timestamp = get_picasaweb_date(self.iphoto_container.date)
        self.online_album = online_albums.get(self.name)
        if not self.online_album:
            print "Creating album: " + su.fsenc(self.name)
            if not options.dryrun:
                client.throttle()
                self.online_album = client.gd_client.InsertAlbum(
                    title=self.name,
                    summary=comments,
                    access='private',
                    timestamp=timestamp)
                online_albums[self.name] = self.online_album
            return

        # Check the properties of the online album
        changed = False
        online_album_summary_text = su.unicode_string(
            self.online_album.summary.text)
        if online_album_summary_text != comments:
            print 'Updating summary for online album %s (%s vs. %s)' % (
                su.fsenc(self.name), su.fsenc(online_album_summary_text),
                su.fsenc(comments))
            self.online_album.summary.text = comments
            changed = True

        if (timestamp and timestamp != self.online_album.timestamp.text):
            print 'Updating timestamp for online album %s (%s/%s)' % (
                su.fsenc(self.name), self.online_album.timestamp.datetime(),
                self.iphoto_container.date)
            self.online_album.timestamp.text = timestamp
            changed = True

        if changed and not options.dryrun:
            client.throttle()
            try:
                self.online_album = client.gd_client.Put(
                    self.online_album,
                    self.online_album.GetEditLink().href,
                    converter=gdata.photos.AlbumEntryFromString)
            except gdata.photos.service.GooglePhotosException, e:
                print 'Failed to update data for online album %s: %s' % (
                    self.name, str(e))

        # Check the pictures in the online album
        try:
            photos = client.gd_client.GetFeed(
                '/data/feed/api/user/%s/albumid/%s?kind=photo' %
                ('default', self.online_album.gphoto_id.text))
            for photo in photos.entry:
                # we won't touch some files
                if imageutils.is_ignore(photo.title.text):
                    continue

                photo_name = su.unicode_string(photo.title.text)
                base_name = su.getfilebasename(photo_name)
                master_file = self.files.get(base_name)

                # everything else must have a master, or will have to go
                if master_file is None:
                    delete_online_photo(client, photo, self.name,
                                        "Obsolete online photo", options)
                elif master_file.picasa_photo:
                    delete_online_photo(client, photo, self.name,
                                        "Duplicate online photo", options)
                else:
                    master_file.picasa_photo = photo
        except gdata.photos.service.GooglePhotosException, e:
            print 'Failed to load pictures for online album %s: %s' % (
                self.name, str(e))
示例#8
0
 def getbasename(self):
     """Returns the base name of the main image file."""
     return su.getfilebasename(self.image_path)
示例#9
0
 def getbasename(self):
     """Returns the base name of the main image file."""
     return su.getfilebasename(self.image_path)