class WebDAVProperties(grok.Adapter, collections.MutableMapping): grok.context(zeit.retresco.interfaces.ITMSContent) grok.provides(zeit.connector.interfaces.IWebDAVProperties) def __getitem__(self, key): name, ns = map(unquote_es_field_name, key) namespace = ns.replace(zeit.retresco.interfaces.DAV_NAMESPACE_BASE, '', 1) return self.context._tms_payload[namespace][name] def keys(self): for ns, values in self.context._tms_payload.items(): namespace = zeit.retresco.interfaces.DAV_NAMESPACE_BASE + ns for name in values: yield (unquote_es_field_name(name), unquote_es_field_name(namespace)) def __iter__(self): return iter(self.keys()) def __len__(self): return len(self.keys()) def __delitem__(self, key): raise RuntimeError("Cannot write on ReadOnlyWebDAVProperties") def __setitem__(self, key, value): raise RuntimeError("Cannot write on ReadOnlyWebDAVProperties")
class Reference(zeit.cms.content.reference.Reference): grok.implements(zeit.content.author.interfaces.IAuthorReference) grok.provides(zeit.content.author.interfaces.IAuthorReference) grok.name('author') location = zeit.cms.content.property.ObjectPathProperty('.location')
class DisplayWidget(grok.MultiAdapter, zope.formlib.itemswidgets.ItemsWidgetBase): grok.adapts(zope.schema.interfaces.ITuple, zeit.wochenmarkt.interfaces.IRecipeCategoriesSource, zeit.cms.browser.interfaces.ICMSLayer) grok.provides(zope.formlib.interfaces.IDisplayWidget) template = zope.app.pagetemplate.ViewPageTemplateFile( 'display-recipe-categories.pt') def __init__(self, field, source, request): super(DisplayWidget, self).__init__( field, zope.formlib.source.IterableSourceVocabulary(source, request), request) def __call__(self): return self.template() def items(self): items = [] RecipeCategory = namedtuple('RecipeCategory', ['text']) for item in self._getFormValue(): text = self.textForValue(self.vocabulary.getTerm(item)) items.append(RecipeCategory(text)) return items
class BioReference(zeit.cms.content.reference.Reference): grok.implements(zeit.content.author.interfaces.IAuthorBioReference) grok.provides(zeit.content.author.interfaces.IAuthorBioReference) grok.name('authorbio') biography = zeit.cms.content.property.ObjectPathProperty('.biography')
class BreadcrumbContentProvider( grok.MultiAdapter, zope.contentprovider.provider.ContentProviderBase): """Content provider rendering the breadcrumbs.""" grok.adapter(zope.interface.Interface, icemac.addressbook.browser.interfaces.IAddressBookLayer, zope.interface.Interface) grok.provides(zope.contentprovider.interfaces.IContentProvider) grok.name('breadcrumbs') def render(self): return '\n'.join(self.rendered_breadcrumbs) @property def rendered_breadcrumbs(self): for bc in reversed(list(self.reversed_breadcrumbs)): yield bc.render() @property def reversed_breadcrumbs(self): bc = self.get_breadcrumb(self.__parent__) parent = bc.parent while parent is not None: if bc.show: yield bc bc = self.get_breadcrumb(parent) parent = bc.parent assert not bc.show, 'Found a root breadcrumb with show = True' def get_breadcrumb(self, context): return zope.component.getMultiAdapter((context, self.request), IBreadcrumb)
class VirtualProperties(zeit.connector.resource.WebDAVProperties, grok.Adapter): grok.context(zeit.content.dynamicfolder.interfaces.IVirtualContent) grok.provides(zeit.connector.interfaces.IWebDAVProperties) def __init__(self, context): super(VirtualProperties, self).__init__() self.context = context self.update(self.parse(context.xml)) # XXX zeit.cms.content.xmlsupport.PropertyToXMLAttribute violates # the contract by assuming that IWebDAVProperties of IRepositoryContent # also provides zeit.cms.content.liveproperty.LiveProperties methods. def is_writeable_on_checkin(self, name, namespace): return True @classmethod def parse(cls, body): properties = {} if isinstance(body, (six.binary_type, six.text_type)): try: body = lxml.etree.fromstring(body) except lxml.etree.LxmlError: return properties # See zeit.connector.filesystem.Connector._get_properties attributes = body.xpath('//head/attribute') for attr in attributes: properties[attr.get('name'), attr.get('ns')] = attr.text or '' properties.pop(zeit.connector.interfaces.UUID_PROPERTY, None) return properties
class Container(zeit.edit.container.TypeOnAttributeContainer, grok.MultiAdapter): grok.provides(IContainer) grok.adapts(IContainer, gocept.lxml.interfaces.IObjectified) type = 'container' grok.name(type)
class Token(zeit.cms.content.dav.DAVPropertiesAdapter): grok.provides(zeit.vgwort.interfaces.IToken) zeit.cms.content.dav.mapProperties(zeit.vgwort.interfaces.IToken, 'http://namespaces.zeit.de/CMS/vgwort', ('public_token', 'private_token'), writeable=WRITEABLE_LIVE)
class RelatedReference(zeit.cms.content.reference.Reference): grok.adapts(zeit.content.article.edit.interfaces.IAuthor, gocept.lxml.interfaces.IObjectified) grok.provides(zeit.cms.content.interfaces.IReference) grok.name('related') biography = zeit.cms.content.property.ObjectPathProperty('.biography')
class ReportInfo(zeit.cms.content.dav.DAVPropertiesAdapter): grok.provides(zeit.vgwort.interfaces.IReportInfo) zeit.cms.content.dav.mapProperties(zeit.vgwort.interfaces.IReportInfo, 'http://namespaces.zeit.de/CMS/vgwort', ('reported_on', 'reported_error'), writeable=WRITEABLE_LIVE)
class HeaderArea(zeit.content.article.edit.container.TypeOnTagContainer, grok.MultiAdapter): grok.provides(zeit.content.article.edit.interfaces.IHeaderArea) grok.adapts(zeit.content.article.interfaces.IArticle, gocept.lxml.interfaces.IObjectified) __name__ = HEADER_NAME def insert(self, position, item): self.clear() return super(HeaderArea, self).insert(position, item) def add(self, item): self.clear() return super(HeaderArea, self).add(item) def clear(self): for key in list(self.keys()): self._delete(key) def _get_keys(self, xml_node): result = [] for child in xml_node.iterchildren(): result.append(self._set_default_key(child)) return result def values(self): # We re-implement values() so it works without keys(), since those are # not present in the repository. result = [] for child in self.xml.iterchildren(): element = self._get_element_for_node(child) if element is None: element = self._get_element_for_node( child, zeit.edit.block.UnknownBlock.type) result.append(element) return result @property def module(self): values = self.values() if values: return values[0] # XXX Kludgy emulation of things that should be in the header, but # aren't yet. body = zeit.content.article.edit.interfaces.IEditableBody( self.__parent__) try: block = body[0] except KeyError: return None if ((zeit.content.article.edit.interfaces.IVideo.providedBy(block) and 'header' in (block.layout or '')) or (zeit.content.article.edit.interfaces.IImage.providedBy(block) and block.display_mode != 'float')): return block return None
class Home3(grok.MultiAdapter): grok.adapts(Cave, Fireplace) grok.implements(IHome, IFireplace) grok.provides(IHome) grok.name('home3') def __init__(self, cave, fireplace): self.cave = cave self.fireplace = fireplace
class PlainTextSerializer(grok.GlobalUtility): grok.provides(ISerializer) grok.name("text") content_type = "text/plain" def serialize(self, body): return body def deserialize(self, body): return body
class CookiesCredentials(grok.GlobalUtility, SessionCredentialsPlugin): grok.name("cookies") grok.provides(ICredentialsPlugin) # ILocation's information __parent__ = None # Required by zope.pluggableauth's IBrowserFormChallenger loginpagename = "login" loginfield = "login" passwordfield = "password" # Required by zope.pluggableauth's ICredentialsPlugin challengeProtocol = None cookie_name = "dolmen.authcookie" @staticmethod def make_cookie(login, password): credstr = f"{login.decode('utf-8')}:{password.decode('utf-8')}" val = base64.encodebytes(credstr.encode('utf-8')) return urllib.parse.quote(val) def extractCredentials(self, request): if not IHTTPRequest.providedBy(request): return login = request.get(self.loginfield, None) password = request.get(self.passwordfield, None) cookie = request.get(self.cookie_name, None) if login and password: login = login.encode('utf-8') password = password.encode('utf-8') cookie = self.make_cookie(login, password) request.response.setCookie(self.cookie_name, cookie, path="/") elif cookie: val = base64.decodebytes( urllib.parse.unquote(cookie).encode("utf-8")) login, password = val.split(b":") else: return return { "login": login.decode('utf-8'), "password": password.decode('utf-8') } def logout(self, request): if not IHTTPRequest.providedBy(request): return request.response.expireCookie(self.cookie_name, path="/") session = ISession(request, None) if session is not None: session.delete()
class JSONSerializer(grok.GlobalUtility): grok.provides(ISerializer) grok.name("json") content_type = "application/x-json" def serialize(self, body): return json.dumps(body) def deserialize(self, body): return json.loads(body)
class PickleSerializer(grok.GlobalUtility): grok.provides(ISerializer) grok.name("pickle") content_type = "application/x-python-serialize" def serialize(self, body): return cPickle.dumps(body) def deserialize(self, body): return cPickle.loads(body)
class MessagePackSerializer(grok.GlobalUtility): grok.provides(ISerializer) grok.name("msgpack") content_type = "application/x-msgpack" def serialize(self, body): return msgpack.packb(body, encoding='utf-8') def deserialize(self, body): return msgpack.unpackb(body, encoding='utf-8')
class DayTimeActivity(grok.MultiSubscription): grok.provides(IActivity) grok.adapts(Cave, Mammoth) grok.baseclass() def __init__(self, where, who): self.where = where self.who = who def do(self): print 'Doing nothing.'
class Workflow(zeit.workflow.timebased.TimeBasedWorkflow, grok.Adapter): grok.context(zeit.newsletter.interfaces.INewsletter) grok.provides(zeit.newsletter.interfaces.INewsletterWorkflow) zeit.cms.content.dav.mapProperties( zeit.newsletter.interfaces.INewsletterWorkflow, zeit.workflow.interfaces.WORKFLOW_NS, ('sent', ), use_default=True, writeable=WRITEABLE_LIVE) def can_publish(self): return zeit.cms.workflow.interfaces.CAN_PUBLISH_SUCCESS
class RelatedReference(zeit.cms.content.reference.Reference): grok.adapts(zeit.content.article.edit.interfaces.IVolume, gocept.lxml.interfaces.IObjectified) grok.provides(zeit.cms.content.interfaces.IReference) grok.name('related') _teaserText_local = zeit.cms.content.property.ObjectPathAttributeProperty( '.', 'teasertext_local', zeit.content.volume.interfaces.IVolumeReference['teaserText']) teaserText = zeit.cms.content.reference.OverridableProperty( zeit.content.volume.interfaces.IVolume['teaserText'], original='target')
class IngredientsWidget(grok.MultiAdapter, zope.formlib.widget.SimpleInputWidget, zeit.cms.browser.view.Base): """Widget to edit ingredients on context. """ grok.adapts(zope.schema.interfaces.ITuple, zeit.wochenmarkt.interfaces.IIngredientsSource, zeit.cms.browser.interfaces.ICMSLayer) grok.provides(zope.formlib.interfaces.IInputWidget) template = zope.app.pagetemplate.ViewPageTemplateFile( 'ingredients_widget.pt') def __init__(self, context, source, request): super(IngredientsWidget, self).__init__(context, request) self.source = source def __call__(self): return self.template() @property def autocomplete_source_url(self): return self.url(zope.component.hooks.getSite(), '@@ingredients_find') @property def uuid(self): return zeit.cms.content.interfaces.IUUID(self.context.context).id def _toFormValue(self, value): return json.dumps([{ 'code': x.code, 'label': x.label, 'amount': x.amount, 'unit': x.unit, 'details': x.details } for x in value or ()]) def _toFieldValue(self, value): data = json.loads(value) return tuple([ Ingredient(x['code'], x['label'], amount=x['amount'], unit=x['unit'], details=x['details']) for x in data ])
class Body(zeit.edit.container.TypeOnAttributeContainer, grok.MultiAdapter): __name__ = BODY_NAME grok.provides(zeit.newsletter.interfaces.IBody) grok.adapts(zeit.newsletter.interfaces.INewsletter, gocept.lxml.interfaces.IObjectified) grok.name(BODY_NAME) def values(self): # We re-implement values() so it works without keys(), since those are # not present in the repository, but since e.g. zeit.frontend is only # interested in the values, anyway, this works out alright. result = [] for node in self.xml.iterchildren(): result.append(self._get_element_for_node(node)) return result
class Body(zeit.edit.container.Base, grok.MultiAdapter): grok.provides(zeit.content.cp.interfaces.IBody) grok.adapts(zeit.content.cp.interfaces.ICenterPage, gocept.lxml.interfaces.IObjectified) __name__ = BODY_NAME _find_item = lxml.etree.XPath('./*[@area = $name]') _get_keys = lxml.etree.XPath('./*/@area') def _get_element_type(self, xml_node): return 'region' def __getitem__(self, key): if key in ['lead', 'informatives']: # backwards compatiblity for tests return self['feature'][key] return super(Body, self).__getitem__(key)
class Group(zeit.edit.container.TypeOnAttributeContainer, grok.MultiAdapter): grok.provides(zeit.newsletter.interfaces.IGroup) grok.adapts(zeit.newsletter.interfaces.IBody, gocept.lxml.interfaces.IObjectified) type = 'group' grok.name(type) title = zeit.cms.content.property.ObjectPathProperty( '.head.title', zeit.newsletter.interfaces.IGroup['title']) def values(self): # We re-implement values() so it works without keys(), since those are # not present in the repository, but since e.g. zeit.frontend is only # interested in the values, anyway, this works out alright. result = [] for node in self.xml.xpath('container'): result.append(self._get_element_for_node(node)) return result
class AutocompleteSourceQuery(grok.MultiAdapter, zeit.cms.browser.view.Base): grok.adapts(zeit.cms.content.interfaces.IAutocompleteSource, zeit.cms.browser.interfaces.ICMSLayer) grok.provides(zope.formlib.interfaces.ISourceQueryView) def __init__(self, source, request): self.source = source self.request = request def __call__(self): return (u'<input type="text" class="autocomplete" ' u'placeholder={placeholder} ' u'cms:autocomplete-source="{url}" />').format( url=zope.component.queryMultiAdapter( (self.source, self.request), zeit.cms.browser.interfaces.ISourceQueryURL), placeholder=xml.sax.saxutils.quoteattr( zope.i18n.translate(_('Type to find entries ...'), context=self.request)))
class RecipeCategoriesWidget(grok.MultiAdapter, zope.formlib.widget.SimpleInputWidget, zeit.cms.browser.view.Base): """Widget to edit recipe categories on context. """ grok.adapts(zope.schema.interfaces.ITuple, zeit.wochenmarkt.interfaces.IRecipeCategoriesSource, zeit.cms.browser.interfaces.ICMSLayer) grok.provides(zope.formlib.interfaces.IInputWidget) template = zope.app.pagetemplate.ViewPageTemplateFile( 'categories_widget.pt') def __init__(self, context, source, request): super(RecipeCategoriesWidget, self).__init__(context, request) self.source = source def __call__(self): return self.template() @property def autocomplete_source_url(self): return self.url(zope.component.hooks.getSite(), '@@recipe_categories_find') @property def uuid(self): return zeit.cms.content.interfaces.IUUID(self.context.context).id def _toFormValue(self, value): return json.dumps([{ 'code': x.code, 'label': x.name } for x in value or ()]) def _toFieldValue(self, value): data = json.loads(value) return tuple([RecipeCategory(x['code'], x['label']) for x in data])
class LoggingErrorReporting(object): grok.provides(zope.error.interfaces.IErrorReportingUtility) def __init__( self, info_level_errors=None, warning_level_errors=None, always_exc_info=False): self.logger = logging.getLogger('grokcore.error') self.info_level_errors = info_level_errors self.warning_level_errors = warning_level_errors self.always_exc_info = always_exc_info def make_extra(self, request=None): return None def raising(self, exc_info, request=None): exc_class = exc_info[0] msg = '%s %s' % (exc_info[0].__name__, str(exc_info[1])) if request is not None: url = getattr(request, 'URL', None) if url is not None: msg += (' (URL: %s)' % url) level = self.logger.error if self.info_level_errors and \ issubclass(exc_class, self.info_level_errors): level = self.logger.info exc_info = exc_info if self.always_exc_info else None elif self.warning_level_errors and \ issubclass(exc_class, self.warning_level_errors): level = self.logger.warning exc_info = exc_info if self.always_exc_info else None try: level(msg, exc_info=exc_info, extra=self.make_extra(request)) finally: exc_info = None # gc cleanup.
class ViewAbsoluteURL(absoluteurl.AbsoluteURL, grok.MultiAdapter): grok.adapts(IGrokView, IBrowserRequest) grok.provides(IAbsoluteURL) def _obj(self): return aq_inner(self.context.context) def __str__(self): return self._obj().absolute_url() + '/' + self.context.__view_name__ __call__ = __str__ def breadcrumbs(self): obj_breadcrumbs = component.getMultiAdapter( (self._obj(), self.request), IAbsoluteURL).breadcrumbs() obj_breadcrumbs += ({ 'name': self.context.__view_name__, 'url': self() }, ) return obj_breadcrumbs
class Breadcrumb(grok.MultiAdapter, icemac.addressbook.browser.base.BaseView): """Base breadcrumb implementation.""" grok.baseclass() grok.provides(IBreadcrumb) show = True template = ViewPageTemplateFile('breadcrumb.pt') def __init__(self, context, request): self.context = context self.request = request @property def title(self): try: title = icemac.addressbook.interfaces.ITitle(self.context) except (zope.security.interfaces.ForbiddenAttribute, ValueError): # pragma: no cover title = "{}: <unprintable title>".format( self.context.__class__.__name__) return title @property def target_url(self): return self.url(self.context) @property def parent(self): return zope.traversing.api.getParent(self.context) def __repr__(self): """Custom representation for breadcrumbs.""" return '<{0}: {1.title!r}>'.format( icemac.addressbook.utils.dotted_name(self.__class__), self) def render(self): return self.template()
class UniqueMessageSource(grok.GlobalUtility): """A source that handles a unique message. """ grok.baseclass() grok.implements(IMessageSource) grok.provides(IMessageSource) message = None def send(self, message, type=u'message'): self.message = PersistentMessage(message, type) def list(self, type=None): if self.message is None: return if type is None or self.message.type == type: yield self.message def delete(self, message): if message is self.message: self.message = None else: raise KeyError(message)