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)
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)
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))
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)
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))
def getbasename(self): """Returns the base name of the main image file.""" return su.getfilebasename(self.image_path)