Commits

Mark Lavin  committed 7161ff2

Added lookup registry and auto-discovery.

  • Participants
  • Parent commits 4aa2810

Comments (0)

Files changed (4)

File selectable/base.py

+from django.utils.encoding import smart_unicode
+
+
+class LookupBase(object):
+
+    def _name(cls):
+        app_name = cls.__module__.split('.')[-2].lower()
+        class_name = cls.__name__.lower()
+        name = u'%s-%s' % (app_name, class_name)       
+        return name
+    name = classmethod(_name)
+
+    def get_query(self, request):
+        return []
+
+    def format_item(self, item):
+        return smart_unicode(item)
+

File selectable/registry.py

+from django.utils.encoding import force_unicode
+
+from selectable.base import LookupBase
+
+
+class LookupAlreadyRegistered(Exception):
+    pass
+
+
+class LookupNotRegistered(Exception):
+    pass
+
+
+class LookupInvalid(Exception):
+    pass
+
+
+class LookupRegistry(object):
+
+    def __init__(self):
+        self._registry = {}
+
+    def validate(self, lookup):
+        if not issubclass(lookup, LookupBase):
+            raise LookupInvalid(u'Registered lookups must inherit from the LookupBase class')
+
+    def register(self, lookup):
+
+        self.validate(lookup)
+
+        name = force_unicode(lookup.name())
+
+        if name in self._registry:
+            raise LookupAlreadyRegistered(u'The name %s is already registered' % name)
+        self._registry[name] = lookup
+
+    def unregister(self, lookup):
+
+        self.validate(lookup)
+    
+        name = force_unicode(lookup.name())
+
+        if name not in self._registry:
+           raise LookupNotRegistered(u'The name %s is not registered' % name)
+    
+        del self._registry[name]
+
+    def get(self, key):
+        return self._registry.get(key, None)
+
+
+registry = LookupRegistry()
+
+
+def autodiscover():
+
+    import copy
+    from django.conf import settings
+    from django.utils.importlib import import_module
+    from django.utils.module_loading import module_has_submodule
+
+    for app in settings.INSTALLED_APPS:
+        mod = import_module(app)
+        # Attempt to import the app's lookups module.
+        try:
+            before_import_registry = copy.copy(registry._registry)
+            import_module('%s.lookups' % app)
+        except:
+            registry._registry = before_import_registry
+
+            if module_has_submodule(mod, 'lookups'):
+                raise
+

File selectable/urls.py

+from django.conf.urls.defaults import *
+
+from selectable import registry
+
+
+registry.autodiscover()
+
+urlpatterns = patterns('selectable.views',
+    url(r'^(?P<lookup_name>[-\w]+)/$', 'get_lookup', name="selectable-lookup"),
+)

File selectable/views.py

-# Create your views here.
+from django.core.serializers import json
+from django.http import HttpResponse, Http404
+from django.utils import simplejson
+
+from selectable.registry import registry
+
+
+def get_lookup(request, lookup_name):
+
+    lookup_cls = registry.get(lookup_name)
+    if lookup_cls is None:
+        raise Http404(u'Lookup %s not found' % lookup_name)
+
+    lookup = lookup_cls()
+    raw_data = lookup.get_query(request)
+    data = []
+    for item in raw_data:
+        data.append(lookup.format_item(item))
+
+    content = simplejson.dumps(data, cls=json.DjangoJSONEncoder, ensure_ascii=False)
+    return HttpResponse(content, content_type='application/json')
+