django-restit 4.2.136__py3-none-any.whl → 4.2.138__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-restit
3
- Version: 4.2.136
3
+ Version: 4.2.138
4
4
  Summary: A Rest Framework for DJANGO
5
5
  License: MIT
6
6
  Author: Ian Starnes
@@ -366,25 +366,25 @@ pushit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
366
366
  pushit/admin.py,sha256=69HdDZU_Iz8Fm72M8r8FUztsZvW37zdGwVmj8VTqr0c,451
367
367
  pushit/migrations/0001_initial.py,sha256=kYF1ksOlKf9ElrlagGhpNf5GbKEq6SORWGreMH9A7as,4555
368
368
  pushit/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
369
- pushit/models.py,sha256=dbUJgD9W1y_2H5NxMUQhjsucvLkruErRMXkUSbza3ck,5066
369
+ pushit/models.py,sha256=fkJdNqj8dC2Y8mbri4keOEVfrZZeq3-IUrvJdxY7ve0,4615
370
370
  pushit/rpc/__init__.py,sha256=13ibfbWNdjoNxzCzF8QxasSzFgs8IZJPc05XhErOBCw,88
371
371
  pushit/rpc/githooks.py,sha256=hjL1x0qN_YB4QZfwrOAVg-biEFRreKp8LK4FaLUBHyw,1756
372
372
  pushit/rpc/legacy.py,sha256=9xsZH1S70htIb0bwKENfhTe-uHvyqSTiPiwYTlLWS3E,5028
373
- pushit/rpc/products.py,sha256=JFNN0VYsZQ9VJ5RZ3vD0m2hhsXEIB5Koz66inlMzx6Y,378
373
+ pushit/rpc/products.py,sha256=n9IAbKbmURrXMQcQji9cP5Wpp8kAqsjwzK9XvKAxu6E,738
374
374
  pushit/static/js/models_pushit.js,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
375
375
  pushit/tq.py,sha256=uD0g1Jj1n5IAlbnNOa_YORfQHEXMW30eYpei35lH3so,424
376
376
  pushit/utils.py,sha256=IeTCGa-164nmB1jIsK1lu1O1QzUhS3BKfuXHGjCW-ck,2121
377
377
  rest/.gitignore,sha256=TbEvWRMnAiajCTOdhiNrd9eeCAaIjRp9PRjE_VkMM5g,118
378
378
  rest/README.md,sha256=V3ETc-cJu8PZIbKr9xSe_pA4JEUpC8Dhw4bQeVCDJPw,5460
379
379
  rest/RemoteEvents.py,sha256=nL46U7AuxIrlw2JunphR1tsXyqi-ep_gD9CYGpYbNgE,72
380
- rest/__init__.py,sha256=P7AsJG2-fQOZPMovCvkbEW57dyHqLdU0F4_ptZlHISg,122
380
+ rest/__init__.py,sha256=JUtEuNqc7n7slOQOEm9TZVqe9zNOKgxUmepHVFPIeJc,122
381
381
  rest/arc4.py,sha256=y644IbF1ec--e4cUJ3KEYsewTCITK0gmlwa5mJruFC0,1967
382
382
  rest/cache.py,sha256=1Qg0rkaCJCaVP0-l5hZg2CIblTdeBSlj_0fP6vlKUpU,83
383
383
  rest/crypto/__init__.py,sha256=Tl0U11rgj1eBYqd6OXJ2_XSdNLumW_JkBZnaJqI6Ldw,72
384
384
  rest/crypto/aes.py,sha256=NOVRBRSHCV-om68YpGySWWG-4kako3iEVjq8hxZWPUU,4372
385
385
  rest/crypto/privpub.py,sha256=_FioylVcbMmDP80yPYjURmafEiDmEAMkskbc7WF10ac,4082
386
386
  rest/crypto/util.py,sha256=agFN2OCPHC70tHNGWrMkkZX4Tt_Ty6imoKEMdTkZpKA,4514
387
- rest/datem.py,sha256=hX6bTbl5mQSg0x2hDK5P1TynkZFUfVTDwYkTuFObgbw,12626
387
+ rest/datem.py,sha256=qbkgDpTVbxpnS4hRm_GnyRo9Gk7nRJbH-tJqxm172mo,13152
388
388
  rest/decorators.py,sha256=AuB4agpog587CUsF8HkAZiHDfs_pueb2rdxXZD7dUUE,15327
389
389
  rest/encryption.py,sha256=x6Kiez0tVqfxK26MSsRL3k8OS05ni1gEX2aj3I0S9V0,788
390
390
  rest/errors.py,sha256=uKwG9OkLme36etabqK54DMjMQc1fgEoUIAUxXa7WFQw,612
@@ -410,7 +410,7 @@ rest/middleware/request.py,sha256=JchRNy5L-bGd-7h-KFYekGRvREe2eCkZXKOYqIkP2hI,41
410
410
  rest/middleware/session.py,sha256=zHSoQpIzRLmpqr_JvW406wzpvU3W3gDbm5JhtzLAMlE,10240
411
411
  rest/middleware/session_store.py,sha256=1nSdeXK8PyuYgGgIufqrS6j6QpIrQ7zbMNT0ol75e6U,1901
412
412
  rest/models/__init__.py,sha256=M8pvFDq-WCF-QcM58X7pMufYYe0aaQ3U0PwGe9TKbbY,130
413
- rest/models/base.py,sha256=asj1ehoq_LLcm99PbyICGG9I_GQikxilrc52tTs2YBY,71301
413
+ rest/models/base.py,sha256=soIYiW71wZdUPmYf-JPPcnHx79CrA9B-hGNFt_WlRCI,71609
414
414
  rest/models/cacher.py,sha256=eKz8TINVhWEqKhJGMsRkKZTtBUIv5rN3NHbZwOC56Uk,578
415
415
  rest/models/metadata.py,sha256=1nQ7CYo9bJHoaXE_hVNaj1-Y7yqhHlf2ZlaD1IfTzic,12904
416
416
  rest/net.py,sha256=LcB2QV6VNRtsSdmiQvYZgwQUDwOPMn_VBdRiZ6OpI-I,2974
@@ -459,7 +459,7 @@ taskqueue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
459
459
  taskqueue/admin.py,sha256=E6zXoToS_ea3MdoGjZzF1JiepWFtDSoZUQdan8H-pXI,208
460
460
  taskqueue/migrations/0001_initial.py,sha256=JwYib8CK5ftSXlfxKZUcKEEVsXktNB5q3h-2tu9inGk,4738
461
461
  taskqueue/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
462
- taskqueue/models.py,sha256=RsBC2YcG058D_LVq5fCgiqIaFqi5yDh9LAwI6Pe2V3A,23719
462
+ taskqueue/models.py,sha256=Q4kAo-1pELdBpS5IkSLiDLJ5-hu4Qa0GG0ERoW0XLg4,23855
463
463
  taskqueue/periodic.py,sha256=hpXnunJL_cuVQLAKpjTbABbsQ4fvdsV9_gyyK-_53Sk,3844
464
464
  taskqueue/rpc.py,sha256=Lf5VUoqCRkfWUAIvx_s508mjAtDPwpiWyxg0ryqWbQA,5793
465
465
  taskqueue/tq.py,sha256=PzSoDrawYcqZylruEgsK95gcJ4J_VhdM6rxg9V6_X8E,942
@@ -503,17 +503,17 @@ wiki/tq.py,sha256=wvuBZ3OMV_D2o4kpJhVLIOwpEUfwlglqLJQvpncAwtk,313
503
503
  ws4redis/README.md,sha256=QvwdsauPKxx4qQqnJ991xeU8DgFQCj3CeQt-nCE4s-w,3624
504
504
  ws4redis/__init__.py,sha256=teNfv83A_ke1CBt9BB7NsnWCcFBhnUFPsPESjF554_k,46
505
505
  ws4redis/client.py,sha256=kElPtVMVObLUXAfu32v_PHd0HyygrW-ukk37_Tuo7ZM,7062
506
- ws4redis/connection.py,sha256=QGjzalYrx1y4o6sb6P1akL-Y2fjf2qil0JCo-ona5F8,13431
506
+ ws4redis/connection.py,sha256=rlzdmgyjmuqETxjNf3uZU3tfoBeQQTzD4ZFru_u3JAs,13738
507
507
  ws4redis/exceptions.py,sha256=EGLoRTdqJVwz900pwhciqPuSjBBd08hhLgFu6umHrI4,636
508
508
  ws4redis/redis.py,sha256=IfT4p3bUtlqso9rryNliH9Ebzlx8-Q2VJcs1kFioeGA,6093
509
509
  ws4redis/servers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
510
510
  ws4redis/servers/base.py,sha256=3nYZF5jSsQxNLbnLtKLFJ82xJs_Mc7N1H2kEOx8wT6o,3747
511
- ws4redis/servers/django.py,sha256=EF8sHw4--hes7nbswT8M0R6PobtjEvPOb_M_tDrEoR0,5898
511
+ ws4redis/servers/django.py,sha256=cKOE4U0cE8I3_rDaLgv-KuDb376RASdOzUn7MlDA4As,5900
512
512
  ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,1723
513
- ws4redis/settings.py,sha256=K0yBiLUuY81iDM4Yr-k8hbvjn5VVHu5zQhmMK8Dtz0s,1536
513
+ ws4redis/settings.py,sha256=KKq00EwoGnz1yLwCZr5Dfoq2izivmAdsNEEM4EhZwN4,1610
514
514
  ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
515
515
  ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
516
- django_restit-4.2.136.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
517
- django_restit-4.2.136.dist-info/METADATA,sha256=0XTqwV9RSBBDL7jfrwHLJoRI-Rr122bpMowDHQbuLCA,7663
518
- django_restit-4.2.136.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
519
- django_restit-4.2.136.dist-info/RECORD,,
516
+ django_restit-4.2.138.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
517
+ django_restit-4.2.138.dist-info/METADATA,sha256=f8SLDPTRNX35L0cWaSmKyOK6ccRD2-Ex2itkf00QD20,7663
518
+ django_restit-4.2.138.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
519
+ django_restit-4.2.138.dist-info/RECORD,,
pushit/models.py CHANGED
@@ -12,6 +12,7 @@ from rest.middleware import get_request
12
12
  from rest import RemoteEvents
13
13
  from rest.models import RestModel, MetaDataModel, MetaDataBase
14
14
 
15
+
15
16
  class Product(models.Model, RestModel, MetaDataModel):
16
17
  class RestMeta:
17
18
  GRAPHS = {
@@ -27,7 +28,6 @@ class Product(models.Model, RestModel, MetaDataModel):
27
28
  "current":"default",
28
29
  "beta":"default",
29
30
  },
30
- "recurse_into":[("getReleases", "versions")],
31
31
  "exclude":["library"]
32
32
  }
33
33
  }
@@ -73,6 +73,7 @@ class Product(models.Model, RestModel, MetaDataModel):
73
73
  class ProductMetaData(MetaDataBase):
74
74
  parent = models.ForeignKey(Product, related_name="properties", on_delete=models.CASCADE)
75
75
 
76
+
76
77
  class Release(models.Model, RestModel, MetaDataModel):
77
78
  class RestMeta:
78
79
  GRAPHS = {
@@ -84,11 +85,9 @@ class Release(models.Model, RestModel, MetaDataModel):
84
85
 
85
86
  POST_SAVE_FIELDS = ["media"]
86
87
 
87
-
88
88
  created = models.DateTimeField(auto_now_add=True, editable=False)
89
89
  modified = models.DateTimeField(auto_now=True)
90
90
  owner = models.ForeignKey(Member, related_name="+", on_delete=models.CASCADE)
91
-
92
91
  product = models.ForeignKey(Product, related_name="releases", on_delete=models.CASCADE)
93
92
 
94
93
  notes = models.TextField(blank=True, null=True, default=None)
@@ -97,6 +96,14 @@ class Release(models.Model, RestModel, MetaDataModel):
97
96
 
98
97
  media = models.ForeignKey(MediaItem, on_delete=models.PROTECT, blank=True, null=True, default=None)
99
98
 
99
+ def set_product(self, value):
100
+ if isinstance(value, str):
101
+ self.product = Product.objects.filter(oid=value).last()
102
+ elif isinstance(value, int):
103
+ self.product = Product.objects.filter(pk=value).last()
104
+ else:
105
+ self.product = value
106
+
100
107
  def makeCurrent(self):
101
108
  self.product.current = self
102
109
  self.product.save()
@@ -110,36 +117,14 @@ class Release(models.Model, RestModel, MetaDataModel):
110
117
  return self.media.url()
111
118
  return None
112
119
 
113
- def set_media(self, value, commit=False):
114
- if value is None:
115
- return
116
-
117
- if value.startswith("http"):
118
- media = MediaItem.CreateFromURL(value, self.owner, library=self.product.getLibrary(), kind=None)
119
- self.media = media
120
- if commit:
121
- self.save()
122
- return media
123
-
124
- request = get_request()
125
- name = request.DATA.get("media_name", "test.txt")
126
- kind = MediaItem.guessMediaKind(value)
127
- media = MediaItem(library=self.product.getLibrary(), name=name, owner=self.product.owner, kind=kind, base64_data=value)
128
- media.save()
129
- self.media = media
130
-
131
- # upload__ called for files
132
- def upload__media(self, value, name):
133
- if value is None:
134
- return
135
-
136
- kind = MediaItem.guessMediaKind(value)
137
- media = MediaItem(library=self.product.getLibrary(), name=name, owner=self.product.owner, kind=kind, newfile=value)
138
- media.save()
139
- self.media = media
140
-
141
- def __unicode__(self):
142
- return "{0} - {1}".format(self.product.name, self.version_str)
143
-
144
-
145
-
120
+ def on_rest_pre_save(self, request, **kwargs):
121
+ self.owner = self.product.owner
122
+ if self.version_num == 1:
123
+ lr = Release.objects.filter(product=self.product).last()
124
+ if lr is not None:
125
+ self.version_num = lr.version_num + 1
126
+
127
+ def on_rest_saved(self, request, is_new=False):
128
+ if is_new:
129
+ self.product.current = self
130
+ self.product.save()
pushit/rpc/products.py CHANGED
@@ -4,8 +4,16 @@ from pushit.models import Product, Release
4
4
 
5
5
 
6
6
  @rd.url('product')
7
- @rd.url('product/<int:pk>')
7
+ @rd.url('product/<str:pk>')
8
8
  def rest_on_product(request, pk=None):
9
+ if pk is not None:
10
+ if isinstance(pk, str) and not pk.isdigit():
11
+ obj = Product.objects.filter(oid=pk).last()
12
+ if obj is not None:
13
+ if request.method == "GET":
14
+ return obj.on_rest_get(request)
15
+ elif request.method == "POST":
16
+ return obj.on_rest_post(request)
9
17
  return Product.on_rest_request(request, pk)
10
18
 
11
19
 
rest/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .uberdict import UberDict # noqa: F401
2
2
  from .settings_helper import settings # noqa: F401
3
3
 
4
- __version__ = "4.2.136"
4
+ __version__ = "4.2.138"
rest/datem.py CHANGED
@@ -394,3 +394,18 @@ def convert_to_epoch_range(start, end=None):
394
394
  raise ValueError("Start parameter must be an int, datetime object, or a string representing a timedelta.")
395
395
 
396
396
  return start_epoch, end_epoch
397
+
398
+
399
+ def updateTimeFromString(dt, time_string):
400
+ # Check if the time_string is in "hour" format (e.g., "13") or
401
+ # "hour:minute" format (e.g., "1:32")
402
+ if ':' in time_string:
403
+ # Parse hour and minute
404
+ hour, minute = map(int, time_string.split(':'))
405
+ else:
406
+ # Only hour is provided
407
+ hour = int(time_string)
408
+ minute = 0
409
+ # Update the datetime object with the new hour and minute
410
+ updated_dt = dt.replace(hour=hour, minute=minute, second=0, microsecond=0)
411
+ return updated_dt
rest/models/base.py CHANGED
@@ -1021,6 +1021,12 @@ class RestModel(object):
1021
1021
  if dr_offset > 0:
1022
1022
  dr_start = dr_start + timedelta(minutes=dr_offset)
1023
1023
  dr_end = dr_end + timedelta(minutes=dr_offset)
1024
+ tr_start = request.DATA.get("tr_start")
1025
+ if tr_start is not None:
1026
+ tr_start = rh.updateTimeFromString(dr_start, tr_start)
1027
+ tr_end = request.DATA.get("tr_end")
1028
+ if tr_end is not None:
1029
+ tr_end = rh.updateTimeFromString(dr_end, tr_end)
1024
1030
  dr_field = request.DATA.get("dr_field", getattr(cls.RestMeta, "DATE_RANGE_FIELD", "created"))
1025
1031
  q = dict()
1026
1032
  q["{}__gte".format(dr_field)] = dr_start
taskqueue/models.py CHANGED
@@ -212,8 +212,12 @@ class Task(models.Model, RestModel):
212
212
  else:
213
213
  bof = TQ_RETRY_BACKOFF_FACTOR
214
214
  delay = TQ_RETRY_DELAY
215
- attempts = self.attempts - 1
216
- from_now_secs = delay * (bof ** attempts)
215
+ attempts = self.attempts - 2
216
+ if attempts == -1:
217
+ # retry first attempt right away
218
+ from_now_secs = 1
219
+ else:
220
+ from_now_secs = delay * (bof ** attempts)
217
221
  if from_now_secs is not None:
218
222
  # this will not run the task again until after this time has been hit
219
223
  self.scheduled_for = datetime.now() + timedelta(seconds=from_now_secs)
ws4redis/connection.py CHANGED
@@ -14,6 +14,7 @@ logger = getLogger("async", filename="async.log")
14
14
  MODEL_CACHE = dict() # caching of app.Model for faster access
15
15
 
16
16
  ALLOW_ANY_FACILITY = not private_settings.WS4REDIS_FACILITIES
17
+ DISCONNECT_AFTER_NO_CREDS = 30
17
18
 
18
19
 
19
20
  def getRemoteIP(request):
@@ -37,10 +38,15 @@ class WebsocketConnection():
37
38
  self.redis = RedisStore(server._redis_connection)
38
39
  self.websocket = server.upgrade_websocket(environ, start_response)
39
40
  self.last_beat = time.time()
41
+ self.conneted_time = time.time()
40
42
  self.last_msg = None
41
43
  self._heart_beat = util.toString(private_settings.WS4REDIS_HEARTBEAT)
42
44
  self.debug = private_settings.WS4REDIS_LOG_DEBUG
43
45
 
46
+ @property
47
+ def elapsed_time(self):
48
+ return time.time() - self.conneted_time
49
+
44
50
  def refreshFDs(self):
45
51
  if len(self.listening_fds) == 1:
46
52
  sub_sd = self.redis.get_file_descriptor()
@@ -160,6 +166,7 @@ class WebsocketConnection():
160
166
  return True
161
167
  Model = self.getAppModel(ch_model)
162
168
  if not hasattr(Model, "canPublishTo"):
169
+ logger.warning("canPublishTo", "no canPublishTo")
163
170
  return False
164
171
  return Model.canPublishTo(self.credentials, msg)
165
172
 
@@ -201,7 +208,7 @@ class WebsocketConnection():
201
208
 
202
209
  def on_channel_msg(self, msg):
203
210
  if not self.canPublishTo(msg):
204
- logger.warning("on_channel_msg permission denied", msg)
211
+ logger.warning("on_channel_msg permission denied", msg, private_settings.WS4REDIS_CHANNELS)
205
212
  self.sendToWS(msg.channel, dict(error="cannot publish to channel"))
206
213
  return None
207
214
  ch_model = private_settings.WS4REDIS_CHANNELS.get(msg.channel, None)
@@ -310,18 +317,17 @@ class WebsocketConnection():
310
317
  self.listening_fds = [websocket_fd]
311
318
  if callable(private_settings.URL_AUTHENTICATOR):
312
319
  private_settings.URL_AUTHENTICATOR(self)
313
- no_cred_count = 0
314
-
320
+
315
321
  while self.websocket and not self.websocket.closed:
316
322
  ready = self.server.select(self.listening_fds, [], [], 4.0)[0]
317
323
  if not ready:
318
324
  self.websocket.flush()
319
325
  if not self.credentials:
320
- no_cred_count += 1
321
- if no_cred_count > 10:
326
+ if self.elapsed_time > 8 and self.elapsed_time < 30:
322
327
  logger.error(f"{self.ip} has sent no credentials", self.ua)
323
- no_cred_count = 0
324
328
  self.sendToWS("member", dict(error="no credentials received"))
329
+ elif private_settings.WS4REDIS_NOAUTH_CLOSE and self.elapsed_time > 30:
330
+ self.release()
325
331
 
326
332
  for fd in ready:
327
333
  if fd == websocket_fd:
@@ -166,7 +166,7 @@ _websocket_url = getattr(settings, 'WEBSOCKET_URL')
166
166
 
167
167
  def application(environ, start_response):
168
168
  if _websocket_url and environ.get('PATH_INFO').startswith(_websocket_url):
169
- logger.info("environ", environ)
169
+ # logger.info("environ", environ)
170
170
  return _websocket_app(environ, start_response)
171
171
  return _django_app(environ, start_response)
172
172
 
ws4redis/settings.py CHANGED
@@ -42,3 +42,4 @@ WS4REDIS_AUTHENTICATORS = getattr(settings, "WS4REDIS_AUTHENTICATORS", {})
42
42
  URL_AUTHENTICATOR = getattr(settings, "URL_AUTHENTICATOR", None)
43
43
 
44
44
  WS4REDIS_LOG_DEBUG = getattr(settings, 'WS4REDIS_LOG_DEBUG', False)
45
+ WS4REDIS_NOAUTH_CLOSE = getattr(settings, 'WS4REDIS_NOAUTH_CLOSE', False)