无法使用Google Drive API复制Google幻灯片文件 修改点:修改后的脚本:修改后的脚本:参考文献

问题描述

我想复制Google驱动器中存在的现有模板ppt。然后,我想将占位符文本更改为其他一些文本。

这是我正在尝试的。

from google.oauth2 import service_account
import googleapiclient.discovery


ScopES = (
    'https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/presentations',)
SERVICE_ACCOUNT_FILE = 'cred.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE,scopes=ScopES) 

SLIDES = discovery.build('slides','v1',credentials=credentials)
DRIVE  = discovery.build('drive','v3',credentials=credentials)

TMPLFILE = 'title slide template' 

rsp = DRIVE.files().list(q="name='%s'" % TMPLFILE).execute().get('files')[0]
print(rsp)
DATA = {'name': 'Google Slides API template DEMO'}
print('** copying template %r as %r' % (rsp['name'],DATA['name']))
DECK_ID = DRIVE.files().copy(body=DATA,fileId=rsp['id']).execute().get('id')
print(DECK_ID)

print('** Replacing placeholder text')

reqs = [
    {'replaceAllText': {
        'containsText': {'text': '{{text}}'},'replaceText': final_til[0]
    }},]

SLIDES.presentations().batchUpdate(body={'requests': reqs},presentationId=DECK_ID).execute()
print('DONE')

但是它不起作用。我没有任何错误。一切正常,但我看不到新的ppt。

输出

{'kind': 'drive#file','id': '15mVjkrT7PkckKetK_q9aYRVxaDcwDdHpAh7xjrAWB6Q','name': 'title slide template','mimeType': 'application/vnd.google-apps.presentation'}  <--- rsp
** copying template 'title slide template' as 'Google Slides API template DEMO'
11O97tySSNaboW6YRVD62Q7HLs8aVuS2pWyLYXImdsec   <-- DECK_ID
** Replacing placeholder text
DONE

如果我改变

SLIDES.presentations().batchUpdate(body={'requests': reqs},presentationId=DECK_ID).execute()

SLIDES.presentations().batchUpdate(body={'requests': reqs},presentationId=rsp.get('id')).execute()

然后它会替换文本,但会替换我不需要的模板文件中的文本。

为什么会这样?

解决方法

我相信您的当前情况和目标如下。

  • 从您的脚本中,
    • 您正在将googleapis用于python。
    • 您已经可以使用服务帐户使用Drive API和Slides API。
    • an existing template ppt present是不是PowerPoint文件的Google幻灯片。

修改点:

  • 通过您的脚本和But it is not working. I don't get any error. everything works fine but I don't see the new ppt.,我了解到您可能希望在服务处将您的Google幻灯片复制到Google云端硬盘中。

    • 通过服务帐户复制Google幻灯片时,复制的Google幻灯片将放置到服务帐户的云端硬盘中。云端硬盘服务帐户与您的Google云端硬盘不同。这样,您将无法在云端硬盘上看到复制的Google幻灯片。我认为这可能是您遇到问题的原因。
  • 例如,要查看服务帐户在您的Google云端硬盘中复制的Google幻灯片,可以使用以下变通办法。

    1. 与您的Google帐户电子邮件共享复制的Google幻灯片。
      • 在这种情况下,您可以在共享文件夹中看到共享文件。
    2. 首先,它会在您的Google云端硬盘中创建新文件夹,并与服务帐户的电子邮件共享该文件夹。复制Google幻灯片后,它将共享文件夹设置为目标文件夹。

解决方法1:

在此替代方法中,它将复制的Google幻灯片与您的Google帐户的电子邮件共享。当这反映到您的脚本时,它如下所示。

修改后的脚本:

在这种情况下,将使用“权限:创建”为复制的文件创建新的权限。

从:
print(DECK_ID)

print('** Replacing placeholder text')
至:
print(DECK_ID)

permission = {
    'type': 'user','role': 'writer','emailAddress': '###@gmail.com'  # <--- Please set the email of your Google account.
}
DRIVE.permissions().create(fileId=DECK_ID,body=permission).execute()

print('** Replacing placeholder text')

解决方法2:

在这种解决方法中,Google幻灯片会复制到Google云端硬盘中的共享文件夹中。在使用此脚本之前,请创建新文件夹并与服务帐户的电子邮件共享该文件夹。当这反映到您的脚本时,它如下所示。

修改后的脚本:

在这种情况下,元数据将添加到DRIVE.files().copy()的请求正文中。

从:
DATA = {'name': 'Google Slides API template DEMO'}
至:
DATA = {'name': 'Google Slides API template DEMO','parents': ['###']}
  • 请将共享文件夹的文件夹ID设置为###

参考文献:

,

@Tanaike的答案很好,但还有另一种选择:

帐户模拟

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE,scopes=SCOPES)
        
delegated_credentials = credentials.with_subject(<email>)

DRIVE = build('drive','v3',credentials = delegated_credentials)

这里有一个很好的概述:Using OAuth 2.0 for Server to Server Applications,特别是this section遍历了代码。

记住要同时在GCP控制台管理控制台中设置域范围授权

在GCP Cloud控制台中初始化的项目也已从管理控制台>安全性> API控件>域范围委派>添加新

脚本执行的第一件事是使用from_service_account_file构建凭据:

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE,scopes=SCOPES)

然后,它构建已授权凭据,即要模拟的用户:

delegated_credentials = credentials.with_subject('<EMAIL>')

从那里可以正常构建服务。您可以将其保存到用户的驱动器中,就像用户自己在进行驱动一样。

参考文献

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...