Example #1
0
 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
Example #3
0
    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())
Example #4
0
    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
Example #5
0
    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")
Example #7
0
 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)
Example #8
0
 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)
             )
Example #9
0
    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)
Example #10
0
 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
Example #12
0
 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,
                 )
             )
Example #13
0
 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,
         )
     )
Example #14
0
    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
Example #16
0
 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"))
Example #17
0
    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
Example #18
0
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)
Example #19
0
#
# 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*(&nbsp;)*)*\s*</p>\s*', '', message)
    message = re.sub(r'\s*<p>(\s*(&nbsp;)*)*\s*</p>\s*$', '', message)
    return message

Example #20
0
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')
Example #21
0
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())
Example #22
0
# 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)
Example #23
0
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)
Example #24
0
            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:
Example #25
0
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
Example #26
0
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())
Example #28
0
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
Example #29
0
# 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())
Example #31
0
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)
Example #32
0
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)
Example #33
0
    def _getExportTemplate(self):

        return PageTemplateFile('ccExport.xml', _xmldir)
Example #34
0
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')
Example #35
0
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')
Example #36
0
            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))
Example #38
0
    ' 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()
Example #39
0
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)
Example #40
0
        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&amp;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&amp;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,
})
Example #41
0
    '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,
Example #42
0
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
Example #43
0
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)
Example #44
0
    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.
Example #45
0
    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,
})
Example #46
0
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='
Example #48
0
                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,
})
Example #49
0
 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)
Example #52
0
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())

Example #53
0
    '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)
Example #54
0
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))
Example #55
0
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
        ])
Example #57
0
    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:
Example #58
0
$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')
Example #59
0
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)
Example #60
0
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)