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

iplweb / bpp / d1a8e4c5-04c7-4d24-97e5-687f076b584c

21 Feb 2025 11:27PM UTC coverage: 46.137% (-2.1%) from 48.187%
d1a8e4c5-04c7-4d24-97e5-687f076b584c

push

circleci

mpasternak
Merge branch 'release/v202502.1158'

45 of 127 new or added lines in 15 files covered. (35.43%)

796 existing lines in 56 files now uncovered.

16384 of 35512 relevant lines covered (46.14%)

0.83 hits per line

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

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

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

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

18
from django.contrib.contenttypes.fields import GenericForeignKey
2✔
19
from django.contrib.contenttypes.models import ContentType
2✔
20

21
from django.utils import timezone
2✔
22

23
from django_bpp.settings.base import AUTH_USER_MODEL
2✔
24

25

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

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

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

43

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

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

51
    FINISHED_OKAY = 5
2✔
52
    FINISHED_ERROR = 6
2✔
53

54

55
class PBN_Export_Queue(models.Model):
2✔
56
    objects = PBN_Export_QueueManager()
2✔
57

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

62
    zamowil = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE)
2✔
63

64
    zamowiono = models.DateTimeField(auto_now_add=True, db_index=True)
2✔
65

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

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

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

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

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

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

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

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

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

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

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

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

127
        from bpp.admin.helpers import sprobuj_wgrac_do_pbn_celery
×
128

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

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

NEW
148
        except AccessDeniedException:
×
NEW
149
            return self.error(
×
150
                "Brak uprawnień, załączam traceback:\n" + traceback.format_exc()
151
            )
152
            SendStatus.FINISHED_ERROR
153

NEW
154
        except PKZeroExportDisabled:
×
UNCOV
155
            self.error(
×
156
                "Eksport prac bez punktów PK wyłączony w konfiguracji, nie wysłano."
157
            )
NEW
158
            return SendStatus.FINISHED_ERROR
×
159

NEW
160
        except ResourceLockedException as e:
×
NEW
161
            self.dopisz_komunikat(f"{e}, ponowiam wysyłkę za kilka minut...")
×
NEW
162
            self.save()
×
NEW
163
            return SendStatus.RETRY_LATER
×
164

NEW
165
        except Exception as e:
×
166
            capture_exception(e)
×
NEW
167
            return self.error(
×
168
                "Wystąpił nieobsługiwany błąd, załączam traceback:\n"
169
                + traceback.format_exc()
170
            )
171

172
        if sent_data is None:
×
NEW
173
            return self.error(
×
174
                "Wystąpił błąd, dane nie zostały wysłane, wyjaśnienie poniżej.\n\n"
175
                + "\n".join(notificator)
176
            )
177

178
        msg = (
×
179
            "Wysłano poprawnie. Link do wysłanego kodu JSON <a href="
180
            + reverse("admin:pbn_api_sentdata_change", args=[sent_data.pk])
181
            + ">tutaj</a>"
182
        )
183
        self.wysylke_zakonczono = timezone.now()
×
184
        self.dopisz_komunikat(msg)
×
185
        self.zakonczono_pomyslnie = True
×
186
        self.save()
×
187

NEW
188
        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