Example #1
0
def send_update_on_new_notification(sender, document, created, **kwargs):
    """
    Sends update through push server to the user when a new notification is created.

    Important: This signal should be processed only asynchronously (background task) as
    it can block. So currently it is assumed that notification documents are created
    only in background tasks.
    """

    notification = document

    def test_if_running_as_celery_worker():
        for filename, line_number, function_name, text in traceback.extract_stack():
            if "celery" in filename:
                return True
        return False

    assert test_if_running_as_celery_worker()

    # Dummy request object, it is used in serialization to get JSONP callback name, but we
    # want always just JSON, so we can create dummy object and hopefuly get away with it
    request = client.RequestFactory().request()

    from piplmesh import urls

    bundle = urls.notification_resource.build_bundle(obj=notification, request=request)
    output_bundle = urls.notification_resource.full_dehydrate(bundle)
    output_bundle = urls.notification_resource.alter_detail_data_to_serialize(request, output_bundle)

    serialized = urls.notification_resource.serialize(
        request, {"type": "notification", "notification": output_bundle.data}, "application/json"
    )
    updates.send_update(notification.recipient.get_user_channel(), serialized, True)
Example #2
0
def check_online_users():
    # TODO: Iterating over all users in Python could become really slow once there are millions of users, much better is to limit the query only to potentially interesting users (conditions are already bellow)
    for user in models.User.objects():
        if models.User.objects(
            id=user.id,
            is_online=True,
            connections=[],
            connection_last_unsubscribe__lt=datetime.datetime.now() - datetime.timedelta(seconds=CHECK_ONLINE_USERS_RECONNECT_TIMEOUT),
        ).update(set__is_online=False):
            updates.send_update(
                views.HOME_CHANNEL_ID,
                {
                    'type': 'userlist',
                    'action': 'PART',
                    'username': user.username,
                }
            )
        elif models.User.objects(
            id=user.id,
            is_online=False,
            connections__ne=[],
        ).update(set__is_online=True):
            updates.send_update(
                views.HOME_CHANNEL_ID,
                {
                    'type': 'userlist',
                    'action': 'JOIN',
                    'username': user.username,
                }
            )
Example #3
0
def check_online_users():
    for user in models.User.objects(
        is_online=False,
        connections__not__in=([], None), # None if field is missing altogether, not__in seems not to be equal to nin
    ):
        if models.User.objects(
            pk=user.pk,
            is_online=False,
            connections__not__in=([], None), # None if field is missing altogether, not__in seems not to be equal to nin
        ).update(set__is_online=True):
            updates.send_update(
                HOME_CHANNEL_ID,
                {
                    'type': 'user_connect',
                    'user': {
                        'username': user.username,
                        'profile_url': user.get_profile_url(),
                        'image_url': user.get_image_url(),
                    },
                }
            )

    for user in models.User.objects(
        is_online=True,
        connections__in=([], None), # None if field is missing altogether
        connection_last_unsubscribe__lt=timezone.now() - datetime.timedelta(seconds=CHECK_ONLINE_USERS_RECONNECT_TIMEOUT),
    ):
        if models.User.objects(
            pk=user.pk,
            is_online=True,
            connections__in=([], None), # None if field is missing altogether
            connection_last_unsubscribe__lt=timezone.now() - datetime.timedelta(seconds=CHECK_ONLINE_USERS_RECONNECT_TIMEOUT),
        ).update(set__is_online=False):
            # On user disconnect we cycle channel_id, this is to improve security if somebody
            # intercepted current channel_id as there is no authentication on HTTP push channels
            # This is the best place to cycle channel_id as we know that user does not listen
            # anymore to any channel
            user.reload()
            user.channel_id = models.generate_channel_id()
            user.save()

            updates.send_update(
                HOME_CHANNEL_ID,
                {
                    'type': 'user_disconnect',
                    'user': {
                        'username': user.username,
                        'profile_url': user.get_absolute_url(),
                        'image_url': user.get_image_url(),
                    },
                }
            )
Example #4
0
def check_online_users():
    for user in models.User.objects(
            is_online=False,
            connections__not__in=
        (
            [], None
        ),  # None if field is missing altogether, not__in seems not to be equal to nin
    ):
        if models.User.objects(
                pk=user.pk,
                is_online=False,
                connections__not__in=
            (
                [], None
            ),  # None if field is missing altogether, not__in seems not to be equal to nin
        ).update(set__is_online=True):
            updates.send_update(
                views.HOME_CHANNEL_ID, {
                    'type': 'user_connect',
                    'user': {
                        'username': user.username,
                        'profile_url': user.get_profile_url(),
                        'image_url': user.get_image_url(),
                    },
                })

    for user in models.User.objects(
            is_online=True,
            connections__in=([], None),  # None if field is missing altogether
            connection_last_unsubscribe__lt=timezone.now() -
            datetime.timedelta(seconds=CHECK_ONLINE_USERS_RECONNECT_TIMEOUT),
    ):
        if models.User.objects(
                pk=user.pk,
                is_online=True,
                connections__in=([],
                                 None),  # None if field is missing altogether
                connection_last_unsubscribe__lt=timezone.now() -
                datetime.timedelta(
                    seconds=CHECK_ONLINE_USERS_RECONNECT_TIMEOUT),
        ).update(set__is_online=False):
            updates.send_update(
                views.HOME_CHANNEL_ID, {
                    'type': 'user_disconnect',
                    'user': {
                        'username': user.username,
                        'profile_url': user.get_absolute_url(),
                        'image_url': user.get_image_url(),
                    },
                })
Example #5
0
def send_update_on_new_post(sender, post, request, bundle, **kwargs):
    """
    Sends update to push server when a new post is created.
    """
    if post.is_published:
        output_bundle = sender.full_dehydrate(bundle)
        output_bundle = sender.alter_detail_data_to_serialize(request, output_bundle)

        serialized = sender.serialize(request, {
            'type': 'post_new',
            'post': output_bundle.data,
        }, 'application/json')

        updates.send_update(HOME_CHANNEL_ID, serialized, True)
Example #6
0
def check_online_users():
    for user in models.User.objects(
        is_online=False,
        connections__not__in=([], None), # None if field is missing altogether, not__in seems not to be equal to nin
    ):
        if models.User.objects(
            pk=user.pk,
            is_online=False,
            connections__not__in=([], None), # None if field is missing altogether, not__in seems not to be equal to nin
        ).update(set__is_online=True):
            updates.send_update(
                views.HOME_CHANNEL_ID,
                {
                    'type': 'userlist',
                    'action': 'JOIN',
                    'user': {
                        'username': user.username,
                        'profile_url': user.get_profile_url(),
                        'image_url': user.get_image_url(),
                    },
                }
            )

    for user in models.User.objects(
        is_online=True,
        connections__in=([], None), # None if field is missing altogether
        connection_last_unsubscribe__lt=timezone.now() - datetime.timedelta(seconds=CHECK_ONLINE_USERS_RECONNECT_TIMEOUT),
    ):
        if models.User.objects(
            pk=user.pk,
            is_online=True,
            connections__in=([], None), # None if field is missing altogether
            connection_last_unsubscribe__lt=timezone.now() - datetime.timedelta(seconds=CHECK_ONLINE_USERS_RECONNECT_TIMEOUT),
        ).update(set__is_online=False):
            updates.send_update(
                views.HOME_CHANNEL_ID,
                {
                    'type': 'userlist',
                    'action': 'PART',
                    'user': {
                        'username': user.username,
                        'profile_url': user.get_absolute_url(),
                        'image_url': user.get_image_url(),
                    },
                }
            )
Example #7
0
def send_update_on_new_post(serialized_update):
    updates.send_update(HOME_CHANNEL_ID, serialized_update, True)
Example #8
0
def send_update(serialized_update):
    updates.send_update(HOME_CHANNEL_ID, serialized_update, True)