• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rero / sonar / 17425918180

03 Sep 2025 07:11AM UTC coverage: 95.796% (-0.6%) from 96.378%
17425918180

push

github

PascalRepond
translations: extract messages

Co-Authored-by: Pascal Repond <pascal.repond@rero.ch>

7816 of 8159 relevant lines covered (95.8%)

0.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.91
/sonar/modules/collections/schemas.py
1
# Swiss Open Access Repository
2
# Copyright (C) 2021 RERO
3
#
4
# This program is free software: you can redistribute it and/or modify
5
# it under the terms of the GNU Affero General Public License as published by
6
# the Free Software Foundation, version 3 of the License.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU Affero General Public License for more details.
12
#
13
# You should have received a copy of the GNU Affero General Public License
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15

16
"""Marshmallow schemas."""
17

18
from functools import partial
1✔
19

20
from invenio_records_rest.schemas import Nested, StrictKeysMixin
1✔
21
from invenio_records_rest.schemas.fields import (
1✔
22
    GenFunction,
23
    PersistentIdentifier,
24
    SanitizedUnicode,
25
)
26
from marshmallow import EXCLUDE, fields, pre_dump, pre_load
1✔
27

28
from sonar.modules.serializers import schema_from_context
1✔
29
from sonar.modules.users.api import current_user_record
1✔
30
from sonar.modules.utils import get_language_value
1✔
31

32
from .api import Record
1✔
33
from .permissions import FilesPermission, RecordPermission
1✔
34

35
schema_from_record = partial(schema_from_context, schema=Record.schema)
1✔
36

37

38
class FileSchemaV1(StrictKeysMixin):
1✔
39
    """File schema."""
40

41
    class Meta:
1✔
42
        """Meta for file schema."""
43

44
        # Specifically exclude unknown fields, as in the new version of
45
        # marshmallow, dump_only fields are treated as included.
46
        # https://github.com/marshmallow-code/marshmallow/issues/875
47
        unknown = EXCLUDE
1✔
48

49
    bucket = SanitizedUnicode()
1✔
50
    file_id = SanitizedUnicode()
1✔
51
    version_id = SanitizedUnicode()
1✔
52
    key = fields.Str()
1✔
53
    mimetype = SanitizedUnicode()
1✔
54
    checksum = SanitizedUnicode()
1✔
55
    size = fields.Integer()
1✔
56
    label = SanitizedUnicode()
1✔
57
    type = SanitizedUnicode()
1✔
58
    order = fields.Integer()
1✔
59
    external_url = SanitizedUnicode()
1✔
60
    access = SanitizedUnicode()
1✔
61
    restricted_outside_organisation = fields.Boolean()
1✔
62
    embargo_date = SanitizedUnicode()
1✔
63
    restriction = fields.Dict(dump_only=True)
1✔
64
    links = fields.Dict(dump_only=True)
1✔
65
    thumbnail = SanitizedUnicode(dump_only=True)
1✔
66
    permissions = fields.Dict(dump_only=True)
1✔
67

68
    @pre_dump
1✔
69
    def add_permissions(self, item, **kwargs):
1✔
70
        """Add permissions to record.
71

72
        :param item: Dict representing the record.
73
        :returns: Modified dict.
74
        """
75
        if not item.get("bucket"):
×
76
            return item
×
77
        doc = Record.get_record_by_bucket(item.get("bucket"))
×
78
        item["permissions"] = {
×
79
            "read": FilesPermission.read(current_user_record, item, doc["pid"], doc),
80
            "update": FilesPermission.update(current_user_record, item, doc["pid"], doc),
81
            "delete": FilesPermission.delete(current_user_record, item, doc["pid"], doc),
82
        }
83

84
        return item
×
85

86
    @pre_load
1✔
87
    def remove_fields(self, data, **kwargs):
1✔
88
        """Removes computed fields.
89

90
        :param data: Dict of record data.
91
        :returns: Modified data.
92
        """
93
        data.pop("permissions", None)
×
94
        return data
×
95

96

97
class RecordMetadataSchema(StrictKeysMixin):
1✔
98
    """Schema for record metadata."""
99

100
    pid = PersistentIdentifier()
1✔
101
    name = fields.List(fields.Dict(), required=True)
1✔
102
    description = fields.List(fields.Dict())
1✔
103
    organisation = fields.Dict()
1✔
104
    permissions = fields.Dict(dump_only=True)
1✔
105
    label = fields.Method("get_label")
1✔
106
    # When loading, if $schema is not provided, it's retrieved by
107
    # Record.schema property.
108
    schema = GenFunction(
1✔
109
        load_only=True,
110
        attribute="$schema",
111
        data_key="$schema",
112
        deserialize=schema_from_record,
113
    )
114
    _files = Nested(FileSchemaV1, many=True)
1✔
115
    _bucket = SanitizedUnicode()
1✔
116

117
    def get_label(self, obj):
1✔
118
        """Get label."""
119
        return get_language_value(obj["name"])
1✔
120

121
    @pre_load
1✔
122
    def remove_fields(self, data, **kwargs):
1✔
123
        """Removes computed fields.
124

125
        :param dict data: Record data
126
        :return: Modified data
127
        :rtype: dict
128
        """
129
        data.pop("permissions", None)
1✔
130
        data.pop("label", None)
1✔
131

132
        return data
1✔
133

134
    @pre_load
1✔
135
    def guess_organisation(self, data, **kwargs):
1✔
136
        """Guess organisation from current logged user.
137

138
        :param dict data: Record data
139
        :return: Modified data
140
        :rtype: dict
141
        """
142
        # Organisation already attached to project, we do nothing.
143
        if data.get("organisation"):
1✔
144
            return data
1✔
145

146
        # Store current user organisation in new project.
147
        if current_user_record.get("organisation"):
1✔
148
            data["organisation"] = current_user_record["organisation"]
1✔
149

150
        return data
1✔
151

152
    @pre_dump
1✔
153
    def add_permissions(self, item, **kwargs):
1✔
154
        """Add permissions to record.
155

156
        :param dict item: Record data
157
        :return: Modified item
158
        :rtype: dict
159
        """
160
        item["permissions"] = {
1✔
161
            "read": RecordPermission.read(current_user_record, item),
162
            "update": RecordPermission.update(current_user_record, item),
163
            "delete": RecordPermission.delete(current_user_record, item),
164
        }
165

166
        return item
1✔
167

168

169
class RecordSchema(StrictKeysMixin):
1✔
170
    """Schema for record."""
171

172
    metadata = fields.Nested(RecordMetadataSchema)
1✔
173
    created = fields.Str(dump_only=True)
1✔
174
    updated = fields.Str(dump_only=True)
1✔
175
    links = fields.Dict(dump_only=True)
1✔
176
    id = PersistentIdentifier()
1✔
177
    explanation = fields.Raw(dump_only=True)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc