def list_content(content, callback): """Recursively list CMF content out of the given one. ``callback`` is called every thousand items after a commit. """ def recurse(content): for child in content.contentValues(): if IFolderish.providedBy(child): for grandchild in recurse(child): yield grandchild yield child count = 0 total = 0 if IFolderish.providedBy(content): for child in recurse(content): yield child count += 1 total += 1 if count > 200: logger.info('{0} items indexed'.format(total)) transaction.commit() content._p_jar.cacheGC() callback() count = 0 yield content elif IContentish.providedBy(content): yield content
def publishTraverse(self, request, name): try: obj = super(RESTTraverse, self).publishTraverse(request, name) if (not IContentish.providedBy(obj) and not IService.providedBy(obj)): if isinstance(obj, VirtualHostMonster): return obj else: raise KeyError except KeyError: # No object, maybe a named rest service service = queryMultiAdapter((self.context, request), name=request._rest_service_id + name) if service is None: # No service, fallback to regular view view = queryMultiAdapter((self.context, request), name=name) if view is not None: return view raise return service if name.startswith(request._rest_service_id): return obj # Do not handle view namespace if '@@' in request['PATH_INFO'] or '++view++' in request['PATH_INFO']: return obj # Wrap object to ensure we handle further traversal return RESTWrapper(obj, request)
def is_suspect_acquisition(context, request, name, result): # both objects traversed should be contentish if ((not ISiteRoot.providedBy(result) and not IContentish.providedBy(result)) or (not ISiteRoot.providedBy(context) and not IContentish.providedBy(context))): return False # allow for explicit acquisition elif IPublishableThroughAcquisition.providedBy(result): return False else: result_id = result.getId() if ((result_id not in context.objectIds()) or (aq_base(result) is not aq_base(context[result_id]))): return True return False
def get_editor_language(request): """ Get editor language override """ cached = getattr(request, "_cached_admin_language", None) if cached: return cached alwaysTranslate = getattr(request, "alwaysTranslate", None) if alwaysTranslate: return None context = find_context(request) # Filter out CSS and other non-sense # IFolderish check includes site root if not (IContentish.providedBy(context) or IFolderish.providedBy(context)): # Early terminate return None # Check if we are the editor portal_state = getMultiAdapter((context, request), name="plone_portal_state") if portal_state.anonymous(): # Anon visitor, normal language -> request.alwaysTranslate = True return None language = 'en' # english for all authenticated users request._cached_admin_language = language return language
def getLanguage(self, langs, env): if not IFtwSubsiteLayer.providedBy(env): return base_negotiator.getLanguage(langs, env) # Get current published object obj = find_context(env) # Filter out CSS/JS and other non contentish objects # IFolderish check includes site root if not (IContentish.providedBy(obj) or IFolderish.providedBy(obj)): return base_negotiator.getLanguage(langs, env) nav_root = get_nav_root(obj) if ISubsite.providedBy(nav_root): # Get language stored on Subsite language = nav_root.force_language if language: return language else: return base_negotiator.getLanguage(langs, env) else: # Use normal Negotiator return base_negotiator.getLanguage(langs, env)
def update(self): values = [] published = getattr(self.request, 'PUBLISHED', None) published = getattr(published, 'context', published) if IContentish.providedBy(published): obj = aq_base(self.context) for x in ['seo_noindex', 'seo_nofollow', 'seo_nosnippet', 'seo_noarchive']: if getattr(obj, x, False): values.append(x.replace('seo_', '')) else: registry = getUtility(IRegistry) seoSettings = registry.forInterface(ISeoSettings) obj_id = getattr(published, 'id', '') if not obj_id: obj_id = self.request.steps[-1].replace('@', '') if obj_id == 'contact-info': if not seoSettings.indexContactInfo: values.append('noindex') elif obj_id in ['login', 'login_form', 'require_login', ]: if not seoSettings.indexLoginForm: values.append('noindex') elif obj_id == 'register': if not seoSettings.indexRegisterForm: values.append('noindex') elif obj_id == 'sitemap' or \ obj_id == 'accessibility-info' or \ obj_id == 'search' or \ obj_id == 'mail_password_form': values.append('noindex') self.content = ', '.join(values)
def publishTraverse(self, request, name): # Try to get an object using default traversal adapter = DefaultPublishTraverse(self.context, request) try: obj = adapter.publishTraverse(request, name) if (not IContentish.providedBy(obj) and not IService.providedBy(obj)): raise KeyError # If there's no object with the given name, we get a KeyError. # In a non-folderish context a key lookup results in an AttributeError. except (KeyError, AttributeError): # No object, maybe a named rest service service = queryMultiAdapter((self.context, request), name=request._rest_service_id + name) if service is None: # No service, fallback to regular view view = queryMultiAdapter((self.context, request), name=name) if view is not None: return view raise return service else: # Wrap object to ensure we handle further traversal return RESTWrapper(obj, request)
def test_provided(self): from Products.CMFCore.interfaces import IContentish from Products.CMFCore.interfaces import IIndexableObjectWrapper obj = DummyContent() w = self._makeOne({}, obj) self.failUnless(IContentish.providedBy(w)) self.failUnless(IIndexableObjectWrapper.providedBy(w))
def available(self): if self.anonymous: return False if not IContentish.providedBy(self.context): return False return checkPermission('big.brother.ViewAuditLog', self.context)
def __init__(self, context, request, view, manager=None): super(FooterViewlet, self).__init__(context, request, view, manager) # Set context to closest content to adapt the assignment mapping. self.context = context while not IContentish.providedBy(self.context) and \ not IPloneSiteRoot.providedBy(self.context): self.context = aq_parent(self.context)
def findContentish(context): # find context by walking up acquisition chain while True: context = aq_parent(context) if IContentish.providedBy(context): break elif IFolderish.providedBy(context): break return context
def test_provided(self): from Products.CMFCore.interfaces import IIndexableObjectWrapper from Products.CMFCore.interfaces import IIndexableObject obj = self._makeContent() w = self._makeOne({}, obj) self.assertTrue(IContentish.providedBy(w)) self.assertTrue(IIndexableObjectWrapper.providedBy(w)) self.assertTrue(IIndexableObject.providedBy(w))
def test_provided(self): from Products.CMFCore.interfaces import IContentish from plone.indexer.interfaces import IIndexableObjectWrapper from Products.CMFCore.tests.base.dummy import DummyContent obj = DummyContent() w = IndexableObjectWrapper(obj, self.portal.portal_catalog) self.assertTrue(IIndexableObjectWrapper.providedBy(w)) self.assertTrue(IContentish.providedBy(w))
def test_provided(self): from Products.CMFCore.interfaces import IContentish from Products.CMFCore.interfaces import IIndexableObjectWrapper from Products.CMFCore.tests.base.dummy import DummyContent obj = DummyContent() w = ExtensibleIndexableObjectWrapper(obj, self.portal) w.update(vars={}) self.failUnless(IContentish.providedBy(w)) self.failUnless(IIndexableObjectWrapper.providedBy(w))
def delObjects(cont, ids): """ abbreviation to delete objects """ delids = [id for id in ids if hasattr(aq_base(cont), id)] for delid in delids: try: obj = cont.get(delid) if not (IContentish.providedBy(obj) or IFolderish.providedBy(obj)): cont.manage_delObjects(delid) except (AttributeError, KeyError, BadRequest): logger.warning("Failed to delete '%s' in '%s'" % (delid, cont.id))
def _publish_structure(portal): wtool = getToolByName(portal, 'portal_workflow') logger = logging.getLogger('sac.aerofacil _publish_structure') to_publish = [i for i in portal.keys() if IContentish.providedBy(portal[i])] for i in to_publish: try: wtool.doActionFor(portal[i], "publish") except WorkflowException: logger.info("Could not publish: %s. Already published?" % i) pass
def publishTraverse(self, request, name): result = super(MinisiteImageTraverser, self).publishTraverse(request, name) if IContentish.providedBy(result): path = '/'.join(result.getPhysicalPath()) logger.debug('Traversing {0}'.format(path)) config = queryUtility(IMinisiteConfig, name=path) decorateRequest(request, config) checkPortlet(request, config) return result
def parent(self): context_state = getMultiAdapter((self.context, self.request), name=u'plone_context_state') context = aq_inner(self.context) parent = aq_parent(context) if context_state.is_default_page(): parent = aq_parent(parent) if INavigationRoot.providedBy(context) or (not IContentish.providedBy(parent) and not IPloneSiteRoot.providedBy(parent)): return return {'url': parent.absolute_url(), 'title': _(u'back to ${parent}', mapping=dict(parent=safe_unicode(parent.Title())))}
def copied(event): """When an object is copied, execute rules assigned to its parent """ obj = event.object if not (IContentish.providedBy(obj) or IComment.providedBy(obj)): return if is_portal_factory(obj): return execute(aq_parent(aq_inner(event.original)), event)
def update(self): common.ViewletBase.update(self) # Get portal_state and portal_url super(DropdownMenuViewlet, self).update() context = aq_inner(self.context) portal_props = getToolByName(context, 'portal_properties') self.properties = portal_props.navtree_properties self.enable_caching = api.portal.get_registry_record('webcouturier.dropdownmenu.browser.interfaces.IDropdownConfiguration.enable_caching') self.enable_parent_clickable = api.portal.get_registry_record('webcouturier.dropdownmenu.browser.interfaces.IDropdownConfiguration.enable_parent_clickable') self.navroot_path = getNavigationRoot(context) uid = api.content.get_uuid(obj=context) if IContentish.providedBy(context) else None self.data = Assignment(root_uid=uid)
def moved_event(event): # only execute moved event if it's not a added or removed event since # those are handled elsewhere and they base off of this event class if (IObjectAddedEvent.providedBy(event) or IObjectRemovedEvent.providedBy(event)): return obj = event.object if not (IContentish.providedBy(obj) or IComment.providedBy(obj)): return execute_event(event)
def show_first_accessible_object(self): mtool = getToolByName(self, 'portal_membership') for obj in self.context.objectValues(): if not IContentish.providedBy(obj): continue if not mtool.checkPermission('View', obj): continue return self.request.RESPONSE.redirect(obj.absolute_url()) # if no page is accessible, we show the folder_summary_view summary_view = self.context.restrictedTraverse('folder_summary_view') return summary_view()
def get_data(content, security=False, domain=None): """Return data to index in ES. """ uid = get_uid(content) if not uid: return None, None title = content.Title() try: # wrap content, so the SearchableText will be # delegated to IIndexer adapters as appropriate. # This will e.g. take care of PDF file indexing. cat = getToolByName(content, 'portal_catalog') wrapper = IndexableObjectWrapper(content, cat) text = getattr(wrapper, 'SearchableText', None) if safe_callable(text): text = text() except: text = title url = content.absolute_url() if domain: parts = urlparse.urlparse(url) url = urlparse.urlunparse((parts[0], domain) + parts[2:]) data = {'title': title, 'metaType': content.portal_type, 'sortableTitle': sortable_string(title), 'description': content.Description(), 'subject': content.Subject(), 'contributors': content.Contributors(), 'url': url, 'author': content.Creator(), 'content': text} if security: data['authorizedUsers'] = get_security(content) if hasattr(aq_base(content), 'pub_date_year'): data['publishedYear'] = getattr(content, 'pub_date_year') created = content.created() if created is not (None, 'None'): data['created'] = created.strftime('%Y-%m-%dT%H:%M:%S') modified = content.modified() if modified is not (None, 'None'): data['modified'] = modified.strftime('%Y-%m-%dT%H:%M:%S') if (not security or 'Anonymous' in data['authorizedUsers']) and \ IContentish.providedBy(content): data['suggest'] = ISuggester(content).terms() return uid, data
def removed(event): """When an IObjectRemovedEvent was received, execute rules assigned to its previous parent. """ obj = event.object if not IContentish.providedBy(obj): return if is_portal_factory(event.object): return execute(event.oldParent, event)
def removed(event): """When an IObjectRemovedEvent was received, execute rules assigned to its previous parent. """ obj = event.object if not (IContentish.providedBy(obj) or IComment.providedBy(obj)): return if is_portal_factory(obj): return execute(event.oldParent, event)
def __call__(self): result = { '@context': 'http://www.w3.org/ns/hydra/context.jsonld', '@id': self.context.absolute_url(), '@type': 'Plone Site', 'parent': {}, } result['member'] = [ getMultiAdapter((member, self.request), ISerializeToJsonSummary)() for member in self.context.objectValues() if IContentish.providedBy(member) ] return result
def get_workflow_for(context): wftool = getToolByName(getSite(), 'portal_workflow') while context and not IContentish.providedBy(context): context = aq_parent(aq_inner(context)) if not context: return None workflows = wftool.getWorkflowsFor(context) if len(workflows) == 0: return None else: return workflows[0]
def __call__(self): if IContentish.providedBy(self.published): context = self.published else: context = self.published.context favorite = FavoriteManager().get_favorite( context, api.user.get_current()) if not favorite: return None return str(favorite.favorite_id)
def moved(event): """ When an object is renamed/moved, execute rules assigned to its new parent.""" obj = event.object if (not event.oldParent or not event.newParent or getattr(obj, "_at_creation_flag", None)): return if is_portal_factory(obj): return elif IContentish.providedBy(obj): execute(event.newParent, event) else: return
def findContext(request): """Find the context from the request """ published = request.get('PUBLISHED', None) context = getattr(published, '__parent__', None) if context is not None: return context for parent in request.PARENTS: if IContentish.providedBy(parent) or ISiteRoot.providedBy(parent): return parent return request.PARENTS[0]
def getThemeStyle(self): context = self.context if not IContentish.providedBy(context): return '' fieldname = 'themeStyle' style = context.Schema()[fieldname].get(context) if not style: source = self._findSource(fieldname) if source: style = source.Schema()[fieldname].get(source) or '' return style or DEFAULT_STYLE
def modified(event): """When an object is modified, execute rules assigned to its parent """ obj = event.object if not IContentish.providedBy(obj): return # Let the special handler take care of IObjectInitializedEvent for event_if in (IObjectInitializedEvent, IObjectAddedEvent, IObjectRemovedEvent, IContainerModifiedEvent): if event_if.providedBy(event): return execute_rules(event)
def __call__(self): result = { '@context': 'http://www.w3.org/ns/hydra/context.jsonld', '@id': self.context.absolute_url(), '@type': 'Plone Site', 'parent': {}, } result['member'] = [{ '@id': member.absolute_url(), 'title': member.title, 'description': member.description } for member in self.context.objectValues() if IContentish.providedBy(member)] return result
def _valid_context(context): """Walk up until finding a content item.""" # Avoid loops. The object id is used as context may not be hashable seen = set() while context is not None and id(aq_base(context)) not in seen: seen.add(id(aq_base(context))) if (IContentish.providedBy(context) or IFolderish.providedBy(context)): return context parent = getattr(context, '__parent__', None) if parent is None: parent = getattr(context, 'context', None) context = parent return None
def get_editor_language(request): """ Get editor language override if Silvuple is installed. """ cached = getattr(request, "_cached_admin_language", None) if cached: return cached if not ICsAdminlanguageLayer.providedBy(request): # Add on is not active return None context = find_context(request) # Filter out CSS and other non-sense # IFolderish check includes site root if not (IContentish.providedBy(context) or IFolderish.providedBy(context)): # Early terminate return None # Check if we are the editor if not getSecurityManager().checkPermission( "cs.adminlanguage: ViewinAdminLanguage", context ): # Anon visitor, normal language -> return None try: # Will raise an exception if plone.app.registry is not quick installed registry = getUtility(IRegistry) # Will raise exception if your product add-on installer has not been run settings = registry.forInterface(ISettings, prefix="admin_language") except (KeyError, ComponentLookupError): # Registry schema and actual values do not match # Quick installer has not been run or need to rerun # to update registry.xml values to database return None # Read language from settings language = settings.adminLanguage if language: # Fake new language for all authenticated users request._cached_admin_language = language return language return None
def getData(self, obj): """ return the expected mapping, see `INextPreviousProvider` """ if not self.security.checkPermission('View', obj): return None elif not IContentish.providedBy(obj): # do not return a not contentish object # such as a local workflow policy for example (#11234) return None ptype = obj.portal_type url = obj.absolute_url() if ptype in self.vat: # "use view action in listings" url += '/view' return dict(id=obj.getId(), url=url, title=obj.Title(), description=obj.Description(), portal_type=ptype)
def modified(event): """When an object is modified, execute rules assigned to its parent """ obj = event.object if not (IContentish.providedBy(obj) or IComment.providedBy(obj)): return # Let the special handler take care of IObjectInitializedEvent for event_if in (IObjectInitializedEvent, IObjectAddedEvent, IObjectRemovedEvent, IContainerModifiedEvent, IObjectCopiedEvent): if event_if.providedBy(event): return execute_rules(event)
def get_editor_language(request): """ Get editor language override if Silvuple is installed. """ cached = getattr(request, "_cached_admin_language", None) if cached: return cached if not IAddonSpecific.providedBy(request): # Add on is not active return None context = find_context(request) # Filter out CSS and other non-sense # IFolderish check includes site root if not (IContentish.providedBy(context) or IFolderish.providedBy(context)): # Early terminate return None # Check if we are the editor if not getSecurityManager().checkPermission(permissions.ModifyPortalContent, context): # Anon visitor, normal language -> return None try: # Will raise an exception if plone.app.registry is not quick installed registry = getUtility(IRegistry) # Will raise exception if your product add-on installer has not been run settings = registry.forInterface(ISettings) except (KeyError, ComponentLookupError): # Registry schema and actual values do not match # Quick installer has not been run or need to rerun # to update registry.xml values to database return None # Read language from settings language = settings.adminLanguage if language: # Fake new language for all authenticated users request._cached_admin_language = language return language return None
def __call__(self, **kwargs): alsoProvides(self, IRoleManager) if IContentish.providedBy(self.context): alsoProvides(self, IContentish) if IMinimalDublinCore.providedBy(self.context): alsoProvides(self, IMinimalDublinCore) if IWorkflowAware.providedBy(self.context): alsoProvides(self, IWorkflowAware) if IDublinCore.providedBy(self.context): alsoProvides(self, IDublinCore) if ICatalogableDublinCore.providedBy(self.context): alsoProvides(self, ICatalogableDublinCore) for key, value in kwargs.items(): setattr(self, key, value) return self.__of__(self.context)
def list_content(content): """Recursively list CMF content out of the given one. ``callback`` is called every thousand items after a commit. """ def recurse(content): for child in content.contentValues(): if IFolderish.providedBy(child): for grandchild in recurse(child): yield grandchild yield child if IFolderish.providedBy(content): for child in recurse(content): yield child yield content elif IContentish.providedBy(content): yield content
def modified(event): """When an object is modified, fire the ParentModifiedEvent for its direct descendents. """ obj = event.object if not (IContentish.providedBy(obj) or IComment.providedBy(obj) or IFolderish.providedBy(obj)): return # IObjectModified event is called when a site is created, but before the # catalog has been initialised which throws an AttributeError exception. try: children = obj.getFolderContents() except AttributeError: return for child in children: notify(ParentModifiedEvent(child.getObject()))
def object_removed(obj, event): """ an object is being deleted - also delete it's history """ if not IContentish.providedBy(obj): return try: histories_storage = getToolByName(obj, 'portal_historiesstorage') repo_tool = getToolByName(obj, 'portal_repository') except AttributeError: # XXX If tools are missing, there is nothing we can do. # This occurs in some Products.CMFDiffTool and # Products.CMFTestCase tests for 4.3.x. Maybe it should # be fixed there. return obj, histid = dereference(obj) if histid is None: return metadata = repo_tool.getHistoryMetadata(obj) try: num_versions = metadata.getLength(countPurged=False) except AttributeError: # portal_historiesstorage will return # an empty list in certain cases, # do nothing return current = metadata.retrieve(num_versions - 1) sys_metadata = current['metadata']['sys_metadata'] if ('parent' in sys_metadata) and \ (sys_metadata['parent']['history_id'] != histid): try: histories_storage.retrieve( history_id=sys_metadata['parent']['history_id']) return except StorageRetrieveError: pass length = len(histories_storage.getHistory(histid, countPurged=False)) for i in range(length): histories_storage.purge( histid, 0, metadata={'sys_metadata': { 'comment': 'purged' }}, countPurged=False)
def update(self): common.ViewletBase.update(self) # Get portal_state and portal_url super(MegamenuViewlet, self).update() context = aq_inner(self.context) portal_props = plone.api.portal.get_tool('portal_properties') self.properties = portal_props.navtree_properties self.navroot_path = getNavigationRoot(context) self.navroot_path = getNavigationRoot(context) try: if IContentish.providedBy(context): uid = plone.api.content.get_uuid(obj=context) else: uid = None except TypeError: # ArcheTypes (such as PFG FormFolder) have no UID yet when the # factory gets called. uid = None self.data = Assignment(root_uid=uid)
def findView(tile, viewName): """Find the view to use for portlet/viewlet context lookup.""" view = tile prequest = tile.request.get('PARENT_REQUEST', None) # Provide IViewView by default when tile is rendered with contentish # context outside subrequest, but don't return to still support custom # policies if prequest is None and IContentish.providedBy(tile.context): alsoProvides(view, IViewView) # Attempt to determine the underlying view name from the parent request # XXX: This won't work if using ESI rendering or any other # technique that doesn't use plone.subrequest if viewName is None and prequest is not None: ppublished = prequest.get('PUBLISHED', None) if IView.providedBy(ppublished): viewName = prequest['PUBLISHED'].__name__ request = tile.request if prequest is not None: request = prequest if viewName is not None: try: view = queryMultiAdapter((tile.context, request), name=viewName) except TypeError: # Helps to debug an issue where broken view registration raised: # TypeError: __init__() takes exactly N arguments (3 given) logger.exception('Error in resolving view for tile: {0:s}'.format( tile.url)) view = None if view is None: view = tile # Decide whether to mark the view # XXX: Again, this probably won't work well if not using plone.subrequest layoutPolicy = queryMultiAdapter((tile.context, request), name='plone_layout') # noqa if layoutPolicy is not None: layoutPolicy.mark_view(view) return view