def upload_single(self, filepath, test=False):

        self.modified = False

        google_cache = GoogleLibrary.cache()
        google_image_filenames = google_cache.get('image_filenames')

        filename = os.path.basename(filepath)
        if filename in google_image_filenames:
            logging.info(f"Image already uploaded: '{filename}'")
            return
        elif test:
            logging.info(f"Image NEEDS uploading: '{filename}'")
            return

        image_spec_list = [{'filepath': filepath, 'filename': filename}]
        creds = GoogleService.credentials()

        try:
            if not test:
                self.upload_image_spec_list(image_spec_list, creds)

        finally:
            if self.modified:
                GoogleLibrary.save_library()
    def upload_image_spec_list(self, image_spec_list, creds):

        # Get captions for each image
        self.get_image_spec_list_captions(image_spec_list)

        # Chunk the spec list upload to max size
        media_item_count = len(image_spec_list)
        chunk_size = 50
        chunk_index = 0
        while chunk_index < media_item_count:
            logging.info(
                f"Batch uploading images byes, chunk index '{chunk_index}'")

            # Get the list into chunks
            chunk_image_spec_list = image_spec_list[chunk_index:(chunk_index +
                                                                 chunk_size)]

            # Build new media item list for batch upload
            newMediaItems = []
            for image_spec in chunk_image_spec_list:

                # Upload the images bytes to the google server
                self.upload_image_spec(image_spec, creds)

                # build
                newMediaItem = {
                    'description': image_spec.get('caption'),
                    'simpleMediaItem': {
                        'uploadToken': image_spec.get('upload_token'),
                        'fileName': image_spec.get('filename'),
                    }
                }
                newMediaItems.append(newMediaItem)

            # Batch upload media items now
            request_body = {'newMediaItems': newMediaItems}

            logging.info(
                f"Batch uploading images for chunk index '{chunk_index}'")

            service = GoogleService.service()
            upload_response = service.mediaItems().batchCreate(
                body=request_body).execute()

            # Save the newly created images in local cache
            google_cache = GoogleLibrary.cache()
            google_image_ids = google_cache['image_ids']
            google_image_filenames = google_cache['image_filenames']

            if upload_response is not None:
                newMediaItemResults = upload_response.get(
                    'newMediaItemResults')
                for newMediaItemResult in newMediaItemResults:
                    status = newMediaItemResult.get('status')
                    message = status.get('message') if status else None
                    if 'Success' == message:
                        mediaItem = newMediaItemResult.get('mediaItem')
                        GoogleLibrary.cache_image(mediaItem, google_image_ids,
                                                  google_image_filenames)
                        self.modified = True
Example #3
0
def main():
    gphoto.init()

    service = GoogleService.service()
    if not service:
        logging.error(
            "GoogleAlbums.cache_albums: GoogleService.service() is not initialized"
        )
        return

    # Album name used
    albumName = "2060 API Album"

    imageid01 = 'ALE2QTBp8OkubJCEMGMr4GTsThO3qMLWTit1_5DRyyQOD4IBUu5LJ8qFGwEb8AFy2yrlNlFTgtKt'
    imageid02 = 'ALE2QTBGNjlDhWc7Y3gwpGtIKvba849RolzOtcQ8xFgz1dh8J-Jmwa8vX80cYAGxJDjUu9m58gUu'
    image_ids = [imageid01, imageid02]

    # Create album
    request_body = {'album': {'title': albumName}}
    response_google_album = service.albums().create(
        body=request_body).execute()
    album_id = response_google_album['id']

    request_body = {'mediaItemIds': image_ids}
    response = service.albums().batchAddMediaItems(
        albumId=album_id, body=request_body).execute()

    print(response)
def main():
    """
    Test code to se if image caption can updated if the images
    was uploaded using Google Photos UI.

    This is not working at this time.  You will see the following
    error:

        "code": 403,
        "message: "Request had insufficient authentication scopes"
        "status": "PERMISSION_DENIED"
    """
    gphoto.init()

    cache = GoogleImages.load_images()
    filenames = cache['filenames']

    image_name = "20050101_000436_OSWA_D70.jpg"
    image_idx = filenames[image_name]
    image = cache['list'][image_idx]
    
    # "ALE2QTAJEnDlApTBWwq-U5n0pg6ulXVp5wdAkqwXVj0knHwrKGcyqFoCt5x5CzeXd_1FUD4VEvrkAZzGaqOxiJIcrsuZmHgJYw"
    image_id = image['id']

    request_body = {
        "description": f"{datetime.now()}: new-media-item-description"
    }

    service = GoogleService.service()
    response = service.mediaItems().patch(
        id=image_id,
        body=request_body
    ).execute()

    print(response)
Example #5
0
    def upload_album_names(album_names):

        gphoto.init()
        service = GoogleService.service()

        LocalLibrary.load_library('jpg')

        for album_name in album_names:
            Uploader.upload_album_name(service, album_name)
    def upload_recursive(self, folder, recursive=True, test=False):

        logging.info(f"uploading images in folder: ({folder})")

        # Get only media types in the folder
        # image spec list holds a list of objects, sample below:
        # [
        #     {
        #         'filepath': ...,
        #         'filename': ...,
        #         'upload_token': ...
        #     },
        #     {
        #         .... next image object ....
        #     }
        # ]

        image_spec_list = []
        folder_items = os.listdir(folder)
        filenames = [
            f for f in folder_items
            if os.path.isfile(os.path.join(folder, f)) and self.is_media(f)
        ]

        google_cache = GoogleLibrary.cache()
        google_image_filenames = google_cache.get('image_filenames')

        for filename in filenames:

            # If image already in cache then ignore
            if filename in google_image_filenames:
                logging.info(f"Image already uploaded: '{filename}'")
                continue
            elif test:
                logging.info(f"Image needs upload: '{filename}'")
                continue

            # Build the spec for each file
            filepath = os.path.join(folder, filename)
            image_spec = {'filepath': filepath, 'filename': filename}
            image_spec_list.append(image_spec)

        if len(image_spec_list) <= 0:
            logging.info(f"NO IMAGES TO UPLOAD IN FOLDER '{folder}'")
        else:
            creds = GoogleService.credentials()
            self.upload_image_spec_list(image_spec_list, creds)

        # Traverse sub-folders if recursive is specified
        if not recursive:
            return
        dirnames = [
            d for d in folder_items if os.path.isdir(os.path.join(folder, d))
        ]
        for dirname in dirnames:
            self.upload_recursive(os.path.join(folder, dirname), recursive,
                                  test)
    def map_recursive(self, root, test):
        """
        High-level algorithm:
        1. For each local folder locate the Google album in cache
        2. If Google album does not exist then call 'gphotocli album upload <...path_to_album...>'
            - Add local images to Google Album from the Local album if missing
            - Remove images from Google album that are not in Local album
        """
        # Argument validation
        if not os.path.exists(root):
            logging.error(f"Folder does not exist: ({root})")
            return

        # Remove trailing slash
        slash_char = root[len(root) - 1]
        if slash_char == '/' or slash_char == '\\':
            root = root[:len(root)-1]

        # Get Google API service
        service = GoogleService.service()

        # Initialize Google API and load cache.
        google_cache = GoogleLibrary.cache()
        google_album_ids = google_cache.get('album_ids')
        google_album_titles = google_cache.get('album_titles')

        # Load local library cache
        local_cache = LocalLibrary.cache('jpg')
        local_albums = local_cache.get('albums')

        # Traverse all the sub folders in the cache
        for local_album in local_albums:

            local_album_name = local_album['name']
            local_album_path = local_album['path']

            if not local_album_path.lower().startswith(root.lower()):
                continue

            # If album not in Google Cache, ignore and then error out
            google_album_id = google_album_titles.get(local_album_name)
            google_album = google_album_ids[google_album_id] if google_album_id is not None else None

            if google_album is None:
                logging.error(f"Ignoring album not in Google Cache: '{google_album.get('title')}'")
                continue

            # Do mapping for each Local/Google album
            self.map_album(local_album, google_album, test)
Example #8
0
    def upload_recursive(self, root, test):

        # Argument validation
        if not os.path.exists(root):
            logging.error(f"Folder does not exist: ({root})")
            return

        # Remove trailing slash
        slash_char = root[len(root) - 1]
        if slash_char == '/' or slash_char == '\\':
            root = root[:len(root) - 1]

        # Get Google API service
        service = GoogleService.service()

        # Initialize Google API and load cache.
        google_cache = GoogleLibrary.cache()
        google_album_ids = google_cache.get('album_ids')
        google_album_titles = google_cache.get('album_titles')

        # Traverse all the sub folders in the cache
        local_cache = LocalLibrary.cache('jpg')
        local_albums = local_cache.get('albums')

        for local_album in local_albums:

            local_album_name = local_album['name']
            local_album_path = local_album['path']

            if not local_album_path.lower().startswith(root.lower()):
                continue

            # Check if album already in Google Cache
            google_album_id = google_album_titles.get(local_album_name)
            google_album = google_album_ids[
                google_album_id] if google_album_id is not None else None

            if google_album is not None:
                logging.info(
                    f"Album already uploaded: '{google_album.get('title')}'")
                continue

            # Do the actual creating of Google album
            album_response = self.create_shareable_album(
                service=service, album_name=local_album_name, test=test)
            if album_response:
                self.modified = True
    def cache_images():

        # Initialize images fields of the cache
        cache = GoogleLibrary.cache()
        google_image_ids = {}
        google_image_filenames = {}
        cache['image_ids'] = google_image_ids
        cache['image_filenames'] = google_image_filenames

        service = GoogleService.service()
        if not service:
            logging.error("GoogleLibrary.cache_images: GoogleService.service() is not initialized")
            return

        # Get the first page of mediaItems
        pageSize=100
        response = service.mediaItems().list(
            pageSize=pageSize
        ).execute()
        mediaItems = response.get('mediaItems')
        nextPageToken = response.get('nextPageToken')

        for mediaItem in mediaItems:
            GoogleLibrary.cache_image(mediaItem, google_image_ids, google_image_filenames)

        # Loop through rest of the pages of mediaItems
        while nextPageToken:
            response = service.mediaItems().list(
                pageSize=pageSize,
                pageToken=nextPageToken
            ).execute()
            mediaItems = response.get('mediaItems')
            nextPageToken = response.get('nextPageToken')

            if mediaItems is not None:
                for mediaItem in mediaItems:
                    GoogleLibrary.cache_image(mediaItem, google_image_ids, google_image_filenames)

        summary = cache.get('summary')
        summary['image_count'] = len(google_image_ids)
    def __init__(self):
        LocalLibrary.load_library('jpg')
        GoogleLibrary.load_library()
        GoogleService.init()

        self.modified = False
    def cache_album_images():

        cache = GoogleLibrary.cache()

        # Service initialization
        service = GoogleService.service()
        if not service:
            logging.error("cache_album_images: GoogleService.service() is not initialized")
            return

        # Hold local vars for google images/albums cache
        google_image_ids = cache['image_ids']
        google_image_filenames = cache['image_filenames']

        google_album_ids = cache['album_ids']
        google_album_titles = cache['album_titles']

        # Initialize album_image and image_album caches
        album_images_cache = {}
        image_albums_cache = {}
        cache['album_images'] = album_images_cache
        cache['image_albums'] = image_albums_cache

        # Loop through each Google Album already cached
        # ---------------------------------------------
        for google_album_id, google_album in google_album_ids.items():
            google_album_title = google_album.get('title')

            # logging.info(f"GAI: Processing album '{google_album_title}', '{google_album_id}'")

            # get first set of images for this album
            request_body = {
                'albumId': google_album_id,
                'pageSize': 100
            }
            response = service.mediaItems().search(body=request_body).execute()
            mediaItems = response.get('mediaItems')
            nextPageToken = response.get('nextPageToken')

            # If there are no images in the album then move on to the next one
            if not mediaItems:
                continue

            for mediaItem in mediaItems:
                GoogleLibrary.cache_album_image_reln(mediaItem, google_album,
                    google_album_ids, google_album_titles,
                    google_image_ids, google_image_filenames,
                    album_images_cache, image_albums_cache)

            # Loop through rest of the pages of mediaItems
            # ------------------------------------------------
            while nextPageToken:
                request_body['pageToken'] = nextPageToken

                response = service.mediaItems().search(body=request_body).execute()
                mediaItems = response.get('mediaItems')
                nextPageToken = response.get('nextPageToken')

                for mediaItem in mediaItems:
                    GoogleLibrary.cache_album_image_reln(mediaItem, google_album,
                        google_album_ids, google_album_titles,
                        google_image_ids, google_image_filenames,
                        album_images_cache, image_albums_cache)
    def cache_albums():

        # Initialize album fields of the cache
        cache = GoogleLibrary.cache()
        google_album_ids = {}
        google_album_titles = {}
        cache['album_ids'] = google_album_ids
        cache['album_titles'] = google_album_titles

        service = GoogleService.service()
        if not service:
            logging.error("GoogleLibrary.cache_albums: GoogleService.service() is not initialized")
            return
        
        # Get unshared albums, first page
        pageSize=50
        response = service.albums().list(
            pageSize=pageSize,
            excludeNonAppCreatedData=False
        ).execute()

        response_albums = response.get('albums')
        nextPageToken = response.get('nextPageToken')

        if response_albums:
            for album in response_albums:
                GoogleLibrary.cache_album(album, google_album_ids, google_album_titles, shared=False)

        # Loop through rest of the pages of unshared albums
        while nextPageToken:
            response = service.albums().list(
                pageSize=pageSize,
                excludeNonAppCreatedData=False,
                pageToken=nextPageToken
            ).execute()
            response_albums = response.get('albums')
            nextPageToken = response.get('nextPageToken')

            if response_albums:
                for album in response_albums:
                    GoogleLibrary.cache_album(album, google_album_ids, google_album_titles, shared=False)


        # Get SHARED albums, first page
        response = service.sharedAlbums().list(
            pageSize=pageSize
        ).execute()
        response_albums = response.get('sharedAlbums')
        nextPageToken = response.get('nextPageToken')

        for album in response_albums:
            GoogleLibrary.cache_album(album, google_album_ids, google_album_titles, shared=True)

        # Loop through rest of the pages of albums
        while nextPageToken:
            response = service.sharedAlbums().list(
                pageSize=pageSize,
                pageToken=nextPageToken
            ).execute()
            response_albums = response.get('sharedAlbums')
            nextPageToken = response.get('nextPageToken')

            for album in response_albums:
                GoogleLibrary.cache_album(album, google_album_ids, google_album_titles, shared=True)

        summary = cache.get('summary')
        summary['album_count'] = len(google_album_ids)
Example #13
0
def init():
    AppData.init()
    LogMgr.init(AppData.APPDATA_NAME, LogMgr.DEFAULT_LOGNAME)
    GoogleService.init()