def set_online(user_id: str, user_name: str, image: str = '') -> None: was_invisible = utils.user_is_invisible(user_id) OnStatusHooks.logger.info( 'setting user {} ({}) online (was invisible before? {})'.format( user_id, user_name, was_invisible)) environ.env.db.set_user_online(user_id) rooms = utils.rooms_for_user(user_id) if not was_invisible: for room_id in rooms: room_name = utils.get_room_name(room_id) join_activity = utils.activity_for_user_joined( user_id, user_name, room_id, room_name, image) environ.env.emit('gn_user_joined', join_activity, room=room_id, broadcast=True, include_self=False, namespace='/ws') return visible_activity = utils.activity_for_going_visible(user_id) for room_id in rooms: room_name = utils.get_room_name(room_id) join_activity = utils.activity_for_user_joined( user_id, user_name, room_id, room_name, image) admins_in_room = environ.env.db.get_admins_in_room( room_id, user_id) if admins_in_room is None or len(admins_in_room) == 0: environ.env.emit('gn_user_joined', join_activity, room=room_id, broadcast=True, include_self=False, namespace='/ws') continue users_in_room = utils.get_users_in_room(room_id).copy() for user_id_in_room, _ in users_in_room.items(): if user_id_in_room in admins_in_room: continue environ.env.emit('gn_user_joined', join_activity, room=user_id_in_room, broadcast=True, include_self=False, namespace='/ws') for admin_id in admins_in_room: environ.env.emit('gn_user_visible', visible_activity, room=admin_id, broadcast=False, namespace='/ws')
def set_invisible(user_id: str, user_name: str, stage: str) -> None: OnStatusHooks.logger.info('setting user {} ({}) to invisible'.format( user_id, user_name, )) # when logging in as 'invisible', the rest call can happen after ws # logs in, in which case we don't want to update last_online if stage == 'login': is_offline = True else: is_offline = not utils.user_is_online(user_id) environ.env.db.set_user_invisible(user_id, is_offline=is_offline) if is_offline: # nothing more to do if offline already return disconnect_activity = utils.activity_for_disconnect(user_id, user_name) rooms = utils.rooms_for_user(user_id) for room_id in rooms: admins_in_room = environ.env.db.get_admins_in_room( room_id, user_id) if admins_in_room is None or len(admins_in_room) == 0: environ.env.emit('gn_user_disconnected', disconnect_activity, room=room_id, broadcast=True, include_self=False, namespace='/ws') continue users_in_room = utils.get_users_in_room(room_id) for other_user_id, _ in users_in_room.items(): if other_user_id in admins_in_room: continue environ.env.emit('gn_user_disconnected', disconnect_activity, room=other_user_id, broadcast=True, include_self=False, namespace='/ws') invisible_activity = utils.activity_for_going_invisible(user_id) for admin_id in admins_in_room: environ.env.emit('gn_user_invisible', invisible_activity, room=admin_id, broadcast=False, namespace='/ws')
def set_offline(user_id: str, user_name: str) -> None: OnStatusHooks.logger.info('setting user {} ({}) to offline'.format( user_id, user_name, )) environ.env.db.set_user_offline(user_id) activity_json = utils.activity_for_disconnect(user_id, user_name) rooms = utils.rooms_for_user(user_id) for room_id in rooms: environ.env.emit('gn_user_disconnected', activity_json, room=room_id, broadcast=True, include_self=False, namespace='/ws')
def set_invisible(user_id: str, user_name: str) -> None: OnStatusHooks.logger.info('setting user {} ({}) to invisible'.format( user_id, user_name, )) is_offline = not utils.user_is_online(user_id) environ.env.db.set_user_invisible(user_id, is_offline=is_offline) if is_offline: # nothing more to do if offline already return disconnect_activity = utils.activity_for_disconnect(user_id, user_name) rooms = utils.rooms_for_user(user_id) for room_id in rooms: admins_in_room = environ.env.db.get_admins_in_room( room_id, user_id) if admins_in_room is None or len(admins_in_room) == 0: environ.env.emit('gn_user_disconnected', disconnect_activity, room=room_id, broadcast=True, include_self=False, namespace='/ws') continue users_in_room = utils.get_users_in_room(room_id) for other_user_id, _ in users_in_room.items(): if other_user_id in admins_in_room: continue environ.env.emit('gn_user_disconnected', disconnect_activity, room=other_user_id, broadcast=True, include_self=False, namespace='/ws') invisible_activity = utils.activity_for_going_invisible(user_id) for admin_id in admins_in_room: environ.env.emit('gn_user_invisible', invisible_activity, room=admin_id, broadcast=False, namespace='/ws')
def broadcast(arg: tuple) -> None: orig_data, activity = arg data = { 'actor': { 'id': activity.actor.id, 'displayName': activity.actor.display_name }, 'verb': 'update', 'object': { 'objectType': 'userInfo', 'attachments': list() }, 'id': activity.id, 'published': activity.published } if not hasattr(activity.object, 'attachments') or len( activity.object.attachments) == 0: logger.warning('empty object.attachments: %s' % str(orig_data)) return user_id = environ.env.session.get(SessionKeys.user_id.value, activity.actor.id) user_name = environ.env.session.get(SessionKeys.user_name.value, activity.actor.display_name) protected_keys = {SessionKeys.user_id.value, SessionKeys.token.value} for attachment in activity.object.attachments: if attachment.object_type in protected_keys: logger.warning( 'user "%s" (%s) tried to change protected key "%s", skipping' % attachment.object_type) decoded = utils.b64d(attachment.content) if attachment.object_type in SessionKeys._member_names_: environ.env.session[attachment.object_type] = decoded else: logger.warning( 'key "%s" is not a predefined, not updating session for "%s" (%s), value was "%s"' % (attachment.object_type, user_name, user_id, decoded)) environ.env.auth.update_session_for_key(user_id, attachment.object_type, decoded) data['object']['attachments'].append({ 'content': attachment.content, 'objectType': attachment.object_type, }) logger.info('about to send updated user info: %s' % str(data)) room_uuid = None if hasattr(activity, 'target') and hasattr(activity.target, 'id'): target_id = activity.target.id if target_id is not None and len(target_id.strip()) > 0: room_uuid = target_id if room_uuid is not None: environ.env.emit('gn_user_info_updated', data, json=True, broadcast=True, room=room_uuid, namespace='/ws') else: rooms = utils.rooms_for_user(activity.actor.id) for room_uuid in rooms: data_copy = data.copy() data_copy['target'] = {'id': room_uuid} environ.env.emit('gn_user_info_updated', data, json=True, broadcast=True, room=room_uuid, namespace='/ws')