Commit 4e38530e authored by Ossi Laine's avatar Ossi Laine
Browse files

Refactoring task.html POST methods

parent 7f462540
......@@ -111,8 +111,12 @@ def experiment_questions():
exp_id = request.args.get('exp_id', None)
form = CreateQuestionForm(request.form)
print(form)
print(form.validate())
if request.method == 'POST' and form.validate():
if request.method == 'POST':
#if request.method == 'POST' and form.validate():
str = form.questions_and_options.data
str_list = str.split('/n')
......@@ -140,9 +144,10 @@ def experiment_questions():
db.session.add(add_question)
db.session.commit()
return redirect(url_for('create.experiment_upload_stimuli', exp_id=exp_id))
#return redirect(url_for('create.experiment_upload_stimuli', exp_id=exp_id))
return redirect(url_for('create.experiment_upload_stimuli', exp_id=exp_id))
return render_template('create_experiment_questions.html', form=form)
#return render_template('create_experiment_questions.html', form=form)
@create_blueprint.route('/experiment_upload_stimuli', methods=['GET', 'POST'])
......
......@@ -517,13 +517,12 @@ def remove_bg_question():
exp_status = experiment.query.filter_by(idexperiment=exp_id).first()
if exp_status.status != 'Hidden':
flash("Experiment is public. Cannot modify structure.")
return redirect(url_for('experiment.view', exp_id=exp_id))
else:
# TODO: cannot remove background question if there are answers
remove_id = request.args.get('idbackground_question', None)
remove_options = background_question_option.query.filter_by(background_question_idbackground_question=remove_id).all()
......@@ -545,8 +544,6 @@ def remove_bg_question():
# Rating set:
@experiment_blueprint.route('/set_embody')
......
......@@ -28,7 +28,6 @@ class background_question_option(db.Model):
background_question_idbackground_question = db.Column(db.Integer, db.ForeignKey('background_question.idbackground_question'))
option = db.Column(db.String(120))
def __repr__(self):
return "<idbackground_question_option = '%s', background_question_idbackground_question = '%s', option = '%s'>" % (self.idbackground_question_option, self.background_question_idbackground_question, self.option)
......@@ -64,6 +63,7 @@ class answer_set (db.Model):
session = db.Column(db.String(120))
agreement = db.Column(db.String(120))
answer_counter = db.Column(db.Integer)
answer_type = db.Column(db.String(120))
registration_time = db.Column(db.DateTime, index=True, default=datetime.utcnow)
last_answer_time = db.Column(db.DateTime, index=True, default=datetime.utcnow)
......@@ -78,15 +78,8 @@ class background_question_answer(db.Model):
answer = db.Column(db.String(120))
background_question_idbackground_question = db.Column(db.Integer, db.ForeignKey('background_question.idbackground_question'))
def __repr__(self):
return "<idbackground_question_answer = '%s', answer_set_idanswer_set = '%s', answer = '%s', background_question_idbackground_question = '%s'>" % (self.idbackground_question_answer, self.answer_set_idanswer_set, self.answer, self.background_question_idbackground_question)
"""
def __repr__(self):
return '<answer {}>'.format(self.answer)
"""
def background_question_answer_query():
......@@ -95,10 +88,7 @@ def background_question_answer_query():
"""
class ChoiceForm(FlaskForm):
opts = QuerySelectField(query_factory=background_question_answer_query, allow_blank=True)
"""
"""
u = background_question.query.get(1)
vastaukset = u.answers.all()
## pitää sisällään kysymyksen 1 vastaukset
......@@ -124,13 +114,7 @@ class page (db.Model):
type = db.Column(db.String(120), index=True)
text = db.Column(db.Text)
media = db.Column(db.String(120), index=True)
"""
def __repr__(self):
return "<idpage = '%s', experiment_idexperiment = '%s', type = '%s', text = '%s', media = '%s'>" % (self.idpage, self.experiment_idexperiment, self.type, self.text, self.media)
def __repr__(self):
return '{}'.format(self.text)
"""
def __repr__(self):
return "<idpage = '%s', experiment_idexperiment = '%s', type = '%s', text = '%s', media = '%s'>" % (self.idpage, self.experiment_idexperiment, self.type, self.text, self.media)
......@@ -147,6 +131,17 @@ class answer (db.Model):
return "<idanswer = '%s', question_idquestion = '%s', answer_set_idanswer_set = '%s', answer = '%s', page_idpage = '%s'>" % (self.idanswer, self.question_idquestion, self.answer_set_idanswer_set, self.answer, self.page_idpage)
class embody_answer (db.Model):
__tablename__ = "embody_answer"
idanswer = db.Column(db.Integer, primary_key=True)
answer_set_idanswer_set = db.Column(db.Integer, db.ForeignKey('answer_set.idanswer_set'))
page_idpage = db.Column(db.Integer, db.ForeignKey('page.idpage'))
coordinates = db.Column(db.Text)
def __repr__(self):
return "<idanswer = '%s', answer_set_idanswer_set = '%s', coordinates = '%s', page_idpage = '%s'>" % (self.idanswer, self.answer_set_idanswer_set, self.coordinates, self.page_idpage)
class trial_randomization (db.Model):
__tablename__ = "trial_randomization"
idtrial_randomization = db.Column(db.Integer, primary_key=True)
......@@ -169,11 +164,6 @@ class forced_id (db.Model):
return "<idforced_id = '%s', experiment_idexperiment = '%s', pregenerated_id = '%s'>" % (self.idforced_id, self.experiment_idexperiment, self.pregenerated_id)
class user(UserMixin, db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
......
......@@ -83,7 +83,7 @@ def remove_language():
@app.route('/session')
def participant_session():
'''Set up session variables'''
'''Set up session variables and create answer_set (database level sessions)'''
#start session
session['exp_id'] = request.args.get('exp_id', None)
......@@ -104,20 +104,29 @@ def participant_session():
session['user'] = random_id
# Set session status variables
exp_status = experiment.query.filter_by(idexperiment=session['exp_id']).first()
#create answer set for the participant in the database
the_time = datetime.now()
the_time = the_time.replace(microsecond=0)
# TODO: Check which question type is the first in answer_set
answer_set_type = 'slider'
if exp_status.embody_enabled:
answer_set_type = 'embody'
participant_answer_set = answer_set(experiment_idexperiment=session['exp_id'],
session=session['user'],
agreement = session['agree'],
answer_counter = '0',
answer_type = answer_set_type,
registration_time=the_time,
last_answer_time=the_time)
db.session.add(participant_answer_set)
db.session.commit()
# Set session status variables
exp_status = experiment.query.filter_by(idexperiment=session['exp_id']).first()
#If trial randomization is set to 'On' for the experiment, create a randomized trial order for this participant
#identification is based on the uniquie answer set id
......@@ -150,18 +159,11 @@ def participant_session():
if exp_status.randomization == "Off":
session['randomization'] = "Off"
if exp_status.embody_enabled:
session['embody'] = True
else:
session['embody'] = False
#store participants session id in session list as answer_set, based on experiment id and session id
session_id_for_participant = answer_set.query.filter(and_(answer_set.session==session['user'], answer_set.experiment_idexperiment==session['exp_id'])).first()
session['answer_set'] = session_id_for_participant.idanswer_set
# TODO: this is unnecessary if experiment contains multiple stimulus types
#collect experiments mediatype from db to session['type'].
#This is later used in task.html to determine page layout based on stimulus type
......@@ -172,7 +174,6 @@ def participant_session():
flash('No pages or mediatype set for experiment')
return redirect('/')
# Redirect user to register page
if 'user' in session:
user = session['user']
......
......@@ -40,6 +40,7 @@ $(document).ready(function() {
});
canvas.mousemove(function(e){
// TODO: if mousedown -> can draw outside of image
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
if(paint && pointInsideBaseImage([mouseX, mouseY])){
......
......@@ -22,7 +22,7 @@ from flask_babel import _, lazy_gettext as _l
from app import db
from app.models import experiment
from app.models import page, question
from app.models import answer_set, answer
from app.models import answer_set, answer, embody_answer
from app.models import user, trial_randomization
from app.forms import Answers, TaskForm, ContinueTaskForm, StringForm
......@@ -33,22 +33,18 @@ task_blueprint = Blueprint("task", __name__,
def get_randomized_page(page_id):
"""if trial randomization is on we will still use the same functionality that is used otherwise
but we will pass the randomized pair of the page_id from trial randomization table to the task.html"""
#this variable is feeded to the template as empty if trial randomization is set to "off"
randomized_stimulus = ""
#if trial randomization is on we will still use the same functionality that is used otherwise
#but we will pass the randomized pair of the page_id from trial randomization table to the task.html
randomized_page = trial_randomization.query.filter(and_(
trial_randomization.answer_set_idanswer_set==session['answer_set'],
trial_randomization.page_idpage==page_id
#trial_randomization.page_idpage==pages.items[0].idpage
)).first()
return randomized_page
def add_slider_answer(key, value, randomized_page_id):
def add_slider_answer(key, value, randomized_page_id=None):
'''Insert slider value to database. If trial randomization is set to 'Off'
the values are inputted for session['current_idpage']. Otherwise the values
are set for the corresponding id found in the trial randomization table'''
......@@ -59,7 +55,8 @@ def add_slider_answer(key, value, randomized_page_id):
db.session.commit()
def update_answer_set():
def update_answer_set_page():
"""Increment the page number by one in answer_set when user goes to next page"""
the_time = datetime.now()
the_time = the_time.replace(microsecond=0)
......@@ -69,6 +66,18 @@ def update_answer_set():
db.session.commit()
def update_answer_set_type(answer_type):
"""If there are multiple question types(embody,slider,...) on one page,
then update the current question type"""
the_time = datetime.now()
the_time = the_time.replace(microsecond=0)
updated_answer_set = answer_set.query.filter_by(idanswer_set=session['answer_set']).first()
updated_answer_set.answer_type = answer_type
updated_answer_set.last_answer_time = the_time
db.session.commit()
def slider_question_has_answers(user, page_id):
'''This should return true IF there are questions from certain page and no answers'''
......@@ -83,9 +92,63 @@ def slider_question_has_answers(user, page_id):
questions = question.query.filter_by(experiment_idexperiment=experiment_id).all()
# TODO: should return true if there are no slider questions!!!!
return (True if (len(answers) == 0 and len(questions) > 0) else False)
def select_form_type():
"""Select form type based on the value in answer_set->answer_type"""
form = None
answer_set_type = answer_set.query.filter_by(idanswer_set=session['answer_set']).first().answer_type
if answer_set_type == 'slider':
form = TaskForm()
# Get sliders from this experiment
categories = question.query.filter_by(experiment_idexperiment=session['exp_id']).all()
categories_and_scales = {}
for cat in categories:
scale_list = [(cat.left, cat.right)]
categories_and_scales[cat.idquestion, cat.question] = scale_list
form.categories1 = categories_and_scales
else:
form = StringForm()
return form
def check_if_answer_exists(answer_type, page_id):
"""Check if there is already answer on certain experiment->page"""
check_answer = None
if answer_type == 'embody':
check_answer = embody_answer.query.filter(and_(embody_answer.answer_set_idanswer_set==session['answer_set'], embody_answer.page_idpage==session['current_idpage'])).first()
elif answer_type == 'slider':
check_answer = answer.query.filter(and_(answer.answer_set_idanswer_set==session['answer_set'], answer.page_idpage==session['current_idpage'])).first()
return (check_answer, None)
def check_if_randomized_answer_exists(answer_type, page_id):
"""Check if there is already answer on certain experiment->page if the pages are in randomized order"""
check_answer = randomized_page_id = None
if answer_type == 'embody':
randomized_page_id = get_randomized_page(page_id).randomized_idpage
check_answer = embody_answer.query.filter(and_(embody_answer.answer_set_idanswer_set==session['answer_set'], embody_answer.page_idpage==randomized_page_id)).first()
elif answer_type == 'slider':
randomized_page_id = get_randomized_page(page_id).randomized_idpage
check_answer = answer.query.filter(and_(answer.answer_set_idanswer_set==session['answer_set'], answer.page_idpage==randomized_page_id)).first()
return (check_answer, randomized_page_id)
################################
### ###
### ROUTES ###
### ###
################################
@task_blueprint.route('/embody/<int:page_num>', methods=['POST'])
def task_embody(page_num):
'''Save embody drawing to database'''
......@@ -96,19 +159,34 @@ def task_embody(page_num):
if form.validate():
data = request.form.to_dict()
coordinates = json.loads(data['coordinates'])
print("x:",coordinates['x'])
print("y:",coordinates['y'])
# Check if randomization ON and if user has already answered to embody question
if session['randomization'] == 'On':
check_answer, randomized_page_id = check_if_randomized_answer_exists('embody',page_id)
else:
check_answer, randomized_page_id = check_if_answer_exists('embody',page_id)
# Add answer to DB
if check_answer is None:
page_idpage = session['current_idpage'] if session['randomization'] == 'Off' else randomized_page_id
# Add new embody answer
participant_answer = embody_answer(answer_set_idanswer_set=session['answer_set'], coordinates=data['coordinates'], page_idpage=page_idpage)
db.session.add(participant_answer)
# Update answer set type
answer_set.query.filter_by(idanswer_set=session['answer_set']).first().answer_type = 'slider'
db.session.commit()
else:
flash("Page has been answered already. Answers discarded")
# Test that everything OK
return json.dumps(coordinates)
# Check if there are unanswered slider questions
if slider_question_has_answers(session['user'], page_id):
return redirect( url_for('task.task', page_num=page_num, show_sliders=True))
update_answer_set_type('slider')
return redirect( url_for('task.task', page_num=page_num))
if not pages.has_next:
return redirect ( url_for('task.completed'))
......@@ -126,23 +204,17 @@ def task_answer(page_num):
page_id = pages.items[0].idpage
if form.validate():
#Lets check if there are answers in database already for this page_id (eg. if user returned to previous page and tried to answer again)
#If so flash ("Page has been answered already. Answers discarded"), else insert values in to db
#this has to be done separately for trial randomization "on" and "off" situations
# Check if randomization ON and if user has already answered to slider question
if session['randomization'] == 'On':
randomized_page_id = get_randomized_page(page_id).randomized_idpage
check_answer = answer.query.filter(and_(answer.answer_set_idanswer_set==session['answer_set'], answer.page_idpage==randomized_page_id)).first()
check_answer, randomized_page_id = check_if_randomized_answer_exists('slider',page_id)
else:
check_answer = answer.query.filter(and_(answer.answer_set_idanswer_set==session['answer_set'], answer.page_idpage==session['current_idpage'])).first()
check_answer, randomized_page_id = check_if_answer_exists('slider',page_id)
if check_answer is None:
update_answer_set()
data = request.form.to_dict()
for key, value in data.items():
add_slider_answer(key, value, randomized_page_id)
else:
flash("Page has been answered already. Answers discarded")
......@@ -151,11 +223,20 @@ def task_answer(page_num):
if not pages.has_next:
return redirect ( url_for('task.completed'))
update_answer_set_page()
# If embody in use -> change the answer set type
exp_status = experiment.query.filter_by(idexperiment=session['exp_id']).first()
if exp_status.embody_enabled:
update_answer_set_type('embody')
return redirect( url_for('task.task', page_num=pages.next_num))
@task_blueprint.route('/<int:page_num>', methods=['GET'])
def task(page_num):
"""Get selected task page"""
randomized_stimulus=""
try:
experiment_info = experiment.query.filter_by(idexperiment=session['exp_id']).first()
......@@ -163,22 +244,16 @@ def task(page_num):
print(err)
flash("No valid session found")
return redirect('/')
rating_instruction = experiment_info.single_sentence_instruction
stimulus_size = experiment_info.stimulus_size
#for text stimuli the size needs to be calculated since the template element utilises h1-h6 tags.
#A value of stimulus size 12 gives h1 and value of 1 gives h6
stimulus_size = experiment_info.stimulus_size
stimulus_size_text = 7-math.ceil((int(stimulus_size)/2))
pages = page.query.filter_by(experiment_idexperiment=session['exp_id']).paginate(per_page=1, page=page_num, error_out=True)
page_id = pages.items[0].idpage
progress_bar_percentage = round((pages.page/pages.pages)*100)
#this variable is feeded to the template as empty if trial randomization is set to "off"
randomized_stimulus = ""
# if trial randomization is on we will still use the same functionality that is used otherwise
# but we will pass the randomized pair of the page_id from trial randomization table to the task.html
if session['randomization'] == 'On':
......@@ -188,39 +263,18 @@ def task(page_num):
for p in pages.items:
session['current_idpage'] = p.idpage
print(session)
# Select form type (TODO: question order is now harcoded to EMBODY -> SLIDERS
# there should be more flexible solution if more question types are added...)
if request.args.get('show_sliders', False) or not session['embody']:
# Init slider form
form = TaskForm()
# Get sliders from this experiment
categories = question.query.filter_by(experiment_idexperiment=session['exp_id']).all()
categories_and_scales = {}
for cat in categories:
scale_list = [(cat.left, cat.right)]
categories_and_scales[cat.idquestion, cat.question] = scale_list
form.categories1 = categories_and_scales
else:
form = StringForm()
return render_template(
'task.html',
pages=pages,
page_num=page_num,
progress_bar_percentage=progress_bar_percentage,
form=form,
form=select_form_type(),
randomized_stimulus=randomized_stimulus,
rating_instruction=rating_instruction,
rating_instruction=experiment_info.single_sentence_instruction,
stimulus_size=stimulus_size,
stimulus_size_text=stimulus_size_text,
experiment_info=experiment_info
)
)
@task_blueprint.route('/completed')
......@@ -261,7 +315,6 @@ def continue_task():
exp = experiment.query.filter_by(idexperiment=session['exp_id']).first()
session['randomization'] = exp.randomization
session['embody'] = exp.embody_enabled
if mediatype:
session['type'] = mediatype.type
......
......@@ -55,6 +55,10 @@ CREATE TABLE answer_set (
FOREIGN KEY(experiment_idexperiment) REFERENCES experiment (idexperiment)
);
ALTER TABLE answer_set ADD COLUMN (answer_type VARCHAR(120));
/* TODO: Update answer_set so it knows which part of the page the user is doing (embody/sliders/something else) */
/* Background questions are asked before the experiment begins */
CREATE TABLE background_question (
idbackground_question INTEGER NOT NULL AUTO_INCREMENT,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment