8a6513d75fe3d4a245135105731a749ba8317f8b
[prawokultury.git] / migdal / helpers.py
1 # -*- coding: utf-8 -*-
2 # This file is part of PrawoKultury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 #
5 from collections import namedtuple
6 from copy import copy
7 import re
8 from django.conf import settings
9 from django.conf.urls import patterns
10 from django.core.urlresolvers import LocaleRegexURLResolver
11 from django.utils.translation import get_language, string_concat
12
13
14 class EntryType(namedtuple('EntryType', 'db slug commentable on_main')):
15     __slots__ = ()
16     def __unicode__(self):
17         return unicode(self.slug)
18
19
20 def field_getter(name):
21     @property
22     def getter(self):
23         val = getattr(self, "%s_%s" % (name, get_language()), None)
24         if not val:
25             val = getattr(self, "%s_%s" % (name, settings.LANGUAGE_CODE))
26         return val
27     return getter
28
29
30 def add_translatable(model, fields, languages=None):
31     """Adds some translatable fields to a model, and a getter."""
32     if languages is None:
33         languages = settings.LANGUAGES
34     for name, field in fields.items():
35         for lang_code, lang_name in languages:
36             new_field = copy(field)
37             if field.verbose_name:
38                 new_field.verbose_name = string_concat(field.verbose_name, ' [%s]' % lang_code)
39             new_field.contribute_to_class(model, "%s_%s" % (name, lang_code))
40         setattr(model, name, field_getter(name))
41         # add setter?
42
43
44 class MyLocaleRegexURLResolver(LocaleRegexURLResolver):
45     """
46     A URL resolver that always matches the active language code as URL prefix.
47
48     Rather than taking a regex argument, we just override the ``regex``
49     function to always return the active language-code as regex.
50     """
51     @property
52     def regex(self):
53         language_code = get_language()
54         if language_code == settings.LANGUAGE_CODE:
55             return re.compile('')
56         if language_code not in self._regex_dict:
57             regex_compiled = re.compile('^%s/' % language_code, re.UNICODE)
58             self._regex_dict[language_code] = regex_compiled
59         return self._regex_dict[language_code]
60
61
62 def i18n_patterns(prefix, *args):
63     """
64     Adds the language code prefix to every URL pattern within this
65     function. This may only be used in the root URLconf, not in an included
66     URLconf.
67
68     """
69     pattern_list = patterns(prefix, *args)
70     if not settings.USE_I18N:
71         return pattern_list
72     return pattern_list + [MyLocaleRegexURLResolver(pattern_list)]
73
74
75 def add_translatable_index(index_class, fields, languages=None):
76     """Adds some translatable fields to a search index, and a getter."""
77     if languages is None:
78         languages = settings.LANGUAGES
79     for name, field in fields.items():
80         for lang_code, lang_name in languages:
81             new_field = copy(field)
82             fname = "%s_%s" % (name, lang_code)
83             new_field.index_fieldname = new_field.index_fieldname \
84                 and "%s_%s" % (new_field.index_fieldname, lang_code) \
85                 or fname
86             new_field.model_attr = new_field.model_attr \
87                 and "%s_%s" % (new_field.model_attr, lang_code) \
88                 or fname
89             setattr(index_class, fname, new_field)
90             index_class.fields[fname] = new_field
91
92
93 def translated_fields(field_names, languages=settings.LANGUAGES):
94     return tuple("%s_%s" % (field_name, lang_code)
95                 for field_name in field_names
96                 for lang_code, lang_name in languages
97                 )