This file is indexed.

/usr/lib/python3/dist-packages/restless/preparers.py is in python3-restless 2.1.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
class Preparer(object):
    """
    A plain preparation object which just passes through data.

    It also is relevant as the protocol subclasses should implement to work with
    Restless.
    """
    def __init__(self):
        super(Preparer, self).__init__()

    def prepare(self, data):
        """
        Handles actually transforming the data.

        By default, this does nothing & simply returns the data passed to it.
        """
        return data


class FieldsPreparer(Preparer):
    """
    A more complex preparation object, this will return a given set of fields.

    This takes a ``fields`` parameter, which should be a dictionary of
    keys (fieldnames to expose to the user) & values (a dotted lookup path to
    the desired attribute/key on the object).

    Example::

        preparer = FieldsPreparer(fields={
            # ``user`` is the key the client will see.
            # ``author.pk`` is the dotted path lookup ``FieldsPreparer``
            # will traverse on the data to return a value.
            'user': 'author.pk',
        })

    """
    def __init__(self, fields):
        super(FieldsPreparer, self).__init__()
        self.fields = fields

    def prepare(self, data):
        """
        Handles transforming the provided data into the fielded data that should
        be exposed to the end user.

        Uses the ``lookup_data`` method to traverse dotted paths.

        Returns a dictionary of data as the response.
        """
        result = {}

        if not self.fields:
            # No fields specified. Serialize everything.
            return data

        for fieldname, lookup in self.fields.items():
            if isinstance(lookup, SubPreparer):
                result[fieldname] = lookup.prepare(data)
            else:
                result[fieldname] = self.lookup_data(lookup, data)

        return result

    def lookup_data(self, lookup, data):
        """
        Given a lookup string, attempts to descend through nested data looking for
        the value.

        Can work with either dictionary-alikes or objects (or any combination of
        those).

        Lookups should be a string. If it is a dotted path, it will be split on
        ``.`` & it will traverse through to find the final value. If not, it will
        simply attempt to find either a key or attribute of that name & return it.

        Example::

            >>> data = {
            ...     'type': 'message',
            ...     'greeting': {
            ...         'en': 'hello',
            ...         'fr': 'bonjour',
            ...         'es': 'hola',
            ...     },
            ...     'person': Person(
            ...         name='daniel'
            ...     )
            ... }
            >>> lookup_data('type', data)
            'message'
            >>> lookup_data('greeting.en', data)
            'hello'
            >>> lookup_data('person.name', data)
            'daniel'

        """
        value = data
        parts = lookup.split('.')

        if not parts or not parts[0]:
            return value

        part = parts[0]
        remaining_lookup = '.'.join(parts[1:])

        if callable(getattr(data, 'keys', None)) and hasattr(data, '__getitem__'):
            # Dictionary enough for us.
            value = data[part]
        elif data is not None:
            # Assume it's an object.
            value = getattr(data, part)

        # Call if it's callable except if it's a Django DB manager instance
        #   We check if is a manager by checking the db_manager (duck typing)
        if callable(value) and not hasattr(value, 'db_manager'):
            value = value()

        if not remaining_lookup:
            return value

        # There's more to lookup, so dive in recursively.
        return self.lookup_data(remaining_lookup, value)


class SubPreparer(FieldsPreparer):
    """
    A preparation class designed to be used within other preparers.

    This is primary to enable deeply-nested structures, allowing you
    to compose/share definitions as well. Typical usage consists of creating
    a configured instance of a FieldsPreparer, then use a `SubPreparer` to
    pull it in.

    Example::

        # First, define the nested fields you'd like to expose.
        author_preparer = FieldsPreparer(fields={
            'id': 'pk',
            'username': 'username',
            'name': 'get_full_name',
        })
        # Then, in the main preparer, pull them in using `SubPreparer`.
        preparer = FieldsPreparer(fields={
            'author': SubPreparer('user', author_preparer),
            # Other fields can come before/follow as normal.
            'content': 'post',
            'created': 'created_at',
        })

    """
    def __init__(self, lookup, preparer):
        self.lookup = lookup
        self.preparer = preparer

    def get_inner_data(self, data):
        """
        Used internally so that the correct data is extracted out of the
        broader dataset, allowing the preparer being called to deal with just
        the expected subset.
        """
        return self.lookup_data(self.lookup, data)

    def prepare(self, data):
        """
        Handles passing the data to the configured preparer.

        Uses the ``get_inner_data`` method to provide the correct subset of
        the data.

        Returns a dictionary of data as the response.
        """
        return self.preparer.prepare(self.get_inner_data(data))


class CollectionSubPreparer(SubPreparer):
    """
    A preparation class designed to handle collections of data.

    This is useful in the case where you have a 1-to-many or many-to-many
    relationship of data to expose as part of the parent data.

    Example::

        # First, set up a preparer that handles the data for each thing in
        # the broader collection.
        comment_preparer = FieldsPreparer(fields={
            'comment': 'comment_text',
            'created': 'created',
        })
        # Then use it with the ``CollectionSubPreparer`` to create a list
        # of prepared sub items.
        preparer = FieldsPreparer(fields={
            # A normal blog post field.
            'post': 'post_text',
            # All the comments on the post.
            'comments': CollectionSubPreparer('comments.all', comment_preparer),
        })

    """
    def prepare(self, data):
        """
        Handles passing each item in the collection data to the configured
        subpreparer.

        Uses a loop and the ``get_inner_data`` method to provide the correct
        item of the data.

        Returns a list of data as the response.
        """
        result = []

        for item in self.get_inner_data(data):
            result.append(self.preparer.prepare(item))

        return result