<s> import datetime <EOL> import email <EOL> import mimetypes <EOL> import urlparse <EOL> try : <EOL> from cStringIO import StringIO <EOL> except ImportError : <EOL> from StringIO import StringIO <EOL> from django . conf import settings <EOL> from django . core . exceptions import ImproperlyConfigured <EOL> from django . core . files . base import File <EOL> from django . core . files . storage import Storage <EOL> from django . core . files . uploadedfile import UploadedFile <EOL> from django . core . files . uploadhandler import FileUploadHandler , StopFutureHandlers <EOL> from django . http import HttpResponse <EOL> from django . utils . encoding import smart_str , force_unicode , filepath_to_uri <EOL> try : <EOL> import cloudstorage <EOL> except ImportError : <EOL> cloudstorage = None <EOL> from google . appengine . api import files <EOL> from google . appengine . api . images import get_serving_url , NotImageError , TransformationError , BlobKeyRequiredError <EOL> from google . appengine . ext . blobstore import BlobInfo , BlobKey , delete , create_upload_url , BLOB_KEY_HEADER , BLOB_RANGE_HEADER , BlobReader , create_gs_key , CLOUD_STORAGE_OBJECT_HEADER <EOL> APPENGINE_STORAGE_SERVICE_KEY = '<STR_LIT>' <EOL> CLOUD_STORAGE_DEFAULT_BUCKET_KEY = '<STR_LIT>' <EOL> BLOBSTORE_SERVICE = '<STR_LIT>' <EOL> CLOUD_STORAGE_SERVICE = '<STR_LIT>' <EOL> def prepare_upload ( request , url , storage_service = None , cloud_storage_bucket = None , ** kwargs ) : <EOL> if not storage_service : <EOL> storage_service = getattr ( settings , APPENGINE_STORAGE_SERVICE_KEY , BLOBSTORE_SERVICE ) <EOL> upload_kwargs = { } <EOL> if storage_service == '<STR_LIT>' : <EOL> if not cloud_storage_bucket : <EOL> cloud_storage_bucket = getattr ( settings , CLOUD_STORAGE_DEFAULT_BUCKET_KEY , None ) <EOL> if not cloud_storage_bucket : <EOL> raise ImproperlyConfigured ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> upload_kwargs [ '<STR_LIT>' ] = cloud_storage_bucket <EOL> return create_upload_url ( url , ** upload_kwargs ) , { } <EOL> def serve_file ( request , file , save_as , content_type , ** kwargs ) : <EOL> if hasattr ( file , '<STR_LIT:file>' ) and hasattr ( file . file , '<STR_LIT>' ) : <EOL> blobkey = file . file . blobstore_info . key ( ) <EOL> elif hasattr ( file , '<STR_LIT>' ) : <EOL> blobkey = file . blobstore_info . key ( ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> response = HttpResponse ( content_type = content_type ) <EOL> response [ BLOB_KEY_HEADER ] = str ( blobkey ) <EOL> response [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> http_range = request . META . get ( '<STR_LIT>' ) <EOL> if http_range is not None : <EOL> response [ BLOB_RANGE_HEADER ] = http_range <EOL> if save_as : <EOL> response [ '<STR_LIT>' ] = smart_str ( <EOL> u'<STR_LIT>' % save_as ) <EOL> if file . size is not None : <EOL> response [ '<STR_LIT>' ] = file . size <EOL> return response <EOL> class AppEngineStorage ( Storage ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , storage_service = None , cloud_storage_bucket = None ) : <EOL> super ( AppEngineStorage , self ) . __init__ ( ) <EOL> if not storage_service : <EOL> storage_service = getattr ( settings , APPENGINE_STORAGE_SERVICE_KEY , BLOBSTORE_SERVICE ) <EOL> if not cloud_storage_bucket : <EOL> cloud_storage_bucket = getattr ( settings , CLOUD_STORAGE_DEFAULT_BUCKET_KEY , None ) <EOL> if storage_service not in ( BLOBSTORE_SERVICE , CLOUD_STORAGE_SERVICE ) : <EOL> raise ImproperlyConfigured ( "<STR_LIT>" <EOL> "<STR_LIT>" % storage_service ) <EOL> if storage_service == CLOUD_STORAGE_SERVICE and not cloud_storage_bucket : <EOL> raise ImproperlyConfigured ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> self . storage_service = storage_service <EOL> self . cloud_storage_bucket = cloud_storage_bucket <EOL> def _open ( self , name , mode = '<STR_LIT:rb>' ) : <EOL> return AppEngineFile ( name , mode , self ) <EOL> def _save ( self , name , content ) : <EOL> name = name . replace ( '<STR_LIT:\\>' , '<STR_LIT:/>' ) <EOL> if isinstance ( content , ( AppEngineFile , AppEngineUploadedFile ) ) : <EOL> data = content . blobstore_info <EOL> elif hasattr ( content , '<STR_LIT:file>' ) and isinstance ( content . file , ( AppEngineFile , AppEngineUploadedFile ) ) : <EOL> data = content . file . blobstore_info <EOL> elif isinstance ( content , File ) : <EOL> guessed_type = mimetypes . guess_type ( name ) [ <NUM_LIT:0> ] <EOL> if self . storage_service == CLOUD_STORAGE_SERVICE : <EOL> assert cloudstorage , '<STR_LIT>' <EOL> file_name = '<STR_LIT>' % ( self . cloud_storage_bucket , name ) <EOL> with cloudstorage . open ( file_name , '<STR_LIT:w>' , guessed_type or '<STR_LIT>' ) as f : <EOL> for chunk in content . chunks ( ) : <EOL> f . write ( chunk ) <EOL> data = self . _get_info ( '<STR_LIT>' + file_name ) <EOL> else : <EOL> file_name = files . blobstore . create ( mime_type = guessed_type or '<STR_LIT>' , <EOL> _blobinfo_uploaded_filename = name ) <EOL> with files . open ( file_name , '<STR_LIT:a>' ) as f : <EOL> for chunk in content . chunks ( ) : <EOL> f . write ( chunk ) <EOL> files . finalize ( file_name ) <EOL> data = files . blobstore . get_blob_key ( file_name ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if isinstance ( data , CloudStorageInfo ) : <EOL> return '<STR_LIT>' + data . fullname <EOL> if isinstance ( data , BlobInfo ) : <EOL> data = data . key ( ) <EOL> if isinstance ( data , BlobKey ) : <EOL> return '<STR_LIT>' % ( data , name . lstrip ( '<STR_LIT:/>' ) ) <EOL> raise ValueError ( "<STR_LIT>" % type ( data ) ) <EOL> def delete ( self , name ) : <EOL> self . _get_info ( name ) . delete ( ) <EOL> def exists ( self , name ) : <EOL> info = self . _get_info ( name ) <EOL> return info is not None and ( not hasattr ( info , '<STR_LIT>' ) or info . exists ( ) ) <EOL> def size ( self , name ) : <EOL> return self . _get_info ( name ) . size <EOL> def url ( self , name ) : <EOL> try : <EOL> info = self . _get_info ( name ) <EOL> if not info : <EOL> raise BlobKeyRequiredError ( '<STR_LIT>' % name ) <EOL> return get_serving_url ( info . key ( ) ) <EOL> except ( NotImageError , TransformationError ) : <EOL> return None <EOL> except BlobKeyRequiredError : <EOL> if settings . DEBUG : <EOL> return urlparse . urljoin ( settings . MEDIA_URL , filepath_to_uri ( name ) ) <EOL> else : <EOL> raise <EOL> def created_time ( self , name ) : <EOL> return self . _get_info ( name ) . creation <EOL> def get_valid_name ( self , name ) : <EOL> return force_unicode ( name ) . strip ( ) . replace ( '<STR_LIT:\\>' , '<STR_LIT:/>' ) <EOL> def get_available_name ( self , name ) : <EOL> return name . replace ( '<STR_LIT:\\>' , '<STR_LIT:/>' ) <EOL> def _get_info ( self , name ) : <EOL> if name . startswith ( '<STR_LIT>' ) : <EOL> assert cloudstorage , '<STR_LIT>' <EOL> return CloudStorageInfo ( name ) <EOL> else : <EOL> key = BlobKey ( name . split ( '<STR_LIT:/>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] ) <EOL> return BlobInfo . get ( key ) <EOL> class CloudStorageInfo ( object ) : <EOL> def __init__ ( self , name ) : <EOL> self . fullname = name [ <NUM_LIT:3> : ] <EOL> self . filename = self . fullname . split ( '<STR_LIT:/>' , <NUM_LIT:2> ) [ <NUM_LIT:2> ] <EOL> def delete ( self ) : <EOL> cloudstorage . delete ( self . fullname ) <EOL> def exists ( self ) : <EOL> try : <EOL> cloudstorage . stat ( self . fullname ) <EOL> return True <EOL> except cloudstorage . NotFoundError : <EOL> return False <EOL> def key ( self ) : <EOL> return create_gs_key ( '<STR_LIT>' + self . fullname ) <EOL> def open ( self ) : <EOL> return cloudstorage . open ( self . fullname , '<STR_LIT:r>' ) <EOL> @ property <EOL> def creation ( self ) : <EOL> return datetime . datetime . fromtimestamp ( cloudstorage . stat ( self . fullname ) . st_ctime ) <EOL> @ property <EOL> def size ( self ) : <EOL> return cloudstorage . stat ( self . fullname ) . st_size <EOL> class AppEngineFile ( File ) : <EOL> def __init__ ( self , name , mode , storage ) : <EOL> self . name = name <EOL> self . _storage = storage <EOL> self . _mode = mode <EOL> self . blobstore_info = storage . _get_info ( name ) <EOL> @ property <EOL> def size ( self ) : <EOL> return self . blobstore_info . size <EOL> def write ( self , content ) : <EOL> raise NotImplementedError ( ) <EOL> @ property <EOL> def file ( self ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . _file = self . blobstore_info . open ( ) <EOL> return self . _file <EOL> class AppEngineFileUploadHandler ( FileUploadHandler ) : <EOL> """<STR_LIT>""" <EOL> def new_file ( self , * args , ** kwargs ) : <EOL> super ( AppEngineFileUploadHandler , self ) . new_file ( * args , ** kwargs ) <EOL> blobkey = self . content_type_extra . get ( '<STR_LIT>' ) <EOL> self . activated = blobkey is not None <EOL> if self . activated : <EOL> self . blobkey = BlobKey ( blobkey ) <EOL> self . filename = kwargs . get ( '<STR_LIT>' , None ) <EOL> self . file = StringIO ( ) <EOL> raise StopFutureHandlers ( ) <EOL> def receive_data_chunk ( self , raw_data , start ) : <EOL> """<STR_LIT>""" <EOL> if self . activated : <EOL> self . file . write ( raw_data ) <EOL> else : <EOL> return raw_data <EOL> def file_complete ( self , file_size ) : <EOL> """<STR_LIT>""" <EOL> if not self . activated : <EOL> return <EOL> self . file . seek ( <NUM_LIT:0> ) <EOL> upload_content = email . message_from_file ( self . file ) <EOL> def get_value ( dict , name ) : <EOL> value = dict . get ( name , None ) <EOL> if value is None : <EOL> raise Exception ( '<STR_LIT>' % ( field_name , name ) ) <EOL> return value <EOL> content_type = get_value ( upload_content , '<STR_LIT>' ) <EOL> size = get_value ( upload_content , '<STR_LIT>' ) <EOL> gs_object_name = upload_content . get ( CLOUD_STORAGE_OBJECT_HEADER , None ) <EOL> kwargs = { <EOL> '<STR_LIT>' : self . blobkey , <EOL> '<STR_LIT:name>' : self . file_name , <EOL> '<STR_LIT>' : content_type , <EOL> '<STR_LIT:size>' : int ( size ) , <EOL> '<STR_LIT>' : self . charset , <EOL> } <EOL> return AppEngineUploadedFile ( ** kwargs ) <EOL> class AppEngineUploadedFile ( UploadedFile ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , ** kwargs ) : <EOL> gs_object_name = kwargs . pop ( '<STR_LIT>' , None ) <EOL> blob_key = kwargs . pop ( '<STR_LIT>' , None ) <EOL> if gs_object_name : <EOL> self . blobstore_info = CloudStorageInfo ( gs_object_name ) <EOL> elif blob_key : <EOL> self . blobstore_info = BlobInfo ( blob_key ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> super ( AppEngineUploadedFile , self ) . __init__ ( self . blobstore_info . open ( ) , ** kwargs ) <EOL> def open ( self , mode = None ) : <EOL> pass <EOL> def chunks ( self , chunk_size = <NUM_LIT> * <NUM_LIT> ) : <EOL> self . file . seek ( <NUM_LIT:0> ) <EOL> while True : <EOL> content = self . read ( chunk_size ) <EOL> if not content : <EOL> break <EOL> yield content <EOL> def multiple_chunks ( self , chunk_size = <NUM_LIT> * <NUM_LIT> ) : <EOL> return True <EOL> BlobstoreStorage = AppEngineStorage <EOL> DevBlobstoreStorage = AppEngineStorage <EOL> BlobstoreFile = AppEngineFile <EOL> BlobstoreFileUploadHandler = AppEngineFileUploadHandler <EOL> BlobstoreUploadedFile = AppEngineUploadedFile </s>
