django-restit 4.2.45__py3-none-any.whl → 4.2.47__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.
@@ -0,0 +1,20 @@
1
+ # Generated by Django 4.1.4 on 2024-02-23 20:55
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('location', '0004_remove_address_modified_by_address_group_and_more'),
11
+ ('account', '0018_userpasskey'),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.AddField(
16
+ model_name='group',
17
+ name='location',
18
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='location.address'),
19
+ ),
20
+ ]
account/models/group.py CHANGED
@@ -38,6 +38,10 @@ class Group(models.Model, RestModel, MetaDataModel):
38
38
  # this is the new model for groups having multiple parents
39
39
  children = models.ManyToManyField("self", related_name="parents", symmetrical=False)
40
40
 
41
+ location = models.ForeignKey(
42
+ "location.Address", default=None, null=True, blank=True,
43
+ related_name="+", on_delete=models.SET_NULL)
44
+
41
45
  class RestMeta:
42
46
  SEARCH_FIELDS = [
43
47
  "name"
@@ -76,7 +80,8 @@ class Group(models.Model, RestModel, MetaDataModel):
76
80
  "default": {
77
81
  "graphs": {
78
82
  "self": "basic",
79
- "parent": "basic"
83
+ "parent": "basic",
84
+ "location": "basic"
80
85
  },
81
86
  "fields": ["metadata"],
82
87
  },
@@ -84,9 +89,17 @@ class Group(models.Model, RestModel, MetaDataModel):
84
89
  "graphs": {
85
90
  "self": "basic",
86
91
  "parent": "basic",
87
- "children": "basic"
92
+ "children": "basic",
93
+ "location": "basic"
88
94
  },
89
- "fields": ["metadata"],
95
+ "extra": ["metadata"],
96
+ },
97
+ "location": {
98
+ "fields": ["name", "kind", "id"],
99
+ "extra": ["location"],
100
+ "graphs": {
101
+ "location": "basic"
102
+ }
90
103
  },
91
104
  "abstract": {
92
105
  "fields": [
@@ -157,7 +170,7 @@ class Group(models.Model, RestModel, MetaDataModel):
157
170
  raise PermissionDeniedException("invalid parent")
158
171
  qset = qset.filter(parent=parent)
159
172
  elif child_of:
160
- parent = parent = request.member.getGroup(child_of)
173
+ parent = request.member.getGroup(child_of)
161
174
  if parent:
162
175
  request.group = None
163
176
  return parent.getAllChildren(grand_children=True)
account/models/session.py CHANGED
@@ -27,6 +27,12 @@ class AuthSession(models.Model, RestModel):
27
27
  "graphs": {
28
28
  "location": "default"
29
29
  }
30
+ },
31
+ "location": {
32
+ "graphs": {
33
+ "location": "default",
34
+ "member": "basic"
35
+ }
30
36
  }
31
37
  }
32
38
  # the signature of session
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-restit
3
- Version: 4.2.45
3
+ Version: 4.2.47
4
4
  Summary: A Rest Framework for DJANGO
5
5
  License: MIT
6
6
  Author: Ian Starnes
@@ -18,17 +18,18 @@ account/migrations/0015_memberdevice_buid.py,sha256=O3M3mS_O1zn4gQahC3ebRu8tMySo
18
18
  account/migrations/0016_authsession_buid.py,sha256=wZdiH_87Ik3jAXYUgtafeAo9IbJq35xDVOlQ_UiTC8k,424
19
19
  account/migrations/0017_rename_requires_topt_member_requires_totp.py,sha256=GksGiF7OQDV2RihyC2OTBzSmDwzCzenThkNs6FKni4M,375
20
20
  account/migrations/0018_userpasskey.py,sha256=SdXYo4TkIeP5wLNfCza3Jq5-gKuUufzTHGBw0hFQOMY,1475
21
+ account/migrations/0019_group_location.py,sha256=EfMB_w4qWUGDqQeNc453PFZwpjpTeoA6xr6Qgo_YAOM,601
21
22
  account/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
23
  account/models/__init__.py,sha256=cV_lMnT2vL_mjiYtT4hlcIHo52ocFbGSNVkOIHHLXZY,385
23
24
  account/models/device.py,sha256=XipNpByreGubB5-d4ZBOoIV5Xw14b2Btcgn6fXz8HAc,4105
24
25
  account/models/feeds.py,sha256=FXqcZ1Qy4oYOLzai7-GL4WNd7iKPb5Y3ZqvKQunq1Yk,1861
25
- account/models/group.py,sha256=d9uYtLub7iABrQmsYg_L88xG3W7f7VRWvOpebD3XgQY,20684
26
+ account/models/group.py,sha256=l56gQxR1PQNae3TdtL5ytxdSCPP9miYZ2pBMLqA0d5E,21125
26
27
  account/models/legacy.py,sha256=zYdtv4LC0ooxPVqWM-uToPwV-lYWQLorSE6p6yn1xDw,2720
27
28
  account/models/member.py,sha256=XwT4evwN6_THL2bKb_TjtQg7NWNwQqtotMHLScplv1s,50188
28
29
  account/models/membership.py,sha256=K2fd0TJYhfv58HPyjQVlahlOPz3Q6ZwrxVkguG-2Ej8,7806
29
30
  account/models/notify.py,sha256=YnZujSHJHY7B09e6FIyZIEJRWLPYk1Sk1e92tFzB1IA,12078
30
31
  account/models/passkeys.py,sha256=TJxITUi4DT4_1tW2K7ZlOcRjJuMVl2NtKz7pKQU8-Tw,1516
31
- account/models/session.py,sha256=iN9x9hi0LyB_2giT__YuqwbClQ7Ae8Gb4bhGph_qD6Q,3561
32
+ account/models/session.py,sha256=o3t98e8itXEtkknBHdBH_PSq9kuw1A858_wl6ZleXMM,3729
32
33
  account/models/settings.py,sha256=gOyRWBVd3BQpjfj_hJPtqX3H46ztyRAFxBrPbv11lQg,2137
33
34
  account/oauth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
35
  account/oauth/google.py,sha256=q5M6Qhpfp9QslKRVYFZBvtG6kgXV6vYMrR5fp6Xdb9I,2078
@@ -102,7 +103,7 @@ incident/migrations/0013_rulecheck_is_required.py,sha256=cL7tOj5XGPpKd2f5BojIKfN
102
103
  incident/migrations/0014_event_group_alter_rulecheck_index.py,sha256=v3gm5k0LVoas27qUDOt7el7YtK4yjFVLeEpuFUCoXaQ,724
103
104
  incident/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
105
  incident/models/__init__.py,sha256=NMphuhb0RTMf7Ov4QkNv7iv6_I8Wtr3xQ54yjX_a31M,209
105
- incident/models/event.py,sha256=CYyJHcTCRSkZuOynVNVBO6P9466OamMVV63jWEbDBZ8,7264
106
+ incident/models/event.py,sha256=qa6BIlellU7uUQcA2c4Botd2x7JLL8b7IjSfxyi5iHk,7306
106
107
  incident/models/incident.py,sha256=0M7QN32BwlHYRvnUWPqI4IIThSpActGDdbmbPjNcJ9A,18415
107
108
  incident/models/ossec.py,sha256=p1ptr-8lnaj1EP_VmPR58b2LmaYBGaYYKAMqhWK5yZM,2227
108
109
  incident/models/rules.py,sha256=uT5GhW6Flso287lJGphAlWwL20NRnHDAZoGrWBBQfeE,6260
@@ -121,9 +122,10 @@ location/geolocate.py,sha256=UgV129vmSxnqYFBYJD2RQVOcC1-lJJ1zUaxDqOJRbG4,1694
121
122
  location/migrations/0001_initial.py,sha256=E0Kekah0vfp7VGKGYRHFEIFjFRTkd8QnFGSHNFllVv0,7000
122
123
  location/migrations/0002_geoip_subnet_alter_geoip_ip.py,sha256=n-oJrEnIqN9VnMhiZsr34LF-EXBluPm1lz1zusaMkx8,576
123
124
  location/migrations/0003_address_postalcode_suffix.py,sha256=DT8voJeMiSQyUhH-69NHK9YywaChAvIJn1ztL7fCI30,443
125
+ location/migrations/0004_remove_address_modified_by_address_group_and_more.py,sha256=Xq0q8oVoElVYbPC779empO4GIQKuRWOyBCUmWg9Wzo4,1270
124
126
  location/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
127
  location/models/__init__.py,sha256=rZhldkoKmoJQXjBAK1IIQn7K_OOJvFtIGOGVl_szqbE,230
126
- location/models/address.py,sha256=oTPQiLdg2QkfPorlm16re1OoR6TJf4Of2Ew1slun2r8,2596
128
+ location/models/address.py,sha256=5059tQZI4XDZJPywQPN0zXIJ8FTUQnONwBkc7DFgwng,3045
127
129
  location/models/ip.py,sha256=ZaBFdW1tL1Q3bnS5gIY9SseiQ5xeeP_oyP1hp3czFeA,5984
128
130
  location/models/legacy.py,sha256=8ROsUSZrjGQkUyXeJvoxPdKAWaKfUH-AL9TIeJb7krg,1994
129
131
  location/models/location.py,sha256=01dJPJecbp5orExsIGWOsBC_KkwFRIW0rGDIwyx1r0w,2316
@@ -141,7 +143,8 @@ location/providers/location/google.py,sha256=RXZoYXUcTerE3-7z2BciEuDJJB-f-0_F6jW
141
143
  location/providers/timezones/__init__.py,sha256=enslc1cVTju3GKrvpLoAxSHUKkLeREhed-eHkvHWdoM,46
142
144
  location/providers/timezones/google.py,sha256=HyATVCGJ3wHwfc47jQRLnwa8nPeBlmpHOGTxetfg7FU,619
143
145
  location/providers/zillow.py,sha256=nCV_q_9ULRkgxi4HTZHioP6nWDDmApvSf1DcwNLcOxk,1935
144
- location/rpc/__init__.py,sha256=74T2Y3Zw7ZOl_h67Gdb-tfkyKJAJFSDFHjv04FRKsjQ,123
146
+ location/rpc/__init__.py,sha256=MDs0Qntwff3d128BhjHEFcGTWSomshHQ1VToqMT0YVA,166
147
+ location/rpc/address.py,sha256=ivkdG5Oc8YnJowEQ8dmiOnZr5OOaIuiw9fuwbrC7gUQ,219
145
148
  location/rpc/ip.py,sha256=TbRRgh4_hykT_Z0PDQrMnCdp_x0nK0Zm_WnvzXuweF4,1305
146
149
  location/rpc/location.py,sha256=D5R54nnmmp8NaHQRkP_TF921Ej6j9nmTUNzX1K5WVPc,779
147
150
  location/rpc/track.py,sha256=jSS9_eiKayM_8iW_4Ldojg9a2_trjfXhnLe_a261x5E,3735
@@ -360,7 +363,7 @@ pushit/utils.py,sha256=IeTCGa-164nmB1jIsK1lu1O1QzUhS3BKfuXHGjCW-ck,2121
360
363
  rest/.gitignore,sha256=TbEvWRMnAiajCTOdhiNrd9eeCAaIjRp9PRjE_VkMM5g,118
361
364
  rest/README.md,sha256=V3ETc-cJu8PZIbKr9xSe_pA4JEUpC8Dhw4bQeVCDJPw,5460
362
365
  rest/RemoteEvents.py,sha256=nL46U7AuxIrlw2JunphR1tsXyqi-ep_gD9CYGpYbNgE,72
363
- rest/__init__.py,sha256=1X-W3BH6L-ujXvvzyMW1tIIeqHcQOhgRzb6isSAl9mY,121
366
+ rest/__init__.py,sha256=KPZYlX8yNoUvOBRew6LnBQO59yY6TNSoJO9DSSVFH10,121
364
367
  rest/arc4.py,sha256=y644IbF1ec--e4cUJ3KEYsewTCITK0gmlwa5mJruFC0,1967
365
368
  rest/cache.py,sha256=1Qg0rkaCJCaVP0-l5hZg2CIblTdeBSlj_0fP6vlKUpU,83
366
369
  rest/crypto/__init__.py,sha256=Tl0U11rgj1eBYqd6OXJ2_XSdNLumW_JkBZnaJqI6Ldw,72
@@ -392,7 +395,7 @@ rest/middleware/request.py,sha256=JchRNy5L-bGd-7h-KFYekGRvREe2eCkZXKOYqIkP2hI,41
392
395
  rest/middleware/session.py,sha256=zHSoQpIzRLmpqr_JvW406wzpvU3W3gDbm5JhtzLAMlE,10240
393
396
  rest/middleware/session_store.py,sha256=1nSdeXK8PyuYgGgIufqrS6j6QpIrQ7zbMNT0ol75e6U,1901
394
397
  rest/models/__init__.py,sha256=M8pvFDq-WCF-QcM58X7pMufYYe0aaQ3U0PwGe9TKbbY,130
395
- rest/models/base.py,sha256=vYs3dlI10VYbYiKMhqZ9XJXTHllrS9eQNzpPRyPBBHg,67303
398
+ rest/models/base.py,sha256=S6lLCPPEUQRVHn_4S2TwAVSQisdlKz3kqKI4dRKWUBY,67650
396
399
  rest/models/cacher.py,sha256=eKz8TINVhWEqKhJGMsRkKZTtBUIv5rN3NHbZwOC56Uk,578
397
400
  rest/models/metadata.py,sha256=ui0962oaWbYGIbkNs7oaUGKyaca9epsW2H-ywgyH7rg,12631
398
401
  rest/net.py,sha256=LcB2QV6VNRtsSdmiQvYZgwQUDwOPMn_VBdRiZ6OpI-I,2974
@@ -482,7 +485,7 @@ wiki/rpc/wiki.py,sha256=iWehZasU8J1E5sPPqz9QoQr3MpGxqu3rd7CH4wFrm2w,1333
482
485
  wiki/tq.py,sha256=wvuBZ3OMV_D2o4kpJhVLIOwpEUfwlglqLJQvpncAwtk,313
483
486
  ws4redis/README.md,sha256=QvwdsauPKxx4qQqnJ991xeU8DgFQCj3CeQt-nCE4s-w,3624
484
487
  ws4redis/__init__.py,sha256=teNfv83A_ke1CBt9BB7NsnWCcFBhnUFPsPESjF554_k,46
485
- ws4redis/client.py,sha256=0PXDFHb7P7BRjvT0_3Al9ZOfsljMzng93HsSl90nzro,5225
488
+ ws4redis/client.py,sha256=ZI8m6c8cG-Ysn80OokZQxg2ihHHWbp0Ea7C7jmFk1UQ,6506
486
489
  ws4redis/connection.py,sha256=QGjzalYrx1y4o6sb6P1akL-Y2fjf2qil0JCo-ona5F8,13431
487
490
  ws4redis/exceptions.py,sha256=EGLoRTdqJVwz900pwhciqPuSjBBd08hhLgFu6umHrI4,636
488
491
  ws4redis/redis.py,sha256=IfT4p3bUtlqso9rryNliH9Ebzlx8-Q2VJcs1kFioeGA,6093
@@ -493,7 +496,7 @@ ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,172
493
496
  ws4redis/settings.py,sha256=K0yBiLUuY81iDM4Yr-k8hbvjn5VVHu5zQhmMK8Dtz0s,1536
494
497
  ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
495
498
  ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
496
- django_restit-4.2.45.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
497
- django_restit-4.2.45.dist-info/METADATA,sha256=sjprDnHaz3wHRJMOMfpI0y3UMinbPipZ0aB8mboJGdI,7594
498
- django_restit-4.2.45.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
499
- django_restit-4.2.45.dist-info/RECORD,,
499
+ django_restit-4.2.47.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
500
+ django_restit-4.2.47.dist-info/METADATA,sha256=L-HD17mdjnfiJOiNb865oC4nGAAQsYmAXETtIrCZnL4,7594
501
+ django_restit-4.2.47.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
502
+ django_restit-4.2.47.dist-info/RECORD,,
incident/models/event.py CHANGED
@@ -136,6 +136,8 @@ class Event(JSONMetaData, rm.RestModel):
136
136
  self.lookupIP(request.ip)
137
137
 
138
138
  def on_rest_saved(self, request, is_new=False):
139
+ if not is_new:
140
+ return
139
141
  if INCIDENT_EVENT_METRICS:
140
142
  if self.hostname:
141
143
  metrics.metric(f"incident_evt_{self.hostname}", category="incident_events", min_granularity="hourly")
@@ -0,0 +1,36 @@
1
+ # Generated by Django 4.1.4 on 2024-02-23 19:15
2
+
3
+ from django.conf import settings
4
+ from django.db import migrations, models
5
+ import django.db.models.deletion
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12
+ ('account', '0018_userpasskey'),
13
+ ('location', '0003_address_postalcode_suffix'),
14
+ ]
15
+
16
+ operations = [
17
+ migrations.RemoveField(
18
+ model_name='address',
19
+ name='modified_by',
20
+ ),
21
+ migrations.AddField(
22
+ model_name='address',
23
+ name='group',
24
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='addresses', to='account.group'),
25
+ ),
26
+ migrations.AddField(
27
+ model_name='address',
28
+ name='label',
29
+ field=models.CharField(blank=True, db_index=True, default=None, max_length=250, null=True),
30
+ ),
31
+ migrations.AddField(
32
+ model_name='address',
33
+ name='member',
34
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='addresses', to=settings.AUTH_USER_MODEL),
35
+ ),
36
+ ]
@@ -6,6 +6,11 @@ from .. import geolocate
6
6
 
7
7
  class Address(models.Model, rm.RestModel):
8
8
  class RestMeta:
9
+ VIEW_PERMS = [
10
+ "view_all_groups",
11
+ "manage_groups",
12
+ "manage_group",
13
+ "manage_settings"]
9
14
  GRAPHS = {
10
15
  "abstract": {
11
16
  "fields":[
@@ -18,7 +23,15 @@ class Address(models.Model, rm.RestModel):
18
23
  ]
19
24
  }
20
25
  }
21
- modified_by = models.ForeignKey("account.User", null=True, blank=True, default=None, on_delete=models.CASCADE)
26
+ label = models.CharField(
27
+ max_length=250, null=True, blank=True,
28
+ default=None, db_index=True)
29
+ member = models.ForeignKey(
30
+ "account.User", null=True, blank=True,
31
+ default=None, on_delete=models.SET_NULL, related_name="addresses")
32
+ group = models.ForeignKey(
33
+ "account.Group", null=True, blank=True,
34
+ default=None, on_delete=models.SET_NULL, related_name="addresses")
22
35
  modified = models.DateTimeField(auto_now=True)
23
36
  line1 = models.CharField(max_length=255, blank=True, null=True, default=None)
24
37
  line2 = models.CharField(max_length=255, blank=True, null=True, default=None)
location/rpc/__init__.py CHANGED
@@ -1,3 +1,4 @@
1
1
  from .ip import * # noqa: F401, F403
2
2
  from .track import * # noqa: F401, F403
3
3
  from .location import * # noqa: F401, F403
4
+ from .address import * # noqa: F401, F403
@@ -0,0 +1,8 @@
1
+ from rest import decorators as rd
2
+ from location import models as location
3
+
4
+
5
+ @rd.url('address')
6
+ @rd.url('address/<int:pk>')
7
+ def rest_on_address(request, pk=None):
8
+ return location.Address.on_rest_request(request, pk)
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.45"
4
+ __version__ = "4.2.47"
rest/models/base.py CHANGED
@@ -321,6 +321,16 @@ class RestModel(object):
321
321
  def getModel(app_name, model_name):
322
322
  return apps.get_model(app_name, model_name)
323
323
 
324
+ @staticmethod
325
+ def getModelInstance(app_name, model_name, **kwargs):
326
+ Model = apps.get_model(app_name, model_name)
327
+ return Model.objects.filter(**kwargs).last()
328
+
329
+ @staticmethod
330
+ def createModelInstance(app_name, model_name, **kwargs):
331
+ Model = apps.get_model(app_name, model_name)
332
+ return Model(**kwargs)
333
+
324
334
  def restGetGenericModel(self, field):
325
335
  # called by the rest module to magically parse
326
336
  # a component that is marked genericr elation in a graph
ws4redis/client.py CHANGED
@@ -131,6 +131,55 @@ def hincrby(name, field, inc=1):
131
131
  return c.hincrby(name, field, inc)
132
132
 
133
133
 
134
+ def lpush(name, value, unique=False):
135
+ c = getRedisClient()
136
+ if isinstance(value, list):
137
+ for v in value:
138
+ if unique and value.encode() in c.lrange(name, 0, -1):
139
+ return 0
140
+ c.lpush(name, v)
141
+ return len(value)
142
+ if unique and value.encode() in c.lrange(name, 0, -1):
143
+ return 0
144
+ return c.lpush(name, value)
145
+
146
+
147
+ def rpush(name, value, unique=False):
148
+ c = getRedisClient()
149
+ if isinstance(value, list):
150
+ for v in value:
151
+ if unique and value.encode() in c.lrange(name, 0, -1):
152
+ return 0
153
+ c.rpush(name, v)
154
+ return len(value)
155
+ if unique and value.encode() in c.lrange(name, 0, -1):
156
+ return 0
157
+ return c.rpush(name, value)
158
+
159
+
160
+ def lpop(name, timeout=None):
161
+ c = getRedisClient()
162
+ if timeout is None:
163
+ return c.lpop(name)
164
+ r = c.blpop(name, timeout=timeout)
165
+ if isinstance(r, tuple):
166
+ return r[1].decode()
167
+
168
+
169
+ def rpop(name, timeout=None):
170
+ c = getRedisClient()
171
+ if timeout is None:
172
+ return c.rpop(name)
173
+ r = c.brpop(name, timeout=timeout)
174
+ if isinstance(r, tuple):
175
+ return r[1].decode()
176
+
177
+
178
+ def lrange(name, start, end):
179
+ c = getRedisClient()
180
+ return [v.decode() for v in c.lrange(name, start, end)]
181
+
182
+
134
183
  def sendToUser(user, name, message=None, priority=0, model=None, model_pk=None, custom=None):
135
184
  return sendMessageToUsers([user], buildEventMessage(name, message, priority, model, model_pk, custom))
136
185