Appengine直接下载文件并保存到google drive
一直对下载文件比较感兴趣。前些日子无意搜到google 推出一项服务,可以直接将文件下载到google drive中,原型猛戳这里,但有限额限制。一时脑洞大开,可不可以在appengine 上架设服务利用google来下载文件呢。(你折腾不折腾,上google dirve还要用梯子,然后还要从google drive上下载,是不是有病,答:我愿意,不折腾就会死)以下是研究结果:
在appengine下申请appid 什么的我就不说了,就从前期的设置权限说起吧。
假设你已经建立了appid为abcd的app,通过这进入总控台,(总控台的最近有些变化,以下我按新版的界面说。)点abcd进入abcd的项目设置。点左侧的“api&auth”下的“API”进入,打开drive api ,注意一定要是drive api 而不是cloud storage api。我在这里走一些弯路,关键是cloud storage api是付费的。
下一步取得OATH key。点左侧的“api&auth”下的“credential”,点“Oath”下的“creat new client ID”在页面中选“web aplication ”,在 "authorized javascript origins" 下填好你的appengine 的域名,一般是
http://apiid .appspot.com (注意是http 而不是https)这里appid 是"abcd"。填好这个后下面的“authorized redirect URI”也能自动填好。然后单击“create client ID”就生成了新的client id 。返回到“credential”页面后就可以看到新生成的client ID。单击下面的download json以.json文件的形式下载刚才生产的client ID ,一般文件名是“client_secrets.json”
上面这些事做得很麻烦,也可以让google替你做,这里的最下方,select an api 选 drive api , select a platform 选 google app engine 然后点“configure project ”选择你要设置的app id ,再“continue”,就设置完成了,点“Download the starter application” 下载下来的框架修改下就可以完成预计任务了。注意这里的client_secrets.json是本地的文件,用于在本地模拟,一定要替换成上面设置的。也就是“Client ID for web application”
修改框架中的文件,用你的client_secrets.json替换原有的文件。
修改main.html为
<html>
<head>
<title>Upload file to Google Drive from url Demo</title>
</head>
<body> {% if has_credentials %}
<form name="input" action="/upload" method="post">
Url:
<input type="text" name="urls" style="width: 350px; height: 60px;">
<input type="submit" value="Upload">
</form>
{% else %}
<p>
You should follow the link below and grant this application permission to access your data using the Drive API.
</p>
<blockquote>
<a href="{{ url }}">{{ url }}</a>
</blockquote>
{% endif %}
</body>
</html>
html很丑大家轻拍。
然后修改main.py主要是处理“/”的mainhandler,和处理“/upload”的uploadhandler
class MainHandler(webapp2.RequestHandler):
@decorator.oauth_required
def get(self):
variables = {
'url': decorator.authorize_url(),
'has_credentials': decorator.has_credentials()
}
template = JINJA_ENVIRONMENT.get_template('main.html')
self.response.write(template.render(variables))
class UploadHandler(webapp2.RequestHandler):
@decorator.oauth_required
def post(self):
url = cgi.escape(self.request.get('urls'))
parse = urlparse(url)
path = parse.path
filename = path.split('/')[-1]
headers = {}
deadline = 5
for i in range(0, 10):
try:
response = urlfetch.fetch(url, headers=headers, deadline=deadline)
break
except apiproxy_errors.OverQuotaError:
response = None
time.sleep(4)
except urlfetch.DeadlineExceededError:
logging.error('DeadlineExceededError(deadline=%s, url=%r)', deadline, url)
response = None
time.sleep(1)
except urlfetch.DownloadError:
logging.error('DownloadError(deadline=%s, url=%r)', deadline, url)
response = None
time.sleep(1)
except urlfetch.InvalidURLError as e:
logging.error('Invalid URL: %s' % e)
response = None
except urlfetch.ResponseTooLargeError as e:
response = e.response
logging.error('ResponseTooLargeError(deadline=%s, url=%r) response(%r)', deadline, url, response)
m = re.search(r'=\s*(\d+)-', headers.get('Range') or headers.get('range') or '')
if m is None:
headers['Range'] = 'bytes=0-%d' % URLFETCH_MAXSIZE
else:
headers.pop('Range', '')
headers.pop('range', '')
start = int(m.group(1))
headers['Range'] = 'bytes=%s-%d' % (start, start+URLFETCH_MAXSIZE)
deadline = URLFETCH_TIMEOUT * 2
except Exception as e:
logging.error('Exception %s(deadline=%s)' % (e, deadline))
response = None
if response:
data = io.BytesIO(response.content)
filemimetype = response.headers.get('Content-Type', 'application/octet-stream')
media = MediaIoBaseUpload(data, mimetype=filemimetype, chunksize=1024*1024, resumable=True)
body = {'title': filename, 'mimeType': filemimetype}
try:
end = service.files().insert(body=body, media_body=media, convert=False).execute(http=decorator.http())
except errors.HttpError as error:
logging.error('An error occured: %s' % error)
end = None
self.response.write("<p>download %s success.</p>" % url)
self.response.write(end)
else:
self.response.write("<p>download %s failed.</p>" % url)
mainhandler比较简单主要是获取授权。uploader是主要的下载和上传程序。下载通过urlfetch完成,其他的代码主要处理各种exception,上传分两步一是通过mediaiobase上传,上传前先转换为iobase,二是执行file insert。其余的还是exception处理。
问题是不知道为什么上传的文件的mimetype总是设置为"application/msword",有哪位大牛来帮忙解决下
Appengine直接下载文件并保存到google drive的更多相关文章
- 使用官方组件下载图片,保存到MySQL数据库,保存到MongoDB数据库
需要学习的地方,使用官方组件下载图片的用法,保存item到MySQL数据库 需要提前创建好MySQL数据库,根据item.py文件中的字段信息创建相应的数据表 1.items.py文件 from sc ...
- Excel文件数据保存到SQL中
1.获取DataTable /// <summary> /// 查询Excel文件中的数据 /// </summary> /// <param name="st ...
- Unity WWW下载图片并保存到Unity的Assets下
1.新建一个UGUI的Image. 2.新建一个脚本wwwTest.cs: using System.Collections; using System.Collections.Generic; us ...
- 前端/H5/JS:通过URL下载文件并转存到其他服务器(微信),Blob文件转File文件
现在有一个图片URL,在自己服务器上,一个微信提供的媒体文件上传URL,我在前端通过JS实现转存微信服务器 1. http://file.xxx.com/asd.jpg 自己的 2.https://a ...
- 【练习】使用服务下载图片并保存到sdcard
public class StringUtils { public static String getStr(String path){ String[] strs = path.split(&quo ...
- matlab 读多个文件夹(有名字规律)中的文件名字保存到txt中
save_file_name='C:\Users\cong\Desktop\研一实战\项目\图像中时间数字识别\OCR\result6\'; :: image_path=strcat('C:\User ...
- HttpClient实现通过url下载文件
其实就是通过浏览器url,点击就会下载文件. 这里是从代码层面上,对文件进行下载. package main.java.com.abp.util; import org.apache.http.*; ...
- 记录python爬取猫眼票房排行榜(带stonefont字体网页),保存到text文件,csv文件和MongoDB数据库中
猫眼票房排行榜页面显示如下: 注意右边的票房数据显示,爬下来的数据是这样显示的: 网页源代码中是这样显示的: 这是因为网页中使用了某种字体的缘故,分析源代码可知: 亲测可行: 代码中获取的是国内票房榜 ...
- [置顶] Android学习系列-把文件保存到SD卡上面(6)
Android学习系列-把文件保存到SD卡上面(5) 一般多媒体文件,大文件需要保存到SD卡中.关键点如下: 1,SD卡保存目录:mnt/sdcard,一般采用Environment.getExter ...
随机推荐
- centos7 tengine 安装
Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检 ...
- 20145203 实验五 Java网络编程及安全
20145203 实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验要求 1.基于Java Socket实现安全传输 2 ...
- linux-top命令查看内存CPU
转自:https://www.cnblogs.com/dragonsuc/p/5512797.html 查看多核CPU命令 mpstat -P ALL 和 sar -P ALL 说明:sar -P ...
- 使用jquery操作元素的css样式(获取、修改等等)
//1.获取和设置样式 $("#tow").attr("class")获取ID为tow的class属性 $("#two").attr(&qu ...
- C语言程序设计I—第三周教学
由于本课程是从教学周的第二周开始上课,所以第二次授课是发生在第三周,为了让PTA.云班课和博客能统一,所以将教学周作为随笔的标题.本周由于处理外聘教师随意退课等事情,总结有些延后了. 第三周教学安排 ...
- RabbitMQ如何保证发送端消息的可靠投递-发生镜像队列发生故障转移时
上一篇最后提到了mandatory这个参数,对于设置mandatory参数个人感觉还是很重要的,尤其在RabbitMQ镜像队列发生故障转移时. 模拟个测试环境如下: 首先在集群队列中增加两个镜像队列的 ...
- UVa 10377 - Maze Traversal
題目:一個機器人在迷宮中行走,它的指令是方向控制(前進.左轉.右轉).給你初始位置和一些指令: 問最後停在那個位置. 分析:模擬.直接模擬就可以,注意一下細節. 假设,不能行走(邊界或者是墻壁)則停在 ...
- 20155237 2016-2017-2 《Java程序设计》第9周学习总结
20155237 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC入门 驱动的四种类型 JDBC-ODBC Bridge Dri ...
- 苏州优步uber司机奖励政策(持续更新)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- [CQOI2015]任务查询系统 主席树
[CQOI2015]任务查询系统 LG传送门 以前还没见过主席树的这种写法. 考虑使用差分的思想处理每一个任务,然后所有的东西就都能顺理成章地用主席树维护了,查询的时候和平时的主席树有一点不同,详见代 ...