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

iplweb / bpp / 0950478e-207f-4389-967f-fb3a6c1090d4

01 Apr 2025 12:57PM UTC coverage: 43.279% (-3.3%) from 46.628%
0950478e-207f-4389-967f-fb3a6c1090d4

push

circleci

mpasternak
Merge branch 'release/v202504.1175'

1 of 19 new or added lines in 5 files covered. (5.26%)

1780 existing lines in 123 files now uncovered.

15876 of 36683 relevant lines covered (43.28%)

0.79 hits per line

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

85.11
src/bpp/models/system.py
1
"""
2
Małe klasy pomocnicze dla całego systemu
3
"""
4

5
import warnings
2✔
6

7
from django.db import models
2✔
8
from django.db.models import CASCADE
2✔
9
from django.db.models.signals import post_migrate
2✔
10
from django.dispatch import receiver
2✔
11
from django.urls import reverse
2✔
12
from model_utils import Choices
2✔
13
from mptt.fields import TreeForeignKey
2✔
14
from mptt.models import MPTTModel
2✔
15

16
from bpp import const
2✔
17
from bpp.models.abstract import ModelZNazwa, NazwaISkrot
2✔
18

19
NAZWY_PRIMO = [
2✔
20
    "",
21
    "Artykuł",
22
    "Książka",
23
    "Zasób tekstowy",
24
    "Rozprawa naukowa",
25
    "Recenzja",
26
    "Artykuł prasowy",
27
    "Rozdział",
28
    "Czasopismo",
29
    "Dane badawcze",
30
    "Materiał konferencyjny",
31
    "Obraz",
32
    "Baza",
33
    "Zestaw danych statystycznych",
34
    "Multimedia",
35
    "Inny",
36
]
37

38
NAZWY_PRIMO = list(zip(NAZWY_PRIMO, NAZWY_PRIMO))
2✔
39

40
RODZAJE_DOKUMENTOW_PBN = [
2✔
41
    ("article", "Artykuł"),
42
    ("book", "Książka"),
43
    ("chapter", "Rozdział"),
44
]
45

46

47
class Charakter_PBN(models.Model):
2✔
48
    wlasciwy_dla = models.CharField(
2✔
49
        "Właściwy dla...", max_length=20, choices=RODZAJE_DOKUMENTOW_PBN
50
    )
51
    identyfikator = models.CharField(max_length=100)
2✔
52
    opis = models.CharField(max_length=500)
2✔
53
    help_text = models.TextField(blank=True)
2✔
54

55
    class Meta:
2✔
56
        ordering = ["identyfikator"]
2✔
57
        verbose_name = "Charakter PBN"
2✔
58
        verbose_name_plural = "Charaktery PBN"
2✔
59

60
    def __str__(self):
2✔
61
        return self.opis
×
62

63

64
CHARAKTER_SLOTY = Choices(
2✔
65
    (const.CHARAKTER_SLOTY_KSIAZKA, "ksiazka", "Książka"),
66
    (const.CHARAKTER_SLOTY_ROZDZIAL, "rozdzial", "Rozdział"),
67
    (const.CHARAKTER_SLOTY_REFERAT, "referat", "Referat"),
68
)
69

70
RODZAJ_PBN_CHOICES = [
2✔
71
    (None, "nie eksportuj do PBN"),
72
    (const.RODZAJ_PBN_ARTYKUL, "artykuł"),
73
    (const.RODZAJ_PBN_KSIAZKA, "książka"),
74
    (const.RODZAJ_PBN_ROZDZIAL, "rozdział"),
75
    (const.RODZAJ_PBN_POSTEPOWANIE, "postępowanie"),
76
]
77

78
CHARAKTER_OGOLNY_CHOICES = Choices(
2✔
79
    (const.CHARAKTER_OGOLNY_ARTYKUL, "artykul", "Artykuł"),
80
    (const.CHARAKTER_OGOLNY_KSIAZKA, "ksiazka", "Książka"),
81
    (const.CHARAKTER_OGOLNY_ROZDZIAL, "rozdzial", "Rozdział"),
82
    (const.CHARAKTER_OGOLNY_INNE, "inne", "Inne"),
83
)
84

85

86
class Charakter_Formalny(NazwaISkrot, MPTTModel):
2✔
87
    class CHARAKTER_CROSSREF(models.IntegerChoices):
2✔
88
        JOURNAL_ARTICLE = 1, "journal-article"
2✔
89
        PROCEEDINGS_ARTICLE = 2, "proceedings-article"
2✔
90
        BOOK = 3, "book"
2✔
91
        BOOK_CHAPTER = 4, "book-chapter"
2✔
92

93
    denorm_always_skip = (
2✔
94
        "tree_id",
95
        "lft",
96
        "rght",
97
        "level",
98
    )
99
    parent = TreeForeignKey(
2✔
100
        "self",
101
        verbose_name="Charakter nadrzędny",
102
        on_delete=models.CASCADE,
103
        null=True,
104
        blank=True,
105
        related_name="children",
106
    )
107

108
    charakter_ogolny = models.CharField(
2✔
109
        max_length=3,
110
        help_text="""Charakter ogólny uzywany jest m.in. do generowania opisów bibliograficznych. Stanowi on
111
        ogólne określenie rekordu, czy jest to książka, rozdział czy coś innego. """,
112
        default=const.CHARAKTER_OGOLNY_INNE,
113
        choices=CHARAKTER_OGOLNY_CHOICES,
114
    )
115

116
    publikacja = models.BooleanField(
2✔
117
        help_text="""Jest charakterem dla publikacji""", default=False
118
    )
119
    streszczenie = models.BooleanField(
2✔
120
        help_text="""Jest charakterem dla streszczeń""", default=False
121
    )
122

123
    nazwa_w_primo = models.CharField(
2✔
124
        "Nazwa w Primo",
125
        max_length=100,
126
        help_text="""
127
    Nazwa charakteru formalnego w wyszukiwarce Primo, eksponowana przez OAI-PMH. W przypadku,
128
    gdy to pole jest puste, prace o danym charakterze formalnym nie będą udostępniane przez
129
    protokół OAI-PMH.
130
    """,
131
        blank=True,
132
        default="",
133
        choices=NAZWY_PRIMO,
134
        db_index=True,
135
    )
136

137
    charakter_pbn = models.ForeignKey(
2✔
138
        Charakter_PBN,
139
        verbose_name="Charakter PBN",
140
        blank=True,
141
        null=True,
142
        default=None,
143
        help_text="""Wartość wybrana w tym polu zostanie użyta jako zawartość tagu <is>
144
                                      w plikach eksportu do PBN""",
145
        on_delete=CASCADE,
146
    )
147

148
    rodzaj_pbn = models.PositiveSmallIntegerField(
2✔
149
        verbose_name="Rodzaj dla PBN",
150
        choices=RODZAJ_PBN_CHOICES,
151
        null=True,
152
        blank=True,
153
        help_text="""Pole określające, czy wydawnictwa posiadające dany charakter formalny zostaną włączone
154
        do eksportu PBN jako artykuły, rozdziały czy książki. """,
155
        default=None,
156
    )
157

158
    charakter_sloty = models.PositiveSmallIntegerField(
2✔
159
        "Charakter dla slotów",
160
        null=True,
161
        blank=True,
162
        default=None,
163
        choices=CHARAKTER_SLOTY,
164
        help_text="""Jak potraktować ten charakter przy kalkulacji slotów dla wydawnictwa zwartego?""",
165
    )
166

167
    charakter_crossref = models.PositiveSmallIntegerField(
2✔
168
        "Charakter w CrossRef",
169
        null=True,
170
        blank=True,
171
        default=None,
172
        choices=CHARAKTER_CROSSREF.choices,
173
        unique=True,
174
    )
175

176
    wliczaj_do_rankingu = models.BooleanField(default=True)
2✔
177

178
    class Meta:
2✔
179
        ordering = ["nazwa"]
2✔
180
        app_label = "bpp"
2✔
181
        verbose_name = "charakter formalny"
2✔
182
        verbose_name_plural = "charaktery formalne"
2✔
183

184
    class MPTTMeta:
2✔
185
        order_insertion_by = ["nazwa"]
2✔
186

187
    #
188
    # Kompatybilne API dla .artykul_pbn, .rozdzial_pbn, .ksiazka_pbn
189
    #
190

191
    def get_rodzaj(self, typ):
2✔
192
        warnings.warn("W przyszlosci uzyj pola 'rodzaj_pbn'", DeprecationWarning)
×
193
        v = getattr(const, "RODZAJ_PBN_%s" % typ.upper())
×
194
        if self.rodzaj_pbn == v:
×
195
            return True
×
196
        return False
×
197

198
    def set_rodzaj(self, typ, value):
2✔
199
        warnings.warn("W przyszlosci uzyj pola 'rodzaj_pbn'", DeprecationWarning)
×
200
        v = getattr(const, "RODZAJ_PBN_%s" % typ.upper())
×
201
        if value is True:
×
202
            self.rodzaj_pbn = v
×
203
        else:
204
            raise NotImplementedError(
×
205
                "Nie wiem jak sie zachowac, gdy atrybut self.%s_pbn jest ustawiany na False"
206
                % typ
207
            )
208

209
    def get_artykul_pbn(self):
2✔
210
        return self.get_rodzaj("artykul")
×
211

212
    def get_ksiazka_pbn(self):
2✔
213
        return self.get_rodzaj("ksiazka")
×
214

215
    def get_rozdzial_pbn(self):
2✔
216
        return self.get_rodzaj("rozdzial")
×
217

218
    def set_artykul_pbn(self, v):
2✔
219
        return self.set_rodzaj("artykul", v)
×
220

221
    def set_ksiazka_pbn(self, v):
2✔
222
        return self.set_rodzaj("ksiazka", v)
×
223

224
    def set_rozdzial_pbn(self, v):
2✔
225
        return self.set_rodzaj("rozdzial", v)
×
226

227
    artykul_pbn = property(get_artykul_pbn, set_artykul_pbn)
2✔
228
    ksiazka_pbn = property(get_ksiazka_pbn, set_ksiazka_pbn)
2✔
229
    rozdzial_pbn = property(get_rozdzial_pbn, set_rozdzial_pbn)
2✔
230

231
    def get_absolute_url(self):
2✔
232
        return reverse("admin:bpp_charakter_formalny_change", args=(self.pk,))
×
233

234

235
@receiver(post_migrate)
2✔
236
def rebuild_handler(sender, **kwargs):
2✔
237
    # Ponieważ przechodzimy z modelu bez-MPTT na model z-MPTT, wypełniamy
238
    # mu defaultowe wartości dla poziomu, parents, itp. Stąd też, po migracji
239
    # potrzebne jest przebudowanie obiektów, aby relacje rodzic-dziecko
240
    # realizowane byłyprawidłowo
241
    if sender.name == "bpp":
2✔
242
        Charakter_Formalny.objects.rebuild()
2✔
243

244

245
class Status_Korekty(ModelZNazwa):
2✔
246
    class Meta:
2✔
247
        verbose_name = "status korekty"
2✔
248
        verbose_name_plural = "statusy korekty"
2✔
249
        app_label = "bpp"
2✔
250

251

252
class Zrodlo_Informacji(ModelZNazwa):
2✔
253
    class Meta:
2✔
254
        verbose_name = "źródło informacji o bibliografii"
2✔
255
        verbose_name_plural = "źródła informacji o bibliografii"
2✔
256
        app_label = "bpp"
2✔
257

258

259
class Typ_Odpowiedzialnosci(NazwaISkrot):
2✔
260
    typ_ogolny = models.SmallIntegerField(
2✔
261
        "Ogólny typ odpowiedzialności",
262
        choices=[
263
            (const.TO_AUTOR, "autor"),
264
            (const.TO_REDAKTOR, "redaktor"),
265
            (const.TO_INNY, "inny"),
266
            (const.TO_TLUMACZ, "tłumacz"),
267
            (const.TO_KOMENTATOR, "komentator"),
268
            (const.TO_RECENZENT, "recenzent"),
269
            (const.TO_OPRACOWAL, "opracował"),
270
            (const.TO_REDAKTOR_TLUMACZENIA, "redaktor tłumaczenia"),
271
        ],
272
        default=const.TO_AUTOR,
273
        help_text="""Pole to jest używane celem rozróżniania typu odpowiedzialności
274
        na cele eksportu do PBN (autor i redaktor) oraz może być też wykorzystywane
275
        np. w raportach autorów i jednostek.
276
        """,
277
        db_index=True,
278
    )
279

280
    class Meta:
2✔
281
        verbose_name = "typ odpowiedzialności"
2✔
282
        verbose_name_plural = "typy odpowiedzialności"
2✔
283
        ordering = ["nazwa"]
2✔
284
        app_label = "bpp"
2✔
285

286
    def __str__(self):
2✔
UNCOV
287
        return self.nazwa
1✔
288

289

290
class Jezyk(NazwaISkrot):
2✔
291
    class SKROT_CROSSREF(models.TextChoices):
2✔
292
        en = "en", "en - angielski"
2✔
293
        es = "es", "es - hiszpański"
2✔
294

295
    skrot_crossref = models.CharField(
2✔
296
        max_length=10,
297
        verbose_name="Skrót nazwy języka wg API CrossRef",
298
        choices=SKROT_CROSSREF.choices,
299
        blank=True,
300
        null=True,
301
        unique=True,
302
    )
303

304
    pbn_uid = models.ForeignKey(
2✔
305
        "pbn_api.Language", null=True, blank=True, on_delete=models.SET_NULL
306
    )
307

308
    widoczny = models.BooleanField(default=True)
2✔
309

310
    class Meta:
2✔
311
        verbose_name = "język"
2✔
312
        verbose_name_plural = "języki"
2✔
313
        ordering = ["nazwa"]
2✔
314
        app_label = "bpp"
2✔
315

316
    def get_skrot_dla_pbn(self):
2✔
317
        if self.skrot_dla_pbn:
×
318
            return self.skrot_dla_pbn
×
319

320
        return self.skrot
×
321

322

323
class Typ_KBN(NazwaISkrot):
2✔
324
    artykul_pbn = models.BooleanField(
2✔
325
        "Artykuł w PBN",
326
        help_text="""Wydawnictwa ciągłe posiadające
327
    ten typ MNiSW/MEiN zostaną włączone do eksportu PBN jako artykuły""",
328
        default=False,
329
    )
330

331
    charakter_pbn = models.ForeignKey(
2✔
332
        Charakter_PBN,
333
        verbose_name="Charakter PBN",
334
        blank=True,
335
        null=True,
336
        default=None,
337
        help_text="""Wartość wybrana w tym polu zostanie użyta jako
338
        fallback, tzn. jeżeli dla charakteru formalnego danego rekordu nie
339
        określono odpowiedniego charakteru PBN, to zostanie użyta wartość
340
        tego pola, o ile wybrana. """,
341
        on_delete=CASCADE,
342
    )
343

344
    wliczaj_do_rankingu = models.BooleanField(default=True)
2✔
345

346
    class Meta:
2✔
347
        verbose_name = "typ MNiSW/MEiN"
2✔
348
        verbose_name_plural = "typy KBN"
2✔
349
        ordering = ["nazwa"]
2✔
350
        app_label = "bpp"
2✔
351

352

353
class Rodzaj_Prawa_Patentowego(ModelZNazwa):
2✔
354
    class Meta:
2✔
355
        verbose_name = "rodzaj prawa patentowego"
2✔
356
        verbose_name_plural = "rodzaje praw patentowych"
2✔
357
        ordering = [
2✔
358
            "nazwa",
359
        ]
360
        app_label = "bpp"
2✔
361

362

363
class Zewnetrzna_Baza_Danych(NazwaISkrot):
2✔
364
    class Meta:
2✔
365
        verbose_name = "zewnętrzna baza danych"
2✔
366
        verbose_name_plural = "zenwętrzne bazy danych"
2✔
367
        ordering = [
2✔
368
            "nazwa",
369
        ]
370
        app_label = "bpp"
2✔
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

© 2026 Coveralls, Inc