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
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
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 []
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
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
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
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
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
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>")
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
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
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>")
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
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
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>')
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> ''')
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> ''')
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>")