Exemple #1
0
  def answer_question_action(self, request, id, ans, com):
    creator = request.session.user
    item = datagate.get_item(id)
    answers = item.search1(name="answers")
    #if this user has already answered this question, update it instead of creating it
    answer = None
    for each in answers:
      if each.who == creator.name:
        answer = each
    if not answer:
      answer = datagate.create_item(creatorid=creator.id, parentid=answers.id)
    
    answer.name = 'answer'
    answer.who = creator.name
    answer.when = time.strftime('%a, %d %b %Y %H:%M:%S')
    answer.answer = ans
    answer.comment = com
    answer.save()
    
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    activities = parent.search1(view='questioneditor')
    userAnswer = activities.search1(name="userAnswers")
    userFound = False
    if userAnswer != None:
      for user in userAnswer:
        if user.name == creator.name:
          userFound = True
          answered = None
          for child in user:
            if child.questionId == id:
              answered = child
          if not answered:
            answered = datagate.create_item(creatorid=creator.id, parentid=user.id)
          answered.questionId = id
          answered.answer = ans
          answered.when = time.strftime('%a, %d %b %Y %H:%M:%S')
          answered.save()
    if userFound == False or userAnswer == None:
      userCreated = datagate.create_item(creatorid=creator.id, parentid=userAnswer.id)
      userCreated.name = creator.name
      answered = datagate.create_item(creatorid=creator.id, parentid=userCreated.id)
      answered.questionId = id
      answered.answer = ans
      answered.when = time.strftime('%a, %d %b %Y %H:%M:%S')
      answered.save()

    if id not in creator.answeredQuestions:
      creator.answeredQuestions.append(id)

    #creator.backtrack = 0 #resets the user to their first unanswered question
    if creator.backtrack < 0:
      creator.backtrack += 1 #moves the user forward one question
    creator.save()

    event = QuestionAsker.next_question(self,request,creator)
    return event
Exemple #2
0
  def exportCSV_action(self, request, filters):
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    
    events = []

    #dictionaries = answerData, answerDataAveraged, questionPOETData, questionSetData, poetData, setData 
    dictionaries = ReportFindings.makeDictionaries(self, meeting, filters, True)

    exportEvents = ReportFindings.makeExports(self, dictionaries) 
    events.extend(exportEvents)

    return events
Exemple #3
0
 def set_picked(self,request):
   creator = request.session.user
   meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
   parent = meeting.get_parent()
   meetingRoot = parent.get_parent()
   groups = meetingRoot.search1(name='groups')
   allGroups = groups.get_child_items(self)
   for group in allGroups:
     allChildren = group.get_child_items(self)
     for child in allChildren:
       if creator.id == child.user_id:
         return group.sets
   return []
Exemple #4
0
  def get_initial_events(self, request, rootid):
    '''Retrieves a list of initial javascript calls that should be sent to the client
       when the view first loads.  Typically, this is a series of add_processor
       events.'''
    global potentialQuestionList
    creator = request.session.user
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    meetingRoot = parent.get_parent()
    groups = meetingRoot.search1(name='groups')
    activities = parent.search1(view='questioneditor')
    userGroup = ''
        
    #find which user group user belongs to
    allGroups = groups.get_child_items(self)
    for group in allGroups:
      allChildren = group.get_child_items(self)
      for child in allChildren:
        if creator.id == child.user_id:
          userGroup = group.name
          #setPicked = group.sets 
          
    setPicked = QuestionAsker.set_picked(self,request)

    #get the question ids of the questions that have already been answered
    groupMapping = activities.search1(name="groupMapping")

    potentialQuestionList = ''
    for group in groupMapping:
      if group.name == userGroup:
        for child in group.get_child_items(self):
          if child.name == 'quesId':
            potentialQuestionList = child.quesId[:]

    filterParams = QuestionAsker.filter_params(self,request,setPicked)
    events = []

    try:
      if (creator.backtrack * -1) < len(creator.answeredQuestions):
        events.append(Event('enableBack'))
      else:
        events.append(Event('disableBack'))
    except AttributeError:
      creator.backtrack = 0
                    
    if not filterParams[0] == "":
      events.append(Event('populateEnd', filterParams[0],str(creator.id)))
    else:
      events.append(Event('populateForm', filterParams[1], filterParams[2], filterParams[3], filterParams[4], str(creator.id), filterParams[5]))
    return events
Exemple #5
0
 def get_initial_events(self, request, rootid):
   '''Retrieves a list of initial javascript calls that should be sent to the client
      when the view first loads.  Typically, this is a series of add_processor
      events.'''
   meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
   parent = meeting.get_parent()
   activities = parent.search1(view='questioneditor')
   events = []
   allQuestions = []
   for child in activities.search1(name="questions"):
     item = datagate.get_item(child.id)
     options = item.search1(name="options")
     allChoices = options.get_child_items(self)
     allOptions = []
     for choice in allChoices:
       allOptions.append(choice.text)
     allQuestions.append([child.id, child.text, child.format, child.comment, allOptions, options.num_selections, child.comOpt])
   return events
Exemple #6
0
  def html_update_action(self, request, filters):
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    setData = ReportFindings.makeDictionaries(self, meeting, filters, False)
    
    #for set in ["Mandatory", "Agility", "Trust", etc.]:
    sets = set([])
    for key in setData.keys():
      sets.add( key.split('|')[0] )
    sets = list(sets)

    groupsList = ["PM", "PMO", "Contractor", "Senior Stakeholder", "User"]

    htmlData = []
    firstRow = [""]
    firstRow.extend(groupsList) #["", "PM", "PMO", "Contractor", "Senior Stakeholder", "User"]
    htmlData.append(firstRow) #[ ["", "PM", "PMO", "Contractor", "Senior Stakeholder", "User"] ]
    
    for aset in sets:
      nextRow = [aset] # e.g. ["Mandatory"]
      for group in groupsList: #["PM", "PMO", "Contractor", "Senior Stakeholder", "User"]:
        try:
          responses = setData[aset+"|"+group]
          responses = filter((lambda x: x < 8), responses)
          mean = float(sum(responses))/float(len(responses))
          nextRow.append(mean)
        except KeyError:
          nextRow.append(0)
        except ZeroDivisionError:
          nextRow.append(0)
      htmlData.append(nextRow)

    #log.info("htmlData: "+str(htmlData))

    htmlString = ReportFindings.makeHTMLString(self, htmlData)
    #log.info("htmlString = "+htmlString)
    #events.append(Event('redirectCSV'))
    events = []
    events.append(Event('updateTable', htmlString))

    return events
Exemple #7
0
  def answer_question_action(self, request, id, ans, com):
    creator = request.session.user
    item = datagate.get_item(id)
    answers = item.search1(name="answers")
    answer = datagate.create_item(creatorid=creator.id, parentid=answers.id)
    answer.name = 'answer'
    answer.who = creator.name
    answer.when = time.strftime('%a, %d %b %Y %H:%M:%S')
    answer.answer = ans
    answer.comment = com
    answer.save()
    
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    activities = parent.search1(view='questioneditor')
    userAnswer = activities.search1(name="userAnswers")
    userFound = False
    if userAnswer != None:
      for user in userAnswer:
        if user.name == creator.name:
          userFound = True
          answered = datagate.create_item(creatorid=creator.id, parentid=user.id)
          answered.questionId = id
          answered.when = time.strftime('%a, %d %b %Y %H:%M:%S')
          answered.save()
    if userFound == False or userAnswer == None:
      userCreated = datagate.create_item(creatorid=creator.id, parentid=userAnswer.id)
      userCreated.name = creator.name
      answered = datagate.create_item(creatorid=creator.id, parentid=userCreated.id)
      answered.questionId = id
      answered.when = time.strftime('%a, %d %b %Y %H:%M:%S')
      answered.save()

    event = QuestionAsker.next_question(self,request)

    return event
Exemple #8
0
  def filter_params(self,request, setPicked):
    global potentialQuestionList
    creator = request.session.user
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    meetingRoot = parent.get_parent()
    groups = meetingRoot.search1(name='groups')
    activities = parent.search1(view='questioneditor')
    answered = 0
    asked = 0
    question = ''
    answeredQuestionList = []
    userGroup = ''
    userQues = ''
    qId = ''
    events = []
    end = False

    if not setPicked:
      return ["Thank you for logging in.<br/>You currently have no questions assigned for you to answer. You will be informed when questions or survey results are released to you.", 0, 0, 0]
   
    #find which user group user belongs to
    allGroups = groups.get_child_items(self)
    for group in allGroups:
      allChildren = group.get_child_items(self)
      for child in allChildren:
        if creator.id == child.user_id:
          userGroup = group.name

    #get the number of questions already answered by the user
    userAnswer = activities.search1(name="userAnswers")
    for user in userAnswer:
      if user.name == creator.name:
        userQues = user.get_child_items(self)
        #answered = len(userQues)   
        #get the list of question ids of the questions that have already been answered
        for q in userQues:
          answeredQuestionList.append(q.questionId)

    # this is equivalent to potentialQuestionList = list( set(potentialQuestionList) - set(answeredQuestionList) )
    # I'm not sure which is more efficient or readable, though.
    for q in potentialQuestionList[:]:
      for a in answeredQuestionList:
        if q == a:
          potentialQuestionList.remove(q)
    
    #make list of questions from potentialQuestionList and set selected
    setQuestionList = []
    sets = activities.search1(name="sets")
    for s in sets:
      if s.name in setPicked:
        for qIds in s.get_child_items(self):
          if qIds.name == 'quesId':
            for q in qIds.quesId:
              if(potentialQuestionList.count(q) != 0) and q not in setQuestionList:
                setQuestionList.append(q)

    if creator.initialize:
      creator.sessionQuestionList = potentialQuestionList[:]
      creator.initialize = False

    #asked = len(setQuestionList) + answered
    answered = len(creator.answeredQuestions) + creator.backtrack
    asked = len(creator.sessionQuestionList)

    preselect = ""

    if answered >= asked :
      end = "You have answered all of your questions.</br>Please log in later to view the results."
    else:
      end = ""
      if creator.backtrack < 0:
        questionId = creator.answeredQuestions[creator.backtrack]
        questionXML = datagate.get_item(questionId)
        answers = questionXML.search1(name="answers")
        question = QuestionAsker.get_question(self,questionId)
        
        #if this user has already answered this question, preselect their answer
        answer = None
        for each in answers:
          if each.who == creator.name:
            answer = each
        #answerDictionary translates answers to radioButton IDs
        answerDictionary = {'stronglydisagree': 'stdInput', 'disagree': 'dInput', 'somewhatdisagree': 'swdInput', 'neither': 'nInput',
                            'stronglyagree': 'staInput', 'agree':'aInput', 'somewhatagree':'swaInput', 'N/A':'N/A'}

        preselect = answerDictionary[answer.answer]
        #log.info("answerDictionary["+(answer.answer)+"] = preselect = "+answerDictionary[answer.answer])
      else:
        question = QuestionAsker.get_question(self,setQuestionList[0])
        preselect = ""
    
    params = [end, question, preselect, answered, asked, setPicked]
    return params
Exemple #9
0
  def send_content(self, request):
    # Sends content of page
    request.writeln(HTML_HEAD_NO_CLOSE + '<link type="text/css" rel="stylesheet" href="' + join(WEB_PROGRAM_URL, "layout.css") + '" /></head>')
    request.writeln('''<body onload='setUser("''' + str(request.session.user.id) + '''")'>''')

    thisPage = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent_id = thisPage.parentid
    parent = datagate.get_item(parent_id)
    grandparent_id = parent.parentid
    meeting = datagate.get_item(grandparent_id)

    thisPage = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = thisPage.get_parent()
    meeting = parent.get_parent()

    user_is_pm = False
    for child in meeting:
     if child.name == "groups":
       for group in child:
         if group.name == "PM":
           for pm_item in group:
             if pm_item.user_id == request.session.user.id:
               user_is_pm = True

    if request.session.user.superuser == '1' or user_is_pm:
      request.writeln('<table cellspacing="0" style="border-bottom:#99ccff 1px dotted;padding:3px;" width=100%><tr>')
      request.writeln('''<td id="menu-logo">
      			<div id="poet-logo">POET</a>
                       </td>''')

      request.writeln('<td id="user-menu">')
      request.writeln('logged in as <strong>'+request.session.user.name+'</strong>')
  
      #navigation
      if request.session.user.superuser == '1':
        request.writeln('<span class="divider">|</span> <a href="' + request.cgi_href(_adminaction=None, global_adminview=None) + '">Home</a>')
      request.writeln('  <span class="divider">|</span> <a target="_top" href="' + request.cgi_href(itemid=meeting.id, global_view='Administrator', global_adminview='POET') + '">Manage Program</a>')
      request.writeln('''<span class="divider">|</span> <a onclick='javascript:openProgInfo();'>Program Information</a> <span class="divider">|</span> <a onclick='javascript:openHelp();'>Help</a> <span class="divider">|</span> ''')
      request.writeln('<a href="' + request.cgi_href(global_view='login', _adminaction='logout') + '">Logout</a>')
      request.writeln('</td>')
      request.writeln('</tr></table>')

    if meeting.status == 0: #this might need rethinking
      msg = "Thank you for logging in.<br/>No questions have been published yet. Please return later to participate."
    else:
      msg = "Thank you for logging in.<br/>You have answered all of the questions that have been assigned to you. You will be informed when more questions or survey results are released to you."

    request.writeln('''<script src="''' + join(WEB_PROGRAM_URL, 'jquery-1.4.2.min.js') + '''"></script>''')
    request.writeln('''<script src="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.min.js') + '''"></script>''')
    request.writeln('''<link href="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.css') + '''" rel="stylesheet" type="text/css"/>''')

    request.writeln('''

      <script language='JavaScript' type='text/javascript'>
        $(function() {
		$("#progressbar").progressbar({
			value: progress
		});
	});
	
	$(function() {
		$("input:button, input:submit").button();
	});
      
        var currentQuestion;
        var progress;
	var loggedInUser;
	
	function openHelp() {
          window.open("''' + WEB_PROGRAM_URL + '''/Help/", "helpwindow", "dependent,height=800,width=1000,scrollbars,resizable");
          return false;
        }
	
	function openProgInfo() {
	  window.open("''' + WEB_PROGRAM_URL + '''/ProgInfo/", "proginfowindow", "dependent,height=800,width=1000,scrollbars,resizable");
          return false;
        }
	
	function setUser(user){
	  loggedInUser = user;
	  window.open("''' + WEB_PROGRAM_URL + '''/ProgInfo/", "proginfowindow", "dependent,height=800,width=1000,scrollbars,resizable");
	}
        
        function populateEnd(message,creator) {
	  if(creator == loggedInUser){
	    document.getElementById('progressbar').style.display = "none";   
	    document.getElementById('quesNum').style.display = "none";
	    //document.getElementById('previewQuestion').innerHTML = "'''+msg+'''";
	    document.getElementById('previewQuestion').innerHTML = message;
	    document.getElementById('previewCommentInput').style.display = "none";
	    document.getElementById('questionInput').style.display = "none";
	    document.getElementById('backButton').style.display = "inline-block";
	    document.getElementById('submitButton').style.display = "none";
	    document.getElementById('resetButton').style.display = "none";
	    document.getElementById('naInput').style.display = "none";
	  }
        }

        function populateForm(question, preselect, answered, asked, creator, set) {
	  if(creator == loggedInUser){
	     document.getElementById('setAssessment').innerHTML = "- " + set + " Questions";
	    currentQuestion = question;
             
	    document.getElementById('progressbar').style.display = "block";   
	    document.getElementById('quesNum').style.display = "block";
	    //document.getElementById('previewCommentInput').style.display = "block";
	    document.getElementById('questionInput').style.display = "block";
	    document.getElementById('backButton').style.display = "inline-block";
	    document.getElementById('submitButton').style.display = "inline-block";
	    document.getElementById('resetButton').style.display = "inline-block";
	    //document.getElementById('naInput').style.display = "none";
	    
	    //populates the questions being asked
	   $("#progressbar").progressbar({value: parseInt(100*(answered+1)/asked, 10)});
	    document.getElementById('quesNum').innerHTML = (answered+1) + " of " + asked;
	    document.getElementById('previewQuestion').innerHTML = question[1];
	    formatChanger(question[2], document.getElementById('questionInput'), question[4], question[5]);
	    if(question[3] == "yes"){
	      document.getElementById('previewCommentInput').style.display = "block";
	      document.getElementById('previewComments').value = "";
	    }else{
	      document.getElementById('previewCommentInput').style.display = "none";
	      document.getElementById('previewComments').value = "";
	    }
	    
	    if(question[7] == "na"){
	      document.getElementById('naInput').style.display = "block";
	      if(preselect == "N/A"){
                document.getElementById('naAnswer').checked = true;
	      }
	      else{
                document.getElementById('naAnswer').checked = false;
              }
	      
	    }
	    else{
	      document.getElementById('naInput').style.display = "none";
	      document.getElementById('naAnswer').checked = false;
	    }

            radioButton = document.getElementById(preselect);
            
	    if (null != radioButton){
              radioButton.checked = true;  
            }
	  }
        }

        function formatChanger(format, area, choices, num){
          //changes the answer options depending on which format the question is
          var type = 1;
          switch(format){
            case "truefalse":
              var trueFalse = '<div id="tfInput" class="radio-group">';
              trueFalse += '<span class="radio-option">';
              trueFalse += '<input id="trueInput" type="radio" name="trueFalseInput" value="true" /> ';
              trueFalse += '<label for="trueInput">True</label></span>  ';
              trueFalse += '<span class="radio-option">';
              trueFalse += '<input id="falseInput" type="radio" name="trueFalseInput" value="false" /> ';
              trueFalse += '<label for="falseInput">False</label></span></div>';
              area.innerHTML = trueFalse;
              break;
            case "multiplechoice":
              var multiplePreview = '<div id="listOptions"></div>';
              area.innerHTML = multiplePreview;
              populateOptions(type, choices, num);
              break;
            case "likert":
              var likert = '<div id="likertInput" class="radio-group">';
              likert += '<table cellpadding="6"><tr align="center">';
              likert += '<td><input id="stdInput" type="radio" name="agreementInput" value="stronglydisagree" /></td>';
              likert += '<td><input id="dInput" type="radio" name="agreementInput" value="disagree" /></td>';
              likert += '<td><input id="swdInput" type="radio" name="agreementInput" value="somewhatdisagree" /></td>';
              likert += '<td><input id="nInput" type="radio" name="agreementInput" value="neither" /></td>';
              likert += '<td><input id="swaInput" type="radio" name="agreementInput" value="somewhatagree" /></td>';  
              likert += '<td><input id="aInput" type="radio" name="agreementInput" value="agree" /></td>';
              likert += '<td><input id="staInput" type="radio" name="agreementInput" value="stronglyagree" /></td>';              
              likert += '</tr><tr>';
              likert += '<td><label for="sdInput">Strongly Disagree</label></td>';
              likert += '<td><label for="dInput">Disagree</label></td>';
              likert += '<td><label for="swdInput">Somewhat Disagree</label></td>';
              likert += '<td><label for="nInput">Neither agree<br/>nor disagree</label></td>';
              likert += '<td><label for="swaInput">Somewhat Agree</label></td>';   
              likert += '<td><label for="aInput">Agree</label></td>';
              likert += '<td><label for="staInput">Strongly Agree</label></td>';  
              likert += '</tr></table></div>';
              area.innerHTML = likert;
              break;
            case "yesno":
              var yesNo = '<div id="ynInput" class="radio-group">';
              yesNo += '<span class="radio-option">';
              yesNo += '<input id="yesInput" type="radio" name="yesNoInput" value="yes" /> ';
              yesNo += '<label for="yesInput">Yes</label></span>  ';
              yesNo += '<span class="radio-option">';
              yesNo += '<input id="noInput" type="radio" name="yesNoInput" value="no" /> ';
              yesNo += '<label for="noInput">No</label></span></div>';
              area.innerHTML = yesNo;;
              break;
            case "topn":
              type = 0;
              var topNPreview = "Please select " + num + " items.<br/>"; 
              topNPreview += '<div id="listOptions"></div>';
              area.innerHTML = topNPreview;
              populateOptions(type, choices, num);
              break;
            default:
          }
        }

        function populateOptions(type, allChoices, num){
          //populate available options for the question
          if(allChoices != null){
            var listOptions = "";
            for(var i=0;i<allChoices.length;i++){
              if(type == '0'){
                listOptions += '<input type="checkbox" name="choiceInput" value="' + allChoices[i] + '" /> ';
              }
              else{
                listOptions += '<input type="radio" name="choiceInput" value="' + allChoices[i] + '" /> ';
              }
              listOptions += allChoices[i];
              listOptions += '<br/>';
            }
            document.getElementById('listOptions').innerHTML = listOptions;
          } 
        }  

        function disableBack(){
          document.getElementById('backButton').disabled = true;
          document.getElementById('backButton').style.visibility = "hidden";
          document.getElementById('backButton').style.display = "none";
          //document.getElementById('backButton').aria-disabled = true;
          //$("#backButton").removeClass("ui-button-disabled").removeClass("ui-state-disabled");
        }

        function enableBack(){
          document.getElementById('backButton').disabled = false;
          document.getElementById('backButton').style.visibility = "visible";
          document.getElementById('backButton').style.display = "inline";
          //document.getElementById('backButton').aria-disabled = false;
          //$("#backButton").addClass("ui-button-disabled").addClass("ui-state-disabled");
        }

        function submitClicked(){
          enableBack();
          var answer = "";
          if(currentQuestion[6] == "no" && document.getElementById('previewComments').value == ""){
            alert("Please enter a comment.");
          }
          else{
	    if((document.getElementById('naInput').style.display == "block") && (document.getElementById('naAnswer').checked)){
	      answer = "N/A";
	      if(answer == ""){
		alert("No answer was selected");
	      }
	      else{
		sendEvent('answer_question', currentQuestion[0], answer, document.getElementById('previewComments').value);
	      }      
	    }
	    else{
	      switch(currentQuestion[2]){
		case "truefalse":
		  var radios = document.getElementsByName('trueFalseInput');
		  for (var i=0; i <radios.length; i++) {
		    if (radios[i].checked) {
		      answer = radios[i].value;
		    }
		  }
		 if(answer == ""){
		    alert("No answer was selected");
		  }
		  else{
		    sendEvent('answer_question', currentQuestion[0], answer, document.getElementById('previewComments').value);
		  }
		  break;
		case "multiplechoice":
		  var radios = document.getElementsByName('choiceInput');
		  for (var i=0; i <radios.length; i++) {
		    if (radios[i].checked) {
		      answer = radios[i].value;
		    }
		  }
		  if(answer == ""){
		    alert("No answer was selected");
		  }
		  else{
		    sendEvent('answer_question', currentQuestion[0], answer, document.getElementById('previewComments').value);
		  }
		  break;
		case "likert":
		  var radios = document.getElementsByName('agreementInput');
		  for (var i=0; i <radios.length; i++) {
		    if (radios[i].checked) {
		      answer = radios[i].value;
		    }
		  }
		  if(answer == ""){
		    alert("No answer was selected");
		  }
		  else{
		    sendEvent('answer_question', currentQuestion[0], answer, document.getElementById('previewComments').value);
		  }
		  break;
		case "yesno":
		  var radios = document.getElementsByName('yesNoInput');
		  for (var i=0; i <radios.length; i++) {
		    if (radios[i].checked) {
		      answer = radios[i].value;
		    }
		  }
		  if(answer == ""){
		    alert("No answer was selected");
		  }
		  else{
		    sendEvent('answer_question', currentQuestion[0], answer, document.getElementById('previewComments').value);
		  }
		  break;
		case "topn":
		  var radios = document.getElementsByName('choiceInput');
		  for (var i=0; i <radios.length; i++) {
		    if (radios[i].checked) {
		      answer = radios[i].value;
		      if(answer == ""){
			alert("No answer was selected");
		      }
		      else{
			sendEvent('answer_question', currentQuestion[0], answer, document.getElementById('previewComments').value);
		      }
		    }
		  }
		  break;
		default:
	      }
	    }
          }
        }

        function resetClicked(){
          document.getElementById('previewComments').value = "";
          switch(currentQuestion[2]){
              case "truefalse":
                var radios = document.getElementsByName('trueFalseInput');
                for (var i=0; i <radios.length; i++) {
                  radios[i].checked = false ;
                }
                break;
              case "multiplechoice":
                var radios = document.getElementsByName('choiceInput');
                for (var i=0; i <radios.length; i++) {
                  radios[i].checked = false ;
                }
                break;
              case "likert":
                var radios = document.getElementsByName('agreementInput');
                for (var i=0; i <radios.length; i++) {
                  radios[i].checked = false ;
                }
                break;
              case "yesno":
                var radios = document.getElementsByName('yesNoInput');
                for (var i=0; i <radios.length; i++) {
                  radios[i].checked = false ;
                }
                break;
              case "topn":
                var radios = document.getElementsByName('choiceInput');
                for (var i=0; i <radios.length; i++) {
                  radios[i].checked = false ;
                }
                break;
              default:
            }
        }

        function backClicked(){
          sendEvent('back_clicked')
        }


      </script>
    ''')

    # HTML for the page #
    request.writeln('''
        <br/>
        <div id="container">
        <div id="program-assessment" class="module">
          <h1>Program Assessment <span id="setAssessment"></span></h1>
	  <div id="assessmentContent">
	    <div id="progressbar">               
	    </div>
	    <div id="quesNum">
	    </div>
	    <div id="content"> 
	      <div id="question-viewer">
		<p class="previewText" id='previewQuestion'></p>
		<div class="previewInput">
		  <div id="questionInput">
		  </div>
		  <div id="naInput">
		    N/A <input type="checkbox" value="N/A" id="naAnswer" />
                  </div>
		  <div id="previewCommentInput" class="comments" style="display:none;">
		    <h3><label for="previewComments">Comments:</label></h3>
		    <textarea id="previewComments" cols="40" rows="3"></textarea>
		  </div>
		  <div class="bottom-toolbar-ask">
		    <div class="questionButtons">
		      <input type="submit" id='backButton' onclick="backClicked()" value="Back" />
		      <input type="submit" id='submitButton' onclick="submitClicked()" value="Submit" />
		      <input type="submit" id='resetButton' onclick="resetClicked()" value="Reset" />''')   
    # This code properly enables/disables the button, but doesn't affect its visibility. Haven't figured out how to get around that.
    '''
    includeBack = True
    backtrack = request.session.user.backtrack
    try:
      previousQuestion = request.session.user.answeredQuestions[backtrack-1] #previous question's id
    except IndexError:
      includeBack = False #there is no previous question -- do not print "Back" button
    if includeBack:
      request.writeln("""<input type="submit" id='backButton' onclick="backClicked()" value="Back" disabled="false" />""")
    else:
      request.writeln("""<input type="submit" id='backButton' onclick="backClicked()" value="Back" disabled="true" />""")
    '''
    request.writeln('''</div>
		  </div>
		</div>
	      </div><!-- /#question-viewer -->
	    </div><!-- /#content -->
	  </div> <!-- /#assessmentContent -->
        </div><!-- /#program-assessment -->
      </div><!-- /#container -->     
    ''')

    request.writeln("<script language='JavaScript' type='text/javascript'>startEventLoop();</script>")
    
    request.writeln("</body></html>")
Exemple #10
0
  def filter_params(self,request, setPicked):
    global potentialQuestionList
    creator = request.session.user
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    meetingRoot = parent.get_parent()
    groups = meetingRoot.search1(name='groups')
    activities = parent.search1(view='questioneditor')
    answered = 0
    asked = 0
    question = ''
    answeredQuestionList = []
    userGroup = ''
    userQues = ''
    qId = ''
    events = []
    end = False

    if not setPicked:
      return ["Thank you for logging in.<br/>You currently have no questions assigned for you to answer. You will be informed when questions or survey results are released to you.", 0, 0, 0]

    #find which user group user belongs to
    allGroups = groups.get_child_items(self)
    for group in allGroups:
      allChildren = group.get_child_items(self)
      for child in allChildren:
        if creator.id == child.user_id:
          userGroup = group.name

    #get the number of questions already answered by the user
    userAnswer = activities.search1(name="userAnswers")
    for user in userAnswer:
      if user.name == creator.name:
        userQues = user.get_child_items(self)
        answered = len(userQues)
    
    #get the list of question ids of the questions that have already been answered
    for q in userQues:
      answeredQuestionList.append(q.questionId)

    for i in answeredQuestionList:
      for q in potentialQuestionList:
        if i == q:
          potentialQuestionList.remove(q)

    #make list of questions from potentialQuestionList and set selected
    setQuestionList = []
    sets = activities.search1(name="sets")
    for s in sets:
      if s.name in setPicked:
        for qIds in s.get_child_items(self):
          if qIds.name == 'quesId':
            for q in qIds.quesId:
              if(potentialQuestionList.count(q) != 0) and q not in setQuestionList:
                setQuestionList.append(q)

    asked = len(setQuestionList) + answered

    if answered >= asked :
      end = "You have answered all of your questions.</br>Please log in later to view the results."
    else:
      end = ""
      question = QuestionAsker.get_question(self,setQuestionList[0])
    
    params = [end,question, answered, asked]
    return params
Exemple #11
0
  def exportCSV_action(self, request, filters):
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    meetingRoot = parent.get_parent()
    questioneditor = parent.search1(view='questioneditor')
    questions = questioneditor.search1(name="questions")

    groups = meetingRoot.search1(name='groups')
    userDictionary = {}    
    for group in groups:
      userDictionary[group.name] = []
      for user in group:
        userDictionary[group.name].append(user.user_id)
        
    group_filter = filters[0]
    poet_filter = filters[1]
    sets_filter = filters[2]

    # Step 1: Create a dictionary with a key for every existing combination of [POET]x[Set]x[Group].
    # Each key's entry will be a list of question ids that belong to that combination.
    # This dictionary acts as a "master list" for ordering purposes. 
    qLists = {}
    for q in questions:
      #Please feel free to change these variable names if you come up with something better
      q_poet = [] #the question's poet factors
      q_poetNode = q.search1(name='poet')
      for q_p in q_poetNode:
        q_poet.append(q_p.name)
      if not q_poet: # if q_poet == []
        q_poet = ["None"] #this is only necessary for POET factors, because a question with no sets/groups can't be asked
      if not "All" in poet_filter: #change this to "elif", and questions without a POET factor will survive the filter anyway
        q_poet = filter(lambda x:x in q_poet, poet_filter)
        
      q_sets = [] #the question's sets
      q_setsNode = q.search1(name='sets')
      for q_set in q_setsNode:
        q_sets.append(q_set.name)      
      if not "All" in sets_filter: #"all" is not in the filter set
        q_sets = filter(lambda x:x in q_sets, sets_filter)

      q_groups = q.users #the queston's groups
      if not "All" in group_filter: #"all" is not in the filter set
        q_groups = filter(lambda x:x in q_groups, group_filter)       

      for qp in q_poet: #for...
        for qs in q_sets: #every...
          for qg in q_groups: #combination:
            try:
              qLists[qp+qs+qg].append(q.id) # add it to the relevant list
            except KeyError: #entry doesn't exist yet
              qLists[qp+qs+qg] = [q.id]
            
    # Step 2: Create a dictionary with a key for every combination of [User] x [POET] x [Set] x [Group].
    # Populate it with each entry a list of ints, with ints corresponding to answers to questions.
    # This is almost exactly what the final CSV will look like.
    answerData = {}
    t = {'stronglydisagree': 1, 'disagree': 2, 'somewhatdisagree': 3, 'neither': 4, 'somewhatagree': 5, 'agree': 6, 'stronglyagree': 7} #translates answers into numbers

    for q in questions: 
      q_poet = [] #the question's poet factors
      q_poetNode = q.search1(name='poet')
      for q_p in q_poetNode:
        q_poet.append(q_p.name)
      if not q_poet: # if q_poet == []
        q_poet = ["None"] #this is only necessary for POET factors, because a question with no sets/groups can't be asked
      if not "All" in poet_filter: #change this to "elif", and questions without a POET factor will survive the filter anyway
        q_poet = filter(lambda x:x in q_poet, poet_filter)
        
      q_sets = [] #the question's sets
      q_setsNode = q.search1(name='sets')
      for q_set in q_setsNode:
        q_sets.append(q_set.name)
      if not "All" in sets_filter: #"all" is not in the filter set
        q_sets = filter(lambda x:x in q_sets, sets_filter)

      q_groups = q.users #the question's groups
      if not "All" in group_filter: #"all" is not in the filter set
        q_groups = filter(lambda x:x in q_groups, group_filter)

      answers = q.search1(name='answers') #all the answers that question has received
      for answer in answers: #for every individual answer...
        user = answer.who #who answered it...
        user_id = answer.creatorid
        for qp in q_poet: #and what...
          for qs in q_sets: #categories it...
            for qg in q_groups: #belongs to:
              if user_id in userDictionary[qg]: #ignore the groups the user doesn't belong to
                index = qLists[qp+qs+qg].index(q.id) #fetch the index from the master list
                entry = user+"|"+qp+"|"+qs+"|"+qg #compose a name with "|" marks for division later
                try:
                  answerData[entry][index] = t[answer.answer] #update the appropriate column of the row
                except KeyError: #that row doesn't exist yet -- so make it
                  answerData[entry] = [0] * len(qLists[qp+qs+qg]) #a zero for every question belonging to the poet/set/group
                  answerData[entry][index] = t[answer.answer]

    # Step 3: Create the CSV file.
    # Each key of the dictionary created in Step 3 will be transformed into a row of the CSV.
    csv = "Username, POET Factor, Set, Group\n" #the header
    for key in answerData.keys(): #each of these will be a row in the final file
      keySplit = key.split('|') #"Alan|Political|Mandatory|PM" -> ["Alan", "Political", "Mandatory", "PM"]
      string = "{user}, {poet}, {set}, {group}".format(
        user=keySplit[0], poet=keySplit[1], set=keySplit[2], group=keySplit[3]) #the key becomes the first four entries of the row
      for answer in answerData[key]:
        if answer > 0:
          string += ", "+str(answer) #if the user answered, add that answer to the end of the row
        else:
          string += ",  " #if the user didn't answer, leave that slot blank
      string += "\n" #move to next row
      csv += string #add to CSV

    log.info("csv:\n"+csv) #debug
                  
    f = open('POET.csv','w')
    print >> f, csv
        
    events = []
    return events
Exemple #12
0
  def send_content(self, request):
    # Sends content of page
    request.writeln(HTML_HEAD_NO_CLOSE + '<link type="text/css" rel="stylesheet" href="' + join(WEB_PROGRAM_URL, "layout.css") + '" />')
    
    request.writeln('''
    <script src="''' + join(WEB_PROGRAM_URL, 'jquery-1.4.2.min.js') + '''"></script>
    <script src="''' + join(WEB_PROGRAM_URL, 'jquery.selectlist.js') + '''"></script>
    <script src="''' + join(WEB_PROGRAM_URL, 'jquery.selectlist.min.js') + '''"></script>
    <script src="''' + join(WEB_PROGRAM_URL, 'jquery.selectlist.pack.js') + '''"></script>
    <script src="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.min.js') + '''"></script>
    <link href="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.css') + '''" rel="stylesheet" type="text/css"/>
    <link href="''' + join(WEB_PROGRAM_URL, 'visualize.css') + '''" rel="stylesheet" type="text/css"/>
    <link href="''' + join(WEB_PROGRAM_URL, 'visualize-dark.css') + '''" rel="stylesheet" type="text/css"/>
    <script src="''' + join(WEB_PROGRAM_URL, 'excanvas.js') + '''"></script>
    <script src="''' + join(WEB_PROGRAM_URL, 'EnhanceJS/enhance.js') + '''"></script>
    <script src="''' + join(WEB_PROGRAM_URL, 'visualize.jQuery.js') + '''"></script>

    <script type="text/javascript">

        $(function() {
		$("input:button, input:submit").button();
		$("select#user-filter").selectList();
		$("select#poet-filter").selectList();
		$("select#set-filter").selectList();
	});
        
        </script>

    </head>''')
    request.writeln('<body onLoad="getFindings();">')
    #request.writeln(HTML_BODY)

    request.writeln('''
      <script language='JavaScript' type='text/javascript'>

        function updateTable(htmlString){
          $("#chartDiv").html(htmlString);
          $('#chartDiv').visualize({
		type: 'bar', 
		width: '900', 
		height:'300',
		barGroupMargin:'15',
		barMargin:'1',
		parseDirection:'y'
	});
        }

        function getFilter(){
          var user_selected = $('select#user-filter').selectList( {instance: true} );
          var user_filter = user_selected.val();

          var poet_selected = $('select#poet-filter').selectList( {instance: true} );
          var poet_filter = poet_selected.val();
          
          var set_selected = $('select#set-filter').selectList( {instance: true} );
          var set_filter = set_selected.val();

          return [user_filter, poet_filter, set_filter];
        }

        function getFindings(){
          filter = getFilter();
          sendEvent('get_findings', filter);
        }

        function viewFindings(checkedCategories){   
          //document.getElementById('content').innerHTML = checkedCategories;
        }

        function openHelp() {
          window.open("''' + WEB_PROGRAM_URL + '''/Help/", "helpwindow", "dependent,height=800,width=1000,scrollbars,resizable");
          return false;
        }
	
	function openProgInfo() {
          window.open("''' + WEB_PROGRAM_URL + '''/ProgInfo/", "proginfowindow", "dependent,height=800,width=1000,scrollbars,resizable");
          return false;
        }

        function exportCSV() {
          filter = [["All"], ["All"], ["All"]];
          sendEvent('exportCSV', filter);
        }

        function exportFilteredCSV() {
          filter = getFilter();
          sendEvent('exportCSV', filter);        
        }

        function redirectCSV(){
          window.open("''' + WEB_PROGRAM_URL + '''/POET.csv");
        }

        function redirectToCSV(name){
          window.open("''' + WEB_PROGRAM_URL + '''/AddPOETChart.bas");
          window.open("''' + WEB_PROGRAM_URL + '''/results.xls");
        }

      </script>
    ''')

    # HTML for page #
    '''determines whether a given user is the PM of a given meeting'''
    activity = Directory.get_meeting(request.getvalue('global_rootid', ''))
    activities = activity.get_parent()
    meeting = activities.get_parent()
    user_is_pm = False
    for child in meeting:
     if child.name == "groups":
       for group in child:
         if group.name == "PM":
           for pm_item in group:
             if pm_item.user_id == request.session.user.id:
               user_is_pm = True
               
    if request.session.user.superuser == '1' or user_is_pm:
      request.writeln('<table cellspacing="0" style="border-bottom:#99ccff 1px dotted;padding:3px;" width=100%><tr>')
      request.writeln('''<td id="menu-logo">
      			<div id="poet-logo">POET</a>
                       </td>''')

      request.writeln('<td id="user-menu">')
      request.writeln('logged in as <strong>'+request.session.user.name+'</strong>')
  
    #navigation
      if request.session.user.superuser == '1':
        request.writeln('<span class="divider">|</span> <a href="' + request.cgi_href(_adminaction=None, global_adminview=None) + '">Home</a>')
      request.writeln('  <span class="divider">|</span> <a target="_top" href="' + request.cgi_href(itemid=meeting.id, global_view='Administrator', global_adminview='POET') + '">Manage Program</a>')
      request.writeln('''<span class="divider">|</span> <a onclick='javascript:openProgInfo();'>Program Information</a> <span class="divider">|</span> <a onclick='javascript:openHelp();'>Help</a> <span class="divider">|</span> ''')
      request.writeln('<a href="' + request.cgi_href(global_view='login', _adminaction='logout') + '">Logout</a>')
      request.writeln('</td>')
      request.writeln('</tr></table>')

    for activity in activities:
      if activity.name == "Question Editor":      
        sets = activity.search1(name="sets")
        break


    request.writeln('''
        <br/>
        <div id="container">
        <div id="reportFindings" class="module">
          <h1 style='float:left;'>Findings</h1><br/><br/><br/>
          <div id="resultControls">
	    <div id="exportButtons">
	      <input class="butControls" type="button" value="Export Results" onclick="javascript:exportFilteredCSV();">
	    </div>
	    <div id="exportFilters">
	      <div id="setFilter" style='float:right;'>Set<br/>
		<select onchange="getFindings()" id="set-filter" multiple>
		  ''')
    for s in sets:
      request.writeln('''<option value="'''+s.name+'''" selected>'''+s.name+'''</option>''')

    request.writeln('''
		</select>
	      </div>
	    
	      <div id="poetFilter" style='float:right;'>POET<br/>
		<select onchange="getFindings()" id="poet-filter" multiple>		  
		  <option value="Political" selected>Political</option>
		  <option value="Operational" selected>Operational</option>
		  <option value="Economic" selected>Economic</option>
		  <option value="Technical" selected>Technical</option>
		</select>
	      </div>
	      
	      <div id="userFilter" style='float:right;'>User Group<br/>
		<select onchange="getFindings()" id="user-filter" multiple>
		  <option value="PM" selected>PM</option>
		  <option value="PMO" selected>PMO</option>
		  <option value="Contractor" selected>Contractor</option>
		  <option value="Senior Stakeholder" selected>Senior Stakeholder</option>
		  <option value="User" selected>User</option>
		</select>
	      </div>
	    
	  </div>
	</div>
          
        <div id="content" style="clear:both;">
          <div id="chartDiv"></div>
        </div><!-- /#content -->
      </div><!-- /#reportFindings -->
      </div><!-- /#container -->     
    ''')

    request.writeln("<script language='JavaScript' type='text/javascript'>startEventLoop();</script>")
    
    request.writeln("</body></html>")
Exemple #13
0
  def exportCSV_action(self, request, filters):
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    meetingRoot = parent.get_parent()
    questioneditor = parent.search1(view='questioneditor')
    questions = questioneditor.search1(name="questions")
    events = []

    groups = meetingRoot.search1(name='groups')
    groupsList = []
    userDictionary = {}    
    for group in groups:
      groupsList.append(group.name)
      userDictionary[group.name] = []
      for user in group:
        userDictionary[group.name].append(user.user_id)

    group_filter = filters[0]
    poet_filter = filters[1]
    sets_filter = filters[2]

    # Step 1: Create a dictionary with a key for every existing combination of [POET]x[Set]x[Group].
    # Each key's entry will be a list of question ids that belong to that combination.
    # This dictionary acts as a "master list" for ordering purposes. 
    qLists = {}
    for q in questions:
      #Please feel free to change these variable names if you come up with something better
      q_poet = [] #the question's poet factors
      q_poetNode = q.search1(name='poet')
      for q_p in q_poetNode:
        q_poet.append(q_p.name)
      if not q_poet: # if q_poet == []
        q_poet = ["None"] #this is only necessary for POET factors, because a question with no sets/groups can't be asked
      if not "All" in poet_filter: #change this to "elif", and questions without a POET factor will survive the filter anyway
        q_poet = filter(lambda x:x in q_poet, poet_filter)
        
      q_sets = [] #the question's sets
      q_setsNode = q.search1(name='sets')
      for q_set in q_setsNode:
        q_sets.append(q_set.name)      
      if not "All" in sets_filter: #"all" is not in the filter set
        q_sets = filter(lambda x:x in q_sets, sets_filter)

      q_groups = q.users #the queston's groups
      if not "All" in group_filter: #"all" is not in the filter set
        q_groups = filter(lambda x:x in q_groups, group_filter)       

      for qp in q_poet: #for...
        for qs in q_sets: #every...
          for qg in q_groups: #combination:
            try:
              qLists[qp+qs+qg].append(q.id) # add it to the relevant list
            except KeyError: #entry doesn't exist yet
              qLists[qp+qs+qg] = [q.id]
            
    # Step 2: Create a dictionary with a key for every combination of [User] x [POET] x [Set] x [Group].
    # Populate it with each entry a list of ints, with ints corresponding to answers to questions.
    # This is almost exactly what the final CSV will look like.
    answerData = {}
    answerDataAveraged = {}
    questionPOETData = {}
    questionSetData = {}
    poetData = {}
    setData = {}
    t = {'stronglydisagree': 1, 'disagree': 2, 'somewhatdisagree': 3, 'neither': 4, 'somewhatagree': 5, 'agree': 6, 'stronglyagree': 7, 'N/A': 8} #translates answers into numbers

    for q in questions:
      q_poet = [] #the question's poet factors
      q_poetNode = q.search1(name='poet')
      for q_p in q_poetNode:
        q_poet.append(q_p.name)
      if not q_poet: # if q_poet == []
        q_poet = ["None"] #this is only necessary for POET factors, because a question with no sets/groups can't be asked
      if not "All" in poet_filter: #change this to "elif", and questions without a POET factor will survive the filter anyway
        q_poet = filter(lambda x:x in q_poet, poet_filter)
        
      q_sets = [] #the question's sets
      q_setsNode = q.search1(name='sets')
      for q_set in q_setsNode:
        q_sets.append(q_set.name)
      if not "All" in sets_filter: #"all" is not in the filter set
        q_sets = filter(lambda x:x in q_sets, sets_filter)

      q_groups = q.users #the question's groups
      if not "All" in group_filter: #"all" is not in the filter set
        q_groups = filter(lambda x:x in q_groups, group_filter)

      answers = q.search1(name='answers') #all the answers that question has received
      for answer in answers: #for every individual answer...
        user = answer.who #who answered it...
        user_id = answer.creatorid
        for qp in q_poet: #and what...
          for qs in q_sets: #categories it...
            for qg in q_groups: #belongs to:
              if user_id in userDictionary[qg]: #ignore the groups the user doesn't belong to
                index = qLists[qp+qs+qg].index(q.id) #fetch the index from the master list
                entry = user+"|"+qp+"|"+qs+"|"+qg #compose a name with "|" marks for division later
                try:
                  answerData[entry][index] = t[answer.answer] #update the appropriate column of the row
                except KeyError: #that row doesn't exist yet -- so make it
                  answerData[entry] = [0] * len(qLists[qp+qs+qg]) #a zero for every question belonging to the poet/set/group
                  answerData[entry][index] = t[answer.answer]
                entryAvg = qp+"|"+qs+"|"+qg #compose a name with "|" marks for division later
                try:
                  answerDataAveraged[entryAvg][index].append(t[answer.answer]) #update the appropriate column of the row
                except KeyError: #that row doesn't exist yet -- so make it
                  answerDataAveraged[entryAvg] = [ [] for i in range(len(qLists[qp+qs+qg])) ]  #an empty list for every question belonging to the poet/set/group
                  answerDataAveraged[entryAvg][index].append(t[answer.answer]) #update the appropriate column of the row
                qpindex = str(q.id)+"|"+qp
                try:
                  text, data = questionPOETData[qpindex]
                  data.append(t[answer.answer])
                  questionPOETData[qpindex] = (text, data)
                except KeyError:
                  questionPOETData[qpindex] = (q.text, [t[answer.answer]])
                qsindex = str(q.id)+"|"+qs
                try:
                  text, data = questionSetData[qsindex]
                  data.append(t[answer.answer])
                  questionSetData[qsindex] = (text, data)
                except KeyError:
                  questionSetData[qsindex] = (q.text, [t[answer.answer]])  
                pindex = qp + "|" + qg
                try:
                  poetData[pindex].append(t[answer.answer])
                except KeyError:
                  poetData[pindex] = [ t[answer.answer] ]
                sindex = qs + "|" + qg
                try:
                  setData[sindex].append(t[answer.answer])
                except KeyError:
                  setData[sindex] = [ t[answer.answer] ]
                                    
    for key in answerDataAveraged.keys():
      for index in range(0,len(answerDataAveraged[key])):
        responses = answerDataAveraged[key][index]
        if len(responses) == 0:
          answerDataAveraged[key][index] = (0,0) #mean = 0, standard deviation = 0
        else:
          mean = float(sum(responses)) / float(len(responses))
          differences = [math.pow(mean-elem, 2) for elem in responses ]
          stddev = math.sqrt( sum(differences) / float(len(differences)) )
          answerDataAveraged[key][index] = (mean, stddev)                     

    for key in questionPOETData.keys():
      text, allResponses = questionPOETData[key]
      if len(allResponses) == 0:
        questionPOETData[key] = (text, 0, 0, 0, [])
      else:
        allResponses.sort()
        responses = filter((lambda x: x < 8), allResponses)
        mean = float(sum(responses)) / float(len(responses))
        differences = [math.pow(mean-elem, 2) for elem in responses ]
        stddev = math.sqrt(sum(differences) / float(len(differences)))
        keySplit = key.split('|')
        qid = keySplit[0]
        questionPOETData[key] = (text, mean, stddev, len(allResponses), allResponses)

    for key in questionSetData.keys():
      text, allResponses = questionSetData[key]
      if len(allResponses) == 0:
        questionSetData[key] = (text, 0, 0, 0, [])
      else:
        allResponses.sort()
        responses = filter((lambda x: x < 8), allResponses)
        mean = float(sum(responses)) / float(len(responses))
        differences = [math.pow(mean-elem, 2) for elem in responses ]
        stddev = math.sqrt(sum(differences) / float(len(differences)))
        keySplit = key.split('|')
        qid = keySplit[0]
        questionSetData[key] = (text, mean, stddev, len(allResponses), allResponses)


    # Step 3: Create the CSV file.
    # Each key of the dictionary created in Step 3 will be transformed into a row of the CSV.
    csv = "Username, POET Factor, Set, Group\n" #the header
    for key in answerData.keys(): #each of these will be a row in the final file
      keySplit = key.split('|') #"Alan|Political|Mandatory|PM" -> ["Alan", "Political", "Mandatory", "PM"]
      string = "{user}, {poet}, {set}, {group}".format(
        user=keySplit[0], poet=keySplit[1], set=keySplit[2], group=keySplit[3]) #the key becomes the first four entries of the row
      for answer in answerData[key]:
        if answer == 8: #user answered N/A
          string += ", NA" #is this the best way to handle this? will non-numerical data create problems later? 
        elif answer > 0:
          string += ", "+str(answer) #if the user answered, add that answer to the end of the row
        else:
          string += ",  " #if the user didn't answer, leave that slot blank
      string += "\n" #move to next row
      csv += string #add to CSV

    book = Workbook()
    #rb = open_workbook('../webroot/GroupMind/results.xls')
    #book = copy(rb)

    #for factor in ["Political", "Operational", "Economical", "Technical"]:
    factors = set([])
    for key in poetData.keys():
      factors.add( key.split('|')[0] )
    for factor in factors:
      date = strftime("%m/%d/%Y", localtime())
      time = strftime("%H:%M:%S", localtime())
      tempCSV = "POET results, "+str(date)+", "+str(time)+"\n\n"
      tempCSV += factor+"\n,Group,Mean,Std Dev\n"
      allData = []
      for group in groupsList: #["PM", "PMO", "Contractor", "Senior Stakeholder", "User"]:
        try:
          responses = poetData[factor+"|"+group]
          responses = filter((lambda x: x < 8), responses)
          allData.extend(responses[:])
          mean = float(sum(responses))/float(len(responses))
          differences = [math.pow(mean-elem, 2) for elem in responses ]
          stddev = math.sqrt(sum(differences) / float(len(differences)))
          tempCSV += ","+group+","+str(mean)+","+str(stddev)+"\n"
        except KeyError:
          tempCSV += ","+group+",0,0\n"
        except ZeroDivisionError:
          tempCSV += ","+group+",0,0\n"
          
      responses = allData
      if len(allData) > 0:
        mean = float(sum(responses))/float(len(responses))
        differences = [math.pow(mean-elem, 2) for elem in responses ]
        stddev = math.sqrt(sum(differences) / float(len(differences)))
        tempCSV += ",Total,"+str(mean)+","+str(stddev)+"\n\n"
      else:
        tempCSV += ",Total,0,0\n\n"
      tempCSV += ",Question ID,Question Text,Mean,Std Dev, Responders, Responses\n"
      for key in questionPOETData.keys():
        qid, qfactor = key.split("|")
        if qfactor == factor:
          datum = questionPOETData[key]
          tempCSV += ',{theqid},"{text}",{mean},{stddev},{responders}'.format(
            theqid=qid, text=datum[0], mean=datum[1], stddev=datum[2], responders=datum[3])
          for answer in datum[4]:
            tempCSV+= ','+str(answer)
          tempCSV += "\n"
          #tempCSV += ','+str(qid)+',"'+text+'",'+str(mean)
      log.info(tempCSV)
      f = open(factor+".csv", 'w')
      print >> f, tempCSV
      f.close()

      ReportFindings.writeExcelSheet(self, book, f.name, factor)

    #for set in ["Mandatory", "Agility", "Trust", etc.]:
    sets = set([])
    
    for key in setData.keys():
      sets.add( key.split('|')[0] )
    sets = list(sets)
    htmlData = []
    firstRow = [""]
    firstRow.extend(groupsList) #["", "PM", "PMO", "Contractor", "Senior Stakeholder", "User"]
    htmlData.append(firstRow) #[ ["", "PM", "PMO", "Contractor", "Senior Stakeholder", "User"] ]
    
    for aset in sets:
      nextRow = [aset] # e.g. ["Mandatory"]
      date = strftime("%m/%d/%Y", localtime())
      time = strftime("%H:%M:%S", localtime())
      tempCSV = "POET results, "+str(date)+", "+str(time)+"\n\n"
      tempCSV += aset+"\n,Group,Mean,Std Dev\n"
      allData = []
      for group in groupsList: #["PM", "PMO", "Contractor", "Senior Stakeholder", "User"]:
        try:
          responses = setData[aset+"|"+group]
          responses = filter((lambda x: x < 8), responses)
          allData.extend(responses[:])
          mean = float(sum(responses))/float(len(responses))
          differences = [math.pow(mean-elem, 2) for elem in responses ]
          stddev = math.sqrt(sum(differences) / float(len(differences)))
          tempCSV += ","+group+","+str(mean)+","+str(stddev)+"\n"
          nextRow.append(mean)
        except KeyError:
          tempCSV += ","+group+",0,0\n"
          nextRow.append(0)
        except ZeroDivisionError:
          tempCSV += ","+group+",0,0\n"
          nextRow.append(0)
      htmlData.append(nextRow)
      
      responses = allData
      if len(allData) > 0:
        mean = float(sum(responses))/float(len(responses))
        differences = [math.pow(mean-elem, 2) for elem in responses ]
        stddev = math.sqrt(sum(differences) / float(len(differences)))
        tempCSV += ",Total,"+str(mean)+","+str(stddev)+"\n\n"
      else:
        tempCSV += ",Total,0,0\n\n"
      tempCSV += ",Question,Text,Mean,Std Dev, Responders, Responses\n"
      for key in questionSetData.keys():
        qid, qset = key.split("|")
        if qset == aset:
          datum = questionSetData[key]
          tempCSV += ',{theqid},"{text}",{mean},{stddev},{responders}'.format(
            theqid=qid, text=datum[0], mean=datum[1], stddev=datum[2], responders=datum[3])
          for answer in datum[4]:
            if answer == 8:
              tempCSV += ',N/A'
            else:
              tempCSV+= ','+str(answer)
          tempCSV += "\n"
          #tempCSV += ','+str(qid)+',"'+text+'",'+str(mean)
      log.info(tempCSV)
      f = open("../webroot/GroupMind/"+aset+".csv", 'w')
      print >> f, tempCSV
      f.close()

      ReportFindings.writeExcelSheet(self, book, f.name, aset)
      
      events.append(Event('redirectToCSV', aset))
    log.info("htmlData: "+str(htmlData))
    #log.info("csv:\n"+csv) #debug
                  
    #f = open('../webroot/GroupMind/POET.csv','w')
    #print >> f, csv

    htmlString = ReportFindings.makeHTMLString(self, htmlData)
    log.info("htmlString = "+htmlString)
    #events.append(Event('redirectCSV'))
    events.append(Event('updateTable', htmlString))
    return events
Exemple #14
0
  def get_findings_action(self, request, filterChoice):
    #log.info("filterChoice = "+str(filterChoice))
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    parent = meeting.get_parent()
    activities = parent.search1(view='questioneditor')
    questions = activities.search1(name="questions")
    doc = xml.dom.minidom.Document()
    root = doc.appendChild(doc.createElement("QuestionSystem"))
    meta = root.appendChild(doc.createElement('meta'))
    date = meta.appendChild(doc.createElement('exportdate'))
    date.appendChild(doc.createTextNode(time.strftime('%a, %d %b %Y %H:%M:%S')))
    quesRoot = root.appendChild(doc.createElement('questions'))
    xmlDoc = doc
     
    #log.info("*** START OF REPORT ***")
    #log.info("filterChoice = "+str(filterChoice))

    # Iterate through all questions, filter out the questions that match the categories
    count = 0 #only for debugging (but could be useful later)
    for q in questions:
      #log.info(" --- QUESTION --- ")
      users = q.users
      poet = []
      sets = []
      for qchild in q:
        if qchild.name == "poet":
          for p in qchild:
            poet.append(p.name)
        elif qchild.name == "sets":
          for s in qchild:
            sets.append(s.name)
      #log.info("Users:      "+str(users)+" vs. "+str(filterChoice[0]))
      #log.info("Poet:       "+str(poet)+" vs. "+str(filterChoice[1]))
      #log.info("Sets:       "+str(sets)+" vs. "+str(filterChoice[2]))
      
      #these three checks could be rewritten as three calls to a function that takes two lists and returns True if there is any shared element
      # check users
      if 'All' in filterChoice[0]:
        includeUsers = True
      else:
        includeUsers = False
        for filterUser in filterChoice[0]: 
          if filterUser in users:
            includeUsers = True
            break
          
      # check poet
      if 'All' in filterChoice[1]:
        includePoet = True
      else:
        includePoet = False
        for filterPoet in filterChoice[1]: 
          if filterPoet in poet:
            includePoet = True
            break
          
      # check categories
      if 'All' in filterChoice[2]:
        includeSet = True
      else:
        includeSet = False
        for filterSet in filterChoice[2]: 
          if filterSet in sets:
            includeSet = True
            break

      #If you want to force a question to match every element of a filter, use this logic instead:
      """
      includeUsers = True #bool starts as true instead of false
      for filterUser in filterChoice[0]: 
        if filterUser not in users: #check for "not in" as opposed to "in"
          includeUsers = False
          break
      """

      #log.info(str(includeUsers)+str(includePoet)+str(includeSet))
      if includeUsers and includePoet and includeSet: 
      	xmldoc = ReportFindings.export(self, doc, quesRoot, q)
      	count += 1
              
      #q_count+=1
      #log.info(" ---------------- ")
    #log.info("# of matches: "+str(count))
    #log.info("**** END OF REPORT ****")
    f = open('qaDoc.xml','w')
    print >> f, xmlDoc.toxml()	
    requestedQuestion = []
    events = []
    events.append(Event('viewFindings', xmlDoc.toxml()))
    return events
Exemple #15
0
  def send_content(self, request):
    '''Sends the content pane to the browser'''
    request.writeln(HTML_HEAD_NO_CLOSE + '<link type="text/css" rel="stylesheet" href="' + join(WEB_PROGRAM_URL, "layout.css") + '" />')
    
    request.writeln('''<script src="''' + join(WEB_PROGRAM_URL, 'jquery-1.4.2.min.js') + '''"></script>''')
    request.writeln('''<script src="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.min.js') + '''"></script>''')
    request.writeln('''<link href="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.css') + '''" rel="stylesheet" type="text/css"/>''')
    
    self.send_javascript(request)
    
    request.writeln('''
      <script language='JavaScript' type='text/javascript'>
        $(document).ready(function() {
	  $("input:button").button();
	  $("input:submit").button();
	  $("button").button();
	});
        </script>
    ''')
    
    
    request.writeln("</head>")

    request.writeln(self.BODY_TAG_NO_CLOSE + ' id="outputBody">')
    
    root = datagate.get_item(request.getvalue('global_rootid', ''))
    item = root.search1(name="comments")
        
    activity = Directory.get_meeting(request.getvalue('global_rootid', ''))
    activities = activity.get_parent()
    meeting = activities.get_parent()
    user_is_pm = False
    for child in meeting:
     if child.name == "groups":
       for group in child:
         if group.name == "PM":
           for pm_item in group:
             if pm_item.user_id == request.session.user.id:
               user_is_pm = True
               
    if request.session.user.superuser == '1' or user_is_pm:
      request.writeln('<div><table cellspacing="0" style="border-bottom:#99ccff 1px dotted;padding:3px;" width=100%><tr>')
      request.writeln('''<td id="menu-logo">
      			<div id="poet-logo">POET</a>
                       </td>''')

      request.writeln('<td id="user-menu">')
      request.writeln('logged in as <strong>'+request.session.user.name+'</strong>')
  
    #navigation
      if request.session.user.superuser == '1':
        request.writeln('<span class="divider">|</span> <a href="' + request.cgi_href(_adminaction=None, global_adminview=None) + '">Home</a>')
      request.writeln('  <span class="divider">|</span> <a target="_top" href="' + request.cgi_href(itemid=meeting.id, global_view='Administrator', global_adminview='POET') + '">Manage Program</a>')
      request.writeln('''<span class="divider">|</span> <a onclick='javascript:openProgInfo();'>Program Information</a> <span class="divider">|</span> <a onclick='javascript:openHelp();'>Help</a> <span class="divider">|</span> ''')
      request.writeln('<a href="' + request.cgi_href(global_view='login', _adminaction='logout') + '">Logout</a>')
      request.writeln('</td>')
      request.writeln('</tr></table></div>')
      
    request.writeln("<br/><h2 align='center'>Brainstorming</h2>")
    
    if item.getvalue('commentertitle', '') != '':
      request.writeln('<p id="title"><h3>' + item.getvalue('commentertitle', '') + '</h3><h4>' + item.getvalue('commenterdescrip', '') + '</h4></p>')
      
    request.writeln('''<div id='addIdea'>
		      <button align='right' onclick='document.getElementById("addcomment").style.display="block";'>Add</button>
		      <div id='addcomment' style='display:none;' align='center'>
		      ''' + request.cgi_form(gm_action="add_comment") + '''
			  <textarea align='center' name="text" cols="50" rows="2" style="width:80%"></textarea>
			  <input type="submit" value="Add" name="submit">
			</form>
		      </div>
		    </div> 
    ''')
    
    request.writeln('''<br/><div id='commentDiv' class='commentList'></div>''')
    
    request.writeln('''<script language='JavaScript' type='text/javascript'>
                    parent.startEventLoop();
                    </script>
    ''')
    
    request.writeln('</body></html>')
Exemple #16
0
  def send_menu(self, request):
    '''Sends the menu'''
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    activities_item = meeting.search1(name='activities')
    activities = datagate.get_child_items(activities_item.id)
    rights = self.get_user_rights(request)

    request.writeln(HTML_HEAD_NO_CLOSE + '''
      <script language='JavaScript' type='text/javascript'>
      <!--
        var views = new Array();
    ''')
    for activity in activities:
      request.writeln('        views["' + activity.id + '"] = "' + activity.view + '";')
    request.writeln('''        
        function selectActivity() {
          var activityid = document.getElementById('activityid').value;
          parent.activity.location.href = "''' + request.cgi_href(global_windowid=request.getvalue('global_windowid', ''), global_view=None, global_rootid=None, frame=None) + '''&global_view=" + views[activityid] + "&global_rootid=" + activityid;
        }
        
        function initialLoad() {
          selectActivity();
        }
        
        function openHelp() {
          window.open("''' + WEB_PROGRAM_URL + '''Help/", "helpwindow", "dependent,height=400,width=300,scrollbars,resizable");
          return false;
        }
        
        function gotoActivity(activityid, requester_sessionid) {
          var activity = document.getElementById('activityid');
          if ("''' + request.session.id + '''" != requester_sessionid) {
            activity.value = activityid;
            selectActivity();
          }else{
            alert("The sync message has been sent to all participants in this meeting.");
          }
        }

        function syncParticipants() {
          if (confirm("Syncronize this meeting's participants to this activity?")) {
            var activityid = document.getElementById('activityid').value;
            sendEvent('gotoActivity', activityid, "''' + request.session.id + '''");
          }
        }
        
      //-->
      </script>
      </head>      
    
      <body background="''' + join(WEB_PROGRAM_URL, "background1.png") + '''" onload="initialLoad();">
      <table border=0 cellspacing=3 cellpadding=0 width=100%><tr><td nowrap valign="center" align="left" style="color:#FFFFFF; font-weight:800">
        ''' + html(meeting.name) + ''': ''' + html(request.session.user.name) + '''
      </td><td nowrap align="center" style="color:#FFFFFF">
    ''')

    if rights['Show Activities Selector'] or request.session.user.superuser == '1': # don't show unless there are more than one or the superuser
      request.writeln('''
        Activity:
        <select name="activityid" id='activityid' onchange="javascript:selectActivity()">
      ''')
      for activity in activities:
        request.writeln('<option value="' + activity.id + '">' + activity.name + '</option>')
      request.writeln('</select>')
      if request.session.user.superuser == '1':
        request.writeln('<input type="button" value="Sync Participants" onclick="javascript:syncParticipants();">')
    
    else: 
      # this hidden input allows the selectActivity() js functions to work (called with body.onLoad)
      request.writeln('<input type="hidden" name="activityid" id="activityid" value="' + activities[0].id + '">')

    request.writeln('</td><td align="right" style="color:#FFFFFF">')
    if request.session.user.superuser == '1':
      request.writeln('<a style="color:white" target="_top" href="' + request.cgi_href(itemid=meeting.id, global_view='Administrator', global_adminview='MeetingHome') + '">Administrator</a> | ')
    request.writeln('''
        <a style='color:white' onclick='javascript:openHelp();'>Help</a>
        | 
        <a target="_top" href="''' + request.cgi_href(global_view='logout') + '''" style="color:white">Logout</a>
      </td></tr></table>
      <script language='JavaScript' type='text/javascript'>startEventLoop();</script>
      </body></html>
    ''')
Exemple #17
0
  def send_menu(self, request):
    '''Sends the menu'''
    meeting = Directory.get_meeting(request.getvalue('global_rootid', ''))
    activities_item = meeting.search1(name='activities')
    activities = datagate.get_child_items(activities_item.id)
    rights = self.get_user_rights(request)

    request.writeln(HTML_HEAD_NO_CLOSE + '''
      <script language='JavaScript' type='text/javascript'>
      <!--
        var views = new Array();
    ''')
    for activity in activities:
      request.writeln('        views["' + activity.id + '"] = "' + activity.view + '";')
    request.writeln('''        
        function selectActivity() {
          var activityid = document.getElementById('activityid').value;
          parent.activity.location.href = "''' + request.cgi_href(global_windowid=request.getvalue('global_windowid', ''), global_view=None, global_rootid=None, frame=None) + '''&global_view=" + views[activityid] + "&global_rootid=" + activityid;   
        }
        
        function initialLoad() {
          selectActivity();
        }
        
        function openHelp() {
          window.open("''' + WEB_PROGRAM_URL + '''/Help/", "helpwindow", "dependent,height=400,width=300,scrollbars,resizable");
          return false;
        }
      
        function gotoActivity(activityid, requester_sessionid) {
          var activity = document.getElementById('activityid');
          if ("''' + request.session.id + '''" != requester_sessionid) {
            activity.value = activityid;
            selectActivity();
          }else{
            alert("The sync message has been sent to all participants in this meeting.");
          }
        }

        function syncParticipants() {
          if (confirm("Syncronize this meeting's participants to this activity?")) {
            var activityid = document.getElementById('activityid').value;
            sendEvent('gotoActivity', activityid, "''' + request.session.id + '''");
          }
        }
        
      //-->
      </script>
      </head>      
    
      <body id="menu" ''" onload="initialLoad();" style="margin:0;padding:0;">
      <table cellspacing="0"  style="border-bottom:#99ccff 1px dotted;padding:3px;">
      	<tr>
      		<td id="menu-logo">
      			<div id="poet-logo">POET</div>
      		</td>
      	<td id="menu-activities">
    ''')

    user_is_pm = 0
    for child in meeting:
      if child.name == "groups":
        for group in child:
          if group.name == "PM":
            for pm_item in group:
              if pm_item.user_id == request.session.user.id:
                user_is_pm = 1

    if rights['Show Activities Selector'] or request.session.user.superuser == '1' or user_is_pm == 1: # don't show unless there are more than one or the superuser
      request.writeln('''
        <div class="hide">Activity:
        <select name="activityid" id='activityid' onchange="javascript:selectActivity()">
      ''')
      for activity in activities:
        request.writeln('<option value="' + activity.id + '">' + activity.name + '</option>')
      request.writeln('</select>')
      if request.session.user.superuser == '1':
        request.writeln('<input type="button" value="Sync Participants" onclick="javascript:syncParticipants();"></div>')

    # select activity based on meeting status
    elif meeting.status < 2: #results not released -- send to QuestionAsker
      # this hidden input allows the selectActivity() js functions to work (called with body.onLoad)
      request.writeln('<input type="hidden" name="activityid" id="activityid" value="' + activities[1].id + '">')
    else: #results released -- send to Findings
      request.writeln('<input type="hidden" name="activityid" id="activityid" value="' + activities[2].id + '">')

    request.writeln('</td><td id="user-menu">')
    request.writeln('logged in as <strong>' + html(request.session.user.name) + '</strong>')
    if request.session.user.superuser == '1' or user_is_pm == 1:
      request.writeln('<span class="divider">|</span> <a target="_top" href="' + request.cgi_href(itemid=meeting.id, global_view='Administrator', global_adminview='POET') + '">Edit</a>')
    request.writeln('''
        <span class="divider">|</span> <a onclick='javascript:openHelp();'>Help</a> <span class="divider">|</span> 
        <a target="_top" href="''' + request.cgi_href(global_view='logout') + '''" >Logout</a>
      </td></tr></table>
      <script language='JavaScript' type='text/javascript'>startEventLoop();</script>
      </body></html>
    ''')
Exemple #18
0
  def send_content(self, request):
    # Sends content of page
    request.writeln(HTML_HEAD_NO_CLOSE + '<link type="text/css" rel="stylesheet" href="' + join(WEB_PROGRAM_URL, "layout.css") + '" />')
    
    request.writeln('''
    <script type="text/javascript" src="''' + join(WEB_PROGRAM_URL, "jsapi.js") + '''"></script>
    <script type="text/javascript" src="''' + join(WEB_PROGRAM_URL, "corechart.js") + '''"></script>
    <script type="text/javascript" src="''' + join(WEB_PROGRAM_URL, "default,corechart.I.js") + '''"></script>
    <script src="''' + join(WEB_PROGRAM_URL, 'jquery-1.4.2.min.js') + '''"></script>'
    <script src="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.min.js') + '''"></script>
    <link href="''' + join(WEB_PROGRAM_URL, 'jquery-ui-1.8.2.custom.css') + '''" rel="stylesheet" type="text/css"/>
    
   <!--<script type="text/javascript" src="http://www.google.com/jsapi"></script>-->
        <script type="text/javascript">

        $(function() {
		$("input:button, input:submit").button();
	});
        
    	var chart;
    	//google.setOnLoadCallback(drawChart);
          //google.load("visualization", "1", {packages:["corechart"]});
          
          function drawChart() {
          try {
            var data = new google.visualization.DataTable();
            data.addColumn('string', 'Category');
            data.addColumn('number', 'PM');
            data.addColumn('number', 'User');
            data.addColumn('number', 'PMO');
            data.addColumn('number', 'Contracter');
            data.addColumn('number', 'Sr Stakeholder');
            data.addRows(6);
            data.setValue(0, 0, 'Trust');
            data.setValue(0, 1, 1000);
            data.setValue(0, 2, 400);
            data.setValue(0, 3, 700);
            data.setValue(0, 4, 900);
            data.setValue(0, 5, 500);
            data.setValue(1, 0, 'Commitment');
            data.setValue(1, 1, 610);
            data.setValue(1, 2, 860);
            data.setValue(1, 2, 690);
            data.setValue(1, 3, 970);
            data.setValue(1, 4, 750);
            data.setValue(1, 5, 500);
            data.setValue(2, 0, 'SA');
            data.setValue(2, 1, 660);
            data.setValue(2, 2, 1120);
            data.setValue(2, 2, 400);
            data.setValue(2, 3, 700);
            data.setValue(2, 4, 900);
            data.setValue(2, 5, 500);
            data.setValue(3, 0, 'Agility');
            data.setValue(3, 1, 1030);
            data.setValue(3, 2, 540);
            data.setValue(3, 2, 400);
            data.setValue(3, 3, 700);
            data.setValue(3, 4, 900);
            data.setValue(3, 5, 500);
            data.setValue(4, 0, 'Teamwork');
            data.setValue(4, 1, 1030);
            data.setValue(4, 2, 540);
            data.setValue(4, 2, 400);
            data.setValue(4, 3, 700);
            data.setValue(4, 4, 900);
            data.setValue(4, 5, 500);
    
            data.setValue(5, 0, 'Complexity');
            data.setValue(5, 1, 1030);
            data.setValue(5, 2, 540);
            data.setValue(5, 2, 400);
            data.setValue(5, 3, 700);
            data.setValue(5, 4, 900);
            data.setValue(5, 5, 500);
    
            chart = new google.visualization.BarChart(document.getElementById('chartDiv'));
            chart.draw(data, {
            	width: 900,
            	height: 800,
            	title: 'Survey ABC Results',
            	vAxis: {
            		title: 'Category',
            		titleColor: '#000'
            	},
            	hAxis: {
            		title: 'Level of Concern',
            		titleColor: '#000'
            	},
            	isStacked:false
    		});
          } catch(e){
          	alert(e);
          }
          }
        </script>

    </head>''')
    request.writeln('<body onLoad="getFindings();">')
    #request.writeln(HTML_BODY)

    request.writeln('''
      <script language='JavaScript' type='text/javascript'>

        function getFilter(){
          var user_filter = [];
          for (i=0; i<document.getElementById('user-filter').options.length; i++){
            if (document.getElementById('user-filter').options[i].selected == true){
              user_filter = user_filter.concat(document.getElementById('user-filter').options[i].text);
            }
          }
          if (user_filter == []){
            user_filter = ['All'];
          }

          var poet_filter = [];
          for (i=0; i<document.getElementById('poet-filter').options.length; i++){
            if (document.getElementById('poet-filter').options[i].selected == true){
              poet_filter = poet_filter.concat(document.getElementById('poet-filter').options[i].text);
            }
          }
          if (poet_filter == []){
            poet_filter = ['All'];
          }

          var set_filter = [];
          for (i=0; i<document.getElementById('set-filter').options.length; i++){
            if (document.getElementById('set-filter').options[i].selected == true){
              set_filter = set_filter.concat(document.getElementById('set-filter').options[i].text);
            }
          }
          if (set_filter == []){
            set_filter = ['All'];
          }

          return [user_filter, poet_filter, set_filter];
        }

        function getFindings(){
          filter = getFilter();
          sendEvent('get_findings', filter);
        }

        function viewFindings(checkedCategories){   
        	drawChart();
          //document.getElementById('content').innerHTML = checkedCategories;
        }

        function openHelp() {
          window.open("''' + WEB_PROGRAM_URL + '''/Help/", "helpwindow", "dependent,height=400,width=300,scrollbars,resizable");
          return false;
        }

        function exportCSV() {
          filter = [["All"], ["All"], ["All"]];
          sendEvent('exportCSV', filter);
        }

        function exportFilteredCSV() {
          filter = getFilter();
          sendEvent('exportCSV', filter);        
        }

      </script>
    ''')

    # HTML for page #
    '''determines whether a given user is the PM of a given meeting'''
    activity = Directory.get_meeting(request.getvalue('global_rootid', ''))
    activities = activity.get_parent()
    meeting = activities.get_parent()
    user_is_pm = False
    for child in meeting:
     if child.name == "groups":
       for group in child:
         if group.name == "PM":
           for pm_item in group:
             if pm_item.user_id == request.session.user.id:
               user_is_pm = True
               
    if request.session.user.superuser == '1' or user_is_pm:
      request.writeln('<table cellspacing="0" style="border-bottom:#99ccff 1px dotted;padding:3px;" width=100%><tr>')
      request.writeln('''<td id="menu-logo">
      			<div id="poet-logo">POET</a>
                       </td>''')

      request.writeln('<td id="user-menu">')
      request.writeln('logged in as <strong>'+request.session.user.name+'</strong>')
  
    #navigation
      if request.session.user.superuser == '1':
        request.writeln('<span class="divider">|</span> <a href="' + request.cgi_href(_adminaction=None, global_adminview=None) + '">Home</a>')
      request.writeln('  <span class="divider">|</span> <a target="_top" href="' + request.cgi_href(itemid=meeting.id, global_view='Administrator', global_adminview='POET') + '">Edit</a>')
      request.writeln('''<span class="divider">|</span> <a onclick='javascript:openHelp();'>Help</a> <span class="divider">|</span> ''')
      request.writeln('<a href="' + request.cgi_href(global_view='login', _adminaction='logout') + '">Logout</a>')
      request.writeln('</td>')
      request.writeln('</tr></table>')

    for activity in activities:
      if activity.name == "Question Editor":      
        sets = activity.search1(name="sets")
        break


    request.writeln('''
        <br/>
        <div id="container">
        <div id="reportFindings" class="module">
          <h1 style='float:left;'>Findings</h1>
          </br></br></br><input type="button" value="Export CSV" onclick="javascript:exportCSV();">
          </br><input type="button" value="Export Filtered CSV" onclick="javascript:exportFilteredCSV();">
          <select size="5" style='float:right;' onchange="getFindings()" id="set-filter" multiple>
          	<option value="All" selected>All</option>''')
    for s in sets:
      request.writeln('''<option value="'''+s.name+'''">'''+s.name+'''</option>''')

    request.writeln('''
          </select>

          <select size="5" style='float:right;' onchange="getFindings()" id="poet-filter" multiple>
          	<option value="All" selected>All</option>
          	<option value="Political">Political</option>
          	<option value="Operational">Operational</option>
          	<option value="Economic">Economic</option>
          	<option value="Technical">Technical</option>
          </select>

          <select size="5" style='float:right;' onchange="getFindings()" id="user-filter" multiple>
          	<option value="All" selected>All</option>
          	<option value="PM">PM</option>
          	<option value="PMO">PMO</option>
          	<option value="Contractor">Contractor</option>
          	<option value="Senior Stakeholder">Senior Stakeholder</option>
                <option value="User">User</option>
          </select>
          
          <br/><br/>
        <div id="content" style="clear:both;">
        
          <div id="chartDiv"></div>
        </div><!-- /#content -->
      </div><!-- /#reportFindings -->
      </div><!-- /#container -->     
    ''')

    request.writeln("<script language='JavaScript' type='text/javascript'>startEventLoop();</script>")
    
    request.writeln("</body></html>")