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

iplweb / bpp / 58b9a630-8512-44e6-b730-daac96d1c4d7

29 Aug 2025 07:21AM UTC coverage: 47.493% (+2.5%) from 45.008%
58b9a630-8512-44e6-b730-daac96d1c4d7

push

circleci

mpasternak
Fix tests

6 of 27 new or added lines in 2 files covered. (22.22%)

1342 existing lines in 64 files now uncovered.

19323 of 40686 relevant lines covered (47.49%)

1.51 hits per line

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

76.63
src/crossref_bpp/core.py
1
from typing import Any, List, Union
4✔
2

3
from django.db import models
4✔
4
from queryset_sequence import QuerySetSequence
4✔
5

6
from crossref_bpp.utils import json_format_with_wrap, perform_trigram_search
4✔
7
from import_common.core import (
4✔
8
    matchuj_autora,
9
    matchuj_wydawce,
10
    normalize_zrodlo_nazwa_for_db_lookup,
11
    normalize_zrodlo_skrot_for_db_lookup,
12
    normalized_db_title,
13
    normalized_db_zrodlo_nazwa,
14
    normalized_db_zrodlo_skrot,
15
)
16
from import_common.normalization import (
4✔
17
    normalize_doi,
18
    normalize_first_name,
19
    normalize_isbn,
20
    normalize_issn,
21
    normalize_last_name,
22
    normalize_orcid,
23
    normalize_publisher,
24
)
25

26
from django.utils.datastructures import CaseInsensitiveMapping
4✔
27
from django.utils.functional import cached_property
4✔
28

29
from bpp.models import (
4✔
30
    Autor,
31
    Crossref_Mapper,
32
    Jezyk,
33
    Licencja_OpenAccess,
34
    Rekord,
35
    Wydawca,
36
    Wydawnictwo_Ciagle,
37
    Wydawnictwo_Zwarte,
38
    Zrodlo,
39
)
40

41

42
class StatusPorownania(models.TextChoices):
4✔
43
    DOKLADNE = "ok", "dokładne (identyczne dane po obu stronach)"
4✔
44
    LUZNE = "luzne", "luźne (może być nieprawidłowe)"
4✔
45
    WYMAGA_INGERENCJI = (
4✔
46
        "user",
47
        "wymaga ręcznego wybrania (dwa lub więcej dokładne wyniki)",
48
    )
49
    BRAK = "brak", "brak porównania"
4✔
50
    BLAD = "blad", "błąd porównania - pusty lub niepoprawny parametr wejściowy"
4✔
51

52

53
class WynikPorownania:
4✔
54
    def __init__(
4✔
55
        self,
56
        status: StatusPorownania,
57
        opis: str = "",
58
        rekordy: [
59
            Union[
60
                List[models.Model,],
61
                None,
62
            ]
63
        ] = None,
64
    ):
65
        self.status = status
4✔
66
        self.opis = opis
4✔
67
        self.rekordy = rekordy
4✔
68

69
    @cached_property
4✔
70
    def rekord_po_stronie_bpp(self):
4✔
71
        """Zwróć pierwszy rekord z self.rekordy jeżeli wynik porównania jest dokładny lub luźny"""
UNCOV
72
        ile_rekordow = 0
1✔
UNCOV
73
        if hasattr(
1✔
74
            self.rekordy,
75
            "exists",
76
        ):
UNCOV
77
            ile_rekordow = self.rekordy.count()
1✔
UNCOV
78
            pierwszy_rekord = self.rekordy.first()
1✔
UNCOV
79
        elif hasattr(self.rekordy, "__len__"):
1✔
80
            ile_rekordow = len(self.rekordy)
×
81
            pierwszy_rekord = self.rekordy[0]
×
82

UNCOV
83
        if (
1✔
84
            self.status in (StatusPorownania.DOKLADNE, StatusPorownania.LUZNE)
85
            and ile_rekordow == 1
86
        ):
UNCOV
87
            return pierwszy_rekord
1✔
88

89

90
NIEPRAWIDLOWY_FORMAT_DANYCH = WynikPorownania(
4✔
91
    StatusPorownania.BLAD, "nieprawidłowy format danych"
92
)
93
BRAK_DOPASOWANIA = WynikPorownania(StatusPorownania.BLAD, "brak dopasowania")
4✔
94

95

96
class Komparator:
4✔
97
    class atrybuty:
4✔
98
        do_porownania_rekordu = [
4✔
99
            "DOI",
100
            "alternative-id",
101
            "title",
102
        ]
103

104
        do_zmatchowania = do_porownania_rekordu + [
4✔
105
            "ISSN",
106
            "issn-type",
107
            "ISBN",
108
            "isbn-type",
109
            "publisher-location",
110
            "link",
111
            "short-container-title",
112
            "container-title",
113
            "type",
114
            "language",
115
            "license",
116
            "publisher",
117
            "URL",
118
            "resource",
119
            "author",
120
        ]
121

122
        do_skopiowania = [
4✔
123
            "abstract",
124
            "issue",
125
            "page",
126
            "subject",
127
            "volume",
128
            "edition-number",
129
        ]
130

131
        ignorowane = [
4✔
132
            "content-domain",
133
            "created",
134
            "deposited",
135
            "indexed",
136
            "is-referenced-by-count",
137
            "issued",
138
            "journal-issue",
139
            "member",
140
            "original-title",
141
            "published",
142
            "published-online",
143
            "reference",
144
            "reference-count",
145
            "references-count",
146
            "relation",
147
            "short-title",
148
            "source",
149
            "subtitle",
150
            "prefix",
151
            "score",
152
        ]
153

154
        wszystkie = do_skopiowania + do_zmatchowania + ignorowane
4✔
155

156
    @classmethod
4✔
157
    def porownaj(cls, atrybut: str, wartosc_z_crossref: Any):
4✔
UNCOV
158
        atrybut = atrybut.replace("-", "_")
1✔
UNCOV
159
        fn = getattr(cls, f"porownaj_{atrybut}", None)
1✔
UNCOV
160
        if fn is None:
1✔
161
            return WynikPorownania(
×
162
                StatusPorownania.BLAD,
163
                "brak funkcji w oprogramowaniu BPP do porównania tego atrybutu",
164
            )
UNCOV
165
        return fn(wartosc_z_crossref)
1✔
166

167
    @classmethod
4✔
168
    def znajdz(cls, *args, **kwargs):
4✔
UNCOV
169
        return Rekord.objects.filter(*args, **kwargs).order_by("-ostatnio_zmieniony")[
1✔
170
            :10
171
        ]
172

173
    @classmethod
4✔
174
    def znajdz_w_tabelach(cls, _wylacznie_zwarte=False, *args, **kwargs):
4✔
UNCOV
175
        qs1 = Wydawnictwo_Zwarte.objects.filter(*args, **kwargs).order_by(
1✔
176
            "-ostatnio_zmieniony"
177
        )
UNCOV
178
        if not _wylacznie_zwarte:
1✔
UNCOV
179
            qs2 = Wydawnictwo_Ciagle.objects.filter(*args, **kwargs).order_by(
1✔
180
                "-ostatnio_zmieniony"
181
            )
UNCOV
182
            ret = QuerySetSequence(qs1, qs2)
1✔
183
        else:
184
            ret = qs1
×
185

UNCOV
186
        return ret.order_by("-ostatnio_zmieniony")[:10]
1✔
187

188
    @classmethod
4✔
189
    def porownaj_DOI(cls, wartosc):
4✔
UNCOV
190
        doi = normalize_doi(wartosc)
1✔
191

UNCOV
192
        if not doi:
1✔
193
            return WynikPorownania(StatusPorownania.BLAD, "puste DOI")
×
194

UNCOV
195
        ile = cls.znajdz(doi__iexact=doi)
1✔
196

UNCOV
197
        if not ile.exists():
1✔
UNCOV
198
            return WynikPorownania(StatusPorownania.BRAK, "brak takiego DOI w bazie")
1✔
199

UNCOV
200
        if ile.count() == 1:
1✔
UNCOV
201
            return WynikPorownania(
1✔
202
                StatusPorownania.DOKLADNE,
203
                "w BPP jest dokładnie jeden taki rekord o takim DOI",
204
                rekordy=ile,
205
            )
206

207
        # wiecej, jak jeden rekord
208
        return WynikPorownania(
×
209
            StatusPorownania.WYMAGA_INGERENCJI,
210
            "więcej, nż jeden rekord w BPP o takim DOI",
211
            rekordy=ile,
212
        )
213

214
    porownaj_alternative_id = porownaj_DOI
4✔
215

216
    @classmethod
4✔
217
    def porownaj_ISSN(cls, wartosc):
4✔
UNCOV
218
        issn = normalize_issn(wartosc)
1✔
UNCOV
219
        if issn is None:
1✔
220
            return WynikPorownania(StatusPorownania.BLAD, "niepirawidłowy ISSN")
×
221

UNCOV
222
        for fld in "issn", "e_issn":
1✔
UNCOV
223
            kw = {f"{fld}__icontains": issn}
1✔
224

UNCOV
225
            ile = cls.znajdz_w_tabelach(**kw)
1✔
226

UNCOV
227
            if not ile.exists():
1✔
UNCOV
228
                continue
1✔
229

230
            if ile.count() == 1:
×
231
                return WynikPorownania(
×
232
                    StatusPorownania.DOKLADNE,
233
                    "w BPP jest dokładnie jeden taki rekord o takim ISSN lub E-ISSN",
234
                    rekordy=ile,
235
                )
236

237
            # wiecej, jak jeden rekord
238
            return WynikPorownania(
×
239
                StatusPorownania.WYMAGA_INGERENCJI,
240
                "więcej, nż jeden rekord w BPP o takim ISSN lub E-ISSN",
241
                rekordy=ile,
242
            )
243

UNCOV
244
        return WynikPorownania(
1✔
245
            StatusPorownania.BRAK, "brak rekordów o takim ISSN lub E-ISSN w BPP"
246
        )
247

248
    @classmethod
4✔
249
    def porownaj_ISBN(cls, wartosc):
4✔
250
        isbn = normalize_isbn(wartosc)
×
251
        if isbn is None:
×
252
            return WynikPorownania(StatusPorownania.BLAD, "niepirawidłowy ISBN")
×
253

254
        for fld in "isbn", "e_isbn":
×
255
            kw = {f"{fld}__icontains": isbn}
×
256

257
            ile = cls.znajdz_w_tabelach(_wylacznie_zwarte=True, **kw)
×
258

259
            if not ile.exists():
×
260
                continue
×
261

262
            if ile.count() == 1:
×
263
                return WynikPorownania(
×
264
                    StatusPorownania.DOKLADNE,
265
                    "w BPP jest dokładnie jeden taki rekord o takim ISBN lub E-ISBN",
266
                    rekordy=ile,
267
                )
268

269
            # wiecej, jak jeden rekord
270
            return WynikPorownania(
×
271
                StatusPorownania.WYMAGA_INGERENCJI,
272
                "więcej, nż jeden rekord w BPP o takim ISBN lub E-ISBN",
273
                rekordy=ile,
274
            )
275

276
        return WynikPorownania(
×
277
            StatusPorownania.BRAK, "brak rekordów o takim ISBN lub E-ISBN w BPP"
278
        )
279

280
    @classmethod
4✔
281
    def porownaj_issn_type(cls, wartosc):
4✔
UNCOV
282
        return cls.porownaj_ISSN(wartosc.get("value"))
1✔
283

284
    @classmethod
4✔
285
    def porownaj_isbn_type(cls, wartosc):
4✔
286
        return cls.porownaj_ISBN(wartosc.get("value"))
×
287

288
    @classmethod
4✔
289
    def porownaj_URL(cls, wartosc):
4✔
UNCOV
290
        if (
1✔
291
            wartosc is None
292
            or not isinstance(wartosc, str)
293
            or not wartosc
294
            or not wartosc.strip()
295
        ):
296
            return WynikPorownania(StatusPorownania.BLAD, "nieprawidłowy URL")
×
297

UNCOV
298
        if (
1✔
299
            wartosc.lower().find("dx.doi.org/") > -1
300
            or wartosc.lower().find("doi.org/") > -1
301
        ):
UNCOV
302
            return WynikPorownania(
1✔
303
                StatusPorownania.BLAD,
304
                "URL wyglada na zakodowany numer DOI, nie wykonuję porównania",
305
            )
306

UNCOV
307
        for fld in "www", "public_www":
1✔
UNCOV
308
            kw = {f"{fld}__icontains": wartosc}
1✔
309

UNCOV
310
            ile = cls.znajdz_w_tabelach(**kw)
1✔
311

UNCOV
312
            if not ile.exists():
1✔
UNCOV
313
                continue
1✔
314

315
            if ile.count() == 1:
×
316
                return WynikPorownania(
×
317
                    StatusPorownania.DOKLADNE,
318
                    "w BPP jest dokładnie jeden taki rekord o takim adresie WWW",
319
                    rekordy=ile,
320
                )
321

322
            # wiecej, jak jeden rekord
323
            return WynikPorownania(
×
324
                StatusPorownania.WYMAGA_INGERENCJI,
325
                "więcej, nż jeden rekord w BPP o takim adresie WWW",
326
                rekordy=ile,
327
            )
328

UNCOV
329
        return WynikPorownania(
1✔
330
            StatusPorownania.BRAK, "brak rekordów o takiej stronie WWW w BPP"
331
        )
332

333
    @classmethod
4✔
334
    def porownaj_link(cls, wartosc):
4✔
UNCOV
335
        return cls.porownaj_URL(wartosc.get("URL"))
1✔
336

337
    @classmethod
4✔
338
    def porownaj_resource(cls, wartosc):
4✔
UNCOV
339
        return cls.porownaj_link(wartosc.get("primary"))
1✔
340

341
    @classmethod
4✔
342
    def porownaj_author(cls, wartosc):
4✔
UNCOV
343
        if wartosc is None or not isinstance(wartosc, dict):
1✔
344
            return NIEPRAWIDLOWY_FORMAT_DANYCH
×
345

UNCOV
346
        wartosc = CaseInsensitiveMapping(wartosc)
1✔
347

UNCOV
348
        orcid = normalize_orcid(wartosc.get("orcid"))
1✔
UNCOV
349
        if orcid:
1✔
UNCOV
350
            ret = None
1✔
UNCOV
351
            try:
1✔
UNCOV
352
                ret = Autor.objects.get(orcid__iexact=orcid)
1✔
UNCOV
353
            except Autor.DoesNotExist:
1✔
UNCOV
354
                pass
1✔
UNCOV
355
            if ret:
1✔
356
                return WynikPorownania(
×
357
                    StatusPorownania.DOKLADNE, "dopasowanie po ORCID", rekordy=[ret]
358
                )
359

UNCOV
360
        nazwisko = normalize_last_name(wartosc.get("family"))
1✔
UNCOV
361
        imiona = normalize_first_name(wartosc.get("given"))
1✔
UNCOV
362
        if nazwisko and imiona:
1✔
UNCOV
363
            ret = matchuj_autora(imiona, nazwisko)
1✔
UNCOV
364
            if ret:
1✔
UNCOV
365
                return WynikPorownania(
1✔
366
                    StatusPorownania.LUZNE,
367
                    "znaleziono dokładnie jednego autora po imieniu i nazwisku",
368
                    rekordy=[
369
                        ret,
370
                    ],
371
                )
372

373
            # Brak jednego autora, ale moze jest wielu? Funkcja matchuj_autora nie zwraca
374
            # takich danych:
375

UNCOV
376
            q = Autor.objects.filter(
1✔
377
                nazwisko__icontains=nazwisko, imiona__icontains=imiona
378
            )
379

UNCOV
380
            if q.exists():
1✔
381
                addendum = ""
×
382
                MAX_AUT = 10
×
383
                if q.count() >= MAX_AUT:
×
384
                    addendum = (
×
385
                        f" - w sumie {q.count()} rekordow, pokazuje pierwsze {MAX_AUT}"
386
                    )
387

388
                msg = "kilku autorów - luźne porównanie po imieniu i nazwisku"
×
389
                status = StatusPorownania.WYMAGA_INGERENCJI
×
390
                if q.count() == 1:
×
391
                    msg = "jeden autor - luźne porównanie po imieniu i nazwisku"
×
392
                    status = StatusPorownania.LUZNE
×
393

394
                return WynikPorownania(
×
395
                    status,
396
                    f"{msg}{addendum}",
397
                    rekordy=q[:MAX_AUT],
398
                )
399

UNCOV
400
        return BRAK_DOPASOWANIA
1✔
401

402
    @classmethod
4✔
403
    def porownaj_short_container_title(cls, wartosc):
4✔
UNCOV
404
        poszukiwania = [wartosc]
1✔
UNCOV
405
        if wartosc.lower().startswith("the "):
1✔
406
            poszukiwania.append(wartosc[4:])
×
407

UNCOV
408
        for ciag in poszukiwania:
1✔
UNCOV
409
            tgrm = perform_trigram_search(
1✔
410
                Zrodlo.objects.exclude(skrot="").exclude(skrot=None),
411
                normalized_db_zrodlo_skrot,
412
                normalize_zrodlo_skrot_for_db_lookup(ciag),
413
            )
UNCOV
414
            if tgrm:
1✔
415
                return WynikPorownania(
×
416
                    StatusPorownania.LUZNE,
417
                    "luźne porównanie tytułu wg funkcji podobieństwa trygramów",
418
                    rekordy=tgrm,
419
                )
420

UNCOV
421
        return BRAK_DOPASOWANIA
1✔
422

423
    @classmethod
4✔
424
    def porownaj_container_title(cls, wartosc):
4✔
UNCOV
425
        poszukiwania = [wartosc]
1✔
UNCOV
426
        if wartosc.lower().startswith("the "):
1✔
427
            poszukiwania.append(wartosc[4:])
×
428

UNCOV
429
        for ciag in poszukiwania:
1✔
UNCOV
430
            tgrm = perform_trigram_search(
1✔
431
                Zrodlo.objects.exclude(nazwa="").exclude(nazwa=None),
432
                normalized_db_zrodlo_nazwa,
433
                normalize_zrodlo_nazwa_for_db_lookup(ciag),
434
            )
UNCOV
435
            if tgrm:
1✔
436
                return WynikPorownania(
×
437
                    StatusPorownania.LUZNE,
438
                    "luźne porównanie tytułu wg funkcji podobieństwa trygramów",
439
                    rekordy=tgrm,
440
                )
441

UNCOV
442
        return BRAK_DOPASOWANIA
1✔
443

444
    @classmethod
4✔
445
    def porownaj_publisher(cls, wartosc):
4✔
UNCOV
446
        wartosc = normalize_publisher(wartosc)
1✔
UNCOV
447
        if wartosc is None:
1✔
448
            return NIEPRAWIDLOWY_FORMAT_DANYCH
×
449

UNCOV
450
        wartosci = [
1✔
451
            wartosc,
452
        ]
UNCOV
453
        if wartosc.find("/") > -1:
1✔
UNCOV
454
            a, b = wartosc.split("/", 1)
1✔
UNCOV
455
            wartosci.append(a)
1✔
UNCOV
456
            wartosci.append(b)
1✔
457

UNCOV
458
        mozliwe_wartosci = set()
1✔
459

UNCOV
460
        for wartosc in wartosci:
1✔
UNCOV
461
            ret = matchuj_wydawce(wartosc, similarity=0.65)
1✔
462

UNCOV
463
            if ret is None:
1✔
UNCOV
464
                t = Wydawca.objects.filter(nazwa__istartswith=wartosc).filter()
1✔
UNCOV
465
                if t.count() == 1:
1✔
466
                    mozliwe_wartosci.add(t)
×
UNCOV
467
                continue
1✔
468

469
            return WynikPorownania(
×
470
                StatusPorownania.LUZNE,
471
                "luźne dopasowanie po nazwie",
472
                rekordy=[
473
                    ret,
474
                ],
475
            )
476

UNCOV
477
        if mozliwe_wartosci:
1✔
478
            if len(mozliwe_wartosci) == 1:
×
479
                return WynikPorownania(
×
480
                    StatusPorownania.LUZNE,
481
                    "luźne dopasowanie po początku nazwy",
482
                    rekordy=list(mozliwe_wartosci),
483
                )
484

485
            return WynikPorownania(
×
486
                StatusPorownania.WYMAGA_INGERENCJI,
487
                "ekstremalnie luźne dopasowanie po początku nazwy, pasuje do kilku wydawców",
488
                rekordy=list(mozliwe_wartosci),
489
            )
490

UNCOV
491
        if ret is None:
1✔
UNCOV
492
            return BRAK_DOPASOWANIA
1✔
493

494
    @classmethod
4✔
495
    def porownaj_title(cls, wartosc):
4✔
UNCOV
496
        ret = Rekord.objects.filter(tytul_oryginalny__istartswith=wartosc)
1✔
UNCOV
497
        if not ret.exists():
1✔
UNCOV
498
            last_chance = perform_trigram_search(
1✔
499
                Rekord.objects.all(), normalized_db_title, wartosc.lower().strip()
500
            )
UNCOV
501
            if last_chance:
1✔
502
                return WynikPorownania(
×
503
                    StatusPorownania.LUZNE,
504
                    "luźne porównanie tytułu wg funkcji podobieństwa trygramów",
505
                    rekordy=last_chance,
506
                )
507

UNCOV
508
            return BRAK_DOPASOWANIA
1✔
509

UNCOV
510
        count = ret.count()
1✔
511

UNCOV
512
        if count == 1:
1✔
UNCOV
513
            return WynikPorownania(
1✔
514
                StatusPorownania.LUZNE,
515
                "znaleziono 1 pracę z tytułem zaczynającym się podobnie",
516
                rekordy=list(ret),
517
            )
518

519
        w = "rekordów"
×
520
        if count <= 4:
×
521
            w = "rekordy"
×
522
        return WynikPorownania(
×
523
            StatusPorownania.WYMAGA_INGERENCJI,
524
            f"znaleziono {count} {w} z tytułem zaczynającym się podobnie",
525
            rekordy=list(ret),
526
        )
527

528
    @classmethod
4✔
529
    def porownaj_type(cls, wartosc):
4✔
UNCOV
530
        if wartosc not in Crossref_Mapper.CHARAKTER_CROSSREF.labels:
1✔
531
            return WynikPorownania(
×
532
                StatusPorownania.BLAD,
533
                f'w systemie BPP nie zdefiniowano wartosci dla typu charakteru crossref "{wartosc}",'
534
                f" prosimy o zgłoszenie tej sytuacji autorowi programu. ",
535
            )
536

UNCOV
537
        c = Crossref_Mapper.objects.get_or_create(
1✔
538
            charakter_crossref=getattr(
539
                Crossref_Mapper.CHARAKTER_CROSSREF,
540
                wartosc.upper().replace("-", "_"),
541
            )
542
        )[0]
543

UNCOV
544
        if c.charakter_formalny_bpp_id is not None:
1✔
545
            return WynikPorownania(
×
546
                StatusPorownania.DOKLADNE, "określony charakter formalny", rekordy=[c]
547
            )
548

UNCOV
549
        return WynikPorownania(
1✔
550
            StatusPorownania.BLAD,
551
            f'w systemie BPP nie zdefiniowano wartosci dla typu charakteru formalnego "{wartosc}",'
552
            f" wejdz w Dane Systemowe -> Crossref Mapper i wybierz typ charakteru formalnego "
553
            f"dla {wartosc} . ",
554
        )
555

556
    @classmethod
4✔
557
    def porownaj_license(cls, wartosc):
4✔
UNCOV
558
        if wartosc.get("URL"):
1✔
UNCOV
559
            url = wartosc.get("URL", "")
1✔
UNCOV
560
            try:
1✔
UNCOV
561
                skrot = "CC-" + (
1✔
562
                    url.split("creativecommons.org/licenses/")[1].split("/")[0].upper()
563
                )
564
            except (IndexError, TypeError, ValueError):
×
565
                return WynikPorownania(
×
566
                    StatusPorownania.BLAD,
567
                    f"system BPP nie umie dopasować rodzaju licencji dla {url}, proszę zgłosić"
568
                    f" ten fakt do autora oprogramowania. ",
569
                )
UNCOV
570
            try:
1✔
UNCOV
571
                licencja = Licencja_OpenAccess.objects.get(skrot=skrot)
1✔
UNCOV
572
            except Licencja_OpenAccess.DoesNotExist:
1✔
UNCOV
573
                return WynikPorownania(
1✔
574
                    StatusPorownania.BLAD,
575
                    f"w systemie BPP nie znaleziono licencji ze skrótem {skrot}, proszę o dopisanie",
576
                )
577

578
            return WynikPorownania(
×
579
                StatusPorownania.DOKLADNE,
580
                "okreslony rodzaj licencji",
581
                rekordy=[licencja],
582
            )
583

584
    @classmethod
4✔
585
    def porownaj_language(cls, wartosc):
4✔
586
        if wartosc not in Jezyk.SKROT_CROSSREF.values:
×
587
            return WynikPorownania(
×
588
                StatusPorownania.BLAD,
589
                f'w systemie BPP nie zdefiniowano wartosci dla typu jezyka "{wartosc}",'
590
                f" prosimy o zgłoszenie tej sytuacji autorowi programu. ",
591
            )
592

593
        try:
×
594
            c = Jezyk.objects.get(skrot_crossref=wartosc)
×
595
            return WynikPorownania(
×
596
                StatusPorownania.DOKLADNE, "określony jezyk", rekordy=[c]
597
            )
598
        except Jezyk.DoesNotExist:
×
599
            return WynikPorownania(
×
600
                StatusPorownania.BLAD,
601
                f'w systemie BPP nie zdefiniowano wartosci dla typu jezyka "{wartosc}",'
602
                f" wejdz w Dane Systemowe -> Języki i wybierz typ charakteru crossref "
603
                f"dla któregoś z języków. ",
604
            )
605

606
    @classmethod
4✔
607
    def utworz_dane_porownania(cls, json_data):
4✔
UNCOV
608
        dane_porownania = []
1✔
609

UNCOV
610
        def porownaj_jeden_parametr(atrybut, wartosc_z_crossref, atrybut_label=None):
1✔
UNCOV
611
            rezultat = Komparator.porownaj(atrybut, wartosc_z_crossref)
1✔
612

UNCOV
613
            if "ORCID" in wartosc_z_crossref:
1✔
UNCOV
614
                wartosc_z_crossref["ORCID"] = normalize_orcid(
1✔
615
                    wartosc_z_crossref["ORCID"]
616
                )
UNCOV
617
            dane_porownania.append(
1✔
618
                {
619
                    "atrybut": atrybut_label or atrybut,
620
                    "orig_atrybut": atrybut,
621
                    "wartosc_z_crossref_print": json_format_with_wrap(
622
                        wartosc_z_crossref
623
                    ),
624
                    "wartosc_z_crossref": wartosc_z_crossref,
625
                    "rezultat": rezultat,
626
                }
627
            )
628

UNCOV
629
        for atrybut in cls.atrybuty.do_zmatchowania:
1✔
UNCOV
630
            wartosc_z_crossref = json_data.get(atrybut)
1✔
631

UNCOV
632
            if wartosc_z_crossref is None or not wartosc_z_crossref:
1✔
UNCOV
633
                continue
1✔
634

UNCOV
635
            if isinstance(wartosc_z_crossref, (list, tuple)):
1✔
UNCOV
636
                if len(wartosc_z_crossref) == 0:
1✔
637
                    continue
×
638

UNCOV
639
                if len(wartosc_z_crossref) > 1:
1✔
UNCOV
640
                    for no, elem in enumerate(wartosc_z_crossref):
1✔
UNCOV
641
                        porownaj_jeden_parametr(
1✔
642
                            atrybut, elem, atrybut_label=f"{atrybut}.{no}"
643
                        )
644
                else:
UNCOV
645
                    porownaj_jeden_parametr(
1✔
646
                        atrybut,
647
                        wartosc_z_crossref[0],
648
                    )
649
            else:
UNCOV
650
                porownaj_jeden_parametr(atrybut, wartosc_z_crossref)
1✔
651

UNCOV
652
        return dane_porownania
1✔
653

654
    @classmethod
4✔
655
    def _dane(cls, json_data, atrybuty, key_in_atrybuty=True):
4✔
UNCOV
656
        return [
1✔
657
            (key, {"original": item, "print": json_format_with_wrap(item)})
658
            for key, item in sorted(json_data.items())
659
            if (key in atrybuty) == key_in_atrybuty
660
        ]
661

662
    @classmethod
4✔
663
    def dane_do_skopiowania(cls, json_data):
4✔
UNCOV
664
        return cls._dane(json_data, Komparator.atrybuty.do_skopiowania)
1✔
665

666
    @classmethod
4✔
667
    def dane_ignorowane(cls, json_data):
4✔
UNCOV
668
        return cls._dane(json_data, Komparator.atrybuty.ignorowane)
1✔
669

670
    @classmethod
4✔
671
    def dane_obce(cls, json_data):
4✔
UNCOV
672
        return cls._dane(
1✔
673
            json_data, Komparator.atrybuty.wszystkie, key_in_atrybuty=False
674
        )
675

676
    @classmethod
4✔
677
    def czy_rekord_ma_odpowiednik_w_bpp(cls, dane_porownania_dict):
4✔
UNCOV
678
        if dane_porownania_dict is None or not dane_porownania_dict:
1✔
679
            return
×
680

UNCOV
681
        for atrybut in Komparator.atrybuty.do_porownania_rekordu:
1✔
UNCOV
682
            wynik_porownania = dane_porownania_dict.get(atrybut)
1✔
683

UNCOV
684
            if wynik_porownania is None:
1✔
UNCOV
685
                continue
1✔
686

UNCOV
687
            if (
1✔
688
                wynik_porownania.get("rezultat")
689
                and wynik_porownania.get("rezultat").rekord_po_stronie_bpp
690
            ):
UNCOV
691
                return wynik_porownania.get("rezultat").rekord_po_stronie_bpp
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

© 2026 Coveralls, Inc