def manage_node(*args):
    node_id = int(args[0]['node_id'])
    action = args[0]['action']
    db = cache.get_raw()

    # add new state
    if action in ['add', 'insert', 'a', 'i', '+']:
        index = int(args[0]['index'])  # state index
        html = urllib.parse.unquote(args[0]['html'])
        db['node_html'][node_id].insert(index, html)
        db['force_update'] = True

    # remove state
    elif action in ['remove', 'delete', 'del', 'r', 'd', '-']:
        index = int(args[0]['index'])  # state index
        del db['node_html'][node_id][index]
        db['force_update'] = True
        db['html_index'][node_id] = 0

    # change update delay [reset timer to prevent overflow]
    elif action in ["speed", "delay"]:
        db['update_delay'][node_id] = abs(int(args[0]['delay']))
        db['update_timer'][node_id] = 0

    elif action in ["update", "change", "replace"]:
        index = int(args[0]['index'])  # state index
        html = urllib.parse.unquote(args[0]['html'])
        db['node_html'][node_id][index] = html
        db['force_update'] = True
    else:
        return "Invalid action"
    return "OK"
def delete_node(*args):
    node_id = int(args[0]['node_id'])
    db = cache.get_raw()
    del db['node_html'][node_id]
    del db['html_index'][node_id]
    del db['update_timer'][node_id]
    del db['update_delay'][node_id]
    db['force_update'] = True
    return 'OK'
def add_node(*args):
    node_id = int(args[0]['node_id'])
    db = cache.get_raw()
    db['node_html'].insert(node_id, [])
    db['html_index'].insert(node_id, 0)
    db['update_timer'].insert(node_id, 0)
    db['update_delay'].insert(node_id, 2)
    db['force_update'] = True
    return 'OK'
def delete_file(*args):
    filename = args[0]['filename']
    if '..' in filename:  # no directory traversal
        return "Nope"
    try:  # Delet the fiile, bu don't tell the user abput errors, tht would enable destructive enumeration
        _os_remove_file("../Frontend/uploads/" + filename)
        db = cache.get_raw()
        db['force_update'] = True
        return 'OK'
    except FileNotFoundError:
        pass
        return 'File not found'
def newContentAvailable(*args):
    # for faster access, get the DB object
    db = cache.get_raw()
    out = []
    for nid, node in enumerate(db['update_timer']):
        out.append(node <= 0 and len(db['node_html'][nid]) > 1
                   or db['force_update'])
        if node <= 0:
            db['update_timer'][nid] = db['update_delay'][nid] - 1
        else:
            db['update_timer'][nid] -= 1
    db['force_update'] = False
    return json.dumps(out)
def node_html(*args, **kwargs):
    # extract node_id from GET params
    node_id = int(args[0]['node_id'])
    # for faster access, get the DB object
    db = cache.get_raw()
    try:
        # fetch the current html data based on the html index of the node
        out = db['node_html'][node_id][db['html_index'][node_id]]
        # update the html_index and roll over
        db['html_index'][node_id] += 1
        db['html_index'][node_id] %= len(db['node_html'][node_id])
    except IndexError:
        out = ""
    return out
def get_delay(*args):
    return cache.get_raw()['update_delay'][int(args[0]['node_id'])]
def db(*args):
    c = cache.get_raw().copy()
    c['config'] = [
        'No passwords for you, you don\'t need them anyways, right?'
    ]
    return json.dumps(c)