Exemplo n.º 1
0
    def get_folder(self):
        folder = None
        path = self.request.form.get('basePath', '/')
        if path == '/':
            folder = self.context
        else:
            path = path.lstrip('/')
            folder = self.context.restrictedTraverse(path, None)
            if folder is None:
                # check parents to see if we can auto create structure
                path = '/'.join(path.split('/')[:-1])
                while path:
                    folder = self.context.restrictedTraverse(path, None)
                    if folder:
                        if not IFolder.providedBy(folder):
                            self.status = 'Not a valid path.'
                            return None
                        break
                    path = '/'.join(path.split('/')[:-1])
                if not folder:
                    self.status = """Will automatically create folder(s) to place
content in this location."""
                    folder = self.context
            elif not IFolder.providedBy(folder):
                self.status = 'Not a valid path.'
                return None

        return folder
Exemplo n.º 2
0
def recursive_create_path(path):
    if path in ('/', ''):
        folder = site
    else:
        path = path.lstrip('/')
        folder = traverse(path)
        if folder is not None and not IFolder.providedBy(folder):
            api.content.delete(folder)
            folder = None
        if folder is None:
            # Need to create folders up to where we want content
            # we'll walk it up create folders as needed
            folder = site
            for part in path.split('/'):
                try:
                    ob = folder[part]
                    if not IFolder.providedBy(ob):
                        api.content.delete(ob)
                        raise KeyError()
                    else:
                        folder = ob
                except (KeyError, AttributeError):
                    fpath = os.path.join(args.export_directory,
                                         relpath(folder), part, '__folder__')

                    if os.path.exists(fpath):
                        fi = open(fpath)
                        data = mjson.loads(fi.read())
                        fi.close()
                        importtype = get_import_type(
                            data, fpath[len(args.export_directory):], None)
                        creation_data = importtype.get_data()
                        creation_data['container'] = folder
                        creation_data['id'] = part
                        try:
                            folder = api.content.create(**creation_data)
                        except api.exc.InvalidParameterError:
                            logger.error(
                                'Error creating content {}'.format(fpath),
                                exc_info=True)
                            return
                        importtype.post_creation(folder)
                        if data['state']:
                            try:
                                api.content.transition(folder,
                                                       to_state=data['state'])
                            except:
                                # maybe workflows do not match up
                                pass
                        folder.reindexObject()
                    else:
                        folder = api.content.create(type='Folder',
                                                    id=part,
                                                    title=part.capitalize(),
                                                    container=folder)
                        bdata = ILayoutAware(folder)
                        bdata.contentLayout = '++contentlayout++castle/folder-query.html'
    return folder
Exemplo n.º 3
0
    def get_breaches_for_item(self, obj=None):
        """Get breaches for one object and its children.

        Breaches coming from the children of a folder are ignored by default.
        """
        if obj is None:
            obj = self.context
        results = []
        catalog = getToolByName(obj, 'portal_catalog')
        obj_path = '/'.join(obj.getPhysicalPath())

        breaches = self.check_object(obj)
        if breaches:
            results.append(breaches)

        if IFolder.providedBy(obj):
            brains = catalog(path={'query': obj_path})
            for brain in brains:
                try:
                    child = brain.getObject()
                except (AttributeError, KeyError):
                    continue
                if child == obj:
                    continue
                breaches = self.check_object(obj=child, excluded_path=obj_path)
                if breaches:
                    results.append(breaches)
        self.breaches = results
        return results
def _children_all(tree, debug=False):
    """returns a list of every child"""

    objects = [o for o in tree.objectValues() if IPersistent.providedBy(o)]

    child_list = []
    to_crawl = deque(objects)

    i = 0
    while to_crawl:
        current = to_crawl.popleft()
        child_list.append(current)
        #print "Looking at ", current.absolute_url()
        print ".",

        if IFolder.providedBy(current):
            node_children = [o for o in current.objectValues() if \
                    IAttributeAnnotatable.providedBy(o) and is_ok(o.getId())]
            to_crawl.extend(node_children)

        i += 1
        if debug and (i > 1000):
            break

    return child_list
Exemplo n.º 5
0
def main():
    """ cleanup old files in a pre-defined container
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--container',
                        help='Folder path',
                        dest='container')
    parser.add_argument('--recursive',
                        help='Recurse through all subfolderish containers',
                        dest='recursive')
    parser.add_argument('--c_type',
                        help='Content type',
                        dest='c_type')
    parser.add_argument('--prefix',
                        help='Content type id prefix',
                        dest='prefix')
    parser.add_argument('--threshold',
                        help='Threshold for the number of old c_type objects',
                        dest='threshold')
    args = parser.parse_args(sys.argv[3:])
    if args.container == None or args.recursive == None or args.c_type == None or args.prefix == None or args.threshold == None:
        parser.print_help()
        sys.exit()
    site = get_zope_site()
    container = site.unrestrictedTraverse(args.container)
    do_cleanup(container, args.c_type, args.prefix, int(args.threshold))
    if args.recursive.lower() in ['true', '1', 'on']:
        folderish = [obj for obj in container.objectValues()
                     if IFolder.providedBy(obj)]
        for folder in folderish:
            do_cleanup(folder, args.c_type, args.prefix, int(args.threshold))
    print "Operations completed."
Exemplo n.º 6
0
    def get_breaches_for_item(self, obj=None):
        """Get breaches for one object and its children.

        Breaches coming from the children of a folder are ignored by default.
        """
        if obj is None:
            obj = self.context
        results = []
        catalog = getToolByName(obj, 'portal_catalog')
        obj_path = '/'.join(obj.getPhysicalPath())

        breaches = self.check_object(obj)
        if breaches:
            results.append(breaches)

        if IFolder.providedBy(obj):
            brains = catalog(path={'query': obj_path})
            for brain in brains:
                child = brain.getObject()
                if child == obj:
                    continue
                breaches = self.check_object(obj=child, excluded_path=obj_path)
                if breaches:
                    results.append(breaches)
        self.breaches = results
        return results
Exemplo n.º 7
0
 def render(self):
     alsoProvides(self.context, IHomePage)
     if HAS_DXCT:
         from plone.app.contenttypes.interfaces import IFolder
         if IFolder.providedBy(self.context):
             self.context.setLayout('subhomepage')
     return self.request.response.redirect(self.context.absolute_url())
Exemplo n.º 8
0
    def get_object_data(self):
        is_dp = False
        if not IFolder.providedBy(self.obj):
            if defaultpage:
                container = aq_parent(self.obj)
                if container:
                    is_dp = defaultpage.is_default_page(container, self.obj)
            else:
                is_dp = ptool.isDefaultPage(self.obj)

        has_sibling_pages = True
        if is_dp:
            container = aq_parent(self.obj)
            res = catalog(
                path={'query': '/'.join(container.getPhysicalPath())})
            if len([b for b in res if b.UID != self.image_to_lead]) > 1:
                has_sibling_pages = False

        try:
            state = workflow.getInfoFor(ob=self.obj, name='review_state')
        except:
            state = None
        return {
            'portal_type': self.obj.portal_type,
            'layout': self.obj.getLayout(),
            'uid': get_uid(self.obj),
            'is_default_page': is_dp,
            'state': state,
            'has_sibling_pages': has_sibling_pages
        }
Exemplo n.º 9
0
    def _deploy_content(self, obj, is_page=True):
        """
        Deploy object as page.
        """
        try:
            new_req, orig_req = fakeRequest(obj)
        except AttributeError:
            # not a valid obj to override request with
            new_req = None
        content = self._render_obj(obj)
        if content is None:
            return

        filename = obj.absolute_url_path().lstrip("/")
        # deploy additional views for content type
        if PLONE_APP_BLOB_INSTALLED and isinstance(obj, ATBlob):
            self._deploy_views([os.path.join(filename, "view")], is_page=True)

        if is_page:
            filename = filename.rstrip("/")
            if self.add_index or IFolder.providedBy(obj):
                filename = os.path.join(filename, "index.html")
            elif not filename.endswith(".htm") and not filename.endswith(".html"):
                filename = filename + ".html"
        elif (
            isinstance(obj, ATImage)
            or hasattr(obj, "getBlobWrapper")
            and "image" in obj.getBlobWrapper().getContentType()
        ):
            # create path to dump ATImage in original size
            if filename.rsplit(".", 1)[-1] in ("png", "jpg", "gif", "jpeg"):
                filename = os.path.join(filename, "image.%s" % (filename.rsplit(".", 1)[-1]))
            else:
                filename = os.path.join(filename, "image.jpg")
            filename, content = self._apply_image_transforms(filename, content)
        elif hasattr(obj, "getBlobWrapper") and "image" not in obj.getBlobWrapper().getContentType():
            # create path like for ATImage
            if len(filename.rsplit(".", 1)) > 1:
                filename = os.path.join(filename, "file.%s" % (filename.rsplit(".", 1)[-1]))
            else:
                filename = os.path.join(filename, "file")

        self._write(filename, content)

        # deploy all sizes of images uploaded for the object
        if not getattr(obj, "schema", None):
            return

        for field in obj.Schema().fields():
            if (PLONE_APP_BLOB_INSTALLED and IBlobImageField.providedBy(field)) or field.type == "image":
                self._deploy_blob_image_field(obj, field)
            elif PLONE_APP_BLOB_INSTALLED and IBlobField.providedBy(field):
                self._deploy_blob_file_field(obj, field)
            elif field.type == "file" and obj.meta_type not in self.file_types:
                self._deploy_file_field(obj, field)
            else:
                continue
        if new_req is not None:
            restoreRequest(orig_req, new_req)
Exemplo n.º 10
0
def listPloneSites(zope):
    out = []
    for item in zope.values():
        if IFolder.providedBy(item):
            for site in item.values():
                if IPloneSiteRoot.providedBy(site):
                    out.append(site)
    return out
Exemplo n.º 11
0
 def render(self):
     context = aq_inner(self.context)
     out = []
     for item in context.values():
         if IFolder.providedBy(item):
             for site in item.values():
                 if IPloneSiteRoot.providedBy(site):
                     out.append(item.id + '/' + site.id)
     return json.dumps(out)
Exemplo n.º 12
0
 def render(self):
     context = aq_inner(self.context)
     out = []
     for item in context.values():
         if IFolder.providedBy(item):
             for site in item.values():
                 if IPloneSiteRoot.providedBy(site):
                     out.append(item.id + '/' + site.id)
     return json.dumps(out)
Exemplo n.º 13
0
def recursive_create_path(path):
    if path in ('/', ''):
        folder = site
    else:
        path = path.lstrip('/')
        folder = traverse(path)
        if folder is not None and not IFolder.providedBy(folder):
            api.content.delete(folder)
            folder = None
        if folder is None:
            # Need to create folders up to where we want content
            # we'll walk it up create folders as needed
            folder = site
            for part in path.split('/'):
                try:
                    ob = folder[part]
                    if not IFolder.providedBy(ob):
                        logger.warn(
                            'Existing object in traversal path is not folderish. Removing it.'
                        )
                        api.content.delete(ob)
                        raise KeyError()
                    else:
                        folder = ob
                except (KeyError, AttributeError):
                    fpath = os.path.join(args.export_directory,
                                         relpath(folder), part, '__folder__')
                    imported = False
                    if os.path.exists(fpath):
                        imported = import_object(fpath)
                    if not imported:
                        logger.info(
                            "Creating plain Folder (no __folder__ file found), %s"
                            % part)
                        folder = api.content.create(type='Folder',
                                                    id=part,
                                                    title=part.capitalize(),
                                                    container=folder)
                        bdata = ILayoutAware(folder)
                        bdata.contentLayout = '++contentlayout++castle/folder-query.html'
                        if not args.skip_transitioning:
                            api.content.transition(folder,
                                                   to_state='published')
    return folder
Exemplo n.º 14
0
def listPloneSites(zope):
    """ List the available plonesites to be used by other function """
    out = []
    for item in zope.values():
        if IFolder.providedBy(item) and not IPloneSiteRoot.providedBy(item):
            for site in item.values():
                if IPloneSiteRoot.providedBy(site):
                    out.append(site)
        elif IPloneSiteRoot.providedBy(item):
            out.append(item)
    return out
Exemplo n.º 15
0
def listPloneSites(zope):
    """ List the available plonesites to be used by other function """
    out = []
    for item in zope.values():
        if IFolder.providedBy(item) and not IPloneSiteRoot.providedBy(item):
            for site in item.values():
                if IPloneSiteRoot.providedBy(site):
                    out.append(site)
        elif IPloneSiteRoot.providedBy(item):
            out.append(item)
    return out
 def _getFolder(self):
     """Return the containing folder of the current context, or the context itself if it is a folder"""
     context = self.context
     request = self.request
     if IFolder.providedBy(context):
         folder = context
     elif self.isFolderOrFolderDefaultPage(context, request):
         folder = aq_parent(aq_inner(context))
     else:
         # don't know how to handle this
         folder = aq_parent(aq_inner(context))
     return folder
Exemplo n.º 17
0
    def get_breaches(self, items=None):
        """Return breaches for multiple items.

        Breaches coming from objects in the list of items
        or their children (if a object is a folder) will be ignored.
        """
        if items is None:
            items = [self.context]
        catalog = getToolByName(self.context, 'portal_catalog')
        results = []
        uids_to_ignore = []
        uids_visited = set()
        self.breach_count = {}
        for obj in items:
            obj_path = '/'.join(obj.getPhysicalPath())
            brains_to_delete = catalog(path={'query': obj_path})
            # add the current items uid and all its childrens uids to the
            # list of uids that are ignored
            uids_to_ignore.extend([i.UID for i in brains_to_delete])
            for brain_to_delete in brains_to_delete:
                obj_to_delete = brain_to_delete.getObject()
                for breach in self.get_breaches_for_item(obj):
                    add_breach = False
                    for source in breach['sources']:
                        # Only add the breach if one the sources is not in the
                        # list of items that are to be deleted.
                        if source['uid'] not in uids_to_ignore and \
                           source['uid'] not in uids_visited:
                            add_breach = True
                            uids_visited.add(source['uid'])
                            break
                    if add_breach:
                        results.append(breach)
            if IFolder.providedBy(obj):
                count = len(catalog(path={'query': obj_path}))
                count_dirs = len(catalog(path={'query': obj_path}, is_folderish=True))
                count_public = len(catalog(path={'query': obj_path}, review_state='published'))
                if count:
                    self.breach_count[obj_path]=[count, count_dirs, count_public]

        # Cleanup: Some breaches where added before it was known
        # that their source will be deleted too.
        for result in results:
            for source in result['sources']:
                if source['uid'] in uids_to_ignore:
                    # Drop sources that are also being deleted
                    result['sources'].remove(source)
                    if not result['sources']:
                        # Remove the breach is there are no more sources
                        # This check is necessary since there can be multiple
                        # sources for a breach
                        results.remove(result)
        return results
Exemplo n.º 18
0
    def _deploy_views(self, views, is_page=False):
        """
        Deploy views of context as pages.
        """
        for fullview_name in views:
            log.info('Deploying %s' % fullview_name)
            fullview_path = None
            fullview_name_args = fullview_name.split('|')
            if len(fullview_name_args) > 1:
                fullview_name = fullview_name_args[0]
                fullview_path = fullview_name_args[1]

            context = self.context
            context_path = os.path.dirname(fullview_name)
            view_name = os.path.basename(fullview_name)
            if context_path:
                context = self.context.restrictedTraverse(context_path, None)
                if not context:
                    log.warning("Unable traverse to '%s'!" % context_path)
                    continue

            # plone.resource file system resource
            if IResourceDirectory.providedBy(context):
                try:
                    content_obj = context[view_name]
                except:
                    log.warning("Unable traverse to '%s'!" % fullview_name)
                    continue
            else:
                content_obj = context.restrictedTraverse(view_name, None)

            # get object's view content
            if ismethod(content_obj) or isfunction(content_obj):
                view = queryMultiAdapter((context, self.request), name=view_name)
                content_obj = view.context()
            content = self._render_obj(content_obj)
            if content is None:
                continue

            filename = fullview_name
            if is_page:
                filename = filename.rstrip('/')
                if self.add_index or IFolder.providedBy(content_obj):
                    filename = os.path.join(filename, 'index.html')
                elif not filename.endswith('.htm') and not filename.endswith('.html'):
                    filename = filename + '.html'
            # where to write view content (based on view path)
            path = urlparse(self.context.portal_url())[2]
            filename = '/'.join((path, filename))
            # write view content on the disk
            self._write(filename, content, fullview_path)
            log.info('%s deployed' % fullview_name)
Exemplo n.º 19
0
def noLongerProvidesITrashed(context):
    annotations = IAnnotations(context)
    infos = annotations.get(KEY, {'count': 0})
    infos['count'] -= 1
    annotations[KEY] = infos
    if infos['count'] <= 0:
        noLongerProvides(context, ITrashed)
        context.setExcludeFromNav(infos.get('ExcludeFromNav', False))
        context.reindexObject(idxs=['trashed', 'object_provides'])

    if IFolder.providedBy(context):
        for obj in context.objectValues():
            noLongerProvidesITrashed(obj)
Exemplo n.º 20
0
def providesITrashed(context):
    annotations = IAnnotations(context)
    infos = annotations.get(KEY, {'count': 0})
    infos['count'] += 1
    infos['ExcludeFromNav'] = context.getExcludeFromNav()
    annotations[KEY] = infos

    alsoProvides(context, ITrashed)
    context.setExcludeFromNav(True)
    context.reindexObject(idxs=['trashed', 'object_provides'])

    if IFolder.providedBy(context):
        for obj in context.objectValues():
            providesITrashed(obj)
Exemplo n.º 21
0
    def getMenuItems(self, context, request):
        """Return menu item entries in a TAL-friendly form."""
        results = PloneFactoriesMenu.getMenuItems(self, context, request)

        # No menu customization if the product is not installed
        if not ICustomMenuFactoryLayer.providedBy(request):
            return results
        
        portal_url = getToolByName(context, 'portal_url')

        # First of all, get the real context of the menu
        if IFolder.providedBy(context):
            folder = context
        elif isFolderOrFolderDefaultPage(context, request):
            folder = aq_parent(aq_inner(context))
        else:
            # don't know how to handle this
            folder = context

        data = {'context': context, 'portal_url': portal_url, 'container': folder}

        # If folder can't be annotable, do nothing
        # uncommon but may happen for old stuff like PloneGazette
        if not queryAdapter(folder, interface=IAnnotations):
            return results

        try:
            m_provider = ICustomFactoryMenuProvider(folder)
        except TypeError:
            # For any adaptation problem
            return results
        
        results = m_provider.getMenuCustomization(data, results)

        # Re-sort
        results.sort(lambda x, y: cmp(x['title'],y['title']))

        mtool = getToolByName(context, 'portal_membership')
        if not mtool.isAnonymousUser() and mtool.getAuthenticatedMember().has_permission('Customize menu: factories', folder):
            context_url = folder.absolute_url()
            results.append({'title'       : _(u'custommenu_manage_title', default=_(u'Customize menu\u2026')),
                            'description' : _(u'custommenu_manage_description', default=_(u'Manage custom elements of this menu')),
                            'action'      : context_url+'/@@customize-factoriesmenu',
                            'selected'    : False,
                            'icon'        : None,
                            'submenu'     : None,
                            'extra'       : {'separator': 'actionSeparator', 'id': 'customize-factoriesmenu', 'class': 'customize-menu'},
                            })
        return results
Exemplo n.º 22
0
def get_relateditems_options(context,
                             value,
                             separator,
                             vocabulary_name,
                             vocabulary_view,
                             field_name=None):

    if IForm.providedBy(context):
        context = context.context

    request = getRequest()
    site = get_top_site_from_url(context, request)
    options = get_ajaxselect_options(site, value, separator, vocabulary_name,
                                     vocabulary_view, field_name)

    nav_root = getNavigationRootObject(context, site)

    # basePath - start to search/browse in here.
    base_path_context = context
    if not IFolder.providedBy(base_path_context):
        base_path_context = aq_parent(base_path_context)
    if not base_path_context:
        base_path_context = nav_root
    options['basePath'] = '/'.join(base_path_context.getPhysicalPath())

    # rootPath - Only display breadcrumb elements deeper than this path.
    options['rootPath'] = '/'.join(site.getPhysicalPath()) if site else '/'

    # rootUrl: Visible URL up to the rootPath. This is prepended to the
    # currentPath to generate submission URLs.
    options['rootUrl'] = site.absolute_url() if site else ''

    # contextPath - current edited object. Will not be available to select.
    options['contextPath'] = '/'.join(context.getPhysicalPath())

    if base_path_context != nav_root:
        options['favorites'] = [
            {
                # 'title': _(u'Current Content'),
                'title': u'Aktueller Inhalt',
                'path': '/'.join(base_path_context.getPhysicalPath())
            },
            {
                'title': _(u'Start Page'),
                'path': '/'.join(nav_root.getPhysicalPath())
            }
        ]

    return options
Exemplo n.º 23
0
 def get_deleting_contents(self, items=None):
     if items is None:
         items = [self.context]
     catalog = getToolByName(self.context, 'portal_catalog')
     contents = {}
     for obj in items:
         obj_path = '/'.join(obj.getPhysicalPath())
         if IFolder.providedBy(obj):
             count = len(catalog(path={'query': obj_path}))
             count_dirs = len(catalog(path={'query': obj_path}, portal_type='Folder'))
             count_public = len(catalog(path={'query': obj_path}, review_state='published'))
             has_breaches = True
             if count > 1:
                 contents[obj_path]=[count, count_dirs, count_public]
     return contents
Exemplo n.º 24
0
    def _get_data(self):
        # First of all, get the real context of the menu
        context = self.context
        request = self.request
        if IFolder.providedBy(context):
            folder = context
        elif isFolderOrFolderDefaultPage(context, request):
            folder = aq_parent(aq_inner(context))
        else:
            # don't know how to handle this
            folder = context

        portal_url = getToolByName(context, 'portal_url')
        data = {'context': context, 'portal_url': portal_url, 'container': folder}
        return data
Exemplo n.º 25
0
def writeExport(obj, data):
    objpath = '/'.join(obj.getPhysicalPath())
    if IFolder.providedBy(obj):
        objpath = os.path.join(objpath, '__folder__')
    else:
        fobj = aq_parent(obj)
        while not ISiteRoot.providedBy(fobj):
            if not os.path.exists(os.path.join('/'.join(fobj.getPhysicalPath()), '__folder__')):
                for eobj, edata in exportObj(fobj):
                    writeExport(eobj, edata)
            fobj = aq_parent(fobj)
    path = createPath(objpath)
    fi = open(path, 'w')
    fi.write(dumps(data))
    fi.close()
Exemplo n.º 26
0
def write_export(obj, data):
    objpath = '/'.join(obj.getPhysicalPath())
    if IFolder.providedBy(obj):
        objpath = os.path.join(objpath, '__folder__')
    else:
        fobj = aq_parent(obj)
        while not ISiteRoot.providedBy(fobj):
            if not os.path.exists(
                    os.path.join('/'.join(fobj.getPhysicalPath()), '__folder__')):  # noqa
                for eobj, edata in export_obj(fobj):
                    write_export(eobj, edata)
            fobj = aq_parent(fobj)
    path = create_path(objpath)
    try:
        fi = open(path, 'w')
        fi.write(dumps(data))
        fi.close()
    except UnicodeDecodeError:
        print('Error exporting {}'.format(objpath))
Exemplo n.º 27
0
    def _get_data(self):
        # First of all, get the real context of the menu
        context = self.context
        request = self.request
        if IFolder.providedBy(context):
            folder = context
        elif isFolderOrFolderDefaultPage(context, request):
            folder = aq_parent(aq_inner(context))
        else:
            # don't know how to handle this
            folder = context

        portal_url = getToolByName(context, 'portal_url')
        data = {
            'context': context,
            'portal_url': portal_url,
            'container': folder
        }
        return data
Exemplo n.º 28
0
    def upgrade_container(self, root, blacklist=[]):
        contents = [root]
        while contents:
            iterate = True
            content = contents.pop()

            if isinstance(content, Broken):
                # We don't upgrade broken objects. They should be
                # removed by their contains if needed.
                continue

            if content.meta_type not in blacklist:
                try:
                    content = self.upgrade_content(content)
                except StopIteration:
                    iterate = False

            if (iterate and
                IFolder.providedBy(content) and
                content.meta_type != "Parsed XML"):
                contents.extend(content.objectValues())
Exemplo n.º 29
0
    def __call__(self):
        """Return JSON structure to indicate if File or Image uploads are
        allowed in the current container.
        """
        self.request.response.setHeader('Content-Type',
                                        'application/json; charset=utf-8')
        context = self.context
        if self.request.form.get('path'):
            context = context.restrictedTraverse(self.request.form.get('path'))

        allow_images = False
        allow_files = False
        if IFolder.providedBy(context):
            allowed_types = [t.getId() for t in context.allowedContentTypes()]
            allow_images = u'Image' in allowed_types
            allow_files = u'File' in allowed_types

        return json.dumps({
            'allowUpload': allow_images or allow_files,
            'allowImages': allow_images,
            'allowFiles': allow_files
        })
    def __call__(self, text, file_path=None):
        dutils = getUtility(IStaticDeploymentUtils)

        if file_path.lower().endswith('rss.xml') and dutils.rss_base_url:
            # will be handled differently, all urls should already
            # have domain ripped out
            base = dutils.rss_base_url.rstrip('/') + '/'

            return text.replace('rdf:resource="/', 'rdf:resource="' + base).replace(
                'rdf:about="/', 'rdf:about="' + base).replace(
                '<link>/', '<link>' + base).replace(
                '/@@staticdeployment-controlpanel', '')

        if dutils.add_index:
            return text
        dom = getDom(text)
        if not dom:
            return text
        for link in dom.cssselect('a[href],base[href]'):
            link = LinkElement(link)
            url = link.val
            if not self.is_same_domain(url, file_path):
                continue
            if url == '/': # root of the site!
                continue
            url = url.rstrip('/')
            obj = self.context.restrictedTraverse(url.lstrip('/'), None)

            mt = None
            try:
                mt = obj.aq_base.meta_type
            except AttributeError:
                pass
            if obj and not isinstance(obj, (FSObject, File)) and \
                    not IFolder.providedBy(obj) and not url.endswith('.htm') \
                    and not url.endswith('.html') and not mt in dutils.file_types:
                link.set(url + '.html')
        return unicode(dom)
Exemplo n.º 31
0
    def __call__(self):
        """Return JSON structure to indicate if File or Image uploads are
        allowed in the current container.
        """
        self.request.response.setHeader(
            'Content-Type', 'application/json; charset=utf-8'
        )
        context = self.context
        if self.request.form.get('path'):
            context = context.restrictedTraverse(self.request.form.get('path'))

        allow_images = False
        allow_files = False
        if IFolder.providedBy(context):
            allowed_types = [t.getId() for t in context.allowedContentTypes()]
            allow_images = u'Image' in allowed_types
            allow_files = u'File' in allowed_types

        return json.dumps({
            'allowUpload': allow_images or allow_files,
            'allowImages': allow_images,
            'allowFiles': allow_files
        })
Exemplo n.º 32
0
def exportObj(obj):
    data = {}

    im_width = 0
    image_to_lead = None
    for field in obj.Schema().fields():
        fdata = field.getRaw(obj)
        if type(fdata) == ImplicitAcquisitionWrapper:
            fdata = fdata.aq_base
        data[field.__name__] = fdata
        if field.__name__ in ('image', 'file'):
            data[field.__name__ + '_filename'] = field.getFilename(obj)
            data[field.__name__ + '_contentType'] = field.getContentType(obj)
        if field.__name__ == 'image':
            im = field.get(obj)
            if im:
                im_width = im.width

    images = getReferencedImages(data)

    # try to find image to associate with it if there is none
    if im_width < 200:
        if len(images) > 0 and images[0].portal_type == 'Image':
            image = images[0]
            if len(image.getBackReferences(relationship='isReferencing')) < 2:
                im = image.getImage()
                data.update({
                    'image': image.Schema().getField('image').getRaw(image),
                    'image_filename': image.getFilename(),
                    'image_contentType': image.getContentType(),
                    'imageCaption': image.Description()
                })
                image_to_lead = image.UID()
                images = images[1:]

    if image_to_lead and 'text' in data:
        data['text'] = data['text'].replace(image_to_lead, obj.UID())

    is_dp = False
    if not IFolder.providedBy(obj):
        if defaultpage:
            container = aq_parent(obj)
            if container:
                is_dp = defaultpage.is_default_page(container, obj)
        else:
            is_dp = ptool.isDefaultPage(obj)

    has_sibling_pages = True
    if is_dp:
        container = aq_parent(obj)
        res = catalog(path={'query': '/'.join(container.getPhysicalPath())})
        if len([b for b in res if b.UID != image_to_lead]) > 1:
            has_sibling_pages = False

    try:
        state = workflow.getInfoFor(ob=obj, name='review_state')
    except:
        state = None
    alldata = {
        'portal_type': obj.portal_type,
        'layout': obj.getLayout(),
        'data': data,
        'uid': obj.UID(),
        'is_default_page': is_dp,
        'state': state,
        'has_sibling_pages': has_sibling_pages
    }
    yield obj, alldata
    for ref in images:
        if ref.UID() == obj.UID():
            continue
        if ref.portal_type != 'Image':
            continue
        if image_to_lead == ref.UID():
            continue
        for o, d in exportObj(ref):
            if o.UID() == ref.UID() or o.UID() == obj.UID():
                continue
            yield o, d
Exemplo n.º 33
0
 def isFolder(self):
     return IFolder.providedBy(self.context)
Exemplo n.º 34
0
    def process_form(self, instance, field, form, empty_marker=None,
                     emptyReturnsMarker=False, validating=True):
        """A custom implementation for the widget form processing."""
        if validating:
            # At the validation phase, only return the existing UID field
            # value or the filename of the new FileUpload object
            value = form.get(field.getName())
            if value:
                return value, {}

            value = empty_marker
            files_list = form.get('%s_file' % field.getName(), [])
            if files_list:
                obj = files_list[0]
                value = getattr(obj, 'filename', getattr(obj, 'name', ''))
            return value, {}

        option = form.get('%s_option' % field.getName(), empty_marker)
        value = form.get(field.getName(), empty_marker)

        # In this case, just do the trivial
        if option == 'select':
            if value is empty_marker:
                return empty_marker
            if emptyReturnsMarker and value == '':
                return empty_marker
            return value, {}

        # In this case, we need to create new object(s) and get its UID(s)
        if option == 'upload':
            result = []
            files_list = form.get('%s_file' % field.getName(), [])
            portal = getToolByName(instance, 'portal_url').getPortalObject()
            mt_tool = getToolByName(portal, 'mimetypes_registry')

            # Define the destination folder
            root = instance
            foldername = self.startup_directory
            if foldername.startswith('/'):
                root = portal
                foldername = foldername[1:]
            try:
                folder = root.restrictedTraverse(foldername)
            except (KeyError, AttributeError):
                # If the startup_directory doesn't exists, fallback to
                # the current instance if folderish, or its parent
                if IFolder.providedBy(instance):
                    folder = instance
                else:
                    folder = aq_parent(instance)

            for fileobj in files_list:
                # Normalize the filename
                filename = getattr(fileobj, 'filename', '')
                filename = filename.split('\\')[-1]

                if filename:
                    # Guess the mimetype & define the content-type class
                    content = 'File'
                    mimetype = str(mt_tool.classify(fileobj.read(1024)))
                    if mimetype.startswith('image'):
                        content = 'Image'

                    # Create the new content
                    old_id = folder.generateUniqueId(content)
                    new_id = folder.invokeFactory(content, id=old_id, title=filename)
                    obj = getattr(folder, new_id)
                    obj._renameAfterCreation()
                    obj.unmarkCreationFlag()
                    obj.update_data(fileobj, mimetype)

                    result.append(obj.UID())

            if field.multiValued:
                # Multi valued, append the old value
                result.extend(value)
            elif result:
                # Non multi valued, with a valid upload, return it
                result = result[0]
            else:
                # Non multi valued, with an invalid upload, return the old value
                result = value

            return result, {}

        return empty_marker
Exemplo n.º 35
0
    def import_object(self, filepath, container=None):
        fi = open(filepath)
        file_read = fi.read()
        fi.close()
        try:
            data = mjson.loads(file_read)
        except Exception:
            print("Skipping {}; Unable to read JSON data".format(filepath))
            return
        if filepath.endswith('__folder__'):
            filepath = '/'.join(filepath.split('/')[:-1])

        skipped = False
        if data['portal_type'] in skip_types:
            print('Skipping omitted type {type}'.format(
                type=data['portal_type']))
            skipped = True
        if only_types and data['portal_type'] not in only_types:
            print("Skipping {type} at {path}, not in only_types.".format(
                type=data['portal_type'], path=filepath))
            skipped = True
        if import_paths:
            do_import = False
            for import_path in import_paths:
                if filepath.startswith('{}/{}'.format(args.export_directory,
                                                      import_path)):
                    do_import = True
                if import_path.startswith(
                        filepath[len(args.export_directory):].lstrip('/') +
                        '/'):
                    # Don't skip folders on the way to import_paths
                    do_import = True
            if not do_import:
                print("Skipping {path}, not in import_paths".format(
                    path=filepath))
                skipped = True
        if skip_paths:
            for skip_path in skip_paths:
                if filepath.lower().startswith('{}/{}'.format(
                        args.export_directory, skip_path)):
                    print(
                        "Skipping {path}, in skip_paths".format(path=filepath))
                    skipped = True
        if skipped:
            if os.path.isdir(filepath) and len(os.listdir(filepath)):
                logger.warn('{path} contains additional content that will be '
                            'skipped.'.format(path=filepath))
            return

        original_path = filepath[len(args.export_directory):]
        if retain_paths:
            importtype = get_import_type(data, original_path, 'retain_paths')
        else:
            importtype = get_import_type(data, original_path)
        path = importtype.get_path()

        if container is None:
            logger.warn(
                'Skipped {} because of creation error'.format(filepath))
            return
        _id = path.split('/')[-1]

        create = True
        if _id in container.objectIds():
            if args.overwrite:
                existing = container[_id]
                if IFolder.providedBy(existing):
                    if len(existing.objectIds()):
                        print("OVERWRITE: Deleting non-empty container {path}".
                              format(path=path))
                else:
                    print("OVERWRITE: Deleting content item at {path}".format(
                        path=path))
                api.content.delete(container[_id])
            else:
                create = False

        creation_data = importtype.get_data()
        pc_data = importtype.get_post_creation_data()
        creation_data['container'] = container

        aspect = ISelectableConstrainTypes(container, None)
        if aspect:
            if (aspect.getConstrainTypesMode() != 1 or [creation_data['type']]
                    != aspect.getImmediatelyAddableTypes()):
                aspect.setConstrainTypesMode(1)
                aspect.setImmediatelyAddableTypes([creation_data['type']])
        if create:
            if ignore_uuids and '_plone.uuid' in creation_data:
                del creation_data['_plone.uuid']

            obj = None
            if not args.overwrite and (_id in container.objectIds()):
                print('Skipping {path}, already exists. Use --overwrite to'
                      ' create anyway.'.format(path=path))
                return
            elif (not ignore_uuids
                  and api.content.get(UID=creation_data['_plone.uuid'])
                  is not None):
                logger.warn(
                    'Skipping {path}, content with its UUID already exists.'
                    'Use --ignore-uuids to create anyway.'.format(path=path))
                return
            else:
                try:
                    obj = api.content.create(safe_id=True, **creation_data)
                    print('Created {path}'.format(path=path))
                    self.imported_count += 1
                    if self.imported_count % 50 == 0:
                        print('%i processed, committing' % self.imported_count)
                        transaction.commit()
                except api.exc.InvalidParameterError:
                    if stop_if_exception:
                        logger.error(
                            'Error creating content {}'.format(filepath),
                            exc_info=True)
                        if pdb_if_exception:
                            pdb.set_trace()
                        raise
                    logger.error('Error creating content {}'.format(filepath),
                                 exc_info=True)
                    return

    # TODO check default folder pages came over as folder with rich text tile
    # TODO any folder pages without default page should have content listing tile
        else:
            obj = container[_id]
            for key, value in creation_data.items():
                if key not in ('id', 'type'):
                    setattr(obj, key, value)

        if obj is not None:
            if path != original_path:
                storage = getUtility(IRedirectionStorage)
                rpath = os.path.join('/'.join(site.getPhysicalPath()),
                                     original_path.strip('/'))
                storage.add(rpath, "/".join(obj.getPhysicalPath()))

            obj.contentLayout = importtype.layout
            importtype.post_creation(obj, post_creation_data=pc_data)
            if not args.skip_transitioning and data['state']:
                # transition item only if it needs it
                state = api.content.get_state(obj=obj)
                if state != data['state']:
                    try:
                        print('Transitioning %s to %s' %
                              (obj.id, data['state']))
                        api.content.transition(obj, to_state=data['state'])
                    except Exception:
                        logger.error(
                            "Error transitioning %s to %s, maybe workflows"
                            " don't match up" % (obj.id, data['state']))
                        # pass
                        if stop_if_exception:
                            if pdb_if_exception:
                                pdb.set_trace()
                            raise

            # set workflow / review history
            if 'review_history' in data:
                review_history = data['review_history']
                wtool = api.portal.get_tool(name='portal_workflow')
                # loop over all workflow chains (usually only 1)
                for workflow_id in wtool.getChainFor(obj):
                    obj.workflow_history[workflow_id] = review_history
            else:
                logger.warn('No review history on {obj}'.format(obj=obj))

            fix_html_images(obj)
            obj.reindexObject()
            try:
                modification_date = data['data']['modification_date']
                obj.setModificationDate(modification_date)
                obj.reindexObject(idxs=['modified'])
                logger.info('    set modification date to %s' %
                            modification_date)
            except Exception:
                logger.info(
                    'Could not set modification date on {obj}'.format(obj=obj))
            return obj
Exemplo n.º 36
0
    def process_form(self,
                     instance,
                     field,
                     form,
                     empty_marker=None,
                     emptyReturnsMarker=False,
                     validating=True):
        """A custom implementation for the widget form processing."""
        if validating:
            # At the validation phase, only return the existing UID field
            # value or the filename of the new FileUpload object
            value = form.get(field.getName())
            if value:
                return value, {}

            value = empty_marker
            files_list = form.get('%s_file' % field.getName(), [])
            if files_list:
                obj = files_list[0]
                value = getattr(obj, 'filename', getattr(obj, 'name', ''))
            return value, {}

        option = form.get('%s_option' % field.getName(), empty_marker)
        value = form.get(field.getName(), empty_marker)

        # In this case, just do the trivial
        if option == 'select':
            if value is empty_marker:
                return empty_marker
            if emptyReturnsMarker and value == '':
                return empty_marker
            return value, {}

        # In this case, we need to create new object(s) and get its UID(s)
        if option == 'upload':
            result = []
            files_list = form.get('%s_file' % field.getName(), [])
            portal = getToolByName(instance, 'portal_url').getPortalObject()
            mt_tool = getToolByName(portal, 'mimetypes_registry')

            # Define the destination folder
            root = instance
            foldername = self.getStartupDirectory(instance, field)
            if foldername.startswith('/'):
                root = portal
                foldername = foldername[1:]
            try:
                folder = root.restrictedTraverse(foldername)
            except (KeyError, AttributeError):
                # If the startup_directory doesn't exists, fallback to
                # the current instance if folderish, or its parent
                if IFolder.providedBy(instance):
                    folder = instance
                else:
                    folder = aq_parent(instance)

            for fileobj in files_list:
                # Normalize the filename
                filename = getattr(fileobj, 'filename', '')
                filename = filename.split('\\')[-1]

                if filename:
                    # Guess the mimetype & define the content-type class
                    content = 'File'
                    mimetype = mimetypes.guess_type(filename)[0] or ""
                    if mimetype.startswith('image'):
                        content = 'Image'

                    # Create the new content
                    old_id = folder.generateUniqueId(content)
                    new_id = folder.invokeFactory(content,
                                                  id=old_id,
                                                  title=filename)
                    obj = getattr(folder, new_id)
                    obj._renameAfterCreation()
                    obj.unmarkCreationFlag()
                    obj.update_data(fileobj, mimetype)
                    obj.reindexObject()

                    result.append(obj.UID())

            if field.multiValued:
                # Multi valued, append the old value
                result.extend(value)
            elif result:
                # Non multi valued, with a valid upload, return it
                result = result[0]
            else:
                # Non multi valued, with an invalid upload, return the old value
                result = value

            return result, {}

        return empty_marker
Exemplo n.º 37
0
    def _deploy_content(self, obj, is_page=True):
        """
        Deploy object as page.
        """
        try:
            new_req, orig_req = fakeRequest(obj)
        except AttributeError:
            # not a valid obj to override request with
            new_req = None
        content = self._render_obj(obj)
        if content is None:
            return

        filename = obj.absolute_url_path().lstrip('/')
        # deploy additional views for content type
        if PLONE_APP_BLOB_INSTALLED and isinstance(obj, ATBlob):
            self._deploy_views([os.path.join(filename, 'view'), ],
                    is_page=True)

        if is_page:
            filename = filename.rstrip('/')
            if self.add_index or IFolder.providedBy(obj):
                filename = os.path.join(filename, 'index.html')
            elif not filename.endswith('.htm') and not filename.endswith('.html'):
                filename = filename + '.html'
        elif isinstance(obj, ATImage) or \
                hasattr(obj, 'getBlobWrapper') and \
                'image' in obj.getBlobWrapper().getContentType():
            # create path to dump ATImage in original size
            if filename.rsplit('.', 1)[-1] in ('png', 'jpg', 'gif', 'jpeg'):
                filename = os.path.join(filename, 'image.%s' % (
                    filename.rsplit('.', 1)[-1]))
            else:
                filename = os.path.join(filename, 'image.jpg')
            filename, content = self._apply_image_transforms(filename, content)
        elif (hasattr(obj, 'getBlobWrapper') and 'image' not in
                obj.getBlobWrapper().getContentType()):
            # create path like for ATImage
            if len(filename.rsplit('.', 1)) > 1:
                filename = os.path.join(filename, 'file.%s' % (
                    filename.rsplit('.', 1)[-1]))
            else:
                filename = os.path.join(filename, 'file')

        self._write(filename, content)

        # deploy all sizes of images uploaded for the object
        if not getattr(obj, 'schema', None):
            return

        # For Dexterity objects
        if IDexterityContent.providedBy(obj):
            from plone.dexterity.interfaces import IDexterityFTI
            from zope.component import getUtility
            from zope.schema import getFieldsInOrder
            from plone.behavior.interfaces import IBehaviorAssignable

            fti = getUtility(IDexterityFTI, name=obj.portal_type)
            schema = fti.lookupSchema()
            fields = getFieldsInOrder(schema)
            for _, field in fields:
                if INamedImageField.providedBy(field):
                    self._deploy_blob_dexterity_image_field(obj, field)
                elif INamedFileField.providedBy(field):
                    self._deploy_blob_dexterity_file_field(obj, field)

            behavior_assignable = IBehaviorAssignable(obj)
            if behavior_assignable:
                behaviors = behavior_assignable.enumerateBehaviors()
                for behavior in behaviors:
                    for k, v in getFieldsInOrder(behavior.interface):
                        pass

        else:
            for field in obj.Schema().fields():
                if (PLONE_APP_BLOB_INSTALLED and IBlobImageField.providedBy(field)) or \
                        field.type == 'image':
                    self._deploy_blob_image_field(obj, field)
                elif PLONE_APP_BLOB_INSTALLED and IBlobField.providedBy(field):
                    self._deploy_blob_file_field(obj, field)
                elif field.type == 'file' and obj.portal_type not in self.file_types:
                    self._deploy_file_field(obj, field)
                else:
                    continue
        if new_req is not None:
            restoreRequest(orig_req, new_req)
Exemplo n.º 38
0
def get_relateditems_options(context, value, separator, vocabulary_name,
                             vocabulary_view, field_name=None,
                             include_recently_added=True):

    if IForm.providedBy(context):
        context = context.context

    request = getRequest()
    site = get_top_site_from_url(context, request)
    options = get_ajaxselect_options(
        site,
        value,
        separator,
        vocabulary_name,
        vocabulary_view,
        field_name
    )

    nav_root = getNavigationRootObject(context, site)

    if not ISimpleItem.providedBy(context):
        context = nav_root

    # basePath - start to search/browse in here.
    base_path_context = context
    if not IFolder.providedBy(base_path_context):
        base_path_context = aq_parent(base_path_context)
    if not base_path_context:
        base_path_context = nav_root
    options['basePath'] = '/'.join(base_path_context.getPhysicalPath())

    # rootPath - Only display breadcrumb elements deeper than this path.
    options['rootPath'] = '/'.join(site.getPhysicalPath()) if site else '/'

    # rootUrl: Visible URL up to the rootPath. This is prepended to the
    # currentPath to generate submission URLs.
    options['rootUrl'] = site.absolute_url() if site else ''

    # contextPath - current edited object. Will not be available to select.
    options['contextPath'] = '/'.join(context.getPhysicalPath())

    if base_path_context != nav_root:
        options['favorites'] = [
            {
                'title': _(u'Current Content'),
                'path': '/'.join(base_path_context.getPhysicalPath())
            }, {
                'title': _(u'Start Page'),
                'path': '/'.join(nav_root.getPhysicalPath())
            }
        ]

    if include_recently_added:
        # Options for recently used key
        tool = getToolByName(context, 'portal_membership')
        user = tool.getAuthenticatedMember()
        options['recentlyUsed'] = False  # Keep that off in Plone 5.1
        options['recentlyUsedKey'] = (u'relateditems_recentlyused_%s_%s' % (
            field_name or '',
            user.id
        ))  # use string substitution with %s here for automatic str casting.

    return options
Exemplo n.º 39
0
    def get_breaches(self, items=None):
        """Return breaches for multiple items.

        Breaches coming from objects in the list of items
        or their children (if a object is a folder) will be ignored.
        """
        if items is None:
            items = [self.context]
        catalog = getToolByName(self.context, 'portal_catalog')
        results = []
        uids_to_ignore = []
        uids_visited = set()
        self.breach_count = {}
        for obj in items:
            obj_path = '/'.join(obj.getPhysicalPath())
            brains_to_delete = catalog(path={'query': obj_path})
            # add the current items uid and all its childrens uids to the
            # list of uids that are ignored
            uids_to_ignore.extend([i.UID for i in brains_to_delete])
            for brain_to_delete in brains_to_delete:
                try:
                    obj_to_delete = brain_to_delete.getObject()  # noqa
                except (AttributeError, KeyError):
                    logger.exception('No object found for %s! Skipping',
                                     brain_to_delete)
                    continue
                for breach in self.get_breaches_for_item(obj):
                    add_breach = False
                    for source in breach['sources']:
                        # Only add the breach if one the sources is not in the
                        # list of items that are to be deleted.
                        if source['uid'] not in uids_to_ignore and \
                           source['uid'] not in uids_visited:
                            add_breach = True
                            uids_visited.add(source['uid'])
                            break
                    if add_breach:
                        results.append(breach)
            if IFolder.providedBy(obj):
                count = len(catalog(path={'query': obj_path}))
                count_dirs = len(
                    catalog(path={'query': obj_path}, is_folderish=True))
                count_public = len(
                    catalog(path={'query': obj_path},
                            review_state='published'))
                if count:
                    self.breach_count[obj_path] = [
                        count, count_dirs, count_public
                    ]

        # Cleanup: Some breaches where added before it was known
        # that their source will be deleted too.
        for result in results:
            for source in result['sources']:
                if source['uid'] in uids_to_ignore:
                    # Drop sources that are also being deleted
                    result['sources'].remove(source)
                    if not result['sources']:
                        # Remove the breach is there are no more sources
                        # This check is necessary since there can be multiple
                        # sources for a breach
                        results.remove(result)
        return results
Exemplo n.º 40
0
def get_relateditems_options(context,
                             value,
                             separator,
                             vocabulary_name,
                             vocabulary_view,
                             field_name=None,
                             include_recently_added=True):

    if IForm.providedBy(context):
        context = context.context

    request = getRequest()
    site = get_top_site_from_url(context, request)
    options = {
        'separator': separator,
    }
    if not vocabulary_name:
        # we need a vocabulary!
        raise ValueError('RelatedItems needs a vocabulary')
    options['vocabularyUrl'] = '{0}/{1}?name={2}'.format(
        get_context_url(site),
        vocabulary_view,
        vocabulary_name,
    )
    if field_name:
        options['vocabularyUrl'] += '&field={0}'.format(field_name)
    if value:
        options['initialValues'] = {}
        catalog = False
        if vocabulary_name == 'plone.app.vocabularies.Catalog':
            catalog = getToolByName(getSite(), 'portal_catalog')
        for value in value.split(separator):
            title = value
            if catalog:
                result = catalog(UID=value)
                title = result[0].Title if result else value
            options['initialValues'][value] = title

    nav_root = getNavigationRootObject(context, site)

    if not ISimpleItem.providedBy(context):
        context = nav_root

    # basePath - start to search/browse in here.
    base_path_context = context
    if not IFolder.providedBy(base_path_context):
        base_path_context = aq_parent(base_path_context)
    if not base_path_context:
        base_path_context = nav_root
    options['basePath'] = '/'.join(base_path_context.getPhysicalPath())

    # rootPath - Only display breadcrumb elements deeper than this path.
    options['rootPath'] = '/'.join(site.getPhysicalPath()) if site else '/'

    # rootUrl: Visible URL up to the rootPath. This is prepended to the
    # currentPath to generate submission URLs.
    options['rootUrl'] = site.absolute_url() if site else ''

    # contextPath - current edited object. Will not be available to select.
    options['contextPath'] = '/'.join(context.getPhysicalPath())

    if base_path_context != nav_root:
        options['favorites'] = [{
            'title':
            _(u'Current Content'),
            'path':
            '/'.join(base_path_context.getPhysicalPath())
        }, {
            'title': _(u'Start Page'),
            'path': '/'.join(nav_root.getPhysicalPath())
        }]

    if include_recently_added:
        # Options for recently used key
        tool = getToolByName(context, 'portal_membership')
        user = tool.getAuthenticatedMember()
        options['recentlyUsed'] = False  # Keep that off in Plone 5.1
        options['recentlyUsedKey'] = (
            u'relateditems_recentlyused_%s_%s' % (field_name or '', user.id)
        )  # use string substitution with %s here for automatic str casting.

    return options
Exemplo n.º 41
0
    def getMenuItems(self, context, request):
        """Return menu item entries in a TAL-friendly form."""
        results = PloneFactoriesMenu.getMenuItems(self, context, request)

        # No menu customization if the product is not installed
        if not ICollectiveFactorymenuLayer.providedBy(request):
            return results

        portal_url = getToolByName(context, 'portal_url')

        # First of all, get the real context of the menu
        if IFolder.providedBy(context):
            folder = context
        elif isFolderOrFolderDefaultPage(context, request):
            folder = aq_parent(aq_inner(context))
        else:
            # don't know how to handle this
            folder = context

        data = {
            'context': context,
            'portal_url': portal_url,
            'container': folder
        }

        # If folder can't be annotable, do nothing
        # uncommon but may happen for old stuff like PloneGazette
        if not queryAdapter(folder, interface=IAnnotations):
            return results

        try:
            m_provider = ICustomFactoryMenuProvider(folder)
        except TypeError:
            # For any adaptation problem
            return results

        results = m_provider.getMenuCustomization(data, results)

        # Re-sort
        results.sort(lambda x, y: cmp(x['title'], y['title']))

        mtool = getToolByName(context, 'portal_membership')
        if not mtool.isAnonymousUser() and\
            mtool.getAuthenticatedMember().has_permission(
                'Customize menu: factories', folder
        ):
            context_url = folder.absolute_url()
            results.append({
                'title':
                _(u'custommenu_manage_title', default=u'Customize menu\u2026'),
                'description':
                _(u'custommenu_manage_description',
                  default=u'Manage custom elements '
                  u'of this menu'),
                'action':
                context_url + '/@@customize-factoriesmenu',
                'selected':
                False,
                'icon':
                None,
                'submenu':
                None,
                'extra': {
                    'separator': 'actionSeparator',
                    'id': 'customize-factoriesmenu',
                    'class': 'customize-menu'
                },
            })
        return results