# ~*~ coding: utf-8 import cElementTree import time import datetime from zope.interface import implements from zope.component import getUtility, queryUtility, queryAdapter from AccessControl import getSecurityManager from zope.component import getSiteManager from interfaces import ICombinedWidget from interfaces import IResource, IWidget, IAttachable class CSSClass(object): curr = True def get(self): if self.curr: self.curr = False return " even" self.curr = True return " odd" class Resource(object): """ resource """ implements(IResource) id = None _typeid = None # type id all_langs = ['et', 'en'] _n_of_files = 0 _stash = {} _infos = {} _fetchTime = None created = None updated = None def _getNode(self, elem, name): for e in elem.getchildren(): ename = e.tag[1:].split('}', 1) if len(ename) > 1 and ename[1] == name: return e return None def __init__(self, conn, data): """ conn - connection to waramu """ self._acl = {'owner': '', 'viewUsers' : [], 'viewGroups' : [], 'editUsers' : [], 'editGroups' : [], 'downUsers' : [], 'downGroups' : []} self._data = data if data is None: return print data xml = cElementTree.fromstring(self._data) id = xml.find('wid') self.id = id.text.strip() self.created = xml.find('created').text.strip() self.updated = xml.find('updated').text.strip() datanode = self._getNode(xml, 'data') self._typeid = datanode.tag[1:].split('}', 1)[0] # get type description td, infos = conn.describeType(self._typeid) self._td = td self._infos = infos self._storeTime = time.time() s = {} all_langs = [] for fn, d in td.items(): vv = xml.findall('{%(t)s}data/{%(t)s}%(f)s' % {'t': self._typeid, 'f': fn}) print "VV:", vv for v in vv: if d.get('multiLingual') == '1': lang = v.get('lang') if lang not in all_langs: all_langs.append(lang) else: lang = None if d.get('type') == 'MultiString' or d.get('type') == 'MultiInteger': if lang is None: s[fn] = [] else: if not s.has_key(fn): s[fn] = {} vo = v.findall('{%s}value' % self._typeid) for onva in v.getchildren(): ns, tag = onva.tag[1:].split('}', 1) if tag != 'value': continue #for onva in vo: val = onva.text if val is None: val = "" else: val = val.strip() if lang is None: s[fn].append(val) else: if not s[fn].has_key(lang): s[fn][lang] = [] s[fn][lang].append(val) else: val = v.text if val is None: val = "" else: val = val.strip() if lang is None: s[fn] = val else: if not s.has_key(fn): s[fn] = {} if not s[fn].has_key(lang): s[fn][lang] = "" s[fn][lang] = val self._stash = s self.all_langs = all_langs # read acl owner = xml.find('acl/owner').text.strip() self._acl['owner'] = owner view = xml.find('acl/view') edit = xml.find('acl/edit') down = xml.find('acl/down') for x, m in [view, 'view'], [edit, 'edit'], [down, 'down']: if x is None: continue users = x.find('users') groups = x.find('groups') if users: us = users.findall('value') for u in us: uname = u.text.strip() self._acl[m+'Users'].append(uname) if groups: gr = groups.findall('value') for g in gr: grname = g.text.strip() self._acl[m+'Groups'].append(grname) ats = xml.findall('attachments/attachment') self._n_of_files = len(ats) def getId(self): return self.id def getTypeID(self): return self._typeid def setTypeID(self, val): self._typeid = val def setTypeDescription(self, td): self._td = td def setTypeInfos(self, inf): self._infos = inf def isNew(self): if self.id is None or self.id == "": return True return False def view(self): r = "id: "+self.id return self._form('view') def edit(self): return self._form('edit') def info(self): return self._acl['owner'] def getTitle(self): title = self._stash.get('title') if isinstance(title, dict): noopt = True gotTitle = False if self._stash.get('mdLanguage'): if title.has_key(self._stash.get('mdLanguage')): title = title.get(self._stash.get('mdLanguage')) gotTitle = True noopt = False if noopt: # XXX: need testing for x in title.keys(): if title.get(x) is not None and \ len(title.get(x)) > 0: title = title.get(x) gotTitle = True break if not gotTitle: title = None if title is None: # needs a fix if self._stash.has_key('k_title'): title = self._stash.get('k_title') if not title: title = "(untitled)" if self.getNOfAttachments() > 0: title += " ("+str(self.getNOfAttachments())+") " return title def getNOfAttachments(self): return self._n_of_files def getDate(self): d, ofs = self.created.split('+', 1) l = datetime.datetime.fromtimestamp(time.mktime(time.strptime(d.strip(), "%Y/%m/%d %H:%M:%S"))) offhour = ofs[:2] offminu = ofs[2:] return l + datetime.timedelta(hours=int(offhour), minutes=int(offminu)) #return self.created def getAuthor(self): own = self._acl.get('owner') #return own[:own.index('@')] return self._acl.get('owner') def isOwner(self): u = getSecurityManager().getUser() w = self._getConnection() suffix = w.getWaramuSuffix() me = u.getId()+"@"+suffix acl = self.getACL() owner = acl.get('owner') if owner == me: return True return False def getACL(self): return self._acl def getViewUsers(self): ac = self.getACL() return ac.get('viewUsers') def getViewGroups(self): ac = self.getACL() return ac.get('viewGroups') def getEditUsers(self): ac = self.getACL() return ac.get('editUsers') def getEditGroups(self): ac = self.getACL() return ac.get('editGroups') def hasMultilingualFields(self): tDesc = self._td for x in tDesc.keys(): f = tDesc[x] if f.get('multiLingual') == '1': return True return False def getResourceLanguages(self): return self.all_langs def getDefaultLanguage(self): if self._stash.has_key('mdLanguage'): mdl = self._stash.get('mdLanguage') if not mdl.strip(): if len(self.getResourceLanguages()) > 0: return self.getResourceLanguages()[0] else: if mdl.strip() not in self.getResourceLanguages(): return self.getResourceLanguages()[0] return mdl.strip() return "et" def get(self, fname, lang=None): fval = self._stash.get(fname) if lang is not None and fval is not None: fval = fval.get(lang) if fval is None: fval = "" return fval def set(self, fname, val, lang=None): """ set field's value. """ if lang is not None: if not self._stash.has_key(fname): self._stash[fname] = {} self._stash[fname][lang] = val else: self._stash[fname] = val def hasRightTo(self, what): acl = self.getACL() if what == 'view': if not acl.get(what+'Users') and not acl.get(what+'Groups'): return True u = getSecurityManager().getUser() grs = [] if hasattr(u, 'getGroups'): grs = u.getGroups() w = self._getConnection() suffix = w.getWaramuSuffix() meid = u.getId() if meid is None: return False me = u.getId()+"@"+suffix owner = acl.get('owner') if me == owner: return True users = acl.get(what+'Users') if users is not None: if me in users: return True groups = acl.get(what+'Groups') if groups is not None: for x in grs: grname = x+"@"+suffix if grname in groups: return True return False def _form(self, mode): if not self.hasRightTo(mode): return "You don't have permission to "+mode+" this resource" w = self._getConnection() tDesc = self._td tid = self.getTypeID() defLang = self.getDefaultLanguage() # possible profile integration r = u"\n" mlFields = [] nlFields = [] langs = self.getResourceLanguages() combined = [] ignore = [] sm = getSiteManager(context=self) ads = sm.getAdapters((self,), ICombinedWidget) for name, ad in ads: toUse = True for x in ad.combines(): # check if combined fields are in type description if x not in tDesc.keys(): toUse = False if toUse: combined.append([ad] + map(tDesc.get, ad.combines())) ignore = ignore + ad.combines() for x in tDesc.keys(): if x in ignore: continue f = tDesc[x] if f.get('autovalue') == '1': continue if f.get('multiLingual') == '1': mlFields.append(f) else: nlFields.append(f) cssSelector = CSSClass() fcls = cssSelector.get() if len(mlFields) > 0: m = u'
\n' for l in langs: cls = "hidden" if l == defLang: cls = "visible" m += '
\n' for f in mlFields: fcls = cssSelector.get() fid = l+'_'+f.get('name') adp = queryAdapter(self, IWidget, f.get('name')) if adp is None: adp = queryAdapter(self, IWidget) m += getattr(adp, mode)(f, fid, fcls, w, tid, lang=l) m += '
\n' r += m + "
\n" p = u'
\n' for f in nlFields: fcls = cssSelector.get() adp = queryAdapter(self, IWidget, f.get('name')) if adp is None: adp = queryAdapter(self, IWidget) p += getattr(adp, mode)(f, f.get('name'), fcls, w, tid) for comb in combined: ad = comb.pop(0) fcls = cssSelector.get() p += '
\n' p += apply(getattr(ad, mode), comb) p += "
\n" r += p + "
\n" fcls = cssSelector.get() a = u'
\n' adp = queryAdapter(self, IAttachable) a += getattr(adp, mode)() a += '
' r += a r += "\n" r += '\n' r += '\n' return r