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:05 UTC

[whimsy] branch master updated (071c22f -> 71e718b)

This is an automated email from the ASF dual-hosted git repository.

curcuru pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git.


    from 071c22f  Implement survey_layout read; improve UI
     new 33ca2df  Implement everything except final submission
     new 71e718b  Improve error display when svn not there

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 www/officers/surveys.cgi | 131 ++++++++++++++++++++++++-----------------------
 1 file changed, 67 insertions(+), 64 deletions(-)


[whimsy] 02/02: Improve error display when svn not there

Posted by cu...@apache.org.
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 71e718bd354f9d8d5ea024d26c5bc32ff3aad23d
Author: Shane Curcuru <as...@shanecurcuru.org>
AuthorDate: Sun May 26 20:44:56 2019 -0400

    Improve error display when svn not there
---
 www/officers/surveys.cgi | 42 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/www/officers/surveys.cgi b/www/officers/surveys.cgi
index 9da47aa..077aee5 100755
--- a/www/officers/surveys.cgi
+++ b/www/officers/surveys.cgi
@@ -14,7 +14,7 @@ require 'whimsy/asf/rack'
 require 'json'
 require 'cgi'
 
-OFFICERS_SURVEYS = ASF::SVN['officers_surveys']
+OFFICERS_SURVEYS = 'officers_surveys'
 SURVEY = :survey
 ERRORS = :errors
 PARAMS = :params
@@ -39,7 +39,12 @@ def get_survey_path(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)
+  # test
+  begin
+    return File.join(ASF::SVN[OFFICERS_SURVEYS], filename)
+  rescue Exception => e
+    return "ERROR-NO-OFFICERS_SURVEYS-CHECKOUT" # Improve error display in browser
+  end
 end
 
 # Emit HTML for a survey_layout form, or display any errors in response to a GET
@@ -95,15 +100,38 @@ end
 # 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 = get_survey_path(formdata[:datafile]).untaint
+  filename = get_survey_path(formdata[:datafile]).untaint
+  formdata.delete(:datafile)
   submission_data = JSON.pretty_generate(formdata) + "\n"
   _div.well do
-    _p.lead "Submitting your survey data to: #{fn}"
+    _p.lead "Submitting your survey data to: #{filename}"
     _pre submission_data
-    _p "DEBUG: not sending any data for testing! 20190525-sc DEBUG: need to add to existing file, not overwrite"
   end
-  return true # DEBUG: not sending any data for testing! 20190525-sc
-  # TODO svn checkout, add data as $USER => {submission_data...}
+
+  rc = 999 # Ensure it's a bogus value
+  Dir.mktmpdir do |tmpdir|
+    tmpdir.untaint
+    credentials = ['--username', $USER, '--password', $PASSWORD]
+    svnopts = ['--depth',  'files', '--no-auth-cache', '--non-interactive']
+    _.system ['svn', 'checkout', OFFICERS_SURVEYS, tmpdir, svnopts, credentials]
+    
+    survey_data = JSON.parse(File.read(filename), :symbolize_names => true)
+    # Add user data (may overwrite existing entry!)
+    survey_data[$USER] = formdata
+    # Sort file (to keep diff clean) and write it back
+    survey_data = Hash[survey_data.keys.sort.map {|k| [k, survey_data[k]]}]
+    File.write(filename, JSON.pretty_generate(survey_data))
+
+    _p "DEBUG: not sending any data for testing! 20190525-sc"
+    _p JSON.pretty_generate(survey_data) # DEBUG
+    
+    Dir.chdir tmpdir do
+      # rc = _.system ['svn', 'commit', filename, '--message', "Survey submission (whimsy)",
+      #   ['--no-auth-cache', '--non-interactive'], credentials]
+    end
+  end
+  
+    return false
 end
 
 DEFAULT_SURVEY = {


[whimsy] 01/02: Implement everything except final submission

Posted by cu...@apache.org.
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
+