Package Camelot :: Package camelot :: Package core :: Package files :: Module storage
[frames] | no frames]

Source Code for Module Camelot.camelot.core.files.storage

  1  # -*- coding: utf8 -*- 
  2   
  3  import logging 
  4   
  5  logger = logging.getLogger( 'camelot.core.files.storage' ) 
  6   
  7  from camelot.view.model_thread import model_function 
8 9 -class StoredFile( object ):
10 """Helper class for the File field type. 11 Stored file objects can be used within the GUI thread, as none of 12 its methods should block. 13 """ 14
15 - def __init__( self, storage, name ):
16 """ 17 :param storage: the storage in which the file is stored 18 :param name: the key by which the file is known in the storage""" 19 self.storage = storage 20 self.name = name
21 22 @property
23 - def verbose_name( self ):
24 """The name of the file, as it is to be displayed in the GUI""" 25 return self.name
26
27 - def __unicode__( self ):
28 return self.verbose_name
29
30 -class StoredImage( StoredFile ):
31 """Helper class for the Image field type Class linking an image and the 32 location and filename where the image is stored""" 33 34 @model_function
35 - def checkout_image( self ):
36 """Checkout the image from the storage, and return a QImage""" 37 from PyQt4.QtGui import QImage 38 p = self.storage.checkout( self ) 39 return QImage( p )
40 41 @model_function
42 - def checkout_thumbnail( self, width, height ):
43 """Checkout a thumbnail for this image form the storage 44 :return: a QImage""" 45 from PyQt4.QtCore import Qt 46 original_image = self.checkout_image() 47 return original_image.scaled( width, height, Qt.KeepAspectRatio )
48
49 -class Storage( object ):
50 """Helper class that opens and saves StoredFile objects 51 The default implementation stores files in the settings.CAMELOT_MEDIA_ROOT 52 directory. The storage object should only be used within the model thread, 53 as all of it's methods might block. 54 55 The methods of this class don't verify if they are called on the model 56 thread, because these classes can be used on the server as well. 57 """ 58
59 - def __init__( self, upload_to = '', stored_file_implementation = StoredFile ):
60 """ 61 :param upload_to: the sub directory in which to put files 62 :param stored_file_implementation: the subclass of StoredFile to be used when 63 checking out files from the storage 64 """ 65 import settings 66 import os 67 self.upload_to = os.path.join( settings.CAMELOT_MEDIA_ROOT, upload_to ) 68 self.stored_file_implementation = stored_file_implementation
69 # 70 # don't do anything here that might reduce the startup time, like verifying the 71 # availability of the storage, sinde the path might be on a slow network share 72 # 73
74 - def available(self):
75 """Verify if the storage is available 76 """ 77 import os 78 try: 79 if not os.path.exists( self.upload_to ): 80 os.makedirs( self.upload_to ) 81 return True 82 except Exception, e: 83 logger.warn( 'Could not access or create path %s, files will be unreachable' % self.upload_to, exc_info = e ) 84 return False
85
86 - def exists( self, name ):
87 """True if a file exists given some name""" 88 if self.available(): 89 import os 90 os.path.exists( self.path( name ) ) 91 return False
92
93 - def list(self, prefix='*', suffix='*'):
94 """Lists all files with a given prefix and or suffix available in this storage 95 :return: a iterator of StoredFile objects 96 """ 97 import glob 98 import os 99 return (StoredFile(self, name) for name in glob.glob( os.path.join( self.upload_to, u'%s*%s'%(prefix, suffix) ) ) )
100
101 - def path( self, name ):
102 """The local filesystem path where the file can be opened using Python’s standard open""" 103 import os 104 return os.path.join( self.upload_to, name )
105
106 - def checkin( self, local_path ):
107 """Check the file pointed to by local_path into the storage, and 108 return a StoredFile""" 109 self.available() 110 import tempfile 111 import shutil 112 import os 113 root, extension = os.path.splitext( os.path.basename( local_path ) ) 114 ( handle, to_path ) = tempfile.mkstemp( suffix = extension, prefix = root, dir = self.upload_to, text = 'b' ) 115 os.close( handle ) 116 logger.debug( 'copy file from %s to %s', local_path, to_path ) 117 shutil.copy( local_path, to_path ) 118 return self.stored_file_implementation( self, os.path.basename( to_path ) )
119
120 - def checkin_stream( self, prefix, suffix, stream ):
121 """Check the datastream in as a file into the storage 122 :param prefix: the prefix to use for generating a file name 123 :param suffix: the suffix to use for generating a filen name, eg '.png' 124 :return: a StoredFile""" 125 self.available() 126 import tempfile 127 import os 128 ( handle, to_path ) = tempfile.mkstemp( suffix = suffix, prefix = prefix, dir = self.upload_to, text = 'b' ) 129 file = os.fdopen( handle, 'wb' ) 130 file.write( stream.read() ) 131 file.flush() 132 file.close() 133 return self.stored_file_implementation( self, os.path.basename( to_path ) )
134
135 - def checkout( self, stored_file ):
136 """Check the file pointed to by the local_path out of the storage and return 137 a local filesystem path where the file can be opened""" 138 self.available() 139 import os 140 return os.path.join( self.upload_to, stored_file.name )
141
142 - def checkout_stream( self, stored_file ):
143 """Check the file stored_file out of the storage as a datastream 144 :return: a file object 145 """ 146 self.available() 147 import os 148 return open( os.path.join( self.upload_to, stored_file.name ), 'rb' )
149
150 - def delete( self, name ):
151 pass
152
153 -class S3Storage( object ):
154 """Helper class that opens and saves StoredFile objects into Amazon S3. 155 156 these attibutes need to be set in your settings for S3Storage to work : 157 * AWS_ACCESS_KEY_ID = '<INSERT YOUR AWS ACCESS KEY ID HERE>' 158 * AWS_SECRET_ACCESS_KEY = '<INSERT YOUR AWS SECRET ACCESS KEY HERE>' 159 * AWS_BUCKET_NAME = 'camelot' 160 * AWS_LOCATION = S3.Location.DEFAULT 161 162 Using this Storage requires the availability of S3.py on your PYTHONPATH. 163 S3.py can be found on the amazon.com website 164 """ 165
166 - def __init__( self, upload_to = '', stored_file_implementation = StoredFile ):
167 # try to work around bug S3 code which uses bad names of days 168 # http://code.google.com/p/boto/issues/detail?id=140 169 # but workaround doesn't work :( 170 #import locale 171 # locale.setlocale(locale.LC_TIME, 'en_US.utf8') 172 # print 'create S3 storage' 173 import settings 174 import S3 175 self.upload_to = upload_to 176 conn = S3.AWSAuthConnection( settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY ) 177 # _generator = S3.QueryStringAuthGenerator( settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY ) 178 if ( conn.check_bucket_exists( settings.AWS_BUCKET_NAME ).status == 200 ): 179 pass 180 else: 181 conn.create_located_bucket( settings.AWS_BUCKET_NAME, settings.AWS_LOCATION ).message
182