Implements create_question

This commit is contained in:
AliasAlreadyTaken 2024-09-12 13:41:27 +02:00
parent d4cf7d98a6
commit ed01ad4ec2
4 changed files with 186 additions and 16 deletions

View File

@ -101,7 +101,7 @@ yl_survey.evaluate(s_id)
??? How do we evaluate that stuff ???
```
yl_survey.create_question(s_id, question, category, sort, {type}, {answers})
yl_survey.create_question(s_id, question, category, sort, {allowed_types}, {answers}, enabled)
```
Returns `true, q_id` if successful, `false, "errormessage` if not.
@ -112,11 +112,12 @@ Adds a question to the survey identified by `s_id`.
* question: string, required. This is the question text the survey asks its respondents.
* category: string, optional, default empty. Use it for additonal explanation, category, help. Is displayed near the question. May be nil or empty.
* sort: integer, optional, defaults to the next free number. Use this to order your questions.
* {type}: table of enum("singlechoice","multiplechoice","freetext"), required. `singlechoice` and `multiplechoice` are mutually exclusive, while freetxt can be combined with either.
* {allowed_types}: table of enum("singlechoice","multiplechoice","freetext"), required. `singlechoice` and `multiplechoice` are mutually exclusive, while freetxt can be combined with either.
* {answers}: table of strings, optional. Holds the answers to a singlechoice or multiplechoice question.
* enabled: boolean, optional, defaults to true. If true, the question is delivered to a participant. If false, the question is hidden.
```
yl_survey.edit_question(s_id, q_id, question, sort, category, {type}, {answers}, delete_responses)
yl_survey.edit_question(s_id, q_id, question, sort, category, {allowed_types}, {answers}, enabled, delete_responses)
```
Returns `true, q_id` if successful, `false, "errormessage` if not.

146
api.lua
View File

@ -1,3 +1,6 @@
--
-- Surveys
--
-- yl_survey.get_data
--
local function get_data()
@ -32,11 +35,45 @@ end
local function validate(value, expect_type, allow_nil)
if ((allow_nil == true) and (value == nil)) then return true end
if ((allow_nil == false) and (value == nil)) then return true end
if ((allow_nil == false) and (value == nil)) then return false end
if (type(value) == expect_type) then return true end
return false
end
local function validate_questiontype(allowed_types)
local valid_types = {
singlechoice = true,
multiplechoice = true,
freetext = true
}
local sm_count = 0
local ft_count = 0
for _, t in ipairs(allowed_types) do
-- Invalid question type
if (valid_types[t] == nil) then return false end
-- Either singlechoice OR multiplechoice
if ((t == "singlechoice") or (t == "multiplechoice")) then
sm_count = sm_count + 1
end
if sm_count > 1 then return false end
-- Only one freetext allowed
if (t == "freetext") then ft_count = ft_count + 1 end
if ft_count > 1 then return false end
end
if ((ft_count + sm_count) == 0) then return false end
return true
end
local function create_survey(owner, allow_names, allow_anonymous, allow_changes,
timestamp_start, timestamp_end)
-- Defense
@ -77,7 +114,8 @@ local function create_survey(owner, allow_names, allow_anonymous, allow_changes,
if ((allow_names == false) and (allow_anonymous == false) and
(allow_changes == false)) then
return false, yl_survey.t("Noone can take part in that survey. " ..
"Neither named nor anonymous participants are allowed and you can't change it later")
"Neither named nor anonymous participants are allowed. " ..
" You can't change it later")
end
-- Specialcase: We don't accept surveys where the enddate is smaller than the startdate
@ -164,6 +202,9 @@ local function edit_survey(id, owner, allow_names, allow_anonymous,
local record = yl_survey.get_record(id)
if (record == nil) then
return false, yl_survey.t("record does not exist")
end
if (record["metadata"].allow_changes == false) then
return false, yl_survey.t("no changes allowed")
end
@ -182,6 +223,12 @@ local function edit_survey(id, owner, allow_names, allow_anonymous,
record["metadata"] = metadata
-- Delete responses
local no
if (delete_responses == true) then
record, no = yl_survey.delete_responses(record)
end
-- Store
local success = yl_survey.save(id, record)
if (success == true) then
@ -205,9 +252,7 @@ end
local function remove_record(id)
local data_success, data = yl_survey.get_data()
if (data_success ~= true) then
return false, "Cannot get data"
end
if (data_success ~= true) then return false, "Cannot get data" end
local remove_success = yl_survey.remove_file(id)
if (remove_success ~= true) then
@ -223,6 +268,93 @@ local function remove_record(id)
return true, record
end
function yl_survey.remove_record(id)
return remove_record(id)
function yl_survey.remove_record(id) return remove_record(id) end
--
-- Questions
--
local function create_question(id, question, category, sort, allowed_types,
answers, enabled)
-- Defense
if (validate(id, "string", false) == false) then
return false, yl_survey.t("id must be string")
end
if (validate(question, "string", false) == false) then
return false, yl_survey.t("question must be string")
end
if (category == nil) then category = "" end
if (validate(category, "string", false) == false) then
return false, yl_survey.t("category must be string")
end
if (validate_nil_or_positive(sort) == false) then
return false, yl_survey.t("sort must be positive number")
end
if (validate(allowed_types, "table", false) == false) then
return false, yl_survey.t("allowed_types must be table")
end
if (validate(answers, "table", true) == false) then
return false, yl_survey.t("answers must be table")
end
if (enabled == nil) then enabled = true end
if (validate(enabled, "boolean", false) == false) then
return false, yl_survey.t("enabled must be boolean")
end
-- Specialcase : allowed_types must be a combination of
-- "singlechoice" or "multiplechoice" or "freetext"
if (validate_questiontype(allowed_types) == false) then
return false, yl_survey.t("wrong allowed_types")
end
-- Specialcase : answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice
if (((answers == nil) or (next(answers) == nil)) and
((allowed_types["multiplechoice"] ~= nil) or
(allowed_types["singlechoice"] ~= nil))) then
return false, yl_survey.t(
"answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice")
end
local record = yl_survey.get_record(id)
if (record == nil) then
return false, yl_survey.t("record does not exist")
end
if (record["metadata"].allow_changes == false) then
return false, yl_survey.t("no changes allowed")
end
-- Payload
-- if sort is nil, then find next sort
local next_sort = sort or yl_survey.find_next_free_number(record, "sort")
-- Find next free q_id
local next_q_id = yl_survey.find_next_free_number(record, "id")
local t_question = {
id = next_q_id,
category = category,
sort = next_sort,
question = question,
enabled = true,
allowed_types = allowed_types,
answers = answers,
responses = {}
}
record[tostring(next_q_id)] = t_question
-- Store
local success = yl_survey.save(id, record)
if (success == true) then
yl_survey.data[id] = record
return true, next_q_id
else
return false, yl_survey.t("Could not store")
end
end
function yl_survey.create_question(id, question, category, sort, allowed_types,
answers)
return create_question(id, question, category, sort, allowed_types, answers)
end

View File

@ -20,8 +20,8 @@ remove_survey(s_id)
list_surveys()
evaluate(s_id)
create_question(s_id, question, category, sort, {type}, {answers}) return q_id
edit_question(s_id, q_id, question, sort, category, {type}, {answers}, delete_responses)
create_question(s_id, question, category, sort, {allowed_types}, {answers}) return q_id
edit_question(s_id, q_id, question, sort, category, {allowed_types}, {answers}, delete_responses)
remove_question(q_id)
list_questions()
@ -49,12 +49,12 @@ This is the planned data structure:
"sort": 99,
"question": "How did you find out about Minetest in general?",
"enabled" : true,
"type": [
"allowed_types": [
"singlechoice",
"multiplechoice",
"freetext"
],
"answer": {
"answers": {
"1": "Friend dragged me over",
"2": "I came here of my own free will"
},
@ -76,12 +76,12 @@ This is the planned data structure:
"sort": 2,
"question": "What do you think about the current state of the server?",
"enabled" : true,
"type": [
"allowed_types": [
"singlechoice",
"multiplechoice",
"freetext"
],
"answer": {
"answers": {
"0": "Write your answer here",
"1": "Terrible",
"2": "Not soo bad"

View File

@ -82,6 +82,43 @@ end
function yl_survey.create_uuid() return create_uuid() end
-- delete responses
local function delete_responses(record)
local no = 0
for key, question in pairs(record) do
if (tonumber(key) ~= nil) then
if question.responses ~= nil then
question.responses = nil
no = no + 1
end
end
end
return record, no
end
function yl_survey.delete_responses(record)
return delete_responses(record)
end
-- yl_survey.find_next_free_sort_number(record)
local function find_next_free_number(record, target)
local highest_no = 1
for key, question in pairs(record) do
if (tonumber(key) ~= nil) then
if (question[target] > highest_no) then
highest_no = question[target] + 1
end
end
end
return highest_no
end
function yl_survey.find_next_free_number(record, target)
return find_next_free_number(record, target)
end
-- Load and save
local function get_savepath()