Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: app/handlers/cloud_storage.py

Issue 1031663002: Increase maximum file upload to 100MB, use cloudstorage python library (Closed) Base URL: https://github.com/dart-lang/pub-dartlang.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « app/cloudstorage ('k') | app/models/package.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 # for details. All rights reserved. Use of this source code is governed by a 2 # for details. All rights reserved. Use of this source code is governed by a
3 # BSD-style license that can be found in the LICENSE file. 3 # BSD-style license that can be found in the LICENSE file.
4 4
5 """Utility functions for dealing with Google Cloud Storage.""" 5 """Utility functions for dealing with Google Cloud Storage."""
6 6
7 from cStringIO import StringIO 7 from cStringIO import StringIO
8 from base64 import b64encode 8 from base64 import b64encode
9 from urlparse import urlparse, parse_qs 9 from urlparse import urlparse, parse_qs
10 from xml.etree import ElementTree 10 from xml.etree import ElementTree
11 import cherrypy 11 import cherrypy
12 import handlers 12 import handlers
13 import json 13 import json
14 import routes 14 import routes
15 import urllib 15 import urllib
16 import time 16 import time
17 17
18 from google.appengine.api import app_identity 18 from google.appengine.api import app_identity
19 from google.appengine.api import files 19 from google.appengine.api import files
20 from google.appengine.api import namespace_manager 20 from google.appengine.api import namespace_manager
21 from google.appengine.api import urlfetch 21 from google.appengine.api import urlfetch
22 22
23 from models.private_key import PrivateKey 23 from models.private_key import PrivateKey
24 24
25 import cloudstorage
26
25 # The Google Cloud Storage bucket for this app 27 # The Google Cloud Storage bucket for this app
26 _BUCKET = "pub.dartlang.org" 28 _BUCKET = "pub.dartlang.org"
27 29
28 # From https://code.google.com/apis/console 30 # From https://code.google.com/apis/console
29 _ACCESS_KEY = "818368855108@developer.gserviceaccount.com" 31 _ACCESS_KEY = "818368855108@developer.gserviceaccount.com"
30 32
31 # From https://developers.google.com/storage/docs/authentication 33 # From https://developers.google.com/storage/docs/authentication
32 _FULL_CONTROL_SCOPE = "https://www.googleapis.com/auth/devstorage.full_control" 34 _FULL_CONTROL_SCOPE = "https://www.googleapis.com/auth/devstorage.full_control"
33 35
34 # The maximum size (in bytes) of a chunk that can be read from cloud storage at 36 # The maximum size (in bytes) of a chunk that can be read from cloud storage at
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 raise handlers.http_error(500, "Cloud storage %s error: %s\n%s" % ( 208 raise handlers.http_error(500, "Cloud storage %s error: %s\n%s" % (
207 response.status_code, 209 response.status_code,
208 xml.find('Code').text, 210 xml.find('Code').text,
209 xml.find('Message').text 211 xml.find('Message').text
210 )) 212 ))
211 213
212 def delete_object(obj): 214 def delete_object(obj):
213 """Deletes an object from cloud storage.""" 215 """Deletes an object from cloud storage."""
214 files.delete(_appengine_object_path(obj)) 216 files.delete(_appengine_object_path(obj))
215 217
216 def open(obj): 218 def open(obj):
Bob Nystrom 2015/03/23 19:41:13 Might be good to leave a comment that this is depr
kustermann 2015/03/24 18:28:20 Done. It's still used -- I've added a deprecation
217 """Opens an object in cloud storage.""" 219 """Opens an object in cloud storage."""
218 return files.open(_appengine_object_path(obj), 'r') 220 return files.open(_appengine_object_path(obj), 'r')
219 221
222 def open_with_gcs(obj):
223 """Opens an object in cloud storage with the GCS library."""
224 return cloudstorage.open(_gcs_appengine_object_path(obj), 'r')
225
220 def read(obj): 226 def read(obj):
221 """Consumes and returns all data in an object in cloud storage. 227 """Consumes and returns all data in an object in cloud storage.
222 228
223 The data is returned as a StringIO instance, so it may be used in place of a 229 The data is returned as a StringIO instance, so it may be used in place of a
224 file. 230 file.
225 231
226 This can be necessary since many operations on the file object itself 232 This can be necessary since many operations on the file object itself
227 require a network round trip.""" 233 require a network round trip."""
228 234
229 with open(obj) as f: 235 with open_with_gcs(obj) as f:
230 io = StringIO() 236 io = StringIO()
231 data = f.read(_CHUNK_SIZE) 237 data = f.read(_CHUNK_SIZE)
232 while data: 238 while data:
233 io.write(data) 239 io.write(data)
234 data = f.read(_CHUNK_SIZE) 240 data = f.read(_CHUNK_SIZE)
235 io.seek(0) 241 io.seek(0)
236 return io 242 return io
237 243
238 def object_url(obj): 244 def object_url(obj):
239 """Returns the URL for an object in cloud storage.""" 245 """Returns the URL for an object in cloud storage."""
240 if handlers.is_production(): 246 if handlers.is_production():
241 return 'https://storage.googleapis.com/' + _object_path(obj) 247 return 'https://storage.googleapis.com/' + _object_path(obj)
242 else: 248 else:
243 return '/gs_/' + urllib.quote(obj) 249 return '/gs_/' + urllib.quote(obj)
244 250
245 def _object_path(obj): 251 def _object_path(obj):
246 """Returns the path for an object in cloud storage.""" 252 """Returns the path for an object in cloud storage."""
247 ns = namespace_manager.get_namespace() 253 ns = namespace_manager.get_namespace()
248 if ns == "": return _BUCKET + '/' + obj 254 if ns == "": return _BUCKET + '/' + obj
249 return _BUCKET + '/ns/' + ns + '/' + obj 255 return _BUCKET + '/ns/' + ns + '/' + obj
250 256
251 def _appengine_object_path(obj): 257 def _appengine_object_path(obj):
252 """Returns the path for an object for use with the AppEngine APIs.""" 258 """Returns the path for an object for use with the AppEngine APIs."""
253 return '/gs/' + _object_path(obj) 259 return '/gs/' + _object_path(obj)
254 260
261 def _gcs_appengine_object_path(obj):
262 """Returns the path for an object for use with the GCS APIs."""
263 return '/' + _object_path(obj)
264
255 def _iso8601(secs): 265 def _iso8601(secs):
256 """Returns the ISO8601 representation of the given time. 266 """Returns the ISO8601 representation of the given time.
257 267
258 The time should be in seconds past the epoch.""" 268 The time should be in seconds past the epoch."""
259 return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(secs)) 269 return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(secs))
OLDNEW
« no previous file with comments | « app/cloudstorage ('k') | app/models/package.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698