django-restit 4.2.66__py3-none-any.whl → 4.2.68__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.
account/models/group.py CHANGED
@@ -119,12 +119,16 @@ class Group(models.Model, RestModel, MetaDataModel):
119
119
  ("metadata__timezone", "timezone"),
120
120
  ("metadata__eod", "end_of_day"),
121
121
  ("parent__name", "parent"),
122
- ("metadata.location.line1", "address_line1"),
123
- ("metadata.location.line2", "address_line2"),
124
- ("metadata.location.city", "city"),
125
- ("metadata.location.state", "state"),
126
- ("metadata.location.country", "country"),
127
- ("metadata.location.zip", "zipcode")
122
+ ("location.line1", "address_line1"),
123
+ ("location.line2", "address_line2"),
124
+ ("location.city", "city"),
125
+ ("location.state", "state"),
126
+ ("location.county", "county"),
127
+ ("location.country", "country"),
128
+ ("location.postalcode", "zipcode"),
129
+ ("location.postalcode_suffix", "zipcode_ext"),
130
+ ("location.lat", "lat"),
131
+ ("location.lng", "lng")
128
132
  ]
129
133
  }
130
134
 
@@ -229,6 +233,7 @@ class Group(models.Model, RestModel, MetaDataModel):
229
233
  q = q | Q(group__parent=self)
230
234
  if great_grand_children:
231
235
  q = q | Q(group__parent__parent=self)
236
+ q = q | Q(group__parent__parent__parent=self)
232
237
  if hasattr(Model, "objects"):
233
238
  return Model.objects.filter(q)
234
239
  return Model.filter(q)
@@ -244,6 +249,7 @@ class Group(models.Model, RestModel, MetaDataModel):
244
249
  q = q | Q(parent__parent=self)
245
250
  if great_grand_children:
246
251
  q = q | Q(parent__parent__parent=self)
252
+ q = q | Q(group__parent__parent__parent=self)
247
253
  return Group.objects.filter(q)
248
254
 
249
255
  def getAllChildrenIds(self, include_me=False, grand_children=False, great_grand_children=False, depth=0):
account/models/member.py CHANGED
@@ -1223,17 +1223,18 @@ class AuthToken(models.Model, RestModel):
1223
1223
  signature = models.CharField(max_length=128, null=True, default=None, blank=True, db_index=True)
1224
1224
 
1225
1225
  def generateToken(self, commit=True):
1226
- self.token = str(uuid.uuid1())
1226
+ self.token = None
1227
1227
  self.updateSignature()
1228
1228
  if commit:
1229
1229
  self.save()
1230
1230
 
1231
1231
  def updateSignature(self):
1232
+ if not self.token:
1233
+ self.token = uuid.uuid4().hex
1232
1234
  self.signature = crypto.hashSHA256(self.token)
1233
1235
 
1234
1236
  def on_rest_pre_save(self, request, **kwargs):
1235
1237
  if not self.token:
1236
- self.token = uuid.uuid4().hex
1237
1238
  self.updateSignature()
1238
1239
  if not self.member_id:
1239
1240
  self.member = request.member
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-restit
3
- Version: 4.2.66
3
+ Version: 4.2.68
4
4
  Summary: A Rest Framework for DJANGO
5
5
  License: MIT
6
6
  Author: Ian Starnes
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.8
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
15
16
  Requires-Dist: boto3 (>=1.26.160,<2.0.0)
16
17
  Requires-Dist: django
17
18
  Requires-Dist: django-redis-cache (>=3.0.1,<4.0.0)
@@ -26,9 +26,9 @@ account/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
26
26
  account/models/__init__.py,sha256=cV_lMnT2vL_mjiYtT4hlcIHo52ocFbGSNVkOIHHLXZY,385
27
27
  account/models/device.py,sha256=MVWZEYrX_4zJaqmJS_feFplfVXYyqBJ-0_Fm3B1SVg8,5226
28
28
  account/models/feeds.py,sha256=vI7fG4ASY1M0Zjke24RdnfDcuWeATl_yR_25jPmT64g,2011
29
- account/models/group.py,sha256=my4KT71BlS64d-Ozz9n6d57nH429kFpVdJQZZTlMqhs,21723
29
+ account/models/group.py,sha256=fgWWYS69Ll5a1jH7syFQKkEGEU54cO-rn6HTbAvPbRY,21984
30
30
  account/models/legacy.py,sha256=zYdtv4LC0ooxPVqWM-uToPwV-lYWQLorSE6p6yn1xDw,2720
31
- account/models/member.py,sha256=uantXINX1lHcJPnQJ6nSddgxIvpvYgQtl0qKqWApzNc,50742
31
+ account/models/member.py,sha256=Pp4Np75L8TzVBC1N3g7Vnt5zy4cMBy7W0OG7mZ5Cfqg,50756
32
32
  account/models/membership.py,sha256=GJ6bSFLfU1CN9466k0XjSwn1sQIEwFeC8-oUYd2MrSs,9217
33
33
  account/models/notify.py,sha256=YnZujSHJHY7B09e6FIyZIEJRWLPYk1Sk1e92tFzB1IA,12078
34
34
  account/models/passkeys.py,sha256=TJxITUi4DT4_1tW2K7ZlOcRjJuMVl2NtKz7pKQU8-Tw,1516
@@ -387,7 +387,7 @@ rest/helpers.py,sha256=Af1EXjgf8JYMrP76rkgmB0SsEGES6iF9eam3jipcu48,28213
387
387
  rest/joke.py,sha256=0PpKaX2iN7jlS62kgjfmmqkFBYLPURz15aQ8R7OJkJ8,260
388
388
  rest/jwtoken.py,sha256=2BjRrnQSzm7ydHgYl6LIjfGW1YPmqjt-gDIo21O0WTk,2388
389
389
  rest/log.py,sha256=hd1_4HBOS395sfXJIL6BTw9yekm1SLgBwYx_PdfIhKA,20930
390
- rest/mail.py,sha256=O9x4ggr5pQjpjJP1zwV6sv5-2_JNTvU877GLih6ceBY,7737
390
+ rest/mail.py,sha256=Rm40hWDYop0tMqxdN-J2NT-dCnP-f4SfCZxSO02ajzs,7965
391
391
  rest/mailman.py,sha256=v5O1G5s3HiAKmz-J1z0uT6_q3xsONPpxVl9saEyQQ2I,9174
392
392
  rest/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
393
393
  rest/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -496,12 +496,12 @@ ws4redis/exceptions.py,sha256=EGLoRTdqJVwz900pwhciqPuSjBBd08hhLgFu6umHrI4,636
496
496
  ws4redis/redis.py,sha256=IfT4p3bUtlqso9rryNliH9Ebzlx8-Q2VJcs1kFioeGA,6093
497
497
  ws4redis/servers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
498
498
  ws4redis/servers/base.py,sha256=3nYZF5jSsQxNLbnLtKLFJ82xJs_Mc7N1H2kEOx8wT6o,3747
499
- ws4redis/servers/django.py,sha256=iNzWtGN4vZ-2ltClayCnPD-OPvB_ZGySnKD2EyXl6l8,4329
499
+ ws4redis/servers/django.py,sha256=EF8sHw4--hes7nbswT8M0R6PobtjEvPOb_M_tDrEoR0,5898
500
500
  ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,1723
501
501
  ws4redis/settings.py,sha256=K0yBiLUuY81iDM4Yr-k8hbvjn5VVHu5zQhmMK8Dtz0s,1536
502
502
  ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
503
503
  ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
504
- django_restit-4.2.66.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
505
- django_restit-4.2.66.dist-info/METADATA,sha256=5QzuN2gDiDACp64YSSsI-0uCKbE1VuJev0fw64U1vrQ,7594
506
- django_restit-4.2.66.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
507
- django_restit-4.2.66.dist-info/RECORD,,
504
+ django_restit-4.2.68.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
505
+ django_restit-4.2.68.dist-info/METADATA,sha256=E9U9owcQp_3cq2b5YoLRfJDJji83qeVzc70nOCFUvbo,7645
506
+ django_restit-4.2.68.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
507
+ django_restit-4.2.68.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.6.1
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
rest/mail.py CHANGED
@@ -15,6 +15,11 @@ try:
15
15
  except Exception:
16
16
  inline_css = None
17
17
 
18
+ try:
19
+ from premailer import transform as premailer
20
+ except Exception:
21
+ premailer = None
22
+
18
23
  from django.template.loader import render_to_string
19
24
  from django.template import TemplateDoesNotExist
20
25
 
@@ -75,7 +80,9 @@ def renderBody(body, template=None, context=None):
75
80
  if template[-4:] not in ["html", ".txt"]:
76
81
  template += ".html"
77
82
  body = render_to_string(template, context)
78
- if inline_css:
83
+ if premailer:
84
+ body = premailer(body)
85
+ elif inline_css:
79
86
  body = inline_css(body)
80
87
  return body
81
88
 
@@ -203,7 +210,9 @@ def render_to_mail(name, context):
203
210
 
204
211
  try:
205
212
  html_content = render_to_string(name + ".html", context)
206
- if inline_css:
213
+ if premailer:
214
+ html_content = premailer(html_content)
215
+ elif inline_css:
207
216
  html_content = inline_css(html_content)
208
217
  except TemplateDoesNotExist:
209
218
  html_content = None
@@ -4,6 +4,7 @@ import base64
4
4
  import select
5
5
  from hashlib import sha1
6
6
  from wsgiref import util
7
+ from django.core.handlers import wsgi as django_wsgi
7
8
  from django.core.wsgi import get_wsgi_application
8
9
  from django.core.servers.basehttp import WSGIServer, WSGIRequestHandler, ServerHandler
9
10
 
@@ -14,12 +15,61 @@ from django.utils.encoding import force_str
14
15
  from ws4redis.websocket import WebSocket
15
16
  from ws4redis.servers.base import WebsocketServerBase, HandshakeError, UpgradeRequiredError
16
17
 
18
+ from io import IOBase
19
+
20
+
17
21
  from rest.log import getLogger
18
22
  logger = getLogger("async", filename="async.log")
19
23
 
20
24
  util._hoppish = {}.__contains__
21
25
 
22
26
 
27
+ class LimitedStreamPatched(IOBase):
28
+ """
29
+ Wrap another stream to disallow reading it past a number of bytes.
30
+
31
+ Based on the implementation from werkzeug.wsgi.LimitedStream
32
+ See https://github.com/pallets/werkzeug/blob/dbf78f67/src/werkzeug/wsgi.py#L828
33
+ """
34
+
35
+ def __init__(self, stream, limit):
36
+ self.stream = stream
37
+ self._read = stream.read
38
+ self._readline = stream.readline
39
+ self._pos = 0
40
+ self.limit = limit
41
+
42
+ def read(self, size=-1, /):
43
+ _pos = self._pos
44
+ limit = self.limit
45
+ if _pos >= limit:
46
+ return b""
47
+ if size == -1 or size is None:
48
+ size = limit - _pos
49
+ else:
50
+ size = min(size, limit - _pos)
51
+ data = self._read(size)
52
+ self._pos += len(data)
53
+ return data
54
+
55
+ def readline(self, size=-1, /):
56
+ _pos = self._pos
57
+ limit = self.limit
58
+ if _pos >= limit:
59
+ return b""
60
+ if size == -1 or size is None:
61
+ size = limit - _pos
62
+ else:
63
+ size = min(size, limit - _pos)
64
+ line = self._readline(size)
65
+ self._pos += len(line)
66
+ return line
67
+
68
+
69
+ def patchLimitedStream():
70
+ django_wsgi.LimitedStream = LimitedStreamPatched
71
+
72
+
23
73
  class WSGIRequestHandlerRunServer(WSGIRequestHandler):
24
74
  def handle(self):
25
75
  self.raw_requestline = self.rfile.readline(65537)
@@ -81,13 +131,17 @@ class WebsocketRunServer(WebsocketServerBase):
81
131
  logger.debug('WebSocket request accepted, switching protocols')
82
132
  start_response(force_str('101 Switching Protocols'), headers)
83
133
  six.get_method_self(start_response).finish_content()
84
- return WebSocket(environ['wsgi.input'].stream)
134
+ winput = environ['wsgi.input']
135
+ if not hasattr(winput, "stream"):
136
+ # hack to get the stream back in later DJANGO
137
+ winput.stream = winput._read.__self__
138
+ return WebSocket(winput.stream)
85
139
 
86
140
  def select(self, rlist, wlist, xlist, timeout=None):
87
141
  return select.select(rlist, wlist, xlist, timeout)
88
142
 
89
143
 
90
- def run(addr, port, wsgi_handler, ipv6=False, threading=False, server_cls=None):
144
+ def run(addr, port, wsgi_handler, ipv6=False, threading=False, server_cls=None, **kwargs):
91
145
  """
92
146
  Function to monkey patch the internal Django command: manage.py runserver
93
147
  """
@@ -101,6 +155,8 @@ def run(addr, port, wsgi_handler, ipv6=False, threading=False, server_cls=None):
101
155
  httpd.serve_forever()
102
156
 
103
157
 
158
+ patchLimitedStream()
159
+
104
160
  runserver.run = run
105
161
 
106
162
  _django_app = get_wsgi_application()
@@ -110,6 +166,7 @@ _websocket_url = getattr(settings, 'WEBSOCKET_URL')
110
166
 
111
167
  def application(environ, start_response):
112
168
  if _websocket_url and environ.get('PATH_INFO').startswith(_websocket_url):
169
+ logger.info("environ", environ)
113
170
  return _websocket_app(environ, start_response)
114
171
  return _django_app(environ, start_response)
115
172