# -*- coding: utf-8 # -*- Mode: Python; py-indent-offset: 4 -*- """ BaseQuestion Class """ __version__ = "$Revision:33$"[11:-2] import re import datetime from waramulib.interfaces import IWaramuClient import Globals from Globals import Acquisition, Persistent from Acquisition import aq_base, aq_inner, aq_parent, Explicit from AccessControl import ClassSecurityInfo, getSecurityManager from OFS.SimpleItem import SimpleItem from Products.ZCatalog.CatalogPathAwareness import CatalogAware from SOAPpy import SOAPProxy from SOAPpy import Types from SOAPpy import Config import cElementTree from zope.interface import implements from zope.component import getUtility from common import commons from Permissions import * from config import VERSION from interfaces import IBaseQuestion class BaseQuestion(CatalogAware, SimpleItem, Persistent, Explicit, commons): """ """ security = ClassSecurityInfo() security.declareObjectPublic() implements(IBaseQuestion) manage_options = SimpleItem.manage_options def __init__(self): self.titletext = "" self.questiontext = "" self.keywords = {} self.description = {} self.default_catalog = "cat_ques" self._state = "draft" def index_html(self): """ index """ return self.restrictedTraverse('view')() security.declareProtected(perm_edit_question, 'setQuestion') def setQuestion(self, question): self.questiontext = question security.declareProtected(perm_view_question, 'getQuestion') def getQuestion(self, REQUEST=None): """ """ if REQUEST is not None: REQUEST.RESPONSE.setHeader('Content-Type', 'text/html; charset=UTF-8') return self.questiontext security.declareProtected(perm_edit_question, 'setTitle') def setTitle(self, title): self.titletext = title security.declareProtected(perm_edit_question, 'setTitles') def setTitles(self, titles): self.titles = titles security.declareProtected(perm_view_question, 'getTitle') def getTitle(self): """ """ try: all_titles = getattr(self, 'titles', None) if all_titles is not None: if all_titles.has_key(self.getLanguage()): return all_titles.get(self.getLanguage()) except AttributeError: # Fall back to old title pass if self.titletext.strip() == '': return "untitled" return self.titletext security.declareProtected(perm_view_question, 'getTitles') def getTitles(self): titles = getattr(self, 'titles', None) if titles is None: lang = self.getLanguage(); self.titles = {lang: self.titletext} #self.titles = {'et': self.titletext} return self.titles security.declareProtected(perm_edit_question, 'setKeywords') def setKeywords(self, keywords): self.keywords = keywords ktuple = [] for k_lang in keywords: keys = keywords.get(k_lang) keys = keys.split(',') for k in keys: k = k.strip() if str(k) != '': ktuple.append(k) self.k = ktuple security.declareProtected(perm_view_question, 'getKeywords') def getKeywords(self): """ """ return self.keywords security.declareProtected(perm_view_question, 'getKeywordsTuple') def getKeywordsTuple(self): #keywordid massiivina """ """ return getattr(self, 'k', []) security.declareProtected(perm_edit_question, 'setDescription') def setDescription(self, description): self.description = description security.declareProtected(perm_view_question, 'getDescription') def getDescription(self): """ """ return self.description security.declareProtected(perm_edit_question, 'setLanguage') def setLanguage(self, language): self.language = language security.declareProtected(perm_view_question, 'getLanguage') def getLanguage(self): """ """ return getattr(self, 'language', 'et') security.declareProtected(perm_edit_question, 'setDifficulty') def setDifficulty(self, difficulty): self.difficulty = difficulty security.declareProtected(perm_view_question, 'getDifficulty') def getDifficulty(self): """ """ return getattr(self, 'difficulty', 'easy') security.declareProtected(perm_edit_question, 'setCreatingDay') def setCreatingDay(self): self.creatingDay = datetime.datetime.today() security.declareProtected(perm_view_question, 'getCreatingDay') def getCreatingDay(self): """ """ return getattr(self, 'creatingDay', self.getLastChange()) security.declareProtected(perm_edit_question, 'setLastChange') def setLastChange(self): self.lastChange = datetime.datetime.today() security.declareProtected(perm_view_question, 'getLastChange') def getLastChange(self): """ """ if not hasattr(self, 'lastChange'): self.lastChange = datetime.datetime.today() return self.lastChange security.declareProtected(perm_view_question, 'setLastPreviewTime') def setLastPreviewTime(self): self.lastPreview = datetime.datetime.today() security.declareProtected(perm_view_question, 'getLastPreviewTime') def getLastPreviewTime(self): return getattr(self, 'lastPreview', datetime.datetime(2000,01,01)) security.declareProtected(perm_edit_question, 'setUser') def setUser(self, user): self.user = str(user) security.declareProtected(perm_view_question, 'getUser') def getUser(self): """ """ return self.user security.declareProtected(perm_edit_question, 'setLREKeywords') def setLREKeywords(self, val): """ set lre keywords """ if val and isinstance(val, str): val = [val] self.lrekeywords = val security.declareProtected(perm_view_question, 'getLREKeywords') def getLREKeywords(self): """ returns array of lrekeywords """ return getattr(self, 'lrekeywords', []) security.declareProtected(perm_edit_question, 'setLicence') def setLicence(self, val): """ set licence """ self.licence = val security.declareProtected(perm_view_question, 'getLicence') def getLicence(self): return getattr(self, 'licence', 'cc1') security.declareProtected(perm_edit_question, 'setAuthor') def setAuthor(self, val): self.author = val security.declareProtected(perm_view_question, 'getAuthor') def getAuthor(self): return getattr(self, 'author', self.getUser()) security.declareProtected(perm_view_question, '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 def _setWaramuUid(self, uid): self.waramuUid = uid def getWaramuUid(self): if not hasattr(self, 'waramuUid'): return "" return self.waramuUid def _setHtmlUid(self): """ """ url = self.getRendererServiceURL() namespace = self.getRendererServiceURL() s = SOAPProxy(url) from socket import gaierror try: htmlUid = s._ns(namespace).newQuestion() self.htmlUid = htmlUid except gaierror, timeout: self.htmlUid = '' def getHtmlUid(self): """ """ if not hasattr(self, 'htmlUid'): self._setHtmlUid() if self.htmlUid == "": self._setHtmlUid() return self.htmlUid def _setHtml(self): """ """ renderopts = 31; quesid = [] quesid.append(self.getId()) z = self._makeZip(quesid) zip = Types.base64BinaryType(z) xmlname = str(self.getId())+'.xml' xml = self.xml2(fullURLs=True) xml = xml.encode("utf-8") #from xml.sax.saxutils import escape #xml = escape(xml) import tempfile fd, filename = tempfile.mkstemp() import os os.close(fd) from StringIO import StringIO f = StringIO() f.write(xml) f.seek(0) file = open(filename, 'w') file.write(xml) file.seek(0) file.close() aa = open(filename, 'rb') export_data=aa.read() aa.close() ex = Types.base64BinaryType(export_data) url = self.getRendererServiceURL() namespace = self.getRendererServiceURL() s = SOAPProxy(url) # don't print out SOAP s.config.debug = 0 s.config.dumpSOAPOut = 0 s.config.dumpSOAPIn = 0 # htmlUid = self.getHtmlUid() # if not htmlUid: self._setHtmlUid() htmlUid = self.getHtmlUid() # get question preview try: s._ns(namespace).newContentPackageSessionWithAttachment(xmlname, "r2q2.rendering.xhtml.XHTMLRenderer", renderopts, ex, "", htmlUid) firstStage = s._ns(namespace).firstStage2(htmlUid) except: self._setHtmlUid() htmlUid = self.getHtmlUid() s._ns(namespace).newContentPackageSessionWithAttachment(xmlname, "r2q2.rendering.xhtml.XHTMLRenderer", renderopts, ex, "", htmlUid) firstStage = s._ns(namespace).firstStage2(htmlUid) #print "XML: ", xml #print "HTML: ", firstStage html = firstStage.decode("utf-8") import base64 if html: #val = base64.decodestring(html) val = html html = val.replace('r2q2response.jsp', 'submitAnswer', 1) cm = re.compile('(.*?)', re.S) head = cm.search(html).group(1) cm = re.compile('(.*?)', re.S) body = cm.search(html).group(1) self.setBody(body) self.setHead(head) self.html = val self.setLastPreviewTime() else: self.setBody("...system error") self.setHead("") #return firstStage.decode("utf-8") #return htmlUid def getBodyWithOwnButtons(self): body = self.getBody(); cm = re.compile("
(.*?)
", re.S) old_buttons = cm.search(body).group(1) to_remove = "
"+old_buttons+"
" body = body.replace(to_remove, ""); submit_button_text = self.utranslate('submit_button_text', 'SUBMIT ANSWER'); reset_button_text = self.utranslate('reset_button_text', 'RESET') buttons = """
""" % (submit_button_text, reset_button_text) return body + buttons; def getPreview(self): """ get question preview """ lastchange = self.getLastChange() lastpreview = self.getLastPreviewTime() if isinstance(lastchange, datetime.date): lastchange = datetime.datetime.today() if lastpreview <= lastchange: self._setHtml() html = self.getBody() head = self.getHead() # cm = re.compile('(.*?)
', re.S) # table = cm.search(html).group(1) # print table # html = html.replace(table, '') html = html.replace('reset', 'hidden') html = html.replace('submit', 'hidden') # if self.getType() == 'extended_text_type': # #print 'html::', html # #tables = re.findall('\.*?\<\/table\>', html) # cm = re.compile('(.*?)
', re.S) # if cm.search(html): # table = cm.search(html).group() # #table = tables[-1] # #print 'table::', table # length = self.getLength() # height = int(length) * 0.15 # text = '' # text += table # html = html.replace(table, text) tmp = """ %s %s """ % (head, html) return html def setBody(self, val): self.body = val def setHead(self, val): self.head = val def getBody(self): """ """ if self.body == "...system error": self._setHtml() return self.body def getHead(self): return self.head def _setErased(self): self.erased = 1 def getErased(self): return getattr(self, 'erased', 0) security.declareProtected(perm_edit_question, 'setWhichImages') def setWhichImages(self, question): #millised pildid on küsimusega kaasas, saan piltide id-d txt = question allimages = re.finditer('src\=".*?\"', txt) srcid=[] self.imagesIds=[] for y in allimages: y.group() srcid.append(y.group()) for x in srcid: y = x.split('/') y = y[-1] z = y.replace('"', '') self.imagesIds.append(z) security.declareProtected(perm_view_question, 'getImages') def getImages(self): """ """ return self.imagesIds def replaceSymbols(self, text): text = text.replace("&", "&") if not isinstance(text, unicode): text = text.decode('utf-8') return text def fixQuestionText(self, questiontext): txt = questiontext; p_tags = re.finditer('\', questiontext) for tag in p_tags: tag = tag.group() txt = txt.replace(tag, "
") txt = txt.replace("

", "
") if not isinstance(txt, unicode): txt = txt.decode('utf-8') return txt def replaceImageurl(self, questiontext): txt = questiontext; p_tags = re.finditer('\', questiontext) for tag in p_tags: tag = tag.group() txt = txt.replace(tag, "
") txt = txt.replace("

", "
") allimages = re.finditer('src\=".*?\"', txt) srcid=[] images2=[] for y in allimages: y.group() srcid.append(y.group()) for x in srcid: y = x.split('/') y = y[-1] z = y.replace('"', '') images2.append(z) ids = [] types = [] for z in images2: ids.append(z) picture = getattr(self.images, z) imageContentType =picture.content_type.split('/') imagetype = imageContentType[-1] types.append(imagetype) allimages2 = re.finditer('src\=".*?\"', txt) i = 0 for k in allimages2: z = k.group() txt = txt.replace(z, 'src="'+ids[i]+'.'+types[i]+'"', 1) i = i + 1 if not isinstance(txt, unicode): txt = txt.decode('utf-8') return txt def isitFloat(self, nr): """ """ try: float(nr) return 1 except ValueError: pass return 0 def setMetaLanguages(self, languages): self.metalanguages = languages def getMetaLanguages(self): return getattr(self, 'metalanguages', self.getLanguage()) def getPortalTypeName(self): """ """ return self.getType() def getStatus(self): """ """ return self._state def setStatus(self, val): self._state = val def hasPermissionToView(self, context, user): if (self.getStatus() == "private"): if (self.checkRoles(context, user, role='Manager') or self.getUser()==str(user)): return True else: return False return True security.declarePrivate('setCommonData') def setCommonData(self, REQUEST): """ set metadata """ #title = REQUEST.get('title', 'untitled') language = REQUEST.get('language', 'et') lang_title = '' meta_languages = REQUEST.get('meta_languages') lang_array = meta_languages.split(' ') self.setMetaLanguages(meta_languages) keys_dict = {} desc_dict = {} titl_dict = {} lang_metadata = REQUEST.get('metadata.'+language) lang_title = lang_metadata.get('titles') for lang in lang_array: if lang != '': metadata = REQUEST.get('metadata.'+lang) keys_dict[lang] = metadata.get('keywords') desc_dict[lang] = metadata.get('description') titl_dict[lang] = metadata.get('titles') if lang_title == '' or lang_title == 'untitled': lang_title = metadata.get('titles') if lang_title != '': titl_dict[language] = lang_title else: titl_dict[language] = 'untitled' difficulty = REQUEST.get('difficulty', 'easy') licence = REQUEST.get('licence', 'cc1') lrekeywords = REQUEST.get('lrekeywords', '') author = REQUEST.get('author', '') user = str(REQUEST.get('AUTHENTICATED_USER')) if author == '': author = user state = REQUEST.get('state', 'draft') self.setStatus(state) q = REQUEST.get('question', '') self.setTitles(titl_dict) self.setKeywords(keys_dict) self.setLanguage(language) self.setDescription(desc_dict) self.setDifficulty(difficulty) self.setLREKeywords(lrekeywords) self.setLicence(licence) self.setQuestion(q) self.setWhichImages(q) self.setLastChange() self.setAuthor(author) if self.getType() not in ['gap_match_type', 'text_entry_type', 'inline_choice_type', 'hottext_type']: self._sendToWaramu() def _sendToWaramu(self): "send's to waramu if waramu is enabled and status is public" status = self.getStatus() # if question is public and waramu possibility is enabled, send or update question in waramu if status == 'public' and self.isWaramuEnabled(): if self.getWaramuUid() == "": self._exportToWaramu() else: self._updateToWaramu() # if waramu is enabled and question is in waramu, but question isn't public, delete it from waramu elif self.isWaramuEnabled() and status != 'public' and self.getWaramuUid() != "": self._deleteFromWaramu() def _getWaramu(self): if not self.isWaramuEnabled(): return None 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 = w._genAppUser(getSecurityManager().getUser()) au = ""+self.getOwnerTuple()[1]+"" data = self._generateWaramuXML() wrid = w.newResource(au, data) w.addAttachment(au, wrid, self._makeZip([self.getId()]), 'question.zip') self._setWaramuUid(wrid) def _updateToWaramu(self): w = self._getWaramu() if w is None: return #au = w._genAppUser(getSecurityManager().getUser()) au = ""+self.getOwnerTuple()[1]+"" data = self._generateWaramuXML() wrid = self.getWaramuUid() if not wrid: return #print w.getResource(au, wrid) 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._makeZip([self.getId()]), 'question.zip') def _deleteFromWaramu(self): """ """ w = self._getWaramu() if w is None: return #au = w._genAppUser(getSecurityManager().getUser()) au = ""+self.getOwnerTuple()[1]+"" uid = self.getWaramuUid() res = w.deleteResource(au, uid) if not res: self._setWaramuUid("") def _generateWaramuXML(self): data = u'\n' # timezone #import time #timezone = - (time.timezone / 60 / 60) #timezone = '%+03d00' % timezone #createdtime = self.getCreatingDay().strftime('%Y/%m/%d %H:%M:%S') #createdtime += ' ' + timezone #updatedtime = self.getLastChange().strftime('%Y/%m/%d %H:%M:%S') #updatedtime += ' ' + timezone #data += ''+ createdtime +'\n' #data += ''+ updatedtime +'\n' data += '\n' all_langs = [] titles = self.getTitles() descs = self.getDescription() keywords = self.getKeywords() all_langs += titles.keys() all_langs += descs.keys() all_langs += keywords.keys() def uniq(inp): res = [] for x in inp: if x in res: continue res.append(x) return res all_langs = uniq(all_langs) for l in all_langs: data += ''+titles.get(l, '').decode('utf-8')+'\n' data += ''+descs.get(l, '').decode('utf-8')+'\n' data += '\n' lk = keywords.get(l, '') lk = lk.split(',') for k in lk: data += '\t'+k.strip().decode('utf-8')+'\n' data += '\n' lic = self.getLicence() if lic == 'cc1': lic = 'http://creativecommons.org/licenses/by/3.0/' elif lic == 'cc2': lic = 'http://creativecommons.org/licenses/by-nc/3.0/' elif lic == 'cc3': lic = 'http://creativecommons.org/licenses/by-nd/3.0/' data += ''+self.getId()+'\n' 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' # lrekeywords data += '\n'; lrekeys = self.getLREKeywords() for lrekey in lrekeys: data += '\t'+lrekey+'\n' data += '\n' typ = self.getInteractionType().decode('utf-8') data += ''+typ+'\n' data += "" return data def match_correct(self): """ """ resp = u""" 1 0 """ % (self.getId(), self.getId()) return resp def map_response(self): """ """ map_resp= u""" 0.0 """ % (self.getId(), self.getId()) return map_resp def match_correct_feedback(self): """ """ resp = u""" 1 0 """ % (self.getId(), self.getId(), self.getId()) return resp def package(self): """ """ extra_files = "" try: extra_files = self.getExtraFilesXML() except AttributeError: pass kw_xml = u"" 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 kws = self.getKeywords() kw_xml += u"\n" for kwl, kw_raw in kws.items(): for kw in kw_raw.split(','): kw = kw.strip() kw_xml += """\t\t\t%s\n""" % ( kwl, kw.decode('utf-8') ) kw_xml += "\t\t" titles = self.getTitles() title_xml = u"\n" for title_lang, titl in titles.items(): title_xml += """\t\t\t%s\n""" % (title_lang, titl.decode('utf-8')) title_xml += "\t\t" descs = self.getDescription() desc_xml = u"\n" for desc_lang, des in descs.items(): desc_xml += """\t\t\t%s\n""" % (desc_lang, des.decode('utf-8')) desc_xml += "\t\t" #print self.getId() #print self.getId()+'.xml' #print self.getId() #print title_xml #print desc_xml #print kw_xml #print self.getLanguage() #print "x-none" #print self.getDifficulty() #print self.getAuthor() #print rights_xml #print self.getInteractionType() #print VERSION #print self.getId()+'.xml' #print extra_files pack = u""" %s %s %s %s %s %s Final Author %s %s %s false %s none true TATS (http://trac.htk.tlu.ee/modules/wiki/Tats) %s Centre for Educational Technology %s """ % ( self.getId(), self.getId()+'.xml', self.getId(), title_xml, desc_xml, kw_xml, self.getLanguage(), "x-none", self.getDifficulty(), self.getAuthorVCard(), rights_xml, classification_xml, self.getInteractionType(), VERSION, self.getId()+'.xml', extra_files) return pack.encode('utf-8') def getEditTemplateName(self, REQUEST): return self.configuration.getEdit(self.meta_type) def getViewTemplateName(self, REQUEST): return self.configuration.getView(self.meta_type) Globals.InitializeClass(BaseQuestion) #EOF