Merge branch 'release' into develop
authorStephen Burrows <stephen.r.burrows@gmail.com>
Fri, 10 Jun 2011 18:52:48 +0000 (14:52 -0400)
committerStephen Burrows <stephen.r.burrows@gmail.com>
Fri, 10 Jun 2011 18:57:58 +0000 (14:57 -0400)
Conflicts:
philo/contrib/sobol/models.py
philo/contrib/sobol/search.py

1  2 
philo/contrib/sobol/models.py
philo/contrib/sobol/search.py

Simple merge
@@@ -9,10 -10,9 +10,10 @@@ from django.utils import simplejson as 
  from django.utils.http import urlquote_plus
  from django.utils.safestring import mark_safe
  from django.utils.text import capfirst
- from django.template import loader, Context, Template
+ from django.template import loader, Context, Template, TemplateDoesNotExist
  
 -from philo.contrib.sobol.utils import make_tracking_querydict, RegistryIterator
 +from philo.contrib.sobol.utils import make_tracking_querydict
 +from philo.utils.registry import Registry
  
  
  if getattr(settings, 'SOBOL_USE_EVENTLET', False):
@@@ -25,22 -25,103 +26,36 @@@ else
  
  
  __all__ = (
-       'Result', 'BaseSearch', 'DatabaseSearch', 'URLSearch', 'JSONSearch', 'GoogleSearch', 'registry'
 -      'Result', 'BaseSearch', 'DatabaseSearch', 'URLSearch', 'JSONSearch', 'GoogleSearch', 'SearchRegistry', 'registry', 'get_search_instance'
++      'Result', 'BaseSearch', 'DatabaseSearch', 'URLSearch', 'JSONSearch', 'GoogleSearch', 'registry', 'get_search_instance'
  )
  
  
- SEARCH_CACHE_KEY = 'philo_sobol_search_results'
- DEFAULT_RESULT_TEMPLATE_STRING = "{% if url %}<a href='{{ url }}'>{% endif %}{{ title }}{% if url %}</a>{% endif %}"
- DEFAULT_RESULT_TEMPLATE = Template(DEFAULT_RESULT_TEMPLATE_STRING)
- # Determines the timeout on the entire result cache.
- MAX_CACHE_TIMEOUT = 60*24*7
+ SEARCH_CACHE_SEED = 'philo_sobol_search_results'
+ USE_CACHE = getattr(settings, 'SOBOL_USE_SEARCH', True)
  
  
 -class RegistrationError(Exception):
 -      """Raised if there is a problem registering a search with a :class:`SearchRegistry`"""
 -      pass
 -
 -
 -class SearchRegistry(object):
 -      """Holds a registry of search types by slug."""
 -      
 -      def __init__(self):
 -              self._registry = {}
 -      
 -      def register(self, search, slug=None):
 -              """
 -              Register a search with the registry.
 -              
 -              :param search: The search class to register - generally a subclass of :class:`BaseSearch`
 -              :param slug: The slug which will be used to register the search class. If ``slug`` is ``None``, the search's default slug will be used.
 -              :raises: :class:`RegistrationError` if a different search is already registered with ``slug``.
 -              
 -              """
 -              slug = slug or search.slug
 -              if slug in self._registry:
 -                      registered = self._registry[slug]
 -                      if registered.__module__ != search.__module__:
 -                              raise RegistrationError("A different search is already registered as `%s`" % slug)
 -              else:
 -                      self._registry[slug] = search
 -      
 -      def unregister(self, search, slug=None):
 -              """
 -              Unregister a search from the registry.
 -              
 -              :param search: The search class to unregister - generally a subclass of :class:`BaseSearch`
 -              :param slug: If provided, the search will only be removed if it was registered with ``slug``. If not provided, the search class will be unregistered no matter what slug it was registered with.
 -              :raises: :class:`RegistrationError` if a slug is provided but the search registered with that slug is not ``search``.
 -              
 -              """
 -              if slug is not None:
 -                      if slug in self._registry and self._registry[slug] == search:
 -                              del self._registry[slug]
 -                      raise RegistrationError("`%s` is not registered as `%s`" % (search, slug))
 -              else:
 -                      for slug, search in self._registry.items():
 -                              if search == search:
 -                                      del self._registry[slug]
 -      
 -      def items(self):
 -              """Returns a list of (slug, search) items in the registry."""
 -              return self._registry.items()
 -      
 -      def iteritems(self):
 -              """Returns an iterator over the (slug, search) pairs in the registry."""
 -              return RegistryIterator(self._registry, 'iteritems')
 -      
 -      def iterchoices(self):
 -              """Returns an iterator over (slug, search.verbose_name) pairs for the registry."""
 -              return RegistryIterator(self._registry, 'iteritems', lambda x: (x[0], x[1].verbose_name))
 -      
 -      def __getitem__(self, key):
 -              """Returns the search registered with ``key``."""
 -              return self._registry[key]
 -      
 -      def __iter__(self):
 -              """Returns an iterator over the keys in the registry."""
 -              return self._registry.__iter__()
 -
 -
 -registry = SearchRegistry()
 +#: A registry for :class:`BaseSearch` subclasses that should be available in the admin.
 +registry = Registry()
  
  
 -      
+ def _make_cache_key(search, search_arg):
+       return sha1(SEARCH_CACHE_SEED + search.slug + search_arg).hexdigest()
+ def get_search_instance(slug, search_arg):
+       """Returns a search instance for the given slug, either from the cache or newly-instantiated."""
+       search = registry[slug]
+       search_arg = search_arg.lower()
+       if USE_CACHE:
+               key = _make_cache_key(search, search_arg)
+               cached = cache.get(key)
+               if cached:
+                       return cached
+       instance = search(search_arg)
+       instance.slug = slug
+       return instance
  class Result(object):
        """
        :class:`Result` is a helper class that, given a search and a result of that search, is able to correctly render itself with a template defined by the search. Every :class:`Result` will pass a ``title``, a ``url`` (if applicable), and the raw ``result`` returned by the search into the template context when rendering.