You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by cu...@apache.org on 2019/05/27 00:45:06 UTC
[whimsy] 01/02: Implement everything except final submission
This is an automated email from the ASF dual-hosted git repository.
curcuru pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git
commit 33ca2dfa66682ef5b0dedd4e80c1816b5c69cf22
Author: Shane Curcuru <as...@shanecurcuru.org>
AuthorDate: Sun May 26 18:18:03 2019 -0400
Implement everything except final submission
---
www/officers/surveys.cgi | 93 ++++++++++++++++++------------------------------
1 file changed, 34 insertions(+), 59 deletions(-)
diff --git a/www/officers/surveys.cgi b/www/officers/surveys.cgi
index 93bec91..9da47aa 100755
--- a/www/officers/surveys.cgi
+++ b/www/officers/surveys.cgi
@@ -31,29 +31,43 @@ def display_alert(lead: 'Error', body: '', type: 'alert-danger')
end
end
-# Emit HTML for a survey_layout form, or display any errors
+# Convenience method to sanitize/construct paths to .json
+# @param filename to request, either a layout or datafile
+# @return sanitized path/filename
+def get_survey_path(f)
+ filename = f
+ filename ||= 'NO_DATAFILE_GIVEN' # For display in errors later
+ filename.gsub!(/[^0-9A-Z.-]/i, '_') # Sanitize input (should only be a filename)
+ filename << DOTJSON if not filename.end_with?(DOTJSON)
+ return File.join(OFFICERS_SURVEYS, filename)
+end
+
+# Emit HTML for a survey_layout form, or display any errors in response to a GET
# Currently, user can only submit a survey_data once
+# @param hash containing entire survey layout
def display_survey(survey_layout)
warning = false
- survey_file = File.join(OFFICERS_SURVEYS, (survey_layout[:datafile] ||= ''))
- if File.file?(survey_file)
+ survey_file = get_survey_path(survey_layout[SURVEY][:datafile]).untaint
+ if survey_layout.has_key?(ERRORS)
+ display_alert(lead: 'Error: could not load survey layout!', body: "#{survey_layout[ERRORS]} Contact the survey owner: #{survey_layout[SURVEY][CONTACT]}.")
+ elsif File.file?(survey_file)
survey_data = {}
begin
survey_data = JSON.parse(File.read(survey_file), :symbolize_names => true)
# Check if the user has already submitted this survey
if survey_data.has_key?($USER.to_sym)
- display_alert(lead: 'Warning: User already submitted survey data!', body: "#{__method__}(#{survey_file}) You appear to have **already submitted** this survey data; if needed edit the survey.json in SVN, or contact #{survey_layout[SURVEY][CONTACT]} with questions.")
- warning = true # TODO should we bail or continue?
+ display_alert(lead: 'Warning: User already submitted survey data!', body: "#{__method__}(#{survey_file}) You appear to have **already submitted** this survey data (can't submit again); if needed edit the survey.json in SVN, or contact the survey owner: #{survey_layout[SURVEY][CONTACT]}.")
+ warning = true
end
rescue StandardError => e
display_alert(lead: 'Error: parsing survey datafile!', body: "**#{__method__}(#{survey_file}) #{e.message}**\n\n #{e.backtrace[0]}")
- warning = true # TODO should we bail or continue?
+ warning = true
end
else
- display_alert(lead: 'Warning: could not find survey datafile!', body: "**#{__method__}(#{survey_file})** the data file to store survey answers was not supplied or found; contact #{survey_layout[SURVEY][CONTACT]} with questions.")
- warning = true # TODO should we bail or continue?
+ display_alert(lead: 'Warning: could not find survey datafile!', body: "**#{__method__}(#{survey_file})** the data file to store survey answers was not supplied or found; contact the survey owner: #{survey_layout[SURVEY][CONTACT]}.")
+ warning = true
end
-
+
# Emit the survey, or the default one which provides help on the survey tool
_whimsy_panel("#{survey_layout[SURVEY][FORM][:title]} (user: #{$USER})", style: 'panel-success') do
_form.form_horizontal method: 'post' do
@@ -78,10 +92,10 @@ def validate_survey(formdata: {})
return true # TODO: Futureuse
end
-# Handle submission (checkout user's apacheid.json, write form data, checkin file)
+# Handle POST submission (checkout user's apacheid.json, write form data, checkin file)
# @return true if we think it succeeded; false in all other cases
def submit_survey(formdata: {})
- fn = "#{formdata[:datafile]}.json".untaint # TODO: check path/file here
+ fn = get_survey_path(formdata[:datafile]).untaint
submission_data = JSON.pretty_generate(formdata) + "\n"
_div.well do
_p.lead "Submitting your survey data to: #{fn}"
@@ -111,56 +125,16 @@ For now, see the code for more help, or contact dev@whimsical for questions on h
submitpass: 'This *markdown-able* message would be displayed after a successful svn commit of survey data.',
submitfail: 'This *markdown-able* message would be displayed after a **FAILED** svn commit of survey data.',
form: {
- title: 'Survey Form Title',
- buttonhelp: 'This sample survey won\'t work, but you can still press Submit below!',
- buttontext: 'Submit',
+ title: 'Survey Help',
+ buttonhelp: 'This sample survey won\'t work, but you can still press the button below if you like!',
+ buttontext: 'Do Not Press',
fields: [
- {
- name: 'field1',
- type: 'text',
- label: 'This field is:',
- helptext: 'This text would explain the field1 (optional)'
- },
- {
- name: 'field2',
- type: 'text',
- rows: '3',
- label: 'This is multiline:',
- helptext: 'This text would explain the field2 (optional)'
- },
- {
- name: 'subhead',
- type: 'subhead',
- label: 'This is a form separator'
- },
- {
- name: 'field4',
- type: 'select',
- label: 'Select some values',
- helptext: 'This text would explain why you should select many values (required)',
- multiple: true,
- options: ['First', 'Second', 'Penultimate', 'Last place', '2First', '2Second', '2Penultimate', '2Last place', 'aFirst', 'aSecond', 'aPenultimate', 'aLast place']
- },
- {
- name: 'field5',
- type: 'radio',
- label: 'Radiobuttons:',
- helptext: 'Please tune in the radio (optional)',
- options: ['99.8', '100.0', '100.2', '100.4']
- },
- {
- name: 'field6',
- type: 'checkbox',
- label: 'Checkboxes:',
- helptext: 'Check one, check them all, have fun! (optional)',
- options: ['Abbot', 'Costello', 'Marx', 'Three Stooges']
- }
]
}
}
# Load survey layout hash from QUERY_STRING ?survey=surveyname
-# @return {} of form layout data for survey; or a default layout of help with ERRORS also set
+# @return {PARAMS: {}, SURVEY: {}, ERRORS: ""} of form layout data for survey; or a default layout of help with ERRORS also set
# Note: does not validate that the survey has a place to store data; only that the layout exists
def get_survey_layout(query)
params = {}
@@ -170,7 +144,7 @@ def get_survey_layout(query)
end
data = {}
data[PARAMS] = params
- filename = File.join(OFFICERS_SURVEYS, "#{params['survey']}.json".gsub(/[^0-9A-Z.-]/i, '_')) # Use 'survey' as string here; sanitize input
+ filename = get_survey_path(params['survey'])
begin
data[SURVEY] = JSON.parse(File.read(filename.untaint), :symbolize_names => true) # TODO: Security, ensure user should have access
rescue StandardError => e
@@ -208,9 +182,9 @@ _html do
formdata = _whimsy_params2formdata(_.params)
formdata[:datafile] = survey_layout[SURVEY][:datafile] # Also pass thru datafile from layout
if validate_survey(formdata: formdata) && submit_survey(formdata: formdata)
- display_alert(lead: 'Survey Submitted', body: survey_layout[SURVEY][:submitpass], type: 'alert-success')
- else
- display_alert(lead: 'Submission Failed', body: survey_layout[SURVEY][:submitfail])
+ display_alert(lead: 'Survey Submitted', body: survey_layout[SURVEY][:submitpass], type: 'alert-success')
+ else
+ display_alert(lead: 'Submission Failed', body: survey_layout[SURVEY][:submitfail])
end
else # if _.post?
display_survey(survey_layout)
@@ -218,3 +192,4 @@ _html do
end
end
end
+