educommon 3.8.0__py3-none-any.whl → 3.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,17 @@
1
+ import re
1
2
  from datetime import (
2
3
  datetime,
3
4
  )
5
+ from logging import (
6
+ WARNING,
7
+ )
4
8
  from typing import (
5
9
  TYPE_CHECKING,
6
10
  Any,
7
11
  Dict,
8
12
  List,
9
13
  Optional,
14
+ Union,
10
15
  )
11
16
 
12
17
  from celery.signals import (
@@ -49,6 +54,9 @@ from educommon.django.db.models import (
49
54
  from educommon.thread_data import (
50
55
  thread_data,
51
56
  )
57
+ from educommon.utils.misc import (
58
+ message_to_sentry,
59
+ )
52
60
 
53
61
 
54
62
  if TYPE_CHECKING:
@@ -186,8 +194,36 @@ class AuditLog(ReadOnlyMixin, BaseModel):
186
194
 
187
195
  return result
188
196
 
189
- def _transform_fields(self, fields: Dict[str, Optional[str]]) -> Dict[str, Any]:
197
+ def _convert_str_to_dict(self, fields: str) -> Dict[str, Any]:
198
+ """Преобразование строки из HStore в словарь."""
199
+ # Перезагружаем значения модели из базы данных
200
+ self.refresh_from_db()
201
+ try:
202
+ fields = dict(fields)
203
+ message = 'Удалось после refresh_from_db()'
204
+ except ValueError:
205
+ # Вручную создаем словарь из строки
206
+ pattern = r'"(\w+)"\s*=>\s*([^,]+)'
207
+ # Ищем совпадения в строке
208
+ matches = re.findall(pattern, fields)
209
+ # Создаем словарь из найденных пар ключ-значение
210
+ fields = {key: None if value == 'NULL' else value[1:-1] for key, value in matches}
211
+ message = 'Удалось вручную'
212
+
213
+ message_to_sentry(
214
+ message=f'{message} преобразовать в словарь поле HStore модели AuditLog',
215
+ extra={'fields': fields, 'id': self.id},
216
+ tag='transformed_fields',
217
+ level=WARNING,
218
+ )
219
+
220
+ return fields
221
+
222
+ def _transform_fields(self, fields: Union[Dict[str, Optional[str]], str]) -> Dict[str, Any]:
190
223
  """Преобразует значения полей лога в соответствии с типами полей модели."""
224
+ if isinstance(fields, str):
225
+ fields = self._convert_str_to_dict(fields)
226
+
191
227
  transformed_fields = dict(fields)
192
228
 
193
229
  model_fields = self.fields
@@ -932,12 +932,28 @@ class HouseValidator(RegexValidator):
932
932
  Эти дома относятся к "специальным" зданиям, хоз. помещениям на закрытых
933
933
  территориях (заводы, склады), гаражам и т.д.
934
934
  Если нужно будет, что бы они так же считались валидными,
935
- то регулярку нужно будет расширить до '^[0-9IVXа-яё/"_,.-]{1,20}$'
935
+ то регулярку нужно будет расширить до
936
+ '^(?=.{,20}$)([0-9IVXА-ЯЁа-яё"/_,.-]{1,} ?){1,}\b$'
936
937
  """
937
- regex = re.compile(r'^[0-9а-яё/"_,.-]{0,12}$', re.IGNORECASE | re.UNICODE)
938
+ regex = re.compile(
939
+ r'^(?=.{,12}$)([0-9а-яё"/_,.-]{1,} ?){1,}\b$',
940
+ re.IGNORECASE | re.UNICODE
941
+ )
938
942
  message = 'Неверно указан номер дома'
939
943
 
940
944
 
945
+ regex_house_validator = HouseValidator()
946
+
947
+
948
+ def house_validator(value):
949
+ value = str(value)
950
+
951
+ regex_house_validator(value)
952
+
953
+
954
+ is_house_number_valid = partial(validate_value, validator=house_validator)
955
+
956
+
941
957
  class BuildingValidator(RegexValidator):
942
958
  """Валидатор номера корпуса дома."""
943
959
  regex = re.compile(r'^[0-9а-яё/_.-]{0,10}$', re.IGNORECASE | re.UNICODE)
educommon/utils/misc.py CHANGED
@@ -1,10 +1,21 @@
1
1
  import hashlib
2
+ import logging
3
+
4
+ from django.conf import (
5
+ settings,
6
+ )
2
7
 
3
8
  from educommon import (
4
9
  Undefined,
5
10
  )
6
11
 
7
12
 
13
+ if getattr(settings, 'SENTRY_DSN', None):
14
+ from raven.contrib.django.raven_compat.models import (
15
+ client as sentry_client,
16
+ )
17
+
18
+
8
19
  class cached_property(property):
9
20
  """Кешируемое свойство.
10
21
 
@@ -112,3 +123,19 @@ def get_mime_type_for_extension(extension):
112
123
  if not extension.startswith('.'):
113
124
  extension = '.%s' % extension
114
125
  return mimetypes.types_map.get(extension.lower())
126
+
127
+
128
+ def message_to_sentry(message=None, extra=None, tag=None, level=logging.INFO):
129
+ """
130
+ Отправляет сообщение в Sentry с переданным типом, или "INFO" по-умолчанию.
131
+ В параметре extra можно передать словарь с дополнительной отладочной
132
+ информацией
133
+ В параметре tag можно отправить тег для последующего поиска в Sentry
134
+ """
135
+ if getattr(settings, 'SENTRY_DSN', None):
136
+ sentry_client.captureMessage(
137
+ message=message,
138
+ data={'level': level},
139
+ extra=extra,
140
+ tags={'tags': tag} if tag else None
141
+ )
educommon/version.conf CHANGED
@@ -4,8 +4,8 @@
4
4
  # нормальной установки обновлений.
5
5
 
6
6
  [version]
7
- BRANCH = tags/3.8.0
8
- VERSION = 3.8.0
9
- REVISION = 78b3e90e31a52e57ef6d034029295f0998db4e0d
10
- VERSION_DATE = 22.01.2024
11
- REVISION_DATE = 22.01.2024
7
+ BRANCH = tags/3.8.2^0
8
+ VERSION = 3.8.2
9
+ REVISION = d04e2e448a6c1650c844fb68c311f296f6944a61
10
+ VERSION_DATE = 06.02.2024
11
+ REVISION_DATE = 06.02.2024
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: educommon
3
- Version: 3.8.0
3
+ Version: 3.8.2
4
4
  Summary: Общая кодовая база для проектов БЦ Образование
5
5
  Home-page: https://stash.bars-open.ru/projects/EDUBASE/repos/educommon
6
6
  Author: BARS Group
@@ -1,6 +1,6 @@
1
1
  educommon/__init__.py,sha256=fvsBDL7g8HgOTd-JHOh7TSvMcnUauvGVgPuyA2Z9hUI,419
2
2
  educommon/thread_data.py,sha256=n0XtdesP9H92O3rJ8K6fVnJLiHqyJEfh2xpuT36wzxs,61
3
- educommon/version.conf,sha256=OTMAPgy6ioA-_MmRhBNoJFq3Gcyl5O7VJbBjIIiwzbY,448
3
+ educommon/version.conf,sha256=ILdztASJn7UgrupbMF5zFiUVtcTAs6m1s2iqLD883iA,450
4
4
  educommon/about/README.rst,sha256=U48UW5jv-8qHyaV56atzzkNMvzHKXVcWSb_NR06PnMo,2685
5
5
  educommon/about/__init__.py,sha256=H1W0IgW-qX9LCZ49GOJzHdmQGHhh-MA6U1xmNx7WnfM,132
6
6
  educommon/about/apps.py,sha256=GrpJAOE2sF0ukWsqugP_WJS88DO4aL-T3kTLprrJrcA,259
@@ -47,7 +47,7 @@ educommon/audit_log/apps.py,sha256=zHeBEoF8HVNc6YIIQTW-lpEMXjrywnB23uqxXIR9IKg,5
47
47
  educommon/audit_log/constants.py,sha256=96Gp-rYpt6poKAu8LbXY_0aApdOWYBy09235kAB0rSo,880
48
48
  educommon/audit_log/helpers.py,sha256=qJLV6yVgf3Z-Mgalc6kGfFvxk8h1L4bTO9fdSL36OPk,738
49
49
  educommon/audit_log/middleware.py,sha256=HkxBh-1RQJnhKqckkXaMbFjJ34WgZGJssbk04wiS3ts,1140
50
- educommon/audit_log/models.py,sha256=8oVyGy4LX1zac38x_AVQPdA4ya5aVOZEz2dGlMu5s-s,10174
50
+ educommon/audit_log/models.py,sha256=LYU-y9OgVFZ1bsH17DMfyfYv2LU1yKvIeGTVSz5HYjM,11599
51
51
  educommon/audit_log/permissions.py,sha256=VB040UAY4_KmqM4ioToHlVHQYSE7OP0qHEUn9bnWUSo,1241
52
52
  educommon/audit_log/proxies.py,sha256=r12ZVAPe8d78tZSnNsOypDnV-gQ4VFtw0l7DycksPhg,8562
53
53
  educommon/audit_log/routers.py,sha256=FF3KLvf6_WWFuZ9VRI8AZyKDfWp_lyd0i6bcVFfIehQ,204
@@ -159,7 +159,7 @@ educommon/django/db/partitioning/management/commands/apply_partitioning.py,sha25
159
159
  educommon/django/db/partitioning/management/commands/clear_table.py,sha256=Dt1u4Q35dz-W39sW1UYIQjdGyI7URJl6Z96qJOJYTbA,2235
160
160
  educommon/django/db/partitioning/management/commands/split_table.py,sha256=AfsBKWyW2yYYc05LGHdfULwW6GvaB6LXMBblSsxfg30,2082
161
161
  educommon/django/db/validators/__init__.py,sha256=Hyx-L4suVzUuCEb-HQB9g8LnaxKQp2ymv-DtaOW6qbw,1986
162
- educommon/django/db/validators/simple.py,sha256=my8K9FzbricSbSWbfZGwg8bFcvqmXcWaPOIXHQl8o3Q,38608
162
+ educommon/django/db/validators/simple.py,sha256=cwG-OLVPdD146A9dzLOaGyzZOoUWgQoFu9KDQ7_k8xI,38886
163
163
  educommon/django/storages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
164
  educommon/django/storages/atcfs/README.rst,sha256=yPy55jjKmSVL6Sg1LHzg_6wI7UAG4JDI6rjqaVxQfWs,2656
165
165
  educommon/django/storages/atcfs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -284,7 +284,7 @@ educommon/utils/caching.py,sha256=ux6ShlJJK3gh0C6XvpanbapXOI5uXUhDNgWQI7AsBBE,40
284
284
  educommon/utils/conversion.py,sha256=kEe15TwIH19RmC2mRl1JrrqD8mXgbCAPOYWnkIQXxqQ,1966
285
285
  educommon/utils/crypto.py,sha256=3uMk2CP53ZOsJ5Tcb0DLWxmk9ezINZQUsQcqF6j8XR0,2158
286
286
  educommon/utils/date.py,sha256=B0-rgaeM1LqjCBsINetjauZaOe0ATAcQUCZJTnLnNzo,16800
287
- educommon/utils/misc.py,sha256=HGSoCSyF6hAZaeFTTgA2IkIfMAXIuURqh-rzHVNe0LE,3352
287
+ educommon/utils/misc.py,sha256=8bCRlgOnm9QDlEIEri_nkeQc9xm9p8cae_wUk2ig1L0,4286
288
288
  educommon/utils/object_grid.py,sha256=mUJd0HJmj4PVljmkwxlR3mQO__YnlLBmAZcFWGxTHLc,9048
289
289
  educommon/utils/patches.py,sha256=Pio9V3bmDH79tTJnM5hi8rwhMEBtbpAg30zPTk5fuN0,1157
290
290
  educommon/utils/plugins.py,sha256=YAD3FM78ihPtyaB_olNM1CoSc5Q5icF_J3A0ivFBFmY,9469
@@ -341,8 +341,8 @@ educommon/ws_log/smev/exceptions.py,sha256=lmy7o2T3dJkqgIhG07qyh5yPqO3qZAYABuT4J
341
341
  educommon/ws_log/templates/report/smev_logs.xlsx,sha256=nnYgB0Z_ix8HoxsRICjsZfFRQBdra-5Gd8nWhCxTjYg,10439
342
342
  educommon/ws_log/templates/ui-js/smev-logs-list-window.js,sha256=AGup3D8GTJSY9WdDPj0zBJeYQBFOmGgcbxPOJbKK-nY,513
343
343
  educommon/ws_log/templates/ui-js/smev-logs-report-setting-window.js,sha256=nQ7QYK9frJcE7g7kIt6INg9TlEEJAPPayBJgRaoTePA,1103
344
- educommon-3.8.0.dist-info/METADATA,sha256=lpijvwxlV2qpNu5bSId3mA5qcCdUIsEMeodMi6_43eY,1450
345
- educommon-3.8.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
346
- educommon-3.8.0.dist-info/dependency_links.txt,sha256=RNlr4t-BxZRm7e_IfVo1ikr5ln-7viimzLHvQMO1C_Q,43
347
- educommon-3.8.0.dist-info/top_level.txt,sha256=z5fbW7bz_0V1foUm_FGcZ9_MTpW3N1dBN7-kEmMowl4,10
348
- educommon-3.8.0.dist-info/RECORD,,
344
+ educommon-3.8.2.dist-info/METADATA,sha256=Q9heCg3X0oaqx1nQDOt0ewJgnRPYU4fDyhQdtnB0uy4,1450
345
+ educommon-3.8.2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
346
+ educommon-3.8.2.dist-info/dependency_links.txt,sha256=RNlr4t-BxZRm7e_IfVo1ikr5ln-7viimzLHvQMO1C_Q,43
347
+ educommon-3.8.2.dist-info/top_level.txt,sha256=z5fbW7bz_0V1foUm_FGcZ9_MTpW3N1dBN7-kEmMowl4,10
348
+ educommon-3.8.2.dist-info/RECORD,,