|
|
|
@ -5,13 +5,7 @@ from .models import DataAccess, ModelLog, ModelOperation, BaseModel, SideStoreMo |
|
|
|
from django.contrib.auth import get_user_model |
|
|
|
from django.contrib.auth import get_user_model |
|
|
|
from django.utils import timezone |
|
|
|
from django.utils import timezone |
|
|
|
|
|
|
|
|
|
|
|
from channels.layers import get_channel_layer |
|
|
|
from .ws_sender import websocket_sender |
|
|
|
from asgiref.sync import async_to_sync |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from threading import Timer |
|
|
|
|
|
|
|
# from functools import partial |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Synchronization |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
User = get_user_model() |
|
|
|
User = get_user_model() |
|
|
|
|
|
|
|
|
|
|
|
@ -19,7 +13,7 @@ User = get_user_model() |
|
|
|
def synchronization_prepare(sender, instance, created=False, **kwargs): |
|
|
|
def synchronization_prepare(sender, instance, created=False, **kwargs): |
|
|
|
|
|
|
|
|
|
|
|
# some classes are excluded in settings_app.py: SYNC_APPS |
|
|
|
# some classes are excluded in settings_app.py: SYNC_APPS |
|
|
|
if not isinstance(instance, BaseModel): |
|
|
|
if not isinstance(instance, BaseModel) and not isinstance(instance, User): |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
save_model_log_if_possible(instance, kwargs.get('signal'), created) |
|
|
|
save_model_log_if_possible(instance, kwargs.get('signal'), created) |
|
|
|
@ -57,10 +51,15 @@ def notify_impacted_users(instance, signal): |
|
|
|
|
|
|
|
|
|
|
|
print(f'notify: {user_ids}') |
|
|
|
print(f'notify: {user_ids}') |
|
|
|
for user_id in user_ids: |
|
|
|
for user_id in user_ids: |
|
|
|
send_user_message(user_id) |
|
|
|
websocket_sender.send_user_message(user_id) |
|
|
|
|
|
|
|
# send_user_message(user_id) |
|
|
|
|
|
|
|
|
|
|
|
def save_model_log_if_possible(instance, signal, created): |
|
|
|
def save_model_log_if_possible(instance, signal, created): |
|
|
|
user = instance.last_updated_by |
|
|
|
if isinstance(instance, User): |
|
|
|
|
|
|
|
user = instance |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
user = instance.last_updated_by |
|
|
|
|
|
|
|
|
|
|
|
if user: |
|
|
|
if user: |
|
|
|
if signal == post_save or signal == pre_save: |
|
|
|
if signal == post_save or signal == pre_save: |
|
|
|
if created: |
|
|
|
if created: |
|
|
|
@ -79,10 +78,11 @@ def save_model_log_if_possible(instance, signal, created): |
|
|
|
ModelLog.objects.filter(model_id=instance.id).delete() |
|
|
|
ModelLog.objects.filter(model_id=instance.id).delete() |
|
|
|
|
|
|
|
|
|
|
|
users = {user} |
|
|
|
users = {user} |
|
|
|
data_access_list = related_data_access(instance) |
|
|
|
if isinstance(instance, BaseModel): |
|
|
|
for data_access in data_access_list: |
|
|
|
data_access_list = related_data_access(instance) |
|
|
|
users.add(data_access.owner) |
|
|
|
for data_access in data_access_list: |
|
|
|
users.update(data_access.shared_with.all()) |
|
|
|
users.add(data_access.owner) |
|
|
|
|
|
|
|
users.update(data_access.shared_with.all()) |
|
|
|
if isinstance(instance, DataAccess): |
|
|
|
if isinstance(instance, DataAccess): |
|
|
|
users.add(instance.owner) |
|
|
|
users.add(instance.owner) |
|
|
|
users.update(instance.shared_with.all()) |
|
|
|
users.update(instance.shared_with.all()) |
|
|
|
@ -102,7 +102,7 @@ def save_model_log(users, model_operation, model_name, model_id, store_id): |
|
|
|
if existing_log: |
|
|
|
if existing_log: |
|
|
|
# print(f'update existing log {existing_log.users} ') |
|
|
|
# print(f'update existing log {existing_log.users} ') |
|
|
|
existing_log.date = now |
|
|
|
existing_log.date = now |
|
|
|
existing_log.model_operation = model_operation |
|
|
|
# existing_log.operation = model_operation |
|
|
|
existing_log.save() |
|
|
|
existing_log.save() |
|
|
|
existing_log.users.set(users) |
|
|
|
existing_log.users.set(users) |
|
|
|
else: |
|
|
|
else: |
|
|
|
@ -135,32 +135,33 @@ def handle_shared_with_changes(sender, instance, action, pk_set, **kwargs): |
|
|
|
instance.create_access_log(users, 'REVOKE_ACCESS') |
|
|
|
instance.create_access_log(users, 'REVOKE_ACCESS') |
|
|
|
|
|
|
|
|
|
|
|
for user_id in pk_set: |
|
|
|
for user_id in pk_set: |
|
|
|
send_user_message(user_id) |
|
|
|
websocket_sender.send_user_message(user_id) |
|
|
|
|
|
|
|
# send_user_message(user_id) |
|
|
|
|
|
|
|
|
|
|
|
def send_user_message(user_id): |
|
|
|
# def send_user_message(user_id): |
|
|
|
|
|
|
|
|
|
|
|
if not hasattr(send_user_message, '_buffer'): |
|
|
|
# if not hasattr(send_user_message, '_buffer'): |
|
|
|
send_user_message._buffer = set() |
|
|
|
# send_user_message._buffer = set() |
|
|
|
send_user_message._timer = None |
|
|
|
# send_user_message._timer = None |
|
|
|
|
|
|
|
|
|
|
|
send_user_message._buffer.add(user_id) |
|
|
|
# send_user_message._buffer.add(user_id) |
|
|
|
|
|
|
|
|
|
|
|
if send_user_message._timer: |
|
|
|
# if send_user_message._timer: |
|
|
|
send_user_message._timer.cancel() |
|
|
|
# send_user_message._timer.cancel() |
|
|
|
|
|
|
|
|
|
|
|
def send_buffered_messages(): |
|
|
|
# def send_buffered_messages(): |
|
|
|
channel_layer = get_channel_layer() |
|
|
|
# channel_layer = get_channel_layer() |
|
|
|
for buffered_id in send_user_message._buffer: |
|
|
|
# for buffered_id in send_user_message._buffer: |
|
|
|
group_name = f"sync_{buffered_id}" |
|
|
|
# group_name = f"sync_{buffered_id}" |
|
|
|
print(f">>> send to group {group_name}") |
|
|
|
# print(f">>> send to group {group_name}") |
|
|
|
async_to_sync(channel_layer.group_send)( |
|
|
|
# async_to_sync(channel_layer.group_send)( |
|
|
|
group_name, {"type": "sync.update", "message": "hello"} |
|
|
|
# group_name, {"type": "sync.update", "message": "hello"} |
|
|
|
) |
|
|
|
# ) |
|
|
|
send_user_message._buffer.clear() |
|
|
|
# send_user_message._buffer.clear() |
|
|
|
send_user_message._timer = None |
|
|
|
# send_user_message._timer = None |
|
|
|
|
|
|
|
|
|
|
|
send_user_message._timer = Timer(0.1, send_buffered_messages) |
|
|
|
# send_user_message._timer = Timer(0.1, send_buffered_messages) |
|
|
|
send_user_message._timer.start() |
|
|
|
# send_user_message._timer.start() |
|
|
|
|
|
|
|
|
|
|
|
@receiver(pre_delete, sender=DataAccess) |
|
|
|
@receiver(pre_delete, sender=DataAccess) |
|
|
|
def revoke_access_after_delete(sender, instance, **kwargs): |
|
|
|
def revoke_access_after_delete(sender, instance, **kwargs): |
|
|
|
|