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

iplweb / bpp / 3104

10 Dec 2023 06:49PM UTC coverage: 52.711% (-29.3%) from 82.043%
3104

push

circleci

mpasternak
Merge branch 'release/v202312.1122'

167 of 327 new or added lines in 47 files covered. (51.07%)

9871 existing lines in 333 files now uncovered.

17929 of 34014 relevant lines covered (52.71%)

2.02 hits per line

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

83.54
src/bpp/models/util.py
1
"""Funkcje pomocnicze dla klas w bpp.models"""
2
from django.core.exceptions import ObjectDoesNotExist, ValidationError
5✔
3

4
from bpp.models.szablondlaopisubibliograficznego import SzablonDlaOpisuBibliograficznego
5✔
5

6
try:
5✔
7
    from django.core.urlresolvers import reverse
5✔
8
except ImportError:
5✔
9
    from django.urls import reverse
5✔
10

11
from django.db import models
5✔
12
from django.db.models import Max
5✔
13
from django.template.loader import get_template
5✔
14

15
from django.utils import safestring
5✔
16

17

18
def dodaj_autora(
5✔
19
    klass,
20
    rekord,
21
    autor,
22
    jednostka,
23
    zapisany_jako=None,
24
    typ_odpowiedzialnosci_skrot="aut.",
25
    kolejnosc=None,
26
    dyscyplina_naukowa=None,
27
    afiliuje=True,
28
):
29
    """
30
    Utility function, dodająca autora do danego rodzaju klasy (Wydawnictwo_Ciagle,
31
    Wydawnictwo_Zwarte, Patent); funkcja używana przez te klasy, niejako
32
    wewnętrzna dla całego API; nie powinna być używana bezpośrednio nigdzie,
33
    jedynie API tych klas winno być używane.
34

35
    :param klass:
36
    :param rekord:
37
    :param autor:
38
    :param jednostka:
39
    :param zapisany_jako:
40
    :param typ_odpowiedzialnosci_skrot:
41
    :param kolejnosc:
42
    :return:
43
    """
44

45
    from bpp.models import Typ_Odpowiedzialnosci
4✔
46

47
    typ_odpowiedzialnosci = Typ_Odpowiedzialnosci.objects.get(
4✔
48
        skrot=typ_odpowiedzialnosci_skrot
49
    )
50

51
    if zapisany_jako is None:
4✔
52
        zapisany_jako = f"{autor.nazwisko} {autor.imiona}"
4✔
53

54
    if kolejnosc is None:
4✔
55
        kolejnosc = klass.objects.filter(rekord=rekord).aggregate(Max("kolejnosc"))[
4✔
56
            "kolejnosc__max"
57
        ]
58
        if kolejnosc is None:
4✔
59
            kolejnosc = 0
4✔
60
        else:
UNCOV
61
            kolejnosc += 1
×
62

63
    inst = klass(
4✔
64
        rekord=rekord,
65
        autor=autor,
66
        jednostka=jednostka,
67
        typ_odpowiedzialnosci=typ_odpowiedzialnosci,
68
        kolejnosc=kolejnosc,
69
        zapisany_jako=zapisany_jako,
70
        dyscyplina_naukowa=dyscyplina_naukowa,
71
        afiliuje=afiliuje,
72
    )
73
    inst.full_clean()
4✔
74
    inst.save()
4✔
75
    return inst
4✔
76

77

78
class ModelZOpisemBibliograficznym(models.Model):
5✔
79
    """Mixin, umożliwiający renderowanie opisu bibliograficznego dla danego
80
    obiektu przy pomocy template."""
81

82
    tekst_przed_pierwszym_autorem = models.TextField(blank=True, null=True)
5✔
83
    tekst_po_ostatnim_autorze = models.TextField(blank=True, null=True)
5✔
84

85
    def opis_bibliograficzny(self, links=None):
5✔
86
        """Renderuje opis bibliograficzny dla danej klasy, używając:
87
        * w pierwszej kolejności zadeklarowanej Template dla danego typu rekordu (lub ogólnego Template),
88
        * w trzeciej kolejności templatki z dysku "opis_bibliograficzny/opis_bibliograficzny.html"
89

90
        :param links: "normal" lub "admin" jeżeli chcemy, aby autorzy prowadzili gdzieś (do stron browse/
91
        lub do admina).
92
        """
93

94
        template_name = SzablonDlaOpisuBibliograficznego.objects.get_for_model(self)
5✔
95
        if template_name is None:
5✔
96
            template_name = "opis_bibliograficzny.html"
5✔
97

98
        template = get_template(template_name)
5✔
99

100
        ret = (
5✔
101
            template.render(dict(praca=self, links=links))
102
            .replace("\r\n", "")
103
            .replace("\n", "")
104
        )
105
        while ret.find("  ") != -1:
5✔
106
            ret = ret.replace("  ", " ")
5✔
107

108
        return (
5✔
109
            ret.replace(" , ", ", ")
110
            .replace(" . ", ". ")
111
            .replace(". . ", ". ")
112
            .replace(". , ", ". ")
113
            .replace(" .", ".")
114
            .replace(".</b>[", ".</b> [")
115
        )
116

117
    def autorzy_dla_opisu(self):
5✔
118
        # Takie 'autorzy_set.all()' ale na potrzeby opisu bibliograficznego -- zaciąga
119
        # rekordy zależne za pomocą .select_related:
120

121
        if not self.pk:
5✔
122
            return []
5✔
123

124
        return self.autorzy_set.select_related(
5✔
125
            "autor", "typ_odpowiedzialnosci"
126
        ).order_by("kolejnosc")
127

128
    def get_slug(self):
5✔
129
        if self.pk is None:
5✔
130
            return
5✔
131

132
        from bpp.util import slugify_function
5✔
133

134
        slug_tytul_oryginalny = slugify_function(self.tytul_oryginalny)
5✔
135

136
        slug_trzech_pierwszych_autorow = []
5✔
137
        for wyd_autor in self.autorzy_set.all().select_related("autor")[:3]:
5✔
UNCOV
138
            slug_trzech_pierwszych_autorow.append(
×
139
                f"{wyd_autor.autor.nazwisko} {wyd_autor.autor.imiona[:1]}"
140
            )
141
        slug_trzech_pierwszych_autorow = " ".join(slug_trzech_pierwszych_autorow)
5✔
142

143
        if hasattr(self, "zrodlo_id") and self.zrodlo_id is not None:
5✔
144
            slug_zrodla = slugify_function(self.zrodlo.nazwa)
2✔
145
        elif (
4✔
146
            hasattr(self, "wydawnictwo_nadrzedne")
147
            and self.wydawnictwo_nadrzedne_id is not None
148
        ):
UNCOV
149
            slug_zrodla = slugify_function(self.wydawnictwo_nadrzedne.tytul_oryginalny)
×
150
        else:
151
            slug_zrodla = ""
4✔
152

153
        lt, la, lz = (
5✔
154
            len(slug_tytul_oryginalny),
155
            len(slug_trzech_pierwszych_autorow),
156
            len(slug_zrodla),
157
        )
158

159
        if lt + la + lz >= 350:
5✔
UNCOV
160
            if lt > 200:
×
UNCOV
161
                lt = 200
×
162

UNCOV
163
            if lt + la + lz >= 350:
×
UNCOV
164
                if lz > 100:
×
UNCOV
165
                    lz = 100
×
166

UNCOV
167
                if lt + la + lz >= 350:
×
UNCOV
168
                    la = 50
×
169

170
        from django.contrib.contenttypes.models import ContentType
5✔
171

172
        ret = "-".join(
5✔
173
            [
174
                slug_tytul_oryginalny[:lt],
175
                slug_zrodla[:lz],
176
                slug_trzech_pierwszych_autorow[:la],
177
                str(ContentType.objects.get_for_model(self).pk),
178
                str(self.pk),
179
            ]
180
        )
181

182
        return slugify_function(ret)
5✔
183

184
    # Ten obiekt stanowi bazę do późniejszego zapełniania pól w podklasach. Pola,
185
    # które powinna podklasa definiować to:
186
    #
187
    # opis_bibliograficzny_cache = models.TextField(default="")
188
    # - generowane przez self.opis_bibliograficzny()
189
    #
190
    # opis_bibliograficzny_autorzy_cache = ArrayField(TextField(), blank=True, null=True)
191
    # -  To pole używane jest na ten moment jedynie przez moduł OAI, do szybkiego
192
    #    produkowania pola "Creator" dla formatu Dublin Core, vide moduł bpp.oai .
193
    #    To pole zawiera listę autorów, w kolejności, nazwisko i imię, bez
194
    #    tytułu
195
    #
196
    # slug = models.SlugField(max_length=400, unique=True, db_index=True, null=True, blank=True)
197
    # - skrót dla rekordu, dla SEO, zależy od m.in. tytułu, autorów, wydawnictwa nadrzędnego, źródła
198
    #
199
    # opis_bibliograficzny_zapisani_autorzy_cache = models.TextField(default="")
200
    # - zależy od klas autorów; to pole używane jest przez Raport autorów oraz Raport
201
    #   jednostek do szybkiego wypluwania listy zapisanych nazwisk
202
    #
203
    # def zaktualizuj_opis_bibliograficzny_cache(self, tylko_opis=False):
204
    #     autorzy = self.autorzy_dla_opisu()
205
    #     self.opis_bibliograficzny_cache = self.opis_bibliograficzny()
206
    #     self.slug = self._get_slug()
207
    #
208
    #     if hasattr(self, "autor"):
209
    #         zapisani = ["%s %s" % (autorzy[0].autor.nazwisko, autorzy[0].autor.imiona)]
210
    #     else:
211
    #         zapisani = [x.zapisany_jako for x in autorzy]
212
    #
213
    #     oac = ["%s %s" % (x.autor.nazwisko, x.autor.imiona) for x in autorzy]
214
    #     self.opis_bibliograficzny_autorzy_cache = oac
215
    #
216
    #     ozac = ", ".join(zapisani)
217
    #     self.opis_bibliograficzny_zapisani_autorzy_cache = ozac
218

219
    class Meta:
5✔
220
        abstract = True
5✔
221

222

223
class ZapobiegajNiewlasciwymCharakterom(models.Model):
5✔
224
    class Meta:
5✔
225
        abstract = True
5✔
226

227
    def clean_fields(self, *args, **kw):
5✔
228
        try:
3✔
229
            cf = self.charakter_formalny
3✔
230
        except ObjectDoesNotExist:
×
231
            cf = None
×
232

233
        if cf is not None:
3✔
234
            if self.charakter_formalny.skrot in ["D", "H", "PAT"]:
3✔
UNCOV
235
                raise ValidationError(
×
236
                    {
237
                        "charakter_formalny": [
238
                            safestring.mark_safe(
239
                                'Jeżeli chcesz dodać rekord o typie "%s"'
240
                                ', <a href="%s">kliknij tutaj</a>.'
241
                                % (
242
                                    self.charakter_formalny.nazwa,
243
                                    reverse(
244
                                        "admin:bpp_%s_add"
245
                                        % self.charakter_formalny.nazwa.lower().replace(
246
                                            " ", "_"
247
                                        )
248
                                    ),
249
                                )
250
                            )
251
                        ]
252
                    }
253
                )
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