Example #1
0
def view_state(request, state_id):
    if not request.user.is_superuser:
        return forbidden()

    state = get_object_or_404(State, id=state_id)
    config = Configuration.objects.get(pk=1)
    schema = config.schema()

    deform_templates = resource_filename('deform', 'templates')
    search_path = (settings.DEFORM_TEMPLATE_OVERRIDES, deform_templates)
    renderer = deform.ZPTRendererFactory(search_path)
    form = deform.Form(schema, buttons=('submit',), renderer=renderer)

    readonly = get_readonly_from_state(state)
    available_sections = get_available_sections(state)

    # Deform's form.render API allows you to pass a readonly=True flag
    # to have deform render a readonly representation of the data;
    # but, the default readonly templates aren't form-like, they're just
    # unstyled lists which look really ugly in our layout.
    # So, instead, the mvsim django template receives the readonly flag,
    # and, if it's set, removes Deform's javascript and injects some JS
    # to disable all the form fields on page load.  The result is prettier.
    if request.method == "GET":
        return view_form(request, state, form, readonly,
                         available_sections)

    if readonly:
        return forbidden()

    controls = parse_qsl(request.body, keep_blank_values=True)

    try:
        appstruct = form.validate(controls)
    except deform.ValidationFailure as e:
        course = None
        if state.game:
            course = state.game.course
        rv = {
            'form': e.render(),
            'readonly': readonly,
            'state': state,
            'course': course,
            'available_sections': available_sections}
        return rv

    new_state = json.dumps(appstruct)
    state.state = new_state
    state.save()
    url = "%s?msg=saved" % state.view_state_url()
    return redirect(url)
Example #2
0
def edit_game(request, game_id):
    game = get_object_or_404(Game, pk=game_id)
    if not game.viewable(request.user):
        return forbidden()
    game.name = request.GET.get('name', smart_text(game))
    game.save()
    return HttpResponse("ok")
Example #3
0
def edit_state(request, state_id):
    if not request.user.is_superuser:
        return forbidden()

    state = get_object_or_404(State, id=state_id)

    if 'visible' in request.POST:
        state.visible = request.POST.get('visible') == "True"
        state.save()

    posted_sections = request.POST.getlist('associated_sections')
    associated_sections = list(state.coursesection_set.all())

    # Add new sections
    for section_id in posted_sections:
        section = get_object_or_404(CourseSection, id=section_id)
        if section not in associated_sections:
            section.starting_states.add(state)
            section.save()

    # Remove sections as needed
    for section in associated_sections:
        if str(section.id) not in posted_sections:
            section.starting_states.remove(state)
            section.save()

    return redirect(state.view_state_url())
Example #4
0
def admin_course_sections(request):
    if not request.user.is_superuser:
        return forbidden()

    sections = CourseSection.objects.all()
    states = State.objects.all().exclude(name="").order_by("name")
    return dict(sections=sections, all_states=states)
Example #5
0
def delete_game(request, game_id):
    statsd.incr("event.delete_game")
    game = get_object_or_404(Game, pk=game_id)
    section = game.course_section()
    if not game.viewable(request.user):
        return forbidden()
    game.delete()
    return redirect("/section/%d/games/" % section.id)
Example #6
0
def history(request, game_id):
    game = Game.objects.get(pk=game_id)

    if not game.viewable(request):
        return forbidden()

    display_vars = build_template_context(request, game)
    return display_vars
Example #7
0
def show_turn(request, game_id):
    game = get_object_or_404(Game, id=game_id)

    if not game.viewable(request.user):
        return forbidden()

    if not game.in_progress():
        return redirect(game.game_over_url())
    display_vars = build_template_context(request, game)
    return display_vars
Example #8
0
def show_turn(request, game_id):
    game = Game.objects.get(pk=game_id)

    if not game.viewable(request):
        return forbidden()

    if not game.in_progress():
        return redirect(game.game_over_url())
    display_vars = build_template_context(request, game)
    return display_vars
Example #9
0
def admin_course_section(request, section_id):
    if not request.user.is_superuser:
        return forbidden()
    section = get_object_or_404(CourseSection, id=section_id)
    states = State.objects.all().exclude(name="")

    users = []
    for u in section.users.all():
        users.append(u.get_full_name() if u.get_full_name() else u.username)

    return dict(section=section, all_states=states, users=sorted(users))
Example #10
0
def view_turn_history(request, game_id, turn_number):
    game = get_object_or_404(Game, id=game_id)

    if not game.viewable(request.user):
        return forbidden()
    turn_number = int(turn_number)
    if turn_number == 1:
        return view_turn_history_first_turn(request, game_id)

    display_vars = build_template_context(request, game, turn_number)
    return display_vars
Example #11
0
def view_turn_history(request, game_id, turn_number):
    game = Game.objects.get(pk=game_id)

    if not game.viewable(request):
        return forbidden()
    turn_number = int(turn_number)
    if turn_number == 1:
        return view_turn_history_first_turn(request, game_id)

    turn = game.get_state(int(turn_number))
    display_vars = build_template_context(request, game, turn_number)
    return display_vars
Example #12
0
def graph(request, game_id):
    game = get_object_or_404(Game, id=game_id)

    if not game.viewable(request.user):
        return forbidden()

    turns = [game.deserialize(state) for state
             in game.state_set.order_by("created")]

    params = {}
    primary_layers = []
    primary_xaxis = None
    secondary_xaxis = None

    layer_names = {}
    kw = request.GET
    for key in kw:
        if key == "primary_xaxis":
            primary_xaxis = kw['primary_xaxis']
            continue

        if key == "secondary_xaxis":
            secondary_xaxis = kw['secondary_xaxis']
            continue

        if key.endswith("_label"):
            layer = key[:-1 * len("_label")]
            name = kw[key]
            layer_names[layer] = name
            continue

        if key == "primary":
            primary_layers = extract_primary_layers(kw, key, primary_layers)
            continue

        params = extract_params(kw, key, params)

    params = params or {"layer_1": []}
    primary_layers = sorted(primary_layers) or []

    all_variables = game.configuration.variables.all()
    variables = process_variables(all_variables, turns)

    return dict(game=game,
                params=params,
                variables=variables,
                primary_xaxis=primary_xaxis,
                secondary_xaxis=secondary_xaxis,
                primary_layers=primary_layers,
                layers=params,
                layer_names=layer_names,
                turns=turns)
Example #13
0
def history(request, game_id):
    game = Game.objects.get(pk=game_id)

    if not game.viewable(request.user):
        return forbidden()

    section = game.course_section(user=request.user)
    starting_state_id = None
    if section.starting_states.all().count() > 0:
        starting_state_id = section.starting_states.all()[0].id

    display_vars = build_template_context(request, game)
    display_vars['starting_state_id'] = starting_state_id
    display_vars['section'] = section
    return display_vars
Example #14
0
def submit_turn(request, game_id):
    statsd.incr("event.play_turn")
    game = get_object_or_404(Game, id=game_id)

    if not game.viewable(request.user):
        return forbidden()
    state = game.deserialize(game.current_state())
    variables, coefficients = state['variables'], state['coefficients']

    while '' in variables.owned_items:
        variables.owned_items.remove('')
    while '' in variables.user_messages:
        variables.user_messages.remove('')

    from engine.simple_controller import adjust_submission
    kwargs = {}
    for key in request.POST:
        kwargs[key] = request.POST.get(key)
    kwargs = adjust_submission(kwargs, variables.names)

    user_submission = game.user_input.schema().deserialize(kwargs)

    for key in user_submission:
        variables[key] = user_submission[key]

    tc = ChainedRandom()
    turn = logic.Turn(variables, coefficients, tc)
    alive, variables = turn.go()

    del variables.people

    old_state = game.current_state()
    new_state = State(name=old_state.name, game=old_state.game)
    new_state.state = json.dumps(dict(
        variables=variables,
        coefficients=coefficients))
    new_state.save()

    if not alive:
        game.mark_finished()
        game.save()

    game.score = game.calculate_score()
    game.save()
    return redirect(game.show_game_url())
Example #15
0
def game_over(request, game_id):
    statsd.incr("event.game_over")
    game = get_object_or_404(Game, id=game_id)
    if not game.viewable(request.user):
        return forbidden()

    section = game.course_section(user=request.user)
    starting_state_id = None
    if section.starting_states.all().count() > 0:
        starting_state_id = section.starting_states.all()[0].id

    if game.in_progress():
        return redirect(game.show_game_url())

    display_vars = build_template_context(request, game)
    display_vars['starting_state_id'] = starting_state_id
    display_vars['section'] = section
    return display_vars
Example #16
0
def submit_turn(request, game_id):
    game = Game.objects.get(pk=game_id)

    if not game.viewable(request):
        return forbidden()
    state = game.deserialize(game.current_state())
    variables, coefficients = state['variables'], state['coefficients']

    if '' in variables.owned_items: 
        variables.owned_items.remove('')
    if '' in variables.user_messages:
        variables.user_messages.remove('')

    from engine.simple_controller import adjust_submission
    kwargs = {}
    for key in request.POST:
        kwargs[key] = request.POST.get(key)
    kwargs = adjust_submission(kwargs, variables.names)

    user_submission = game.user_input.schema().deserialize(kwargs)

    for key in user_submission:        
        variables[key] = user_submission[key]
        
    from twisterclient import TwisterClient as TC
    tc = TC(base="http://twister.ccnmtl.columbia.edu/", chain=True)
    turn = logic.Turn(variables, coefficients, tc)
    alive, variables = turn.go()

    del variables.people
    import json
    old_state = game.current_state()
    new_state = State(name=old_state.name, game=old_state.game)
    new_state.state = json.dumps(dict(
            variables=variables,
            coefficients=coefficients))
    new_state.save()

    if not alive:
        game.mark_finished()
        game.save()

    return redirect(game.show_game_url())
Example #17
0
def clone_state(request, state_id):
    if not request.user.is_superuser:
        return forbidden("Forbidden")

    state = get_object_or_404(State, id=state_id)

    new_state = State(name=request.POST.get('state_name') or state.name)
    new_state.state = state.state
    new_state.visible = request.POST.get('visible', False) == "True"
    new_state.save()

    # Add new sections
    posted_sections = request.POST.getlist('associated_sections')
    for section_id in posted_sections:
        section = get_object_or_404(CourseSection, id=section_id)
        section.starting_states.add(new_state)
        section.save()

    return redirect(new_state.view_state_url())
Example #18
0
def associate_state(request, section_id):
    if not request.user.is_superuser:
        return forbidden()

    section = get_object_or_404(CourseSection, id=section_id)

    posted_states = request.POST.getlist('associated_states')
    associated_states = list(section.starting_states.all())

    # Add new states
    for state_id in posted_states:
        state = get_object_or_404(State, id=state_id)
        if state not in associated_states:
            section.starting_states.add(state)
            section.save()

    # Remove sections as needed
    for state in associated_states:
        if str(state.id) not in posted_states:
            section.starting_states.remove(state)
            section.save()

    return redirect("/course_sections/%d/" % section.id)
Example #19
0
def view_state(request, state_id):
    state = State.objects.get(id=state_id)
    config = Configuration.objects.get(pk=1)
    schema = config.schema()

    deform_templates = resource_filename('deform', 'templates')
    search_path = (settings.DEFORM_TEMPLATE_OVERRIDES, deform_templates)
    renderer = deform.ZPTRendererFactory(search_path)
    form = deform.Form(schema, buttons=('submit',), renderer=renderer)

    readonly = False
    if state.game:
        readonly = True

    # Deform's form.render API allows you to pass a readonly=True flag
    # to have deform render a readonly representation of the data;
    # but, the default readonly templates aren't form-like, they're just
    # unstyled lists which look really ugly in our layout.
    # So, instead, the mvsim django template receives the readonly flag, 
    # and, if it's set, removes Deform's javascript and injects some JS
    # to disable all the form fields on page load.  The result is prettier.
    if request.method == "GET":
        return {'form': form.render(state.loads()),
                'readonly': readonly,
                'state': state}

    if readonly:
        return forbidden()

    # trick from Chris Pyper, http://groups.google.com/group/pylons-discuss/browse_thread/thread/83b4f2950cbc1892?hl=en
    controls = parse_qsl(request.raw_post_data, keep_blank_values=True)
    try:
        appstruct = form.validate(controls)
    except deform.ValidationFailure, e:
        return {'form': e.render(),
                'readonly': readonly,
                'state': state}
Example #20
0
def game_over(request, game_id):
    sections = CourseSection.objects.filter(users=request.user, 
                                            course=request.course)
    try:
        section = sections[0]
    except IndexError:
        section = CourseSection.objects.filter(course=request.course)[0]
        section.users.add(request.user)
        section.save()
    try:
        starting_state_id  = section.starting_states.all()[0].id
    except:
        starting_state_id = None

    game = Game.objects.get(pk=game_id)
    if game.in_progress():
        return redirect(game.show_game_url())

    if not game.viewable(request):
        return forbidden()

    display_vars = build_template_context(request, game)
    display_vars['starting_state_id'] = starting_state_id
    return display_vars
Example #21
0
def course_section_game_stats(request, section_id):
    if not request.user.is_superuser:
        return forbidden()
    section = get_object_or_404(CourseSection, id=section_id)
    return dict(section=section)
Example #22
0
def view_turn_history_first_turn(request, game_id):
    game = Game.objects.get(pk=game_id)

    if not game.viewable(request):
        return forbidden()
    return {'game': game}
Example #23
0
def graph(request, game_id):
    game = Game.objects.get(pk=game_id)

    if not game.viewable(request):
        return forbidden()

    turns = [game.deserialize(state) for state in game.state_set.order_by("created")]

    params = {}
    
    primary_layers = []
    
    primary_xaxis = None
    secondary_xaxis = None
    
    layer_names = {}
    kw = request.GET
    for key in kw:
        if key == "primary_xaxis":
            primary_xaxis = kw['primary_xaxis']
            continue
        if key == "secondary_xaxis":
            secondary_xaxis = kw['secondary_xaxis']
            continue
            
        if key.endswith("_label"):
            layer = key[:-1*len("_label")]
            name = kw[key]
            layer_names[layer] = name
            continue

        if key == "primary":
            for val in kw.getlist(key):
                primary_layers.append(val)
            continue

        for val in kw.getlist(key):
            params.setdefault(key, []).append(val)

    params = params or {"layer_1": []}
    primary_layers = sorted(primary_layers) or []

    all_variables = game.configuration.variables.all()
    excluded_variables = (
        'calculated_food_cost',
        'cotton_yield',
        'energy_req',
        'fertilizer_last_turn',
        'fertilizer_t1',
        'fertilizer_t2',
        'fish_coeff',
        'food_yield',
        'initial_population',
        'market',
        'maximum_effort',
        'propane_fuel',
        'season',
        'try_for_child',
        'wood_coeff',
        'wood_fuel',
        'year',
        )
    class BoundVariable(object):
        def __init__(self, name, getter=None, descriptive_name=None):
            self.name = name
            self.descriptive_name = descriptive_name or name.replace("_", " ").title()
            self.values = []
            for turn in turns:
                if getter is None:
                    self.values.append(
                        turn.variables[name])
                else:
                    self.values.append(
                        getter(turn, name))
    variables = []
    def add_divided_farming():
        # in addition to effort_farming, we also want to calculate
        # separate variables for each turn's effort farming spent
        # on each of maize and cotton
        def getter(turn, name):
            total_effort = turn.variables.effort_farming
            plots = turn.variables.crops
            if name == "effort_farming_maize":
                amount = sum(1 for i in plots if i == "Maize")
            elif name == "effort_farming_cotton":
                amount = sum(1 for i in plots if i == "Cotton")
            amount = 1.0 * amount / len(plots)
            return total_effort * amount
    
        variables.append(BoundVariable("effort_farming_maize", getter, "Effort Farming Maize (person-hours/day)"))
        variables.append(BoundVariable("effort_farming_cotton", getter, "Effort Farming Cotton (person-hours/day)"))
    def add_divided_health():
        # since health is a compound variable, we want to split it apart
        # into individual variables for each family member
        def getter(turn, name):
            health = turn.variables.health
            person_name = name[len("health_"):].title() # name will be like health_kodjo
            names = turn.variables.names
            try:
                index = names.index(person_name)
            except ValueError:
                # this person was not yet born, or was dead, at this turn
                return 0 
            return health[index]
        # we need to figure out all the people who were ever part of the family
        all_names = {}
        for turn in turns:
            names = turn.variables.names
            for name in names:
                all_names[name] = "health_" + name.lower()
        for name, var_name in all_names.items():
            variables.append(BoundVariable(
                    var_name, getter, 
                    "Health %s " % name + "(%)"))
    def add_average_health():
        # since health is a compound variable, we want to split it apart
        # into individual variables for each family member
        def getter(turn, name):
            health = turn.variables.health
            names = turn.variables.names
            if len(names) == 0:
                return 0
            return sum(health) / len(names)
        variables.append(BoundVariable(
                "health_average", getter,
                "Average Family Health (%)"))
    
    def add_divided_sickness():
        # since sick is a compound variable, we want to split it apart
        # into individual variables for each family member
        def getter(turn, name):
            sick = turn.variables.sick
            person_name = name[len("sick_"):].title() # name will be like health_kodjo
            names = turn.variables.names
            try:
                index = names.index(person_name)
            except ValueError:
                # this person was not yet born, or was dead, at this turn
                return 0
            return int(bool(sick[index].strip()))
        # we need to figure out all the people who were ever part of the family
        all_names = {}
        for turn in turns:
            names = turn.variables.names
            for name in names:
                all_names[name] = "sick_" + name.lower()
        for name, var_name in all_names.items():
            variables.append(BoundVariable(
                    var_name, getter,
                    "%s Sick" % name))
    def add_percent_sickness():
        def getter(turn, name):
            sick = turn.variables.sick
            names = turn.variables.names
            if len(names) == 0:
                return 0
            return 1.0 * sum(bool(i.strip()) for i in sick) / len(names)
        variables.append(BoundVariable(
                "sick_percent", getter,
                "Family Sick (% of family)"))
    for variable in all_variables:
        if variable.name in excluded_variables:
            continue
        if variable.name == "health":
            add_divided_health()
            add_average_health()
            continue
        if variable.name == "sick":
            add_divided_sickness()
            add_percent_sickness()
            continue
        if variable.type == "bool":
            def getter(turn, name):
                value = turn.variables[name]
                return int(value)
            variables.append(BoundVariable(
                    variable.name, getter,
                    variable.description))
            continue
        if not variable.graphable():
            continue
        variables.append(BoundVariable(
                variable.name,
                descriptive_name=variable.description))
        if variable.name == "effort_farming":
            add_divided_farming()
    
    return dict(game=game,
                params=params,
                variables=variables,
                primary_xaxis=primary_xaxis,
                secondary_xaxis=secondary_xaxis,
                primary_layers=primary_layers,
                layers=params,
                layer_names=layer_names,
                turns=turns)
Example #24
0
def view_turn_history_first_turn(request, game_id):
    game = get_object_or_404(Game, id=game_id)

    if not game.viewable(request.user):
        return forbidden()
    return {'game': game}