программа python создает презентацию слайдов Google, но она оказывается пустой

У меня есть несколько файлов изображений jpg, которые мне нужно программно вставить в презентацию слайдов Google. Первый шаг - создать программу, которая генерирует только один слайд и вставляет одно изображение в слайд. Если это удастся, я дополню код циклом по моим изображениям. Код выглядит следующим образом:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import library_JP

# If modifying these scopes, delete the file token.pickle.
#SCOPES = ['https://www.googleapis.com/auth/presentations.readonly']
SCOPES = ['https://www.googleapis.com/auth/presentations']

# The ID of a sample presentation.
PRESENTATION_ID = '1EAYk18WDjIG-zp_0vLm3CsfQh_i8eXc67Jo2O9C6Vuc'
PRESENTATION_ID = '1tWESMVHXsbbW-rro6wdeDQL3ygkxAf3c0xSd-JK-oXg'
presentation_id = '1tWESMVHXsbbW-rro6wdeDQL3ygkxAf3c0xSd-JK-oXg'

def main():
    """Shows basic usage of the Slides API.
    Prints the number of slides and elments in a sample presentation.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('slides', 'v1', credentials=creds)

    # Call the Slides API
    IMAGE_URL = ('https://www.google.com/images/branding/'
             'googlelogo/2x/googlelogo_color_272x92dp.png')
#    page_id = '3b330c04-6eb2-11eb-9439-0242ac130002'
    page_id = '0c00dd21-da6d-4b9a-9694-3b9e81b2ab1b'
    requests = [
    {
        'createSlide': {
#            'objectId': page_id,
            'insertionIndex': '1',
            'slideLayoutReference': {
                'predefinedLayout': 'TITLE_AND_TWO_COLUMNS'
            }
        }
    }
              ]


    title = 'JP_february13-2021 '
    print('debug requests before creating pres ',requests)
    body0 = {'title': title}
#
    presentation = service.presentations().create(body=body0).execute()
    print('Created presentation with ID: {0}'.format(
    presentation.get('presentationId')))
    body = { 'requests': requests}
#
    response = service.presentations() \
    .batchUpdate(presentationId=presentation_id, body=body).execute()
    create_slide_response = response.get('replies')[0].get('createSlide')
    print('Created slide with ID: {0}'.format(
    create_slide_response.get('objectId')))
#
    requests = []
    image_id = 'MyImage_01'
    emu4M = {
    'magnitude': 4000000,
    'unit': 'EMU',
            }
    requests.append({
     'createImage': {
        'objectId': image_id,
        'url': IMAGE_URL,
        'elementProperties': {
            'pageObjectId': page_id,
            'size': {
                'height': emu4M,
                'width': emu4M
            },
            'transform': {
                'scaleX': 1,
                'scaleY': 1,
                'translateX': 100000,
                'translateY': 100000,
                'unit': 'EMU'
                         }
            }
                    }
                    })


    response = service.presentations() \
    .batchUpdate(presentationId=presentation_id, body=body).execute()
    create_image_response = response.get('replies')[0].get('createImage')
#    print('Created image with ID: {0}'.format(
#    create_image_response.get('objectId')))

if __name__ == '__main__':
    main()


Результат программы:

python quickstart_JP5.py
debug requests before creating pres  [{'createSlide': {'insertionIndex': '1', 'slideLayoutReference': {'predefinedLayout': 'TITLE_AND_TWO_COLUMNS'}}}]
Created presentation with ID: 1gRl0h60XXK8_p7kfn4pgBe212ncKHbScj1Y7pesjZlo
Created slide with ID: SLIDES_API1707490034_0

Однако, когда я использую хром с идентификатором презентации сверху, результат оказывается не таким, как я ожидал:

https://docs.google.com/presentation/d/1gRl0h60XXK8_p7kfn4pgBe212ncKHbScj1Y7pesjZlo/edit#slide=id.p

person LP0    schedule 16.02.2021    source источник
comment
К сожалению, я не могу понять when I use chrome with the presentation id from above the result is not what I expected. Прошу прощения за это. Могу я спросить вас о деталях вашей текущей проблемы и вашей цели?   -  person Tanaike    schedule 16.02.2021
comment
Можете ли вы немного привести в порядок свой код? Например, не имеет смысла делать это requests = [] image_id = 'MyImage_01', но вы ранее установили body на запросы, и это не будет обновлять тело ... в этом случае переместите body = { 'requests': requests} непосредственно перед response = service.presentations() - но есть и другие вещи, такие как переменные, объявленные дважды и перезаписанные, закомментированный код (вы можете просто удалить это для целей этого вопроса) - см. Минимальный воспроизводимый пример   -  person iansedano    schedule 16.02.2021
comment
Спасибо большое за вашу помощь. Тем временем я выяснил, что не так в коде. Как мне действовать, следует ли опубликовать новую версию и стереть ту, что указана в окне вопроса?   -  person LP0    schedule 18.02.2021
comment
Если вы решили свою проблему, они опубликуют ее как ответ ниже и примут ее. Если проблема не исчезла, отредактируйте свой вопрос. Спасибо!   -  person iansedano    schedule 19.02.2021


Ответы (1)


Следующий код работает должным образом и устраняет проблемы, о которых сообщалось ранее:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
#
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/presentations']


def main():
    """Shows basic usage of the Slides API.
    Prints the number of slides and elments in a sample presentation.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('slides', 'v1', credentials=creds)

    # Call the Slides API
    IMAGE_URL = ('https://www.google.com/images/branding/'
             'googlelogo/2x/googlelogo_color_272x92dp.png')


    title = 'JP_february13-2021 '
    body0 = {'title': title}
#
    presentation = service.presentations().create(body=body0).execute()
    print('Created presentation with ID: {0}'.format(
    presentation.get('presentationId')))
    XXX = presentation.get('presentationId')
#
    requests = [
    {
        'createSlide': {
            'insertionIndex': '1',
            'slideLayoutReference': {
                'predefinedLayout': 'TITLE_AND_TWO_COLUMNS'
            }
        }
    }
              ]

    body1 = { 'requests': requests}
#
    response = service.presentations() \
    .batchUpdate(presentationId=XXX, body=body1).execute()
    create_slide_response = response.get('replies')[0].get('createSlide')
    print('Created slide with ID: {0}'.format(
    create_slide_response.get('objectId')))
    YYY = create_slide_response.get('objectId')
#
    requests = []
    image_id = 'MyImage_01'
    emu4M = {
    'magnitude': 4000000,
    'unit': 'EMU',
            }
    requests.append({
     'createImage': {
        'objectId': image_id,
        'url': IMAGE_URL,
        'elementProperties': {
            'pageObjectId': YYY,
            'size': {
                'height': emu4M,
                'width': emu4M
            },
            'transform': {
                'scaleX': 1,
                'scaleY': 1,
                'translateX': 100000,
                'translateY': 100000,
                'unit': 'EMU'
                         }
            }
                    }
                    })

    body2 = {'requests': requests}
    response = service.presentations() \
    .batchUpdate(presentationId=XXX, body=body2).execute()
    create_image_response = response.get('replies')[0].get('createImage')
#    print('Created image with ID: {0}'.format(
#    create_image_response.get('objectId')))

if __name__ == '__main__':
    main()

Проблема в исходном коде заключается в том, что неправильная переменная была передана в таких инструкциях, как:

    response = service.presentations() \
    .batchUpdate(presentationId=XXX, body=body1).execute()

В результате исправления программа возвращает адрес вида

presentation with ID: 1JHjscoAl3perOnqeJQocpt0YmwHSuXLu5fCgATCY2dc

который можно использовать "вручную" в URL-адресе для доступа к презентации слайдов Google.

person LP0    schedule 21.02.2021