예제 #1
0
def preview_battery(request, bid, no_send=None):

    # No robots allowed!
    if request.user_agent.is_bot:
        return render_to_response("messages/robot_sorry.html")

    battery = get_battery(bid, request)
    router_url = battery.get_router_url()

    # If the user has already started and authenticated
    worker = get_worker("DUMMY", create=True)
    request.session['worker_id'] = "DUMMY"

    # If no_send is defined, the user doesn't want to email results
    if no_send != None:
        request.session['no_send'] = "anything"

    # We set the userid in the template to send to the service worker before routing to battery
    context = {
        "instruction_forms": get_battery_intro(battery),
        "start_url": router_url,
        "userid": "DUMMY"
    }

    return render(request, "batteries/serve_battery_intro.html", context)
예제 #2
0
def serve_battery_gmail(request, bid):
    '''serves a battery, creating user with gmail'''
    # Check if the keyid is correct
    battery = get_battery(bid, request)
    uid = hashlib.md5(battery.name).hexdigest()
    if "keyid" in request.POST and "gmail" in request.POST:
        keyid = request.POST["keyid"]
        address = request.POST["gmail"]
        if uid == keyid:
            userid = hashlib.md5(address).hexdigest()
            worker = get_worker(userid, create=True)
            return redirect("intro_battery", bid=bid, userid=userid)
        else:
            return render_to_response("messages/robot_sorry.html")
    else:
        return render_to_response("messages/robot_sorry.html")
예제 #3
0
def reset_preview(request, bid, redirect=True):
    '''reset_preview will delete the battery experiments for the preview user, meaning
    the preview can be restarted
    :param bid: the battery id
    :param redirect: if True, will redirect back to battery page, with message of reset
    (default is True, should only be false if called by server)
    '''
    preview_user = get_worker("DUMMY")
    battery = get_battery(bid, request)
    experiments = battery.experiment_set.all()
    preview_user.experiments_completed = preview_user.experiments_completed.exclude(
        id__in=[x.id for x in experiments])
    preview_user.save()
    if redirect == True:
        message = "Dummy worker history successfully reset."
        return view_battery(request, battery.id, message=message)
예제 #4
0
def send_result(eid,wid,data):
    '''send_result will use the sendgrid email API to send a result object to a worker. If there
    is an error, the user will be emailed instead using expfactory email, and the battery status
    will be made inactive.
    :param eid: the experiment id
    :param data: the data object (json)
    '''
    try:
        # Retrieve worker, experiment, and battery
        worker = get_worker(wid)
        experiment = Experiment.objects.get(id=eid)
        battery = experiment.battery

        # Generate email and send with sendgrid
        email = generate_email(battery,experiment,worker,data)
        sg = SendGridAPIClient(apikey=battery.sendgrid)
        response = sg.client.mail.send.post(request_body=email)
        if response.status_code != 202:
            failed_send(battery,experiment,worker)
    except:
        failed_send(battery,experiment,worker)
예제 #5
0
def serve_battery_anon(request, bid, keyid):
    '''serve an anonymous local battery, userid is generated upon going to link
    '''
    # Check if the keyid is correct
    battery = get_battery(bid, request)
    uid = hashlib.md5(battery.name).hexdigest()

    if uid == keyid:

        # If the user has already started and authenticated
        userid = request.session.get('worker_id', None)
        if userid == None:
            userid = uuid.uuid4()
            worker = get_worker(userid, create=True)
            request.session['worker_id'] = worker.id

        return redirect("intro_battery", bid=bid, userid=userid)

    # Invalid URL for battery!
    else:
        return render_to_response("messages/robot_sorry.html")
예제 #6
0
def battery_router(request, bid, eid=None, userid=None, no_send=False):
    '''battery_router will direct the user (determined from the session variable) to an uncompleted experiment. If an
    experiment id is provided, the redirect is being sent from a completed experiment, and we log the experiment as completed
    first. 
    :param bid: the battery id
    :param eid: the experiment id, if provided, means we are submitting a result
    :param userid: the userid, will be "DUMMY" if doing a battery preview
    :param no_send: don't send result to email, default is False
    '''
    # No robots allowed!
    if request.user_agent.is_bot:
        return render_to_response("messages/robot_sorry.html")

    # Is this a valid user?
    preview = False
    if userid != "DUMMY":  # not a preview battery
        userid = request.session.get('worker_id', None)
        if userid == None:
            return render_to_response("messages/invalid_id_sorry.html")
    else:
        # If no_send is defined, then don't send
        preview = True
        no_send = request.session.get('no_send', False)

    worker = get_worker(userid)

    # Retrieve the battery based on the bid
    battery = get_battery(bid, request)

    # If there is a post, we are finishing an experiment and sending data
    if request.method == "POST" and eid != None:

        experiment = get_experiment(eid, request)

        # If it's a survey, format the results before sending
        data = request.POST

        if experiment.template == "survey":
            data = complete_survey_result(experiment, data)

        else:
            data = dict(data)

        # Mark the experiment as completed
        if experiment not in worker.experiments_completed.all():

            # Only send data if the user hasn't completed it yet
            if no_send != True:
                send_result.apply_async([experiment.id, worker.id, data])
            worker.experiments_completed.add(experiment)
            worker.save()

    # Deploy the next experiment
    missing_batteries, blocking_batteries = check_battery_dependencies(
        battery, worker)
    if missing_batteries or blocking_batteries:
        return render_to_response("messages/battery_requirements_not_met.html",
                                  context={
                                      'missing_batteries': missing_batteries,
                                      'blocking_batteries': blocking_batteries
                                  })

    # Is the battery still active?
    if battery.active == False:
        context = {"contact_email": battery.email}
        return render(request, "messages/battery_inactive.html", context)

    # Does the worker have experiments remaining?
    uncompleted_experiments = get_worker_experiments(worker, battery)
    experiments_left = len(uncompleted_experiments)
    if experiments_left == 0:
        # If it's a preview, reset it before showing the final page
        if preview == True:
            reset_preview(request, bid, redirect=False)
        # Thank you for your participation - no more experiments!
        return render_to_response("messages/worker_sorry.html")

    next_experiment = select_experiments(battery, uncompleted_experiments)[0]

    # Redirect the user to the experiment!
    return HttpResponseRedirect(next_experiment.serve_url())