Exemplo n.º 1
0
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_update_alive(sid):

    if 'type' not in request.args:
        return json_bad_request_error("ARGUMENT_MISSING",
                                      "device type missing")
    device_type = request.args['type']
    if device_type not in ['box', 'sensor', 'mobile']:
        return json_bad_request_error("INVALID_ARGUMENT",
                                      "invalid device type")

    if 'name' not in request.args:
        return json_bad_request_error("ARGUMENT_MISSING",
                                      "device name missing")
    device_name = request.args['name']

    now = datetime.utcnow().timestamp()
    if sid not in socketio_sessions:
        socketio_sessions[sid] = {'sid': sid, 'connect_time': now, 'env': {}}
    socketio_sessions[sid]['type'] = device_type
    socketio_sessions[sid]['name'] = device_name
    socketio_sessions[sid]['connected'] = True
    socketio_sessions[sid]['alive_time'] = now
    socketio_sessions[sid]['env']['REMOTE_ADDR'] = request.args.get(
        'ip', default='-')

    info = request.args.get('info')
    activity_description = info + " " + str(
        datetime.utcnow()) if info else request.args.get('activity')
    if activity_description:
        socketio_sessions[sid]['activity'] = activity_description

    return json_success("alive state updated")
Exemplo n.º 3
0
def on_trigger_simple_trigger(sensor_name):

    # find sensor
    sensor = mongo.db.objects.find_one(
        {
            'type': 'simpletrigger',
            'fields.name': sensor_name,
            'timestamp-deleted': {
                '$exists': False
            }
        }, {'_id': False})
    if not sensor or 'id' not in sensor or 'fields' not in sensor:
        log.warning(f"sensor {sensor_name} not registered")
        return json_not_found_error('SENSOR_NOT_REGISTERED',
                                    "sensor not registered")
    sensor_fields = sensor['fields']

    # execute effects
    effect_ids = sensor_fields.get('triggereffects') or []
    log.info(
        f"{len(effect_ids)} effects(s) triggered by simple trigger {sensor_name}"
    )
    errors = execute_effects(datetime.utcnow(), effect_ids, None, None, [],
                             False)
    if errors:
        return json_action_execution_error(errors)
    else:
        return json_success("sensor triggered successfully")
Exemplo n.º 4
0
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")
Exemplo n.º 5
0
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)
Exemplo n.º 6
0
def on_set_log_level(level):
    log.info("Changing log level to " + level)
    if level.lower() == "info":
        log.setLevel(logging.INFO)
    elif level.lower() == "debug":
        log.setLevel(logging.DEBUG)

    log.info("New log level: " + str(log.level))
    log.debug("debug New log level: " + str(log.level))
    return json_success("log level set to " + level)
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
def on_get_recycle_object(id):

    if id is None:
        return json_error_wrong_parameters()

    # undelete item
    item = mongo.db.objects.find_one_and_update(
        {'id': id}, {'$unset': {
            'timestamp-deleted': '',
            'user-deleted': ''
        }})
    if not item:
        return json_error_no_record_found()

    # signal success
    handle_object_change(item)
    return json_success('Object successfully restored.')
Exemplo n.º 11
0
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"
        )
Exemplo n.º 12
0
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")
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
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)
Exemplo n.º 15
0
def on_shortcut(cbox_name, index):

    try:
        index = int(index)
    except:
        return json_bad_request_error('INVALID_ARGUMENTS',
                                      'index argument must be numeric')

    # find cbox by name
    cbox = find_box(cbox_name)
    if not cbox or 'fields' not in cbox:
        return json_not_found_error('CBOX_NOT_FOUND', 'cbox not found')
    log.debug(f"picked cbox {cbox}")

    # get body data
    body = request.get_json()
    log.info(f"executing shortcut action {index} of {cbox} with {body}")

    # find shortcut
    shortcut = cbox.get('fields').get(
        'shortcuts')[index] if cbox.get('fields').get('shortcuts') and len(
            cbox.get('fields').get('shortcuts')) > index else None
    if not shortcut or 'fields' not in shortcut:
        return json_not_acceptable_error('INVALID_ITEM',
                                         'invalid shortcut item')
    log.debug(f"picked shortcut {shortcut}")

    # execute actions
    context = body.get('context') if body else {}
    individual = context.get('individual') if context else None
    shortcut_fields = shortcut['fields']
    actions = shortcut_fields.get('actions') or []
    targets = [cbox['id']]
    errors = schedule_actions(datetime.utcnow(), actions, None, None,
                              {'individual': individual or 'anyone'}, targets)
    if errors:
        return json_action_execution_error(errors)
    else:
        return json_success("shortcut actions executed")
Exemplo n.º 16
0
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)
Exemplo n.º 17
0
def on_get_logfile(bytes_hint):
    log.info("logfile:" + app.config['LOGFILE_PATH'])
    f = open(app.config['LOGFILE_PATH'], "r")
    result = "".join(f.readlines(bytes_hint))
    f.close()
    return json_success(result)
Exemplo n.º 18
0
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")
Exemplo n.º 19
0
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")
Exemplo n.º 20
0
def on_trigger_badgesensor(sensor_name, range_index):

    # find method
    method = request.args.get('method')
    signature = request.args.get('signature')

    # find sensor
    sensor_info = find_badgesensor_info(sensor_name)
    if not sensor_info:
        log.warning(f"sensor {sensor_name} not registered")
        return json_not_found_error('SENSOR_NOT_REGISTERED',
                                    "sensor not registered")
    if signature and signature != sensor_info.get('signature'):
        return json_gone_error(
            'SENSOR_CONFIGURATION_CHANGED',
            "sensor configuration has been changed and must be updated")

    # find beacon range
    beacon_ranges = sensor_info['ranges']
    if range_index >= len(beacon_ranges):
        log.warning(
            f"beacon range {range_index} not defined for {sensor_name}")
        return json_not_found_error('INVALID_BEACON_RANGE',
                                    "invalid beacon range")
    beacon_range = beacon_ranges[range_index]

    # find individual / visitor type from badge
    badge = find_badge(request.args)
    if not badge or 'id' not in badge or 'fields' not in badge:
        return json_not_found_error('BADGE_NOT_REGISTERED',
                                    "badge not registered")
    badge_fields = badge['fields']
    individual = badge['id']
    visitor_type_field = badge_fields.get('visitortype')
    if visitor_type_field:
        visitor_type_id = visitor_type_field[0]
        visitor_type = mongo.db.objects.find_one(
            {'id': visitor_type_id},
            {'_id': False}) if visitor_type_id else None
    else:
        visitor_type = None

    # update sensor state
    now = datetime.utcnow()
    if method == 'hold':
        hold_badgesensor_range(sensor_info, range_index, individual, now)
        return json_success("sensor hold successfully")
    elif method == 'leave':
        leave_badgesensor_range(sensor_info, range_index, individual, now)
    else:
        enter_badgesensor_range(sensor_info, range_index, individual, now)

    # find effects
    sensor_effect_ids = beacon_range.get('effects') or []
    badge_effect_ids = badge_fields.get('effects') or []
    effect_ids = sensor_effect_ids + badge_effect_ids
    if not effect_ids:
        return json_success("sensor triggered without effects")

    # execute effects
    log.info(
        f"{len(effect_ids)} effects(s) on {method} for {individual} of visitor type {visitor_type and visitor_type.get('title')} triggered by badge sensor {sensor_name}"
    )
    errors = execute_effects(now, effect_ids, individual, visitor_type, [],
                             method == 'leave')
    if errors:
        return json_action_execution_error(errors)
    else:
        return json_success("sensor triggered successfully")