Слайды Google возвращают «Предоставленное изображение в неподдерживаемом формате» даже с настроенными полями авторизации - PullRequest
0 голосов
/ 08 апреля 2020

Самая близкая тема -

https://stackoverflow.com/questions/60160794/getting-the-provided-image-is-in-an-unsupported-format-error-when-trying-to-in

Но я не хочу открывать изображение, делясь им с остальным миром. Поэтому я настраиваю с доменом

file_id = uploaded_file.get('id')
drive_service.permissions().create(fileId=file_id, body={
    'type': 'domain',
    'domain': 'mydomain.com', # this is the domain I use the gsuite user e.g. richard@mydomain.com to login
    'role': 'reader'
}).execute()

И ресурс слайдов создается с помощью

def build_request(http, *args, **kwargs):
    import google_auth_httplib2
    new_http = google_auth_httplib2.AuthorizedHttp(credentials=drive_creds)
    auth_header = {
        'Authorization': 'Bearer '+ drive_creds.token
    }
    headers = kwargs.get('headers', {})
    if not headers:
        kwargs['headers'] = auth_headers
    else:
        kwargs['headers'].update(auth_header)
    http_req = googleapiclient.http.HttpRequest(new_http, *args, **kwargs)
    return http_req
slides_service = build('slides', 'v1', credentials=slides_creds, requestBuilder=build_request)

При выполнении я вижу, что kwargs передаются в HttpRequest с полями авторизации, настроенными правильно, например

{'headers': {'Authorization': 'Bearer <google drive token>', ... }

Однако, во время выполнения, функция создания изображения (я уверен, что моя функция создания изображения работает правильно, потому что как только я использую доступное изображение publi c, например, google lo go, нет проблем с отправкой изображения в google slide page) всегда возвращает код состояния 400 с сообщением «Предоставленное изображение в неподдерживаемом формате». Я открываю приватное окно и вставляю ссылку, похоже, она все еще перенаправляет запрос на вход на страницу.

Какие дополнительные шаги мне нужно настроить, чтобы получить эту работу? Большое спасибо за помощь.

Обновление 1 :

Код ниже используется для создания соответствующего слайда и запуска Resour c на основе Google Do c.

slides_scopes = ['https://www.googleapis.com/auth/drive',
                 'https://www.googleapis.com/auth/drive.file',
                 'https://www.googleapis.com/auth/drive.readonly',
                 'https://www.googleapis.com/auth/presentations',
                 'https://www.googleapis.com/auth/spreadsheets',
                 'https://www.googleapis.com/auth/spreadsheets.readonly']

drive_scopes =  ['https://www.googleapis.com/auth/drive',
                 'https://www.googleapis.com/auth/drive.appdata',
                 'https://www.googleapis.com/auth/drive.file',
                 'https://www.googleapis.com/auth/drive.metadata',
                 'https://www.googleapis.com/auth/drive.metadata.readonly',
                 'https://www.googleapis.com/auth/drive.photos.readonly',
                 'https://www.googleapis.com/auth/drive.readonly']


def auth(token_file='token.pickle', credentials_json='cred.json',scopes=[]):

    creds = None
    if os.path.exists(token_file):
        with open(token_file, 'rb') as token:
            creds = pickle.load(token)
    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)
        with open(token_file, 'wb') as token:
            pickle.dump(creds, token)
    return creds

slides_creds = auth(token_file='slides_t.pickle', credentials_json='slides_t.json', scopes=slides_scopes)
drive_creds = auth(token_file='drive_t.pickle', credentials_json='drive_t.json', scopes=drive_scopes)
def build_request(http, *args, **kwargs):
    import google_auth_httplib2
    new_http = google_auth_httplib2.AuthorizedHttp(credentials=drive_creds)
    auth_header = {
        'Authorization': 'Bearer '+ drive_creds.token
    }
    headers = kwargs.get('headers', {})
    if not headers:
        kwargs['headers'] = auth_headers
    else:
        kwargs['headers'].update(auth_header)
    http_req = googleapiclient.http.HttpRequest(new_http, *args, **kwargs)
    return http_req
slides_service = build('slides', 'v1', credentials=slides_creds, requestBuilder=build_request)
drive_service = build('drive', 'v3', credentials=drive_creds)

Обновление 2 :

При переключении на обслуживание изображения с использованием локального http-сервера (доступно с http://<intranet ip or localhost>:<port>/path/to/img.png, API-интерфейс Google Slide возвращает следующую ошибку

"Invalid requests[0].createImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats."

Это заставляет меня задуматься, возможно, API Google Slide больше не разрешает доступ к webContentLink со специальным разрешением (например, доменом). Вместо этого разрешено только publi c Доступный URL.

Обновление 3 :

  • Параметры функции create_image:

    • slide_object_id: g6f1c6c22f2_1_69

    • web_content_link: https://drive.google.com/a/ {{имя домена}} / u c? Id = {{id изображения}} & export = download

    • size: {'height': {'magnitude': 10800, 'unit': 'EMU'}, 'width': {'magnitude': 19800, 'unit': 'EMU'}}

    • преобразовать: {scaleY ': 171,9097, scaleX': 21 2.4558, «translateY»: 937125, «translateX»: 2347875, «unit»: «EMU»}

  • функция создания изображения

    def create_image(slides_service=None, slide_object_id=None, web_content_link=None, size_height_magnitude=4000000, size_width_magnitude=4000000,  transform_scale_x=1,  transform_scale_y=1, transform_translate_x=100000,  transform_translate_y=100000):
        requests = []
        requests.append({
            'createImage': {
                'url': web_content_link,
                'elementProperties': {
                    'pageObjectId': slide_object_id,
                    'size': {
                        'height': {
                            'magnitude': size_height_magnitude,
                            'unit': 'EMU'
                        },
                        'width': {
                            'magnitude': size_width_magnitude,
                            'unit': 'EMU'
                        }
                    },
                    'transform': {
                        'scaleX': transform_scale_x,
                        'scaleY': transform_scale_y,
                        'translateX': transform_translate_x,
                        'translateY': transform_translate_y,
                        'unit': 'EMU'
                    }
                }
            }
        })
        body = {
            'requests': requests
        }
        response = slides_service.presentations() \
            .batchUpdate(presentationId=presentation_id, body=body).execute()
        return response.get('replies')[0].get('createImage')
    

1 Ответ

0 голосов
/ 15 апреля 2020

Проблема:

На слайд можно добавлять только изображения с общедоступным URL-адресом. Недостаточно поделиться изображением с учетной записью, с которой сделан запрос. Как вы можете видеть в официальной документации :

Если вы хотите добавить личные или локальные изображения в слайд, сначала вам нужно будет сделать их доступными на общедоступный URL .

Обходные пути:

  • Что вы можете сделать, как объяснено в ответ Танаике , так это : (1) опубликовать изображение публично, (2) добавить изображение на слайд с помощью общедоступного URL-адреса и (3) удалить разрешение, созданное на шаге 1. Таким образом, изображение станет общедоступным только в течение короткого времени. Программа выполняет шаги 2 и 3.

  • Другой вариант, указанный в документации по ссылкам:

загрузить изображения в Google Cloud Storage и использовать подписанные URL-адреса с 15-минутным TTL. Загруженные изображения автоматически удаляются через 15 минут.

Ссылка:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...