Source code for google.appengine.api.files.gs

#!/usr/bin/env python## Copyright 2007 Google Inc.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#"""Files API... deprecated:: 1.8.1 Use Google Cloud Storage Client library instead.Google Storage specific Files API calls."""from__future__importwith_statement__all__=['create']importosimportrefromurllibimporturlencodefromxml.domimportminidomfromgoogle.appengine.apiimportapp_identityfromgoogle.appengine.apiimporturlfetchfromgoogle.appengine.api.filesimportfileasfilesfromgoogle.appengine.api.filesimportfile_service_pb_GS_FILESYSTEM=files.GS_FILESYSTEM_GS_PREFIX='/'+_GS_FILESYSTEM+'/'_MIME_TYPE_PARAMETER='content_type'_CANNED_ACL_PARAMETER='acl'_CONTENT_ENCODING_PARAMETER='content_encoding'_CONTENT_DISPOSITION_PARAMETER='content_disposition'_CACHE_CONTROL_PARAMETER='cache_control'_USER_METADATA_PREFIX='x-goog-meta-'_GS_RESTFUL_URL='storage.googleapis.com'_GS_RESTFUL_SCOPE_READ_ONLY=('https://www.googleapis.com/auth/devstorage.read_only')_GS_RESTFUL_API_VERSION='2'_GS_BUCKETPATH_REGEX=re.compile(r'/gs/[a-z0-9\.\-_]{3,}$')_GS_FILEPATH_REGEX=re.compile(r'/gs/[a-z0-9\.\-_]{3,}')defparseGlob(filename):"""Parse a Gs filename or a filename pattern. Handle escape of '*' and '/'. Args: filename: a filename or filename pattern. filename must be a valid gs filepath in the format of '/gs/bucket/filename'. filename pattern has format '/gs/bucket/prefix*'. filename pattern represents filenames with the given prefix in the bucket. Please escape '*' and '\' with '\' if your filename contains them. We recommend using Python raw string to simplify escape expressions. Returns: A (string, string) tuple if filename is a pattern. The first string is the bucket name, second is the prefix or '' if prefix doesn't exist. Properly escaped filename if filename is not a pattern. example '/gs/bucket1/file1' => '/gs/bucket1/file1' '/gs/bucket2/*' => ('gs/bucket2', '') all files under bucket2 '/gs/bucket3/p*' => ('gs/bucket2', 'p') files under bucket3 with a prefix 'p' in its name r'/gs/bucket/file\*' => '/gs/bucket/file*' r'/gs/bucket/file\\*' => ('/gs/bucket', r'file\') all files under bucket with prefix r'file\' r'/gs/bucket/file\\\*' => '/gs/bucket/file\*' r'/gs/bucket/file\**' => ('/gs/bucket', 'file*') all files under bucket with prefix 'file*' Raises: google.appengine.api.files.InvalidFileNameError if filename is illegal. """ifnotfilename:raisefiles.InvalidFileNameError('filename is None.')ifnotisinstance(filename,basestring):raisefiles.InvalidFileNameError('filename %s should be of type string'%filename)match=_GS_FILEPATH_REGEX.match(filename)ifnotmatch:raisefiles.InvalidFileNameError('filename %s should start with/gs/bucketname',filename)bucketname=match.group(0)rest=filename[len(bucketname):]ifnotrestor(len(rest)==1andrest[0]=='/'):returnbucketname,''ifnotrest.startswith('/'):raisefiles.InvalidFileNameError('Expect / to separate bucketname and filename in %s'%filename)i=1prefix=Falseprocessed=''whilei<len(rest):char=rest[i]ifchar=='\\':ifi+1==len(rest):processed+=charelse:processed+=rest[i+1]i+=1elifchar=='*':ifi+1!=len(rest):raisefiles.InvalidFileNameError('* as a wildcard is not the last.')prefix=Trueelse:processed+=chari+=1ifprefix:returnbucketname,processedelse:returnbucketname+'/'+processeddeflistdir(path,kwargs=None):"""Return a sorted list of filenames (matching a pattern) in the given path. Sorting (decrease by string) is done automatically by Google Cloud Storage. Args: path: a Google Cloud Storage path of "/gs/bucketname" form. kwargs: other keyword arguments to be relayed to Google Cloud Storage. This can be used to select certain files with names matching a pattern. Supported keywords: marker: a string after which (exclusive) to start listing. max_keys: the maximum number of filenames to return. prefix: limits the returned filenames to those with this prefix. no regex. See Google Cloud Storage documentation for more details and examples. https://developers.google.com/storage/docs/reference-methods#getbucket Returns: a sorted list containing filenames (matching a pattern) from the given path. The last filename can be used as a marker for another request for more files. """ifnotpath:raisefiles.InvalidFileNameError('Empty path')elifnotisinstance(path,basestring):raisefiles.InvalidFileNameError('Expected string for path %s'%path)elifnot_GS_BUCKETPATH_REGEX.match(path):raisefiles.InvalidFileNameError('Google storage path must have the form /gs/bucketname')ifkwargsandkwargs.has_key('max_keys'):kwargs['max-keys']=kwargs['max_keys']kwargs.pop('max_keys')if('SERVER_SOFTWARE'notinos.environoros.environ['SERVER_SOFTWARE'].startswith('Development')):return_listdir_local(path,kwargs)bucketname=path[len(_GS_PREFIX):]request_headers={'Authorization':'OAuth %s'%app_identity.get_access_token(_GS_RESTFUL_SCOPE_READ_ONLY)[0],'x-goog-api-version':_GS_RESTFUL_API_VERSION}url='https://%s/%s'%(_GS_RESTFUL_URL,bucketname)ifkwargs:url+='/?'+urlencode(kwargs)response=urlfetch.fetch(url=url,headers=request_headers,deadline=60)ifresponse.status_code==404:raisefiles.InvalidFileNameError('Bucket %s does not exist.'%bucketname)elifresponse.status_code==401:raisefiles.PermissionDeniedError('Permission denied to read bucket %s.'%bucketname)dom=minidom.parseString(response.content)def__textValue(node):returnnode.firstChild.nodeValueerror=dom.getElementsByTagName('Error')iflen(error)==1:details=error[0].getElementsByTagName('Details')iflen(details)==1:raisefiles.InvalidParameterError(__textValue(details[0]))else:code=__textValue(error[0].getElementsByTagName('Code')[0])msg=__textValue(error[0].getElementsByTagName('Message')[0])raisefiles.InvalidParameterError('%s: %s'%(code,msg))return['/'.join([path,__textValue(key)])forkeyindom.getElementsByTagName('Key')]def_listdir_local(path,kwargs):"""Dev app server version of listdir. See listdir for doc. """request=file_service_pb.ListDirRequest()response=file_service_pb.ListDirResponse()request.set_path(path)ifkwargsandkwargs.has_key('marker'):request.set_marker(kwargs['marker'])ifkwargsandkwargs.has_key('max-keys'):request.set_max_keys(kwargs['max-keys'])ifkwargsandkwargs.has_key('prefix'):request.set_prefix(kwargs['prefix'])files._make_call('ListDir',request,response)returnresponse.filenames_list()

[docs]defcreate(filename,mime_type='application/octet-stream',acl=None,cache_control=None,content_encoding=None,content_disposition=None,user_metadata=None):"""Create a writable googlestore file. Args: filename: Google Storage object name (/gs/bucket/object) mime_type: Blob content MIME type as string. acl: Canned acl to apply to the object as per: http://code.google.com/apis/storage/docs/reference-headers.html#xgoogacl If not specified (or set to None), default object acl is used. cache_control: Cache control header to set when serving through Google storage. If not specified, default of 3600 seconds is used. content_encoding: If object is compressed, specify the compression method here to set the header correctly when served through Google Storage. content_disposition: Header to use when serving through Google Storage. user_metadata: Dictionary specifying key value pairs to apply to the object. Each key is prefixed with x-goog-meta- when served through Google Storage. Returns: A writable file name for a Google Storage file. This file can be opened for write by File API open function. To read the file call file::open with the plain Google Storage filename (/gs/bucket/object). """ifnotfilename:raisefiles.InvalidArgumentError('Empty filename')elifnotisinstance(filename,basestring):raisefiles.InvalidArgumentError('Expected string for filename',filename)elifnotfilename.startswith(_GS_PREFIX)orfilename==_GS_PREFIX:raisefiles.InvalidArgumentError('Google storage files must be of the form /gs/bucket/object',filename)elifnotmime_type:raisefiles.InvalidArgumentError('Empty mime_type')elifnotisinstance(mime_type,basestring):raisefiles.InvalidArgumentError('Expected string for mime_type',mime_type)params={_MIME_TYPE_PARAMETER:mime_type}ifacl:ifnotisinstance(acl,basestring):raisefiles.InvalidArgumentError('Expected string for acl',acl)params[_CANNED_ACL_PARAMETER]=aclifcontent_encoding:ifnotisinstance(content_encoding,basestring):raisefiles.InvalidArgumentError('Expected string for content_encoding')else:params[_CONTENT_ENCODING_PARAMETER]=content_encodingifcontent_disposition:ifnotisinstance(content_disposition,basestring):raisefiles.InvalidArgumentError('Expected string for content_disposition')else:params[_CONTENT_DISPOSITION_PARAMETER]=content_dispositionifcache_control:ifnotisinstance(cache_control,basestring):raisefiles.InvalidArgumentError('Expected string for cache_control')else:params[_CACHE_CONTROL_PARAMETER]=cache_controlifuser_metadata:ifnotisinstance(user_metadata,dict):raisefiles.InvalidArgumentError('Expected dict for user_metadata')forkey,valueinuser_metadata.items():ifnotisinstance(key,basestring):raisefiles.InvalidArgumentError('Expected string for key in user_metadata')ifnotisinstance(value,basestring):raisefiles.InvalidArgumentError('Expected string for value in user_metadata for key: ',key)params[_USER_METADATA_PREFIX+key]=valuereturnfiles._create(_GS_FILESYSTEM,filename=filename,params=params)

defdefault_bucket_name():"""Obtain the default Google Storage bucket name for this application. Returns: A string that is the name of the default bucket. """returnfiles._default_gs_bucket_name()