making migdal more universal
[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(object):
15     def __init__(self, db, slug, commentable=False, on_main=False,
16             promotable=False, categorized=False):
17         self.db = db
18         self.slug = slug
19         self.commentable = commentable
20         self.on_main = on_main
21         self.promotable = promotable
22         self.categorized = categorized
23
24     def __unicode__(self):
25         return unicode(self.slug)
26
27
28 def field_getter(name):
29     @property
30     def getter(self):
31         val = getattr(self, "%s_%s" % (name, get_language()), None)
32         if not val:
33             val = getattr(self, "%s_%s" % (name, settings.LANGUAGE_CODE))
34         return val
35     return getter
36
37
38 def add_translatable(model, fields, languages=None):
39     """Adds some translatable fields to a model, and a getter."""
40     if languages is None:
41         languages = settings.LANGUAGES
42     for name, field in fields.items():
43         for lang_code, lang_name in languages:
44             new_field = copy(field)
45             if field.verbose_name:
46                 new_field.verbose_name = string_concat(field.verbose_name, ' [%s]' % lang_code)
47             new_field.contribute_to_class(model, "%s_%s" % (name, lang_code))
48         setattr(model, name, field_getter(name))
49         # add setter?
50
51
52 class MyLocaleRegexURLResolver(LocaleRegexURLResolver):
53     """
54     A URL resolver that always matches the active language code as URL prefix.
55
56     Rather than taking a regex argument, we just override the ``regex``
57     function to always return the active language-code as regex.
58     """
59     @property
60     def regex(self):
61         language_code = get_language()
62         if language_code == settings.LANGUAGE_CODE:
63             return re.compile('')
64         if language_code not in self._regex_dict:
65             regex_compiled = re.compile('^%s/' % language_code, re.UNICODE)
66             self._regex_dict[language_code] = regex_compiled
67         return self._regex_dict[language_code]
68
69
70 def i18n_patterns(prefix, *args):
71     """
72     Adds the language code prefix to every URL pattern within this
73     function. This may only be used in the root URLconf, not in an included
74     URLconf.
75
76     """
77     pattern_list = patterns(prefix, *args)
78     if not settings.USE_I18N:
79         return pattern_list
80     return pattern_list + [MyLocaleRegexURLResolver(pattern_list)]
81
82
83 def add_translatable_index(index_class, fields, languages=None):
84     """Adds some translatable fields to a search index, and a getter."""
85     if languages is None:
86         languages = settings.LANGUAGES
87     for name, field in fields.items():
88         for lang_code, lang_name in languages:
89             new_field = copy(field)
90             fname = "%s_%s" % (name, lang_code)
91             new_field.index_fieldname = new_field.index_fieldname \
92                 and "%s_%s" % (new_field.index_fieldname, lang_code) \
93                 or fname
94             new_field.model_attr = new_field.model_attr \
95                 and "%s_%s" % (new_field.model_attr, lang_code) \
96                 or fname
97             setattr(index_class, fname, new_field)
98             index_class.fields[fname] = new_field
99
100
101 def translated_fields(field_names, languages=settings.LANGUAGES):
102     return tuple("%s_%s" % (field_name, lang_code)
103                 for field_name in field_names
104                 for lang_code, lang_name in languages
105                 )