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

iplweb / bpp / fff5565f-f10d-4646-9e88-4f0c30e045b7

26 Feb 2025 11:46PM UTC coverage: 46.674% (+0.5%) from 46.137%
fff5565f-f10d-4646-9e88-4f0c30e045b7

push

circleci

mpasternak
Merge branch 'release/v202502.1159'

148 of 555 new or added lines in 35 files covered. (26.67%)

2309 existing lines in 130 files now uncovered.

16652 of 35677 relevant lines covered (46.67%)

1.19 hits per line

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

39.45
src/pbn_api/models/queue.py
1
import traceback
3✔
2
from enum import Enum
3✔
3

4
from django.db import models
3✔
5
from django.db.models import PositiveIntegerField
3✔
6
from django.urls import reverse
3✔
7
from sentry_sdk import capture_exception
3✔
8

9
from pbn_api.exceptions import (
3✔
10
    AccessDeniedException,
11
    AlreadyEnqueuedError,
12
    CharakterFormalnyNieobslugiwanyError,
13
    NeedsPBNAuthorisationException,
14
    PKZeroExportDisabled,
15
    PraceSerwisoweException,
16
    ResourceLockedException,
17
)
18

19
from django.contrib.contenttypes.fields import GenericForeignKey
3✔
20
from django.contrib.contenttypes.models import ContentType
3✔
21

22
from django.utils import timezone
3✔
23

24
from django_bpp.settings.base import AUTH_USER_MODEL
3✔
25

26

27
class PBN_Export_QueueManager(models.Manager):
3✔
28
    def filter_rekord_do_wysylki(self, rekord):
3✔
29
        return self.filter(
×
30
            content_type=ContentType.objects.get_for_model(rekord),
31
            object_id=rekord.pk,
32
            wysylke_zakonczono=None,
33
        )
34

35
    def sprobuj_utowrzyc_wpis(self, user, rekord):
3✔
36
        if self.filter_rekord_do_wysylki(rekord).exists():
×
37
            raise AlreadyEnqueuedError("ten rekord jest już w kolejce do wysyłki")
×
38

39
        return self.create(
×
40
            rekord_do_wysylki=rekord,
41
            zamowil=user,
42
        )
43

44

45
class SendStatus(Enum):
3✔
46
    RETRY_SOON = 0  # few seconds, 423 Locked
3✔
47
    RETRY_LATER = 1  # few minutes
3✔
48
    RETRY_MUCH_LATER = 2  # few hours, PraceSerwisoweExecption
3✔
49

50
    RETRY_AFTER_USER_AUTHORISED = 3  # when user logs in + authorizes
3✔
51

52
    FINISHED_OKAY = 5
3✔
53
    FINISHED_ERROR = 6
3✔
54

55

56
class PBN_Export_Queue(models.Model):
3✔
57
    objects = PBN_Export_QueueManager()
3✔
58

59
    object_id = PositiveIntegerField()
3✔
60
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
3✔
61
    rekord_do_wysylki = GenericForeignKey()
3✔
62

63
    zamowil = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE)
3✔
64

65
    zamowiono = models.DateTimeField(auto_now_add=True, db_index=True)
3✔
66

67
    wysylke_podjeto = models.DateTimeField(null=True, blank=True)
3✔
68
    wysylke_zakonczono = models.DateTimeField(null=True, blank=True, db_index=True)
3✔
69

70
    ilosc_prob = models.PositiveSmallIntegerField(default=0)
3✔
71
    zakonczono_pomyslnie = models.BooleanField(null=True, default=None, db_index=True)
3✔
72
    komunikat = models.TextField(null=True, blank=True)
3✔
73

74
    retry_after_user_authorised = models.BooleanField(
3✔
75
        null=True, default=None, db_index=True
76
    )
77

78
    class Meta:
3✔
79
        verbose_name = "Kolejka eksportu do PBN"
3✔
80
        verbose_name_plural = "Kolejka eksportu do PBN"
3✔
81
        ordering = ("-zamowiono", "zamowil")
3✔
82

83
    def __str__(self):
3✔
84
        return f"Zlecenie wysyłki do PBN dla {self.rekord_do_wysylki}"
×
85

86
    def check_if_record_still_exists(self):
3✔
87
        if self.rekord_do_wysylki is None:
×
88
            return False
×
89
        return True
×
90

91
    def dopisz_komunikat(self, msg):
3✔
92
        res = str(timezone.now())
×
93
        res += "\n" + "==============================================================="
×
94
        res += "\n" + msg + "\n"
×
95
        if self.komunikat:
×
96
            self.komunikat = "\n" + res + "\n" + self.komunikat
×
97
        else:
98
            self.komunikat = res
×
99

100
    def error(self, msg):
3✔
101
        self.wysylke_zakonczono = timezone.now()
×
102
        self.zakonczono_pomyslnie = False
×
103
        self.dopisz_komunikat(msg)
×
104
        self.save()
×
105
        return SendStatus.FINISHED_ERROR
×
106

107
    def send_to_pbn(self):
3✔
108
        """
109
        :return: (int : SendStatus,)
110
        """
111

112
        if not self.check_if_record_still_exists():
×
113
            if self.wysylke_zakonczono is not None:
×
114
                raise Exception(
×
115
                    "System próbuje ponownie wysyłać rekordy, których wysyłać nie powinien"
116
                )
117

118
            return self.error("Rekord został usunięty nim wysyłka była możliwa.")
×
119

120
        self.wysylke_podjeto = timezone.now()
×
121
        if self.retry_after_user_authorised:
×
122
            self.retry_after_user_authorised = (
×
123
                None  # Zresetuj wartosc tego pola, rekord wysyłany n-ty raz
124
            )
125
        self.ilosc_prob += 1
×
126
        self.save()
×
127

NEW
128
        from bpp.admin.helpers.pbn_api.cli import sprobuj_wyslac_do_pbn_celery
×
129

130
        try:
×
NEW
131
            sent_data, notificator = sprobuj_wyslac_do_pbn_celery(
×
132
                user=self.zamowil.get_pbn_user(),
133
                obj=self.rekord_do_wysylki,
134
                force_upload=True,
135
            )
136
        except PraceSerwisoweException:
×
137
            self.dopisz_komunikat("Prace serwisowe w PBN, spróbuję za kilka godzin")
×
138
            self.save()
×
139
            return SendStatus.RETRY_MUCH_LATER
×
140

141
        except NeedsPBNAuthorisationException:
×
142
            self.dopisz_komunikat(
×
143
                "Użytkownik bez autoryzacji w PBN, spróbuję po zalogowaniu do PBN."
144
            )
145
            self.retry_after_user_authorised = True
×
146
            self.save()
×
147
            return SendStatus.RETRY_AFTER_USER_AUTHORISED
×
148

NEW
149
        except CharakterFormalnyNieobslugiwanyError:
×
NEW
150
            self.error(
×
151
                "Charakter formalny tego rekordu nie jest ustawiony jako wysyłany do PBN. Zmień konfigurację "
152
                "bazy BPP, Redagowanie -> Dane systemowe -> Charaktery formalne"
153
            )
NEW
154
            return SendStatus.FINISHED_ERROR
×
155

156
        except AccessDeniedException:
×
157
            return self.error(
×
158
                "Brak uprawnień, załączam traceback:\n" + traceback.format_exc()
159
            )
160
            return SendStatus.FINISHED_ERROR
161

162
        except PKZeroExportDisabled:
×
163
            self.error(
×
164
                "Eksport prac bez punktów PK wyłączony w konfiguracji, nie wysłano."
165
            )
166
            return SendStatus.FINISHED_ERROR
×
167

168
        except ResourceLockedException as e:
×
169
            self.dopisz_komunikat(f"{e}, ponowiam wysyłkę za kilka minut...")
×
170
            self.save()
×
171
            return SendStatus.RETRY_LATER
×
172

173
        except Exception as e:
×
174
            capture_exception(e)
×
175
            return self.error(
×
176
                "Wystąpił nieobsługiwany błąd, załączam traceback:\n"
177
                + traceback.format_exc()
178
            )
179

180
        if sent_data is None:
×
181
            return self.error(
×
182
                "Wystąpił błąd, dane nie zostały wysłane, wyjaśnienie poniżej.\n\n"
183
                + "\n".join(notificator)
184
            )
185

186
        msg = (
×
187
            "Wysłano poprawnie. Link do wysłanego kodu JSON <a href="
188
            + reverse("admin:pbn_api_sentdata_change", args=[sent_data.pk])
189
            + ">tutaj</a>. "
190
        )
NEW
191
        extra_info = "\n".join(notificator)
×
192
        # Jeżeli notyfikator zawiera cokolwiek, a może zawierać np ostrzeżenia czy uwagi do
193
        # wysłanego rekordu to dołącz to
NEW
194
        if extra_info:
×
NEW
195
            msg += "\n\nDodatkowe informacje:\n" + extra_info
×
196

197
        self.wysylke_zakonczono = timezone.now()
×
198
        self.dopisz_komunikat(msg)
×
199
        self.zakonczono_pomyslnie = True
×
200
        self.save()
×
201

202
        return SendStatus.FINISHED_OKAY
×
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