Exemplo n.º 1
0
class SaveThumbnails(object):
    def __init__(self, path, photos_path, tmp_db):
        self.path = os.path.abspath(path)
        self.photos_path = photos_path

        db_path = os.path.join(photos_path, "database")
        self.library = Library(db_path, tmp_db)

        self.photos = dict()

    def build(self):
        logger.debug("Fetch photos")
        self.photos = dict((p.id, p) for p in self.library.fetch_photos())

        logger.debug("Save folders and albums")
        self.save_folder(self.library.top_folder, None)

    def save_folder(self, folder, parent_path):
        logger.debug("Save %s with parent %s", folder, parent_path)
        path = os.path.join(parent_path, folder.name) if folder != self.library.top_folder else "."
        logger.debug("Create directory %s", path)
        if not os.path.exists(os.path.join(self.path, path)):
            os.makedirs(os.path.join(self.path, path))
        for sub_folder in self.library.fetch_subfolders(folder):
            self.save_folder(sub_folder, path)
        for album in self.library.fetch_albums(folder):
            self.save_album(album, path)

    def save_album(self, album, parent_path):
        logger.debug("Save %s with parent %s", album, parent_path)
        path = os.path.join(parent_path, album.name)
        logger.debug("Create directory %s", path)
        if not os.path.exists(os.path.join(self.path, path)):
            os.makedirs(os.path.join(self.path, path))
        photos = set(self.photos[i] for i in self.library.fetch_album_photo_id_list(album))
        for photo in sorted(photos, key=lambda  p: p.date):
            self.save_photo(photo, path)

    def save_photo(self, photo, parent_path):
        caption = photo.name or "Photo_%d" % photo.id
        file_name = photo.thumbnails["hd"] or photo.thumbnails["mini"] or photo.original
        src = os.path.join(self.photos_path, file_name)
        ext = os.path.splitext(src)[1]
        dst = os.path.join(self.path, parent_path, caption + ext)
        logger.debug("Copy %s to %s", src, dst)
        shutil.copy(src, dst)
Exemplo n.º 2
0
class AlbumData(object):
    def __init__(self, path, disable_rolls=None, disable_rating=None, tmp_db=None, gen_caption=None):
        self.path = os.path.abspath(path)

        db_path = os.path.join(path, "database")
        self.library = Library(db_path, tmp_db)

        self.data = copy.deepcopy(BASE)
        self.data[ARCHIVE_PATH] = self.path
        self.data[ALBUMS] = []

        self.photos = dict()

        self.disable_rolls = disable_rolls
        self.disable_rating = disable_rating
        self.all_roll_id = 5

        self.generate_caption = gen_caption

    def build(self):
        logger.debug("Fetch photos")
        self.photos = dict((p.id, p) for p in self.library.fetch_photos())

        logger.debug("Save folders and albums")
        self.data[ALBUMS] += [self._all_photos_album, self._flagged_album]
        self.save_folder(self.library.top_folder, None)

        logger.debug("Save rolls")
        if not self.disable_rolls:
            self.data["List of Rolls"] = [self._all_roll]

        logger.debug("Save images")
        self.data[IMAGES] = dict((str(p.id), self._photo(p)) for p in self.photos.values())

    def save_folder(self, folder, parent):
        logger.debug("Save %s with parent %s", folder, parent)
        photo_ids = set()
        if folder != self.library.top_folder:
            data = self._album_base(folder, [], parent=parent)
            self.data[ALBUMS].append(data)
        parent = folder if folder != self.library.top_folder else None
        for sub_folder in self.library.fetch_subfolders(folder):
            photo_ids |= self.save_folder(sub_folder, parent)
        for album in self.library.fetch_albums(folder):
            photo_ids |= self.save_album(album, parent)
        if folder != self.library.top_folder:
            self._append_photos(data, photo_ids)
        logger.debug("Got %s photos for %s", len(photo_ids), folder)
        return photo_ids

    def save_album(self, album, parent):
        logger.debug("Save %s with parent %s", album, parent)
        photo_ids = set(self.library.fetch_album_photo_id_list(album))
        self.data[ALBUMS].append(self._album_base(album, photo_ids, parent=parent))
        return photo_ids

    def walk_through_tree(self, folder):
        logger.info("Process %s", folder)
        for album in self.library.fetch_albums(folder):
            logger.info("Write %s", album)

        for folder in self.library.fetch_subfolders(folder):
            self.walk_through_tree(folder)

    @property
    def _all_photos_album(self):
        album = self.library.all_photos_album
        photo_ids = self.photos.keys()
        data = self._album_base(album, photo_ids, album_type="99", name="Photos")
        data["Master"] = True
        return data

    @property
    def _flagged_album(self):
        album = self.library.favorites
        photo_ids = list(str(p.id) for p in self.photos.values() if p.is_favorite)
        return self._album_base(album, photo_ids, album_type="Flagged", name="Flagged", sort_order="1")

    @property
    def _last_imported_album(self):
        album = self.library.last_import_album
        photo_ids = set(self.library.fetch_album_photo_id_list(album))
        return self._album_base(album, photo_ids)

    def _album_base(self, album, photo_ids, name=None, album_type=None, sort_order=None, parent=None):
        if album_type is None:
            if isinstance(album, Album):
                album_type = "Regular"
            elif isinstance(album, Folder):
                album_type = "Folder"
        data = {
            "AlbumId": _iphoto_id(album),
            "AlbumName": name or album.name,
            "GUID": album.uuid,
            "Album Type": album_type,
        }
        if album.poster_id:
            data["KeyPhotoKey"] = str(album.poster_id)
        if sort_order:
            data["Sort Order"] = sort_order
        if parent:
            data["Parent"] = _iphoto_id(parent)
        if photo_ids:
            self._append_photos(data, photo_ids)
        return data

    def _append_photos(self, data, photo_ids):
        data["KeyList"] = list(str(k) for k in sorted(photo_ids))
        data["PhotoCount"] = len(photo_ids)
        return data

    def _photo(self, photo):
        empty_caption = ""
        if self.generate_caption:
            empty_caption = "photo_%d" % photo.id
        data = {
            "Caption": photo.name or empty_caption,
            "Comment": photo.description or " ",
            "GUID": photo.uuid,
            "Roll": self.all_roll_id,
            "Rating": 5 if photo.is_favorite and not self.disable_rating else 0,
            "ImagePath": os.path.join(self.path, photo.path),
            "MediaType": "Image",
            # "MediaType": "photo",
            "ModDateAsTimerInterval": photo.export_image_change_date_ts,
            "MetaModDateAsTimerInterval": photo.export_metadata_change_date_ts,
            "DateAsTimerInterval": photo.image_date_ts,
            "DateAsTimerIntervalGMT": photo.image_data_gmt_ts,
            "OriginalPath": os.path.join(self.path, photo.original),
            "ThumbPath": os.path.join(self.path, photo.thumbnails["mini"]),
        }
        if photo.is_favorite:
            data["Flagged"] = True
        return data

    @property
    def _all_roll(self):
        """One fake event"""
        return {
            "RollID": self.all_roll_id,
            "ProjectUuid": "RBoLkXF0QxGHAqJTrs9p0Q",
            "RollName": "Photos",
            "RollDateAsTimerInterval": min(p.image_date_ts for p in self.photos.values()),
            "KeyPhotoKey": str(min(p.id for p in self.photos.values())),
            "PhotoCount": len(self.photos),
            "KeyList": list(str(p.id) for p in self.photos.values()),
        }