Example #1
0
    def upload_profile_image(self, files):
        """
		POST only, validates email during registration
		"""
        input_file = files['file']
        up = UserProfile(photo=input_file, id=self.user_id)
        create_thumbnail(input_file, up)
        up.save(update_fields=('photo', 'thumbnail'))
        up = UserProfile.objects.values('sex', 'thumbnail', 'photo',
                                        'username').get(id=self.user_id)
        payload = {
            VarNames.HANDLER_NAME: HandlerNames.WS,
            VarNames.EVENT: Actions.USER_PROFILE_CHANGED
        }
        payload.update(
            RedisPrefix.set_js_user_structure(
                self.user_id,
                up['username'],
                up['sex'],
                get_thumbnail_url(up['thumbnail']),
            ))
        global_redis.sync_redis.publish(settings.ALL_ROOM_ID,
                                        json.dumps(payload))
        global_redis.sync_redis.publish(
            RedisPrefix.generate_user(self.user_id),
            json.dumps({
                VarNames.HANDLER_NAME: HandlerNames.WS,
                VarNames.EVENT: Actions.SET_PROFILE_IMAGE,
                VarNames.CONTENT: get_thumbnail_url(up['photo']),
            }))
        return settings.VALIDATION_IS_OK
Example #2
0
 def invite_user(self, message):
     room_id = message[VarNames.ROOM_ID]
     user_id = message[VarNames.USER_ID]
     room = get_or_create_room(self.channels, room_id, user_id)
     users_in_room = {
         user.id: RedisPrefix.set_js_user_structure(user.username, user.sex)
         for user in room.users.all()
     }
     self.publish(
         self.add_user_to_room(room_id, user_id, users_in_room[user_id]),
         room_id)
     subscribe_message = self.invite_room_channel_message(
         room_id, user_id, room.name, users_in_room)
     self.publish(subscribe_message, RedisPrefix.generate_user(user_id),
                  True)
Example #3
0
	def save_channels_settings(self, message):
		channel_id = message[VarNames.CHANNEL_ID]
		channel_name = message[VarNames.CHANNEL_NAME]
		new_creator = message[VarNames.CHANNEL_CREATOR_ID]
		if not channel_name or len(channel_name) > 16:
			raise ValidationError('Incorrect channel name name "{}"'.format(channel_name))
		channel = Channel.objects.get(id=channel_id)
		users_id = list(RoomUsers.objects.filter(room__channel_id=channel_id).values_list('user_id', flat=True))
		if channel.creator_id != self.user_id and self.user_id not in users_id:
			raise ValidationError("You are not allowed to edit this channel")
		if new_creator != channel.creator_id:
			if self.user_id != channel.creator_id:
				raise ValidationError("Only admin can change the admin of this channel")
			if new_creator not in users_id:
				raise ValidationError("You can only change admin to one of the users in this channels room")
			channel.creator_id = new_creator
		if self.user_id not in users_id: # if channel has no rooms
			users_id.append(self.user_id)
		channel.name = channel_name
		channel.save()
		m = {
			VarNames.EVENT: Actions.SAVE_CHANNEL_SETTINGS,
			VarNames.CHANNEL_ID: channel_id,
			VarNames.CB_BY_SENDER: self.id,
			VarNames.HANDLER_NAME: HandlerNames.ROOM,
			VarNames.CHANNEL_NAME: channel_name,
			VarNames.CHANNEL_CREATOR_ID: channel.creator_id,
			VarNames.TIME: get_milliseconds(),
			VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
		}
		for user_id in users_id:
			self.publish(m, RedisPrefix.generate_user(user_id))
Example #4
0
def get_users_in_current_user_rooms(user_id):
	user_rooms = Room.objects.filter(users__id=user_id, disabled=False).values('id', 'name', 'roomusers__notifications', 'roomusers__volume')
	res = MessagesCreator.create_user_rooms(user_rooms)
	room_ids = (room_id for room_id in res)
	rooms_users = User.objects.filter(rooms__in=room_ids).values('id', 'username', 'sex', 'rooms__id')
	for user in rooms_users:
		dict = res[user['rooms__id']][VarNames.ROOM_USERS]
		dict[user['id']] = RedisPrefix.set_js_user_structure(user['username'], user['sex'])
	return res
Example #5
0
 def create_user_channel(self, message):
     user_id = message[VarNames.USER_ID]
     room_id = create_room(self.user_id, user_id)
     subscribe_message = self.subscribe_direct_channel_message(
         room_id, user_id, self.user_id != user_id)
     self.publish(subscribe_message, self.channel, True)
     other_channel = RedisPrefix.generate_user(user_id)
     if self.channel != other_channel:
         self.publish(subscribe_message, other_channel, True)
Example #6
0
	def upload_profile_image(self, files):
		"""
		POST only, validates email during registration
		"""
		up = UserProfile(photo=files['file'], id=self.user_id)
		up.save(update_fields=('photo',))
		url = up.photo.url
		message = json.dumps(MessagesCreator.set_profile_image(url))
		channel = RedisPrefix.generate_user(self.user_id)
		global_redis.sync_redis.publish(channel, message)
		return settings.VALIDATION_IS_OK
Example #7
0
	def invite_user(self, message):
		room_id = message[VarNames.ROOM_ID]
		if room_id not in self.channels:
			raise ValidationError("Access denied, only allowed for channels {}".format(self.channels))
		room = Room.objects.get(id=room_id)
		if room.is_private:
			raise ValidationError("You can't add users to direct room, create a new room instead")
		users = message.get(VarNames.ROOM_USERS)
		users_in_room = list(RoomUsers.objects.filter(room_id=room_id).values_list('user_id', flat=True))
		intersect = set(users_in_room) & set(users)
		if bool(intersect):
			raise ValidationError("Users %s are already in the room", intersect)
		users_in_room.extend(users)

		max_id = Message.objects.filter(room_id=room_id).aggregate(Max('id'))['id__max']
		if not max_id:
			max_id = Message.objects.all().aggregate(Max('id'))['id__max']
		ru = [RoomUsers(
			user_id=user_id,
			room_id=room_id,
			last_read_message_id=max_id,
			volume=1,
			notifications=False
		) for user_id in users]
		RoomUsers.objects.bulk_create(ru)

		add_invitee = {
			VarNames.EVENT: Actions.ADD_INVITE,
			VarNames.ROOM_ID: room_id,
			VarNames.ROOM_USERS: users_in_room,
			VarNames.ROOM_NAME: room.name,
			VarNames.INVITEE_USER_ID: users,
			VarNames.INVITER_USER_ID: self.user_id,
			VarNames.HANDLER_NAME: HandlerNames.ROOM,
			VarNames.TIME: get_milliseconds(),
			VarNames.VOLUME: 1,
			VarNames.NOTIFICATIONS: False,
		}
		add_invitee_dumped = encode_message(add_invitee, True)
		for user in users:
			self.raw_publish(add_invitee_dumped, RedisPrefix.generate_user(user))

		invite = {
			VarNames.EVENT: Actions.INVITE_USER,
			VarNames.ROOM_ID: room_id,
			VarNames.INVITEE_USER_ID: users,
			VarNames.INVITER_USER_ID: self.user_id,
			VarNames.HANDLER_NAME: HandlerNames.ROOM,
			VarNames.ROOM_USERS: users_in_room,
			VarNames.TIME: get_milliseconds(),
			VarNames.CB_BY_SENDER: self.id,
			VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID]
		}
		self.publish(invite, room_id, True)
Example #8
0
def upload_profile_image(request):
    """
	POST only, validates email during registration
	"""

    up = UserProfile(photo=request.FILES['file'], id=request.user.id)
    up.save(update_fields=('photo', ))
    url = up.photo.url
    message = json.dumps(MessagesCreator.set_profile_image(url))
    channel = RedisPrefix.generate_user(request.user.id)
    global_redis.sync_redis.publish(channel, message)
    return HttpResponse(settings.VALIDATION_IS_OK, content_type='text/plain')
Example #9
0
    def register(self, username, password, email, sex):
        check_user(username)
        self.__check_password(password)
        self.__check_email__(email)
        user_profile = UserProfile(username=username, email=email, sex_str=sex)
        user_profile.set_password(password)
        user_profile.save()
        RoomUsers(user_id=user_profile.id,
                  room_id=settings.ALL_ROOM_ID,
                  notifications=False).save()

        user_data = {
            VarNames.ROOMS: [{
                VarNames.ROOM_ID:
                settings.ALL_ROOM_ID,
                VarNames.ROOM_USERS:
                list(
                    RoomUsers.objects.filter(room_id=ALL_ROOM_ID).values_list(
                        'user_id', flat=True))
            }],
            VarNames.EVENT:
            Actions.CREATE_NEW_USER,
            VarNames.HANDLER_NAME:
            HandlerNames.ROOM,
        }
        user_data.update(
            RedisPrefix.set_js_user_structure(user_profile.id,
                                              user_profile.username,
                                              user_profile.sex, None))
        global_redis.async_redis_publisher.publish(
            settings.ALL_ROOM_ID,
            json.dumps(user_data),
        )

        if email:
            yield from self.__send_sign_up_email(user_profile)
        return MessagesCreator.get_session(
            self.__generate_session__(user_profile.id))
Example #10
0
    def save_room_settings(self, message):
        """
		POST only, validates email during registration
		"""
        room_id = message[VarNames.ROOM_ID]
        room_name = message[VarNames.ROOM_NAME]
        creator_id = message.get(
            VarNames.ROOM_CREATOR_ID)  # will be none for private room
        updated = RoomUsers.objects.filter(
            room_id=room_id, user_id=self.user_id).update(
                volume=message[VarNames.VOLUME],
                notifications=message[VarNames.NOTIFICATIONS])
        if updated != 1:
            raise ValidationError("You don't have access to this room")
        room = Room.objects.get(id=room_id)
        update_all = False
        if not room.name:
            if room.p2p != message[VarNames.P2P]:
                room.p2p = message[VarNames.P2P]
                update_all = True
        elif room_id != settings.ALL_ROOM_ID:
            if room_name != room.name:
                room.name = room_name
                update_all = True

            if room.channel_id != message[VarNames.CHANNEL_ID]:
                room.channel_id = message[VarNames.CHANNEL_ID]
                if room.channel_id and room.channel_id not in self.get_users_channels_ids(
                ):
                    raise ValidationError(
                        "You don't have access to this channel")
                update_all = True
            if creator_id != room.creator_id:
                if room.creator_id != self.user_id:
                    raise ValidationError(
                        "Only an owner of this room can change its admin")
                users_id = RoomUsers.objects.filter(
                    room_id=room.id).values_list('user_id', flat=True)
                if creator_id not in users_id:
                    raise ValidationError(
                        "You can only change admin to one of the users in this channels room"
                    )
                room.creator_id = creator_id
                update_all = True
        if message.get(VarNames.CHANNEL_ID):  # will be nOne for private room
            channel = Channel.objects.get(id=message[VarNames.CHANNEL_ID])
            channel_name = channel.name
            channel_creator_id = channel.creator_id
        else:
            channel_name = None
            channel_creator_id = None
        if update_all:
            room.save()
            room_users = list(RoomUsers.objects.filter(room_id=room_id))
            for room_user in room_users:
                self.publish(
                    {
                        VarNames.EVENT: Actions.SAVE_ROOM_SETTINGS,
                        VarNames.CHANNEL_ID: room.channel_id,
                        VarNames.CB_BY_SENDER: self.id,
                        VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
                        VarNames.CHANNEL_NAME: channel_name,
                        VarNames.CHANNEL_CREATOR_ID: channel_creator_id,
                        VarNames.ROOM_CREATOR_ID: room.creator_id,
                        VarNames.ROOM_ID: room.id,
                        VarNames.VOLUME: room_user.volume,
                        VarNames.NOTIFICATIONS: room_user.notifications,
                        VarNames.P2P: message[VarNames.P2P],
                        VarNames.ROOM_NAME: room_name,
                        VarNames.TIME: get_milliseconds(),
                        VarNames.JS_MESSAGE_ID:
                        message[VarNames.JS_MESSAGE_ID],
                    }, RedisPrefix.generate_user(room_user.user_id))
        else:
            self.publish(
                {
                    VarNames.EVENT: Actions.SAVE_ROOM_SETTINGS,
                    VarNames.CHANNEL_ID: room.channel_id,
                    VarNames.CB_BY_SENDER: self.id,
                    VarNames.CHANNEL_CREATOR_ID: channel_creator_id,
                    VarNames.ROOM_CREATOR_ID: room.creator_id,
                    VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
                    VarNames.CHANNEL_NAME: channel_name,
                    VarNames.ROOM_ID: room.id,
                    VarNames.VOLUME: message[VarNames.VOLUME],
                    VarNames.NOTIFICATIONS: message[VarNames.NOTIFICATIONS],
                    VarNames.P2P: message[VarNames.P2P],
                    VarNames.ROOM_NAME: room_name,
                    VarNames.TIME: get_milliseconds(),
                    VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
                }, self.channel)
Example #11
0
    def create_new_room(self, message):
        room_name = message.get(VarNames.ROOM_NAME)
        users = message.get(VarNames.ROOM_USERS)
        channel_id = message.get(VarNames.CHANNEL_ID)
        users.append(self.user_id)
        users = list(set(users))
        if room_name and len(room_name) > 16:
            raise ValidationError('Incorrect room name "{}"'.format(room_name))
        create_room = True
        if not room_name and len(users) == 2:
            user_rooms = evaluate(
                Room.users.through.objects.filter(
                    user_id=self.user_id,
                    room__name__isnull=True).values('room_id'))
            user_id = users[0] if users[1] == self.user_id else users[1]
            try:
                room = RoomUsers.objects.filter(user_id=user_id,
                                                room__in=user_rooms).values(
                                                    'room__id',
                                                    'room__disabled').get()
                room_id = room['room__id']
                if room['room__disabled']:  # only a private room can be disabled
                    Room.objects.filter(id=room_id).update(
                        disabled=False, p2p=message[VarNames.P2P])
                    RoomUsers.objects.filter(
                        user_id=self.user_id, room_id=room_id).update(
                            volume=message[VarNames.VOLUME],
                            notifications=message[VarNames.NOTIFICATIONS])
                else:
                    raise ValidationError('This room already exist')
                create_room = False
            except RoomUsers.DoesNotExist:
                pass
        elif not room_name:
            raise ValidationError(
                'At least one user should be selected, or room should be public'
            )

        if channel_id and channel_id not in self.get_users_channels_ids():
            raise ValidationError("You don't have access to this channel")
        if channel_id:
            channel = Channel.objects.get(id=channel_id)
            channel_name = channel.name
            channel_creator_id = channel.creator_id
        else:
            channel_name = None
            channel_creator_id = None
        if create_room:
            room = Room(name=room_name,
                        channel_id=channel_id,
                        p2p=message[VarNames.P2P])
            if not room_name:
                room.creator_id = self.user_id
            room.save()
            room_id = room.id
            max_id = Message.objects.all().aggregate(Max('id'))['id__max']
            ru = [
                RoomUsers(user_id=user_id,
                          room_id=room_id,
                          last_read_message_id=max_id,
                          volume=message[VarNames.VOLUME],
                          notifications=message[VarNames.NOTIFICATIONS])
                for user_id in users
            ]
            RoomUsers.objects.bulk_create(ru)

        m = {
            VarNames.EVENT: Actions.CREATE_ROOM,
            VarNames.ROOM_ID: room_id,
            VarNames.ROOM_USERS: users,
            VarNames.CB_BY_SENDER: self.id,
            VarNames.INVITER_USER_ID: self.user_id,
            VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
            VarNames.VOLUME: message[VarNames.VOLUME],
            VarNames.P2P: message[VarNames.P2P],
            VarNames.NOTIFICATIONS: message[VarNames.NOTIFICATIONS],
            VarNames.ROOM_NAME: room_name,
            VarNames.TIME: get_milliseconds(),
            VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
        }
        if channel_id:
            m[VarNames.CHANNEL_NAME] = channel_name
            m[VarNames.CHANNEL_ID] = channel_id
            m[VarNames.CHANNEL_CREATOR_ID] = channel_creator_id
        jsoned_mess = encode_message(m, True)
        for user in users:
            self.raw_publish(jsoned_mess, RedisPrefix.generate_user(user))
Example #12
0
    def create_new_room(self, message):
        room_name = message.get(VarNames.ROOM_NAME)
        users = message.get(VarNames.ROOM_USERS)
        users.append(self.user_id)
        users = list(set(users))
        if room_name and len(room_name) > 16:
            raise ValidationError('Incorrect room name "{}"'.format(room_name))
        create_user_rooms = True
        if not room_name and len(users) == 2:
            user_rooms = evaluate(
                Room.users.through.objects.filter(
                    user_id=self.user_id,
                    room__name__isnull=True).values('room_id'))
            user_id = users[0] if users[1] == self.user_id else users[1]
            try:
                room = RoomUsers.objects.filter(user_id=user_id,
                                                room__in=user_rooms).values(
                                                    'room__id',
                                                    'room__disabled').get()
                room_id = room['room__id']
                if room['room__disabled']:
                    Room.objects.filter(id=room_id).update(disabled=False)
                else:
                    raise ValidationError('This room already exist')
                create_user_rooms = False
            except RoomUsers.DoesNotExist:
                pass
        elif not room_name:
            raise ValidationError(
                'At least one user should be selected, or room should be public'
            )
        if create_user_rooms:
            room = Room(name=room_name)
            do_db(room.save)
            room_id = room.id
            max_id = Message.objects.all().aggregate(Max('id'))['id__max']
            ru = [
                RoomUsers(user_id=user_id,
                          room_id=room_id,
                          last_read_message_id=max_id,
                          volume=message[VarNames.VOLUME],
                          notifications=message[VarNames.NOTIFICATIONS])
                for user_id in users
            ]
            RoomUsers.objects.bulk_create(ru)

        m = {
            VarNames.EVENT: Actions.CREATE_ROOM_CHANNEL,
            VarNames.ROOM_ID: room_id,
            VarNames.ROOM_USERS: users,
            VarNames.CB_BY_SENDER: self.id,
            VarNames.INVITER_USER_ID: self.user_id,
            VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
            VarNames.VOLUME: message[VarNames.VOLUME],
            VarNames.NOTIFICATIONS: message[VarNames.NOTIFICATIONS],
            VarNames.ROOM_NAME: room_name,
            VarNames.TIME: get_milliseconds(),
            VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
        }
        jsoned_mess = encode_message(m, True)
        for user in users:
            self.raw_publish(jsoned_mess, RedisPrefix.generate_user(user))
Example #13
0
    def open(self):
        session_key = self.get_argument('sessionId', None)
        user_id = self.sync_redis.hget('sessions', session_key)
        if user_id is None:
            self.logger.warning('!! Session key %s has been rejected' %
                                session_key)
            self.close(403, "Session key %s has been rejected" % session_key)
            return
        self.user_id = int(user_id)
        self.ip = self.get_client_ip()
        user_db = UserProfile.objects.get(id=self.user_id)
        self.generate_self_id()
        self.message_creator = WebRtcMessageCreator(self.user_id, self.id)
        self._logger = logging.LoggerAdapter(parent_logger, {
            'id': self.id,
            'ip': self.ip
        })
        self.logger.debug("!! Incoming connection, session %s, thread hash %s",
                          session_key, self.id)
        self.async_redis.connect()
        self.async_redis_publisher.sadd(RedisPrefix.ONLINE_VAR, self.id)
        # since we add user to online first, latest trigger will always show correct online

        online = self.get_dict_users_from_redis()
        # current user is already online
        my_online = online.setdefault(self.user_id, [])
        if self.id not in my_online:
            my_online.append(self.id)

        was_online = len(online.get(
            self.user_id)) > 1  # if other tabs are opened
        user_rooms_query = Room.objects.filter(users__id=self.user_id, disabled=False) \
         .values('id', 'name', 'creator_id', 'channel_id', 'p2p', 'roomusers__notifications', 'roomusers__volume')
        room_users = [{
            VarNames.ROOM_ID: room['id'],
            VarNames.ROOM_NAME: room['name'],
            VarNames.CHANNEL_ID: room['channel_id'],
            VarNames.ROOM_CREATOR_ID: room['creator_id'],
            VarNames.NOTIFICATIONS: room['roomusers__notifications'],
            VarNames.P2P: room['p2p'],
            VarNames.VOLUME: room['roomusers__volume'],
            VarNames.ROOM_USERS: []
        } for room in user_rooms_query]
        user_rooms_dict = {room[VarNames.ROOM_ID]: room for room in room_users}
        channels_ids = [
            channel[VarNames.CHANNEL_ID] for channel in room_users
            if channel[VarNames.CHANNEL_ID]
        ]
        channels_db = Channel.objects.filter(Q(id__in=channels_ids)
                                             | Q(creator=self.user_id),
                                             disabled=False)
        channels = [{
            VarNames.CHANNEL_ID: channel.id,
            VarNames.CHANNEL_NAME: channel.name,
            VarNames.CHANNEL_CREATOR_ID: channel.creator_id
        } for channel in channels_db]
        room_ids = [room_id[VarNames.ROOM_ID] for room_id in room_users]
        rooms_users = RoomUsers.objects.filter(room_id__in=room_ids).values(
            'user_id', 'room_id')
        for ru in rooms_users:
            user_rooms_dict[ru['room_id']][VarNames.ROOM_USERS].append(
                ru['user_id'])
        # get all missed messages
        self.channels = room_ids  # py2 doesn't support clear()
        self.channels.append(self.channel)
        self.channels.append(self.id)
        self.listen(self.channels)
        # this was replaced to syncHistory method that's called from browser and passes existing ids
        # off_messages, history = self.get_offline_messages(room_users, was_online, self.get_argument('history', False))
        # for room in room_users:
        # 	room_id = room[VarNames.ROOM_ID]
        # 	h = history.get(room_id)
        # 	o = off_messages.get(room_id)
        # 	if h:
        # 		room[VarNames.LOAD_MESSAGES_HISTORY] = h
        # 	if o:
        # 		room[VarNames.LOAD_MESSAGES_OFFLINE] = o

        if settings.SHOW_COUNTRY_CODE:
            fetched_users = User.objects.annotate(user_c=Count('id')).values(
                'id', 'username', 'sex', 'userjoinedinfo__ip__country_code',
                'userjoinedinfo__ip__country', 'userjoinedinfo__ip__region',
                'userjoinedinfo__ip__city')
            user_dict = [
                RedisPrefix.set_js_user_structure_flag(
                    user['id'], user['username'], user['sex'],
                    user['userjoinedinfo__ip__country_code'],
                    user['userjoinedinfo__ip__country'],
                    user['userjoinedinfo__ip__region'],
                    user['userjoinedinfo__ip__city']) for user in fetched_users
            ]
        else:
            fetched_users = User.objects.values('id', 'username', 'sex')
            user_dict = [
                RedisPrefix.set_js_user_structure(user['id'], user['username'],
                                                  user['sex'])
                for user in fetched_users
            ]

        self.ws_write(
            self.message_creator.set_room(room_users, user_dict, online,
                                          user_db, channels))
        online_user_names_mes = self.message_creator.room_online_login(
            online, user_db.username, user_db.sex_str)
        self.logger.info('!! First tab, sending refresh online for all')
        self.publish(online_user_names_mes, settings.ALL_ROOM_ID)
        self.logger.info("!! User %s subscribes for %s", self.user_id,
                         self.channels)
        self.connected = True
Example #14
0
	def channel(self):
		return RedisPrefix.generate_user(self.user_id)
    def open(self):
        session_key = self.get_argument('sessionId', None)
        user_id = self.sync_redis.hget('sessions', session_key)
        if user_id is None:
            self.logger.warning('!! Session key %s has been rejected' %
                                session_key)
            self.close(403, "Session key %s has been rejected" % session_key)
            return
        self.user_id = int(user_id)
        self.ip = self.get_client_ip()
        user_db = UserProfile.objects.get(id=self.user_id)
        self.generate_self_id()
        self._logger = logging.LoggerAdapter(parent_logger, {
            'id': self.id,
            'ip': self.ip
        })
        self.logger.debug("!! Incoming connection, session %s, thread hash %s",
                          session_key, self.id)
        self.async_redis.connect()
        self.async_redis_publisher.sadd(RedisPrefix.ONLINE_VAR, self.id)
        # since we add user to online first, latest trigger will always show correct online
        was_online, online = self.get_online_and_status_from_redis()
        user_rooms_query = Room.objects.filter(users__id=self.user_id, disabled=False) \
         .values('id', 'name', 'roomusers__notifications', 'roomusers__volume')
        room_users = [{
            VarNames.ROOM_ID: room['id'],
            VarNames.ROOM_NAME: room['name'],
            VarNames.NOTIFICATIONS: room['roomusers__notifications'],
            VarNames.VOLUME: room['roomusers__volume'],
            VarNames.ROOM_USERS: []
        } for room in user_rooms_query]
        user_rooms_dict = {room[VarNames.ROOM_ID]: room for room in room_users}
        room_ids = [room_id[VarNames.ROOM_ID] for room_id in room_users]
        rooms_users = RoomUsers.objects.filter(room_id__in=room_ids).values(
            'user_id', 'room_id')
        for ru in rooms_users:
            user_rooms_dict[ru['room_id']][VarNames.ROOM_USERS].append(
                ru['user_id'])
        # get all missed messages
        self.channels = room_ids  # py2 doesn't support clear()
        self.channels.append(self.channel)
        self.channels.append(self.id)
        self.listen(self.channels)
        off_messages, history = self.get_offline_messages(
            room_users, was_online, self.get_argument('history', False))
        for room in room_users:
            room_id = room[VarNames.ROOM_ID]
            h = history.get(room_id)
            o = off_messages.get(room_id)
            if h:
                room[VarNames.LOAD_MESSAGES_HISTORY] = h
            if o:
                room[VarNames.LOAD_MESSAGES_OFFLINE] = o

        if settings.SHOW_COUNTRY_CODE:
            fetched_users = User.objects.annotate(user_c=Count('id')).values(
                'id', 'username', 'sex', 'userjoinedinfo__ip__country_code',
                'userjoinedinfo__ip__country', 'userjoinedinfo__ip__region',
                'userjoinedinfo__ip__city')
            user_dict = [
                RedisPrefix.set_js_user_structure_flag(
                    user['id'], user['username'], user['sex'],
                    user['userjoinedinfo__ip__country_code'],
                    user['userjoinedinfo__ip__country'],
                    user['userjoinedinfo__ip__region'],
                    user['userjoinedinfo__ip__city']) for user in fetched_users
            ]
        else:
            fetched_users = User.objects.values('id', 'username', 'sex')
            user_dict = [
                RedisPrefix.set_js_user_structure(user['id'], user['username'],
                                                  user['sex'])
                for user in fetched_users
            ]
        if self.user_id not in online:
            online.append(self.user_id)

        self.ws_write(self.set_room(room_users, user_dict, online, user_db))
        if not was_online:  # if a new tab has been opened
            online_user_names_mes = self.room_online_login(
                online, user_db.username, user_db.sex_str)
            self.logger.info('!! First tab, sending refresh online for all')
            self.publish(online_user_names_mes, settings.ALL_ROOM_ID)
        self.logger.info("!! User %s subscribes for %s", self.user_id,
                         self.channels)
        self.connected = True