Michael Merickel
2018-10-26 4149922e64aecf2a213f8efb120cd2d61fed3eb7
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
from pyramid.interfaces import ILocaleNegotiator, ITranslationDirectories
 
from pyramid.exceptions import ConfigurationError
from pyramid.path import AssetResolver
 
from pyramid.config.actions import action_method
 
 
class I18NConfiguratorMixin(object):
    @action_method
    def set_locale_negotiator(self, negotiator):
        """
        Set the :term:`locale negotiator` for this application.  The
        :term:`locale negotiator` is a callable which accepts a
        :term:`request` object and which returns a :term:`locale
        name`.  The ``negotiator`` argument should be the locale
        negotiator implementation or a :term:`dotted Python name`
        which refers to such an implementation.
 
        Later calls to this method override earlier calls; there can
        be only one locale negotiator active at a time within an
        application.  See :ref:`activating_translation` for more
        information.
 
        .. note::
 
           Using the ``locale_negotiator`` argument to the
           :class:`pyramid.config.Configurator` constructor can be used to
           achieve the same purpose.
        """
 
        def register():
            self._set_locale_negotiator(negotiator)
 
        intr = self.introspectable(
            'locale negotiator',
            None,
            self.object_description(negotiator),
            'locale negotiator',
        )
        intr['negotiator'] = negotiator
        self.action(ILocaleNegotiator, register, introspectables=(intr,))
 
    def _set_locale_negotiator(self, negotiator):
        locale_negotiator = self.maybe_dotted(negotiator)
        self.registry.registerUtility(locale_negotiator, ILocaleNegotiator)
 
    @action_method
    def add_translation_dirs(self, *specs, **kw):
        """ Add one or more :term:`translation directory` paths to the
        current configuration state.  The ``specs`` argument is a
        sequence that may contain absolute directory paths
        (e.g. ``/usr/share/locale``) or :term:`asset specification`
        names naming a directory path (e.g. ``some.package:locale``)
        or a combination of the two.
 
        Example:
 
        .. code-block:: python
 
           config.add_translation_dirs('/usr/share/locale',
                                       'some.package:locale')
 
        The translation directories are defined as a list in which
        translations defined later have precedence over translations defined
        earlier.
 
        By default, consecutive calls to ``add_translation_dirs`` will add
        directories to the start of the list. This means later calls to
        ``add_translation_dirs`` will have their translations trumped by
        earlier calls. If you explicitly need this call to trump an earlier
        call then you may set ``override`` to ``True``.
 
        If multiple specs are provided in a single call to
        ``add_translation_dirs``, the directories will be inserted in the
        order they're provided (earlier items are trumped by later items).
 
        .. versionchanged:: 1.8
 
           The ``override`` parameter was added to allow a later call
           to ``add_translation_dirs`` to override an earlier call, inserting
           folders at the beginning of the translation directory list.
 
        """
        introspectables = []
        override = kw.pop('override', False)
        if kw:
            raise TypeError('invalid keyword arguments: %s', sorted(kw.keys()))
 
        def register():
            directories = []
            resolver = AssetResolver(self.package_name)
 
            # defer spec resolution until register to allow for asset
            # overrides to take place in an earlier config phase
            for spec in specs:
                # the trailing slash helps match asset overrides for folders
                if not spec.endswith('/'):
                    spec += '/'
                asset = resolver.resolve(spec)
                directory = asset.abspath()
                if not asset.isdir():
                    raise ConfigurationError(
                        '"%s" is not a directory' % directory
                    )
                intr = self.introspectable(
                    'translation directories',
                    directory,
                    spec,
                    'translation directory',
                )
                intr['directory'] = directory
                intr['spec'] = spec
                introspectables.append(intr)
                directories.append(directory)
 
            tdirs = self.registry.queryUtility(ITranslationDirectories)
            if tdirs is None:
                tdirs = []
                self.registry.registerUtility(tdirs, ITranslationDirectories)
            if override:
                tdirs.extend(directories)
            else:
                for directory in reversed(directories):
                    tdirs.insert(0, directory)
 
        self.action(None, register, introspectables=introspectables)