storage.storage_system_from_paste_config() utility, w/ tests
authorChristopher Allan Webber <cwebber@dustycloud.org>
Sun, 17 Apr 2011 15:24:36 +0000 (10:24 -0500)
committerChristopher Allan Webber <cwebber@dustycloud.org>
Sun, 17 Apr 2011 15:24:36 +0000 (10:24 -0500)
mediagoblin/storage.py
mediagoblin/tests/test_storage.py

index d9a57c2a931ad6ca334b913581d7ddd682f10f0a..8a594e83b3e4bf2a2459fc2a5e0cdef468d14e22 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
+import re
 import urlparse
 import uuid
 
 from werkzeug.utils import secure_filename
 
+from mediagoblin import util
+
 
 class Error(Exception): pass
 class InvalidFilepath(Error): pass
@@ -193,3 +196,49 @@ class BasicFileStorage(StorageInterface):
         return urlparse.urljoin(
             self.base_url,
             '/'.join(clean_listy_filepath(filepath)))
+
+
+def storage_system_from_paste_config(paste_config, storage_prefix):
+    """
+    Utility for setting up a storage system from the paste app config.
+
+    Note that a special argument may be passed in to the paste_config
+    which is "${storage_prefix}_storage_class" which will provide an
+    import path to a storage system.  This defaults to
+    "mediagoblin.storage:BasicFileStorage" if otherwise undefined.
+
+    Arguments:
+     - paste_config: dictionary of config parameters
+     - storage_prefix: the storage system we're setting up / will be
+       getting keys/arguments from.  For example 'publicstore' will
+       grab all arguments that are like 'publicstore_FOO'.
+
+    Returns:
+      An instantiated storage system.
+
+    Example:
+      storage_system_from_paste_config(
+        {'publicstore_base_url': '/media/',
+         'publicstore_base_dir': '/var/whatever/media/'},
+        'publicstore')
+
+       Will return:
+         BasicFileStorage(
+           base_url='/media/',
+           base_dir='/var/whatever/media')
+    """
+    prefix_re = re.compile('^%s_(.+)$' % re.escape(storage_prefix))
+
+    config_params = dict(
+        [(prefix_re.match(key).groups()[0], value)
+         for key, value in paste_config.iteritems()
+         if prefix_re.match(key)])
+
+    if config_params.has_key('storage_class'):
+        storage_class = config_params['storage_class']
+        config_params.pop('storage_class')
+    else:
+        storage_class = "mediagoblin.storage:BasicFileStorage"
+
+    storage_class = util.import_component(storage_class)
+    return storage_class(**config_params)
index 0db9df842a580a434f213ff38d134da2c0b237ea..61dd5dcac7013200947831fc1a13f2a100fa912a 100644 (file)
@@ -24,6 +24,10 @@ from werkzeug.utils import secure_filename
 from mediagoblin import storage
 
 
+################
+# Test utilities
+################
+
 def test_clean_listy_filepath():
     expected = [u'dir1', u'dir2', u'linooks.jpg']
     assert storage.clean_listy_filepath(
@@ -43,6 +47,36 @@ def test_clean_listy_filepath():
         ['../../', 'linooks.jpg'])
 
 
+class FakeStorageSystem():
+    def __init__(self, foobie, blech, **kwargs):
+        self.foobie = foobie
+        self.blech = blech
+
+
+def test_storage_system_from_paste_config():
+    this_storage = storage.storage_system_from_paste_config(
+        {'somestorage_base_url': 'http://example.org/moodia/',
+         'somestorage_base_dir': '/tmp/',
+         'somestorage_garbage_arg': 'garbage_arg',
+         'garbage_arg': 'trash'},
+        'somestorage')
+    assert this_storage.base_url == 'http://example.org/moodia/'
+    assert this_storage.base_dir == '/tmp/'
+    assert this_storage.__class__ is storage.BasicFileStorage
+
+    this_storage = storage.storage_system_from_paste_config(
+        {'somestorage_foobie': 'eiboof',
+         'somestorage_blech': 'hcelb',
+         'somestorage_garbage_arg': 'garbage_arg',
+         'garbage_arg': 'trash',
+         'somestorage_storage_class':
+             'mediagoblin.tests.test_storage:FakeStorageSystem'},
+         'somestorage')
+    assert this_storage.foobie == 'eiboof'
+    assert this_storage.blech == 'hcelb'
+    assert this_storage.__class__ is FakeStorageSystem
+
+
 ##########################
 # Basic file storage tests
 ##########################