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

Side by Side Diff: appengine/monorail/framework/gcs_helpers.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 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
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """Set of helpers for interacting with Google Cloud Storage."""
7
8 import base64
9 import logging
10 import os
11 import time
12 import urllib
13 import uuid
14
15 from datetime import datetime, timedelta
16
17 from google.appengine.api import app_identity
18 from google.appengine.api import images
19 from third_party import cloudstorage
20
21 from framework import filecontent
22
23
24 ATTACHMENT_TTL = timedelta(seconds=30)
25
26 IS_DEV_APPSERVER = (
27 'development' in os.environ.get('SERVER_SOFTWARE', '').lower())
28
29 RESIZABLE_MIME_TYPES = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif']
30
31 DEFAULT_THUMB_WIDTH = 250
32 DEFAULT_THUMB_HEIGHT = 200
33 LOGO_THUMB_WIDTH = 110
34 LOGO_THUMB_HEIGHT = 30
35
36
37 def _Now():
38 return datetime.utcnow()
39
40
41 class UnsupportedMimeType(Exception):
42 pass
43
44
45 def DeleteObjectFromGCS(object_id):
46 object_path = ('/' + app_identity.get_default_gcs_bucket_name() + object_id)
47 cloudstorage.delete(object_path)
48
49
50 def StoreObjectInGCS(
51 content, mime_type, project_id, thumb_width=DEFAULT_THUMB_WIDTH,
52 thumb_height=DEFAULT_THUMB_HEIGHT):
53 bucket_name = app_identity.get_default_gcs_bucket_name()
54 guid = uuid.uuid4()
55 object_id = '/%s/attachments/%s' % (project_id, guid)
56 object_path = '/' + bucket_name + object_id
57 with cloudstorage.open(object_path, 'w', mime_type) as f:
58 f.write(content)
59
60 if mime_type in RESIZABLE_MIME_TYPES:
61 # Create and save a thumbnail too.
62 thumb_content = None
63 try:
64 thumb_content = images.resize(content, thumb_width, thumb_height)
65 except Exception, e:
66 # Do not raise exception for incorrectly formed images.
67 # See https://bugs.chromium.org/p/monorail/issues/detail?id=597 for more
68 # detail.
69 logging.exception(e)
70 if thumb_content:
71 thumb_path = '%s-thumbnail' % object_path
72 with cloudstorage.open(thumb_path, 'w', 'image/png') as f:
73 f.write(thumb_content)
74
75 return object_id
76
77
78 def CheckMimeTypeResizable(mime_type):
79 if mime_type not in RESIZABLE_MIME_TYPES:
80 raise UnsupportedMimeType(
81 'Please upload a logo with one of the following mime types:\n%s' %
82 ', '.join(RESIZABLE_MIME_TYPES))
83
84
85 def StoreLogoInGCS(file_name, content, project_id):
86 mime_type = filecontent.GuessContentTypeFromFilename(file_name)
87 CheckMimeTypeResizable(mime_type)
88 if '\\' in file_name: # IE insists on giving us the whole path.
89 file_name = file_name[file_name.rindex('\\') + 1:]
90 return StoreObjectInGCS(
91 content, mime_type, project_id, thumb_width=LOGO_THUMB_WIDTH,
92 thumb_height=LOGO_THUMB_HEIGHT)
93
94
95 def SignUrl(gcs_filename):
96 expiration_dt = _Now() + ATTACHMENT_TTL
97 expiration = int(time.mktime(expiration_dt.timetuple()))
98 signature_string = '\n'.join([
99 'GET',
100 '', # Optional MD5, which we don't have.
101 '', # Optional content-type, which only applies to uploads.
102 str(expiration),
103 gcs_filename]).encode('utf-8')
104
105 signature_bytes = app_identity.sign_blob(signature_string)[1]
106
107 query_params = {'GoogleAccessId': app_identity.get_service_account_name(),
108 'Expires': str(expiration),
109 'Signature': base64.b64encode(signature_bytes)}
110
111 result = 'https://storage.googleapis.com{resource}?{querystring}'
112
113 if IS_DEV_APPSERVER:
114 result = '/_ah/gcs{resource}?{querystring}'
115
116 return result.format(
117 resource=gcs_filename, querystring=urllib.urlencode(query_params))
118
OLDNEW
« no previous file with comments | « appengine/monorail/framework/framework_views.py ('k') | appengine/monorail/framework/grid_view_helpers.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698