| #!/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. |
| |
| Blobstore-specific Files API calls.""" |
| |
| from __future__ import with_statement |
| |
| |
| __all__ = ['create', 'get_blob_key', 'get_file_name'] |
| |
| import hashlib |
| import urllib |
| |
| from google.appengine.api import datastore |
| from google.appengine.api import namespace_manager |
| from google.appengine.api.files import file as files |
| from google.appengine.ext import blobstore |
| |
| |
| |
| _BLOBSTORE_FILESYSTEM = files.BLOBSTORE_FILESYSTEM |
| _BLOBSTORE_DIRECTORY = '/' + _BLOBSTORE_FILESYSTEM + '/' |
| _BLOBSTORE_NEW_FILE_NAME = 'new' |
| _MIME_TYPE_PARAMETER = 'content_type' |
| _BLOBINFO_UPLOADED_FILENAME_PARAMETER = 'file_name' |
| _DATASTORE_MAX_PROPERTY_SIZE = 500 |
| |
| |
| def create(mime_type='application/octet-stream', |
| _blobinfo_uploaded_filename=None): |
| """Create a writable blobstore file. |
| |
| Args: |
| mime_type: Resulting blob content MIME type as string. |
| _blobinfo_uploaded_filename: Resulting blob's BlobInfo file name as string. |
| |
| Returns: |
| A file name for blobstore file. This file can be opened for write |
| by File API open function. To read the file or obtain its blob key, finalize |
| it and call get_blob_key function. |
| """ |
| if not mime_type: |
| raise files.InvalidArgumentError('Empty mime_type') |
| if not isinstance(mime_type, basestring): |
| raise files.InvalidArgumentError('Expected string for mime_type') |
| |
| params = {_MIME_TYPE_PARAMETER: mime_type} |
| if _blobinfo_uploaded_filename: |
| if not isinstance(_blobinfo_uploaded_filename, basestring): |
| raise files.InvalidArgumentError( |
| 'Expected string for _blobinfo_uploaded_filename') |
| params[_BLOBINFO_UPLOADED_FILENAME_PARAMETER] = _blobinfo_uploaded_filename |
| return files._create(_BLOBSTORE_FILESYSTEM, params=params) |
| |
| |
| |
| _BLOB_FILE_INDEX_KIND = '__BlobFileIndex__' |
| |
| |
| |
| _BLOB_KEY_PROPERTY_NAME = 'blob_key' |
| |
| |
| def _get_blob_file_index_key_name(creation_handle): |
| """Get key name for a __BlobFileIndex__ entity. |
| |
| Returns creation_handle if it is < _DATASTORE_MAX_PROPERTY_SIZE |
| symbols and its sha512 otherwise. |
| """ |
| if len(creation_handle) < _DATASTORE_MAX_PROPERTY_SIZE: |
| return creation_handle |
| return hashlib.sha512(creation_handle).hexdigest() |
| |
| |
| def get_blob_key(create_file_name): |
| """Get a blob key for finalized blobstore file. |
| |
| Args: |
| create_file_name: Writable blobstore filename as obtained from create() |
| function. The file should be finalized. |
| |
| Returns: |
| An instance of apphosting.ext.blobstore.BlobKey for corresponding blob |
| or None if the blob referred to by the file name is not finalized. |
| |
| Raises: |
| google.appengine.api.files.InvalidFileNameError if the file name is not |
| a valid nonfinalized blob file name. |
| """ |
| if not create_file_name: |
| raise files.InvalidArgumentError('Empty file name') |
| if not isinstance(create_file_name, basestring): |
| raise files.InvalidArgumentError('Expected string for file name') |
| if not create_file_name.startswith(_BLOBSTORE_DIRECTORY): |
| raise files.InvalidFileNameError( |
| 'Filename %s passed to get_blob_key doesn\'t have prefix %s' % |
| (create_file_name, _BLOBSTORE_DIRECTORY)) |
| ticket = create_file_name[len(_BLOBSTORE_DIRECTORY):] |
| |
| if not ticket.startswith(files._CREATION_HANDLE_PREFIX): |
| |
| return blobstore.BlobKey(ticket) |
| |
| |
| |
| blob_file_index = datastore.Get([datastore.Key.from_path( |
| _BLOB_FILE_INDEX_KIND, |
| _get_blob_file_index_key_name(ticket), |
| namespace='')])[0] |
| if blob_file_index: |
| blob_key_str = blob_file_index[_BLOB_KEY_PROPERTY_NAME] |
| |
| |
| |
| |
| |
| |
| |
| results = datastore.Get([datastore.Key.from_path( |
| blobstore.BLOB_INFO_KIND, blob_key_str, namespace='')]) |
| if results[0] is None: |
| return None |
| elif len(ticket) >= _DATASTORE_MAX_PROPERTY_SIZE: |
| return None |
| else: |
| |
| |
| |
| |
| query = datastore.Query(blobstore.BLOB_INFO_KIND, |
| {'creation_handle =': ticket}, |
| keys_only=True, |
| namespace='') |
| results = query.Get(1) |
| if not results: |
| return None |
| blob_key_str = results[0].name() |
| return blobstore.BlobKey(blob_key_str) |
| |
| |
| def get_file_name(blob_key): |
| """Get a filename to read from the blob. |
| |
| Args: |
| blob_key: An instance of BlobKey. |
| |
| Returns: |
| File name as string which can be used with File API to read the file. |
| """ |
| if not blob_key: |
| raise files.InvalidArgumentError('Empty blob key') |
| if not isinstance(blob_key, (blobstore.BlobKey, basestring)): |
| raise files.InvalidArgumentError('Expected string or blobstore.BlobKey') |
| return '%s%s' % (_BLOBSTORE_DIRECTORY, blob_key) |