File: __init__.py

package info (click to toggle)
moin 1.9.9-1%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 76,024 kB
  • sloc: python: 143,896; java: 10,704; php: 2,385; perl: 1,574; xml: 371; makefile: 214; sh: 81; sed: 5
file content (339 lines) | stat: -rw-r--r-- 10,086 bytes parent folder | download | duplicates (7)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - base classes for datastructs.

@copyright: 2009 MoinMoin:DmitrijsMilajevs
@license: GPL, see COPYING for details
"""

from UserDict import DictMixin


class GroupDoesNotExistError(Exception):
    """
    Raised when a group name is not found in the backend.
    """


class DictDoesNotExistError(Exception):
    """
    Raised when a dict name is not found in the backend.
    """


class BaseGroup(object):
    """
    Group is something which stores members. Groups are immutable. A
    member is some arbitrary entity name (Unicode object).
    """

    def __init__(self, request, name, backend):
        """
        Initialize a group.

        @param request
        @param name: moin group name
        @backend: backend object which created this object
        """
        self.request = request
        self.name = name
        self._backend = backend

    def __contains__(self, member, processed_groups=None):
        raise NotImplementedError()

    def __iter__(self, yielded_members=None, processed_groups=None):
        raise NotImplementedError()


class BaseGroupsBackend(object):
    """
    Backend provides access to the group definitions for the other
    MoinMoin code.
    """

    def __init__(self, request):
        self.request = request
        self.page_group_regex = request.cfg.cache.page_group_regexact

    def is_group_name(self, member):
        return self.page_group_regex.match(member)

    def __contains__(self, group_name):
        """
        Check if a group called <group_name> is available in this backend.
        """
        raise NotImplementedError()

    def __iter__(self):
        """
        Iterate over moin group names of the groups defined in this backend.

        @return: moin group names
        """
        raise NotImplementedError()

    def __getitem__(self, group_name):
        """
        Get a group by its moin group name.
        """
        raise NotImplementedError()

    def __repr__(self):
        return "<%s groups=%s>" % (self.__class__, list(self))

    def _retrieve_members(self, group_name):
        raise NotImplementedError()

    def groups_with_member(self, member):
        """
        List all group names of groups containing <member>.

        @param member: member name [unicode]
        @return: list of group names [unicode]
        """
        for group_name in self:
            try:
                if member in self[group_name]:
                    yield group_name
            except GroupDoesNotExistError:
                pass

    def get(self, key, default=None):
        """
        Return the group named <key> if key is in the backend, else
        default. If default is not given, it defaults to None, so that
        this method never raises a GroupDoesNotExistError.
        """
        try:
            return self[key]
        except GroupDoesNotExistError:
            return default


class LazyGroup(BaseGroup):
    """
    A lazy group does not store members internally, but gets them from
    a backend when needed.

    Lazy group is made only of members. It can not consist of other groups.

    For instance, this is a possible LazyGroup:

     PossibleGroup
      * OneMember
      * OtherMember

    This is a group which cannot be LazyGroup:

     NotPossibleGroup
      * OneMember
      * OtherMember
      * OtherGroup
    """

    def __init__(self, request, name, backend):
        super(LazyGroup, self).__init__(request, name, backend)

        if name not in backend:
            raise GroupDoesNotExistError(name)

    def __contains__(self, member, processed_groups=None):
        # processed_groups are not used here but other group classes
        # may expect this parameter.
        return self._backend._group_has_member(self.name, member)

    def __iter__(self, yielded_members=None, processed_groups=None):
        # processed_groups are not used here but other group classes
        # may expect this parameter.
        if yielded_members is None:
            yielded_members = set()

        for member in self._backend._iter_group_members(self.name):
            if member not in yielded_members:
                yielded_members.add(member)
                yield member


class LazyGroupsBackend(BaseGroupsBackend):

    def _iter_group_members(self, group_name):
        raise NotImplementedError()

    def _group_has_member(self, group_name, member):
        raise NotImplementedError()


class GreedyGroup(BaseGroup):
    """
    GreedyGroup gets all members during initialization and stores them internally.

    Members of a group may be names of other groups.
    """

    def __init__(self, request, name, backend):

        super(GreedyGroup, self).__init__(request, name, backend)
        self.members, self.member_groups = self._load_group()

    def _load_group(self):
        """
        Retrieve group data from the backend and filter it to members and group_members.
        """
        members_retrieved = set(self._backend._retrieve_members(self.name))

        member_groups = set(member for member in members_retrieved if self._backend.is_group_name(member))
        members = members_retrieved - member_groups

        return members, member_groups

    def __contains__(self, member, processed_groups=None):
        """
        First check if <member> is part of this group and then check
        for every subgroup in this group.

        <processed_groups> is needed to avoid infinite recursion, if
        groups are defined recursively.

        @param member: member name [unicode]
        @param processed_groups: groups which were checked for containment before [set]
        """

        if processed_groups is None:
            processed_groups = set()

        processed_groups.add(self.name)

        if member in self.members or member in self.member_groups:
            return True
        else:
            groups = self.request.groups
            for group_name in self.member_groups:
                if group_name not in processed_groups and group_name in groups and groups[group_name].__contains__(member, processed_groups):
                    return True

        return False

    def __iter__(self, yielded_members=None, processed_groups=None):
        """
        Iterate first over members of this group, then over subgroups of this group.

        <yielded_members> and <processed_groups> are needed to avoid infinite recursion.
        This can happen if there are two groups like these:
           OneGroup: Something, OtherGroup
           OtherGroup: OneGroup, SomethingOther

        @param yielded_members: members which have been already yielded before [set]
        @param processed_groups: group names which have been iterated before [set]
        """

        if processed_groups is None:
            processed_groups = set()

        if yielded_members is None:
            yielded_members = set()

        processed_groups.add(self.name)

        for member in self.members:
            if member not in yielded_members:
                yielded_members.add(member)
                yield member

        groups = self.request.groups
        for group_name in self.member_groups:
            if group_name not in processed_groups:
                if group_name in groups:
                    for member in groups[group_name].__iter__(yielded_members, processed_groups):
                        yield member
                else:
                    yield group_name

    def __repr__(self):
        return "<%s name=%s members=%s member_groups=%s>" % (self.__class__,
                                                             self.name,
                                                             self.members,
                                                             self.member_groups)


class BaseDict(object, DictMixin):

    def __init__(self, request, name, backend):
        """
        Initialize a dict. Dicts are greedy, it stores all keys and
        items internally.

        @param request
        @param name: moin dict name
        @backend: backend object which created this object
        """
        self.request = request
        self.name = name
        self._backend = backend
        self._dict = self._load_dict()

    def __iter__(self):
        return self._dict.__iter__()

    def keys(self):
        return list(self)

    def __len__(self):
        return self._dict.__len__()

    def __getitem__(self, key):
        return self._dict[key]

    def get(self, key, default=None):
        """
        Return the value if key is in the dictionary, else default. If
        default is not given, it defaults to None, so that this method
        never raises a KeyError.
        """
        return self._dict.get(key, default)

    def _load_dict(self):
        """
        Retrieve dict data from the backend.
        """
        return self._backend._retrieve_items(self.name)

    def __repr__(self):
        return "<%r name=%r items=%r>" % (self.__class__, self.name, self._dict.items())


class BaseDictsBackend(object):

    def __init__(self, request):
        self.request = request
        self.page_dict_regex = request.cfg.cache.page_dict_regexact

    def is_dict_name(self, name):
        return self.page_dict_regex.match(name)

    def __contains__(self, dict_name):
        """
        Check if a dict called <dict_name> is available in this backend.
        """
        raise NotImplementedError()

    def __getitem__(self, dict_name):
        """
        Get a dict by its moin dict name.
        """
        raise NotImplementedError()

    def _retrieve_items(self, dict_name):
        raise NotImplementedError()

    def get(self, key, default=None):
        """
        Return the dictionary named <key> if key is in the backend,
        else default. If default is not given, it defaults to None, so
        that this method never raises a DictDoesNotExistError.
        """
        try:
            return self[key]
        except DictDoesNotExistError:
            return default