# Path: django_private_chat/utils.py
# async def get_user_from_session(session_key):
#     """
#     Gets the user from current User model using the passed session_key
#     :param session_key: django.contrib.sessions.models.Session - session_key
#     :return: User instance or None if not found
#     """
#     session = Session.objects.get(session_key=session_key)
#     if session:
#         session_data = session.get_decoded()
#         uid = session_data.get('_auth_user_id')
#         user = get_user_model().objects.filter(id=uid).first()  # get object or none
#         return user
#     else:
#         return None
# 
# def get_dialogs_with_user(user_1, user_2):
#     """
#     gets the dialog between user_1 and user_2
#     :param user_1: the first user in dialog (owner or opponent)
#     :param user_2: the second user in dialog (owner or opponent)
#     :return: queryset which include dialog between user_1 and user_2 (queryset can be empty)
#     """
#     return Dialog.objects.filter(
#         Q(owner=user_1, opponent=user_2) | Q(opponent=user_1, owner=user_2))


import asyncio
import json
import logging
import websockets
from django.contrib.auth import get_user_model
from . import models, router
from .utils import get_user_from_session, get_dialogs_with_user
        session_id = packet.get('session_key')
        opponent_username = packet.get('username')
        if session_id and opponent_username:
            user_owner = await get_user_from_session(session_id)
            if user_owner:
                # Find all connections including user_owner as opponent
                online_opponents = list(filter(lambda x: x[1] == user_owner.username, ws_connections))
                logger.debug('User ' + user_owner.username + ' has ' + str(len(online_opponents)) + ' opponents online')
                # Send user online statuses of his opponents
                socket = ws_connections.get((user_owner.username, opponent_username))
                if socket:
                    online_opponents_usernames = [i[0] for i in online_opponents]
                    await target_message(socket, {'type': 'gone-online', 'usernames': online_opponents_usernames})
                else:
                    pass  # socket for the pair user_owner.username, opponent_username not found
                    # this can be in case the user has already gone offline
            else:
                pass  # invalid session id
        else:
            pass  # no session id or opponent username


async def gone_offline(stream):
    """
    Distributes the users online status to everyone he has dialog with
    """
    while True:
        packet = await stream.get()
        session_id = packet.get('session_key')
        if session_id:

# Path: django_private_chat/utils.py
# async def get_user_from_session(session_key):
#     """
#     Gets the user from current User model using the passed session_key
#     :param session_key: django.contrib.sessions.models.Session - session_key
#     :return: User instance or None if not found
#     """
#     session = Session.objects.get(session_key=session_key)
#     if session:
#         session_data = session.get_decoded()
#         uid = session_data.get('_auth_user_id')
#         user = get_user_model().objects.filter(id=uid).first()  # get object or none
#         return user
#     else:
#         return None
# 
# def get_dialogs_with_user(user_1, user_2):
#     """
#     gets the dialog between user_1 and user_2
#     :param user_1: the first user in dialog (owner or opponent)
#     :param user_2: the second user in dialog (owner or opponent)
#     :return: queryset which include dialog between user_1 and user_2 (queryset can be empty)
#     """
#     return Dialog.objects.filter(
#         Q(owner=user_1, opponent=user_2) | Q(opponent=user_1, owner=user_2))


# Path: django_private_chat/handlers.py
import asyncio
import json
import logging
import websockets
from django.contrib.auth import get_user_model
from . import models, router
from .utils import get_user_from_session, get_dialogs_with_user

        session_id = packet.get('session_key')
        opponent_username = packet.get('username')
        if session_id and opponent_username:
            user_owner = await get_user_from_session(session_id)
            if user_owner:
                # Find all connections including user_owner as opponent
                online_opponents = list(filter(lambda x: x[1] == user_owner.username, ws_connections))
                logger.debug('User ' + user_owner.username + ' has ' + str(len(online_opponents)) + ' opponents online')
                # Send user online statuses of his opponents
                socket = ws_connections.get((user_owner.username, opponent_username))
                if socket:
                    online_opponents_usernames = [i[0] for i in online_opponents]
                    await target_message(socket, {'type': 'gone-online', 'usernames': online_opponents_usernames})
                else:
                    pass  # socket for the pair user_owner.username, opponent_username not found
                    # this can be in case the user has already gone offline
            else:
                pass  # invalid session id
        else:
            pass  # no session id or opponent username


async def gone_offline(stream):
    """
    Distributes the users online status to everyone he has dialog with
    """
    while True:
        packet = await stream.get()
        session_id = packet.get('session_key')
        if session_id:

            user_owner = await get_user_from_session(session_id)