- Timestamp:
- 16 Nov 2011, 18:05:03 (13 years ago)
- Location:
- main/waeup.sirp/trunk/src/waeup/sirp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.sirp/trunk/src/waeup/sirp/imagestorage.py
r7105 r7120 20 20 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 21 ## 22 """A storage for image files.22 """A storage for image (and other) files. 23 23 24 24 A few words about storing files with ``waeup.sirp``. The need for this … … 84 84 Later, we can get the file back like this: 85 85 86 >>> store.getFile('myfile .txt')86 >>> store.getFile('myfile') 87 87 <open file ...> 88 89 Please note, that we ask for ``myfile`` instead of ``myfile.jpg`` as 90 the file id should not make a difference for different filename 91 extensions. The file id for ``sample.jpg`` thus could simply be 92 ``sample``. 88 93 89 94 What we get back is a file or file-like object already opened for 90 95 reading: 91 96 92 >>> store.getFile('myfile .txt').read()97 >>> store.getFile('myfile').read() 93 98 'some file content' 94 99 … … 106 111 this:: 107 112 108 __<MARKER-STRING>__real-filename .jpg113 __<MARKER-STRING>__real-filename 109 114 110 115 Please note the double underscores before and after the marker … … 128 133 case. For example if the file id would be 129 134 130 ``__IMG_USER__manfred .jpg``135 ``__IMG_USER__manfred`` 131 136 132 137 then the looked up utility should be registered under name … … 137 142 such utility can be found, a default handler is used instead 138 143 (see :class:`DefaultFileStoreHandler`). 144 145 **About File IDs and Filenames** 146 147 In the waeup.sirp package we want to store documents like CVs, 148 photographs, and similar. Each of this documents might come into the 149 system with different filename extensions. This could be a problem as 150 the browser components might have to set different response headers 151 for different filetypes and we nevertheless want to make sure that 152 only one file is stored per document. For instance we don't want 153 ``passport.jpg`` *and* ``passport.png`` but only one of them. 154 155 The default components like :class:`DefaultFileStoreHandler` take care 156 of this by searching the filesystem for already existing files with 157 same file id and eventually removing them. 158 159 Therefore file ids should never include filename extensions (except if 160 you only support exactly one filename extension for a certain 161 document). The only part where you should add an extension (and it is 162 important to do so) is when creating new files: when a file was 163 uploaded you can pass in the filename (including the filename 164 extension) and the file stored in external file store will (most 165 probably) have a different name but the same extension as the original 166 file. 167 168 When looking for the file, you however only have to give the file id 169 and the handlers should find the right file for you, regardless of the 170 filename extension it has. 139 171 140 172 **Context Adapters: Knowing Your Family** … … 148 180 filename. You then would create filenames of a format like this:: 149 181 150 __<MARKER-STRING>__applicant0001 .jpg182 __<MARKER-STRING>__applicant0001 151 183 152 184 where ``applicant0001`` would tell exactly which applicant you can see … … 182 214 183 215 """ 216 import glob 184 217 import grok 185 218 import os … … 401 434 """Store a file. 402 435 """ 403 file_id = filename404 436 root = self.root # Calls to self.root are expensive 405 marker, filename, base, ext = self.extractMarker(file_id) 437 file_id = os.path.splitext(filename)[0] 438 marker, filename, base, ext = self.extractMarker(filename) 406 439 handler = queryUtility(IFileStoreHandler, name=marker, 407 440 default=DefaultFileStoreHandler()) 408 441 f, path, file_obj = handler.createFile( 409 self, root, file _id, filename, f)442 self, root, filename, file_id, f) 410 443 dirname = os.path.dirname(path) 411 444 if not os.path.exists(dirname): … … 480 513 grok.implements(IFileStoreHandler) 481 514 515 def _searchInPath(self, path): 516 """Get complete path of any existing file starting with `path`. 517 518 If no such file can be found, return input path. 519 520 If multiple such files exist, return the first one. 521 522 **Example:** 523 524 Looking for a `path`:: 525 526 '/tmp/myfile' 527 528 will find any file like ``'/tmp/myfile.txt'``, 529 ``'/tmp/myfile.jpg'`` and so on, if it exists. 530 """ 531 result = path 532 if os.path.isdir(os.path.dirname(path)): 533 file_iter = glob.iglob('%s*' % (path,)) 534 try: 535 result = file_iter.next() 536 except StopIteration: 537 pass 538 return result 539 482 540 def pathFromFileID(self, store, root, file_id): 483 """Return the root path of external file store appended by file id. 484 """ 485 return os.path.join(root, file_id) 541 """Return a path for getting/storing a file with given file id. 542 543 If there is already a file stored for the given file id, the 544 path to this file is returned. 545 546 If no such file exists yet (or the the only file existing has 547 no filename extension at all) a path to store the file but 548 without any filename extension is returned. 549 """ 550 path = os.path.join(root, file_id) 551 return self._searchInPath(path) 486 552 487 553 def createFile(self, store, root, filename, file_id, f): … … 503 569 file itself, it should leave that task to the calling file 504 570 store. 505 """ 571 572 This method does, however, remove any existing files stored 573 under the given file id. 574 """ 575 ext = os.path.splitext(filename)[1] 506 576 path = self.pathFromFileID(store, root, file_id) 507 return f, path, HurryFile(filename, file_id) 577 base, old_ext = os.path.splitext(path) 578 if old_ext != ext: 579 if os.path.exists(path): 580 os.unlink(path) 581 path = base + ext 582 return f, path, HurryFile(filename, file_id + ext) -
main/waeup.sirp/trunk/src/waeup/sirp/tests/test_imagestorage.py
r7105 r7120 104 104 return 105 105 106 def test_create_file_w_ext(self): 107 # We can store files with filename extension 108 storage = ExtFileStore(root=self.workdir) 109 dummy_file = StringIO('sample file') 110 image_file = storage.createFile('mysample.txt', dummy_file) 111 self.assertTrue('mysample.txt' in os.listdir(storage.root)) 112 self.assertEqual('mysample.txt', image_file.data) 113 return 114 106 115 def test_get_file(self): 107 116 # We can get files after having them stored … … 111 120 result = storage.getFile(image_file.data) 112 121 self.assertEqual(result.read(), 'sample file') 122 return 123 124 def test_get_file_w_ext(self): 125 # We can get files with filename extension after having them 126 # stored 127 storage = ExtFileStore(root=self.workdir) 128 dummy_file = StringIO('sample file') 129 image_file = storage.createFile('mysample.txt', dummy_file) 130 result = storage.getFile('mysample') 131 self.assertEqual(result.read(), 'sample file') 132 return 133 134 def test_replace_file_w_new_ext(self): 135 # when we store a file with the same file_id but different 136 # filename extension, the old file will be deleted 137 storage = ExtFileStore(root=self.workdir) 138 dummy_file = StringIO('sample_file') 139 image_file = storage.createFile('mysample.jpg', dummy_file) 140 file1_path = storage.getFile('mysample').name 141 new_file = storage.createFile( 142 'mysample.png', StringIO('new file')) 143 file2 = storage.getFile('mysample') 144 self.assertEqual(file2.name[-12:], 'mysample.png') 145 self.assertEqual(file2.read(), 'new file') 146 # the old file was deleted 147 self.assertFalse(os.path.exists(file1_path)) 113 148 return 114 149 … … 147 182 return os.path.join(root, file_id[12:]) 148 183 149 def createFile(self, store, root, file_id, filename, f): 150 path = self.pathFromFileID(store, root, file_id) 151 return f, path, HurryFile(filename, file_id) 184 def createFile(self, store, root, filename, file_id, f): 185 ext = os.path.splitext(filename)[1] 186 path = self.pathFromFileID(store, root, file_id) + ext 187 return f, path, HurryFile(filename, file_id + ext) 152 188 153 189 class CustomContext(object): … … 162 198 # the `attr` parameter, a simple string. 163 199 if attr=='img': 164 return '__mymarker__mysample .jpg'200 return '__mymarker__mysample_img.jpg' 165 201 elif attr=='doc': 166 return '__mymarker__mysample .doc'202 return '__mymarker__mysample_doc.doc' 167 203 return '__mymarker__mysample.txt' 168 204 … … 246 282 return 247 283 284 def test_customized_handler_create_file_w_ext(self): 285 # when we create a file of img type, the filename ext is taken 286 # from input file. 287 fs = ExtFileStore() 288 result = fs.createFile( 289 '__MYMARKER__sample_img.png', StringIO('sample text')) 290 self.assertEqual(result.data, '__MYMARKER__sample_img.png') 291 self.assertTrue('sample_img.png' in os.listdir(fs.root)) 292 return 293 248 294 def test_customized_handler_get_file(self): 249 295 # we consider registered filename handlers when asking for … … 279 325 # each file has a different file id 280 326 self.assertEqual(file_id1, '__mymarker__mysample.txt') 281 self.assertEqual(file_id2, '__mymarker__mysample .jpg')282 self.assertEqual(file_id3, '__mymarker__mysample .doc')327 self.assertEqual(file_id2, '__mymarker__mysample_img.jpg') 328 self.assertEqual(file_id3, '__mymarker__mysample_doc.doc') 283 329 # each file has different content 284 330 self.assertEqual(result1.read(), 'my sample 1')
Note: See TracChangeset for help on using the changeset viewer.