摘要:
我有一个问题,有时python的google-drive-sdk没有检测到导出文档的结尾.它似乎认为谷歌文件是无限大小.
我遵循的背景,源代码和教程:
我正在开发自己的基于python的google-drive备份脚本(一个带有良好CLI界面的浏览器). git link for source code
它仍在制作中,目前只能找到新文件并下载它们(使用’pull’命令).
要执行最重要的google-drive命令,我按照官方的google驱动器api教程下载媒体. here
什么有效:
当文档或文件是非google-docs文档时,文件会正确下载.但是,当我尝试“导出”文件时.我看到我需要使用不同的mimeType.我有一本字典.
例如:我在导出文档时将application / vnd.google-apps.document映射到application / vnd.openxmlformats-officedocument.wordprocessingml.document.
从谷歌驱动器下载谷歌文档文件时,这似乎工作正常.我的意思是:我的while循环具有代码状态,done = downloader.next_chunk()将最终设置为true并且下载完成.
什么行不通:
但是,在某些文件中,done标志永远不会变为true,脚本将永远下载.这最终达到几Gb.也许我正在寻找错误的标志,表示文件在导出时已完成.我很惊讶谷歌驱动器永远不会抛出错误.有人知道是什么原因引起的吗?
当前状态
目前我在我的代码中禁用了谷歌文档导出功能.
当我使用像“drive by rakyll”这样的脚本(至少是我的版本)时,只需添加一个指向在线副本的链接.我真的想做一个正确的导出,以便我的离线系统可以维护驱动器上所有内容的完整备份.
附:为了其他人找到这个页面,可以使用“你应该使用这个服务而不是api”.我知道还有其他服务,但我真的希望探索与我自己的其他系统集成的drive-api功能.
最佳答案 好.我在这里找到了伪解决方案.
问题是Google API从不返回Content-Length,响应在Chunks中完成.但是,返回的块是错误的,或者Python API无法正确处理它.
我做的是,获取MediaIoBaseDownload from here的代码
我离开了所有,但改变了这一部分:
if 'content-range' in resp:
content_range = resp['content-range']
length = content_range.rsplit('/', 1)[1]
self._total_size = int(length)
elif 'content-length' in resp:
self._total_size = int(resp['content-length'])
else:
# PSEUDO BUG FIX: No content-length, no chunk info, cut the response here.
self._total_size = self._progress
最后的其他是我添加的内容.我还通过设置DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024来更改默认块大小.此外,您还必须从该文件中复制一些导入,包括googleapiclient.http import _retry_request,_should_retry_response中的一个导入.
当然这不是一个解决方案,它只是说“如果我不理解响应,那就停止它”.这可能会使一些导出无效,但至少它不会杀死服务器.直到我们找到一个好的解决方案.
更新:
这里已经报道了Bug:https://github.com/google/google-api-python-client/issues/15
截至2017年1月,唯一的解决方法是不使用MediaIoBaseDownload并改为执行此操作(不适合大文件):
req = service.files().export(fileId=file_id, mimeType=mimeType)
resp = req.execute(http=http)