1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch# Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch# found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch"""Implementation of CloudBucket using Google Cloud Storage as the backend.""" 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochimport os 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochimport sys 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochimport cloudstorage 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfrom common import cloud_bucket 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass GoogleCloudStorageBucket(cloud_bucket.BaseCloudBucket): 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch """Subclass of cloud_bucket.CloudBucket with actual GS commands.""" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def __init__(self, bucket): 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch """Initializes the bucket. 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Args: 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bucket: the name of the bucket to connect to. 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch """ 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.bucket = '/' + bucket 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def _full_path(self, path): 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return self.bucket + '/' + path.lstrip('/') 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # override 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def UploadFile(self, path, contents, content_type): 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file = cloudstorage.open( 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self._full_path(path), 'w', content_type=content_type) 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file.write(contents) 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file.close() 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # override 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def DownloadFile(self, path): 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch try: 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file = cloudstorage.open(self._full_path(path), 'r') 39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch r = gs_file.read() 40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file.close() 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch except Exception as e: 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch raise Exception('%s: %s' % (self._full_path(path), str(e))) 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return r 44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # override 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def UpdateFile(self, path, contents): 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if not self.FileExists(path): 48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch raise cloud_bucket.FileNotFoundError 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file = cloudstorage.open(self._full_path(path), 'w') 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file.write(contents) 51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gs_file.close() 52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # override 54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def RemoveFile(self, path): 55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cloudstorage.delete(self._full_path(path)) 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # override 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def FileExists(self, path): 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch try: 60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cloudstorage.stat(self._full_path(path)) 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch except cloudstorage.NotFoundError: 62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return False 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return True 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # override 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def GetImageURL(self, path): 67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return '/image?file_path=%s' % path 68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # override 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def GetAllPaths(self, prefix, max_keys=None, marker=None, delimiter=None): 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return (f.filename[len(self.bucket) + 1:] for f in 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cloudstorage.listbucket(self.bucket, prefix=prefix, 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch max_keys=max_keys, marker=marker, delimiter=delimiter)) 74