# -*- coding: utf-8 # $Id$ # # Copyright 2001, 2002 by IVA Team and contributors # # This file is part of IVA. # # IVA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # IVA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with IVA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Contains class Cruft, which is used as a placeholder for miscellaneous utility functions that many objects need.""" __version__ = "$Revision$"[11:-2] from AccessControl import ClassSecurityInfo from AccessControl import getSecurityManager from urllib import quote from common import perm_view, perm_edit, perm_manage, perm_add_lo, translate import re import common import time from common import get_local_roles import string from DateTime import DateTime import calendar calendar.setfirstweekday(0) from Errors import FleError from Features import _FEATURES from interfaces import IWebtopItem, IUserManager, IStatistics, ICourseManager from zope.component import getUtility, queryUtility, getAdapter from zope.component.interfaces import ComponentLookupError from zope.sendmail.interfaces import IMailer from email.MIMEText import MIMEText from email.Header import Header from email.Utils import parseaddr, formataddr class Cruft: """Class containing miscellaneous methods that are historical baggage, but possible be gotten rid of, or at least implemented differently or somewhere else.""" security = ClassSecurityInfo() security.declarePublic('find_URL_of_fle_root') def find_URL_of_fle_root(self, REQUEST): """Return URL of our FLE installation.""" import FLE from string import rfind url = REQUEST.URL1 obj = self while not isinstance(obj, FLE.FLE): obj = obj.parent() url = url[:rfind(url,'/')] return url def find_URL_of_user_info(self, REQUEST): """Return URL of UserInfo.""" import UserInfo from string import rfind url = REQUEST.URL1 obj = self while not isinstance(obj, UserInfo.UserInfo): obj = obj.parent() url = url[:rfind(url,'/')] return url security.declarePublic('find_URL_of_webtop') def find_URL_of_webtop(self, REQUEST): """Return URL of Webtop.""" import Webtop from string import rfind url = REQUEST.URL1 obj = self while not isinstance(obj, Webtop.Webtop): obj = obj.parent() url = url[:rfind(url,'/')] return url security.declarePublic('find_URL_of_group_folder') def find_URL_of_group_folder(self, REQUEST): """Return URL of toplevel group folder or group folder proxy.""" import GroupFolder from string import rfind url = REQUEST.URL1 obj = self while 1: if isinstance(obj, GroupFolder.GroupFolder): return url obj = obj.parent() url = url[:rfind(url,'/')] return url security.declarePublic('find_URL_of_thread_start_node') def find_URL_of_thread_start_node(self, REQUEST): """Return URL of starting note.""" import CourseContext from string import rfind url = REQUEST.URL1 obj = self while not isinstance(obj.parent(), CourseContext.CourseContext): obj = obj.parent() url = url[:rfind(url,'/')] return url security.declarePublic('find_URL_of_course') def find_URL_of_course(self, REQUEST): """Return URL of starting note.""" obj = self while not obj.meta_type == 'Course': obj = obj.parent() return obj.absolute_url() security.declarePublic('find_URL_of_course_context') def find_URL_of_course_context(self, REQUEST): """Return URL of starting note.""" import CourseContext from string import rfind url = REQUEST.URL1 obj = self while not isinstance(obj, CourseContext.CourseContext): obj = obj.parent() url = url[:rfind(url,'/')] return url security.declarePublic('is_student') def is_student(self, REQUEST,nr=None, uname=''): """ is user student in given course """ splitter = '/' if splitter not in REQUEST.PATH_TRANSLATED: splitter = '\\' if nr is None: nr = self.jooksva_kursuse_nr(REQUEST,uname) ic = string.rfind(REQUEST.PATH_TRANSLATED, 'fle_users') url = REQUEST.PATH_TRANSLATED if ic == -1: nr = self.fle_root().courses.get_course_id_from_req(REQUEST) else: i = ic plst = filter(lambda x:x, string.split(url[i:], splitter)) nr = plst[3][1:] cm = getUtility(ICourseManager) if not hasattr(cm, str(nr)): return 0 checkname = getSecurityManager().getUser() for x in self.acl_users._getGroupsForPrincipal(checkname): if x == str(nr) or x == str(nr)+'_teachers' : return 1 #if 'Student' in get_local_roles(getattr(self.fle_root().courses, nr),checkname): # return 1 try: fm = getattr(self.fle_root().fle_users, str(checkname)) if fm.has_any_role(('IVAAdmin','Manager')): return 1 except AttributeError: return 0 return 0 security.declarePublic('kas_opetaja') def kas_opetaja(self,REQUEST,nr=None,uname=''): """ If user is teacher. Additional role checks """ if nr is None: nr = self.jooksva_kursuse_nr(REQUEST,uname) if not hasattr(getUtility(ICourseManager), str(nr)): return 0 #checkname = str(REQUEST.AUTHENTICATED_USER) checkname = str(getSecurityManager().getUser()) uur = getSecurityManager().getUser() # XXX: finish me if nr+'_teachers' in uur.getGroups(): return 1 #groups = self.acl_users.getGroupsForPrincipal(checkname) if uur.has_role(('Manager','IVAAdmin')): return 1 #if checkname in getattr(self.fle_root().courses, nr).get_teachers(): # return 1 print "I am nobody!" print uur, uur.getGroups() print uur.getRoles() return 0 security.declarePublic('jooksva_kursuse_nimi') def jooksva_kursuse_nimi(self,REQUEST,uname=''): """ jooksva kursuse nimi """ nr = str(self.jooksva_kursuse_nr(REQUEST,uname)) cm = getUtility(ICourseManager) try: return str(cm.get_child(nr).get_name()) except UnicodeEncodeError: return str(cm.get_child(nr).get_name().encode('utf-8')) except AttributeError: return translate(self,"course not selected") except KeyError: return translate(self,"course not selected") security.declarePublic('jooksva_kursuse_nr') def jooksva_kursuse_nr(self,REQUEST,uname=''): """ jooksva kursuse number """; um = getUtility(IUserManager) try: if not uname: uname = self.get_current_user() u = um.get_user_info(uname) return u.get_jooksev_kursus() except: return 0 security.declarePublic('get_current_user') def get_current_user(self, REQUEST=None): """Extract current user's name from the REQUEST object.""" return str(getSecurityManager().getUser()) security.declarePublic('urlquote') def urlquote(self, text): """urlquote given text.""" return quote(text) def get_url_to_object(self,obj): # Make a list of parents without the Application object # (from obj to FLE) return obj.absolute_url()+'/' #objs = obj.aq_inner.aq_chain[:-1] #objs.reverse() #path='/'.join([x.getId() for x in objs])+'/' #return path def get_object_of_url(self,url,base,remove_last=1): #XXX: broken for VirtualHostMonster! path=url.split('/') if remove_last: path.pop() # remove last entry path.reverse() if path[-1]=='http:': # remove protocol path.pop() path.pop() path.pop() # remove first (root) entry obj = base.fle_root() #obj = base.getPhysicalRoot() try: while path: oname=path.pop() obj=getattr(obj,oname).__of__(obj) return obj except: #raise 'Internal link error, object not found',str(obj)+' - '+oname return None def algusURList(self, REQUEST, osa): "URL soovitud loiguni" x=REQUEST.URL0 if x.find(osa)==-1: return "" return x[:x.find(osa)+len(osa)] def kasLopeb(self, tekst, otsitav): "jah/ei" # return tekst+" ja " + otsitav return tekst.endswith(otsitav) def myOwnWebtop(self, REQUEST): "jah/ei" return self.kasutajaNimi(REQUEST)==str(REQUEST.AUTHENTICATED_USER) def kasutajaNimi(self, REQUEST): "nimi" aadress=REQUEST.URL0 nr=aadress.find('fle_users') if nr==-1: return "" ots=aadress.find('/', nr+10) nimi=aadress[nr+10:ots] nimi = re.sub('%20', ' ',nimi) return nimi def ajaMuutmisElemendid(self, elemendinimi, aeg=-1): "Valikute kogum" import YlTest from YlTest import LahendusLuba from types import StringType abi=LahendusLuba() if type(aeg)==StringType: aeg=float(aeg) if aeg==-1:aeg=time.time() m=time.localtime(aeg) tulemus=abi.looValik(elemendinimi+"Aasta", m[0]-5, m[0]+10, m[0]) tulemus=tulemus+"-"+\ abi.looValik(elemendinimi+"Kuu", 1, 12, m[1]) tulemus=tulemus+"-"+\ abi.looValik(elemendinimi+"Paev", 1, 31, m[2]) tulemus=tulemus+"   "+\ abi.looValik(elemendinimi+"Tund", 0, 23, m[3]) tulemus=tulemus+":"+\ abi.looValik(elemendinimi+"Minut", 0, 59, m[4], samm=5) return tulemus def set_undefined_page(self, message, REQUEST): """Set REQUEST.RESPONSE.redirect, so that we go to undefined page and give an explanation.""" message = common.quote_html_hack(message) REQUEST.RESPONSE.redirect("undefined_page?explanation=%s" % message) def kasutajaasukoht(self, REQUEST,url=''): """Kasutaja asukoht""" if url: x = url else: x = REQUEST.URL0 if x.find('sub_manager')>0: return "Workshops" if x.find('manage')>0: return "Management" if x.find('sharedDocs')>0: return "Organizer" if x.find('tracker_show')>0: return "Bookshelf" if x.find('tracker')>0: return "Management" if x.find('WelCome')>0: return "Bookshelf" #Course ZWiki if x.find('assignmentGrading')>0: return "Webtop" if x.find('feedmoot')>0: return "Organizer" if x.find('createMail')>0 or x.find('edit_user_form')>0 or x.find('show_user_info')>0: return 'Organizer' if x.find('kalendriAasta')>0 or x.find('organizer')>0 or x.find('logout')>0: return 'Organizer' if x.find('course_info_user')>0: return "Webtop" if x.find('course_index')>0 or x.find('course_info')>0: return 'Bookshelf' if x.find('workshop_')>0: return "Workshops" if x.find('/courses/')>0: if x.find('/qt_index')>0 or x.find('/courses/index_html')>0 or self.kas_haldus(REQUEST,x): return "Management" if not x.find('/gf/')>0 and x.find('/testid/')>0: return "Management" if x.find('import_form_handler2')>0: return "Management" if not x.find('/gf/')>0: return "Workshops" if x.find('/fle_users/')>0 and x.find('/webtop/')>0: return "Webtop" if x.find('qtExercise')>0: return "Webtop" if self.kas_haldus(REQUEST, x) or x.find('ootajateLoetelu')>0: return 'Management' else: return 'Bookshelf' security.declarePublic('kas_haldus') def kas_haldus(self, REQUEST, veebiurl): """kas sobib halduseks""" if re.match(".*/courses/[0-9]+/syndmused", veebiurl): if self.kas_opetaja(self, REQUEST): return 1 else: return 0 laused=( ".*management_index", ".*qt_index", ".*muuda_vorm", ".*kysimuse_vorm", ".*add_course_form", ".*sisegrupihaldus", ".*courses/index_html", ".*ylesandedMuutmisTabelina", ".*ylesanneteTyypideLoetelu", ".*pealkirjaMuutmisVormHTML", ".*muutmisVorm", ".*lubadeViited", ".*koigiLuba", ".*isikuLubadeLisamisVorm", ".*grupiLubadeLisamisVorm", ".*/filtreerimisvorm2", ".*/kasutajateTulemused", ".*/typesets", ".*/lahendusteStatistika", ".*/kodutood.*", ".*/manage_.*", ".*qtCatalog.*", #".*", ) leitud=0 x=veebiurl for lause in laused: if re.match(lause, x): leitud=1 break return leitud def zwiki_export(self,REQUEST,level=None,wiki_id=''): """ zwiki manage form handler """ if not wiki_id: return REQUEST.RESPONSE.redirect(self.absolute_url()) from ExportIMS import Kirjutus from ExportIMS import kirjutaYldM import tempfile, os failinimi = tempfile.mktemp() if not level: level=99999 # number = self.get_course_id_from_req(REQUEST) number = 0 # nr = self.get_id() # try: # number = int(nr) # except: # number = int(nr[1:]) yld = kirjutaYldM() yld.kirjutaYldmanifest(number,'WIKI',base=str(number)+'/') yld.lisaFaili(failinimi) k = Kirjutus(self.fle_root(), number) k.looKursuseFail(0) wikikoht='' try: wikikoht = getattr(self,wiki_id) except: pass if wikikoht: k.kirjutaWiki(wikikoht,'ZWiki',wikikoht.aq_inner.get_name(),wikikoht.wikiKaustEsimeneLeht(),palju=level) k.pakiKursusFaili(failinimi) file = open(failinimi,"rb") export_data=file.read() file.close() os.remove(failinimi) REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=zwikiexport.zip') REQUEST.RESPONSE.setHeader('content-type','application/zip') return export_data security.declareProtected(perm_view, 'saadaEmail') def saadaEmail(self, tomail, subject, message, saatja=''): """ proovime saata kirja """ p_saatja = '' if saatja: p_saatja = saatja if hasattr(self,'MFROM') and not p_saatja: p_saatja = self.MFROM if not p_saatja: return 0 try: mailer = getUtility(IMailer, 'iva.smtp') except ComponentLookupError: return 0 if mailer is None: return 0 charset = 'utf-8' msg = MIMEText(message.encode('utf-8'), 'plain', charset) msg['From'] = formataddr(('', saatja)) msg['To'] = formataddr(('', tomail)) msg['Subject'] = Header(subject, charset) mailer.send(saatja, tomail, msg.as_string()) return 1 def numberToText(self, REQUEST, arv): "Asendab punkti komaga, kui see vajalik" tekst=str(arv) eraldaja=translate(self, "decimal_separator") tekst=tekst.replace(".", eraldaja) return tekst def firstAndLast(self,uname='',req=None): """ Give object author's first and last name """ if hasattr(uname, 'im_func'): uname = uname() abc = '' if not uname and not req: abc = self.getOwnerTuple()[1] if not uname and not abc and req: abc = str(req.AUTHENTICATED_USER) elif not uname and not abc and not req: abc = uname elif uname: abc = uname try: ui = self.fle_users.get_user_info(str(abc)) if ui and ui.get_first_name()!='' and ui.get_last_name()!='': nimi = ui.get_first_name()+" "+ui.get_last_name() else: nimi = abc except FleError: nimi = uname except KeyError: nimi = uname return nimi def firstAndLastNG(self, uname='', req=None, last_first = False): """Give object author's first and last name """ if hasattr(uname, 'im_func'): uname = uname() abc = '' if not uname and not req: abc = self.getOwnerTuple()[1] if not uname and not abc and req: abc = str(req.AUTHENTICATED_USER) elif not uname and not abc and not req: abc = uname elif uname: abc = uname # first first and last name nimi = str(abc) cat = getUtility(IUserManager).userinfo_zcatalog res = cat({'get_uname': str(abc)}) if len(res) == 1: if res[0].get_last_name.strip() == "" or res[0].get_first_name.strip() == "": return nimi if last_first: return res[0].get_last_name + ", " + res[0].get_first_name return res[0].get_first_name+" "+res[0].get_last_name else: for x in res: if x.get_uname == str(abc): if x.get_last_name.strip() == "" or x.get_first_name.strip() == "": return nimi if last_first: return x.get_last_name + ", " + x.get_first_name return x.get_first_name+" "+x.get_last_name return nimi def lastAndFirst(self,uname='',req=None): """ Give object author's first and last name """ return self.firstAndLastNG(uname, req, last_first = True) def is_courseContext(self): return 0 def getCalendar(self): """ return closest calendar """ return getattr(self, 'syndmused', None) def batch_previous(self, batch): """ generate links to next and previous pages """ result = [] while batch.previous: batch = batch.previous result.append(batch.start-1) result.reverse() return result def batch_next(self, batch): """ return an array of next batch staring points """ result = [] while batch.next: batch = batch.next result.append(batch.start-1) return result security.declareProtected(perm_view, 'format_date') def format_date(self, REQUEST, timestamp): """ format timestamp """ return time.strftime(translate(self,'short_date_format',default="%Y-%m-%d"), time.localtime(timestamp)) security.declareProtected(perm_manage, 'getFeatures') def getFeatures(self, installed=1, not_installed=0): """ get all (not)installed features """ res = [] for x in _FEATURES.keys(): adapt = getAdapter(self, _FEATURES.get(x).get('interface')) if adapt.isInstalled(): if installed: res.append(x) else: if not_installed: res.append(x) return res def getFeatureDescription(self, feature, spec): """ return feature description """ return _FEATURES[feature][spec] security.declareProtected(perm_manage, 'enableFeature') def enableFeature(self, REQUEST=None, feature='_x'): """ enable/install module - usually it means setting up skins and possibly some objects """ if not _FEATURES.has_key(feature): raise 'Not available' adapt = getAdapter(self, _FEATURES.get(feature).get('interface')) adapt._install() if REQUEST: return REQUEST.RESPONSE.redirect('manage_iva_setup.html') return 0 security.declareProtected(perm_manage, 'disableFeature') def disableFeature(self, REQUEST=None, feature='_x'): """ disable/uninstall feature XXX: should add support for uninstall method? """ if not _FEATURES.has_key(feature): raise 'Not available' adapt = getAdapter(self, _FEATURES.get(feature).get('interface')) adapt._uninstall() if REQUEST: return REQUEST.RESPONSE.redirect('manage_iva_setup.html') return 0 def isFeatureEnabled(self, feature): """ is feature enabled/installed """ feat = _FEATURES.get(feature, None) if feat: adapt = getAdapter(self.fle_root(), _FEATURES.get(feature).get('interface')) if adapt.isInstalled(): return True def isFeatureVisible(self, feature): """ should feature be visible to users or not """ if not self.isFeatureEnabled(feature): return False adapt = getAdapter(self.fle_root(), _FEATURES.get(feature).get('interface')) return adapt.isVisible() security.declareProtected(perm_manage, 'featureManagement') def featureManagement(self, REQUEST, feature): """ return feature management page """ if not _FEATURES.has_key(feature): raise 'Not available' return REQUEST.RESPONSE.redirect('@@manage-'+feature) security.declarePublic('isAnonymousUser') def isAnonymousUser(self): """ check if user is anonymous """ u = getSecurityManager().getUser() if u is None or u.getUserName() == 'Anonymous User': return 1 return 0 # EOF