def on_send_play_object_id_command(object_id): now = datetime.utcnow() # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # find object item = mongo.db.objects.find_one({'id': object_id}, {'_id': False}) if not item: return json_not_found_error('OBJECT_NOT_FOUND', 'object not found') referenced_items = find_referenced_items(item) # send command log.debug( f"playing object {item} with {len(referenced_items)} referenced item(s)" ) socketio.emit('playobject', { 'time': now.timestamp(), 'object': item, 'loop': False, 'referenced': referenced_items }, room=target) return json_success("object playback command sent to " + target)
def on_show_menu(slot): # find target target = get_target(request.args) if not target: return json_bad_request_error('TARGET_MISSING', "target missing") # get parameters if 'visible' not in request.args: return json_bad_request_error('ARGUMENT_MISSING', 'no visibility argument specified') visibleParam = str(request.args.get('visible')).lower() if visibleParam in ['true', '1', 'yes']: visible = True elif visibleParam in ['false', '0', 'no']: visible = False else: return json_bad_request_error('INVALID_ARGUMENT', 'visibility argument invalid') # send command socketio.emit('showmenu', { 'time': datetime.utcnow().timestamp(), 'slot': slot, 'visible': visible }, room=target) return json_success("menu shown")
def on_play_scene_json(): # find visitor type visitor_type = get_visitor_type(request.args) visitor_type_id = visitor_type['id'] if visitor_type else None # find target target = get_target(request.args) # find avatar avatars = visitor_type['fields'][ 'avatar'] if visitor_type and 'fields' in visitor_type and 'avatar' in visitor_type[ 'fields'] else [] avatar_id = avatars[0] if avatars else None # execute scene scene = request.get_json() targets = [target] if target else [] now = datetime.utcnow() storyline = str(uuid.uuid4()) errors = execute_scene(now, scene, storyline, { 'individual': 'anyone', 'avatar': avatar_id }, targets) if errors: return json_action_execution_error(errors) else: return json_success("scene played")
def on_send_stop_command(): now = datetime.utcnow() # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # send command socketio.emit('stop', {'time': now.timestamp()}, room=target) return json_success("stop command sent to " + target)
def on_send_ping_command(): # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # send command now = datetime.utcnow() socketio.emit('pingbox', { 'target': target, 'time': now.timestamp() }, room=target) log.info("pinging target " + target) return json_success("ping command sent to " + target)
def on_send_play_story_command(): # find visitor type and target visitor_type = get_visitor_type(request.args) target = get_target(request.args) method = request.args.get('method') # execute story story = request.get_json() errors = execute_story(story, 'anyone', visitor_type, [target] if target else [], method == 'leave') if errors: return json_action_execution_error(errors) else: return json_success( f"story {'stopped' if method == 'leave' else 'started'} successfully" )
def on_send_show_notification_command(): now = datetime.utcnow() # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # send command text = request.args.get('text') socketio.emit('shownotification', { 'time': now.timestamp(), 'text': text }, room=target) return json_success("notification command sent to " + target)
def on_post_change_menu(slot): # find target target = get_target(request.args) if not target: return json_bad_request_error('TARGET_MISSING', "target missing") # send command menu = request.get_json() socketio.emit('changemenu', { 'time': datetime.utcnow().timestamp(), 'slot': slot, 'menu': menu, 'visible': True, 'referencedObjects': find_referenced_items(menu) }, room=target) return json_success("menu changed")
def on_send_play_media_url_command(): now = datetime.utcnow() # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # send command url = request.args.get('url') log.debug(f"playing media URL {url}") socketio.emit('playmedia', { 'time': now.timestamp(), 'url': url }, room=target) return json_success("media playback command sent to " + target)
def on_send_chat_text_command(): now = datetime.utcnow() # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # send command text = request.args.get('text') socketio.emit('chatmessage', { 'time': now.timestamp(), 'text': text, 'objects': [] }, room=target) return json_success("chat message command sent to " + target)
def on_send_adjust_volume_command(): now = datetime.utcnow() # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # get parameters if 'percent' not in request.args: return json_bad_request_error('ARGUMENT_MISSING', 'no volume argument specified') percent = request.args.get('percent') # send command socketio.emit('setvolume', { 'time': now.timestamp(), 'volume': percent }, room=target) return json_success("volume command sent to " + target)
def on_post_menu_action(menu_id, index): # parse index try: index_list = [int(i) for i in index.split(";")] except: return json_bad_request_error('INVALID_ARGUMENTS', 'arguments must be numeric') # get body data body = request.get_json() log.info(f"executing menu action {index} of {menu_id} with {body}") # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() targets = [target] # find object menu = mongo.db.objects.find_one({'id': menu_id}, {'_id': False}) if not menu or 'fields' not in menu: return json_not_found_error('MENU_NOT_FOUND', 'menu not found') log.debug(f"picked menu {menu}") menu_fields = menu['fields'] # find item item, parent = find_menu_item_and_parent_by_index_list(menu, index_list) if parent and parent.get('type') == 'menuobjectselection': item = parent if not item or 'fields' not in item: return json_not_acceptable_error('INVALID_ITEM', 'invalid menu item') item_fields = item.get('fields') or {} log.debug(f"picked item {item}") # alternative targets defined? # currently not possible and probably a bad idea # if 'target' in menu_fields and menu_fields['target']: # targets = menu_fields['target'] context = body.get('context') or {} if body else {} context['individual'] = context.get('individual') or 'anyone' # find visitor type visitor_type = get_visitor_type(request.args) visitor_type_id = visitor_type['id'] if visitor_type else None # find avatar avatars = visitor_type['fields'][ 'avatar'] if visitor_type and 'fields' in visitor_type and 'avatar' in visitor_type[ 'fields'] else [] avatar_id = avatars[0] if avatars else None context['avatar'] = avatar_id # find subjects if item['type'] == 'menuobjectselection': subject_ids = item_fields.get('items') or [] subject_id = subject_ids[index_list[-1]] context['subjects'] = [ mongo.db.objects.find_one({'id': subject_id}, {'_id': False}) ] # execute actions if item['type'] == 'submenu': header = item_fields.get('header') if header: header_fields = header[0].get('fields') or {} actions = header_fields.get('actions') or [] else: actions = [] else: actions = item_fields.get('actions') or [] additional_actions = menu_fields.get('additionalactions') or [] errors = schedule_actions(datetime.utcnow(), actions + additional_actions, None, None, context, targets) if errors: return json_action_execution_error(errors) else: return json_success("menu actions executed")
def on_answer_interaction(scene_id, index, answer): # validate arguments assert index >= 0 and answer >= 0 # get body data body = request.get_json() log.info(f"got interaction answer {answer} of {scene_id} with {body}") # find target target = get_target(request.args) if not target: return json_no_command_target_found_error() # find scene scene = mongo.db.objects.find_one({'id': scene_id}, {'_id': False}) if not scene or 'fields' not in scene: return json_not_found_error('SCENE_NOT_FOUND', 'scene not found') scene_fields = scene['fields'] if 'actions' not in scene_fields: return json_not_acceptable_error('INVALID_ANSWER', 'invalid answer') log.debug(f"picked scene {scene}") # find action actions = scene_fields['actions'] if not actions or index >= len(actions): return json_not_acceptable_error('INVALID_ANSWER', 'invalid answer') action = actions[index] if not action or 'fields' not in action or 'type' not in action or action[ 'type'] != 'interaction': return json_not_acceptable_error('INVALID_ANSWER', 'invalid answer') log.debug(f"picked action {action}") # find option action_fields = action['fields'] if 'options' not in action_fields: return json_not_acceptable_error('INVALID_ANSWER', 'invalid answer') options = action_fields['options'] if not options or answer >= len(options): return json_not_acceptable_error('INVALID_ANSWER', 'invalid answer') option = options[answer] if not option or 'fields' not in option or 'type' not in option or option[ 'type'] != 'interactioncase': return json_not_acceptable_error('INVALID_ANSWER', 'invalid answer') log.debug(f"picked option {option}") # find visitor type visitor_type = get_visitor_type(request.args) visitor_type_id = visitor_type['id'] if visitor_type else None # find avatar avatars = visitor_type['fields'][ 'avatar'] if visitor_type and 'fields' in visitor_type and 'avatar' in visitor_type[ 'fields'] else [] avatar_id = avatars[0] if avatars else None # execute option context = body.get('context') errors = execute_interaction_option(datetime.utcnow(), option, context, [target]) if errors: return json_action_execution_error(errors) else: return json_success("interaction executed")