new fields added but can't send video anymore

This commit is contained in:
Jan 2024-06-15 19:02:38 +02:00
parent 1fffa33fe6
commit 3a21fb0914
10 changed files with 270 additions and 30 deletions

View File

@ -5,7 +5,7 @@ import base64
from flask import Flask, redirect, url_for, request, session, make_response, jsonify, send_from_directory from flask import Flask, redirect, url_for, request, session, make_response, jsonify, send_from_directory
from flask import render_template from flask import render_template
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Integer, String, Column from sqlalchemy import Integer, String, Column, Float
from datetime import datetime from datetime import datetime
import uuid import uuid
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
@ -41,7 +41,7 @@ UPLOAD_FOLDER = 'uploads'
#---------testing JSON Stuff #---------testing JSON Stuff
#open the json file with the config #open the json file with the config
testconfigfile = open("singleformconfig.json") testconfigfile = open("singleformconfig.json", encoding='utf-8')
#convert it to dict #convert it to dict
testconfig = json.load(testconfigfile) testconfig = json.load(testconfigfile)
testconfigfile.close() testconfigfile.close()
@ -93,7 +93,7 @@ except SQLAlchemyError as e:
#open the json file with the config #open the json file with the config
configfile = open("default.json") #todo replace with other name configfile = open("default.json", encoding='utf-8') #todo replace with other name
#convert it to dict #convert it to dict
config = json.load(configfile) config = json.load(configfile)
configfile.close() configfile.close()
@ -132,6 +132,8 @@ def create_model_class(schema):
column_type = Integer column_type = Integer
elif column_info["type"] == "string": elif column_info["type"] == "string":
column_type = String(int(column_info["size"])) column_type = String(int(column_info["size"]))
if column_info["type"] == "float":
column_type = Float
attributes[column_name] = Column(column_name,column_type, nullable=column_info["nullable"]) attributes[column_name] = Column(column_name,column_type, nullable=column_info["nullable"])
@ -186,7 +188,7 @@ def teststartpage():
print(session["block_names"]) print(session["block_names"])
for name in block_names: for name in block_names:
if config[name]["type"] == "TaskTemplate": if config[name]["type"] == "TaskTemplate" and ("stimuli" in current_block):
match config[name]["stimuli"]["type"]: match config[name]["stimuli"]["type"]:
case "single_video": case "single_video":
order = list(config[name]["stimuli"]["list"]) # order = list of simuli keys order = list(config[name]["stimuli"]["list"]) # order = list of simuli keys
@ -194,6 +196,11 @@ def teststartpage():
if config[name]["stimuli"]["order"] == "random": if config[name]["stimuli"]["order"] == "random":
random.shuffle(order) #in random order random.shuffle(order) #in random order
session["block_order"][name] = order session["block_order"][name] = order
case "empty":
order = list(config[name]["stimuli"]["list"]) # order = list of simuli keys
print("order: ",order)
session["block_order"][name] = order
if "stimuli" in current_block: if "stimuli" in current_block:
#get the name of the current stimulus #get the name of the current stimulus
@ -245,8 +252,21 @@ def jsonform():
# erster Fall: SinglePage # erster Fall: SinglePage
if current_block["type"] == "SinglePage": if current_block["type"] == "SinglePage":
return render_template(current_block["template"]) return render_template(current_block["template"])
#zweiter Fall, empty TaskTemplate
if current_block["type"] == "TaskTemplate" and current_block["stimuli"]["type"] == "empty":
current_block_order = session["block_order"][session["current_block_name"]]
current_block_stimuli = current_block["stimuli"]
current_stimulus = current_block_order[session["current_stimulus_index"]]
stimulus_type=current_block["stimuli"]["type"]
return render_template(
"standard_template.html",
stimuli=current_block_stimuli,
stimulus_type=stimulus_type,
current_stimulus=current_stimulus,
questions=current_block["questions"]
)
# ansonsten, templates: # ansonsten, templates:
@ -318,14 +338,15 @@ def sendpage_json():
return "There was a problem while adding the response to the Database" return "There was a problem while adding the response to the Database"
# handle possible Video that was send # handle possible Video that was send
formatted_date = date.strftime("%Y.%m.%d %H-%M-%S") if 'recordedVideo' in request.files:
print("date: ", date) video = request.files['recordedVideo']
video = request.files['recordedVideo'] formatted_date = date.strftime("%Y.%m.%d %H-%M-%S")
video_name = str(session_user_id) + "_" + session["current_block_name"] + "_" + session["current_stimulus_name"] + "_" + str(formatted_date) + ".webm" print("date: ", date)
path = os.path.join(UPLOAD_FOLDER, video_name) video_name = str(session_user_id) + "_" + session["current_block_name"] + "_" + session["current_stimulus_name"] + "_" + str(formatted_date) + ".webm"
print("path: ",path) path = os.path.join(UPLOAD_FOLDER, video_name)
os.makedirs(UPLOAD_FOLDER, exist_ok=True) print("path: ",path)
video.save(path) os.makedirs(UPLOAD_FOLDER, exist_ok=True)
video.save(path)
# Now move to the next stimulus or block # Now move to the next stimulus or block

View File

@ -1,5 +1,141 @@
{ {
"Block 3":{ "Block 3":{
"type": "TaskTemplate",
"tempalte": "standard_template.html",
"stimuli":{
"type":"empty",
"list":{
"empty_stimulus":""
}
},
"questions":{
"question1_alter":{
"type": "numberinput",
"name": "alter",
"text": "Alter:",
"required": "true",
"min": "1",
"max": "120"
},
"question2_geschlecht":{
"type": "dropdowninput",
"name": "geschlecht",
"text": "Geschlecht:",
"required": "true",
"defaulttext": "",
"points":{
"männlich":{
"value":"Männlich",
"text":"Männlich"
},
"weiblich":{
"value":"Weiblich",
"text":"Weiblich"
},
"divers":{
"value":"Divers",
"text":"Divers"
},
"keine_angabe":{
"value":"keine_angabe",
"text":"Keine Angabe"
}
}
},
"question3_hoerstatus":{
"type": "dropdowninput",
"name": "hoerstatus",
"text": "Hörstatus:",
"required": "true",
"defaulttext": "",
"points":{
"hörend":{
"value":"Hörend",
"text":"Hörend"
},
"schwerhörig":{
"value":"Schwerhörig",
"text":"Schwerhörig"
},
"gehörlos":{
"value":"Gehörlos",
"text":"Gehörlos"
}
}
},
"question4_bevorzugte_kommunikation":{
"type": "dropdowninput",
"name": "bevorzugte_kommunikation",
"text": "Bevorzugte Kommunikationsform:",
"required": "true",
"defaulttext": "",
"points":{
"gesprochen":{
"value":"Gesprochene Sprache",
"text":"Gesprochene Sprache"
},
"text":{
"value":"Text",
"text":"Text"
},
"gebärdensprache":{
"value":"Gebärdensprache",
"text":"Gebärdensprache"
}
}
},
"question5_gebeardenzeitraum":{
"type": "numberinput",
"name": "gebärdenzeitraum",
"text": "Wie viele Jahre verwenden sie schon Gebärdensprache:",
"required": "true",
"min": "0",
"max": "100",
"step": "0.5"
},
"question6_sprachkompetenz":{
"type": "numberinput",
"name": "gebärdensprachkompetenz",
"text": "Wie schätzen sie ihre Gebärdensprachkompetenz ein (1-10):",
"required": "true",
"min": "1",
"max": "10"
}
},
"database_table" :{
"table_name": "default_demographic_test",
"fields": {
"alter":{
"type": "integer",
"nullable": "false"
},
"geschlecht":{
"type": "string",
"size": "14",
"nullable": "false"
},
"hoerstatus":{
"type": "string",
"size": "14",
"nullable": "false"
},
"bevorzugte_kommunikation":{
"type": "string",
"size": "22",
"nullable": "false"
},
"gebärdenzeitraum":{
"type": "float",
"nullable": "false"
},
"gebärdensprachkompetenz":{
"type": "integer",
"nullable": "false"
}
}
}
},
"Block 4":{
"type": "TaskTemplate", "type": "TaskTemplate",
"tempalte": "standard_template.html", "tempalte": "standard_template.html",
"number_of_pages":"3", "number_of_pages":"3",
@ -19,6 +155,7 @@
"question1":{ "question1":{
"type": "likert", "type": "likert",
"name": "likertscale", "name": "likertscale",
"text": "How would you rate this video?",
"required": "true", "required": "true",
"points":{ "points":{
"p1":{ "p1":{
@ -46,11 +183,13 @@
"question2":{ "question2":{
"type": "textinput", "type": "textinput",
"name": "text_feedback", "name": "text_feedback",
"text": "Here you can give us Feedback",
"required": "false", "required": "false",
"size": "250" "size": "250"
}, },
"question3":{ "question3":{
"type": "videoinput", "type": "videoinput",
"text": "Here you can give us Feedback as video",
"name": "video_feedback", "name": "video_feedback",
"required": "false" "required": "false"
} }

View File

@ -1,15 +1,34 @@
html {
height: 100%;
}
body { body {
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
display: flex;
justify-content: center;
/*align-items: center; this will make the content a square, with edges up and bottom*/ /*align-items: center; this will make the content a square, with edges up and bottom*/
background-color: #a4b5ff; background-color: #a4b5ff;
color: #000000; color: #000000;
font-family: Tahoma; font-family: Tahoma;
font-size: 16px; font-size: 16px;
} }
.centercontent {
height: 100%;
display: flex;
justify-content: center;
}
.container {
height: 100%;
width: 80%; /* You can adjust this width as needed */
max-width: 1200px; /* Maximum width to keep it from getting too wide on large screens */
padding: 20px;
background-color: #7b8cdb; /* Just for visual differentiation */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.spacer { .spacer {
clear: both; clear: both;
@ -44,13 +63,7 @@ body {
.textarea-label{ .textarea-label{
align-self: flex-start; /* Aligns the label to the start of the container */ align-self: flex-start; /* Aligns the label to the start of the container */
} }
.container {
width: 80%; /* You can adjust this width as needed */
max-width: 1200px; /* Maximum width to keep it from getting too wide on large screens */
padding: 20px;
background-color: #7b8cdb; /* Just for visual differentiation */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
video { video {
max-width: 100%; max-width: 100%;
@ -127,6 +140,10 @@ iframe {
form { form {
text-align: center; text-align: center;
display: flex;
flex-direction: column;
align-items: center;
} }
.centertext { .centertext {

View File

@ -25,6 +25,18 @@ required
{% endif %} {% endif %}
{%- endmacro %} {%- endmacro %}
{% macro inputconfig(question) -%}
{% if ("min" in question) %}
min={{question["min"]}}
{% endif %}
{% if ("max" in question) %}
max={{question["max"]}}
{% endif %}
{% if ("step" in question) %}
step={{question["step"]}}
{% endif %}
{%- endmacro %}
{% macro input(name, value='', type='text', size=20) -%} {% macro input(name, value='', type='text', size=20) -%}
<input type="{{ type }}" name="{{ name }}" value="{{ <input type="{{ type }}" name="{{ name }}" value="{{
value|e }}" size="{{ size }}"> value|e }}" size="{{ size }}">
@ -45,11 +57,12 @@ required
</head> </head>
<body> <body>
<div class="centercontent">
<div class="container"> <div class="container">
<h2>Stimulus part</h2> <h2>Stimulus part</h2>
{% if (stimulus_type == "single_video") %} {% if (stimulus_type == "single_video") %}
{{ single_video(**stimulus_configuration) }} {{ single_video(**stimulus_configuration) }}
{% elif (False) %} {% elif (stimulus_type == "empty") %}
{% else %} {% else %}
<p>Error: Block {{ stimulus["type"] }} could not be loaded!</p> <p>Error: Block {{ stimulus["type"] }} could not be loaded!</p>
@ -63,26 +76,65 @@ required
{% if (questions[question]["type"] == "likert") %} {% if (questions[question]["type"] == "likert") %}
<div class="likercontainer"> <div class="likercontainer">
<div class="likert"> <div class="likert">
{{ questions[question]['text']}}
{% for point in questions[question]["points"] %} {% for point in questions[question]["points"] %}
<label><input name="likertscale" type="radio" <label>
<input name="{{ questions[question]['name']}}" type="radio" id="{{ questions[question]['name'] }}"
value="{{ questions[question]['points'][point]['value'] }}" value="{{ questions[question]['points'][point]['value'] }}"
{{required(questions[question])}} /><span>{{ questions[question]['points'][point]['text'] {{required(questions[question])}} /><span>{{ questions[question]['points'][point]['text']
}}</span></label> }}</span>
</label>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% elif (questions[question]["type"] == "textinput") %} {% elif (questions[question]["type"] == "textinput") %}
<div class="textarea-container"> <div class="textarea-container">
<label class="textarea-label" for="{{ questions[question]['name'] }}">Additional Feedback: </label> <label class="textarea-label">
<textarea id="{{ questions[question]['name'] }}" name="{{ questions[question]['name'] }}" rows="6" {{ questions[question]['text']}}
<textarea id="{{ questions[question]['name'] }}" name="{{ questions[question]['name'] }}" rows="6"
cols="60" maxlength="{{ questions[question]['size'] }}" cols="60" maxlength="{{ questions[question]['size'] }}"
{{required(questions[question])}}></textarea> {{required(questions[question])}}></textarea>
</label>
</div> </div>
{% elif (questions[question]["type"] == "dateinput") %}
<label>
{{ questions[question]['text']}}
<input type="date" name="{{ questions[question]['name']}}" id="{{ questions[question]['name'] }}" {{required(questions[question])}}>
</label>
{% elif (questions[question]["type"] == "numberinput") %}
<label>
{{ questions[question]['text']}}
<input type="number" name="{{ questions[question]['name']}}" id="{{ questions[question]['name'] }}" {{inputconfig(questions[question])}} {{required(questions[question])}}>
</label>
{% elif (questions[question]["type"] == "emailinput") %}
<label>
{{ questions[question]['text']}}
<input type="email" name="{{ questions[question]['name']}}" id="{{ questions[question]['name'] }}" {{required(questions[question])}}>
</label>
{% elif (questions[question]["type"] == "dropdowninput") %}
<label>
{{ questions[question]['text']}}
<select name="{{ questions[question]['name']}}" {{required(questions[question])}}>
<option value="" disabled selected>{{ questions[question]['defaulttext']}}</option>
{% for point in questions[question]["points"] %}
<option name="{{ point }}" id="{{ point }}"
value="{{ questions[question]['points'][point]['value'] }}"
{{required(questions[question])}}><span>{{ questions[question]['points'][point]['text']
}}</span></option>
{% endfor %}
</select>
</label>
{% elif (questions[question]["type"] == "videoinput") %} {% elif (questions[question]["type"] == "videoinput") %}
<h2>Gib Feedback als Video</h2> <h2>Gib Feedback als Video</h2>
<div class="centertext"> <div class="centertext">
{{ questions[question]['text']}}
<button type="button" class="videocontrols" id="buttonCamera" onclick="cameraButton()"> <button type="button" class="videocontrols" id="buttonCamera" onclick="cameraButton()">
<img id="buttonCameraIcon" src="{{ url_for('static', filename='icons/camera-icon.png')}}" <img id="buttonCameraIcon" src="{{ url_for('static', filename='icons/camera-icon.png')}}"
alt="Camera Icon"> alt="Camera Icon">
@ -91,7 +143,7 @@ required
</div> </div>
<div class="spacer" aria-hidden="true" style="height:30px"></div> <div class="spacer" aria-hidden="true" style="height:30px"></div>
<div class="centertext"> <div class="centertext">
<button type="button" class="videocontrols" id="buttonRecord" style="display:none" <button type="button" class="videocontrols" id="buttonRecord" style="display:none"
onclick="recordButton()"> onclick="recordButton()">
<img id="buttonRecordIcon" src="{{ url_for('static', filename='icons/record-icon.png')}}" <img id="buttonRecordIcon" src="{{ url_for('static', filename='icons/record-icon.png')}}"
@ -123,6 +175,7 @@ required
</div> </div>
</form> </form>
</div> </div>
</div>
</body> </body>
</html> </html>

View File

@ -8,6 +8,8 @@
</head> </head>
<body> <body>
<div class="centercontent">
<div class="container">
<h2>Hello! Thank you for participating in our study!</h2> <h2>Hello! Thank you for participating in our study!</h2>
<form action="http://localhost:5000/start" method="post"> <form action="http://localhost:5000/start" method="post">
<label for="terms-and-conditions"> <label for="terms-and-conditions">
@ -16,6 +18,8 @@
<p><input id="submitbutton" type = "submit" value = "submit" /></p> <p><input id="submitbutton" type = "submit" value = "submit" /></p>
</form> </form>
</div>
</div>
</body> </body>
</html> </html>

View File

@ -9,6 +9,7 @@
</head> </head>
<body> <body>
<div class="centercontent"></div>
<div class="container"> <div class="container">
<p>This is just a test page for the single page option of the json configuration, but without something to submit</p> <p>This is just a test page for the single page option of the json configuration, but without something to submit</p>
<form action="http://localhost:5000/send_json" method="post"> <form action="http://localhost:5000/send_json" method="post">
@ -16,5 +17,6 @@
<p><input id="submitbutton" type = "submit" value = "submit";/></p> <p><input id="submitbutton" type = "submit" value = "submit";/></p>
</form> </form>
</div> </div>
</div>
</body> </body>
</html> </html>

View File

@ -9,6 +9,7 @@
</head> </head>
<body> <body>
<div class="centercontent">
<div class="container"> <div class="container">
<p>This is just a test page for the single page option of the json configuration</p> <p>This is just a test page for the single page option of the json configuration</p>
<form action="http://localhost:5000/send_json" method="post"> <form action="http://localhost:5000/send_json" method="post">
@ -21,5 +22,6 @@
<p><input id="submitbutton" type = "submit" value = "submit";/></p> <p><input id="submitbutton" type = "submit" value = "submit";/></p>
</form> </form>
</div> </div>
</div>
</body> </body>
</html> </html>

View File

@ -8,6 +8,7 @@
</head> </head>
<body> <body>
<div class="centercontent">
<div class="container"> <div class="container">
<h2>Hello! Thank you for participating in our study!</h2> <h2>Hello! Thank you for participating in our study!</h2>
<form action="http://localhost:5000/teststart" method="post"> <form action="http://localhost:5000/teststart" method="post">
@ -18,6 +19,7 @@
<p><input id="submitbutton" type = "submit" value = "submit" /></p> <p><input id="submitbutton" type = "submit" value = "submit" /></p>
</form> </form>
</div> </div>
</div>
</body> </body>
</html> </html>