| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 import json | 5 import json |
| 6 import logging | 6 import logging |
| 7 import os | 7 import os |
| 8 import re | 8 import re |
| 9 import shutil | 9 import shutil |
| 10 import tempfile | 10 import tempfile |
| 11 | 11 |
| 12 from telemetry import page as page_module | 12 from telemetry import page as page_module |
| 13 from telemetry.util import cloud_storage | 13 from telemetry.util import cloud_storage |
| 14 | 14 |
| 15 | 15 |
| 16 def AssertValidCloudStorageBucket(bucket): | 16 def AssertValidCloudStorageBucket(bucket): |
| 17 is_valid = bucket in (None, | 17 is_valid = bucket in (None, |
| 18 cloud_storage.PUBLIC_BUCKET, | 18 cloud_storage.PUBLIC_BUCKET, |
| 19 cloud_storage.PARTNER_BUCKET, | 19 cloud_storage.PARTNER_BUCKET, |
| 20 cloud_storage.INTERNAL_BUCKET) | 20 cloud_storage.INTERNAL_BUCKET) |
| 21 if not is_valid: | 21 if not is_valid: |
| 22 raise ValueError("Cloud storage privacy bucket %s is invalid" % bucket) | 22 raise ValueError("Cloud storage privacy bucket %s is invalid" % bucket) |
| 23 | 23 |
| 24 | 24 |
| 25 class ArchiveError(Exception): |
| 26 pass |
| 27 |
| 28 |
| 25 class WprArchiveInfo(object): | 29 class WprArchiveInfo(object): |
| 26 def __init__(self, file_path, data, bucket, ignore_archive=False): | 30 def __init__(self, file_path, data, bucket): |
| 27 AssertValidCloudStorageBucket(bucket) | 31 AssertValidCloudStorageBucket(bucket) |
| 28 self._file_path = file_path | 32 self._file_path = file_path |
| 29 self._base_dir = os.path.dirname(file_path) | 33 self._base_dir = os.path.dirname(file_path) |
| 34 self._data = data |
| 30 self._bucket = bucket | 35 self._bucket = bucket |
| 31 | 36 |
| 32 # Ensure directory exists. | 37 # Ensure directory exists. |
| 33 if not os.path.exists(self._base_dir): | 38 if not os.path.exists(self._base_dir): |
| 34 os.makedirs(self._base_dir) | 39 os.makedirs(self._base_dir) |
| 35 | 40 |
| 36 # TODO(aiolos): We should take this out of init if we reduce the number of | |
| 37 # supported code paths/configs using archive_info when switching over to | |
| 38 # user_stories. | |
| 39 # Download all .wpr files. | |
| 40 if not ignore_archive: | |
| 41 if not self._bucket: | |
| 42 logging.warning('User story set in %s has no bucket specified, and ' | |
| 43 'cannot be downloaded from cloud_storage.', file_path) | |
| 44 else: | |
| 45 for archive_path in data['archives']: | |
| 46 archive_path = self._WprFileNameToPath(archive_path) | |
| 47 try: | |
| 48 cloud_storage.GetIfChanged(archive_path, bucket) | |
| 49 except (cloud_storage.CredentialsError, | |
| 50 cloud_storage.PermissionError): | |
| 51 if os.path.exists(archive_path): | |
| 52 # If the archive exists, assume the user recorded their own and | |
| 53 # simply warn. | |
| 54 logging.warning('Need credentials to update WPR archive: %s', | |
| 55 archive_path) | |
| 56 else: | |
| 57 logging.error("You either aren't authenticated or don't have " | |
| 58 "permission to use the archives for this page set." | |
| 59 "\nYou may need to run gsutil config") | |
| 60 raise | |
| 61 | |
| 62 # Map from the relative path (as it appears in the metadata file) of the | 41 # Map from the relative path (as it appears in the metadata file) of the |
| 63 # .wpr file to a list of user story names it supports. | 42 # .wpr file to a list of user story names it supports. |
| 64 self._wpr_file_to_user_story_names = data['archives'] | 43 self._wpr_file_to_user_story_names = data['archives'] |
| 65 | 44 |
| 66 # Map from the user_story name to a relative path (as it appears | 45 # Map from the user_story name to a relative path (as it appears |
| 67 # in the metadata file) of the .wpr file. | 46 # in the metadata file) of the .wpr file. |
| 68 self._user_story_name_to_wpr_file = dict() | 47 self._user_story_name_to_wpr_file = dict() |
| 69 # Find out the wpr file names for each user_story. | 48 # Find out the wpr file names for each user_story. |
| 70 for wpr_file in data['archives']: | 49 for wpr_file in data['archives']: |
| 71 user_story_names = data['archives'][wpr_file] | 50 user_story_names = data['archives'][wpr_file] |
| 72 for user_story_name in user_story_names: | 51 for user_story_name in user_story_names: |
| 73 self._user_story_name_to_wpr_file[user_story_name] = wpr_file | 52 self._user_story_name_to_wpr_file[user_story_name] = wpr_file |
| 74 self.temp_target_wpr_file_path = None | 53 self.temp_target_wpr_file_path = None |
| 75 | 54 |
| 76 @classmethod | 55 @classmethod |
| 77 def FromFile(cls, file_path, bucket, ignore_archive=False): | 56 def FromFile(cls, file_path, bucket): |
| 78 if os.path.exists(file_path): | 57 if os.path.exists(file_path): |
| 79 with open(file_path, 'r') as f: | 58 with open(file_path, 'r') as f: |
| 80 data = json.load(f) | 59 data = json.load(f) |
| 81 return cls(file_path, data, bucket, ignore_archive=ignore_archive) | 60 return cls(file_path, data, bucket) |
| 82 return cls(file_path, {'archives': {}}, bucket, | 61 return cls(file_path, {'archives': {}}, bucket) |
| 83 ignore_archive=ignore_archive) | 62 |
| 63 def DownloadArchivesIfNeeded(self): |
| 64 """Downloads archives iff the Archive has a bucket parameter and the user |
| 65 has permission to access the bucket. |
| 66 |
| 67 Raises cloud storage Permissions or Credentials error when there is no |
| 68 local copy of the archive and the user doesn't have permission to access |
| 69 the archive's bucket. |
| 70 |
| 71 Warns when a bucket is not specified or when the user doesn't have |
| 72 permission to access the archive's bucket but a local copy of the archive |
| 73 exists. |
| 74 """ |
| 75 # Download all .wpr files. |
| 76 if self._data: |
| 77 return |
| 78 if not self._bucket: |
| 79 logging.warning('User story set in %s has no bucket specified, and ' |
| 80 'cannot be downloaded from cloud_storage.', ) |
| 81 |
| 82 for archive_path in self._data['archives']: |
| 83 archive_path = self._WprFileNameToPath(archive_path) |
| 84 try: |
| 85 cloud_storage.GetIfChanged(archive_path, self._bucket) |
| 86 except (cloud_storage.CredentialsError, cloud_storage.PermissionError): |
| 87 if os.path.exists(archive_path): |
| 88 # If the archive exists, assume the user recorded their own and |
| 89 # simply warn. |
| 90 logging.warning('Need credentials to update WPR archive: %s', |
| 91 archive_path) |
| 92 else: |
| 93 logging.error("You either aren't authenticated or don't have " |
| 94 "permission to use the archives for this page set." |
| 95 "\nYou may need to run gsutil config.") |
| 96 raise |
| 84 | 97 |
| 85 def WprFilePathForUserStory(self, story): | 98 def WprFilePathForUserStory(self, story): |
| 86 if self.temp_target_wpr_file_path: | 99 if self.temp_target_wpr_file_path: |
| 87 return self.temp_target_wpr_file_path | 100 return self.temp_target_wpr_file_path |
| 88 wpr_file = self._user_story_name_to_wpr_file.get(story.display_name, None) | 101 wpr_file = self._user_story_name_to_wpr_file.get(story.display_name, None) |
| 89 if wpr_file is None and isinstance(story, page_module.Page): | 102 if wpr_file is None and isinstance(story, page_module.Page): |
| 90 # Some old pages always use the URL to identify a page rather than the | 103 # Some old pages always use the URL to identify a page rather than the |
| 91 # display_name, so try to look for that. | 104 # display_name, so try to look for that. |
| 92 wpr_file = self._user_story_name_to_wpr_file.get(story.url, None) | 105 wpr_file = self._user_story_name_to_wpr_file.get(story.url, None) |
| 93 if wpr_file: | 106 if wpr_file: |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 207 |
| 195 def _SetWprFileForUserStory(self, user_story_name, wpr_file): | 208 def _SetWprFileForUserStory(self, user_story_name, wpr_file): |
| 196 """For modifying the metadata when we're going to record a new archive.""" | 209 """For modifying the metadata when we're going to record a new archive.""" |
| 197 old_wpr_file = self._user_story_name_to_wpr_file.get(user_story_name, None) | 210 old_wpr_file = self._user_story_name_to_wpr_file.get(user_story_name, None) |
| 198 if old_wpr_file: | 211 if old_wpr_file: |
| 199 self._wpr_file_to_user_story_names[old_wpr_file].remove(user_story_name) | 212 self._wpr_file_to_user_story_names[old_wpr_file].remove(user_story_name) |
| 200 self._user_story_name_to_wpr_file[user_story_name] = wpr_file | 213 self._user_story_name_to_wpr_file[user_story_name] = wpr_file |
| 201 if wpr_file not in self._wpr_file_to_user_story_names: | 214 if wpr_file not in self._wpr_file_to_user_story_names: |
| 202 self._wpr_file_to_user_story_names[wpr_file] = [] | 215 self._wpr_file_to_user_story_names[wpr_file] = [] |
| 203 self._wpr_file_to_user_story_names[wpr_file].append(user_story_name) | 216 self._wpr_file_to_user_story_names[wpr_file].append(user_story_name) |
| OLD | NEW |