def check_content_type(self, text, expected_type): f = open(self.TEMPFILENAME, "wb") f.write(text) f.close() pt = PageTemplateFile(self.TEMPFILENAME) pt.read() self.assertEqual(pt.content_type, expected_type)
def patch_pagetemplates(): from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate from zope.pagetemplate.pagetemplate import _error_start # customize `pt_editForm` of ZopePageTemplate tmpl = PageTemplateFile('ptEdit', globals(), __name__='pt_editForm') tmpl._owner = None ZopePageTemplate.pt_editForm = tmpl ZopePageTemplate.manage = tmpl ZopePageTemplate.manage_main = tmpl def get_codemirror_json(self, request): error_lines = [int(re.sub(r'.*line ([0-9]+),.*',r'\1',error)) for error in getattr(self, '_v_errors', []) if re.match(r'.*line ([0-9]+),.*', error)] data = { 'error_lines': error_lines, } data.update(_cursor_position(request)) return json.dumps(data) ZopePageTemplate.get_codemirror_json = get_codemirror_json original_read = ZopePageTemplate.read def read(self, *args, **kwargs): text = original_read(self, *args, **kwargs) if text.startswith(_error_start): errend = text.find('-->') if errend >= 0: text = text[errend + 3:] if text[:1] == "\n": text = text[1:] return text ZopePageTemplate.read = read
def test_pagetemplatefile(self): from Products.PageTemplates.PageTemplateFile import PageTemplateFile # test rendering engine template = PageTemplateFile(os.path.join(path, "simple.pt")) template = template.__of__(self.folder) self.assertTrue('world' in template())
def __init__(self, filename, _globals, name, bundle_name="Naaya"): PageTemplateFile.__init__(self, filename, _globals, __name__=name) #Register this template to a specific bundle bundle = bundles.get(bundle_name) bundle.registerUtility(self, ITemplate, name) self._bundle_name = bundle_name
def test_pagetemplatefile_processing_instruction_skipped(self): from Products.PageTemplates.PageTemplateFile import PageTemplateFile # test rendering engine template = PageTemplateFile(os.path.join(path, "pi.pt")) template = template.__of__(self.folder) self.assertIn('world', template())
def manage_updatePortlets(self, REQUEST=None, **kwargs): """Add admininstration portlet""" ptool = getattr(self, "portal_portlets", None) if not ptool: zLOG.LOG("NaayaSurvey", zLOG.ERROR, "Could not add administration portlet for portal_survey") return zLOG.LOG( "NaayaSurvey", zLOG.INFO, "Adding administration portlet to portal_portlets %s" % (ptool.absolute_url(1)) ) # # Admin portlet # portlet_id = "portlet_admin_survey" portlet_title = "Portal Survey Manager" if portlet_id not in ptool.objectIds(): ptool.addPortlet(portlet_id, portlet_title, portlettype=100) portlet_ob = ptool._getOb(portlet_id) # Set portlet content text = PageTemplateFile("portlets/%s" % portlet_id, globals()) text = text.read() portlet_ob.pt_edit(text=text, content_type="text/html") # Add special property in order to be found by generic template if not portlet_ob.hasProperty("show_in_form"): portlet_ob.manage_addProperty("show_in_form", "admin_centre_html", "string") portlet_ob.manage_changeProperties(show_in_form="admin_centre_html")
def check_content_type(self, bytes, expected_type, encoding=None): with open(self.TEMPFILENAME, "wb") as f: f.write(bytes) if encoding: pt = PageTemplateFile(self.TEMPFILENAME, encoding=encoding) else: pt = PageTemplateFile(self.TEMPFILENAME) pt.read() self.assertEqual(pt.content_type, expected_type)
def test_getId(self): desired_id = os.path.splitext(os.path.split(self.TEMPFILENAME)[-1])[0] f = open(self.TEMPFILENAME, 'w') print >> f, 'Boring' f.close() pt = PageTemplateFile(self.TEMPFILENAME) pt_id = pt.getId() self.failUnlessEqual( pt_id, desired_id, 'getId() returned %r. Expecting %r' % (pt_id, desired_id) )
def _default_form(self, form_id): """ get the non-customized form """ for form in self.listDefaultForms(): if form['id'] == form_id: if 'form_ob' in form: t = form['form_ob'] else: t = PageTemplateFile(form['path']) return t.__of__(self) raise KeyError('Not found form named "%s"' % form_id)
def test_getId(self): desired_id = os.path.splitext(os.path.split(self.TEMPFILENAME)[-1])[0] f = open(self.TEMPFILENAME, 'wb') f.write(b'Boring') f.close() pt = PageTemplateFile(self.TEMPFILENAME) pt_id = pt.getId() self.assertEqual( pt_id, desired_id, 'getId() returned %r. Expecting %r' % (pt_id, desired_id) )
def manage_afterAdd(self, object, container): try: BaseClass.manage_afterAdd(self, object, container) # Re-read .metadata after adding so that we can do validation checks # using information in portal_form_controller. Since manage_afterAdd # is not guaranteed to run, we also call these in __init__ self._read_action_metadata(self.getId(), self.filepath) self._read_validator_metadata(self.getId(), self.filepath) except: log(summary='metadata error', text='file = %s' % self.filepath) logException() raise
def test_getPhysicalPath(self): desired_id = os.path.splitext(os.path.split(self.TEMPFILENAME)[-1])[0] desired_path = (desired_id,) f = open(self.TEMPFILENAME, 'w') print >> f, 'Boring' f.close() pt = PageTemplateFile(self.TEMPFILENAME) pt_path = pt.getPhysicalPath() self.failUnlessEqual( pt_path, desired_path, 'getPhysicalPath() returned %r. Expecting %r' % ( desired_path, pt_path, ) )
def test_getPhysicalPath(self): desired_id = os.path.splitext(os.path.split(self.TEMPFILENAME)[-1])[0] desired_path = (desired_id,) f = open(self.TEMPFILENAME, 'wb') f.write(b'Boring') f.close() pt = PageTemplateFile(self.TEMPFILENAME) pt_path = pt.getPhysicalPath() self.assertEqual( pt_path, desired_path, 'getPhysicalPath() returned %r. Expecting %r' % ( desired_path, pt_path, ) )
def _default_form(self, form_id): """ get the non-customized form """ for form in self.listDefaultForms(): if form["id"] == form_id: if "form_ob" in form: t = form["form_ob"] else: file_path = form["path"] if file_path in template_cache: t = template_cache[file_path] else: t = PageTemplateFile(file_path) template_cache[file_path] = t return t.__of__(self) raise KeyError('Not found form named "%s"' % form_id)
def pt_getContext(self): from Products.PageTemplates.PageTemplateFile import PageTemplateFile import jcu.shibboleth.pas.Constants as Constants c = PageTemplateFile.pt_getContext(self) dict = Constants.__dict__.copy() del dict['__builtins__'] c['sa_const'] = dict return c
def manage_workspace(self, REQUEST, RESPONSE): """ """ pt = PageTemplateFile('zpt/stats_item', globals()) dt = datetime.fromtimestamp(self.stats[1]) formatted_stats = [] for site_id, values in self.stats[0].items(): formatted_stats.append(values) entry = formatted_stats[-1] entry['pretty_size'] = pretty_size(entry['du']) ob = self.unrestrictedTraverse("/").get(site_id, None) if ob: entry.update(site_url=ob.absolute_url(), site_title=ob.title_or_id()) else: entry.update(site_url='#', site_title='%s (removed)' % site_id) formatted_stats.sort(key=lambda x: x['du'], reverse=True) return pt.__of__(self)(stats=formatted_stats, date=dt.strftime("%Y-%m-%d %H:%M"))
def __init__(self, filename, _prefix=None, content_type=None): # XXX doesn't use content_type yet self.ZBindings_edit(self._default_bindings) path = self.get_path_from_prefix(_prefix) self.filename = os.path.join(path, filename) if not os.path.isfile(self.filename): raise ValueError("No such file", self.filename) basepath, ext = os.path.splitext(self.filename) self.__name__ = os.path.basename(basepath) # required for the ajung-zpt-final-integration branch try: PageTemplateFile.__init__(self, self.filename, _prefix) except: pass
def manage_addRDFCalendar(self, id, title='', first_day_week='Monday', week_day_len=3, REQUEST=None): """Add a new RDFCalendar object with id=title.""" ob=RDFCalendar(id, title, first_day_week, week_day_len) ob.id = id self._setObject(id, ob) #create index_html page template indexfile = PageTemplateFile('zpt/RDFCalendarIndex', globals()) content = indexfile.read() manage_addPageTemplate(ob, id='index_html', title='Calendar Events', text=content) #create show_day_events page template show_events_file = PageTemplateFile('zpt/RDFCalendar_dayevents', globals()) content = show_events_file.read() manage_addPageTemplate(ob, id='show_day_events', title='Show events for one day', text=content) if REQUEST is not None: return self.manage_main(self, REQUEST, update_menu=1)
# # Alex Morega, Eau de Web # Cornel Nitu, Eau de Web # Valentin Dumitru, Eau de Web from datetime import datetime from OFS.SimpleItem import SimpleItem from Globals import InitializeClass from AccessControl import ClassSecurityInfo from Products.PageTemplates.PageTemplateFile import PageTemplateFile from Products.ZCatalog.CatalogAwareness import CatalogAware from constants import * from utilities import * manage_addComment_html = PageTemplateFile('zpt/comment', globals()) import scrubber if 'any' not in dir(__builtins__): from Products.NaayaCore.backport import any scrubber.any = any sanitize = scrubber.Scrubber().scrub def trim(message): """ Remove leading and trailing empty paragraphs """ message = re.sub(r'^\s*<p>(\s*( )*)*\s*</p>\s*', '', message) message = re.sub(r'\s*<p>(\s*( )*)*\s*</p>\s*$', '', message) return message
class NyCountry(NyFolder): """ """ meta_type = METATYPE_OBJECT meta_label = LABEL_OBJECT icon = 'misc_/NaayaContent/NyCountry.gif' icon_marked = 'misc_/NaayaContent/NyCountry_marked.gif' manage_options = (NyFolder.manage_options) security = ClassSecurityInfo() nfp_label = LocalProperty('nfp_label') nfp_url = LocalProperty('nfp_url') link_ins = LocalProperty('link_ins') link_doc = LocalProperty('link_doc') link_train = LocalProperty('link_train') link_rd = LocalProperty('link_rd') link_data = LocalProperty('link_data') def __init__(self, id, title, description, coverage, keywords, sortorder, smallflag, nfp_label, nfp_url, link_ins, link_doc, link_train, link_rd, link_data, publicinterface, contributor, folder_meta_types, releasedate, lang): """ """ NyFolder.__dict__['__init__'](self, id, title, description, coverage, keywords, sortorder, publicinterface, '', contributor, folder_meta_types, releasedate, lang) self._setLocalPropValue('nfp_label', lang, nfp_label) self._setLocalPropValue('nfp_url', lang, nfp_url) self._setLocalPropValue('link_ins', lang, link_ins) self._setLocalPropValue('link_doc', lang, link_doc) self._setLocalPropValue('link_train', lang, link_train) self._setLocalPropValue('link_rd', lang, link_rd) self._setLocalPropValue('link_data', lang, link_data) self.smallflag = smallflag security.declarePrivate('loadDefaultData') def loadDefaultData(self, lang, legislation_feed_url, project_feed_url): """ """ #load country folder skeleton - default content path = join(NAAYACONTENT_PRODUCT_PATH, 'NyCountry', 'skel.nyexp') import_handler, error = import_parser().parse(self.futRead(path, 'r')) if import_handler is not None: for object in import_handler.root.objects: self.import_data(object) else: raise Exception, EXCEPTION_PARSINGFILE % (path, error) #create right portlets addHTMLPortlet(self, id=self.get_portlet_indicators_id(), title='Key indicators', lang=lang) addHTMLPortlet(self, id=self.get_portlet_reports_id(), title='Important reports', lang=lang) #create remote channels manage_addRemoteChannel(self, id=self.get_rc_legislation_id(), title='Legislation on water RSS feed', url=legislation_feed_url) manage_addRemoteChannel(self, id=self.get_rc_project_id(), title='Project water RSS feed', url=project_feed_url) security.declarePrivate('export_this_tag_custom') def export_this_tag_custom(self): return 'publicinterface="%s" maintainer_email="%s" folder_meta_types="%s" smallflag="%s" legislation_feed_url="%s" project_feed_url="%s"' % \ (self.utXmlEncode(self.publicinterface), self.utXmlEncode(self.maintainer_email), self.utXmlEncode(','.join(self.folder_meta_types)), self.utBase64Encode(self.utNoneToEmpty(self.smallflag)), self.utXmlEncode(self.get_rc_legislation_url()), self.utXmlEncode(self.get_rc_project_url())) security.declarePrivate('export_this_body_custom') def export_this_body_custom(self): r = [] ra = r.append for l in self.gl_get_languages(): ra('<nfp_label lang="%s"><![CDATA[%s]]></nfp_label>' % (l, self.utToUtf8(self.getLocalProperty('nfp_label', l)))) ra('<nfp_url lang="%s"><![CDATA[%s]]></nfp_url>' % (l, self.utToUtf8(self.getLocalProperty('nfp_url', l)))) ra('<link_ins lang="%s"><![CDATA[%s]]></link_ins>' % (l, self.utToUtf8(self.getLocalProperty('link_ins', l)))) ra('<link_doc lang="%s"><![CDATA[%s]]></link_doc>' % (l, self.utToUtf8(self.getLocalProperty('link_doc', l)))) ra('<link_train lang="%s"><![CDATA[%s]]></link_train>' % (l, self.utToUtf8(self.getLocalProperty('link_train', l)))) ra('<link_rd lang="%s"><![CDATA[%s]]></link_rd>' % (l, self.utToUtf8(self.getLocalProperty('link_rd', l)))) ra('<tooltip lang="%s"><![CDATA[%s]]></tooltip>' % (l, self.utToUtf8(self.getLocalProperty('tooltip', l)))) ra('<link_data lang="%s"><![CDATA[%s]]></link_data>' % (l, self.utToUtf8(self.getLocalProperty('link_data', l)))) #portlets and remote channels for l_portlet in self.objectValues('Naaya HTML Portlet'): ra('<ob meta_type="%s" id="%s" param="0">' % (l_portlet.meta_type, l_portlet.id)) for l in self.gl_get_languages(): ra('<title lang="%s"><![CDATA[%s]]></title>' % (l, self.utToUtf8(l_portlet.getLocalProperty('title', l)))) ra('<body lang="%s"><![CDATA[%s]]></body>' % (l, self.utToUtf8(l_portlet.getLocalProperty('body', l)))) ra('</ob>') for l_channel in self.objectValues('Naaya Remote Channel'): ra('<ob meta_type="%s" id="%s" title="%s" url="%s" numbershownitems="%s" param="0"/>' % (l_channel.meta_type, l_channel.id, l_channel.title, l_channel.url, l_channel.numbershownitems)) return ''.join(r) def get_left_portlets_objects(self): #get the left portlets objects l = ['portlet_country_left'] return filter(lambda x: x is not None, map(self.getPortletsTool()._getOb, l, (None, ) * len(l))) def get_right_portlets_objects(self): #get the right portlets objects l, t = [], self.getPortletsTool() p = self.get_portlet_indicators() if p is not None: l.append(p) p = self.get_portlet_reports() if p is not None: l.append(p) p = t._getOb('portlet_country_news') if p is not None: l.append(p) p = t._getOb('portlet_country_events') if p is not None: l.append(p) p = t._getOb('portlet_country_projects') if p is not None: l.append(p) return l def hasVersion(self): """ Checks if the object is locked. @return: - B{TRUE/1} if true - B{FALSE/0} otherwise """ return 0 def hasLinksValues(self): """ Checks if the object has at least one link value. @return: - B{TRUE/1} if true - B{FALSE/0} otherwise """ return self.utLinkValue(self.link_ins) or self.utLinkValue(self.link_doc) or \ self.utLinkValue(self.link_train) or self.utLinkValue(self.link_rd) or \ self.utLinkValue(self.link_data) #api def get_country_object(self): return self def get_country_object_title(self, lang='en'): return self.utToUtf8(self.getLocalProperty('title', lang)) def get_country_object_path(self, p=0): return self.absolute_url(p) def get_portlet_indicators_id(self): return '%sindicators' % PREFIX_PORTLET def get_portlet_indicators(self): return self._getOb('%sindicators' % PREFIX_PORTLET, None) def get_portlet_reports_id(self): return '%sreports' % PREFIX_PORTLET def get_portlet_reports(self): return self._getOb('%sreports' % PREFIX_PORTLET, None) def get_rc_legislation_id(self): return 'rclegislation' def get_rc_legislation(self): return self._getOb('rclegislation', None) def get_rc_legislation_url(self): return self._getOb('rclegislation', None).url def get_rc_project_id(self): return 'rcproject' def get_rc_project(self): return self._getOb('rcproject', None) def get_rc_project_url(self): return self._getOb('rcproject', None).url def getCountryNews(self): #returns a list with news related with the country l_search_key = self.getLocalProperty( 'title', 'en') + ' or ' + self.getLocalProperty('coverage', 'en') expr = 'self.getCatalogedObjects(meta_type=\'%s\', approved=1, howmany=5, coverage_%s=l_search_key)' % ( METATYPE_NYSEMNEWS, 'en') return eval(expr) def getCountryEvents(self): #returns a list with upcoming events related with the country l_search_key = self.getLocalProperty( 'title', 'en') + ' or ' + self.getLocalProperty('coverage', 'en') expr = 'self.getCatalogedObjects(meta_type=\'%s\', approved=1, howmany=5, coverage_%s=l_search_key)' % ( METATYPE_NYSEMEVENT, 'en') return eval(expr) def getCountryProjects(self): #returns a list with projects related with the country l_search_key = self.getLocalProperty('coverage', 'en') expr = 'self.getCatalogedObjects(meta_type=\'%s\', approved=1, coverage_%s=l_search_key)' % ( METATYPE_NYSEMPROJECT, 'en') return eval(expr) def getCountryContent(self): #returns the contained objects sorted by sort order return self.utSortObjsListByAttr([ x for x in self.objectValues(self.searchable_content) if x.approved == 1 ], 'sortorder', 0) def inCountryTopic(self, p_topic, p_location): #test if the given location is in the context of a country topic if isinstance(p_topic, str): page = self.REQUEST['URL'].split('/')[-1] return page == p_topic if p_location == self: return 0 else: l_parent = p_location while l_parent.getParentNode() != self: l_parent = l_parent.getParentNode() return p_topic == l_parent def getSmallFlag(self, REQUEST=None): """ """ return self.smallflag def hasSmallFlag(self): return self.smallflag is not None def setSmallFlag(self, source, file, url): """ Upload the small flag. """ if source == 'file': if file != '': if hasattr(file, 'filename'): if file.filename != '': l_read = file.read() if l_read != '': self.smallflag = l_read self._p_changed = 1 else: self.smallflag = file self._p_changed = 1 elif source == 'url': if url != '': l_data, l_ctype = self.grabFromUrl(url) if l_data is not None: self.smallflag = l_data self._p_changed = 1 def delSmallFlag(self): """ Delete the small flag. """ self.smallflag = None self._p_changed = 1 #zmi actions security.declareProtected(view_management_screens, 'manageProperties') def manageProperties(self, title='', description='', coverage='', keywords='', sortorder='', publicinterface='', approved='', source='file', flag_file='', flag_url='', del_smallflag='', nfp_label='', nfp_url='', link_ins='', link_doc='', link_train='', link_rd='', link_data='', legislation_feed_url='', project_feed_url='', releasedate='', discussion='', lang='', REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG try: sortorder = abs(int(sortorder)) except: sortorder = DEFAULT_SORTORDER if publicinterface: publicinterface = 1 else: publicinterface = 0 if approved: approved = 1 else: approved = 0 releasedate = self.process_releasedate(releasedate, self.releasedate) if not lang: lang = self.gl_get_selected_language() self._setLocalPropValue('title', lang, title) self._setLocalPropValue('description', lang, description) self._setLocalPropValue('coverage', lang, coverage) self._setLocalPropValue('keywords', lang, keywords) self._setLocalPropValue('nfp_label', lang, nfp_label) self._setLocalPropValue('nfp_url', lang, nfp_url) self._setLocalPropValue('link_ins', lang, link_ins) self._setLocalPropValue('link_doc', lang, link_doc) self._setLocalPropValue('link_train', lang, link_train) self._setLocalPropValue('link_rd', lang, link_rd) self._setLocalPropValue('link_data', lang, link_data) self.sortorder = sortorder self.publicinterface = publicinterface self.approved = approved self.releasedate = releasedate self.updatePropertiesFromGlossary(lang) self.updateDynamicProperties( self.processDynamicProperties(METATYPE_OBJECT, REQUEST, kwargs), lang) if approved != self.approved: if approved == 0: approved_by = None else: approved_by = self.REQUEST.AUTHENTICATED_USER.getUserName() self.approveThis(approved, approved_by) if del_smallflag != '': self.delSmallFlag() else: self.setSmallFlag(source, flag_file, flag_url) self._p_changed = 1 if discussion: self.open_for_comments() else: self.close_for_comments() self.recatalogNyObject(self) self.createPublicInterface() #update remote channels feeds self.get_rc_legislation().set_new_feed_url(legislation_feed_url) self.get_rc_project().set_new_feed_url(project_feed_url) if REQUEST: REQUEST.RESPONSE.redirect('manage_edit_html?save=ok') #site actions security.declareProtected(PERMISSION_EDIT_OBJECTS, 'saveProperties') def saveProperties(self, title='', description='', coverage='', keywords='', sortorder='', source='file', flag_file='', flag_url='', del_smallflag='', nfp_label='', nfp_url='', link_ins='', link_doc='', link_train='', link_rd='', link_data='', legislation_feed_url='', project_feed_url='', releasedate='', discussion='', lang=None, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG if not sortorder: sortorder = DEFAULT_SORTORDER if lang is None: lang = self.gl_get_selected_language() #check mandatory fiels r = self.getSite().check_pluggable_item_properties(METATYPE_OBJECT, title=title, \ description=description, coverage=coverage, keywords=keywords, sortorder=sortorder, \ releasedate=releasedate, discussion=discussion, \ nfp_label=nfp_label, nfp_url=nfp_url, source=source, flag_file=flag_file, flag_url=flag_url, \ link_ins=link_ins, link_doc=link_doc, link_train=link_train, link_rd=link_rd, link_data=link_data, \ legislation_feed_url=legislation_feed_url, project_feed_url=project_feed_url) if not len(r): releasedate = self.process_releasedate(releasedate, self.releasedate) sortorder = int(sortorder) self.sortorder = sortorder self.releasedate = releasedate self._setLocalPropValue('title', lang, title) self._setLocalPropValue('description', lang, description) self._setLocalPropValue('coverage', lang, coverage) self._setLocalPropValue('keywords', lang, keywords) self._setLocalPropValue('nfp_label', lang, nfp_label) self._setLocalPropValue('nfp_url', lang, nfp_url) self._setLocalPropValue('link_ins', lang, link_ins) self._setLocalPropValue('link_doc', lang, link_doc) self._setLocalPropValue('link_train', lang, link_train) self._setLocalPropValue('link_rd', lang, link_rd) self._setLocalPropValue('link_data', lang, link_data) if del_smallflag != '': self.delSmallFlag() else: self.setSmallFlag(source, flag_file, flag_url) self.updatePropertiesFromGlossary(lang) self.updateDynamicProperties( self.processDynamicProperties(METATYPE_OBJECT, REQUEST, kwargs), lang) self._p_changed = 1 if discussion: self.open_for_comments() else: self.close_for_comments() self.recatalogNyObject(self) #update remote channels feeds self.get_rc_legislation().set_new_feed_url(legislation_feed_url) self.get_rc_project().set_new_feed_url(project_feed_url) if REQUEST: self.setSessionInfo( [MESSAGE_SAVEDCHANGES % self.utGetTodayDate()]) REQUEST.RESPONSE.redirect('edit_html?lang=%s' % lang) else: if REQUEST is not None: self.setSessionErrors(r) self.set_pluggable_item_session(METATYPE_OBJECT, id=id, title=title, \ description=description, coverage=coverage, keywords=keywords, \ sortorder=sortorder, releasedate=releasedate, discussion=discussion, \ nfp_label=nfp_label, nfp_url=nfp_url, source=source, flag_url=flag_url, \ link_ins=link_ins, link_doc=link_doc, link_train=link_train, link_rd=link_rd, link_data=link_data, \ legislation_feed_url=legislation_feed_url, project_feed_url=project_feed_url, \ del_smallflag=del_smallflag) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), lang)) else: raise Exception, '%s' % ', '.join(r) security.declareProtected(PERMISSION_EDIT_OBJECTS, 'update_legislation_feed') def update_legislation_feed(self, REQUEST=None): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG channel = self.get_rc_legislation() channel.harvest_feed() if REQUEST: if channel.get_feed_bozo_exception() is not None: self.setSessionErrors([channel.get_feed_bozo_exception()]) else: self.setSessionInfo( [MESSAGE_SAVEDCHANGES % self.utGetTodayDate()]) REQUEST.RESPONSE.redirect('%s/legislation_water/' % self.absolute_url()) security.declareProtected(PERMISSION_EDIT_OBJECTS, 'update_project_feed') def update_project_feed(self, REQUEST=None): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG channel = self.get_rc_project() channel.harvest_feed() if REQUEST: if channel.get_feed_bozo_exception() is not None: self.setSessionErrors([channel.get_feed_bozo_exception()]) else: self.setSessionInfo( [MESSAGE_SAVEDCHANGES % self.utGetTodayDate()]) REQUEST.RESPONSE.redirect('%s/project_water/index_html' % self.absolute_url()) security.declareProtected(PERMISSION_EDIT_OBJECTS, 'editPortlet') def editPortlet(self, id='', title='', body='', lang=None, REQUEST=None): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG ob = self.getObjectById(id) if ob is not None: ob.manage_properties(title, body, lang) if REQUEST: self.setSessionInfo([MESSAGE_SAVEDCHANGES % self.utGetTodayDate()]) REQUEST.RESPONSE.redirect('%s/editportlet_html?id=%s' % (self.absolute_url(), id)) #zmi pages security.declareProtected(view_management_screens, 'manage_edit_html') manage_edit_html = PageTemplateFile('zpt/country_manage_edit', globals()) #site pages security.declareProtected(view, 'standard_html_header') def standard_html_header(self, REQUEST=None, RESPONSE=None, **args): """ """ if not args.has_key('show_edit'): args['show_edit'] = 0 args['here'] = self.REQUEST.PARENTS[0] args['skin_files_path'] = self.getLayoutTool().getSkinFilesPath() return self.getFormsTool().getContent( args, 'country_custom_header').split( '<!--SITE_HEADERFOOTER_MARKER-->')[0] security.declareProtected(view, 'standard_html_header') def standard_html_footer(self, REQUEST=None, RESPONSE=None): """ """ context = {'here': self.REQUEST.PARENTS[0]} context['skin_files_path'] = self.getLayoutTool().getSkinFilesPath() return self.getFormsTool().getContent( context, 'country_custom_footer').split( '<!--SITE_HEADERFOOTER_MARKER-->')[1] security.declareProtected(view, 'index_html') def index_html(self, REQUEST=None, RESPONSE=None): """ """ if self.publicinterface: l_index = self._getOb('index', None) if l_index is not None: return l_index() return self.getFormsTool().getContent({'here': self}, 'country_index') security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html') def edit_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getContent({'here': self}, 'country_edit') security.declareProtected(PERMISSION_EDIT_OBJECTS, 'editportlet_html') def editportlet_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getContent({'here': self}, 'country_editportlet')
class EmailTool(Folder): """ """ meta_type = METATYPE_EMAILTOOL icon = 'misc_/NaayaCore/EmailTool.gif' manage_options = (Folder.manage_options[:1] + ({ 'label': 'Settings', 'action': 'manage_settings_html' }, ) + Folder.manage_options[3:]) meta_types = ({ 'name': METATYPE_EMAILTEMPLATE, 'action': 'manage_addEmailTemplateForm', 'permission': PERMISSION_ADD_NAAYACORE_TOOL }, ) all_meta_types = meta_types manage_addEmailTemplateForm = EmailTemplate.manage_addEmailTemplateForm manage_addEmailTemplate = EmailTemplate.manage_addEmailTemplate security = ClassSecurityInfo() def __init__(self, id, title): """ """ self.id = id self.title = title security.declarePrivate('loadDefaultData') def loadDefaultData(self): #load default stuff pass def _guess_from_address(self): if self.portal_url != '': return 'notifications@%s' % urlparse( self.getSite().get_portal_domain())[1] else: return 'notifications@%s' % urlparse(self.REQUEST.SERVER_URL)[1] @deprecate('_get_from_address renamed to get_addr_from') def _get_from_address(self): return self.get_addr_from() security.declarePrivate('get_addr_from') def get_addr_from(self): """ Get "From:" address, to use in mails originating from this portal. If no such address is configured then we attempt to guess it. """ addr_from = self.getSite().mail_address_from return addr_from or self._guess_from_address() _errors_report = PageTemplateFile('zpt/configuration_errors_report', globals()) security.declareProtected(naaya_admin, 'configuration_errors_report') def configuration_errors_report(self): errors = [] delivery = queryUtility(IMailDelivery, 'naaya-mail-delivery') if delivery is None: if not (self.mail_server_name and self.mail_server_port): errors.append('Mail server address/port not configured') if not self.get_addr_from(): errors.append('"From" address not configured') return self._errors_report(errors=errors) #api security.declarePrivate('sendEmail') def sendEmail(self, p_content, p_to, p_from, p_subject, _immediately=False, p_cc=[]): """ Send email message on transaction commit. If the transaction fails, the message is discarded. """ if not isinstance(p_to, list): p_to = [e.strip() for e in p_to.split(',')] p_to = filter(None, p_to) # filter out blank recipients if not isinstance(p_cc, list): p_cc = [e.strip() for e in p_cc.split(',')] p_cc = filter(None, p_cc) # filter out blank recipients try: site = self.getSite() site_path = '/'.join(site.getPhysicalPath()) except: site = None site_path = '[no site]' try: if diverted_mail is not None: # we're inside a unit test diverted_mail.append( [p_content, p_to, p_cc, p_from, p_subject]) return 1 delivery = delivery_for_site(site) if delivery is None: mail_logger.info( 'Not sending email from %r because mail ' 'server is not configured', site_path) return 0 if not p_from: mail_logger.info('Not sending email from %r - no sender', site_path) return 0 if not p_to: mail_logger.info('Not sending email from %r - no recipients', site_path) return 0 if _immediately: delivery = _ImmediateDelivery(delivery) mail_logger.info( 'Sending email from site: %r ' 'to: %r, cc: %r, subject: %r', site_path, p_to, p_cc, p_subject) l_message = create_message(p_content, p_to, p_from, p_subject, addr_cc=p_cc) send_by_delivery(delivery, p_from, p_to, l_message) return 1 except: mail_logger.error( 'Did not send email from site: %r to: %r ' 'because an error occurred', site_path, p_to) if site is not None: self.getSite().log_current_error() return 0 security.declarePrivate('sendEmailImmediately') def sendEmailImmediately(self, *args, **kwargs): """ Send email message straight away, without waiting for transaction commit. Useful when sending error emails because the transaction will probably be aborted. """ kwargs['_immediately'] = True self.sendEmail(*args, **kwargs) security.declareProtected(view_management_screens, 'manageSettings') def manageSettings(self, mail_server_name='', mail_server_port='', administrator_email='', mail_address_from='', notify_on_errors_email='', REQUEST=None): """ """ site = self.getSite() try: mail_server_port = int(mail_server_port) except: mail_server_port = site.mail_server_port site.mail_server_name = mail_server_name site.mail_server_port = mail_server_port site.mail_address_from = mail_address_from site.administrator_email = administrator_email site.notify_on_errors_email = notify_on_errors_email self._p_changed = 1 if REQUEST: REQUEST.RESPONSE.redirect('manage_settings_html?save=ok') #zmi pages security.declareProtected(view_management_screens, 'manage_settings_html') manage_settings_html = PageTemplateFile('zpt/email_settings', globals())
# coding=utf-8 from zope.publisher.browser import BrowserPage from Products.PageTemplates.PageTemplateFile import PageTemplateFile viewer_zpt = PageTemplateFile('zpt/view_ag_index.zpt', globals()) class viewer_aggregator(BrowserPage): def __init__(self, context, request): self.context = context self.request = request def __call__(self, country=None, theme=None): ctx = self.context.aq_inner # because self subclasses from Explicit if country is not None: results = self.aggregate_vl_cf_viewers(country, theme) else: results = [] heading_mapping = self.get_survey_for_headings() return viewer_zpt.__of__(ctx)(results=results, heading_mapping=heading_mapping) def aggregate_vl_cf_viewers(self, country, theme): cf_v = self.context['country-fiches-viewer'] vl_v = self.context['virtual-library-viewer'] cf = cf_v.target_survey() vl = vl_v.target_survey() cf_shadows = cf_v.filter_answers_cf_vl_aggregator(country, theme) vl_shadows = vl_v.filter_answers_cf_vl_aggregator(country, theme)
class ExportStepRegistry(BaseStepRegistry): """ Registry of known site-configuration export steps. o Each step is registered with a unique id. o When called, with the portal object passed in as an argument, the step must return a sequence of three-tuples, ( 'data', 'content_type', 'filename' ), one for each file exported by the step. - 'data' is a string containing the file data; - 'content_type' is the MIME type of the data; - 'filename' is a suggested filename for use when downloading. """ implements(IExportStepRegistry) security = ClassSecurityInfo() RegistryParser = _ExportStepRegistryParser security.declarePrivate('registerStep') def registerStep(self, id, handler, title=None, description=None): """ Register an export step. o 'id' is the unique identifier for this step o 'handler' is the dottoed name of a handler which should implement IImportPlugin. o 'title' is a one-line UI description for this step. If None, the first line of the documentation string of the step is used, or the id if no docstring can be found. o 'description' is a one-line UI description for this step. If None, the remaining line of the documentation string of the step is used, or default to ''. """ if not isinstance(handler, str): handler = _getDottedName(handler) if title is None or description is None: method = _resolveDottedName(handler) if method is None: t, d = id, '' else: t, d = _extractDocstring(method, id, '') title = title or t description = description or d info = { 'id': id, 'handler': handler, 'title': title, 'description': description } self._registered[id] = info # # Helper methods # security.declarePrivate('_exportTemplate') _exportTemplate = PageTemplateFile('esrExport.xml', _xmldir)
msg = ("An error occurred while generating " "this part of the page.") try: log = aq_get(context, '__error_log__', None, 1) except AttributeError: LOG("Composite", ERROR, "Error in a page element", error=exc_info) return msg else: error_log_url = log.raising(exc_info) return error_tag % (msg, error_log_url) finally: del exc_info addSlotForm = PageTemplateFile("addSlotForm", _www) def manage_addSlot(dispatcher, id, REQUEST=None): """Adds a slot to a composite. """ ob = Slot(id) dispatcher._setObject(ob.getId(), ob) if REQUEST is not None: return dispatcher.manage_main(dispatcher, REQUEST) def manage_generateSlots(dispatcher, REQUEST=None): """Adds all slots requested by a template to a composite. """ dispatcher.this().generateSlots() if REQUEST is not None:
class TypeInformation(SimpleItemWithProperties, ActionProviderBase): """ Base class for information about a content type. """ manage_options = (SimpleItemWithProperties.manage_options[:1] + ({ 'label': 'Aliases', 'action': 'manage_aliases' }, ) + ActionProviderBase.manage_options + SimpleItemWithProperties.manage_options[1:]) security = ClassSecurityInfo() security.declareProtected(ManagePortal, 'manage_editProperties') security.declareProtected(ManagePortal, 'manage_changeProperties') security.declareProtected(ManagePortal, 'manage_propertiesForm') _basic_properties = ( { 'id': 'title', 'type': 'string', 'mode': 'w', 'label': 'Title' }, { 'id': 'description', 'type': 'text', 'mode': 'w', 'label': 'Description' }, { 'id': 'i18n_domain', 'type': 'string', 'mode': 'w', 'label': 'I18n Domain' }, { 'id': 'content_icon', 'type': 'string', 'mode': 'w', 'label': 'Icon' }, { 'id': 'content_meta_type', 'type': 'string', 'mode': 'w', 'label': 'Product meta type' }, ) _advanced_properties = ( { 'id': 'immediate_view', 'type': 'string', 'mode': 'w', 'label': 'Initial view name' }, { 'id': 'global_allow', 'type': 'boolean', 'mode': 'w', 'label': 'Implicitly addable?' }, { 'id': 'filter_content_types', 'type': 'boolean', 'mode': 'w', 'label': 'Filter content types?' }, { 'id': 'allowed_content_types', 'type': 'multiple selection', 'mode': 'w', 'label': 'Allowed content types', 'select_variable': 'listContentTypes' }, { 'id': 'allow_discussion', 'type': 'boolean', 'mode': 'w', 'label': 'Allow Discussion?' }, ) title = '' description = '' i18n_domain = '' content_meta_type = '' content_icon = '' immediate_view = '' filter_content_types = True allowed_content_types = () allow_discussion = False global_allow = True def __init__(self, id, **kw): self.id = id self._actions = () self._aliases = {} if not kw: return kw = kw.copy() # Get a modifiable dict. if (not kw.has_key('content_meta_type') and kw.has_key('meta_type')): kw['content_meta_type'] = kw['meta_type'] if (not kw.has_key('content_icon') and kw.has_key('icon')): kw['content_icon'] = kw['icon'] self.manage_changeProperties(**kw) actions = kw.get('actions', ()) for action in actions: self.addAction(id=action['id'], name=action['title'], action=action['action'], condition=action.get('condition'), permission=action.get('permissions', ()), category=action.get('category', 'object'), visible=action.get('visible', True)) self.setMethodAliases(kw.get('aliases', {})) # # ZMI methods # security.declareProtected(ManagePortal, 'manage_aliases') manage_aliases = PageTemplateFile('typeinfoAliases.zpt', _wwwdir) security.declareProtected(ManagePortal, 'manage_setMethodAliases') def manage_setMethodAliases(self, REQUEST): """ Config method aliases. """ form = REQUEST.form aliases = {} for k, v in form['aliases'].items(): v = v.strip() if v: aliases[k] = v _dict = {} for k, v in form['methods'].items(): if aliases.has_key(k): _dict[aliases[k]] = v self.setMethodAliases(_dict) REQUEST.RESPONSE.redirect('%s/manage_aliases' % self.absolute_url()) # # Accessors # security.declareProtected(View, 'Title') def Title(self): """ Return the "human readable" type name (note that it may not map exactly to the 'portal_type', e.g., for l10n/i18n or where a single content class is being used twice, under different names. """ if self.title and self.i18n_domain: return Message(self.title, self.i18n_domain) else: return self.title or self.getId() security.declareProtected(View, 'Description') def Description(self): """ Textual description of the class of objects (intended for display in a "constructor list"). """ if self.description and self.i18n_domain: return Message(self.description, self.i18n_domain) else: return self.description security.declareProtected(View, 'Metatype') def Metatype(self): """ Returns the Zope 'meta_type' for this content object. May be used for building the list of portal content meta types. """ return self.content_meta_type security.declareProtected(View, 'getIcon') def getIcon(self): """ Returns the icon for this content object. """ return self.content_icon security.declarePublic('allowType') def allowType(self, contentType): """ Can objects of 'contentType' be added to containers whose type object we are? """ if not self.filter_content_types: ti = self.getTypeInfo(contentType) if ti is None or ti.globalAllow(): return 1 #If a type is enabled to filter and no content_types are allowed if not self.allowed_content_types: return 0 if contentType in self.allowed_content_types: return 1 return 0 security.declarePublic('getId') def getId(self): return self.id security.declarePublic('allowDiscussion') def allowDiscussion(self): """ Can this type of object support discussion? """ return self.allow_discussion security.declarePublic('globalAllow') def globalAllow(self): """ Should this type be implicitly addable anywhere? """ return self.global_allow security.declarePublic('listActions') def listActions(self, info=None, object=None): """ Return a sequence of the action info objects for this type. """ return self._actions or () security.declarePublic('constructInstance') def constructInstance(self, container, id, *args, **kw): """Build an instance of the type. Builds the instance in 'container', using 'id' as its id. Returns the object. """ if not self.isConstructionAllowed(container): raise AccessControl_Unauthorized('Cannot create %s' % self.getId()) ob = self._constructInstance(container, id, *args, **kw) return self._finishConstruction(ob) security.declarePrivate('_finishConstruction') def _finishConstruction(self, ob): """ Finish the construction of a content object. Set its portal_type, insert it into the workflows. """ if hasattr(ob, '_setPortalTypeName'): ob._setPortalTypeName(self.getId()) if hasattr(aq_base(ob), 'notifyWorkflowCreated'): ob.notifyWorkflowCreated() ob.reindexObject() return ob security.declareProtected(ManagePortal, 'getMethodAliases') def getMethodAliases(self): """ Get method aliases dict. """ aliases = self._aliases # for aliases created with CMF 1.5.0beta for key, method_id in aliases.items(): if isinstance(method_id, tuple): aliases[key] = method_id[0] self._p_changed = True return aliases.copy() security.declareProtected(ManagePortal, 'setMethodAliases') def setMethodAliases(self, aliases): """ Set method aliases dict. """ _dict = {} for k, v in aliases.items(): v = v.strip() if v: _dict[k.strip()] = v if not getattr(self, '_aliases', None) == _dict: self._aliases = _dict return True else: return False security.declarePublic('queryMethodID') def queryMethodID(self, alias, default=None, context=None): """ Query method ID by alias. """ aliases = self._aliases method_id = aliases.get(alias, default) # for aliases created with CMF 1.5.0beta if isinstance(method_id, tuple): method_id = method_id[0] return method_id
class Transform(SimpleItem): """A transform is an external method with additional configuration information """ meta_type = 'Transform' meta_types = all_meta_types = () manage_options = (( { 'label': 'Configure', 'action': 'manage_main' }, { 'label': 'Reload', 'action': 'manage_reloadTransform' }, ) + SimpleItem.manage_options) manage_main = PageTemplateFile('configureTransform', _www) manage_reloadTransform = PageTemplateFile('reloadTransform', _www) tr_widgets = PageTemplateFile('tr_widgets', _www) security = ClassSecurityInfo() __allow_access_to_unprotected_subobjects__ = 1 def __init__(self, id, module, transform=None): self.id = id self.module = module # DM 2004-09-09: 'Transform' instances are stored as # part of a module level configuration structure # Therefore, they must not contain persistent objects self._config = UserDict() self._config.__allow_access_to_unprotected_subobjects__ = 1 self._config_metadata = UserDict() self._tr_init(1, transform) def __setstate__(self, state): """ __setstate__ is called whenever the instance is loaded from the ZODB, like when Zope is restarted. We should reload the wrapped transform at this time """ Transform.inheritedAttribute('__setstate__')(self, state) self._tr_init() def _tr_init(self, set_conf=0, transform=None): """ initialize the zope transform by loading the wrapped transform """ __traceback_info__ = (self.module, ) if transform is None: transform = self._load_transform() else: self._v_transform = transform # check this is a valid transform if not hasattr(transform, '__class__'): raise TransformException( 'Invalid transform : transform is not a class') if not ITransform.providedBy(transform): raise TransformException( 'Invalid transform : ITransform is not implemented by %s' % transform.__class__) if not hasattr(transform, 'inputs'): raise TransformException( 'Invalid transform : missing required "inputs" attribute') if not hasattr(transform, 'output'): raise TransformException( 'Invalid transform : missing required "output" attribute') # manage configuration if set_conf and hasattr(transform, 'config'): conf = dict(transform.config) self._config.update(conf) make_config_persistent(self._config) if hasattr(transform, 'config_metadata'): conf = dict(transform.config_metadata) self._config_metadata.update(conf) make_config_persistent(self._config_metadata) transform.config = dict(self._config) make_config_nonpersistent(transform.config) transform.config_metadata = dict(self._config_metadata) make_config_nonpersistent(transform.config_metadata) self.inputs = transform.inputs self.output = transform.output self.output_encoding = getattr(transform, 'output_encoding', None) return transform def _load_transform(self): try: m = import_from_name(self.module) except ImportError as err: transform = BrokenTransform(self.id, self.module, err) msg = ("Cannot register transform %s (ImportError), using " "BrokenTransform: Error\n %s" % (self.id, err)) self.title = 'BROKEN' log(msg, severity=ERROR) return transform if not hasattr(m, 'register'): msg = ("Invalid transform module %s: no register function " "defined" % self.module) raise TransformException(msg) try: transform = m.register() except Exception as err: transform = BrokenTransform(self.id, self.module, err) msg = ("Cannot register transform %s, using BrokenTransform: " "Error\n %s" % (self.id, err)) self.title = 'BROKEN' log(msg, severity=ERROR) else: self.title = '' self._v_transform = transform return transform @security.private def manage_beforeDelete(self, item, container): SimpleItem.manage_beforeDelete(self, item, container) if self is item: # unregister self from catalog on deletion tr_tool = getToolByName(self, 'portal_transforms') tr_tool._unmapTransform(self) @security.public def get_documentation(self): """ return transform documentation """ if not hasattr(self, '_v_transform'): self._load_transform() return self._v_transform.__doc__ @security.public def convert(self, *args, **kwargs): # return apply the transform and return the result if not hasattr(self, '_v_transform'): self._load_transform() return self._v_transform.convert(*args, **kwargs) @security.public def name(self): """return the name of the transform instance""" return self.id @security.protected(ManagePortal) def get_parameters(self): """ get transform's parameters names """ if not hasattr(self, '_v_transform'): self._load_transform() keys = sorted(self._v_transform.config.keys()) return keys @security.protected(ManagePortal) def get_parameter_value(self, key): """ get value of a transform's parameter """ value = self._config[key] type = self.get_parameter_infos(key)[0] if type == 'dict': result = {} if value: for key, val in value.items(): result[key] = val elif type == 'list': result = list(value) else: result = value return result @security.protected(ManagePortal) def get_parameter_infos(self, key): """ get informations about a parameter return a tuple (type, label, description [, type specific data]) where type in (string, int, list, dict) label and description are two string describing the field there may be some additional elements specific to the type : (key label, value label) for the dict type """ try: return tuple(self._config_metadata[key]) except KeyError: return 'string', '', '' @security.protected(ManagePortal) def set_parameters(self, REQUEST=None, **kwargs): """ set transform's parameters """ if not kwargs: kwargs = REQUEST.form self.preprocess_param(kwargs) for param, value in kwargs.items(): try: self.get_parameter_value(param) except KeyError: log('Warning: ignored parameter %r' % param) continue meta = self.get_parameter_infos(param) self._config[param] = VALIDATORS[meta[0]](value) tr_tool = getToolByName(self, 'portal_transforms') # need to remap transform if necessary (i.e. configurable # inputs / output) if 'inputs' in kwargs or 'output' in kwargs: tr_tool._unmapTransform(self) if not hasattr(self, '_v_transform'): self._load_transform() self.inputs = kwargs.get('inputs', self._v_transform.inputs) self.output = kwargs.get('output', self._v_transform.output) tr_tool._mapTransform(self) # track output encoding if 'output_encoding' in kwargs: self.output_encoding = kwargs['output_encoding'] if REQUEST is not None: REQUEST['RESPONSE'].redirect(tr_tool.absolute_url() + '/manage_main') @security.protected(ManagePortal) def reload(self): """ reload the module where the transformation class is defined """ log('Reloading transform %s' % self.module) m = import_from_name(self.module) reload_module(m) self._tr_init() def preprocess_param(self, kwargs): """ preprocess param fetched from an http post to handle optional dictionary """ for param in self.get_parameters(): if self.get_parameter_infos(param)[0] == 'dict': try: keys = kwargs[param + '_key'] del kwargs[param + '_key'] except: keys = () try: values = kwargs[param + '_value'] del kwargs[param + '_value'] except: values = () kwargs[param] = dict = {} for key, value in zip(keys, values): key = key.strip() if key: value = value.strip() if value: dict[key] = value
from collective.pwexpiry.config import _ from collective.pwexpiry.utils import days_since_event from DateTime import DateTime from Globals import InitializeClass from plone import api from plone.registry.interfaces import IRegistry from Products.PageTemplates.PageTemplateFile import PageTemplateFile from Products.PlonePAS.interfaces.plugins import IUserManagement from Products.PluggableAuthService.interfaces.plugins import ( IAuthenticationPlugin, IChallengePlugin) from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin from Products.statusmessages.interfaces import IStatusMessage from zope.component import getUtility from zope.interface import implements manage_addPwExpiryPluginForm = PageTemplateFile( 'www/addPwExpiryPlugin', globals(), __name__='manage_addPwExpiryPlugin') def addPwExpiryPlugin(self, id, title='', REQUEST=None): """ Add PwExpiry plugin """ o = PwExpiryPlugin(id, title) self._setObject(o.getId(), o) if REQUEST is not None: REQUEST['RESPONSE'].redirect( '%s/manage_main' '?manage_tabs_message=PwExpiry+Plugin+added.' % self.absolute_url())
class WorkflowDefinitionConfigurator(Implicit): """ Synthesize XML description of site's workflows. """ security = ClassSecurityInfo() def __init__(self, obj): self._obj = obj security.declareProtected(ManagePortal, 'getWorkflowInfo') def getWorkflowInfo(self, workflow_id): """ Return a mapping describing a given workflow. o Keys in the mappings: 'id' -- the ID of the workflow within the tool 'meta_type' -- the workflow's meta_type 'title' -- the workflow's title property 'description' -- the workflow's description property o See '_extractDCWorkflowInfo' below for keys present only for DCWorkflow definitions. """ workflow = self._obj workflow_info = { 'id': workflow_id, 'meta_type': workflow.meta_type, 'title': workflow.title_or_id(), 'description': workflow.description } if workflow.meta_type == DCWorkflowDefinition.meta_type: self._extractDCWorkflowInfo(workflow, workflow_info) return workflow_info security.declareProtected(ManagePortal, 'generateWorkflowXML') def generateWorkflowXML(self): """ Pseudo API. """ return self._workflowConfig(workflow_id=self._obj.getId()) security.declareProtected(ManagePortal, 'getWorkflowScripts') def getWorkflowScripts(self): """ Get workflow scripts information """ return self._extractScripts(self._obj) security.declareProtected(ManagePortal, 'parseWorkflowXML') def parseWorkflowXML(self, xml, encoding='utf-8'): """ Pseudo API. """ dom = parseString(xml) root = dom.getElementsByTagName('dc-workflow')[0] workflow_id = _getNodeAttribute(root, 'workflow_id', encoding) title = _getNodeAttribute(root, 'title', encoding) try: description = _getNodeAttribute(root, 'description', encoding) except ValueError: # Don't fail on export files that do not have the description field! description = '' manager_bypass = _queryNodeAttributeBoolean(root, 'manager_bypass', False) creation_guard = _extractCreationGuard(root, encoding) state_variable = _getNodeAttribute(root, 'state_variable', encoding) initial_state = _getNodeAttribute(root, 'initial_state', encoding) states = _extractStateNodes(root, encoding) transitions = _extractTransitionNodes(root, encoding) variables = _extractVariableNodes(root, encoding) worklists = _extractWorklistNodes(root, encoding) permissions = _extractPermissionNodes(root, encoding) scripts = _extractScriptNodes(root, encoding) return (workflow_id, title, state_variable, initial_state, states, transitions, variables, worklists, permissions, scripts, description, manager_bypass, creation_guard) security.declarePrivate('_workflowConfig') _workflowConfig = PageTemplateFile('wtcWorkflowExport.xml', _xmldir, __name__='workflowConfig') security.declarePrivate('_extractDCWorkflowInfo') def _extractDCWorkflowInfo(self, workflow, workflow_info): """ Append the information for a 'workflow' into 'workflow_info' o 'workflow' must be a DCWorkflowDefinition instance. o 'workflow_info' must be a dictionary. o The following keys will be added to 'workflow_info': 'creation_guard' -- the guard of 'Instance creation conditions' 'permissions' -- a list of names of permissions managed by the workflow 'state_variable' -- the name of the workflow's "main" state variable 'initial_state' -- the name of the state in the workflow in which objects start their lifecycle. 'variable_info' -- a list of mappings describing the variables tracked by the workflow (see '_extractVariables'). 'state_info' -- a list of mappings describing the states tracked by the workflow (see '_extractStates'). 'transition_info' -- a list of mappings describing the transitions tracked by the workflow (see '_extractTransitions'). 'worklist_info' -- a list of mappings describing the worklists tracked by the workflow (see '_extractWorklists'). 'script_info' -- a list of mappings describing the scripts which provide added business logic (see '_extractScripts'). """ workflow_info['manager_bypass'] = bool(workflow.manager_bypass) workflow_info['creation_guard'] = self._extractCreationGuard(workflow) workflow_info['state_variable'] = workflow.state_var workflow_info['initial_state'] = workflow.initial_state workflow_info['permissions'] = workflow.permissions workflow_info['variable_info'] = self._extractVariables(workflow) workflow_info['state_info'] = self._extractStates(workflow) workflow_info['transition_info'] = self._extractTransitions(workflow) workflow_info['worklist_info'] = self._extractWorklists(workflow) workflow_info['script_info'] = self._extractScripts(workflow) security.declarePrivate('_extractCreationGuard') def _extractCreationGuard(self, workflow): """ Return a mapping describing 'Instance creation conditions' if 'creation_guard' is initialized or None """ guard = workflow.creation_guard if guard is not None: info = { 'guard_permissions': guard.permissions, 'guard_roles': guard.roles, 'guard_groups': guard.groups, 'guard_expr': guard.getExprText() } return info security.declarePrivate('_extractVariables') def _extractVariables(self, workflow): """ Return a sequence of mappings describing DCWorkflow variables. o Keys for each mapping will include: 'id' -- the variable's ID 'description' -- a textual description of the variable 'for_catalog' -- whether to catalog this variable 'for_status' -- whether to ??? this variable (XXX) 'update_always' -- whether to update this variable whenever executing a transition (xxX) 'default_value' -- a default value for the variable (XXX) 'default_expression' -- a TALES expression for the default value 'guard_permissions' -- a list of permissions guarding access to the variable 'guard_roles' -- a list of roles guarding access to the variable 'guard_groups' -- a list of groups guarding the transition 'guard_expr' -- an expression guarding access to the variable """ result = [] items = workflow.variables.objectItems() items.sort() for k, v in items: guard = v.getInfoGuard() default_type = _guessVariableType(v.default_value) info = { 'id': k, 'description': v.description, 'for_catalog': bool(v.for_catalog), 'for_status': bool(v.for_status), 'update_always': bool(v.update_always), 'default_value': v.default_value, 'default_type': default_type, 'default_expr': v.getDefaultExprText(), 'guard_permissions': guard.permissions, 'guard_roles': guard.roles, 'guard_groups': guard.groups, 'guard_expr': guard.getExprText() } result.append(info) return result security.declarePrivate('_extractStates') def _extractStates(self, workflow): """ Return a sequence of mappings describing DCWorkflow states. o Within the workflow mapping, each 'state_info' mapping has keys: 'id' -- the state's ID 'title' -- the state's title 'description' -- the state's description 'transitions' -- a list of IDs of transitions out of the state 'permissions' -- a list of mappings describing the permission map for the state 'groups' -- a list of ( group_id, (roles,) ) tuples describing the group-role assignments for the state 'variables' -- a list of mapping for the variables to be set when entering the state. o Within the state_info mappings, each 'permissions' mapping has the keys: 'name' -- the name of the permission 'roles' -- a sequence of role IDs which have the permission 'acquired' -- whether roles are acquired for the permission o Within the state_info mappings, each 'variable' mapping has the keys: 'name' -- the name of the variable 'type' -- the type of the value (allowed values are: 'string', 'datetime', 'bool', 'int') 'value' -- the value to be set """ result = [] items = workflow.states.objectItems() items.sort() for k, v in items: groups = v.group_roles and list(v.group_roles.items()) or [] groups = [x for x in groups if x[1]] groups.sort() variables = list(v.getVariableValues()) variables.sort() v_info = [] for v_name, value in variables: v_info.append({ 'name': v_name, 'type': _guessVariableType(value), 'value': value }) info = { 'id': k, 'title': v.title, 'description': v.description, 'transitions': v.transitions, 'permissions': self._extractStatePermissions(v), 'groups': groups, 'variables': v_info } result.append(info) return result security.declarePrivate('_extractStatePermissions') def _extractStatePermissions(self, state): """ Return a sequence of mappings for the permissions in a state. o Each mapping has the keys: 'name' -- the name of the permission 'roles' -- a sequence of role IDs which have the permission 'acquired' -- whether roles are acquired for the permission """ result = [] perm_roles = state.permission_roles if perm_roles: items = state.permission_roles.items() items.sort() for k, v in items: result.append({ 'name': k, 'roles': v, 'acquired': not isinstance(v, tuple) }) return result security.declarePrivate('_extractTransitions') def _extractTransitions(self, workflow): """ Return a sequence of mappings describing DCWorkflow transitions. o Each mapping has the keys: 'id' -- the transition's ID 'title' -- the transition's ID 'description' -- the transition's description 'new_state_id' -- the ID of the state into which the transition moves an object 'trigger_type' -- one of the following values, indicating how the transition is fired: - "AUTOMATIC" -> fired opportunistically whenever the workflow notices that its guard conditions permit - "USER" -> fired in response to user request 'script_name' -- the ID of a script to be executed before the transition 'after_script_name' -- the ID of a script to be executed after the transition 'actbox_name' -- the name of the action by which the user triggers the transition 'actbox_url' -- the URL of the action by which the user triggers the transition 'actbox_icon' -- the icon URL for the action by which the user triggers the transition 'actbox_category' -- the category of the action by which the user triggers the transition 'variables' -- a list of ( id, expr ) tuples defining how variables are to be set during the transition 'guard_permissions' -- a list of permissions guarding the transition 'guard_roles' -- a list of roles guarding the transition 'guard_groups' -- a list of groups guarding the transition 'guard_expr' -- an expression guarding the transition """ result = [] items = workflow.transitions.objectItems() items.sort() for k, v in items: guard = v.getGuard() v_info = [] for v_name, expr in v.getVariableExprs(): v_info.append({'name': v_name, 'expr': expr}) info = { 'id': k, 'title': v.title, 'description': v.description, 'new_state_id': v.new_state_id, 'trigger_type': TRIGGER_TYPES[v.trigger_type], 'script_name': v.script_name, 'after_script_name': v.after_script_name, 'actbox_name': v.actbox_name, 'actbox_url': v.actbox_url, 'actbox_icon': v.actbox_icon, 'actbox_category': v.actbox_category, 'variables': v_info, 'guard_permissions': guard.permissions, 'guard_roles': guard.roles, 'guard_groups': guard.groups, 'guard_expr': guard.getExprText() } result.append(info) return result security.declarePrivate('_extractWorklists') def _extractWorklists(self, workflow): """ Return a sequence of mappings describing DCWorkflow transitions. o Each mapping has the keys: 'id' -- the ID of the worklist 'title' -- the title of the worklist 'description' -- a textual description of the worklist 'var_match' -- a list of ( key, value ) tuples defining the variables used to "activate" the worklist. 'actbox_name' -- the name of the "action" corresponding to the worklist 'actbox_url' -- the URL of the "action" corresponding to the worklist 'actbox_icon' -- the icon URL of the "action" corresponding to the worklist 'actbox_category' -- the category of the "action" corresponding to the worklist 'guard_permissions' -- a list of permissions guarding access to the worklist 'guard_roles' -- a list of roles guarding access to the worklist 'guard_expr' -- an expression guarding access to the worklist """ result = [] items = workflow.worklists.objectItems() items.sort() for k, v in items: guard = v.getGuard() var_match = [(id, v.getVarMatchText(id)) for id in v.getVarMatchKeys()] info = { 'id': k, 'title': v.title, 'description': v.description, 'var_match': var_match, 'actbox_name': v.actbox_name, 'actbox_url': v.actbox_url, 'actbox_icon': v.actbox_icon, 'actbox_category': v.actbox_category, 'guard_permissions': guard.permissions, 'guard_roles': guard.roles, 'guard_groups': guard.groups, 'guard_expr': guard.getExprText() } result.append(info) return result security.declarePrivate('_extractScripts') def _extractScripts(self, workflow): """ Return a sequence of mappings describing DCWorkflow scripts. o Each mapping has the keys: 'id' -- the ID of the script 'meta_type' -- the title of the worklist 'body' -- the text of the script (only applicable to scripts of type Script (Python)) 'module' -- The module from where to load the function (only applicable to External Method scripts) 'function' -- The function to load from the 'module' given (Only applicable to External Method scripts) 'filename' -- the name of the file to / from which the script is stored / loaded (Script (Python) only) """ result = [] items = workflow.scripts.objectItems() items.sort() for k, v in items: filename = _getScriptFilename(workflow.getId(), k, v.meta_type) module = '' function = '' if v.meta_type == 'External Method': module = v.module() function = v.function() info = { 'id': k, 'meta_type': v.meta_type, 'module': module, 'function': function, 'filename': filename } result.append(info) return result
# It can be useful to set NO_CACHE_MODE to 1 in order to debug # complex security issues related to caching groups. For example, # the use of scripts instead of external methods for # assignment category lookup may make the system unstable and # hard to debug. Setting NO_CACHE_MODE allows to debug such # issues. NO_CACHE_MODE = 0 class ConsistencyError(Exception): pass manage_addERP5GroupManagerForm = PageTemplateFile( 'www/ERP5Security_addERP5GroupManager', globals(), __name__='manage_addERP5GroupManagerForm') def addERP5GroupManager(dispatcher, id, title=None, REQUEST=None): """ Add a ERP5GroupManager to a Pluggable Auth Service. """ egm = ERP5GroupManager(id, title) dispatcher._setObject(egm.getId(), egm) if REQUEST is not None: REQUEST['RESPONSE'].redirect('%s/manage_workspace' '?manage_tabs_message=' 'ERP5GroupManager+added.' % dispatcher.absolute_url())
from Products.PluggableAuthService.interfaces.plugins \ import IRolesPlugin from Products.membrane.interfaces import group as group_ifaces from Products.membrane.interfaces import user as user_ifaces from Products.membrane.interfaces.plugins import IMembraneGroupManagerPlugin from Products.membrane.config import QIM_ANNOT_KEY from Products.membrane.config import TOOLNAME from Products.membrane.utils import findMembraneUserAspect # XXX REMOVE WHEN REFACTORING from Acquisition import aq_base from Products.PlonePAS.plugins.group import PloneGroup manage_addMembraneGroupManagerForm = PageTemplateFile( '../www/MembraneGroupManagerForm', globals(), __name__='manage_addMembraneGroupManagerForm') def addMembraneGroupManager(dispatcher, id, title=None, REQUEST=None): """ Add a MembraneGroupManager to a Pluggable Auth Service. """ pmm = MembraneGroupManager(id, title) dispatcher._setObject(pmm.getId(), pmm) if REQUEST is not None: REQUEST['RESPONSE'].redirect('%s/manage_workspace' '?manage_tabs_message=' 'MembraneGroupManager+added.' % dispatcher.absolute_url())
class DynamicGroupsPlugin(Folder, BasePlugin, Cacheable): """ Define groups via business rules. o Membership in a candidate group is established via a predicate, expressed as a TALES expression. Names available to the predicate include: 'group' -- the dynamic group definition object itself 'plugin' -- this plugin object 'principal' -- the principal being tested. 'request' -- the request object. """ meta_type = 'Dynamic Groups Plugin' security = ClassSecurityInfo() def __init__(self, id, title=''): self._setId(id) self.title = title # # Plugin implementations # security.declareProtected(ManageGroups, 'getGroupsForPrincipal') def getGroupsForPrincipal(self, principal, request=None): """ See IGroupsPlugin. """ grps = [] DGD = DynamicGroupDefinition.meta_type for group in self.objectValues(DGD): if group.active and group(principal, request): grps.append('%s%s' % (self.prefix, group.getId())) return grps security.declareProtected(ManageGroups, 'enumerateGroups') def enumerateGroups(self, id=None, exact_match=False, sort_by=None, max_results=None, **kw): """ See IGroupEnumerationPlugin. """ group_info = [] group_ids = [] plugin_id = self.getId() view_name = createViewName('enumerateGroups', id) # Look in the cache first... keywords = copy.deepcopy(kw) keywords.update({ 'id': id, 'exact_match': exact_match, 'sort_by': sort_by, 'max_results': max_results }) cached_info = self.ZCacheable_get(view_name=view_name, keywords=keywords, default=None) if cached_info is not None: return tuple(cached_info) if isinstance(id, str): id = [id] if exact_match and id: group_ids.extend(id) if group_ids: group_filter = None else: # Searching group_ids = self.listGroupIds() group_filter = _DynamicGroupFilter(id, **kw) for group_id in group_ids: url = '/%s/%s/manage_propertiesForm' % (self.absolute_url(1), group_id) info = {} info.update(self.getGroupInfo(group_id)) info['pluginid'] = plugin_id info['properties_url'] = url info['members_url'] = url info['id'] = '%s%s' % (self.prefix, info['id']) if not group_filter or group_filter(info): if info['active']: group_info.append(info) # Put the computed value into the cache self.ZCacheable_set(group_info, view_name=view_name, keywords=keywords) return tuple(group_info) # # Housekeeping # security.declareProtected(ManageGroups, 'listGroupIds') def listGroupIds(self): """ Return a list of IDs for the dynamic groups we manage. """ return self.objectIds(DynamicGroupDefinition.meta_type) security.declareProtected(ManageGroups, 'getGroupInfo') def getGroupInfo(self, group_id): """ Return a mappings describing one dynamic group we manage. o Raise KeyError if we don't have an existing group definition for 'group_ id'. o Keys include: 'id' -- the group's ID 'predicate' -- the TALES expression defining group membership 'active' -- boolean flag: is the group currently active? """ try: original = self._getOb(group_id) except AttributeError: try: original = self._getOb(group_id[len(self.prefix):]) except AttributeError: raise KeyError, group_id if not isinstance(original, DynamicGroupDefinition): raise KeyError, group_id info = {} for k, v in original.propertyItems(): info[k] = v return info security.declareProtected(ManageGroups, 'listGroupInfo') def listGroupInfo(self): """ Return a list of mappings describing the dynamic groups we manage. o Keys include: 'id' -- the group's ID 'predicate' -- the TALES expression defining group membership 'active' -- boolean flag: is the group currently active? """ return [self.getGroupInfo(x) for x in self.listGroupIds()] security.declareProtected(ManageGroups, 'addGroup') def addGroup(self, group_id, predicate, title='', description='', active=True): """ Add a group definition. o Raise KeyError if we have an existing group definition for 'group_id'. """ if group_id in self.listGroupIds(): raise KeyError, 'Duplicate group ID: %s' % group_id info = DynamicGroupDefinition(group_id, predicate, title, description, active) self._setObject(group_id, info) # This method changes the enumerateGroups return value view_name = createViewName('enumerateGroups') self.ZCacheable_invalidate(view_name=view_name) security.declareProtected(ManageGroups, 'updateGroup') def updateGroup(self, group_id, predicate, title=None, description=None, active=None): """ Update a group definition. o Raise KeyError if we don't have an existing group definition for 'group_id'. o Don't update 'title', 'description', or 'active' unless supplied. """ if group_id not in self.listGroupIds(): raise KeyError, 'Invalid group ID: %s' % group_id group = self._getOb(group_id) group._setPredicate(predicate) if title is not None: group.title = title if description is not None: group.description = description if active is not None: group.active = active # This method changes the enumerateGroups return value view_name = createViewName('enumerateGroups') self.ZCacheable_invalidate(view_name=view_name) view_name = createViewName('enumerateGroups', group_id) self.ZCacheable_invalidate(view_name=view_name) security.declareProtected(ManageGroups, 'removeGroup') def removeGroup(self, group_id, REQUEST=None): """ Remove a group definition. o Raise KeyError if we don't have an existing group definition for 'group_id'. """ if group_id not in self.listGroupIds(): raise KeyError, 'Invalid group ID: %s' % group_id self._delObject(group_id) # This method changes the enumerateGroups return value view_name = createViewName('enumerateGroups') self.ZCacheable_invalidate(view_name=view_name) view_name = createViewName('enumerateGroups', group_id) self.ZCacheable_invalidate(view_name=view_name) removeGroup = postonly(removeGroup) # # ZMI # manage_options = (({ 'label': 'Groups', 'action': 'manage_groups' }, ) + Folder.manage_options[:1] + BasePlugin.manage_options[:1] + Folder.manage_options[1:] + Cacheable.manage_options) manage_groups = PageTemplateFile('www/dgpGroups', globals(), __name__='manage_groups') security.declareProtected(ManageGroups, 'manage_addGroup') def manage_addGroup(self, group_id, title, description, predicate, active=True, RESPONSE=None): """ Add a group via the ZMI. """ self.addGroup(group_id, predicate, title, description, active) message = 'Group+%s+added' % group_id if RESPONSE is not None: RESPONSE.redirect('%s/manage_groups?manage_tabs_message=%s' % (self.absolute_url(), message)) security.declareProtected(ManageGroups, 'manage_updateGroup') def manage_updateGroup(self, group_id, predicate, title=None, description=None, active=True, RESPONSE=None): """ Update a group via the ZMI. """ self.updateGroup(group_id, predicate, title, description, active) message = 'Group+%s+updated' % group_id if RESPONSE is not None: RESPONSE.redirect( ('%s/manage_groups?group_id=%s&' + 'manage_tabs_message=%s') % (self.absolute_url(), group_id, message)) security.declareProtected(ManageGroups, 'manage_removeGroups') def manage_removeGroups(self, group_ids, RESPONSE=None, REQUEST=None): """ Remove one or more groups via the ZMI. """ group_ids = filter(None, group_ids) if not group_ids: message = 'no+groups+selected' else: for group_id in group_ids: self.removeGroup(group_id) message = 'Groups+removed' if RESPONSE is not None: RESPONSE.redirect('%s/manage_groups?manage_tabs_message=%s' % (self.absolute_url(), message)) manage_removeGroups = postonly(manage_removeGroups)
class WorkflowUIMixin: ''' ''' security = ClassSecurityInfo() security.declareProtected(ManagePortal, 'manage_properties') manage_properties = DTMLFile('workflow_properties', _dtmldir) manage_groups = PageTemplateFile('workflow_groups.pt', _dtmldir) security.declareProtected(ManagePortal, 'setProperties') @postonly def setProperties(self, title, manager_bypass=0, props=None, REQUEST=None, description=''): """Sets basic properties. """ self.title = str(title) self.description = str(description) self.manager_bypass = manager_bypass and 1 or 0 g = Guard() if g.changeFromProperties(props or REQUEST): self.creation_guard = g else: self.creation_guard = None if REQUEST is not None: return self.manage_properties( REQUEST, manage_tabs_message='Properties changed.') _permissions_form = DTMLFile('workflow_permissions', _dtmldir) security.declareProtected(ManagePortal, 'manage_permissions') def manage_permissions(self, REQUEST, manage_tabs_message=None): """Displays the form for choosing which permissions to manage. """ return self._permissions_form(REQUEST, management_view='Permissions', manage_tabs_message=manage_tabs_message, ) security.declareProtected(ManagePortal, 'addManagedPermission') @postonly def addManagedPermission(self, p, REQUEST=None): """Adds to the list of permissions to manage. """ if p in self.permissions: raise ValueError, 'Already a managed permission: ' + p if REQUEST is not None and p not in self.getPossiblePermissions(): raise ValueError, 'Not a valid permission name:' + p self.permissions = self.permissions + (p,) if REQUEST is not None: return self.manage_permissions( REQUEST, manage_tabs_message='Permission added.') security.declareProtected(ManagePortal, 'delManagedPermissions') @postonly def delManagedPermissions(self, ps, REQUEST=None): """Removes from the list of permissions to manage. """ if ps: l = list(self.permissions) for p in ps: l.remove(p) self.permissions = tuple(l) if REQUEST is not None: return self.manage_permissions( REQUEST, manage_tabs_message='Permission(s) removed.') security.declareProtected(ManagePortal, 'getPossiblePermissions') def getPossiblePermissions(self): """Returns the list of all permissions that can be managed. """ # possible_permissions is in AccessControl.Role.RoleManager. return list(self.possible_permissions()) security.declareProtected(ManagePortal, 'getGroups') def getGroups(self): """Returns the names of groups managed by this workflow. """ return tuple(self.groups) security.declareProtected(ManagePortal, 'getAvailableGroups') def getAvailableGroups(self): """Returns a list of available group names. """ gf = aq_get( self, '__allow_groups__', None, 1 ) if gf is None: return () try: groups = gf.searchGroups() except AttributeError: return () else: return [g['id'] for g in groups] security.declareProtected(ManagePortal, 'addGroup') @postonly def addGroup(self, group, RESPONSE=None, REQUEST=None): """Adds a group by name. """ if group not in self.getAvailableGroups(): raise ValueError(group) self.groups = self.groups + (group,) if RESPONSE is not None: RESPONSE.redirect( "%s/manage_groups?manage_tabs_message=Added+group." % self.absolute_url()) security.declareProtected(ManagePortal, 'delGroups') @postonly def delGroups(self, groups, RESPONSE=None, REQUEST=None): """Removes groups by name. """ self.groups = tuple([g for g in self.groups if g not in groups]) if RESPONSE is not None: RESPONSE.redirect( "%s/manage_groups?manage_tabs_message=Groups+removed." % self.absolute_url()) security.declareProtected(ManagePortal, 'getAvailableRoles') def getAvailableRoles(self): """Returns the acquired roles mixed with base_cms roles. """ roles = list(self.valid_roles()) for role in getDefaultRolePermissionMap().keys(): if role not in roles: roles.append(role) roles.sort() return roles security.declareProtected(ManagePortal, 'getRoles') def getRoles(self): """Returns the list of roles managed by this workflow. """ roles = self.roles if roles is not None: return roles roles = getDefaultRolePermissionMap().keys() if roles: # Map the base_cms roles by default. roles.sort() return roles return self.valid_roles() security.declareProtected(ManagePortal, 'setRoles') @postonly def setRoles(self, roles, RESPONSE=None, REQUEST=None): """Changes the list of roles mapped to groups by this workflow. """ avail = self.getAvailableRoles() for role in roles: if role not in avail: raise ValueError(role) self.roles = tuple(roles) if RESPONSE is not None: RESPONSE.redirect( "%s/manage_groups?manage_tabs_message=Roles+changed." % self.absolute_url()) security.declareProtected(ManagePortal, 'getGuard') def getGuard(self): """Returns the initiation guard. If no init guard has been created, returns a temporary object. """ if self.creation_guard is not None: return self.creation_guard else: return Guard().__of__(self) # Create a temporary guard. security.declarePublic('guardExprDocs') def guardExprDocs(self): """Returns documentation on guard expressions. """ here = os.path.dirname(__file__) fn = os.path.join(here, 'doc', 'expressions.stx') f = open(fn, 'rt') try: text = f.read() finally: f.close() from DocumentTemplate.DT_Var import structured_text return structured_text(text)
def _getExportTemplate(self): return PageTemplateFile('ccExport.xml', _xmldir)
from eea.ldapadmin.ui_common import load_template from eea.ldapadmin.users_admin import eionet_edit_users from email.mime.text import MIMEText from persistent.mapping import PersistentMapping from zope.component import getUtility from zope.component.interfaces import ComponentLookupError from zope.sendmail.interfaces import IMailDelivery import base64 import hashlib import logging import random log = logging.getLogger(__name__) manage_add_pwreset_tool_html = PageTemplateFile('zpt/pwreset_manage_add', globals()) manage_add_pwreset_tool_html.ldap_config_edit_macro = ldap_config.edit_macro manage_add_pwreset_tool_html.config_defaults = lambda: ldap_config.defaults def manage_add_pwreset_tool(parent, id, REQUEST=None): """ Create a new PasswordResetTool object """ form = (REQUEST is not None and REQUEST.form or {}) config = ldap_config.read_form(form) obj = PasswordResetTool(config) obj.title = form.get('title', id) obj._setId(id) parent._setObject(id, obj) if REQUEST is not None: REQUEST.RESPONSE.redirect(parent.absolute_url() + '/manage_workspace')
class ToolsetRegistry(Implicit): """ Track required / forbidden tools. """ implements(IToolsetRegistry) security = ClassSecurityInfo() security.setDefaultAccess('allow') def __init__(self): self.clear() # # Toolset API # security.declareProtected(ManagePortal, 'listForbiddenTools') def listForbiddenTools(self): """ See IToolsetRegistry. """ result = list(self._forbidden) result.sort() return result security.declareProtected(ManagePortal, 'addForbiddenTool') def addForbiddenTool(self, tool_id): """ See IToolsetRegistry. """ if tool_id in self._forbidden: return if self._required.get(tool_id) is not None: raise ValueError, 'Tool %s is required!' % tool_id self._forbidden.append(tool_id) security.declareProtected(ManagePortal, 'listRequiredTools') def listRequiredTools(self): """ See IToolsetRegistry. """ result = list(self._required.keys()) result.sort() return result security.declareProtected(ManagePortal, 'getRequiredToolInfo') def getRequiredToolInfo(self, tool_id): """ See IToolsetRegistry. """ return self._required[tool_id] security.declareProtected(ManagePortal, 'listRequiredToolInfo') def listRequiredToolInfo(self): """ See IToolsetRegistry. """ return [self.getRequiredToolInfo(x) for x in self.listRequiredTools()] security.declareProtected(ManagePortal, 'addRequiredTool') def addRequiredTool(self, tool_id, dotted_name): """ See IToolsetRegistry. """ if tool_id in self._forbidden: raise ValueError, "Forbidden tool ID: %s" % tool_id self._required[tool_id] = {'id': tool_id, 'class': dotted_name} security.declareProtected(ManagePortal, 'generateXML') def generateXML(self): """ Pseudo API. """ return self._toolsetConfig() security.declareProtected(ManagePortal, 'parseXML') def parseXML(self, text, encoding=None): """ Pseudo-API """ reader = getattr(text, 'read', None) if reader is not None: text = reader() parser = _ToolsetParser(encoding) parseString(text, parser) for tool_id in parser._forbidden: self.addForbiddenTool(tool_id) for tool_id, dotted_name in parser._required.items(): self.addRequiredTool(tool_id, dotted_name) security.declarePrivate('clear') def clear(self): self._forbidden = [] self._required = {} # # Helper methods. # security.declarePrivate('_toolsetConfig') _toolsetConfig = PageTemplateFile('tscExport.xml', _xmldir, __name__='toolsetConfig')
self.setSessionErrors(['Error while delete data.']) if REQUEST: REQUEST.RESPONSE.redirect('reportquestionnaires_html') security.declareProtected(view, 'report_macro_objecttree_html') def report_macro_objecttree_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getForm('report_macro_objecttree') security.declareProtected(PERMISSION_EDIT_OBJECTS, 'sectioncomments_html') def sectioncomments_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getContent({'here': self}, 'section_comments') InitializeClass(NyReportSection) manage_addNyReportSection_html = PageTemplateFile('zpt/reportsection_manage_add', globals()) manage_addNyReportSection_html.kind = METATYPE_OBJECT manage_addNyReportSection_html.action = 'addNyReportSection' config.update({ 'constructors': (manage_addNyReportSection_html, addNyReportSection), 'folder_constructors': [ # NyFolder.manage_addNyReportSection_html = manage_addNyReportSection_html ('manage_addNyReportSection_html', manage_addNyReportSection_html), ('reportsection_add_html', reportsection_add_html), ('addNyReportSection', addNyReportSection), (config['import_string'], importNyReportSection), ], 'add_method': addNyReportSection, 'validation': issubclass(NyReportSection, NyValidation), '_class': NyReportSection,
_properties = (PropertyManager._properties + (dict( id="roles", label="roles (empty means all roles)", type="lines", mode="rw", ), )) roles = () manage_options = ((NotCompetentBase.manage_options[0], ) + PropertyManager.manage_options + NotCompetentBase.manage_options[1:-1]) def isNotCompetentToAuthenticate(self, request): return self._getHigherLevelUser(request, self.roles) is not None manage_addNotCompetent_byRolesForm = PageTemplateFile( 'www/ncbrAdd', globals(), __name__='manage_addNotCompetent_byRolesForm') def manage_addNotCompetent_byRoles(self, id, title='', REQUEST=None): """ Factory method to instantiate a NotCompetent_byRoles """ obj = NotCompetent_byRoles(id, title=title) self._setObject(id, obj) if REQUEST is not None: qs = 'manage_tabs_message=NotCompetent_byRoles+added.' my_url = self.absolute_url() REQUEST['RESPONSE'].redirect('%s/manage_workspace?%s' % (my_url, qs))
' are edited. You can automatically recompile all Scripts that have' ' this problem by visiting /manage_addProduct/PythonScripts/recompile' ' of your server in a browser.') _default_file = os.path.join(package_home(globals()), 'www', 'default_cpy') _marker = [] # Create a new marker object _first_indent = re.compile('(?m)^ *(?! |$)') _nonempty_line = re.compile('(?m)^(.*\S.*)$') # ########################################################################### # Product registration and Add support manage_addControllerPythonScriptForm = PageTemplateFile('www/cpyAdd', globals()) manage_addControllerPythonScriptForm.__name__='manage_addControllerPythonScriptForm' def manage_addControllerPythonScript(self, id, REQUEST=None, submit=None): """Add a Python script to a folder. """ id = str(id) id = self._setObject(id, ControllerPythonScript(id)) if REQUEST is not None: file = REQUEST.form.get('file', '') if not isinstance(file, str): file = file.read() if not file: file = open(_default_file).read() self._getOb(id).write(file) try: u = self.DestinationURL()
class ImportStepRegistry(BaseStepRegistry): """ Manage knowledge about steps to create / configure site. o Steps are composed together to define a site profile. """ implements(IImportStepRegistry) security = ClassSecurityInfo() RegistryParser = _ImportStepRegistryParser security.declareProtected(ManagePortal, 'sortSteps') def sortSteps(self): """ Return a sequence of registered step IDs o Sequence is sorted topologically by dependency, with the dependent steps *after* the steps they depend on. """ return self._computeTopologicalSort() security.declareProtected(ManagePortal, 'checkComplete') def checkComplete(self): """ Return a sequence of ( node, edge ) tuples for unsatisifed deps. """ result = [] seen = {} graph = self._computeTopologicalSort() for node in graph: dependencies = self.getStepMetadata(node)['dependencies'] for dependency in dependencies: if seen.get(dependency) is None: result.append((node, dependency)) seen[node] = 1 return result security.declarePrivate('registerStep') def registerStep(self, id, version=None, handler=None, dependencies=(), title=None, description=None): """ Register a setup step. o 'id' is a unique name for this step, o 'version' is a string for comparing versions, it is preferred to be a yyyy/mm/dd-ii formatted string (date plus two-digit ordinal). when comparing two version strings, the version with the lower sort order is considered the older version. - Newer versions of a step supplant older ones. - Attempting to register an older one after a newer one results in a KeyError. o 'handler' is the dottoed name of a handler which should implement IImportPlugin. o 'dependencies' is a tuple of step ids which have to run before this step in order to be able to run at all. Registration of steps that have unmet dependencies are deferred until the dependencies have been registered. o 'title' is a one-line UI description for this step. If None, the first line of the documentation string of the handler is used, or the id if no docstring can be found. o 'description' is a one-line UI description for this step. If None, the remaining line of the documentation string of the handler is used, or default to ''. """ already = self.getStepMetadata(id) if handler is None: raise ValueError, 'No handler specified' if already and already['version'] > version: raise KeyError('Existing registration for step %s, version %s' % (id, already['version'])) if not isinstance(handler, str): handler = _getDottedName(handler) if title is None or description is None: method = _resolveDottedName(handler) if method is None: t, d = id, '' else: t, d = _extractDocstring(method, id, '') title = title or t description = description or d info = { 'id': id, 'version': version, 'handler': handler, 'dependencies': dependencies, 'title': title, 'description': description } self._registered[id] = info # # Helper methods # security.declarePrivate('_computeTopologicalSort') def _computeTopologicalSort(self): return _computeTopologicalSort(self._registered.values()) security.declarePrivate('_exportTemplate') _exportTemplate = PageTemplateFile('isrExport.xml', _xmldir)
site = self.getSite() lang = lang or self.gl_get_selected_language() fileitem = self.getFileItem(lang) if not fileitem: return self.absolute_url() + '/download?lang=%s&version=1' % lang file_path = fileitem._get_data_name() media_server = getattr(site, 'media_server', '').strip() if not (media_server and file_path): return self.absolute_url() + '/download?lang=%s&version=1' % lang file_path = (media_server, ) + tuple(file_path) return '/'.join(file_path) InitializeClass(NyExFile_extfile) manage_addNyExFile_html = PageTemplateFile('zpt/exfile_manage_add', globals()) manage_addNyExFile_html.kind = config['meta_type'] manage_addNyExFile_html.action = 'addNyExFile' config.update({ 'constructors': (manage_addNyExFile_html, addNyExFile), 'folder_constructors': [ # NyFolder.manage_addNyExFile_html = manage_addNyExFile_html ('manage_addNyExFile_html', manage_addNyExFile_html), ('exfile_add_html', exfile_add_html), ('addNyExFile', addNyExFile), ('import_exfile_item', importNyExFile), ], 'add_method': addNyExFile, 'validation': issubclass(NyExFile_extfile, NyValidation), '_class': NyExFile_extfile, })
'nfp_url': (0, '', ''), 'source': (0, '', ''), 'flag_file': (0, '', ''), 'flag_url': (0, '', ''), 'del_smallflag': (0, '', ''), 'link_ins': (0, '', ''), 'link_doc': (0, '', ''), 'link_train': (0, '', ''), 'link_rd': (0, '', ''), 'link_data': (0, '', ''), 'legislation_feed_url': (0, '', ''), 'project_feed_url': (0, '', ''), 'lang': (0, '', '') } manage_addNyCountry_html = PageTemplateFile('zpt/country_manage_add', globals()) manage_addNyCountry_html.kind = METATYPE_OBJECT manage_addNyCountry_html.action = 'addNyCountry' def country_add_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getContent( { 'here': self, 'kind': METATYPE_OBJECT, 'action': 'addNyCountry' }, 'country_add') def addNyCountry(self,
class TypesTool(UniqueObject, IFAwareObjectManager, Folder, ActionProviderBase): """ Provides a configurable registry of portal content types. """ implements(ITypesTool) __implements__ = (z2ITypesTool, ActionProviderBase.__implements__) id = 'portal_types' meta_type = 'CMF Types Tool' _product_interfaces = (ITypeInformation, ) security = ClassSecurityInfo() manage_options = (Folder.manage_options[:1] + ({ 'label': 'Aliases', 'action': 'manage_aliases' }, ) + ActionProviderBase.manage_options + ({ 'label': 'Overview', 'action': 'manage_overview' }, ) + Folder.manage_options[1:]) # # ZMI methods # security.declareProtected(ManagePortal, 'manage_overview') manage_overview = DTMLFile('explainTypesTool', _dtmldir) security.declareProtected(ManagePortal, 'manage_aliases') manage_aliases = PageTemplateFile('typesAliases.zpt', _wwwdir) # # ObjectManager methods # def all_meta_types(self, interfaces=None): # this is a workaround and should be removed again if allowedTypes # have an interface we can use in _product_interfaces all = TypesTool.inheritedAttribute('all_meta_types')(self) others = [ mt for mt in Products.meta_types if mt['name'] in allowedTypes ] return tuple(all) + tuple(others) # # other methods # security.declareProtected(ManagePortal, 'manage_addTypeInformation') def manage_addTypeInformation(self, add_meta_type, id=None, typeinfo_name=None, RESPONSE=None): """Create a TypeInformation in self. """ # BBB: typeinfo_name is ignored if not id: raise BadRequest('An id is required.') for mt in Products.meta_types: if mt['name'] == add_meta_type: klass = mt['instance'] break else: raise ValueError, ('Meta type %s is not a type class.' % add_meta_type) id = str(id) ob = klass(id) self._setObject(id, ob) if RESPONSE is not None: RESPONSE.redirect('%s/manage_main' % self.absolute_url()) security.declareProtected(ManagePortal, 'manage_setTIMethodAliases') def manage_setTIMethodAliases(self, REQUEST): """ Config method aliases. """ form = REQUEST.form aliases = {} for k, v in form['aliases'].items(): v = v.strip() if v: aliases[k] = v for ti in self.listTypeInfo(): _dict = {} for k, v in form[ti.getId()].items(): if aliases.has_key(k): _dict[aliases[k]] = v ti.setMethodAliases(_dict) REQUEST.RESPONSE.redirect('%s/manage_aliases' % self.absolute_url()) security.declareProtected(AccessContentsInformation, 'getTypeInfo') def getTypeInfo(self, contentType): """ Return an instance which implements the TypeInformation interface, corresponding to the specified 'contentType'. If contentType is actually an object, rather than a string, attempt to look up the appropriate type info using its portal_type. """ if not isinstance(contentType, basestring): if hasattr(aq_base(contentType), 'getPortalTypeName'): contentType = contentType.getPortalTypeName() if contentType is None: return None else: return None ob = getattr(self, contentType, None) if ITypeInformation.providedBy(ob): return ob if getattr(aq_base(ob), '_isTypeInformation', 0): # BBB warn( "The '_isTypeInformation' marker attribute is deprecated, " "and will be removed in CMF 2.3. Please mark the instance " "with the 'ITypeInformation' interface instead.", DeprecationWarning, stacklevel=2) return ob else: return None security.declareProtected(AccessContentsInformation, 'listTypeInfo') def listTypeInfo(self, container=None): """ Return a sequence of instances which implement the TypeInformation interface, one for each content type registered in the portal. """ rval = [] for t in self.objectValues(): # Filter out things that aren't TypeInformation and # types for which the user does not have adequate permission. if ITypeInformation.providedBy(t): rval.append(t) elif getattr(aq_base(t), '_isTypeInformation', 0): # BBB warn( "The '_isTypeInformation' marker attribute is deprecated, " "and will be removed in CMF 2.3. Please mark the " "instance with the 'ITypeInformation' interface instead.", DeprecationWarning, stacklevel=2) rval.append(t) # Skip items with no ID: old signal for "not ready" rval = [t for t in rval if t.getId()] # check we're allowed to access the type object if container is not None: rval = [t for t in rval if t.isConstructionAllowed(container)] return rval security.declareProtected(AccessContentsInformation, 'listContentTypes') def listContentTypes(self, container=None, by_metatype=0): """ List type info IDs. Passing 'by_metatype' is deprecated (type information may not correspond 1:1 to an underlying meta_type). This argument will be removed when CMFCore/dtml/catalogFind.dtml doesn't need it anymore. """ typenames = {} for t in self.listTypeInfo(container): if by_metatype: warn( 'TypeInformation.listContentTypes(by_metatype=1) is ' 'deprecated.', DeprecationWarning) name = t.Metatype() else: name = t.getId() if name: typenames[name] = None result = typenames.keys() result.sort() return result security.declarePublic('constructContent') def constructContent(self, type_name, container, id, RESPONSE=None, *args, **kw): """ Build an instance of the appropriate content class in 'container', using 'id'. """ info = self.getTypeInfo(type_name) if info is None: raise ValueError('No such content type: %s' % type_name) ob = info.constructInstance(container, id, *args, **kw) if RESPONSE is not None: immediate_url = '%s/%s' % (ob.absolute_url(), info.immediate_view) RESPONSE.redirect(immediate_url) return ob.getId() security.declarePrivate('listActions') def listActions(self, info=None, object=None): """ List all the actions defined by a provider. """ actions = list(self._actions) if object is None and info is not None: object = info.object if object is not None: type_info = self.getTypeInfo(object) if type_info is not None: actions.extend(type_info.listActions(info, object)) return actions security.declareProtected(ManagePortal, 'listMethodAliasKeys') def listMethodAliasKeys(self): """ List all defined method alias names. """ _dict = {} for ti in self.listTypeInfo(): aliases = ti.getMethodAliases() for k, v in aliases.items(): _dict[k] = 1 rval = _dict.keys() rval.sort() return rval
class CalendarTool(UniqueObject, SimpleItem): """ A tool for encapsulating how calendars work and are displayed """ id = 'portal_calendar' meta_type = 'CMF Calendar Tool' security = ClassSecurityInfo() implements(ICalendarTool) calendar_types = ('Event', ) calendar_states = ('published', ) use_session = False firstweekday = 6 # 6 is Sunday manage_options = (( { 'label': 'Overview', 'action': 'manage_overview' }, { 'label': 'Configure', 'action': 'manage_configure' }, ) + SimpleItem.manage_options) # # ZMI methods # security.declareProtected(ManagePortal, 'manage_overview') manage_overview = PageTemplateFile('www/explainCalendarTool', globals(), __name__='manage_overview') security.declareProtected(ManagePortal, 'manage_configure') manage_configure = PageTemplateFile('www/configureCalendarTool', globals(), __name__='manage_configure') security.declareProtected(ManagePortal, 'edit_configuration') def edit_configuration(self, show_types, use_session, show_states=None, firstweekday=None): """ Change the configuration of the calendar tool """ self.calendar_types = tuple(show_types) self.use_session = bool(use_session) if show_states is not None: self.calendar_states = tuple(show_states) if firstweekday is not None: try: fwd = int(firstweekday) if 0 <= fwd <= 6: # Do nothing with illegal values self.firstweekday = fwd except ValueError: # Do nothing with illegal values pass if hasattr(self.REQUEST, 'RESPONSE'): self.REQUEST.RESPONSE.redirect('manage_configure') security.declarePrivate('_getCalendar') def _getCalendar(self): """ Wrapper to ensure we set the first day of the week every time """ calendar.setfirstweekday(self.getFirstWeekDay()) return calendar security.declarePublic('getFirstWeekDay') def getFirstWeekDay(self): """ Get our first weekday setting """ return self.firstweekday security.declarePublic('getCalendarTypes') def getCalendarTypes(self): """ Returns a list of type that will show in the calendar """ return self.calendar_types security.declarePublic('getCalendarStates') def getCalendarStates(self): """ Returns a list of workflow states that will show in the calendar """ return self.calendar_states security.declarePublic('getUseSession') def getUseSession(self): """ Returns the Use_Session option """ return bool(self.use_session) security.declarePublic('getDays') def getDays(self): """ Returns a list of days with the correct start day first """ return self._getCalendar().weekheader(2).split() security.declarePublic('getWeeksList') def getWeeksList(self, month='1', year='2002'): """ Return a series of weeks, each containing an integer day number. A day number of 0 means that day is in the previous or next month. """ year = int(year) month = int(month) # daysByWeek is a list of days inside a list of weeks, like so: # [[0, 1, 2, 3, 4, 5, 6], # [7, 8, 9, 10, 11, 12, 13], # [14, 15, 16, 17, 18, 19, 20], # [21, 22, 23, 24, 25, 26, 27], # [28, 29, 30, 31, 0, 0, 0]] daysByWeek = self._getCalendar().monthcalendar(year, month) return daysByWeek security.declarePublic('getEventsForCalendar') def getEventsForCalendar(self, month='1', year='2002'): """ recreates a sequence of weeks, by days each day is a mapping. {'day': #, 'url': None} """ year = int(year) month = int(month) # daysByWeek is a list of days inside a list of weeks, like so: # [[0, 1, 2, 3, 4, 5, 6], # [7, 8, 9, 10, 11, 12, 13], # [14, 15, 16, 17, 18, 19, 20], # [21, 22, 23, 24, 25, 26, 27], # [28, 29, 30, 31, 0, 0, 0]] daysByWeek = self._getCalendar().monthcalendar(year, month) weeks = [] events = self.catalog_getevents(year, month) for week in daysByWeek: days = [] for day in week: if events.has_key(day): days.append(events[day]) else: days.append({'day': day, 'event': 0, 'eventslist': []}) weeks.append(days) return weeks security.declarePublic('catalog_getevents') def catalog_getevents(self, year, month): """ given a year and month return a list of days that have events """ year = int(year) month = int(month) last_day = self._getCalendar().monthrange(year, month)[1] first_date = self.getBeginAndEndTimes(1, month, year)[0] last_date = self.getBeginAndEndTimes(last_day, month, year)[1] query = self.portal_catalog(portal_type=self.getCalendarTypes(), review_state=self.getCalendarStates(), start={ 'query': last_date, 'range': 'max' }, end={ 'query': first_date, 'range': 'min' }, sort_on='start') # compile a list of the days that have events eventDays = {} for daynumber in range(1, 32): # 1 to 31 eventDays[daynumber] = { 'eventslist': [], 'event': 0, 'day': daynumber } includedevents = [] for result in query: if result.getRID() in includedevents: break else: includedevents.append(result.getRID()) event = {} # we need to deal with events that end next month if result.end.month() != month: # doesn't work for events that last ~12 months # fix it if it's a problem, otherwise ignore eventEndDay = last_day event['end'] = None else: eventEndDay = result.end.day() event['end'] = result.end.Time() # and events that started last month if result.start.month() != month: # same as above (12 month thing) eventStartDay = 1 event['start'] = None else: eventStartDay = result.start.day() event['start'] = result.start.Time() event['title'] = result.Title or result.getId if eventStartDay != eventEndDay: allEventDays = range(eventStartDay, eventEndDay + 1) eventDays[eventStartDay]['eventslist'].append({ 'end': None, 'start': result.start.Time(), 'title': event['title'] }) eventDays[eventStartDay]['event'] = 1 for eventday in allEventDays[1:-1]: eventDays[eventday]['eventslist'].append({ 'end': None, 'start': None, 'title': event['title'] }) eventDays[eventday]['event'] = 1 if result.end == result.end.earliestTime(): last_day_data = eventDays[allEventDays[-2]] last_days_event = last_day_data['eventslist'][-1] last_days_event['end'] = (result.end - 1).latestTime().Time() else: eventDays[eventEndDay]['eventslist'].append({ 'end': result.end.Time(), 'start': None, 'title': event['title'] }) eventDays[eventEndDay]['event'] = 1 else: eventDays[eventStartDay]['eventslist'].append(event) eventDays[eventStartDay]['event'] = 1 # This list is not uniqued and isn't sorted # uniquing and sorting only wastes time # and in this example we don't need to because # later we are going to do an 'if 2 in eventDays' # so the order is not important. # example: [23, 28, 29, 30, 31, 23] return eventDays security.declarePublic('getEventsForThisDay') def getEventsForThisDay(self, thisDay): """ given an exact day return ALL events that: A) Start on this day OR B) End on this day OR C) Start before this day AND end after this day """ catalog = self.portal_catalog day, month, year = (int(thisDay.day()), int(thisDay.month()), int(thisDay.year())) first_date, last_date = self.getBeginAndEndTimes(day, month, year) zone = first_date.localZone() after_midnight_str = '%d-%02d-%02d 00:01:00 %s' % (year, month, day, zone) after_midnight = DateTime(after_midnight_str) # Get all events that Start on this day query = self.portal_catalog(portal_type=self.getCalendarTypes(), review_state=self.getCalendarStates(), start={ 'query': (first_date, last_date), 'range': 'minmax' }) # Get all events that End on this day query += self.portal_catalog(portal_type=self.getCalendarTypes(), review_state=self.getCalendarStates(), end={ 'query': (after_midnight, last_date), 'range': 'minmax' }) # Get all events that Start before this day AND End after this day query += self.portal_catalog(portal_type=self.getCalendarTypes(), review_state=self.getCalendarStates(), start={ 'query': first_date, 'range': 'max' }, end={ 'query': last_date, 'range': 'min' }) # Unique the results results = [] rids = [] for item in query: rid = item.getRID() if not rid in rids: results.append(item) rids.append(rid) def sort_function(x, y): z = cmp(x.start, y.start) if not z: return cmp(x.end, y.end) return z # Sort by start date results.sort(sort_function) return results security.declarePublic('getPreviousMonth') def getPreviousMonth(self, month, year): """ Get a DateTime object for one month prior to the given year/month """ month = int(month) year = int(year) if month == 0 or month == 1: month, year = 12, year - 1 else: month -= 1 return DateTime(year, month, 1) security.declarePublic('getNextMonth') def getNextMonth(self, month, year): """ Get a DateTime object for one month after the given year/month """ month = int(month) year = int(year) if month == 12: month, year = 1, year + 1 else: month += 1 return DateTime(year, month, 1) security.declarePublic('getBeginAndEndTimes') def getBeginAndEndTimes(self, day, month, year): """ Get two DateTime objects representing the beginning and end of the given day """ day = int(day) month = int(month) year = int(year) begin = DateTime('%d-%02d-%02d 00:00:00' % (year, month, day)) end = DateTime('%d-%02d-%02d 23:59:59' % (year, month, day)) return (begin, end)
import IGroupsPlugin from Products.PluggableAuthService.interfaces.plugins \ import IGroupEnumerationPlugin from Products.PluggableAuthService.permissions import ManageGroups from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin from Products.PluggableAuthService.utils import createViewName from Products.PluggableAuthService.utils import classImplements from Products.PluggableAuthService.utils import postonly class IDynamicGroupsPlugin(Interface): """ Marker interface. """ manage_addDynamicGroupsPluginForm = PageTemplateFile( 'www/dgpAdd', globals(), __name__='manage_addDynamicGroupsPluginForm') def addDynamicGroupsPlugin(dispatcher, id, title='', RESPONSE=None): """ Add a DGP to 'dispatcher'. """ dgp = DynamicGroupsPlugin(id, title) dispatcher._setObject(id, dgp) if RESPONSE is not None: RESPONSE.redirect('%s/manage_main?manage_tabs_messsage=%s' % (dispatcher.absolute_url(), 'DPG+added.')) class DynamicGroupDefinition(SimpleItem, PropertyManager): """ Represent a single dynamic group.
def index_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getContent({'here': self}, 'geopoint_index') security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html') def edit_html(self, REQUEST=None, RESPONSE=None): """ """ if self.hasVersion(): obj = self.version else: obj = self return self.getFormsTool().getContent({'here': obj}, 'geopoint_edit') InitializeClass(NyGeoPoint) manage_addNyGeoPoint_html = PageTemplateFile('zpt/geopoint_manage_add', globals()) manage_addNyGeoPoint_html.kind = config['meta_type'] manage_addNyGeoPoint_html.action = 'addNyGeoPoint' config.update({ 'constructors': (manage_addNyGeoPoint_html, addNyGeoPoint), 'folder_constructors': [ # NyFolder.manage_addNyGeoPoint_html = manage_addNyGeoPoint_html ('manage_addNyGeoPoint_html', manage_addNyGeoPoint_html), ('geopoint_add_html', geopoint_add_html), ('addNyGeoPoint', addNyGeoPoint), ('import_geopoint_item', importNyGeoPoint), ], 'add_method': addNyGeoPoint, 'validation': issubclass(NyGeoPoint, NyValidation), '_class': NyGeoPoint, })
class ModuleVersionStub(SimpleItem, PropertyManager): """Zope object to hold versions of an object""" meta_type = 'Module Version Folder' security = ClassSecurityInfo() __allow_access_to_unprotected_subobjects__ = 1 manage_options = PropertyManager.manage_options + SimpleItem.manage_options # Special 'latest' attribute points to most recent version security.declarePublic('latest') latest = ComputedAttribute(lambda self: self._getModuleVersion('latest'), 1) def __init__(self, id, storage, **kwargs): #Acquisition.__init__(self, id, **kwargs) #self.__name__ = id self.id = id self.storage = storage self._endorsed = False def __getitem__(self, name): version = self._getModuleVersion(name) if not version: raise KeyError, name return version security.declarePublic('getId') def getId(self): """Return my ID""" return self.id security.declarePrivate('_getModuleVersion') def _getModuleVersion(self, version, **kwargs): #self._log("Module %s: retrieving version %s" % (self.id, version), zLOG.INFO) if version == 'latest': return ModuleView(version, self.id, **kwargs).__of__(self) else: versions = [h.version for h in self.aq_parent.getHistory(self.id)] if version in versions: return ModuleView(version, self.id, **kwargs).__of__(self) else: raise KeyError, version security.declarePublic('index_html') def index_html(self): """ Redirect to latest version """ path = self.REQUEST.URL1 + '/latest/' if self.REQUEST.QUERY_STRING: path = path + '?' + self.REQUEST.QUERY_STRING self.REQUEST.RESPONSE.redirect(path, status=301) security.declarePrivate('_log') def _log(self, message, severity): zLOG.LOG("ModuleVersionStub", severity, "%s (%s)" % (message, self.REQUEST['PATH_INFO'])) security.declarePublic('url') def url(self): """Return the canonical URL used to access the latest version""" return self.absolute_url() + '/latest/' def getHistoryCount(self): """Return the number of versions of the object""" return len(self.aq_parent.getHistory(self.id)) # FIXME: These should be in a skin _created = PageTemplateFile('zpt/created', globals()) security.declareProtected('Edit Rhaptos Object', 'postUpdate') def postUpdate(self): """Allow users to post updates over the web""" # GET on this method does nothing if self.REQUEST['REQUEST_METHOD']=="GET": self.REQUEST.RESPONSE.setStatus(204) return if self.REQUEST.has_key('moduleText'): content = self.REQUEST['moduleText'] elif self.REQUEST.has_key('BODY'): content = self.REQUEST['BODY'] else: raise CommitError, "No text provided" try: baseVersion = self.REQUEST['baseVersion'] except KeyError: raise CommitError, "No base version specified" try: message = self.REQUEST['message'] except KeyError: raise CommitError, "No commit message specified" # Checkout latest copy to a temp folder tmp = ModuleEditor('latest').__of__(self) tmp.setState('published') tmp.checkout(self.id) self._log("Checking out working copy of module %s" % self.id, zLOG.BLATHER) # Update module text and validate it file = tmp.getDefaultFile() file.manage_upload(content) results = file.validate() if results: raise CommitError, "Module text not valid: %s" % results else: self.content.publishRevision(tmp, message) # Pretend like we're going to delete the temporary folder so it gets unindexed #tmp.manage_beforeDelete(folder, self) del tmp # If its successful, return nothing self.REQUEST.RESPONSE.setStatus(201) url = self.latest.absolute_url() self.REQUEST.RESPONSE.setHeader('Location', url) return self._created(url=url) # ---- Local role manipulations to allow group memners access security.declarePrivate('_getLocalRoles') def _getLocalRoles(self): """Query the database for the local roles in this workgroup""" # Give all maintainers the 'Maintainer' role dict = {} try: for m in self.latest.maintainers: dict[m] = ['Maintainer'] except IndexError: pass # module couldn't be located, but don't explode return dict __ac_local_roles__ = ComputedAttribute(_getLocalRoles, 1) def manage_addLocalRoles(self, userid, roles, REQUEST=None): """Set local roles for a user.""" pass def manage_setLocalRoles(self, userid, roles, REQUEST=None): """Set local roles for a user.""" pass def manage_delLocalRoles(self, userids, REQUEST=None): """Remove all local roles for a user.""" pass # Set default roles for these permissions security.setPermissionDefault('Edit Rhaptos Object', ('Manager', 'Owner','Maintainer')) security.declareProtected('Edit Rhaptos Object', 'endorse') def endorse(self, REQUEST=None): """Set endorsed to True""" self._endorsed = True if REQUEST is not None: msg = _("You have endorsed the module") getToolByName(self, 'plone_utils').addPortalMessage(msg) REQUEST.RESPONSE.redirect(REQUEST.HTTP_REFERER) security.declareProtected('Edit Rhaptos Object', 'denounce') def denounce(self, REQUEST=None): """Set endorsed to False""" self._endorsed = False if REQUEST is not None: msg = _("You have removed the endorsement from the module") getToolByName(self, 'plone_utils').addPortalMessage(msg) REQUEST.RESPONSE.redirect(REQUEST.HTTP_REFERER) security.declareProtected(View, 'endorsed') def endorsed(self): return getattr(self, '_endorsed', False) security.declareProtected(View, 'canEndorse') def canEndorse(self): # todo: check that module is associated with an open lens pms = getToolByName(self, 'portal_membership') member = pms.getAuthenticatedMember() return member.has_permission('Edit Rhaptos Object', self) security.declareProtected(RATE_MODULE_PERMISSION, 'rate') def rate(self, value, REQUEST=None): """ Register a rate params: value: a non-negative integer not greater than 5 return: nothing """ if (value > 5) or (value < 0): if REQUEST is not None: msg = _("Your rating (%s) is invalid" % value) getToolByName(self, 'plone_utils').addPortalMessage(msg) REQUEST.RESPONSE.redirect(REQUEST.HTTP_REFERER) return # Stop a user from rating twice or more pm = getToolByName(self, 'portal_membership') member = pm.getAuthenticatedMember() adapted = getAdapter(member, IRateable) if adapted.hasRating(self.id): # if REQUEST is not None: # msg = _("You have already rated this module") # getToolByName(self, 'plone_utils').addPortalMessage(msg) # REQUEST.RESPONSE.redirect(REQUEST.HTTP_REFERER) # return current_rating = adapted.getRating(self.id) self.portal_moduledb.sqlDeregisterRating(moduleid=self.id, version=self.latest.version, rating=current_rating) adapted.rate(self.id, value) self.portal_moduledb.sqlRegisterRating(moduleid=self.id, version=self.latest.version, rating=value) notify(ModuleRatedEvent(self)) if REQUEST is not None: msg = _("Your rating has been registered") getToolByName(self, 'plone_utils').addPortalMessage(msg) REQUEST.RESPONSE.redirect(REQUEST.HTTP_REFERER) security.declareProtected(View, 'rating') def rating(self): """ Return the average rating return: the average rating """ res = self.portal_moduledb.sqlGetRating(moduleid=self.id, version=self.latest.version) if not res: return 0.0 totalrating = res[0].totalrating votes = res[0].votes if votes == 0: return 0.0 return round(totalrating * 1.0 / votes, 1) security.declareProtected(View, 'numberOfRatings') def numberOfRatings(self): """ Return the number of times the item was rated """ res = self.portal_moduledb.sqlGetRating(moduleid=self.id, version=self.latest.version) if not res: return 0 return res[0].votes #security.declareProtected('Edit Rhaptos Object', 'setGoogleAnalyticsTrackingCode') security.declarePublic('setGoogleAnalyticsTrackingCode') def setGoogleAnalyticsTrackingCode(self, GoogleAnalyticsTrackingCode): """set the Google Analytics Tracking Code""" self._GoogleAnalyticsTrackingCode = GoogleAnalyticsTrackingCode security.declarePublic('getGoogleAnalyticsTrackingCode') def getGoogleAnalyticsTrackingCode(self): """set the Google Analytics Tracking Code""" if hasattr(self,'_GoogleAnalyticsTrackingCode'): return self._GoogleAnalyticsTrackingCode else: return None
_request_type_bmap = {} def registerRequestType(label, iface): global _request_types registry = list(_request_types) registry.append((label, iface)) _request_types = tuple(registry) _request_type_bmap[iface] = label def listRequestTypesLabels(): return _request_type_bmap.values() manage_addChallengeProtocolChooserForm = PageTemplateFile( 'www/cpcAdd', globals(), __name__='manage_addChallengeProtocolChooserForm') def addChallengeProtocolChooserPlugin(dispatcher, id, title=None, mapping=None, REQUEST=None): """ Add a ChallengeProtocolChooserPlugin to a Pluggable Auth Service. """ cpc = ChallengeProtocolChooser(id, title=title, mapping=mapping) dispatcher._setObject(cpc.getId(), cpc) if REQUEST is not None: REQUEST['RESPONSE'].redirect('%s/manage_workspace' '?manage_tabs_message='
params['restricted'] = 1 return self.getFormsTool().getContent(params, 'pointer_index') elif not obj: params['missing'] = 1 return self.getFormsTool().getContent(params, 'pointer_index') else: return self.getFormsTool().getContent(params, 'pointer_index') security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html') def edit_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getContent({'here': self}, 'pointer_edit') InitializeClass(NyPointer) manage_addNyPointer_html = PageTemplateFile('zpt/pointer_manage_add', globals()) manage_addNyPointer_html.kind = config['meta_type'] manage_addNyPointer_html.action = 'addNyPointer' config.update({ 'constructors': (manage_addNyPointer_html, addNyPointer), 'folder_constructors': [ # NyFolder.manage_addNyPointer_html = manage_addNyPointer_html ('manage_addNyPointer_html', manage_addNyPointer_html), ('pointer_add_html', pointer_add_html), ('addNyPointer', addNyPointer), ('import_pointer_item', importNyPointer), ], 'add_method': addNyPointer, 'validation': issubclass(NyPointer, NyValidation), '_class': NyPointer, })
def version_status(self): version, editable = self._version_status() pt = PageTemplateFile('zpt/version_status', globals()) return pt.__of__(self)(version=version, editable=editable)
class ChallengeProtocolChooser(BasePlugin): """ PAS plugin for choosing challenger protocol based on request """ meta_type = 'Challenge Protocol Chooser Plugin' security = ClassSecurityInfo() manage_options = (({ 'label': 'Mapping', 'action': 'manage_editProtocolMapping' }, ) + BasePlugin.manage_options) def __init__(self, id, title=None, mapping=None): self._id = self.id = id self.title = title self._map = OOBTree() if mapping is not None: self.manage_updateProtocolMapping(mapping=mapping) security.declarePrivate('chooseProtocols') def chooseProtocols(self, request): pas_instance = self._getPAS() plugins = pas_instance._getOb('plugins') sniffers = plugins.listPlugins(IRequestTypeSniffer) for sniffer_id, sniffer in sniffers: request_type = sniffer.sniffRequestType(request) if request_type is not None: return self._getProtocolsFor(request_type) def _getProtocolsFor(self, request_type): label = _request_type_bmap.get(request_type, None) if label is None: return return self._map.get(label, None) def _listProtocols(self): pas_instance = self._getPAS() plugins = pas_instance._getOb('plugins') challengers = plugins.listPlugins(IChallengePlugin) found = [] for challenger_id, challenger in challengers: protocol = getattr(challenger, 'protocol', challenger_id) if protocol not in found: found.append(protocol) return found manage_editProtocolMappingForm = PageTemplateFile( 'www/cpcEdit', globals(), __name__='manage_editProtocolMappingForm') def manage_editProtocolMapping(self, REQUEST=None): """ Edit Protocol Mapping """ info = [] available_protocols = self._listProtocols() request_types = listRequestTypesLabels() request_types.sort() for label in request_types: settings = [] select_any = False info.append({'label': label, 'settings': settings}) protocols = self._map.get(label, None) if not protocols: select_any = True for protocol in available_protocols: selected = False if protocols and protocol in protocols: selected = True settings.append({ 'label': protocol, 'selected': selected, 'value': protocol, }) settings.insert(0, { 'label': '(any)', 'selected': select_any, 'value': '', }) return self.manage_editProtocolMappingForm(info=info, REQUEST=REQUEST) def manage_updateProtocolMapping(self, mapping, REQUEST=None): """ Update mapping of Request Type to Protocols """ for key, value in mapping.items(): value = filter(None, value) if not value: if self._map.has_key(key): del self._map[key] else: self._map[key] = value if REQUEST is not None: REQUEST['RESPONSE'].redirect('%s/manage_editProtocolMapping' '?manage_tabs_message=' 'Protocol+Mappings+Changed.' % self.absolute_url())
def pt_render(self, source=False, extra_context={}): options = extra_context.get('options', {}) options.update(self._extra) extra_context['options'] = options return PageTemplateFile.pt_render(self, source, extra_context)
from App.class_init import default__class_init__ as InitializeClass from BTrees.OOBTree import OOBTree from Products.PageTemplates.PageTemplateFile import PageTemplateFile from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin from Products.PluggableAuthService.interfaces.plugins \ import IAuthenticationPlugin from Products.PluggableAuthService.interfaces.plugins \ import IUserEnumerationPlugin from Products.PluggableAuthService.interfaces.plugins \ import IUserAdderPlugin from Products.PluggableAuthService.permissions import ManageUsers from Products.PluggableAuthService.permissions import SetOwnPassword manage_addZODBUserManagerForm = PageTemplateFile( 'www/zuAdd', globals(), __name__='manage_addZODBUserManagerForm') def addZODBUserManager(dispatcher, id, title=None, REQUEST=None): """ Add a ZODBUserManagern to a Pluggable Auth Service. """ zum = ZODBUserManager(id, title) dispatcher._setObject(zum.getId(), zum) if REQUEST is not None: REQUEST['RESPONSE'].redirect('%s/manage_workspace' '?manage_tabs_message=' 'ZODBUserManager+added.' % dispatcher.absolute_url())
'bigpicture': (0, '', ''), 'del_bigpicture': (0, '', ''), 'resourceurl': (0, '', ''), 'source': (0, '', ''), 'lang': (0, '', '') } DEFAULT_SCHEMA = { 'details': dict(sortorder=100, widget_type='TextArea', label='Details (HTML)', localized=True, tinymce=True), 'expirationdate': dict(sortorder=110, widget_type='Date', label='Expiration date', data_type='date'), 'topitem': dict(sortorder=120, widget_type='Checkbox', label='Top item', data_type='int'), 'resourceurl': dict(sortorder=130, widget_type='String', label='Concerned URL'), 'source': dict(sortorder=140, widget_type='String', label='Source', localized=True), } DEFAULT_SCHEMA.update(NY_CONTENT_BASE_SCHEMA) manage_addNyNews_html = PageTemplateFile('zpt/news_manage_add', globals()) manage_addNyNews_html.kind = METATYPE_OBJECT manage_addNyNews_html.action = 'addNyNews' def news_add_html(self, REQUEST=None, RESPONSE=None): """ """ from Products.NaayaBase.NyContentType import get_schema_helper_for_metatype form_helper = get_schema_helper_for_metatype(self, METATYPE_OBJECT) return self.getFormsTool().getContent({'here': self, 'kind': METATYPE_OBJECT, 'action': 'addNyNews', 'form_helper': form_helper}, 'news_add') def _create_NyNews_object(parent, id, contributor): i = 0 while parent._getOb(id, None): i += 1 id = '%s-%u' % (id, i) ob = NyNews(id, contributor)
class ZODBUserManager(BasePlugin): """ PAS plugin for managing users in the ZODB. """ __implements__ = (IAuthenticationPlugin, IUserEnumerationPlugin, IUserAdderPlugin) meta_type = 'ZODB User Manager' security = ClassSecurityInfo() def __init__(self, id, title=None): self._id = self.id = id self.title = title self._user_passwords = OOBTree() self._login_to_userid = OOBTree() self._userid_to_login = OOBTree() # # IAuthenticationPlugin implementation # security.declarePrivate('authenticateCredentials') def authenticateCredentials(self, credentials): """ See IAuthenticationPlugin. o We expect the credentials to be those returned by ILoginPasswordExtractionPlugin. """ login = credentials.get('login') password = credentials.get('password') if login is None or password is None: return None userid = self._login_to_userid.get(login, login) digested = sha.sha(password).hexdigest() if self._user_passwords.get(userid) == digested: return userid, login return None # # IUserEnumerationPlugin implementation # security.declarePrivate('enumerateUsers') def enumerateUsers(self, id=None, login=None, exact_match=False, sort_by=None, max_results=None, **kw): """ See IUserEnumerationPlugin. """ user_info = [] user_ids = [] plugin_id = self.getId() if isinstance(id, str): id = [id] if isinstance(login, str): login = [login] if exact_match and (id or login): if id: user_ids.extend(id) elif login: user_ids.extend([self._login_to_userid.get(x) for x in login]) if user_ids: user_filter = None else: # Searching user_ids = self.listUserIds() user_filter = _ZODBUserFilter(id, login, **kw) for user_id in user_ids: if self._userid_to_login.get(user_id): e_url = '%s/manage_users' % self.getId() qs = 'user_id=%s' % user_id info = { 'id': user_id, 'login': self._userid_to_login[user_id], 'pluginid': plugin_id, 'editurl': '%s?%s' % (e_url, qs) } if not user_filter or user_filter(info): user_info.append(info) return tuple(user_info) # # IUserAdderPlugin implementation # security.declarePrivate('doAddUser') def doAddUser(self, login, password): try: self.addUser(login, login, password) except KeyError: return False return True # # (notional)IZODBUserManager interface # security.declareProtected(ManageUsers, 'listUserIds') def listUserIds(self): """ -> ( user_id_1, ... user_id_n ) """ return self._user_passwords.keys() security.declareProtected(ManageUsers, 'getUserInfo') def getUserInfo(self, user_id): """ user_id -> {} """ return { 'user_id': user_id, 'login_name': self._userid_to_login[user_id], 'pluginid': self.getId() } security.declareProtected(ManageUsers, 'listUserInfo') def listUserInfo(self): """ -> ( {}, ...{} ) o Return one mapping per user, with the following keys: - 'user_id' - 'login_name' """ return [self.getUserInfo(x) for x in self._user_passwords.keys()] security.declareProtected(ManageUsers, 'getUserIdForLogin') def getUserIdForLogin(self, login_name): """ login_name -> user_id o Raise KeyError if no user exists for the login name. """ return self._login_to_userid[login_name] security.declareProtected(ManageUsers, 'getLoginForUserId') def getLoginForUserId(self, user_id): """ user_id -> login_name o Raise KeyError if no user exists for that ID. """ return self._userid_to_login[user_id] security.declarePrivate('addUser') def addUser(self, user_id, login_name, password): if self._user_passwords.get(user_id) is not None: raise KeyError, 'Duplicate user ID: %s' % user_id if self._login_to_userid.get(login_name) is not None: raise KeyError, 'Duplicate login name: %s' % login_name self._user_passwords[user_id] = sha.sha(password).hexdigest() self._login_to_userid[login_name] = user_id self._userid_to_login[user_id] = login_name security.declarePrivate('removeUser') def removeUser(self, user_id): if self._user_passwords.get(user_id) is None: raise KeyError, 'Invalid user ID: %s' % user_id login_name = self._userid_to_login[user_id] del self._user_passwords[user_id] del self._login_to_userid[login_name] del self._userid_to_login[user_id] security.declarePrivate('updateUserPassword') def updateUserPassword(self, user_id, login_name, password): if self._user_passwords.get(user_id) is None: raise KeyError, 'Invalid user ID: %s' % user_id old_login_name = self._userid_to_login[user_id] if old_login_name != login_name: del self._login_to_userid[old_login_name] self._login_to_userid[login_name] = user_id self._userid_to_login[user_id] = login_name if password: digested = sha.sha(password).hexdigest() self._user_passwords[user_id] = digested # # ZMI # manage_options = (({ 'label': 'Users', 'action': 'manage_users', }, ) + BasePlugin.manage_options) security.declarePublic('manage_widgets') manage_widgets = PageTemplateFile('www/zuWidgets', globals(), __name__='manage_widgets') security.declareProtected(ManageUsers, 'manage_users') manage_users = PageTemplateFile('www/zuUsers', globals(), __name__='manage_users') security.declareProtected(ManageUsers, 'manage_addUser') def manage_addUser(self, user_id, login_name, password, confirm, RESPONSE=None): """ Add a user via the ZMI. """ if password != confirm: message = 'password+and+confirm+do+not+match' else: if not login_name: login_name = user_id # XXX: validate 'user_id', 'login_name' against policies? self.addUser(user_id, login_name, password) message = 'User+added' if RESPONSE is not None: RESPONSE.redirect('%s/manage_users?manage_tabs_message=%s' % (self.absolute_url(), message)) security.declareProtected(ManageUsers, 'manage_updateUserPassword') def manage_updateUserPassword(self, user_id, login_name, password, confirm, RESPONSE=None): """ Update a user's login name / password via the ZMI. """ if password and password != confirm: message = 'password+and+confirm+do+not+match' else: if not login_name: login_name = user_id # XXX: validate 'user_id', 'login_name' against policies? self.updateUserPassword(user_id, login_name, password) message = 'password+updated' if RESPONSE is not None: RESPONSE.redirect('%s/manage_users?manage_tabs_message=%s' % (self.absolute_url(), message)) security.declareProtected(ManageUsers, 'manage_removeUsers') def manage_removeUsers(self, user_ids, RESPONSE=None): """ Remove one or more users via the ZMI. """ user_ids = filter(None, user_ids) if not user_ids: message = 'no+users+selected' else: for user_id in user_ids: self.removeUser(user_id) message = 'Users+removed' if RESPONSE is not None: RESPONSE.redirect('%s/manage_users?manage_tabs_message=%s' % (self.absolute_url(), message)) # # Allow users to change their own login name and password. # security.declareProtected(SetOwnPassword, 'getOwnUserInfo') def getOwnUserInfo(self): """ Return current user's info. """ user_id = getSecurityManager().getUser().getId() return self.getUserInfo(user_id) security.declareProtected(SetOwnPassword, 'manage_updatePasswordForm') manage_updatePasswordForm = PageTemplateFile( 'www/zuPasswd', globals(), __name__='manage_updatePasswordForm') security.declareProtected(SetOwnPassword, 'manage_updatePassword') def manage_updatePassword(self, login_name, password, confirm, RESPONSE=None): """ Update the current user's password and login name. """ user_id = getSecurityManager().getUser().getId() if password != confirm: message = 'password+and+confirm+do+not+match' else: if not login_name: login_name = user_id # XXX: validate 'user_id', 'login_name' against policies? self.updateUserPassword(user_id, login_name, password) message = 'password+updated' if RESPONSE is not None: RESPONSE.redirect('%s/manage_updatePasswordForm' '?manage_tabs_message=%s' % (self.absolute_url(), message))
from edw.circaimport import zexpcopy upload_prefix = None logger = logging.getLogger('edw.circaimport.ui') logger.setLevel(logging.DEBUG) import_all_zpt = PageTemplateFile('zpt/import_all.zpt', globals()) import_files_zpt = PageTemplateFile('zpt/import_files.zpt', globals()) import_files_result_zpt = PageTemplateFile('zpt/import_files_result.zpt', globals()) import_roles_zpt = PageTemplateFile('zpt/import_roles.zpt', globals()) import_notifications_zpt = PageTemplateFile('zpt/import_notifications.zpt', globals()) import_acls_zpt = PageTemplateFile('zpt/import_acls.zpt', globals()) zexpcopy_export_zpt = PageTemplateFile('zpt/zexpcopy/export.zpt', globals()) zexpcopy_import_zpt = PageTemplateFile('zpt/zexpcopy/import.zpt', globals()) zexpcopy_tree_ajax_zpt = PageTemplateFile('zpt/zexpcopy/tree_ajax.zpt', globals()) def init_log_stream(): log = StringIO() handler = logging.StreamHandler(log) handler.setLevel(logging.DEBUG) handler.setFormatter(UIFormatter()) logger.addHandler(handler) return log class UIFormatter(logging.Formatter): color_codes = { 'DEBUG': 'blue', 'INFO': 'green',
class PloneGlossaryTool(PropertyManager, UniqueObject, SimpleItem): """Tool for PloneGlossary""" implements(IGlossaryTool) plone_tool = 1 id = PLONEGLOSSARY_TOOL title = 'PloneGlossaryTool' meta_type = 'PloneGlossaryTool' _properties = ({'id': 'title', 'type': 'string', 'mode': 'w'}, ) _actions = () manage_options = (PropertyManager.manage_options + SimpleItem.manage_options + ({ 'label': 'Migrate', 'action': 'manage_migration' }, )) security = ClassSecurityInfo() security.declareProtected(CMFCorePermissions.ManagePortal, 'manage_migration') manage_migration = PageTemplateFile('manage_migration', _zmi) # # # Migrations management # # # security.declareProtected(CMFCorePermissions.ManagePortal, 'manage_migrate') def manage_migrate(self, REQUEST=None): """Migration script""" request = self.REQUEST options = {} options['dry_run'] = 0 options['meta_type'] = 0 stdout = StringIO.StringIO() if request is not None: options['dry_run'] = request.get('dry_run', 0) options['meta_type'] = request.get('meta_type', 'PloneGlossary') Migrator().migrate(self, stdout, options) if request is not None: message = "Migration completed." logs = stdout.getvalue() logs = '<br />'.join(logs.split('\r\n')) return self.manage_migration(self, manage_tabs_message=message, logs=logs) security.declareProtected(CMFCorePermissions.ManagePortal, 'initProperties') def initProperties(self): """Init properties""" self.safeEditProperty(self, 'highlight_content', 1, data_type='boolean') self.safeEditProperty(self, 'use_general_glossaries', 1, data_type='boolean') self.safeEditProperty(self, 'general_glossary_uids', 'getGlossaryUIDs', data_type='multiple selection', new_value=[]) self.safeEditProperty(self, 'allowed_portal_types', 'getAvailablePortalTypes', data_type='multiple selection', new_value=['PloneGlossaryDefinition']) self.safeEditProperty(self, 'description_length', 0, data_type='int') self.safeEditProperty(self, 'description_ellipsis', '...', data_type='string') self.safeEditProperty(self, 'not_highlighted_tags', ['a', 'h1', 'input', 'textarea'], data_type='lines') self.safeEditProperty(self, 'available_glossary_metatypes', (), data_type='lines') self.safeEditProperty(self, 'glossary_metatypes', 'getAvailableGlossaryMetaTypes', data_type='multiple selection', new_value=['PloneGlossary']) security.declarePrivate('safeEditProperty') def safeEditProperty(self, obj, key, value, data_type='string', new_value=None): """ An add or edit function, surprisingly useful :) """ if obj.hasProperty(key): for property in self._properties: if property['id'] == key: property['data_type'] = data_type if data_type in ('selection', 'multiple selection'): property['select_variable'] = value break else: obj._setProperty(key, value, data_type) if new_value is not None: obj._updateProperty(key, new_value) security.declarePublic('getAvailablePortalTypes') def getAvailablePortalTypes(self): """Returns available portal types""" plone_tools = getMultiAdapter((self, self.REQUEST), name='plone_tools') portal_types = plone_tools.types() return portal_types.listContentTypes() security.declarePublic('getAvailableGlossaryMetaTypes') def getAvailableGlossaryMetaTypes(self): """ Returns available glossary portal types """ return self.available_glossary_metatypes security.declarePublic('getAllowedPortalTypes') def getAllowedPortalTypes(self): """Returns allowed portal types. Allowed portal types can be highlighted.""" return self.allowed_portal_types security.declarePublic('getUseGeneralGlossaries') def getUseGeneralGlossaries(self): """Returns use_general_glossaries """ if not hasattr(self, 'use_general_glossaries'): self.safeEditProperty(self, 'use_general_glossaries', 1, data_type='boolean') return self.use_general_glossaries security.declarePublic('showPortlet') def showPortlet(self): """Returns true if you want to show glosssary portlet""" return True #return self.show_portlet security.declarePublic('highlightContent') def highlightContent(self, obj): """Returns true if content must be highlighted""" portal_type = obj.getTypeInfo().getId() allowed_portal_types = self.getAllowedPortalTypes() if allowed_portal_types and portal_type not in allowed_portal_types: return False return self.highlight_content security.declarePublic('getUsedGlossaryUIDs') def getUsedGlossaryUIDs(self, obj): """Helper method for the portlet Page Template. Fetches the general or local glossary uids depending on the settings in the glossary tool. """ if self.getUseGeneralGlossaries(): return self.getGeneralGlossaryUIDs() else: return self.getLocalGlossaryUIDs(obj) security.declarePublic('getLocalGlossaryUIDs') def getLocalGlossaryUIDs(self, context): """Returns glossary UIDs used to highlight content in the context of the current object. This method traverses upwards in the navigational tree in search for the neares glossary. This neares glossary is then returned """ plone_tools = getMultiAdapter((context, context.REQUEST), name='plone_tools') portal = plone_tools.url().getPortalObject() portal_path = portal.getPhysicalPath() if context.getPhysicalPath() == portal_path: parent = context else: parent = context.aq_inner.aq_parent glossaries = [] proceed = True while proceed: # check for a glossary in this parent glossaries = [] for o in parent.contentValues(): if o.portal_type in self.glossary_metatypes: glossaries.append(o.UID()) if glossaries: # we found one or more glossaries break # move upwards if parent.getPhysicalPath() == portal_path: proceed = False parent = parent.aq_inner.aq_parent return glossaries security.declarePublic('getGeneralGlossaryUIDs') def getGeneralGlossaryUIDs(self): """Returns glossary UIDs used to highlight content""" if self.general_glossary_uids: return self.general_glossary_uids else: return self.getGlossaryUIDs() security.declarePublic('getGeneralGlossaries') def getGeneralGlossaries(self): """Returns glossaries used to highlight content""" general_glossary_uids = self.getGeneralGlossaryUIDs() return self.getGlossaries(general_glossary_uids) security.declarePublic('getGlossaryUIDs') def getGlossaryUIDs(self): """Returns glossary UIDs defined on portal""" uid_cat = getToolByName(self, 'uid_catalog') brains = uid_cat(portal_type=self.glossary_metatypes) return tuple([x.UID for x in brains]) security.declarePublic('getGlossaries') def getGlossaries(self, glossary_uids=None): """Returns glossaries defined on portal""" glossaries = [] uid_cat = getToolByName(self, 'uid_catalog') plone_tools = getMultiAdapter((self, self.REQUEST), name='plone_tools') mbtool = plone_tools.membership() kwargs = {} if glossary_uids is not None: kwargs['UID'] = glossary_uids brains = uid_cat(portal_type=self.glossary_metatypes, **kwargs) for brain in brains: obj = brain.getObject() if obj is None: continue # Check view permission has_view_permission = mbtool.checkPermission( CMFCorePermissions.View, obj) and mbtool.checkPermission( CMFCorePermissions.AccessContentsInformation, obj) if has_view_permission: glossaries.append(obj) return tuple(glossaries) # Make it private because this method doesn't check term security def _getGlossaryTermItems(self, glossary_uids): """Returns glossary terms as a list of dictionaries Item: - path -> term path - id -> term id - title -> term title - variants -> term variants - description -> term description - url -> term url @param glossary_uids: uids of glossary where we get terms """ # Get glossaries glossaries = self.getGlossaries(glossary_uids) if not glossaries: return [] # Get items items = [] for glossary in glossaries: new_items = glossary._getGlossaryTermItems() items.extend(new_items) return tuple(items) security.declarePublic('getGlossaryTermItems') def getGlossaryTermItems(self, glossary_uids): """Returns the same list as _getGlossaryTermItems but check security. @param glossary_uids: Uids of glossary where we get term items""" # Get glossaries term items not_secured_term_items = self._getGlossaryTermItems(glossary_uids) # Walk into each catalog of glossaries and get terms plone_tools = getMultiAdapter((self, self.REQUEST), name='plone_tools') utool = plone_tools.url() portal_object = utool.getPortalObject() term_items = [] for item in not_secured_term_items: path = item['path'] try: obj = portal_object.restrictedTraverse(path) except: continue term_items.append(item) return term_items security.declarePublic('getGlossaryTerms') def getGlossaryTerms(self, glossary_uids): """Returns term titles stored in glossaries. @param glossary_uids: Uids of glossary where we get term items""" # Get glossaries term items term_items = self.getGlossaryTermItems(glossary_uids) # Returns titles return [x['title'] for x in term_items] def _getObjectText(self, obj): """Returns all text of an object. If object is an AT content, get schema and returns all text fields. Otherwise returns SearchableText. @param obj: Content to analyse""" text = '' if hasattr(aq_base(obj), 'SearchableText'): text = obj.SearchableText() elif hasattr(aq_base(obj), 'Schema'): schema = obj.Schema() data = [] # Loop on fields for field in schema.fields(): if field.type in ( 'string', 'text', ): method = field.getAccessor(obj) if method is None: continue # Get text/plain content try: datum = method(mimetype="text/plain") except TypeError: # retry in case typeerror was raised because accessor doesn't # handle the mimetype argument try: datum = method() except ConflictError: raise except: continue # Make sure value is a string if type(datum) == type(''): data.append(datum) text = ' '.join(data) return text def _getTextRelatedTermItems(self, text, glossary_term_items, excluded_terms=()): """ @param text: charset encoded text @param excluded_terms: charset encoded terms to exclude from search """ utext = text.decode(SITE_CHARSET, "replace") usplitted_text_terms = self._split(utext) atext = encode_ascii(utext) aexcluded_terms = [ encode_ascii(t.decode(SITE_CHARSET, "replace")) for t in excluded_terms ] result = [] # Search glossary terms in text analyzed_terms = [] for item in glossary_term_items: # Take into account the word and its variants terms = [] item_title = item['title'] item_variants = item['variants'] if type(item_title) == type(''): terms.append(item_title) if type(item_variants) in ( type([]), type(()), ): terms.extend(item_variants) # Loop on glossary terms and intersect with object terms for term in terms: if term in analyzed_terms: continue # Analyze term analyzed_terms.append(term) uterm = term.decode(SITE_CHARSET, "replace") aterm = encode_ascii(uterm) if aterm in aexcluded_terms: continue # Search the word in the text found_pos = find_word(aterm, atext) if not found_pos: continue # Extract terms from obj text term_length = len(aterm) text_terms = [] for pos in found_pos: utext_term = utext[pos:(pos + term_length)] # FIX ME: Workaround for composed words. Works in 99% # Check the word is not a subword but a real word composing the text if not [ x for x in self._split(utext_term) if x in usplitted_text_terms ]: continue # Encode the term and make sure there are no doublons text_term = utext_term.encode(SITE_CHARSET, "replace") if text_term in text_terms: continue text_terms.append(text_term) if not text_terms: continue # Append object term item new_item = item.copy() new_item['terms'] = text_terms result.append(new_item) return result # Make it private because this method doesn't check term security def _getObjectRelatedTermItems(self, obj, glossary_term_items): """Returns object terms in a specific structure Item: - terms -> object terms - path -> term path - id -> term id - title -> term title - variants -> term variants - description -> term description - url -> term url @param obj: object to analyse @param glossary_term_items: Glossary term items to check in the object text Variables starting with a are supposed to be in ASCII Variables starting with u are supposed to be in Unicode """ # Get obj properties ptype = obj.portal_type title = obj.title_or_id() text = self._getObjectText(obj) # Words to remove from terms to avoid recursion # For example, on a glossary definition itself, it makes no sense to # underline the defined word. removed_words = () if ptype in ('PloneGlossaryDefinition', ): removed_words = (title, ) return self._getTextRelatedTermItems( text, glossary_term_items, removed_words, ) security.declarePublic('getObjectRelatedTermItems') def getObjectRelatedTermItems(self, obj, glossary_term_items, alpha_sort=False): """Returns the same list as _getObjectRelatedTermItems but check security. @param obj: object to analyse @param glossary_term_items: Glossary term items to check in the object text @param alpha_sort: if True, returned items are sorted by title, asc""" # Get glossaries term items not_secured_term_items = self._getObjectRelatedTermItems( obj, glossary_term_items) # Walk into each catalog of glossaries and get terms plone_tools = getMultiAdapter((self, self.REQUEST), name='plone_tools') utool = plone_tools.url() portal_object = utool.getPortalObject() term_items = [] for item in not_secured_term_items: path = item['path'] try: obj = portal_object.restrictedTraverse(path) except: continue term_items.append(item) if alpha_sort: def glossary_cmp(o1, o2): return cmp(o1.get('title', ''), o2.get('title', '')) term_items.sort(glossary_cmp) return term_items security.declarePublic('getObjectRelatedTerms') def getObjectRelatedTerms(self, obj, glossary_uids, alpha_sort=False): """Returns glossary term titles found in object @param obj: Content to analyse and extract related glossary terms @param glossary_uids: if None tool will search all glossaries @param alpha_sort: if True, returned items are sorted by title, asc """ # Get term definitions found in obj definitions = self.getObjectRelatedDefinitions(obj, glossary_uids, alpha_sort=False) # Returns titles return [x['title'] for x in definitions] security.declarePublic('getObjectRelatedDefinitions') def getObjectRelatedDefinitions(self, obj, glossary_uids, alpha_sort=False): """Returns object term definitions get from glossaries. definition : - terms -> exact words in obj text - id -> term id - path -> term path - title -> term title - variants -> term variants - description -> term definitions - url -> term url @param obj: Content to analyse and extract related glossary terms @param glossary_uids: if None tool will search all glossaries @param alpha_sort: if True, returned items are sorted by title, asc """ # Get glossary term items from the glossary # All terms are loaded in the memory as a list of dictionaries if not glossary_uids: return [] glossary_term_items = self._getGlossaryTermItems(glossary_uids) marked_definitions = [] urls = {} # Search related definitions in glossary definitions for definition in self.getObjectRelatedTermItems( obj, glossary_term_items, alpha_sort): if urls.has_key(definition['url']): # The glossary item is already going to be shown definition['show'] = 0 else: # The glossary item is going to be shown urls[definition['url']] = 1 definition['show'] = 1 marked_definitions.append(definition) return marked_definitions security.declarePublic('getDefinitionsForUI') @memoize_diy_request(arg=2) def getDefinitionsForUI(self, context, request): """Provides UI friendly definitions for the context item""" # LOG.debug("Running PloneGlossaryTool.getDefinitionsForUi") glossary_uids = self.getUsedGlossaryUIDs(context) if len(glossary_uids) == 0: glossary_uids = None return self.getObjectRelatedDefinitions(context, glossary_uids) security.declarePublic('searchResults') def searchResults(self, glossary_uids, **search_args): """Returns brains from glossaries. glossary_uids: UIDs of glossaries where to search. search_args: Use index of portal_catalog.""" # Get path of glossaries glossaries = self.getGlossaries(glossary_uids) paths = ['/'.join(x.getPhysicalPath()) for x in glossaries] plone_tools = getMultiAdapter((self, self.REQUEST), name='plone_tools') ctool = plone_tools.catalog() definitions_metatypes = self._getDefinitionsMetaTypes(glossaries) return ctool.searchResults(path=paths, portal_type=definitions_metatypes, **search_args) def _getDefinitionsMetaTypes(self, glossaries): """ get glossary definitions metatypes using glossaries list """ metatypes = [] for glossary in glossaries: glossary_def_mts = [deftype \ for deftype in glossary.definition_types\ if deftype not in metatypes] metatypes.extend(glossary_def_mts) return metatypes security.declarePublic('getAsciiLetters') def getAsciiLetters(self): """Returns list of ascii letters in lower case""" return tuple([chr(x) for x in range(97, 123)]) security.declarePublic('getAbcedaire') def getAbcedaire(self, glossary_uids): """Returns abcedaire. glossary_uids: UIDs of glossaries used to build abcedaire""" terms = self.getGlossaryTerms(glossary_uids) letters = [] for term in terms: letter = term[0:1].lower() if letter not in letters: letters.append(letter) # Sort alphabetically letters.sort() return tuple(letters) security.declarePublic('getAbcedaireBrains') def getAbcedaireBrains(self, glossary_uids, letters): """Returns brains from portal_catalog. glossary_uids: UIDs of glossaries used to build abcedaire. letters: beginning letters of terms to search""" abcedaire_brains = [] brains = self.searchResults(glossary_uids) for brain in brains: letter = brain.Title[0:1].lower() if letter in letters: abcedaire_brains.append(brain) # Sort alphabetically def cmp_alpha(a, b): return cmp(a.Title, b.Title) abcedaire_brains.sort(cmp_alpha) return abcedaire_brains security.declarePublic('truncateDescription') def truncateDescription(self, text): """Truncate definition using tool properties""" max_length = self.description_length text = text.decode(SITE_CHARSET, "replace") text = text.strip() if max_length > 0 and len(text) > max_length: ellipsis = self.description_ellipsis text = text[:max_length] text = text.strip() text = '%s %s' % (text, ellipsis) text = text.encode(SITE_CHARSET, "replace") return text security.declarePublic('escape') def escape(self, text): """Returns escaped text.""" return escape_special_chars(text) def _split(self, text, removed_words=()): """Split unicode text into tuple of unicode terms @param text: unicode text to split @param remove_words: words to remove from the split result""" return tuple([ x for x in text2words(text) if len(x) > 1 and x not in removed_words ])
def manage_customizeTemplate(self, name, REQUEST=None): """ customize the email template called `name` """ ob_id = 'emailpt_%s' % name manage_addEmailPageTemplate(self, ob_id, email_templates[name]._text) ob = self._getOb(ob_id) if REQUEST is not None: REQUEST.RESPONSE.redirect(ob.absolute_url() + '/manage_workspace') else: return ob_id security.declareProtected(view_management_screens, 'manage_main') manage_main = folder_manage_main_plus security.declareProtected(view_management_screens, 'ny_after_listing') ny_after_listing = PageTemplateFile('zpt/customize_emailpt', globals()) ny_after_listing.email_templates = email_templates security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'download') def download(self, REQUEST=None, RESPONSE=None): """returns all the subscriptions in a csv file""" header = ['User', 'Location', 'Notification type', 'Language'] rows = [] for s in self.admin_get_subscriptions(): row = [] row.append(s['user']) if (s['location']): row.append(s['location']) else:
$Id$ """ import os from AccessControl.class_init import InitializeClass from AccessControl.SecurityInfo import ClassSecurityInfo from App.Common import package_home from OFS.SimpleItem import SimpleItem from Products.PageTemplates.PageTemplateFile import PageTemplateFile from ZODB.POSException import ConflictError _wwwdir = os.path.join(package_home(globals()), 'www') manage_addFSDumpForm = PageTemplateFile('www/addDumper', globals()) USE_DUMPER_PERMISSION = 'Use Dumper' def manage_addFSDump(self, id, fspath=None, use_metadata_file=0, REQUEST=None): """Add a Dumper object to the system """ dumper = Dumper() dumper.id = id dumper.edit(fspath, use_metadata_file) self._setObject(id, dumper) if REQUEST is not None: REQUEST['RESPONSE'].redirect('manage_main')
DESCRIPTION_OBJECT = 'This is Naaya URL type.' PREFIX_OBJECT = 'url' PROPERTIES_OBJECT = { 'id': (0, '', ''), 'title': (1, MUST_BE_NONEMPTY, 'The Title field must have a value.'), 'description': (0, '', ''), 'coverage': (0, '', ''), 'keywords': (0, '', ''), 'sortorder': (0, MUST_BE_POSITIV_INT, 'The Sort order field must contain a positive integer.'), 'releasedate': (0, MUST_BE_DATETIME, 'The Release date field must contain a valid date.'), 'discussion': (0, '', ''), 'locator': (0, '', ''), 'lang': (0, '', '') } manage_addNyURL_html = PageTemplateFile('zpt/url_manage_add', globals()) manage_addNyURL_html.kind = METATYPE_OBJECT manage_addNyURL_html.action = 'addNyURL' def url_add_html(self, REQUEST=None, RESPONSE=None): """ """ return self.getFormsTool().getContent({'here': self, 'kind': METATYPE_OBJECT, 'action': 'addNyURL'}, 'url_add') def addNyURL(self, id='', title='', description='', coverage='', keywords='', sortorder='', locator='', contributor=None, releasedate='', discussion='', lang=None, REQUEST=None, **kwargs): """ Create an URL type of object. """ #process parameters id = self.utCleanupId(id)
class Dumper(SimpleItem): """ """ meta_type = 'Dumper' manage_options = ({ 'label': 'Edit', 'action': 'editForm', 'help': ('FSDump', 'Dumper_editForm.stx') }, { 'label': 'Security', 'action': 'manage_access', 'help': ('OFSP', 'Security_Define-Permissions.stx') }) security = ClassSecurityInfo() fspath = None use_metadata_file = 0 # # Management interface methods. # index_html = None security.declareProtected(USE_DUMPER_PERMISSION, 'editForm') editForm = PageTemplateFile('www/editDumper', globals()) @security.protected(USE_DUMPER_PERMISSION) def edit(self, fspath, use_metadata_file, REQUEST=None): """ Update the path to which we will dump our peers. """ self._setFSPath(fspath) self.use_metadata_file = use_metadata_file if REQUEST is not None: REQUEST['RESPONSE'].redirect( self.absolute_url() + '/editForm' + '?manage_tabs_message=Dumper+updated.') @security.protected(USE_DUMPER_PERMISSION) def dumpToFS(self, REQUEST=None): """ Iterate recursively over our peers, creating simulacra of them on the filesystem in 'fspath' """ if REQUEST and 'fspath' in REQUEST.form: self._setFSPath(REQUEST.form['fspath']) parent = self.aq_parent.aq_base if getattr(parent, 'isTopLevelPrincipiaApplicationObject', 0): self._dumpRoot(self.aq_parent) else: self._dumpFolder(self.aq_parent) if REQUEST is not None: REQUEST['RESPONSE'].redirect(self.absolute_url() + '/editForm' + '?manage_tabs_message=Peers+dumped.') # # Utility methods # @security.private def _setFSPath(self, fspath): # Canonicalize fspath. fspath = os.path.normpath(fspath) if not os.path.isabs(fspath): raise RunTimeError('Dumper Error: path must be absolute.') self.fspath = fspath @security.private def _buildPathString(self, path=None): # Construct a path string, relative to self.fspath. if self.fspath is None: raise RunTimeError('Dumper Error: Path not set.') if path is None: path = self.fspath else: path = os.path.normpath(os.path.join(self.fspath, path)) return path @security.private def _checkFSPath(self, path=None): # Ensure that fspath/path exists. path = self._buildPathString(path) if not os.path.exists(path): os.makedirs(path) return path @security.private def _createFile(self, path, filename, mode='w'): # Create/replace file; return the file object. fullpath = "%s/%s" % (self._checkFSPath(path), filename) return open(fullpath, mode) @security.private def _createMetadataFile(self, path, filename, mode='w'): # Create/replace file; return the file object. extension = self.use_metadata_file and 'metadata' or 'properties' fullpath = "%s/%s.%s" % (self._checkFSPath(path), filename, extension) file = open(fullpath, mode) if self.use_metadata_file: file.write("[default]\n") else: file.write("[Default]\n") return file @security.private def _dumpObject(self, object, path=None): # Dump one item, using path as prefix. try: handler = self._handlers.get(object.meta_type, None) if handler is not None: handler(self, object, path) return 1 except ConflictError: raise except: return -1 return 0 @security.private def _dumpObjects(self, objects, path=None): # Dump each item, using path as prefix. dumped = [] for object in objects: if self._dumpObject(object, path) > 0: id = object.id if callable(id): id = id() dumped.append((id, object.meta_type)) return dumped @security.private def _writeProperties(self, obj, file): propIDs = obj.propertyIds() propIDs.sort() # help diff out :) for propID in propIDs: type = obj.getPropertyType(propID) value = obj.getProperty(propID) if self.use_metadata_file and type == 'string': file.write('%s=%s\n' % (propID, value)) else: file.write('%s:%s=%s\n' % (propID, type, value)) # # Type-specific dumpers # @security.private def _dumpRoot(self, obj): self._dumpObjects(obj.objectValues()) @security.private def _dumpFolder(self, obj, path=None): # Recurse to dump items in a folder. if path is None: path = '' path = os.path.join(path, obj.id) file = self._createMetadataFile(path, '') self._writeProperties(obj, file) dumped = self._dumpObjects(obj.objectValues(), path) dumped.sort() # help diff out :) if self.use_metadata_file: file.write("\n[Objects]\n") else: file.close() file = self._createFile(path, '.objects') for id, meta in dumped: file.write('%s:%s\n' % (id, meta)) file.close() @security.private def _dumpDTML(self, obj, path=None, suffix='dtml'): # Dump obj (assumed to be a DTML Method/Document) to the # filesystem as a file, appending 'suffix' to the name. peer_id = obj.id() file = self._createFile(path, '%s.%s' % (peer_id, suffix)) text = obj.raw if text[-1] != '\n': text = '%s\n' % text file.write(text) file.close() @security.private def _dumpSecurityInfo(self, obj, file): if getattr(obj.aq_base, '_proxy_roles', None): file.write('proxy=%s\n' % ','.join(obj._proxy_roles)) security_header_written = 0 valid_roles = obj.valid_roles() for perm_dict in obj.permission_settings(): perm_name = perm_dict['name'] acquire = (perm_dict['acquire'] and 1) or 0 roles = [] for role_idx in range(len(valid_roles)): if perm_dict['roles'][role_idx]['checked']: roles.append(valid_roles[role_idx]) if roles or (acquire == 0): if not security_header_written: security_header_written = 1 file.write('\n[security]\n') file.write('%s=%d:%s\n' % (perm_name, acquire, ','.join(roles))) @security.private def _dumpDTMLMethod(self, obj, path=None): # Dump properties of obj (assumed to be a DTML Method) to the # filesystem as a file, with the accompanyting properties file. self._dumpDTML(obj, path) file = self._createMetadataFile(path, '%s.dtml' % obj.id()) if self.use_metadata_file: file.write('title=%s\n' % obj.title) self._dumpSecurityInfo(obj, file) else: file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpZWikiPage(self, obj, path=None, suffix='zwiki'): peer_id = obj.id() file = self._createFile(path, '%s.%s' % (peer_id, suffix)) text = obj.text() if text[-1] != '\n': text = '%s\n' % text file.write(text) file.close() if self.use_metadata_file: file = self._createMetadataFile(path, '%s.%s' % (peer_id, suffix)) self._writeProperties(obj, file) self._dumpSecurityInfo(obj, file) file.close() @security.private def _dumpDTMLDocument(self, obj, path=None): # Dump properties of obj (assumed to be a DTML Document) to the # filesystem as a file, with the accompanyting properties file. self._dumpDTML(obj, path) file = self._createMetadataFile(path, '%s.dtml' % obj.id()) self._writeProperties(obj, file) file.close() @security.private def _dumpExternalMethod(self, obj, path=None): # Dump properties of obj (assumed to be an Externa Method) to the # filesystem as a file. file = self._createMetadataFile(path, '%s.em' % obj.id) if self.use_metadata_file: file.write('title=%s\n' % obj.title) file.write('module=%s\n' % obj._module) file.write('function=%s\n' % obj._function) self._dumpSecurityInfo(obj, file) else: file.write('title:string=%s\n' % obj.title) file.write('module:string=%s\n' % obj._module) file.write('function:string=%s\n' % obj._function) file.close() @security.private def _dumpFileOrImage(self, obj, path=None): # Dump properties of obj (assumed to be an Externa Method) to the # filesystem as a file, with the accompanyting properties file. file = self._createMetadataFile(path, '%s' % obj.id()) if self.use_metadata_file: file.write('title=%s\n' % obj.title) file.write('content_type=%s\n' % obj.content_type) file.write('precondition=%s\n' % obj.precondition) else: file.write('title:string=%s\n' % obj.title) file.write('content_type:string=%s\n' % obj.content_type) file.write('precondition:string=%s\n' % obj.precondition) file.close() file = self._createFile(path, obj.id(), 'wb') data = obj.data if type(data) == type(''): file.write(data) else: while data is not None: file.write(data.data) data = data.next file.close() @security.private def _dumpPythonMethod(self, obj, path=None): # Dump properties of obj (assumed to be a Python Method) to the # filesystem as a file, with the accompanyting properties file. body_lines = obj._body.split('\n') body = '\n '.join(body_lines) text = "def %s(%s)\n\n %s" % (obj.id, obj._params, body) if text[-1] != '\n': text = '%s\n' % text file = self._createFile(path, '%s.py' % obj.id) file.write(text) file.close() file = self._createMetadataFile(path, '%s.py' % obj.id) if self.use_metadata_file: file.write('title=%s\n' % obj.title) self._dumpSecurityInfo(obj, file) else: file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpPythonScript(self, obj, path=None): # Dump properties of obj (assumed to be a Python Script) to the # filesystem as a file, with the accompanyting properties file. file = self._createFile(path, '%s.py' % obj.id) file.write(obj.read()) file.close() file = self._createMetadataFile(path, '%s.py' % obj.id) if self.use_metadata_file: file.write('title=%s\n' % obj.title) self._dumpSecurityInfo(obj, file) else: file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpControllerPythonScript(self, obj, path=None): # Dump properties of obj (assumed to be a Python Script) to the # filesystem as a file, with the accompanyting properties file. file = self._createFile(path, '%s.cpy' % obj.id) file.write(obj.read()) file.close() file = self._createMetadataFile(path, '%s.cpy' % obj.id) file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpValidatorScript(self, obj, path=None): # Dump properties of obj (assumed to be a Controller Validator) to the # filesystem as a file, with the accompanyting properties file. file = self._createFile(path, '%s.vpy' % obj.id) file.write(obj.read()) file.close() file = self._createMetadataFile(path, '%s.vpy' % obj.id) file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpControllerPageTemplate(self, obj, path=None): # Dump properties of obj (assumed to be a ZopeControllerPageTemplate) to the # filesystem as a file, with the accompanyting properties file. file = self._createFile(path, '%s.cpt' % obj.id) file.write(obj.read()) file.close() file = self._createMetadataFile(path, '%s.cpt' % obj.id) file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpPageTemplate(self, obj, path=None): # Dump properties of obj (assumed to be a ZopePageTemplate) to the # filesystem as a file, with the accompanyting properties file. file = self._createFile(path, '%s.pt' % obj.id) file.write(obj.read()) file.close() file = self._createMetadataFile(path, '%s.pt' % obj.id) if self.use_metadata_file: file.write('title=%s\n' % obj.title) self._dumpSecurityInfo(obj, file) else: file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpSQLMethod(self, obj, path=None): # Dump properties of obj (assumed to be a SQL Method) to the # filesystem as a file, with the accompanyting properties file. file = self._createFile(path, '%s.zsql' % obj.id) text = "%s" % obj.src file.write(' <dtml-comment>\n') file.write('title:%s\n' % obj.title) file.write('arguments: %s\n' % ' '.join(obj.arguments_src.splitlines())) file.write('connection_id:%s\n' % obj.connection_id) file.write('max_rows:%s\n' % obj.max_rows_) file.write('max_cache:%s\n' % obj.max_cache_) file.write('cache_time:%s\n' % obj.cache_time_) file.write('class_name:%s\n' % obj.class_name_) file.write('class_file:%s\n' % obj.class_file_) file.write('</dtml-comment>\n') if text[-1] != '\n': text = '%s\n' % text file.write(text) file.close() @security.private def _dumpZCatalog(self, obj, path=None): # Dump properties of obj (assumed to be a ZCatalog) to the # filesystem as a file, with the accompanyting properties file. file = self._createFile(path, '%s.catalog' % obj.id) for brain in obj.searchResults(): file.write('%s\n' % obj.getpath(brain.data_record_id_)) file.close() file = self._createMetadataFile(path, '%s' % obj.id) file.write('title:string=%s\n' % obj.title) file.write('vocab_id:string=%s\n' % obj.vocab_id) file.write('threshold:int=%s\n' % obj.threshold) file.close() file = self._createFile(path, '%s.indexes' % obj.id) for index in obj.index_objects(): file.write('%s:%s\n' % (index.id, index.meta_type)) file.close() file = self._createFile(path, '%s.metadata' % obj.id) for column in obj.schema(): file.write('%s\n' % column) file.close() @security.private def _dumpZClass(self, obj, path=None): # Dump properties of obj (assumed to be a ZClass) to the # filesystem as a directory, including propertysheets and # methods, as well as any nested ZClasses. if path is None: path = '' path = os.path.join(path, obj.id) file = self._createMetadataFile(path, '') file.write('title:string=%s\n' % obj.title) file.write('metatype:string=%s\n' % obj._zclass_.meta_type) file.write('bases:tokens=%s\n' % ','.join(map(lambda klass: str(klass), obj._zbases))) file.write('class_id:int=%s\n' % obj._zclass_.__module__) file.close() # Dump icon file = self._createFile(path, '.icon', 'wb') img = obj._zclass_.ziconImage data = img.data if type(data) == type(''): file.write(data) else: while data is not None: file.write(data.data) data = data.next file.close() # Dump views file = self._createFile(path, '.views') for view in obj.propertysheets.views.data(): file.write('%s:%s\n' % (view['label'], view['action'])) file.close() # Dump property sheets. sheetpath = os.path.join(path, 'propertysheets', 'common') sheets = self._dumpObjects(obj.propertysheets.common.objectValues(), sheetpath) sheets.sort() # help diff out :) file = self._createFile(sheetpath, '.objects') for id, meta in sheets: file.write('%s:%s\n' % (id, meta)) file.close() # Dump methods methodpath = os.path.join(path, 'propertysheets', 'methods') methods = self._dumpObjects(obj.propertysheets.methods.objectValues(), methodpath) methods.sort() # help diff out :) file = self._createFile(methodpath, '.objects') for id, meta in methods: file.write('%s:%s\n' % (id, meta)) file.close() @security.private def _dumpZClassPropertySheet(self, obj, path=None): # Dump properties of obj (assumed to be a ZClass) to the # filesystem as a directory, including propertysheets and # methods, as well as any nested ZClasses. file = self._createFile(path, obj.id) self._writeProperties(obj, file) file.close() file = self._createMetadataFile(path, obj.id) file.write('title:string=%s\n' % obj.title) file.close() @security.private def _dumpPermission(self, obj, path=None): # Dump properties of obj (assumed to be a Zope Permission) to the # filesystem as a .properties file. file = self._createMetadataFile(path, obj.id) file.write('title:string=%s\n' % obj.title) file.write('name:string=%s\n' % obj.name) file.close() @security.private def _dumpFactory(self, obj, path=None): # Dump properties of obj (assumed to be a Zope Factory) to the # filesystem as a .properties file. file = self._createMetadataFile(path, obj.id) file.write('title:string=%s\n' % obj.title) file.write('object_type:string=%s\n' % obj.object_type) file.write('initial:string=%s\n' % obj.initial) file.write('permission:string=%s\n' % obj.permission) file.close() @security.private def _dumpWizard(self, obj, path=None): # Dump properties of obj (assumed to be a Wizard) to the # filesystem as a directory, containing a .properties file # and analogues for the pages. if path is None: path = '' path = os.path.join(path, obj.id) file = self._createMetadataFile(path, '') file.write('title:string=%s\n' % obj.title) file.write('description:text=[[%s]]\n' % obj.description) file.write('wizard_action:string=%s\n' % obj.wizard_action) file.write('wizard_icon:string=%s\n' % obj.wizard_icon) file.write('wizard_hide_title:int=%s\n' % obj.wizard_hide_title) file.write('wizard_stepcount:int=%s\n' % obj.wizard_stepcount) file.close() pages = self._dumpObjects(obj.objectValues(), path) pages.sort() # help diff out :) file = self._createFile(path, '.objects') for id, meta in pages: file.write('%s:%s\n' % (id, meta)) file.close() @security.private def _dumpWizardPage(self, obj, path=None): # Dump properties of obj (assumed to be a WizardPage) to the # filesystem as a file, appending ".wizardpage" to the name. self._dumpDTML(obj, path, 'wizardpage') file = self._createMetadataFile(path, obj.id()) self._writeProperties(obj, file) file.close() @security.private def _dumpFormulatorForm(self, obj, path=None): if path is None: path = '' file = self._createFile(path, obj.id + '.form') file.write(obj.get_xml()) file.close() _handlers = { 'DTML Method': _dumpDTMLMethod, 'DTML Document': _dumpDTMLDocument, 'Folder': _dumpFolder, 'BTreeFolder2': _dumpFolder, 'External Method': _dumpExternalMethod, 'File': _dumpFileOrImage, 'Image': _dumpFileOrImage, 'Python Method': _dumpPythonMethod, 'Script (Python)': _dumpPythonScript, 'Controller Python Script': _dumpControllerPythonScript, 'Controller Validator': _dumpValidatorScript, 'Controller Page Template': _dumpControllerPageTemplate, 'Page Template': _dumpPageTemplate, 'Z SQL Method': _dumpSQLMethod, 'ZCatalog': _dumpZCatalog, 'Z Class': _dumpZClass, 'Common Instance Property Sheet': _dumpZClassPropertySheet, 'Zope Permission': _dumpPermission, 'Zope Factory': _dumpFactory, 'Wizard': _dumpWizard, 'Wizard Page': _dumpWizardPage, 'Formulator Form': _dumpFormulatorForm #, 'SQL DB Conn' : _dumpDBConn , 'ZWiki Page': _dumpZWikiPage } @security.protected(USE_DUMPER_PERMISSION) def testDump(self, peer_path, path=None, REQUEST=None): """ Test dumping a single item. """ obj = self.aq_parent.restrictedTraverse(peer_path) self._dumpObject(obj) if REQUEST is not None: REQUEST['RESPONSE'].redirect(self.absolute_url() + '/editForm' + '?manage_tabs_message=%s+dumped.' % peer_path)