Index: main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/applicants/tests/test_applicant.py
===================================================================
--- main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/applicants/tests/test_applicant.py	(revision 7033)
+++ main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/applicants/tests/test_applicant.py	(revision 7034)
@@ -39,5 +39,5 @@
 from waeup.sirp.image import WAeUPImageFile, createWAeUPImageFile
 from waeup.sirp.image.interfaces import IWAeUPImageFile
-from waeup.sirp.imagestorage import ImageStorageFileRetrieval, DefaultStorage
+from waeup.sirp.imagestorage import DefaultStorage
 from waeup.sirp.interfaces import IFileStoreHandler, IFileStoreNameChooser
 from waeup.sirp.applicants import (
@@ -218,7 +218,4 @@
     def setUp(self):
         super(ApplicantFactoryTest, self).setUp()
-        # Install a IFileRetrieval utility that returns WAeUPImageFiles.
-        storage = ImageStorageFileRetrieval()
-        #provideUtility(storage, IFileRetrieval)
         self.factory = ApplicantFactory()
         return
Index: main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/applicants/tests/test_browser.py
===================================================================
--- main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/applicants/tests/test_browser.py	(revision 7033)
+++ main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/applicants/tests/test_browser.py	(revision 7034)
@@ -748,5 +748,4 @@
         file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
         self.browser.getControl("Save").click() # submit form
-        storage = self.app['images']
         storage = getUtility(IExtFileStore)
         file_id = IFileStoreNameChooser(self.applicant).chooseName()
Index: main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/imagestorage.py
===================================================================
--- main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/imagestorage.py	(revision 7033)
+++ main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/imagestorage.py	(revision 7034)
@@ -200,13 +200,4 @@
 from waeup.sirp.utils.helpers import cmp_files
 
-def md5digest(fd):
-    """Get an MD5 hexdigest for the file stored in `fd`.
-
-    `fd`
-      a file object open for reading.
-
-    """
-    return hashlib.md5(fd.read()).hexdigest()
-
 class FileStoreNameChooser(grok.Adapter):
     """Default file store name chooser.
@@ -252,200 +243,4 @@
             return name
         return u'unknown_file'
-
-class Basket(grok.Container):
-    """A basket holds a set of image files with same hash.
-
-    It is used for storing files as blobs in ZODB. Current sites do
-    not use it.
-
-    .. deprecated:: 0.2
-
-    """
-
-    def _del(self):
-        """Remove temporary files associated with local blobs.
-
-        A basket holds files as Blob objects. Unfortunately, if a
-        basket was not committed (put into ZODB), those blobs linger
-        around as real files in some temporary directory and won't be
-        removed.
-
-        This is a helper function to remove all those uncommitted
-        blobs that has to be called explicitly, for instance in tests.
-        """
-        key_list = self.keys()
-        for key in key_list:
-            item = self[key]
-            if getattr(item, '_p_oid', None):
-                # Don't mess around with blobs in ZODB
-                continue
-            fd = item.open('r')
-            name = getattr(fd, 'name', None)
-            fd.close()
-            if name is not None and os.path.exists(name):
-                os.unlink(name)
-            del self[key]
-        return
-
-    def getInternalId(self, fd):
-        """Get the basket-internal id for the file stored in `fd`.
-
-        `fd` must be a file open for reading. If an (byte-wise) equal
-        file can be found in the basket, its internal id (basket id)
-        is returned, ``None`` otherwise.
-        """
-        fd.seek(0)
-        for key, val in self.items():
-            fd_stored = val.open('r')
-            file_len = os.stat(fd_stored.name)[6]
-            if file_len == 0:
-                # Nasty workaround. Blobs seem to suffer from being emptied
-                # accidentally.
-                site = grok.getSite()
-                if site is not None:
-                    site.logger.warn(
-                        'Empty Blob detected: %s' % fd_stored.name)
-                warnings.warn("EMPTY BLOB DETECTED: %s" % fd_stored.name)
-                fd_stored.close()
-                val.open('w').write(fd.read())
-                return key
-            fd_stored.seek(0)
-            if cmp_files(fd, fd_stored):
-                fd_stored.close()
-                return key
-            fd_stored.close()
-        return None
-
-    @property
-    def curr_id(self):
-        """The current basket id.
-
-        An integer number which is not yet in use. If there are
-        already `maxint` entries in the basket, a :exc:`ValueError` is
-        raised. The latter is _highly_ unlikely. It would mean to have
-        more than 2**32 hash collisions, i.e. so many files with the
-        same MD5 sum.
-        """
-        num = 1
-        while True:
-            if str(num) not in self.keys():
-                return str(num)
-            num += 1
-            if num <= 0:
-                name = getattr(self, '__name__', None)
-                raise ValueError('Basket full: %s' % name)
-
-    def storeFile(self, fd, filename):
-        """Store the file in `fd` into the basket.
-
-        The file will be stored in a Blob.
-        """
-        fd.seek(0)
-        internal_id = self.getInternalId(fd) # Moves file pointer!
-        if internal_id is None:
-            internal_id = self.curr_id
-            fd.seek(0)
-            self[internal_id] = Blob()
-            transaction.commit() # Urgently needed to make the Blob
-                                 # persistent. Took me ages to find
-                                 # out that solution, which makes some
-                                 # design flaw in ZODB Blobs likely.
-            self[internal_id].open('w').write(fd.read())
-            fd.seek(0)
-            self._p_changed = True
-        return internal_id
-
-    def retrieveFile(self, basket_id):
-        """Retrieve a file open for reading with basket id `basket_id`.
-
-        If there is no such id, ``None`` is returned. It is the
-        callers responsibility to close the open file.
-        """
-        if basket_id in self.keys():
-            return self[basket_id].open('r')
-        return None
-
-class ImageStorage(grok.Container):
-    """A container for image files.
-
-    .. deprecated:: 0.2
-
-       Use :class:`waeup.sirp.ExtFileStore` instead.
-    """
-    def _del(self):
-        for basket in self.values():
-            try:
-                basket._del()
-            except:
-                pass
-
-    def storeFile(self, fd, filename):
-        """Store contents of file addressed by `fd` under filename `filename`.
-
-        Returns the internal file id (a string) for the file stored.
-        """
-        fd.seek(0)
-        digest = md5digest(fd)
-        fd.seek(0)
-        if not digest in self.keys():
-            self[digest] = Basket()
-        basket_id = self[digest].storeFile(fd, filename)
-        full_id = "%s-%s" % (digest, basket_id)
-        return full_id
-
-    def retrieveFile(self, file_id):
-        if not '-' in file_id:
-            return None
-        full_id, basket_id = file_id.split('-', 1)
-        if not full_id in self.keys():
-            return None
-        return self[full_id].retrieveFile(basket_id)
-
-class ImageStorageFileRetrieval(Persistent):
-    """A persistent object to retrieve files stored in ZODB.
-
-    .. deprecated:: 0.2
-
-       Since we have :class:`ExtFileStore` now we do not need this
-       class anymore.
-    """
-    grok.implements(IFileRetrieval)
-
-    def getImageStorage(self):
-        site = grok.getSite()
-        if site is None:
-            return None
-        return site.get('images', None)
-
-    def isImageStorageEnabled(self):
-        site = grok.getSite()
-        if site is None:
-            return False
-        if site.get('images', None) is None:
-            return False
-        return True
-
-    def getFile(self, data):
-        # ImageStorage is disabled, so give fall-back behaviour for
-        # testing without ImageStorage
-        if not self.isImageStorageEnabled():
-            return StringIO(data)
-        storage = self.getImageStorage()
-        if storage is None:
-            raise ValueError('Cannot find an image storage')
-        result = storage.retrieveFile(data)
-        if result is None:
-            return StringIO(data)
-        return storage.retrieveFile(data)
-
-    def createFile(self, filename, f):
-        if not self.isImageStorageEnabled():
-            return WAeUPImageFile(filename, f.read())
-        storage = self.getImageStorage()
-        if storage is None:
-            raise ValueError('Cannot find an image storage')
-        file_id = storage.storeFile(f, filename)
-        return WAeUPImageFile(filename, file_id)
-
 
 class ExtFileStore(object):
@@ -604,4 +399,9 @@
 
 class DefaultStorage(ExtFileStore):
+    """Default storage for files.
+
+    Registered globally as utility for
+    :class:`hurry.file.interfaces.IFileRetrieval`.
+    """
     grok.provides(IFileRetrieval)
 
@@ -613,4 +413,7 @@
     This handler is the fallback called by external file stores when
     there is no or an unknown marker in the file id.
+
+    Registered globally as utility for
+    :class:`waeup.sirp.interfaces.IFileStoreHandler`.
     """
     grok.implements(IFileStoreHandler)
Index: main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/tests/test_app.py
===================================================================
--- main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/tests/test_app.py	(revision 7033)
+++ main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/tests/test_app.py	(revision 7034)
@@ -6,5 +6,4 @@
 from zope.interface.verify import verifyClass, verifyObject
 from waeup.sirp.app import University
-from waeup.sirp.imagestorage import ImageStorageFileRetrieval
 from waeup.sirp.interfaces import IUniversity
 from waeup.sirp.testing import FunctionalLayer, FunctionalTestCase
@@ -32,9 +31,4 @@
         return
 
-    def test_images(self):
-        # Make sure we have a image container in a university
-        assert 'images' in self.app.keys()
-        return
-
     def test_IFileRetrieval_utility(self):
         # Make sure we can get a local IFileRetrieval utility
Index: main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/tests/test_imagestorage.py
===================================================================
--- main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/tests/test_imagestorage.py	(revision 7033)
+++ main/waeup.sirp/branches/ulif-extimgstore/src/waeup/sirp/tests/test_imagestorage.py	(revision 7034)
@@ -16,5 +16,4 @@
 from waeup.sirp.image import createWAeUPImageFile
 from waeup.sirp.imagestorage import (
-    md5digest, Basket, ImageStorage, ImageStorageFileRetrieval,
     FileStoreNameChooser, ExtFileStore, DefaultFileStoreHandler,
     DefaultStorage)
@@ -29,284 +28,4 @@
     def tearDown(self):
         shutil.rmtree(self.workdir)
-
-    def test_md5digest(self):
-        samplefile = os.path.join(self.workdir, 'sample')
-        open(samplefile, 'wb').write('blah')
-        fp = open(samplefile, 'r')
-        digest = md5digest(fp)
-        self.assertEqual(digest, '6f1ed002ab5595859014ebf0951522d9')
-
-class BasketTests(FunctionalTestCase):
-
-    layer = FunctionalLayer
-
-    def setUp(self):
-        super(BasketTests, self).setUp()
-        self.workdir = tempfile.mkdtemp()
-        self.samplefile = os.path.join(self.workdir, 'sample')
-        self.otherfile = os.path.join(self.workdir, 'other')
-        open(self.samplefile, 'wb').write('Hi there!')
-        open(self.otherfile, 'wb').write('Hi from other!')
-        self.basket = Basket()
-        self.fd = open(self.samplefile, 'r')
-        self.fd2 = open(self.otherfile, 'r')
-        self.stderr = StringIO()
-        self.old_stderr = sys.stderr
-
-    def tearDown(self):
-        sys.stderr = self.old_stderr
-        super(BasketTests, self).tearDown()
-        self.fd.close()
-        shutil.rmtree(self.workdir)
-        self.basket._del() # Remove subojects explicitly
-        del self.basket
-        return
-
-    def test_ifaces(self):
-        pass
-
-    def test_curr_id_empty(self):
-        curr_id = self.basket.curr_id
-        self.assertEqual(curr_id, '1')
-
-    def test_getInternalId_empty(self):
-        basket_id = self.basket.getInternalId(self.fd)
-        self.assertTrue(basket_id is None)
-
-    def test_storeFile_single(self):
-        basket_id = self.basket.storeFile(self.fd, 'sample')
-        self.assertEqual(basket_id, '1')
-        contents = self.basket['1'].open('r').read()
-        self.assertEqual(contents, 'Hi there!')
-
-    def test_storeFile_double(self):
-        basket_id1 = self.basket.storeFile(self.fd, 'sample')
-        basket_id2 = self.basket.storeFile(self.fd, 'sample')
-        self.assertTrue(basket_id1 == basket_id2 == '1')
-        contents = self.basket['1'].open('r').read()
-        self.assertEqual(contents, 'Hi there!')
-
-    def test_storeFile_multiple(self):
-        basket_id1 = self.basket.storeFile(self.fd, 'sample')
-        basket_id2 = self.basket.storeFile(self.fd2, 'sample')
-        self.assertEqual(basket_id1, '1')
-        self.assertEqual(basket_id2, '2')
-        contents1 = self.basket['1'].open('r').read()
-        contents2 = self.basket['2'].open('r').read()
-        self.assertEqual(contents1, 'Hi there!')
-        self.assertEqual(contents2, 'Hi from other!')
-
-    def test_retrieveFile(self):
-        basket_id = self.basket.storeFile(self.fd, 'sample')
-        fd = self.basket.retrieveFile(basket_id)
-        result = fd.read()
-        self.assertEqual(result, 'Hi there!')
-
-    def test_retrieveFile_not_existent(self):
-        result = self.basket.retrieveFile('not-a-valid-basket-id')
-        self.assertTrue(result is None)
-
-    def test_detect_zero_length_blobs(self):
-        # Ensure we get a warning when an empty Blob is found
-        self.basket.storeFile(self.fd, 'sample')
-        self.basket['1'].open('w').write('')
-        self.fd.seek(0)
-        sys.stderr = self.stderr         # Redirect stderr
-        self.basket.storeFile(self.fd, 'sample')
-        sys.stderr = self.old_stderr     # Restore stderr
-        self.stderr.seek(0)
-        self.assertTrue(
-            "EMPTY BLOB DETECTED" in self.stderr.read())
-
-    def test_refill_zero_length_blobs(self):
-        # When we detect an empty Blob, it will be reused
-        self.basket.storeFile(self.fd, 'sample')
-        self.basket['1'].open('w').write('')
-        self.fd.seek(0)
-        sys.stderr = self.stderr         # Redirect stderr
-        self.basket.storeFile(self.fd, 'sample')
-        sys.stderr = self.old_stderr     # Restore stderr
-        contents = self.basket['1'].open('r').read()
-        self.assertEqual(contents, 'Hi there!')
-
-
-class ImageStorageTests(FunctionalTestCase):
-
-    layer = FunctionalLayer
-
-    def setUp(self):
-        super(ImageStorageTests, self).setUp()
-        self.workdir = tempfile.mkdtemp()
-        self.samplefile = os.path.join(self.workdir, 'sample')
-        self.otherfile = os.path.join(self.workdir, 'other')
-        open(self.samplefile, 'wb').write('Hi there!')
-        open(self.otherfile, 'wb').write('Hi from other!')
-        self.storage = ImageStorage()
-        self.fd = open(self.samplefile, 'r')
-        self.fd2 = open(self.otherfile, 'r')
-
-    def tearDown(self):
-        super(ImageStorageTests, self).tearDown()
-        self.fd.close()
-        self.fd2.close()
-        shutil.rmtree(self.workdir)
-        self.storage._del() # Remove subojects explicitly
-        del self.storage
-        return
-
-    def test_ifaces(self):
-        pass
-
-    def test_storeFile(self):
-        full_id = self.storage.storeFile(self.fd, 'sample.txt')
-        self.assertEqual(full_id, '396199333edbf40ad43e62a1c1397793-1')
-
-    def test_storeFile_duplicate(self):
-        full_id1 = self.storage.storeFile(self.fd, 'sample1.txt')
-        full_id2 = self.storage.storeFile(self.fd, 'sample2.txt')
-        full_id3 = self.storage.storeFile(self.fd, 'sample1.txt')
-        self.assertEqual(full_id1, '396199333edbf40ad43e62a1c1397793-1')
-        self.assertEqual(full_id2, '396199333edbf40ad43e62a1c1397793-1')
-        self.assertEqual(full_id3, '396199333edbf40ad43e62a1c1397793-1')
-        contents = self.storage.retrieveFile(
-            '396199333edbf40ad43e62a1c1397793-1').read()
-        self.assertEqual(contents, 'Hi there!')
-
-    def test_storeFile_multiple(self):
-        full_id1 = self.storage.storeFile(self.fd, 'sample1.txt')
-        full_id2 = self.storage.storeFile(self.fd2, 'sample1.txt')
-        self.assertEqual(full_id1, '396199333edbf40ad43e62a1c1397793-1')
-        self.assertEqual(full_id2, '6936fcf8d564f1c5be5a017e650c5e8f-1')
-
-    def test_retrieveFile_not_existent(self):
-        result = self.storage.retrieveFile('not-existent')
-        self.assertTrue(result is None)
-
-    def test_retrieveFile_illegal_marker(self):
-        result1 = self.storage.retrieveFile('really-not-existent')
-        result2 = self.storage.retrieveFile('notexistent')
-        self.assertTrue(result1 is result2 is None)
-
-    def test_retrieveFile(self):
-        full_id = self.storage.storeFile(self.fd, 'sample.txt')
-        result = self.storage.retrieveFile(full_id)
-        content = result.read()
-        self.assertEqual(content, 'Hi there!')
-
-    def test_retrieveFile_multiple(self):
-        full_id1 = self.storage.storeFile(self.fd, 'sample.txt')
-        full_id2 = self.storage.storeFile(self.fd2, 'other.txt')
-        result1 = self.storage.retrieveFile(full_id1)
-        result2 = self.storage.retrieveFile(full_id2)
-        content1 = result1.read()
-        content2 = result2.read()
-        self.assertEqual(content1, 'Hi there!')
-        self.assertEqual(content2, 'Hi from other!')
-
-class ImageStorageFileRetrievalTests(FunctionalTestCase):
-
-    layer = FunctionalLayer
-
-    def setUp(self):
-        super(ImageStorageFileRetrievalTests, self).setUp()
-        self.workdir = tempfile.mkdtemp()
-        self.samplefile = os.path.join(self.workdir, 'sample')
-        self.otherfile = os.path.join(self.workdir, 'other')
-        open(self.samplefile, 'wb').write('Hi there!')
-        open(self.otherfile, 'wb').write('Hi from other!')
-        self.storage = ImageStorage()
-        self.fd = open(self.samplefile, 'r')
-        self.fd2 = open(self.otherfile, 'r')
-        # Set up a single image storage in a site
-        self.getRootFolder()['app'] = University()
-        self.app = self.getRootFolder()['app']
-        if not 'images' in self.app.keys():
-            self.app['images'] = ImageStorage()
-        self.storage = self.app['images']
-        return
-
-
-    def tearDown(self):
-        super(ImageStorageFileRetrievalTests, self).tearDown()
-        self.fd.close()
-        self.fd2.close()
-        shutil.rmtree(self.workdir)
-        self.storage._del() # Remove subojects explicitly
-        return
-
-    def test_ifaces(self):
-        retrieval = ImageStorageFileRetrieval()
-        assert verifyClass(IFileRetrieval, ImageStorageFileRetrieval)
-        assert verifyObject(IFileRetrieval, retrieval)
-        return
-
-    def test_getImageStorage_nosite(self):
-        retrieval = ImageStorageFileRetrieval()
-        storage = retrieval.getImageStorage()
-        self.assertTrue(storage is None)
-        return
-
-    def test_getImageStorage(self):
-        setSite(self.app)
-        retrieval = ImageStorageFileRetrieval()
-        storage = retrieval.getImageStorage()
-        self.assertTrue(storage is self.storage)
-        return
-
-    def test_isImageStorageEnabled_nosite(self):
-        retrieval = ImageStorageFileRetrieval()
-        self.assertTrue(retrieval.isImageStorageEnabled() is False)
-        return
-
-    def test_isImageStorageEnabled(self):
-        setSite(self.app)
-        retrieval = ImageStorageFileRetrieval()
-        self.assertTrue(retrieval.isImageStorageEnabled() is True)
-        return
-
-    def test_getFile_nosite(self):
-        retrieval = ImageStorageFileRetrieval()
-        f = retrieval.getFile('Hi there!')
-        self.assertEqual(f.read(), 'Hi there!')
-        return
-
-    def test_getFile(self):
-        setSite(self.app)
-        retrieval = ImageStorageFileRetrieval()
-        waeup_image = retrieval.createFile('sample.txt', self.fd)
-        full_id = waeup_image.data
-        result = retrieval.getFile(full_id)
-        self.assertEqual(result.read(), 'Hi there!')
-        return
-
-    def test_createFile_nosite(self):
-        retrieval = ImageStorageFileRetrieval()
-        waeup_image = retrieval.createFile('sample.txt', self.fd)
-        self.assertEqual(waeup_image.data, 'Hi there!')
-        return
-
-    def test_createFile(self):
-        # Ensure we can create WAeUPImageFiles when in site
-        setSite(self.app)
-        retrieval = ImageStorageFileRetrieval()
-        waeup_image = retrieval.createFile('sample.txt', self.fd)
-        full_id = waeup_image.data
-        self.assertEqual(full_id, '396199333edbf40ad43e62a1c1397793-1')
-        return
-
-    def DISABLEDtest_waeupimagefile(self):
-        # Make sure WAeUPImageFile can use our file retrieval
-        setSite(self.app)
-        myfile = createWAeUPImageFile('sample.jpg', self.fd)
-        contents = myfile.file.read()
-        self.assertEqual(contents, 'Hi there!')
-
-    def DISABLEDtest_waeupimagefile_raw(self):
-        # Make sure we can retrieve a file also if it was initialized
-        # with no image storage available
-        myfile = createWAeUPImageFile('sample.jpg', self.fd)
-        setSite(self.app)
-        contents = myfile.file.read()
-        self.assertEqual(contents, 'Hi there!')
 
 class FileStoreNameChooserTests(FunctionalTestCase):
@@ -429,6 +148,4 @@
 class CustomizedFileHandler(object):
     def pathFromFileID(self, store, root, file_id):
-        """Turn filename into path to store.
-        """
         return os.path.join(root, file_id[12:])
 
@@ -440,5 +157,4 @@
 
     layer = FunctionalLayer
-
 
     def setUp(self):
@@ -449,5 +165,4 @@
         open(self.samplefile, 'wb').write('Hi there!')
         open(self.otherfile, 'wb').write('Hi from other!')
-        self.storage = ImageStorage()
         self.fd = open(self.samplefile, 'r')
         self.fd2 = open(self.otherfile, 'r')
