OLD | NEW |
---|---|
1 # Copyright 2017 The Chromium Authors. All rights reserved. | 1 # Copyright 2017 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Helper functions to upload data to Google Storage. | 5 """Helper functions to upload data to Google Storage. |
6 | 6 |
7 Text data should be streamed to logdog using |logdog_helper| module. | 7 Text data should be streamed to logdog using |logdog_helper| module. |
8 Due to logdog not having image or HTML viewer, those instead should be uploaded | 8 Due to logdog not having image or HTML viewer, those instead should be uploaded |
9 to Google Storage directly using this module. | 9 to Google Storage directly using this module. |
10 """ | 10 """ |
11 | 11 |
12 import logging | 12 import logging |
13 import os | 13 import os |
14 import sys | 14 import sys |
15 import time | 15 import time |
16 | 16 |
17 from pylib.constants import host_paths | 17 from pylib.constants import host_paths |
18 from pylib.utils import decorators | 18 from pylib.utils import decorators |
19 | 19 |
20 if host_paths.DEVIL_PATH not in sys.path: | 20 if host_paths.DEVIL_PATH not in sys.path: |
21 sys.path.append(host_paths.DEVIL_PATH) | 21 sys.path.append(host_paths.DEVIL_PATH) |
22 from devil.android import md5sum | |
jbudorick
2017/05/12 17:13:59
Using this is fine (if not a bit unusual for a pur
mikecase (-- gone --)
2017/05/12 17:39:04
done. I agree this is definitely better
| |
22 from devil.utils import cmd_helper | 23 from devil.utils import cmd_helper |
23 | 24 |
24 _GSUTIL_PATH = os.path.join( | 25 _GSUTIL_PATH = os.path.join( |
25 host_paths.DIR_SOURCE_ROOT, 'third_party', 'catapult', | 26 host_paths.DIR_SOURCE_ROOT, 'third_party', 'catapult', |
26 'third_party', 'gsutil', 'gsutil.py') | 27 'third_party', 'gsutil', 'gsutil.py') |
27 _PUBLIC_URL = 'https://storage.googleapis.com/%s/' | 28 _PUBLIC_URL = 'https://storage.googleapis.com/%s/' |
28 _AUTHENTICATED_URL = 'https://storage.cloud.google.com/%s/' | 29 _AUTHENTICATED_URL = 'https://storage.cloud.google.com/%s/' |
29 | 30 |
30 | 31 |
31 @decorators.NoRaiseException(default_return_value='') | 32 @decorators.NoRaiseException(default_return_value='') |
32 def upload(name, filepath, bucket, content_type=None, authenticated_link=True): | 33 def upload(name, filepath, bucket, content_type=None, authenticated_link=True): |
33 """Uploads data to Google Storage. | 34 """Uploads data to Google Storage. |
34 | 35 |
35 Args: | 36 Args: |
36 name: Name of the file on Google Storage. | 37 name: Name of the file on Google Storage. |
37 filepath: Path to file you want to upload. | 38 filepath: Path to file you want to upload. |
38 bucket: Bucket to upload file to. | 39 bucket: Bucket to upload file to. |
39 content_type: Content type to upload as. If not specified, Google storage | 40 content_type: Content type to upload as. If not specified, Google storage |
40 will attempt to infer content type from file extension. | 41 will attempt to infer content type from file extension. |
41 authenticated_link: Whether to return a link that requires user to | 42 authenticated_link: Whether to return a link that requires user to |
42 authenticate with a Google account. Setting this to false will return | 43 authenticate with a Google account. Setting this to false will return |
43 a link that does not require user to be signed into Google account but | 44 a link that does not require user to be signed into Google account but |
44 will only work for completely public storage buckets. | 45 will only work for completely public storage buckets. |
45 Returns: | 46 Returns: |
46 Web link to item uploaded to Google Storage bucket. | 47 Web link to item uploaded to Google Storage bucket. |
47 """ | 48 """ |
48 if bucket.startswith('gs://'): | 49 bucket = _format_bucket_name(bucket) |
49 bucket = bucket[len('gs://'):] | |
50 if bucket.endswith('/'): | |
51 bucket = bucket[:-1] | |
52 | 50 |
53 gs_path = 'gs://%s/%s' % (bucket, name) | 51 gs_path = 'gs://%s/%s' % (bucket, name) |
54 logging.info('Uploading %s to %s', filepath, gs_path) | 52 logging.info('Uploading %s to %s', filepath, gs_path) |
55 | 53 |
56 cmd = [_GSUTIL_PATH, '-q'] | 54 cmd = [_GSUTIL_PATH, '-q'] |
57 if content_type: | 55 if content_type: |
58 cmd.extend(['-h', 'Content-Type:%s' % content_type]) | 56 cmd.extend(['-h', 'Content-Type:%s' % content_type]) |
59 cmd.extend(['cp', filepath, gs_path]) | 57 cmd.extend(['cp', filepath, gs_path]) |
60 | 58 |
61 cmd_helper.RunCmd(cmd) | 59 cmd_helper.RunCmd(cmd) |
62 | 60 |
63 url_template = _AUTHENTICATED_URL if authenticated_link else _PUBLIC_URL | 61 return get_url_link(name, bucket, authenticated_link) |
64 return os.path.join(url_template % bucket, name) | 62 |
63 | |
64 def upload_content_addressed( | |
65 filepath, bucket, content_type=None, authenticated_link=True): | |
66 """Uploads data to Google Storage with filename as md5sum hash. If file | |
jbudorick
2017/05/12 17:13:59
nit:
"""Summary on one line.
Other lines.
"""
mikecase (-- gone --)
2017/05/12 17:39:04
Done
| |
67 already exists in bucket with hash name, nothing is uploaded.""" | |
68 md5 = md5sum.CalculateHostMd5Sums(filepath)[filepath] | |
69 if not exists(md5, bucket): | |
70 upload(md5, filepath, bucket, content_type, authenticated_link) | |
71 return get_url_link(md5, bucket, authenticated_link) | |
72 | |
73 | |
74 @decorators.NoRaiseException(default_return_value=False) | |
75 def exists(name, bucket): | |
76 bucket = _format_bucket_name(bucket) | |
77 gs_path = 'gs://%s/%s' % (bucket, name) | |
78 | |
79 cmd = [_GSUTIL_PATH, '-q', 'stat', gs_path] | |
80 return_code = cmd_helper.RunCmd(cmd) | |
81 if return_code == 0: | |
82 return True | |
83 else: | |
84 return False | |
65 | 85 |
66 | 86 |
67 def unique_name(basename, suffix='', timestamp=True, device=None): | 87 def unique_name(basename, suffix='', timestamp=True, device=None): |
68 """Helper function for creating a unique name for a file to store in GS. | 88 """Helper function for creating a unique name for a file to store in GS. |
69 | 89 |
70 Args: | 90 Args: |
71 basename: Base of the unique filename. | 91 basename: Base of the unique filename. |
72 suffix: Suffix of filename. | 92 suffix: Suffix of filename. |
73 timestamp: Whether or not to add a timestamp to name. | 93 timestamp: Whether or not to add a timestamp to name. |
74 device: Device to add device serial of to name. | 94 device: Device to add device serial of to name. |
(...skipping 12 matching lines...) Expand all Loading... | |
87 Args: | 107 Args: |
88 name: Name of the file on Google Storage. | 108 name: Name of the file on Google Storage. |
89 bucket: Bucket to upload file to. | 109 bucket: Bucket to upload file to. |
90 authenticated_link: Whether to return a link that requires user to | 110 authenticated_link: Whether to return a link that requires user to |
91 authenticate with a Google account. Setting this to false will return | 111 authenticate with a Google account. Setting this to false will return |
92 a link that does not require user to be signed into Google account but | 112 a link that does not require user to be signed into Google account but |
93 will only work for completely public storage buckets. | 113 will only work for completely public storage buckets. |
94 Returns: | 114 Returns: |
95 Web link to item to be uploaded to Google Storage bucket | 115 Web link to item to be uploaded to Google Storage bucket |
96 """ | 116 """ |
117 bucket = _format_bucket_name(bucket) | |
118 url_template = _AUTHENTICATED_URL if authenticated_link else _PUBLIC_URL | |
119 return os.path.join(url_template % bucket, name) | |
120 | |
121 | |
122 def _format_bucket_name(bucket): | |
97 if bucket.startswith('gs://'): | 123 if bucket.startswith('gs://'): |
98 bucket = bucket[len('gs://'):] | 124 bucket = bucket[len('gs://'):] |
99 if bucket.endswith('/'): | 125 if bucket.endswith('/'): |
100 bucket = bucket[:-1] | 126 bucket = bucket[:-1] |
101 url_template = _AUTHENTICATED_URL if authenticated_link else _PUBLIC_URL | 127 return bucket |
102 return os.path.join(url_template % bucket, name) | |
OLD | NEW |