|
|
|
|
@ -9,10 +9,12 @@ from django.contrib.auth import get_user_model |
|
|
|
|
from django.utils import timezone |
|
|
|
|
|
|
|
|
|
from .ws_sender import websocket_sender |
|
|
|
|
from .registry import device_registry |
|
|
|
|
from .registry import device_registry, related_users_registry |
|
|
|
|
|
|
|
|
|
User = get_user_model() |
|
|
|
|
|
|
|
|
|
### Device |
|
|
|
|
|
|
|
|
|
@receiver(post_save, sender=Device) |
|
|
|
|
def device_created(sender, instance, **kwargs): |
|
|
|
|
if not instance.user: |
|
|
|
|
@ -29,12 +31,15 @@ def device_post_delete(sender, instance, **kwargs): |
|
|
|
|
return |
|
|
|
|
evaluate_if_user_should_sync(instance._user) |
|
|
|
|
|
|
|
|
|
### Sync |
|
|
|
|
|
|
|
|
|
@receiver(pre_save) |
|
|
|
|
def presave_handler(sender, instance, **kwargs): |
|
|
|
|
synchronization_prepare(sender, instance, **kwargs) |
|
|
|
|
|
|
|
|
|
def synchronization_prepare(sender, instance, **kwargs): |
|
|
|
|
|
|
|
|
|
print(f'*** synchronization_prepare for instance: {instance}') |
|
|
|
|
signal = kwargs.get('signal') |
|
|
|
|
|
|
|
|
|
# avoid crash in manage.py createsuperuser + delete user in the admin |
|
|
|
|
@ -45,6 +50,11 @@ def synchronization_prepare(sender, instance, **kwargs): |
|
|
|
|
if not isinstance(instance, BaseModel) and not isinstance(instance, User): |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
users = related_users(instance) |
|
|
|
|
print(f'* impacted users = {users}') |
|
|
|
|
related_users_registry.register(instance.id, users) |
|
|
|
|
# user_ids = [user.id for user in users] |
|
|
|
|
|
|
|
|
|
if signal == pre_save: |
|
|
|
|
detect_foreign_key_changes(sender, instance) |
|
|
|
|
|
|
|
|
|
@ -66,25 +76,31 @@ def synchronization_notifications(sender, instance, created=False, **kwargs): |
|
|
|
|
save_model_log_if_possible(instance, signal, created) |
|
|
|
|
notify_impacted_users(instance) |
|
|
|
|
|
|
|
|
|
def notify_impacted_users(instance): |
|
|
|
|
user_ids = set() |
|
|
|
|
# add impacted users |
|
|
|
|
if isinstance(instance, User): |
|
|
|
|
user_ids.add(instance.id) |
|
|
|
|
elif isinstance(instance, BaseModel): |
|
|
|
|
owner = instance.last_updated_by |
|
|
|
|
if owner: |
|
|
|
|
user_ids.add(owner.id) |
|
|
|
|
related_users_registry.unregister(instance.id) |
|
|
|
|
|
|
|
|
|
if isinstance(instance, BaseModel): |
|
|
|
|
if hasattr(instance, '_users_to_notify'): |
|
|
|
|
user_ids.update(instance._users_to_notify) |
|
|
|
|
else: |
|
|
|
|
print('no users to notify') |
|
|
|
|
def notify_impacted_users(instance): |
|
|
|
|
print(f'*** notify_impacted_users for instance: {instance}') |
|
|
|
|
# user_ids = set() |
|
|
|
|
# # add impacted users |
|
|
|
|
# if isinstance(instance, User): |
|
|
|
|
# user_ids.add(instance.id) |
|
|
|
|
# elif isinstance(instance, BaseModel): |
|
|
|
|
# owner = instance.last_updated_by |
|
|
|
|
# if owner: |
|
|
|
|
# user_ids.add(owner.id) |
|
|
|
|
|
|
|
|
|
# if isinstance(instance, BaseModel): |
|
|
|
|
# if hasattr(instance, '_users_to_notify'): |
|
|
|
|
# user_ids.update(instance._users_to_notify) |
|
|
|
|
# else: |
|
|
|
|
# print('no users to notify') |
|
|
|
|
|
|
|
|
|
device_id = device_registry.get_device_id(instance.id) |
|
|
|
|
users = related_users_registry.get_users(instance.id) |
|
|
|
|
|
|
|
|
|
# print(f'notify: {device_id}') |
|
|
|
|
if users: |
|
|
|
|
user_ids = [user.id for user in users] |
|
|
|
|
print(f'notify device: {device_id}, users = {user_ids}') |
|
|
|
|
for user_id in user_ids: |
|
|
|
|
websocket_sender.send_user_message(user_id, device_id) |
|
|
|
|
|
|
|
|
|
@ -92,8 +108,8 @@ def notify_impacted_users(instance): |
|
|
|
|
|
|
|
|
|
def save_model_log_if_possible(instance, signal, created): |
|
|
|
|
|
|
|
|
|
users = related_users(instance) |
|
|
|
|
# print(f'users = {len(users)}, instance = {instance}') |
|
|
|
|
users = related_users_registry.get_users(instance.id) |
|
|
|
|
print(f'*** save_model_log >>> users = {users}, instance = {instance}') |
|
|
|
|
if users: |
|
|
|
|
if signal == post_save or signal == pre_save: |
|
|
|
|
if created: |
|
|
|
|
@ -111,10 +127,9 @@ def save_model_log_if_possible(instance, signal, created): |
|
|
|
|
if operation == ModelOperation.DELETE: # delete now unnecessary logs |
|
|
|
|
ModelLog.objects.filter(model_id=instance.id).delete() |
|
|
|
|
|
|
|
|
|
user_ids = [user.id for user in users] |
|
|
|
|
|
|
|
|
|
# print(f'users to notify: {user_ids}') |
|
|
|
|
instance._users_to_notify = user_ids # save this for the post_save signal |
|
|
|
|
# user_ids = [user.id for user in users] |
|
|
|
|
# # print(f'users to notify: {user_ids}') |
|
|
|
|
# instance._users_to_notify = user_ids # save this for the post_save signal |
|
|
|
|
save_model_log(users, operation, model_name, instance.id, store_id) |
|
|
|
|
|
|
|
|
|
else: |
|
|
|
|
@ -200,6 +215,8 @@ def process_foreign_key_changes(sender, instance, **kwargs): |
|
|
|
|
model_name, change['new_value'].id, |
|
|
|
|
change['new_value'].get_store_id()) |
|
|
|
|
|
|
|
|
|
### Data Access |
|
|
|
|
|
|
|
|
|
@receiver(post_delete) |
|
|
|
|
def delete_data_access_if_necessary(sender, instance, **kwargs): |
|
|
|
|
if not isinstance(instance, BaseModel): |
|
|
|
|
@ -210,6 +227,7 @@ def delete_data_access_if_necessary(sender, instance, **kwargs): |
|
|
|
|
@receiver(m2m_changed, sender=DataAccess.shared_with.through) |
|
|
|
|
def handle_shared_with_changes(sender, instance, action, pk_set, **kwargs): |
|
|
|
|
|
|
|
|
|
print(f'm2m changed = {pk_set}') |
|
|
|
|
users = User.objects.filter(id__in=pk_set) |
|
|
|
|
|
|
|
|
|
if action == "post_add": |
|
|
|
|
@ -233,10 +251,14 @@ def data_access_post_save(sender, instance, **kwargs): |
|
|
|
|
@receiver(pre_delete, sender=DataAccess) |
|
|
|
|
def revoke_access_after_delete(sender, instance, **kwargs): |
|
|
|
|
instance.create_revoke_access_log() |
|
|
|
|
related_users_registry.register(instance.id, instance.shared_with.all()) |
|
|
|
|
|
|
|
|
|
instance._user = instance.related_user |
|
|
|
|
|
|
|
|
|
@receiver(post_delete, sender=DataAccess) |
|
|
|
|
def data_access_post_delete(sender, instance, **kwargs): |
|
|
|
|
notify_impacted_users(instance) |
|
|
|
|
|
|
|
|
|
if not hasattr(instance, '_user') or not instance._user: |
|
|
|
|
return |
|
|
|
|
evaluate_if_user_should_sync(instance._user) |
|
|
|
|
@ -285,8 +307,6 @@ def evaluate_if_user_should_sync(user): |
|
|
|
|
).count() > 0: |
|
|
|
|
should_synchronize = True |
|
|
|
|
|
|
|
|
|
print(f'should_synchronize = {should_synchronize}') |
|
|
|
|
|
|
|
|
|
with transaction.atomic(): |
|
|
|
|
user.should_synchronize = should_synchronize |
|
|
|
|
# if we go from True to False we might want to delete ModelLog once the last device has synchronized |
|
|
|
|
|