def path_traverse(base, econtext, call, path_items): if path_items: request = econtext.get("request") path_items = list(path_items) path_items.reverse() while path_items: name = path_items.pop() ns_used = ":" in name if ns_used: namespace, name = name.split(":", 1) base = z3c.pt.namespaces.function_namespaces[namespace](base) if ITraversable.providedBy(base): base = traversePathElement(base, name, path_items, request=request) # base = proxify(base) continue # special-case dicts for performance reasons if isinstance(base, dict): next = base.get(name, _marker) else: next = getattr(base, name, _marker) if next is not _marker: base = next if ns_used and isinstance(base, MethodType): base = base() # The bytecode peephole optimizer removes the next line: continue # pragma: no cover else: base = traversePathElement(base, name, path_items, request=request) # if not isinstance(base, (basestring, tuple, list)): # base = proxify(base) if call and getattr(base, "__call__", _marker) is not _marker: return base() return base
def path_traverse(base, econtext, call, path_items): if path_items: request = econtext.get('request') path_items = list(path_items) path_items.reverse() while len(path_items): name = path_items.pop() ns_used = ':' in name if ns_used: namespace, name = name.split(':', 1) base = z3c.pt.namespaces.function_namespaces[namespace](base) if ITraversable.providedBy(base): base = traversePathElement(base, name, path_items, request=request) # base = proxify(base) continue # special-case dicts for performance reasons if isinstance(base, dict): next = base.get(name, _marker) else: next = getattr(base, name, _marker) if next is not _marker: base = next if ns_used and isinstance(base, MethodType): base = base() continue else: base = traversePathElement(base, name, path_items, request=request) # if not isinstance(base, (basestring, tuple, list)): # base = proxify(base) if call and getattr(base, '__call__', _marker) is not _marker: return base() return base
def path_traverse(base, econtext, call, path_items): if path_items: request = econtext.get("request") path_items = list(path_items) path_items.reverse() while path_items: name = path_items.pop() ns_used = ":" in name if ns_used: namespace, name = name.split(":", 1) base = z3c.pt.namespaces.function_namespaces[namespace](base) if ITraversable.providedBy(base): base = traversePathElement( base, name, path_items, request=request ) # base = proxify(base) continue # special-case dicts for performance reasons if isinstance(base, dict): next = base.get(name, _marker) else: next = getattr(base, name, _marker) if next is not _marker: base = next if ns_used and isinstance(base, MethodType): base = base() # The bytecode peephole optimizer removes the next line: continue # pragma: no cover else: base = traversePathElement( base, name, path_items, request=request ) # if not isinstance(base, (basestring, tuple, list)): # base = proxify(base) if call and getattr(base, "__call__", _marker) is not _marker: return base() return base
def path_traverse(base, econtext, call, path_items): if path_items: request = econtext.get('request') path_items = list(path_items) path_items.reverse() while len(path_items): name = path_items.pop() ns_used = ':' in name if ns_used: namespace, name = name.split(':', 1) base = z3c.pt.namespaces.function_namespaces[namespace](base) if ITraversable.providedBy(base): base = traversePathElement( base, name, path_items, request=request) # base = proxify(base) continue # special-case dicts for performance reasons if isinstance(base, dict): next = base.get(name, _marker) else: next = getattr(base, name, _marker) if next is not _marker: base = next if ns_used and isinstance(base, MethodType): base = base() continue else: base = traversePathElement( base, name, path_items, request=request) # if not isinstance(base, (basestring, tuple, list)): # base = proxify(base) if call and getattr(base, '__call__', _marker) is not _marker: return base() return base
def testImplementsITraversable(self): self.assertTrue(ITraversable.providedBy(DefaultTraversable(None)))
def testImplementsITraversable(self): self.failUnless(ITraversable.providedBy(DefaultTraversable(None)))
def __call__(self, text, file_path=None): dom = getDom(text) if not dom: return text for link in dom.cssselect('a[href],img[src]'): link = LinkElement(link) url = link.val.rstrip('/').strip() match_path = url.replace('%20', ' ').lstrip('/').strip() if type(match_path) == unicode: match_path = match_path.encode('utf-8') obj = self.context.unrestrictedTraverse(match_path, None) ext = match_path.split('.')[-1].lower() ext = ext in ('png', 'jpg', 'gif', 'jpeg') and ext or 'jpg' if obj and isinstance(obj, ATImage) or ( hasattr(obj, 'getBlobWrapper') and \ 'image' in obj.getBlobWrapper().getContentType()): link.set(url + '/image.%s' % ext) elif obj and isinstance(obj, ArchetypesImage): # it's a scale, always use image.jpg extension link.set(url + '/image.jpg') if not obj: try: path, filename = match_path.rsplit('/', 1) except ValueError: continue fieldname = filename.split('_', 1)[0] obj = self.context.restrictedTraverse('/'.join((path, fieldname)), None) if not obj: # not all fields are traversable obj = self.context.restrictedTraverse(path, None) if IImageScaling.providedBy(obj) or \ ITraversable.providedBy(obj): # we can't do anything with the @@images view yet here... obj = None if obj and hasattr(obj, 'getField'): field = obj.getField(fieldname) if field: obj = field.get(obj) if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj): link.set(url + '/image.jpg') if not obj: if '/@@images/' in match_path: parent_path, image_name = match_path.split('/@@images/') spl_img_name = image_name.split('/') if len(spl_img_name) == 1: # no scalename in path uid = spl_img_name[0] if '-' in uid: # seems to be actual uid for a custom scale here... # it should written out as [uid].[ext] new_path = '/'.join((parent_path, uid)) else: # just use original if we can't figure this out... new_path = '/'.join((parent_path, 'image.%s' % ext)) else: # scalename in path fieldname, scalename = spl_img_name new_path = '/'.join((parent_path, '_'.join((fieldname, scalename)))) new_path = new_path + '/image.jpg' new_path = '/' + new_path.lstrip('/') link.set(new_path) return unicode(dom)
def __call__(self, request): # pylint:disable=too-many-locals,too-many-branches,too-many-statements """ See :meth:`pyramid.interfaces.ITraversar.__call__`. """ # JAM: Unfortunately, the superclass implementation is entirely monolithic # and we so we cannot reuse any part of it. Instead, # we copy-and-paste it. Unless otherwise noted, comments below are # original. # JAM: Note the abundance of no covers. These are for features we are # not currently using and the code is lifted directly from pyramid. environ = request.environ if request.matchdict is not None: matchdict = request.matchdict path = matchdict.get('traverse', '/') or '/' if is_nonstr_iter(path): # this is a *traverse stararg (not a {traverse}) # routing has already decoded these elements, so we just # need to join them path = '/'.join(path) or '/' subpath = matchdict.get('subpath', ()) if not is_nonstr_iter(subpath): # pragma: no cover # this is not a *subpath stararg (just a {subpath}) # routing has already decoded this string, so we just need # to split it subpath = split_path_info(subpath) else: # pragma: no cover # this request did not match a route subpath = () try: # empty if mounted under a path in mod_wsgi, for example path = decode_path_info(environ['PATH_INFO'] or '/') except KeyError: path = '/' except UnicodeDecodeError as e: raise URLDecodeError(e.encoding, e.object, e.start, e.end, e.reason) if VH_ROOT_KEY in environ: # pragma: no cover # HTTP_X_VHM_ROOT vroot_path = decode_path_info(environ[VH_ROOT_KEY]) vroot_tuple = split_path_info(vroot_path) # both will (must) be unicode or asciistr vpath = vroot_path + path vroot_idx = len(vroot_tuple) - 1 else: vroot_tuple = () vpath = path vroot_idx = -1 root = self.root ob = vroot = root if vpath == '/': # invariant: vpath must not be empty # prevent a call to traversal_path if we know it's going # to return the empty tuple vpath_tuple = () else: i = 0 view_selector = self.VIEW_SELECTOR # A list so that remaining_path can be modified vpath_tuple = list(split_path_info(vpath)) for segment in vpath_tuple: # JAM: Fire traversal events, mainly so sites get installed. See # zope.publisher.base. _notify_before_traverse_event(ob, request) # JAM: Notice that checking for '@@' is special cased, and # doesn't go through the normal namespace lookup as it would in # plain zope traversal. (XXX: Why not?) if segment.startswith(view_selector): # pragma: no cover return { 'context': ob, 'view_name': segment[2:], 'subpath': vpath_tuple[i + 1:], 'traversed': vpath_tuple[:vroot_idx + i + 1], 'virtual_root': vroot, 'virtual_root_path': vroot_tuple, 'root': root } try: # JAM: This is where we differ. instead of using __getitem__, # we use the traversing machinery. # The zope app would use IPublishTraverser, which # would install security proxies along the way. We probably don't need to # do that? TODO: # NOTE: By passing the request here, we require all traversers # (including the namespace traversers) to be registered as multi-adapters. # None of the default namespaces are. See our # configure.zcml for what is. # JAM: Damn stupid implementation of traversePathElement ignores # the request argument to find a traversable /except/ when a namespace is found. # therefore, we explicitly query for the multi adapter ourself in the non-namespace case # (In the namespace case, we let traversing handle it, because it needs a named adapter # after parsing) traversable = None if segment and segment[0] not in '+@' \ and not ITraversable.providedBy(ob): try: # Use the installed component registry # instead of the request registry (which # is the global component registry if # pyramid was configured that way, or a # standalone registry) in case the act of # traversing has changed the site manager; # zope.site.site.threadSiteSubscriber will # do this for each BeforeTraverseEvent # that's fired (though that's not # registered by default). traversable = queryMultiAdapter((ob, request), ITraversable) except TypeError: # Some things are registered for "*" (DefaultTraversable) # which means they get called here. If they can't take # two arguments, then we bail. Sucks. pass remaining_path = vpath_tuple[i + 1:] next_ob = ztraversing.traversePathElement( ob, segment, remaining_path, traversable=traversable, request=request) if remaining_path != vpath_tuple[i + 1:]: # Is this if check necessary? It would be faster to # always assign vpath_tuple[i + 1:] = remaining_path except LocationError: # LocationError is a type of KeyError. The DefaultTraversable turns # plain KeyError and TypeErrors into LocationError. return { 'context': ob, 'view_name': segment, 'subpath': vpath_tuple[i + 1:], 'traversed': vpath_tuple[:vroot_idx + i + 1], 'virtual_root': vroot, 'virtual_root_path': vroot_tuple, 'root': root } if i == vroot_idx: # pragma: no cover vroot = next_ob ob = next_ob i += 1 # JAM: Also fire before traversal for the actual context item, since we # won't actually traverse into it. Be sure not to fire multiple times # for this (E.g., the root). This logic is complicated by the # multi-returns above. _notify_before_traverse_event(ob, request) return { 'context': ob, 'view_name': empty, 'subpath': subpath, 'traversed': vpath_tuple, 'virtual_root': vroot, 'virtual_root_path': vroot_tuple, 'root': root }