# -*- coding: utf-8 # -*- Mode: Python; py-indent-offset: 4 -*- """ Test """ __version__ = "$Revision:33$"[11:-2] from Globals import Acquisition, Persistent, InitializeClass from Acquisition import aq_base, aq_inner, aq_parent, Explicit from AccessControl import ClassSecurityInfo from OFS.SimpleItem import SimpleItem from Products.ZCatalog.CatalogPathAwareness import CatalogAware from Products.QTAuthor.utils import send_mail from zope.interface import implements from common import commons from Permissions import * import re from random import choice import string from interfaces import ITest class Test(CatalogAware, SimpleItem, Persistent, Explicit, commons): """ """ meta_type = 'QTTest' security = ClassSecurityInfo() security.declareObjectPublic() implements(ITest) manage_options = SimpleItem.manage_options def __init__(self, id): self.id=id self.chosen=[] #self.feedback_enabled = enable_feedback self._state = "private" self.default_catalog = 'cat_tests' security.declarePrivate('manage_afterAdd') def manage_afterAdd(self, item, container): self.index_object() def index_html(self, REQUEST): """ index """ return self.restrictedTraverse('test_index.html')() security.declareProtected(perm_edit_test, 'setQuestions') def setQuestions(self, val): self.chosen = val security.declareProtected(perm_view_test, 'getQuestions') def getQuestions(self): """ """ return self.chosen security.declareProtected(perm_edit_test, 'setTitle') def setTitle(self, title): self.title = title security.declareProtected(perm_view_test, 'getTitle') def getTitle(self): """ """ return self.title security.declareProtected(perm_edit_test, 'setUser') def setUser(self, user): self.user = str(user) security.declareProtected(perm_view_test, 'getUser') def getUser(self): """ """ if not hasattr(self, 'user'): self.user = self.getOwnerTuple()[1] return self.user security.declareProtected(perm_edit_test, 'setDescription') def setDescription(self, description): self.description = description security.declareProtected(perm_view_test, 'getDescription') def getDescription(self): """ """ return getattr(self, 'description', '') security.declareProtected(perm_edit_test, 'setKeywords') def setKeywords(self, keywords): self.keywords = keywords ktuple = [] keys = keywords.split(',') for k in keys: k = k.strip() if str(k) != '': ktuple.append(k) self.k = ktuple security.declareProtected(perm_view_test, 'getKeywords') def getKeywords(self): """ """ return getattr(self, 'keywords', '') security.declareProtected(perm_view_test, 'getKeywordsTuple') def getKeywordsTuple(self): #keywordid massiivina """ """ return getattr(self, 'k', []) security.declareProtected(perm_edit_test, 'setLanguage') def setLanguage(self, language): self.language = language security.declareProtected(perm_view_test, 'getLanguage') def getLanguage(self): """ """ return getattr(self, 'language', 'et') security.declareProtected(perm_edit_test, 'setAuthor') def setAuthor(self, val): self.author = val security.declareProtected(perm_view_test, 'getAuthor') def getAuthor(self): return getattr(self, 'author', self.getUser()) security.declareProtected(perm_view_test, 'getAuthorVCard') def getAuthorVCard(self): """ returns author info in a form of vCard """ author = self.getAuthor().decode('utf-8') adata = author.split(" ") fname = adata[0] lname = "" if len(adata) > 1: lname = adata[1] vauthordata = 'BEGIN:VCARD\n' vauthordata += 'VERSION:3.0\n' vauthordata += 'N:%s;%s;;;\n' % (fname, lname) vauthordata += 'FN:%s\n' % (author) #vauthordata += 'ORG:\n' vauthordata += 'END:VCARD' return vauthordata security.declareProtected(perm_edit_test, 'setDifficulty') def setDifficulty(self, difficulty): self.difficulty = difficulty security.declareProtected(perm_view_test, 'getDifficulty') def getDifficulty(self): """ """ return getattr(self, 'difficulty', 'easy') security.declareProtected(perm_edit_test, 'setLREKeywords') def setLREKeywords(self, val): """ set lre keywords """ if val and isinstance(val, str): val = [val] self.lrekeywords = val security.declareProtected(perm_view_test, 'getLREKeywords') def getLREKeywords(self): """ returns array of lrekeywords """ return getattr(self, 'lrekeywords', []) security.declareProtected(perm_edit_test, 'setLicence') def setLicence(self, val): """ set licence """ self.licence = val security.declareProtected(perm_view_test, 'getLicence') def getLicence(self): return getattr(self, 'licence', 'cc1') security.declareProtected(perm_edit_test, 'setEmailContent') def setEmailContent(self, emailcontent): self.emailcontent = emailcontent security.declareProtected(perm_view_test, 'getEmailContent') def getEmailContent(self): """ """ return getattr(self, 'emailcontent', '') security.declareProtected(perm_edit_test, 'setStatus') def setStatus(self, state): """ """ self._state = state security.declareProtected(perm_view_test, 'getStatus') def getStatus(self): """ """ return self._state def _setWaramuUid(self, uid): self.waramuUid = uid def getWaramuUid(self): if not hasattr(self, 'waramuUid'): return "" return self.waramuUid # security.declareProtected(perm_view_test, 'isFeedbackEnabled') # def isFeedbackEnabled(self): # """ is automatic feedback enabled """ # return getattr(self, 'feedback_enabled', 0) security.declareProtected(perm_view_test, 'getNumQuestions') def getNumQuestions(self): return len(self.chosen) security.declareProtected(perm_edit_test, 'setCreatingDay') def setCreatingDay(self): import datetime self.creatingDay = datetime.datetime.today() security.declareProtected(perm_view_test, 'getCreatingDay') def getCreatingDay(self): """ """ if not hasattr (self, 'creatingDay'): self.setCreatingDay() return self.creatingDay security.declareProtected(perm_edit_test, 'setLastChange') def setLastChange(self): import datetime self.lastChange = datetime.datetime.today() security.declareProtected(perm_view_test, 'getLastChange') def getLastChange(self): """ """ return getattr(self, 'lastChange', self.getCreatingDay()) security.declareProtected(perm_edit_test, 'setTestGroups') def setTestGroups(self, val): self.testgroups = val security.declareProtected(perm_view_test, 'getTestGroups') def getTestGroups(self): testgroup_results = self.cat_groups({'getTests': self.getId()}) groups = [] for group in testgroup_results: groups.append(group.getId) return groups security.declareProtected(perm_edit_test, '_setErased') def _setErased(self): self.erased = 1 security.declareProtected(perm_view_test, 'getErased') def getErased(self): return getattr(self, 'erased', 0) security.declareProtected(perm_edit_test, 'changeTest') def changeTest(self, REQUEST, to_add=[], to_remove=[], add_to_button='', remove_from_button='', search_button=''): """ for adding or removing questions in test (or searching questions)""" if search_button: word = REQUEST.get('searchword', '') what = REQUEST.get('s_what', '') lic = REQUEST.get('s_licence', '') order = REQUEST.get('s_order', 'by_title') user = REQUEST.get('AUTHENTICATED_USER') creator = REQUEST.get('s_creator', 'my_ques') res = self.questions.searchQuestions(word, what, lic, order, user, creator) return self.restrictedTraverse('test_index.html')(results=res) if add_to_button: exst = self.getQuestions() exst += to_add self.setQuestions(exst) if remove_from_button: exst = self.getQuestions() for x in to_remove: exst.remove(x) self.setQuestions(exst) self.setLastChange() self.reindex_object() self._sendToWaramu() return REQUEST.RESPONSE.redirect('test_index.html') security.declareProtected(perm_edit_test, 'changeTestInfo') def changeTestInfo(self, REQUEST): """ """ self.setTitle(REQUEST.get('testname')) self.setDescription(REQUEST.get('description')) self.setKeywords(REQUEST.get('keywords')) self.setLanguage(REQUEST.get('language')) self.setAuthor(REQUEST.get('author')) self.setDifficulty(REQUEST.get('difficulty')) self.setLREKeywords(REQUEST.get('lrekeywords', '')) self.setLicence(REQUEST.get('licence')) self.setEmailContent(REQUEST.get('emailcontent')) self.setStatus(REQUEST.get('state')) self.setLastChange() #self.feedback_enabled = enable_feedback self.reindex_object() self._sendToWaramu() return REQUEST.RESPONSE.redirect(self.get_root().absolute_url()+'/tests') def _sendToWaramu(self): """ sends to waramu, if waramu is enabled, status is public and test contains at least one question """ status = self.getStatus() if status == 'public' and self.isWaramuEnabled() and len(self.getQuestions()) > 0: if self.getWaramuUid() == "": self._exportToWaramu() else: self._updateToWaramu() # if waramu is enabled and question is in waramu, # but question isn't public or does not contain any questions, delete it from waramu elif self.isWaramuEnabled() and self.getWaramuUid() != "" and (status != 'public' or len(self.getQuestions()) == 0): self._deleteFromWaramu() def _getWaramu(self): if not self.isWaramuEnabled(): return None from waramulib.interfaces import IWaramuClient from zope.component import getUtility wu = getUtility(IWaramuClient, name="waramuconnection") if wu.isConnected(): return wu wu._init(self.getWaramuURL()) wu.newSession(self.getWaramuUsername(), self.getWaramuPassword()) wu.Identify() return wu def _exportToWaramu(self): """ """ w = self._getWaramu() if w is None: return au = ""+self.getOwnerTuple()[1]+"" data = self._generateWaramuXML() wrid = w.newResource(au, data) w.addAttachment(au, wrid, self.makeTestZip([self.getId()]), 'test.zip') self._setWaramuUid(wrid) def _updateToWaramu(self): w = self._getWaramu() if w is None: return au = ""+self.getOwnerTuple()[1]+"" data = self._generateWaramuXML() wrid = self.getWaramuUid() if not wrid: return res = w.updateResource(au, wrid, data) if res: print "... cannot update... " else: ats = w.listAttachments(au, wrid) for a in ats.keys(): w.removeAttachment(au, wrid, a) w.addAttachment(au, wrid, self.makeTestZip([self.getId()]), 'test.zip') def _deleteFromWaramu(self): """ """ w = self._getWaramu() if w is None: return au = ""+self.getOwnerTuple()[1]+"" uid = self.getWaramuUid() res = w.deleteResource(au, uid) if not res: self._setWaramuUid("") def _generateWaramuXML(self): data = u'\n' data += '\n' title = self.getTitle() desc = self.getDescription() keywords = self.getKeywords() l = self.getLanguage() data += ''+title.decode('utf-8')+'\n' data += ''+desc.decode('utf-8')+'\n' data += '\n' lk = keywords lk = lk.split(',') for k in lk: data += '\t'+k.strip().decode('utf-8')+'\n' data += '\n' data += ''+self.getId()+'\n' lic = self.getLicence() # licence licences = self.getLicenceTypes() if licences.get(lic): lic = licences.get(lic).get('url') data += ''+lic+'\n' lang = self.getLanguage().decode('utf-8') data += '\n\t'+lang+'\n\n' data += ''+self.getAuthorVCard()+'\n' dif = self.getDifficulty().decode('utf-8') data += ''+dif+'\n' data += '\n' #lrekeywords lrekeys = self.getLREKeywords() for lrekey in lrekeys: data += '\t'+lrekey.decode('utf-8')+'\n' data += '\n' data += '\n\tassessment\n\n' data += "" return data def sendTest(self, REQUEST, groupslist=''): """ """ tokens = self.getTokens() participants = self.getParticipants() participants2 = self.getAllParticipants() if isinstance(groupslist, type('')): groupslist = [groupslist,] # if group isn't chosen, redirect to same page and display error message to user if groupslist == ['']: message = ['Choose group!'] return REQUEST.RESPONSE.redirect(self.id +'/test_preferences.html?message='+'
'.join(message)) groups = self.getTestGroups() for g in groupslist: groups.append(g) self.setTestGroups(groups) for g in groupslist: group = self.getGroupById(g) group.addTest(self.getId()) gmembers = group.getMembers() for m in gmembers: member = self.getStudentById(m) email = member['email'] if email != '': token = '' chars = string.letters + string.digits # generate token for i in range(25): token += choice(chars) tokens.append(token) participants[token] = email participants2[token] = email # create answer container fnames = self.getTokenFolderNames() if fnames.has_key(token) == False: folderid = '' for i in range(20): folderid += choice(chars) self.answers.setupTokenFolder(folderid, token, self.getId(), g) fnames[token] = folderid self.setTokenFolderNames(fnames) m_ans = member['ans_containers'] m_ans.append(folderid) member['ans_containers'] = m_ans self.students._changeStudentFolders(member, m_ans) mail_subject = unicode(self.getTitle(), "utf-8") test_text = self.getEmailContent() test_url = '\n'+self.get_root().absolute_url()+'/test?token='+token test_owner = self.users._getOb(self.getUser()) test_ownertext = unicode(test_owner.getFullName(), "utf-8") test_ownermail = test_owner.getEmail() mail_content = unicode(test_text, "utf-8") content = self.utranslate('test_mail_content', '\n\nTest is located at:%(testurl)s \n\n\nBest regards,\n%(testowner)s') %{'testurl': test_url, 'testowner': test_ownertext} mail_content += content send_mail(email, mail_subject, mail_content, 'utf-8', 'plain', test_owner.getFullName(), test_ownermail) group.changeMemberInfo(gmembers) group.reindex_object() self.setParticipants(participants) self.setAllParticipants(participants2) self.setTokens(tokens) self.setTestQuesHtml() return REQUEST.RESPONSE.redirect('test_preferences.html') def createMemberTokenFolder(self, student_id, group_id): tokens = self.getTokens() participants = self.getParticipants() participants2 = self.getAllParticipants() member = self.getStudentById(student_id) email = member['email'] if email != '': token = '' chars = string.letters + string.digits # generate token for i in range(25): token += choice(chars) tokens.append(token) participants[token] = email participants2[token] = email # create answer container fnames = self.getTokenFolderNames() if fnames.has_key(token) == False: folderid = '' for i in range(20): folderid += choice(chars) self.answers.setupTokenFolder(folderid, token, self.getId(), group_id) fnames[token] = folderid self.setTokenFolderNames(fnames) m_ans = member['ans_containers'] m_ans.append(folderid) member['ans_containers'] = m_ans self.students._changeStudentFolders(member, m_ans) self.setParticipants(participants) self.setAllParticipants(participants2) self.setTokens(tokens) def sendReminder(self, REQUEST, reminder=''): """ """ if isinstance(reminder, type('')): reminder = [reminder,] # if nobody is chosen, then don't do anything and redirect to same page if reminder == ['']: return REQUEST.RESPONSE.redirect(self.id +'/test_preferences.html') all = self.getAllParticipants() all_length = len(all) for r in reminder: token = r email = all[token] mail_subject = 'TATS: Test Reminder' mail_content = '\n'+self.get_root().absolute_url()+'/test?token='+token send_mail(email, mail_subject, mail_content) return REQUEST.RESPONSE.redirect('test_preferences.html') def getGroupsToAdd(self, user): """ get groups to which I can send test """ #all = self.cat_groups(getUser=user) added_groups = self.getTestGroups() objs = self.groups._getAllGroups() all = [] for x in objs: if x.getOwnerTuple()[1] == str(user): if x.getId() not in added_groups: all.append(x) return all def setTestQuesHtml(self): ques = self.getQuestions() for q in ques: q = self.getQuestionById(q) q._setHtml() def setTokens(self, tokens): self.tokens = tokens def getTokens(self): """ """ if not hasattr(self, 'tokens'): self.tokens = [] return self.tokens def setParticipants(self, participants): self.participants = participants def getParticipants(self): """ """ return getattr(self, 'participants', {}) def setAllParticipants(self, participants): self.allparticipants = participants def getAllParticipants(self): """ """ if not hasattr(self, 'allparticipants'): self.allparticipants = {} return self.allparticipants def haventDone(self, token): tokens = self.getParticipants() return tokens.has_key(token) def deleteToken(self, token): import time p = self.getParticipants() p.pop(token) self.setParticipants(p) self._p_changed = 1 def removeParticipant(self, token): """ """ tokens = self.getTokens() tokens.remove(token) self.setTokens(tokens) def getTokenAnswers(self, token): """ """ folders = self.getTokenFolderNames() tfoldername = folders[token] container = self.getAnswerContainerById(tfoldername) sessions = container.getSessions() for s in sessions: answers = s.getAllAnswers() return answers def changeTokenPoints(self, REQUEST, feedback_button=''): """ """ token = REQUEST.get('token', '') ansobjs = self.getTokenAnswers(token) length = len(ansobjs) for i in range(1, length+1): points = float(REQUEST.get('ans'+str(i))) ansobjs[i-1].setPoints(points) if feedback_button: for i in range(1, length+1): feedback = REQUEST.get('feedback'+str(i)) ansobjs[i-1].setFeedback(feedback) all = self.getAllParticipants() email = all[token] mail_content = '' for ans in ansobjs: mail_content += '

' ans_html = ans.getAnswerHtml() if isinstance(ans_html, unicode): mail_content += ans_html.encode('utf-8') else: mail_content += ans_html mail_content += 'Points: ' + str(ans.getPoints()) + '
' feedback = ans.getFeedback() if feedback != '': mail_content += '
Feedback:
' + feedback mail_subject = 'TATS: Test feedback' send_mail(email, mail_subject, mail_content, 'utf-8', 'html') return REQUEST.RESPONSE.redirect('test_answers.html?token='+token) def setTokenFolderNames(self, val): self.tfoldernames = val def getTokenFolderNames(self): return getattr(self, 'tfoldernames', {}) def changePosition(self, move, pos, REQUEST): """ """ questions = self.getQuestions() pos = int(pos) ques = questions[pos] ques_len = len(questions) if move == 'up' and pos != 0: prevques = questions[pos-1] questions[pos] = prevques questions[pos-1] = ques if move == 'down' and pos != ques_len-1: nextques = questions[pos+1] questions[pos] = nextques questions[pos+1] = ques self.setQuestions(questions) return REQUEST.RESPONSE.redirect('test_index.html') def getTestResults(self, REQUEST): """ get test results (coma separated) """ groups = self.getTestGroups() test_id = self.getId() test_ques = self.getQuestions() alltext = ';' for q in test_ques: ques = self.getQuestionById(q) alltext += ques.getTitle()+';' alltext += 'Total;' for g in groups: group = self.getGroupById(g) gmembers = group.getMembers() for member in gmembers: student = self.getStudentById(member) container = self.getContainerByTestId(student['ans_containers'], test_id, g) sessions = container.getSessions() token = container.getAnswerToken() done = container.checkDoneOrNot() if done == True: s_email = student['email'] alltext += '\n' + s_email + ';' for session in sessions: s_answers = session.getAllAnswers() for ans in s_answers: ques_id = ans.getQuesId() ques = self.getQuestionById(ques_id) ques_type = ques.getType() if ques_type != 'extended_text_type': ques_points = ques.getMaxPoints() ans_points = ans.getPoints() alltext += self.roundNumber((ans_points/ques_points)*100) +'%;' user_allpoints = self.getUserTestPoints(sessions) test_points = self.getTestMaxPoints() alltext += self.roundNumber((user_allpoints/test_points)*100)+'%;' self.REQUEST.RESPONSE.setHeader('content-type', 'text/txt') self.REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=testresults.txt') return alltext def getTestMaxPoints(self): test_ques = self.getQuestions() testMaxPoints = 0 for ques_id in test_ques: ques = self.getQuestionById(ques_id) ques_type = ques.getType() if ques_type != 'extended_text_type': ques_points = ques.getMaxPoints() testMaxPoints += ques_points return testMaxPoints def getUserTestPoints(self, sessions): user_points = 0 for session in sessions: answers = session.getAllAnswers() for ans in answers: points = ans.getPoints() user_points += points return user_points def remove_html_tags(self, data): import re p = re.compile(r'<.*?>') return p.sub('', data) def getTestChoiceQuestionsCSVfile(self, REQUEST): """ """ import re statstext = u"" statstext += self.utranslate('Group') + ";" statstext += self.utranslate('Student') + ";" statstext += self.utranslate('email') + ";" statstext += self.utranslate('time') + ";" questions = self.getQuestions() groups = self.getTestGroups() # first row is question titles for ques_id in questions: ques = self.getQuestionById(ques_id) ques_varslength = self.getQuesVarsLength(ques_id) for i in range (0, ques_varslength): num = questions.index(ques_id) + 1 statstext += "\"" + str(num) + ". " questiontext = self.remove_html_tags(ques.getQuestion()) questiontext = questiontext.replace('"', "'") statstext += questiontext.decode("utf-8") + "\";" # second row choices and gaps (for some types) statstext += "\n;;;;" for ques_id in questions: ques = self.getQuestionById(ques_id) questype = ques.getType() if questype in ['Choice_type']: statstext += ";" # other rows, students answers frequencies = {} answerstext = "" for group_id in groups: group = self.getGroupById(group_id) gmembers = group.getMembers() for m in gmembers: member = self.getStudentById(m) container = self.getContainerByTestId(member['ans_containers'], self.getId(), group_id) sessions = container.getSessions() done = container.checkDoneOrNot() if done == True: studentname = member['firstname'] + ' ' + member['lastname'] answerstext += "\n" + group.getTitle() + ";" + studentname + ";" submittime = sessions[0].getSubmitTime() answerstext += member['email'] + ";" + submittime + ";" for ques_id in questions: ques = self.getQuestionById(ques_id) for session in sessions: answers = session.getAllAnswers() for ans in answers: if ques_id == ans.getQuesId(): ans_send = ans.getAnswerSend() # check is this answersend for correct question cm = re.compile('(.*?)', re.S) cm_results = cm.search(ans_send) queskey = "" if cm_results: queskey = cm_results.group(1) if ques_id in queskey or queskey == "": if ques.getType() in ['Choice_type']: ques_stats = ques.getCSVstatsWithNumbers(ans_send, frequencies) answerstext += ques_stats.get('csvtext') frequencies = ques_stats.get('frequencies') else: answerstext += ";"*self.getQuesVarsLength(ques_id) statstext += answerstext.decode("utf-8") # last row, questions frequencies statstext += "\n" + self.utranslate("Frequencies") + ": ;;;;" text = "" averagerow = 0 for ques_id in questions: usersanswers = frequencies.get(ques_id) if not usersanswers: text += ";"*self.getQuesVarsLength(ques_id) else: ques = self.getQuestionById(ques_id) ques_type = ques.getType() if ques_type == 'Choice_type': variants = ques.getAnswers() for i in range(0, 2): varcount = usersanswers.count(i) text += str(i) + '=' +str(varcount) + ' ' text += ';' statstext += text.decode("utf-8") self.REQUEST.RESPONSE.setHeader('content-type', 'text/csv;charset=utf-8') self.REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=testquestions_stats.csv') return statstext def getQuesVarsLength(self, ques_id): """ """ def getTestQuestionsCSVfile(self, REQUEST): """ """ import re statstext = u"" statstext += self.utranslate('Group') + ";" statstext += self.utranslate('Student') + ";" statstext += self.utranslate('email') + ";" statstext += self.utranslate('time') + ";" questions = self.getQuestions() groups = self.getTestGroups() # first row is question titles for ques_id in questions: ques = self.getQuestionById(ques_id) ques_varslength = self.getQuesVarsLength(ques_id) for i in range (0, ques_varslength): statstext += ques.getTitle().decode("utf-8") + ";" # second row choices and gaps (for some types) statstext += "\n;;;;" for ques_id in questions: ques = self.getQuestionById(ques_id) questype = ques.getType() if questype in ['Choice_type', 'hottext_type', 'extended_text_type', 'slider_type', 'hotspot_type']: statstext += ";" if questype in ['Choice_multiple']: variants = ques.getAnswers() for var in variants: statstext += variants.get(var).decode("utf-8") + ";" if questype in ['order_type', 'associate_type']: variants = ques.getAnswers() for var in variants: statstext += variants.get(var).decode("utf-8") + ";" if questype in ['match_type']: variants = ques.getVariants() for var in variants: statstext += variants.get(var).decode("utf-8") + ";" if questype in ['gap_match_type']: gaps = ques.getGapvariants() for gap in gaps: statstext += gap.decode("utf-8") + ";" if questype in ['inline_choice_type', 'text_entry_type']: gaps_count = ques.getGapsCount() for i in range(1, gaps_count + 1): statstext += self.utranslate("gap") + str(i) + ";" # other rows, students answers frequencies = {} answerstext = "" for group_id in groups: group = self.getGroupById(group_id) gmembers = group.getMembers() for m in gmembers: member = self.getStudentById(m) container = self.getContainerByTestId(member['ans_containers'], self.getId(), group_id) sessions = container.getSessions() done = container.checkDoneOrNot() if done == True: studentname = member['firstname'] + ' ' + member['lastname'] answerstext += "\n" + group.getTitle() + ";" + studentname + ";" submittime = sessions[0].getSubmitTime() answerstext += member['email'] + ";" + submittime + ";" for ques_id in questions: ques = self.getQuestionById(ques_id) for session in sessions: answers = session.getAllAnswers() for ans in answers: if ques_id == ans.getQuesId(): ans_send = ans.getAnswerSend() # check is this answersend for correct question cm = re.compile('(.*?)', re.S) cm_results = cm.search(ans_send) queskey = "" if cm_results: queskey = cm_results.group(1) if ques_id in queskey or queskey == "": ques_stats = ques.getCSVstats(ans_send, frequencies) answerstext += ques_stats.get('csvtext') frequencies = ques_stats.get('frequencies') else: answerstext += ";"*self.getQuesVarsLength(ques_id) statstext += answerstext.decode("utf-8") # last row, questions frequencies statstext += "\n" + self.utranslate("Frequencies") + ": ;;;;" text = "" averagerow = 0 for ques_id in questions: usersanswers = frequencies.get(ques_id) if not usersanswers: text += ";"*self.getQuesVarsLength(ques_id) else: ques = self.getQuestionById(ques_id) ques_type = ques.getType() if ques_type == 'Choice_type': variants = ques.getAnswers() for var in variants: variant = variants.get(var) varcount = usersanswers.count(variant) text += variant + '=' +str(varcount) + ' ' text += ';' if ques_type == 'Choice_multiple': variants = ques.getAnswers() for var in variants: varanswers = usersanswers.get(var) for i in range(0, 2): varcount = varanswers.count(i) text += str(i) + '=' +str(varcount) + ' ' text += ';' if ques_type == 'hottext_type': variants = ques.getVariants() for var in variants: variant = variants.get(var) varcount = usersanswers.count(variant) text += variant + '=' +str(varcount) + ' ' text += ';' if ques_type == 'gap_match_type': gaps = ques.getGapvariants() variants = ques.getAnswers() for gap in gaps: gapanswers = usersanswers.get(gap) for var in variants: variant = variants.get(var) varcount = gapanswers.count(variant) text += variant + '=' +str(varcount) + ' ' text += ';' if ques_type == 'order_type': variants = ques.getAnswers() for var in variants: variant = variants.get(var) varanswers = usersanswers.get(variant) for i in range(1,len(variants)+1): numcount = varanswers.count(i) text += str(i) + '=' +str(numcount) + ' ' text += ';' if ques_type == 'match_type': uppervariants = ques.getUpperVariants() variants = ques.getVariants() for variant in variants: varanswers = usersanswers.get(variant) if varanswers: for uppervar in uppervariants: uppervariant = uppervariants.get(uppervar) varcount = varanswers.count(uppervariant) text += uppervariant + '=' + str(varcount) +' ' text += ';' if ques_type == 'text_entry_type': variants = ques.getVariants() for i in range(1, len(usersanswers)+1): gapanswers = usersanswers.get('gap'+str(i)) gap = usersanswers.get('gap'+str(i)) different = gap.get('different') allvariants = gap.get('allvariants') for j in range(1, 4): if variants.get('gap'+str(i)+'_'+str(j)) != None and variants.get('gap'+str(i)+'_'+str(j)) != '': var = variants.get('gap'+str(i)+'_'+str(j)) varcount = allvariants.count(var) text += var + '=' +str(varcount) + ' ' if var in different: different.remove(var) for var in different: varcount = allvariants.count(var) text += var + '=' + str(varcount) + ' ' text += ';' if ques_type == 'inline_choice_type': variants = ques.getVariants() for i in range(1, len(usersanswers)+1): gapanswers = usersanswers.get('gap'+str(i)) for j in range(1, 100): if variants.get('gap'+str(i)+'_'+str(j)) != None: variant = variants.get('gap'+str(i)+'_'+str(j)) varcount = gapanswers.count(variant) text += variant + '=' +str(varcount) + ' ' text += ';' if ques_type == 'extended_text_type': text += ';' if ques_type == 'hotspot_type': variants = ques.getCoords() for i in range(1, len(variants)+1): varcount = usersanswers.count('v'+str(i)) text += 'variant'+str(i) + '=' +str(varcount) + ' ' text += ';' if ques_type == 'associate_type': variants = ques.getAnswers() allvariants = ques.getAllVariants() for variant in usersanswers: varanswers = usersanswers.get(variant) for v in allvariants: var = allvariants.get(v) varcount = varanswers.count(var) if allvariants.get(variant) != var: text += var + '=' + str(varcount) + ' ' text += ';' if ques_type == 'slider_type': averagerow = 1 text += ';' statstext += text.decode("utf-8") if averagerow == 1: statstext += "\n" + self.utranslate("Average") + ": ;;;;" for ques_id in questions: usersanswers = frequencies.get(ques_id) ques = self.getQuestionById(ques_id) ques_type = ques.getType() if ques_type != 'slider_type': length = self.getQuesVarsLength(ques_id) statstext += ';'*length if ques_type == 'slider_type': sum = 0 for ans in usersanswers: answer = float(ans) sum += answer average = sum/len(usersanswers) statstext += str(average) + ';' self.REQUEST.RESPONSE.setHeader('content-type', 'text/csv;charset=utf-8') self.REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=testquestions_stats.csv') return statstext def getQuesVarsLength(self, ques_id): """ """ ques = self.getQuestionById(ques_id) questype = ques.getType() if questype in ['Choice_multiple']: answers = ques.getAnswers() return len(answers) if questype in ['inline_choice_type', 'text_entry_type']: return ques.getGapsCount() if questype == 'gap_match_type': gaps = ques.getGapvariants() return len(gaps) if questype in ['order_type', 'match_type', 'associate_type']: try: answers = ques.getAnswers() except: answers = ques.getVariants() return len(answers) return 1 def getTestTableCSVfile(self, REQUEST): """ """ status = REQUEST.get('status', '') tabletext = u"" tabletext += self.utranslate('first_name') + ";" tabletext += self.utranslate('last_name') + ";" tabletext += self.utranslate('email') + ";" tabletext += self.utranslate('test_status') + ";" tabletext += self.utranslate('score') + ";" if status != "done": tabletext += "URL" tabletext += "\n" groups = self.getTestGroups() group_id = REQUEST.get('group', '') if group_id: groups = [group_id] for group in groups: group_obj = self.getGroupById(group) gmembers = group_obj.getMembers() gmembers_len = len(gmembers) for member in gmembers: student = self.getStudentById(member) container = self.getContainerByTestId(student['ans_containers'], self.getId(), group) sessions = container.getSessions() token = container.getAnswerToken() done = container.checkDoneOrNot() studentinfo = student['firstname'] + ";" + student['lastname'] + ";" + student['email'] + ";" if (status=='done' and done==True) or (status=='not_done' and done==False) or status=='': tabletext += studentinfo.decode("utf-8") if done == False: tabletext += self.utranslate("havent_done_yet") + ";" tabletext += ";" tabletext += self.portal_url()+'/test?token='+token elif done == True: for session in sessions: tabletext += self.utranslate("submitted") + ": " tabletext += session.getSubmitTime() + ";" tabletext += str(session.getScore()) + ";" tabletext += "\n" self.REQUEST.RESPONSE.setHeader('content-type', 'text/csv;charset=utf-8') self.REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=test_stats.csv') return tabletext def getTestXML(self): """ """ xml = '\n' xml += '\n' xml += '\n' xml += '\n' testquestions = self.getQuestions() for ques_id in testquestions: xml += '\n' xml += '\n' xml += '\n' xml += '\n' return xml def getTestPackage(self): """ """ ques_files = "" testquestions = self.getQuestions() for ques_id in testquestions: ques_files += '\n' keywords = self.getKeywordsTuple() kw_xml = u"" for kw in keywords: kw_xml += "\n" kw = kw.strip() kw_xml += """\t\t\t%s\n""" % ( self.getLanguage(), kw.decode('utf-8') ) kw_xml += "\t\t" rights_vals = ('no', 'no', '') if self.getLicence() == 'copyleft': rights_vals = ( 'no', 'no', 'copyleft') if self.getLicence() == 'cc1': rights_vals = ( 'no', 'yes', 'http://creativecommons.org/licenses/by/3.0/') #. Creative Commons Attribution 3.0 License.') if self.getLicence() == 'cc2': rights_vals = ( 'no', 'yes', 'http://creativecommons.org/licenses/by-nc/3.0/') #. Creative Commons Attribution-Noncommercial 3.0 License.') if self.getLicence() == 'cc3': rights_vals = ( 'no', 'yes', 'http://creativecommons.org/licenses/by-nd/3.0/') #. Creative Commons Attribution-No Derivative Works 3.0 License.') if self.getLicence() == 'copyright': rights_vals = ( 'yes', 'yes', 'copyright') rights_xml = u""" LOMv1.0 %s LOMv1.0 %s %s """ % rights_vals lrekeywords = self.getLREKeywords() classification_xml = "" if lrekeywords: taxons = u"" for lrekey in lrekeywords: taxons += """ %s """ % lrekey classification_xml = u""" LREv3.0 discipline LRE Thesaurus %s """ % taxons pack = u""" %s %s %s %s %s %s Final Author %s %s %s %s """ % ( self.getId(), self.getId()+'.xml', self.getId(), self.getLanguage(), self.getTitle().decode('utf-8'), self.getLanguage(), self.getDescription().decode('utf-8'), kw_xml, self.getLanguage(), self.getDifficulty(), self.getAuthorVCard(), rights_xml, classification_xml, self.getId()+'.xml', ques_files) return pack.encode('utf-8') InitializeClass(Test) # EOF