diff options
Diffstat (limited to 'main/utils.py')
-rw-r--r-- | main/utils.py | 155 |
1 files changed, 147 insertions, 8 deletions
diff --git a/main/utils.py b/main/utils.py index 81093e2a..f94f314d 100644 --- a/main/utils.py +++ b/main/utils.py @@ -2,7 +2,24 @@ try: import cPickle as pickle except ImportError: import pickle -from django.utils.hashcompat import md5_constructor + +import hashlib +import markdown +from markdown.extensions import Extension + +from django.core.cache import cache +from django.db import connections, router +from django.http import HttpResponse +from django.utils.timezone import now +from django.template.defaultfilters import slugify + + +def cache_function_key(func, args, kwargs): + raw = [func.__name__, func.__module__, args, kwargs] + pickled = pickle.dumps(raw, protocol=pickle.HIGHEST_PROTOCOL) + key = hashlib.md5(pickled).hexdigest() + return 'cache_function.' + func.__name__ + '.' + key + def cache_function(length): """ @@ -18,12 +35,7 @@ def cache_function(length): """ def decorator(func): def inner_func(*args, **kwargs): - from django.core.cache import cache - - raw = [func.__name__, func.__module__, args, kwargs] - pickled = pickle.dumps(raw, protocol=pickle.HIGHEST_PROTOCOL) - key = md5_constructor(pickled).hexdigest() - key = 'cache_function.' + func.__name__ + '.' + key + key = cache_function_key(func, args, kwargs) value = cache.get(key) if value is not None: return value @@ -34,5 +46,132 @@ def cache_function(length): return inner_func return decorator -#utility to make a pair of django choices + +def clear_cache_function(func, args, kwargs): + key = cache_function_key(func, args, kwargs) + cache.delete(key) + + +def empty_response(): + empty = HttpResponse('') + # designating response as 'streaming' forces ConditionalGetMiddleware to + # not add a 'Content-Length: 0' header + empty.streaming = True + return empty + + +def format_http_headers(request): + headers = sorted((k, v) for k, v in request.META.items() + if k.startswith('HTTP_')) + data = [] + for k, v in headers: + data.extend([k[5:].replace('_', '-').title(), ': ', v, '\n']) + return ''.join(data) + + +# utility to make a pair of django choices make_choice = lambda l: [(str(m), str(m)) for m in l] + + +def set_created_field(sender, **kwargs): + '''This will set the 'created' field on any object to the current UTC time + if it is unset. + Additionally, this will set the 'last_modified' field on any object to the + current UTC time on any save of the object. + For use as a pre_save signal handler.''' + obj = kwargs['instance'] + time = now() + if hasattr(obj, 'created') and not obj.created: + obj.created = time + if hasattr(obj, 'last_modified'): + obj.last_modified = time + + +def find_unique_slug(model, title): + '''Attempt to find a unique slug for this model with given title.''' + existing = set(model.objects.values_list( + 'slug', flat=True).order_by().distinct()) + + suffixed = slug = slugify(title) + suffix = 0 + while suffixed in existing: + suffix += 1 + suffixed = "%s-%d" % (slug, suffix) + + return suffixed + + +def database_vendor(model, mode='read'): + if mode == 'read': + database = router.db_for_read(model) + elif mode == 'write': + database = router.db_for_write(model) + else: + raise Exception('Invalid database mode specified') + return connections[database].vendor + + +class EscapeHtml(Extension): + def extendMarkdown(self, md, md_globals): + del md.preprocessors['html_block'] + del md.inlinePatterns['html'] + + +def parse_markdown(text, allow_html=False): + if allow_html: + return markdown.markdown(text, enable_attributes=False) + ext = [EscapeHtml()] + return markdown.markdown(text, extensions=ext, enable_attributes=False) + + +def groupby_preserve_order(iterable, keyfunc): + '''Take an iterable and regroup using keyfunc to determine whether items + belong to the same group. The order of the iterable is preserved and + similar keys do not have to be consecutive. This means the earliest + occurrence of a given key will determine the order of the lists in the + returned list.''' + seen_keys = {} + result = [] + for item in iterable: + key = keyfunc(item) + + group = seen_keys.get(key, None) + if group is None: + group = [] + seen_keys[key] = group + result.append(group) + + group.append(item) + + return result + + +class PackageStandin(object): + '''Resembles a Package object, and has a few of the same fields, but is + really a link to a pkgbase that has no package with matching pkgname.''' + def __init__(self, package): + self.package = package + self.pkgname = package.pkgbase + + def __getattr__(self, name): + return getattr(self.package, name) + + def get_absolute_url(self): + return '/packages/%s/%s/%s/' % ( + self.repo.name.lower(), self.arch.name, self.pkgbase) + + +class DependStandin(object): + '''Resembles a Depend object, and has a few of the same fields, but is + really a link to a base package rather than a single package.''' + def __init__(self, depends): + self._depends = depends + first = depends[0] + self.name = first.name + self.version = first.version + self.comparison = first.comparison + self.description = first.description + self.deptype = first.deptype + self.pkg = first.pkg.base_package() or PackageStandin(first.pkg) + +# vim: set ts=4 sw=4 et: |