# -*- 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