Converted, corrected, improved, and added to documentation for sobol's models and...
[philo.git] / philo / contrib / sobol / utils.py
1 from hashlib import sha1
2
3 from django.conf import settings
4 from django.http import QueryDict
5 from django.utils.encoding import smart_str
6 from django.utils.http import urlquote_plus, urlquote
7
8
9 SEARCH_ARG_GET_KEY = 'q'
10 URL_REDIRECT_GET_KEY = 'url'
11 HASH_REDIRECT_GET_KEY = 's'
12
13
14 def make_redirect_hash(search_arg, url):
15         """Hashes a redirect for a ``search_arg`` and ``url`` to avoid providing a simple URL spoofing service."""
16         return sha1(smart_str(search_arg + url + settings.SECRET_KEY)).hexdigest()[::2]
17
18
19 def check_redirect_hash(hash, search_arg, url):
20         """Checks whether a hash is valid for a given ``search_arg`` and ``url``."""
21         return hash == make_redirect_hash(search_arg, url)
22
23
24 def make_tracking_querydict(search_arg, url):
25         """Returns a :class:`QueryDict` instance containing the information necessary for tracking :class:`.Click`\ s on the ``url``."""
26         return QueryDict("%s=%s&%s=%s&%s=%s" % (
27                 SEARCH_ARG_GET_KEY, urlquote_plus(search_arg),
28                 URL_REDIRECT_GET_KEY, urlquote(url),
29                 HASH_REDIRECT_GET_KEY, make_redirect_hash(search_arg, url))
30         )
31
32
33 class RegistryIterator(object):
34         def __init__(self, registry, iterattr='__iter__', transform=lambda x:x):
35                 if not hasattr(registry, iterattr):
36                         raise AttributeError("Registry has no attribute %s" % iterattr)
37                 self.registry = registry
38                 self.iterattr = iterattr
39                 self.transform = transform
40         
41         def __iter__(self):
42                 return self
43         
44         def next(self):
45                 if not hasattr(self, '_iter'):
46                         self._iter = getattr(self.registry, self.iterattr)()
47                 
48                 return self.transform(self._iter.next())
49         
50         def copy(self):
51                 return self.__class__(self.registry, self.iterattr, self.transform)