forked from pycontw/pycon.tw
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
132 lines (97 loc) · 3.88 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import collections
from django.conf import settings
from django.http import Http404
from django.template.loader import TemplateDoesNotExist
from django.template.response import TemplateResponse
from django.utils.functional import lazy
from django.utils.html import conditional_escape, format_html, mark_safe
from django.test import override_settings
from registry.helper import reg
format_html_lazy = lazy(format_html, str)
def html_join(sep, sequence):
"""Similar to str.join, but passes the separator and all elements in the
sequence through conditional_escape, and calls 'mark_safe' on the result.
This function should be used instead of str.join to build up small HTML
fragments.
"""
sep_safe = conditional_escape(sep)
return mark_safe(sep_safe.join(conditional_escape(e) for e in sequence))
class TemplateExistanceStatusResponse(TemplateResponse):
"""Extended response that raises Http404 when a template cannot be found.
"""
def resolve_template(self, template):
try:
return super().resolve_template(template)
except (UnicodeEncodeError, TemplateDoesNotExist):
if settings.DEBUG:
raise
raise Http404
def collect_language_codes(user_code):
"""Collect implied language codes for a requested langauge code.
The language code requested is the first choice. If the code indicates a
sublanguage (e.g. ``zh-hant``), the base language (``zh``) is collected as
a fallback. The site's default langauge (``settings.LANGUAGE_CODE``),
its base language (if applicable), and a default directory "_default" are
then appended as further fallbacks.
Examples (assuming site language is "en"):
* "zh-tw" -> "zh-tw", "zh", "en", "_default"
* "ja" -> "ja", "en", "_default"
:returns: An ordered iterable containing collected language codes.
"""
codes = [user_code]
if '-' in user_code:
codes.append(user_code.split('-')[0])
codes.append(settings.LANGUAGE_CODE)
if '-' in settings.LANGUAGE_CODE:
codes.append(settings.LANGUAGE_CODE.split('-')[0])
codes.append('_default')
return codes
def form_has_instance(form):
instance = getattr(form, 'instance', None)
return instance and instance.pk is not None
def split_css_class(class_str):
if not class_str:
return set()
return set(s.strip() for s in class_str.split())
class SequenceQuerySet:
"""Wrap a sequence to use the same API as Django's QuerySet.
"""
__slots__ = ('_seq')
def __init__(self, seq):
self._seq = seq
def __repr__(self):
return '<SequenceQuerySet: {seq!r}>'.format(seq=self._seq)
def __len__(self):
return len(self._seq)
def __iter__(self):
return iter(self._seq)
def __bool__(self):
return bool(self._seq)
def __getitem__(self, i):
return type(self)(self._seq[i])
def all(self):
return self
def count(self):
return len(self._seq)
def exists(self):
return bool(self._seq)
class OrderedDefaultDict(collections.OrderedDict):
"""Add defaultdict behavior to OrderedDict.
"""
def __init__(self, default_factory=None, *args, **kwargs):
if default_factory is not None and not callable(default_factory):
raise TypeError('first argument must be callable')
super().__init__(*args, **kwargs)
self.default_factory = default_factory
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
self[key] = self.default_factory()
return self[key]
class set_registry(override_settings):
def enable(self):
for key, value in self.options.items():
reg[f'{settings.CONFERENCE_DEFAULT_SLUG}.{key}'] = value
def disable(self):
for key, value in self.options.items():
del reg[f'{settings.CONFERENCE_DEFAULT_SLUG}.{key}']