From jwashin at codespeak.net Sat Oct 7 23:20:50 2006 From: jwashin at codespeak.net (jwashin at codespeak.net) Date: Sat, 7 Oct 2006 23:20:50 +0200 (CEST) Subject: [z3-checkins] r32995 - z3/jsonserver/trunk Message-ID: <20061007212050.8F07B1006E@code0.codespeak.net> Author: jwashin Date: Sat Oct 7 23:20:46 2006 New Revision: 32995 Added: z3/jsonserver/trunk/JSONViews.txt z3/jsonserver/trunk/ftests.py Modified: z3/jsonserver/trunk/__init__.py z3/jsonserver/trunk/interfaces.py z3/jsonserver/trunk/jsonrpc.py Log: Added JSONViews, and JSONViews.txt as ftest Added: z3/jsonserver/trunk/JSONViews.txt ============================================================================== --- (empty file) +++ z3/jsonserver/trunk/JSONViews.txt Sat Oct 7 23:20:46 2006 @@ -0,0 +1,162 @@ +JSON Views are used when an HTTP GET is a reasonable way to get some +JSON-formatted data from the server, for example, if you have a javascript +library that employs JSON GETs, e.g., Dojo. + +A JSON View is simply a page that, instead of HTML, is a JSON.representation of +some data. + +To do this you need to create a view class and register it in ZCML. + +We'll follow the xmlrpc README to demonstrate. + +First, write a view class, descended from JSONView. Whatever is returned in the +doResponse method is what will be sent as a response. The usual view instance +variables context and request are available. + + >>> from jsonserver import JSONView + >>> class FolderListing(JSONView): + ... def doResponse(self): + ... return list(self.context.keys()) + +Register it as a view. Usually, this will be a browser:page or browser:view +directive (I'm not sure which is really preferred, either should work.). +browser2:page should also work, though I have not tried it. + + >>> from zope.configuration import xmlconfig + >>> ignored = xmlconfig.string(""" + ... + ... + ... + ... + ... + ... """) + +Exactly like the xmlrpc example, we add some items to the root folder. + + >>> print http(r""" + ... POST /@@contents.html HTTP/1.1 + ... Authorization: Basic bWdyOm1ncnB3 + ... Content-Length: 73 + ... Content-Type: application/x-www-form-urlencoded + ... + ... type_name=BrowserAdd__zope.app.folder.folder.Folder&new_value=f1""") + HTTP/1.1 303 See Other + ... + + >>> print http(r""" + ... POST /@@contents.html HTTP/1.1 + ... Authorization: Basic bWdyOm1ncnB3 + ... Content-Length: 73 + ... Content-Type: application/x-www-form-urlencoded + ... + ... type_name=BrowserAdd__zope.app.folder.folder.Folder&new_value=f2""") + HTTP/1.1 303 See Other + ... + +Before we can JSONView, there needs to be an IJSONWriter utility. Here's one. + >>> import zope.component + >>> import jsoncomponent + >>> from jsonserver.interfaces import IJSONWriter + >>> zope.component.provideUtility(jsoncomponent.JSONWriter(),IJSONWriter) + +Let's set up a browser. + >>> from zope.testbrowser.testing import Browser + >>> browser = Browser('http://localhost/@@/testbrowser/simple.html') + >>> #this was how I figured out the need for the IJSONWriter utility... + >>> #browser.handleErrors = False + +Now, we can call our new JSONView and get a response: + >>> browser.open('/folderlist') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 401: Unauthorized + +That was expected Let's view again, and provide authentication this time. +Content-type is set appropriately. + >>> browser.addHeader('Authorization','Basic mgr:mgrpw') + >>> browser.open('/folderlist') + >>> browser.headers['content-type'] + 'application/json;charset=utf-8' + >>> browser.contents + '["f1","f2"]' + +Pretty cool, yes? This is much smaller than a similar xmlrpc response. + +But what about parameters? Let's create another class with some error handling. +There's no real standard on this, so you may need to commune with the cliemt +implementation to see how to handle errors. + >>> import decimal + >>> class FolderStupidSum(JSONView): + ... """return two values and their sum""" + ... def doResponse(self, a=0, b=0): + ... try: + ... a = decimal.Decimal(a) + ... b = decimal.Decimal(b) + ... except decimal.InvalidOperation: + ... self.request.response.setStatus(500) + ... return {'error':'bad params','a':a, 'b':b} + ... return {'a':a,'b':b,'sum':a+b} + +and register it. + >>> from zope.configuration import xmlconfig + >>> ignored = xmlconfig.string(""" + ... + ... + ... + ... + ... + ... """) + +Start a new browser. + >>> browser = Browser('http://localhost/@@/testbrowser/simple.html') + >>> #browser.handleErrors = False + >>> browser.addHeader('Authorization','Basic mgr:mgrpw') + +Let's do a couple of views. browser is already authenticated. Asssure the +parameters in the GET match the names in the doResponse method. Default values +are OK, and probably a good idea. + >>> browser.open('/sum?a=5') + +We are expecting something that looks like '{"a":5,"sum":5,"b":0}' + >>> '"a"' in browser.contents + True + >>> '"b"' in browser.contents + True + >>> '"sum"' in browser.contents + True + >>> browser.contents.count('5') == 2 + True + +This request should get something that looks like '{"a":5,"sum":15,"b":10}' + >>> browser.open('/sum?a=5&b=10') + >>> browser.contents.count('15') == 1 + True + +Let's see if the error handling works. We should get an HTTP error and something +like '{"a":"zzz5","b":"10","error":"bad params"} + >>> browser.handleErrors = True + >>> browser.open('/sum?a=zzz5&b=10') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 500: Internal Server Error + >>> 'zzz5' in browser.contents + True + >>> 'bad params' in browser.contents + True + Modified: z3/jsonserver/trunk/__init__.py ============================================================================== --- z3/jsonserver/trunk/__init__.py (original) +++ z3/jsonserver/trunk/__init__.py Sat Oct 7 23:20:46 2006 @@ -1 +1,2 @@ #python package +from jsonrpc import MethodPublisher, JSONView Added: z3/jsonserver/trunk/ftests.py ============================================================================== --- (empty file) +++ z3/jsonserver/trunk/ftests.py Sat Oct 7 23:20:46 2006 @@ -0,0 +1,57 @@ +############################################################################## +# +# Copyright (c) 2004 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Functional tests for JSON Views +Original file z.a.publisher.xmlrpc/ftests.py +$Id: ftests.py 29787 2005-04-01 16:41:05Z srichter $ +Mod by jmw 7 Oct 06 for JSON Views +""" +import zope.interface +import zope.app.folder.folder +import zope.publisher.interfaces.xmlrpc +from zope.app.testing import ztapi, functional, setup + +def setUp(test): + setup.setUpTestAsModule(test, 'jsonserver.JSONViews') + +def tearDown(test): + # clean up the views we registered: + + # we use the fact that registering None unregisters whatever is + # registered. We can't use an unregistration call because that + # requires the object that was registered and we don't have that handy. + # (OK, we could get it if we want. Maybe later.) + + ztapi.provideView(zope.app.folder.folder.IFolder, + zope.publisher.interfaces.IRequest, + zope.interface, + 'folderlist', + None, + ) + + ztapi.provideView(zope.app.folder.folder.IFolder, + zope.publisher.interfaces.xmlrpc.IXMLRPCRequest, + zope.interface, + 'sum', + None, + ) + + setup.tearDownTestAsModule(test) + +def test_suite(): + return functional.FunctionalDocFileSuite( + 'JSONViews.txt', setUp=setUp, tearDown=tearDown) + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='test_suite') Modified: z3/jsonserver/trunk/interfaces.py ============================================================================== --- z3/jsonserver/trunk/interfaces.py (original) +++ z3/jsonserver/trunk/interfaces.py Sat Oct 7 23:20:46 2006 @@ -23,12 +23,15 @@ from zope.publisher.interfaces.http import IHTTPApplicationRequest,\ IHTTPCredentials from zope.interface import Interface -from zope.component.interfaces import IView, IPresentation +from zope.component.interfaces import IView from zope.interface import Attribute from zope.app.publisher.xmlrpc import IMethodPublisher from zope.publisher.interfaces.xmlrpc import IXMLRPCPublication from zope.app.publication.interfaces import IRequestFactory -from zope.publisher.interfaces.browser import IDefaultBrowserLayer +from zope.publisher.interfaces.browser import IDefaultBrowserLayer, \ + IBrowserPage +from zope.schema.interfaces import TextLine + class IJSONRPCRequestFactory(IRequestFactory): """Browser request factory""" @@ -78,3 +81,12 @@ """Premarshaller to remove security proxies""" def __call__(): """return the object without proxies""" + +class IJSONView(IBrowserPage): + """A view that is a JSON representation of an object""" + contentType = TextLine(title=u"content-type", default=u"application/json") + def doResponse(): + """return the list or dict that is response for this view""" + def doCacheControl(): + """set any cache headers that may be needed. Default sends 'no-cache' + to KHTML browsers. May be extended/overridden in subclasses""" Modified: z3/jsonserver/trunk/jsonrpc.py ============================================================================== --- z3/jsonserver/trunk/jsonrpc.py (original) +++ z3/jsonserver/trunk/jsonrpc.py Sat Oct 7 23:20:46 2006 @@ -22,12 +22,14 @@ #2006-03-09 enabled gzip compression for large responses #2006-05-10 removed gzip compression and (prematurely) enabled json-rpc 1.1 jmw #2006-06-19 updated with ctheune's xmlrpc solution for removing proxies jmw +#2006-09-27 added JSONView class __docformat__ = 'restructuredtext' from zope.app.publication.http import BaseHTTPPublication from interfaces import IMethodPublisher, IJSONRPCView, IJSONRPCPublisher,\ - IJSONRPCRequest, IJSONReader, IJSONWriter, IJSONRPCPremarshaller + IJSONRPCRequest, IJSONReader, IJSONWriter, IJSONRPCPremarshaller, \ + IJSONView from zope.interface import implements #from zope.publisher.http import IResult from zope.location.location import Location @@ -36,8 +38,11 @@ from zope.publisher.browser import BrowserRequest from zope.security.proxy import isinstance from zope.publisher.interfaces.browser import IBrowserRequest + from zope.publisher.interfaces.browser import IBrowserApplicationRequest from zope.component import getUtility +from zope.publisher.browser import BrowserPage + try: from cStringIO import StringIO except ImportError: @@ -50,6 +55,8 @@ keyword_key = "pythonKwMaRkEr" +json_charsets = ('utf-8','utf-16', 'utf-32') + #writeProfileData transcribes reads and writes files in the zope3 # instance directory for profiling use. # profiledata.py has response dicts that can be read as python @@ -208,6 +215,9 @@ def _prepareResult(self,result): #we've asked json to return unicode; result should be unicode encoding = getCharsetUsingRequest(self._request) or 'utf-8' + enc = encoding.lower() + if not enc in json_charsets: + encoding = 'utf-8' #at outgoing boundary; encode it. if isinstance(result,unicode): body = result.encode(encoding) @@ -268,7 +278,7 @@ return map(premarshal, self.data) def premarshal(data): - """Premarshal data before handing it to xmlrpclib for marhalling + """Premarshal data before handing it to JSON writer for marshalling The initial purpose of this function is to remove security proxies without resorting to removeSecurityProxy. This way, we can avoid @@ -303,6 +313,69 @@ #return premarshaller(data) #return data +class JSONView(BrowserPage): + """This is a base view class for 'ordinary' JSON methods. + JSONViews are accessible by ordinary URLs and HTTP GETs. + """ + implements(IJSONView) + contentType = 'application/json' + + def doResponse(self, *args, **kw): + """return the python list or dict that will be the body of the response. + This needs to be overridden in subclasses""" + raise NotImplementedError("Subclasses should override doResponse to " + "provide a response body") + def doCacheControl(self): + """ at the moment, KHTML-based browsers do not handle cached JSON data + properly. This may be Dojo-specific, and may be only necessary for + a short time until Konq and Safari behave like other browsers in this + respect. + Default here is to send 'no-cache' header to KHTML browsers. + For other user agents, a 1-hour public cache is specified. + + May be overridden/extended in subclasses. + """ + agent = self.request.get('HTTP_USER_AGENT','') + response = self.request.response + if 'KHTML' in agent: + response.setHeader('cache-control','no-cache') + else: + response.setHeader('cache-control', + 'public, must-revalidate, max-age=3600') + + def __call__(self, *args, **kw): + """the doResponse method is called. + + First, anything that matches the method signature in request.form is + put in the method's **kw. + + After call, the response is JSONized and sent out with appropriate + encoding. + + """ + request = self.request + meth = self.doResponse + #introspect the method and set kw params if the arg is in request.form + params = meth.im_func.func_code.co_varnames[1:] + for key in request.form.keys(): + if key in params: + kw[str(key)] = request.form.get(key) + resp = premarshal(self.doResponse(*args,**kw)) + + if not isinstance(resp,dict) and not isinstance(resp,list): + raise ValueError("JSON responses must be dicts or lists") + + self.doCacheControl() + + encoding = getCharsetUsingRequest(self.request) + enc = encoding.lower() + if not enc in json_charsets: + #we'll allow utf-32, utf-16 or utf-8; if not specified, use utf-8 + enc = 'utf-8' + request.response.setHeader('content-type','%s;charset=%s' % (self.contentType,enc)) + json = getUtility(IJSONWriter) + s = json.write(resp).encode(enc) + return s class JSONRPCView(object): """A base JSON-RPC view that can be used as mix-in for JSON-RPC views. From jwashin at codespeak.net Sun Oct 8 16:09:02 2006 From: jwashin at codespeak.net (jwashin at codespeak.net) Date: Sun, 8 Oct 2006 16:09:02 +0200 (CEST) Subject: [z3-checkins] r33001 - in z3/jsonserver/trunk: . tests Message-ID: <20061008140902.B660710072@code0.codespeak.net> Author: jwashin Date: Sun Oct 8 16:08:59 2006 New Revision: 33001 Added: z3/jsonserver/trunk/tests/test_sum_form.pt Modified: z3/jsonserver/trunk/JSONViews.txt z3/jsonserver/trunk/ftests.py Log: added a POST test to JSONViews.txt Modified: z3/jsonserver/trunk/JSONViews.txt ============================================================================== --- z3/jsonserver/trunk/JSONViews.txt (original) +++ z3/jsonserver/trunk/JSONViews.txt Sun Oct 8 16:08:59 2006 @@ -10,8 +10,8 @@ We'll follow the xmlrpc README to demonstrate. First, write a view class, descended from JSONView. Whatever is returned in the -doResponse method is what will be sent as a response. The usual view instance -variables context and request are available. +doResponse method is what will be sent as a response. The usual view instance +variables, context and request, are available. >>> from jsonserver import JSONView >>> class FolderListing(JSONView): @@ -39,27 +39,21 @@ ... ... """) -Exactly like the xmlrpc example, we add some items to the root folder. - - >>> print http(r""" - ... POST /@@contents.html HTTP/1.1 - ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 73 - ... Content-Type: application/x-www-form-urlencoded - ... - ... type_name=BrowserAdd__zope.app.folder.folder.Folder&new_value=f1""") - HTTP/1.1 303 See Other - ... +Let's set up a browser. + >>> from zope.testbrowser.testing import Browser + >>> browser = Browser('http://localhost/@@/testbrowser/simple.html') + >>> #N.B.,this was how I figured out the need for the IJSONWriter utility... + >>> #browser.handleErrors = False + >>> browser.addHeader('Authorization','Basic mgr:mgrpw') - >>> print http(r""" - ... POST /@@contents.html HTTP/1.1 - ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 73 - ... Content-Type: application/x-www-form-urlencoded - ... - ... type_name=BrowserAdd__zope.app.folder.folder.Folder&new_value=f2""") - HTTP/1.1 303 See Other - ... +Almost exactly like the xmlrpc example, we add some items to the root folder. + >>> typeName = "BrowserAdd__zope.app.folder.folder.Folder" + >>> newValue = 'f1' + >>> browser.open('/@@contents.html?type_name=%s&new_value=%s' % (typeName, + ... newValue)) + >>> newValue = 'f2' + >>> browser.open('/@@contents.html?type_name=%s&new_value=%s' % (typeName, + ... newValue)) Before we can JSONView, there needs to be an IJSONWriter utility. Here's one. >>> import zope.component @@ -67,11 +61,8 @@ >>> from jsonserver.interfaces import IJSONWriter >>> zope.component.provideUtility(jsoncomponent.JSONWriter(),IJSONWriter) -Let's set up a browser. - >>> from zope.testbrowser.testing import Browser +We reset the browser just for fun... >>> browser = Browser('http://localhost/@@/testbrowser/simple.html') - >>> #this was how I figured out the need for the IJSONWriter utility... - >>> #browser.handleErrors = False Now, we can call our new JSONView and get a response: >>> browser.open('/folderlist') @@ -91,8 +82,8 @@ Pretty cool, yes? This is much smaller than a similar xmlrpc response. But what about parameters? Let's create another class with some error handling. -There's no real standard on this, so you may need to commune with the cliemt -implementation to see how to handle errors. +There's no real standard on error handling in JSON, so you may need to commune +with the client implementation to see how to handle errors. >>> import decimal >>> class FolderStupidSum(JSONView): ... """return two values and their sum""" @@ -105,7 +96,11 @@ ... return {'error':'bad params','a':a, 'b':b} ... return {'a':a,'b':b,'sum':a+b} -and register it. +First, a hack to make the page template file findable, then register the sum +page and a sum_form page. + >>> import os + >>> loc = os.path.dirname(__file__) + >>> pt = os.path.join(loc,'tests','test_sum_form.pt') >>> from zope.configuration import xmlconfig >>> ignored = xmlconfig.string(""" ... + ... ... - ... """) + ... """ % pt) Start a new browser. >>> browser = Browser('http://localhost/@@/testbrowser/simple.html') >>> #browser.handleErrors = False >>> browser.addHeader('Authorization','Basic mgr:mgrpw') -Let's do a couple of views. browser is already authenticated. Asssure the +Let's do a couple of views. Browser is already authenticated. Asssure the parameters in the GET match the names in the doResponse method. Default values are OK, and probably a good idea. >>> browser.open('/sum?a=5') @@ -160,3 +161,15 @@ >>> 'bad params' in browser.contents True +Now, let's open the test form in the browser so that we can see if POST works. +Ordinarily, a POST for a JSONView would be done in an XHR, but we are just +testing functionality here. + >>> browser.open('/sum_form.html') + >>> a = browser.getControl(name='a') + >>> b = browser.getControl(name='b') + >>> a.value="34" + >>> b.value="66" + >>> submit = browser.getControl(name="submit") + >>> submit.click() + >>> '"sum":100' in browser.contents + True Modified: z3/jsonserver/trunk/ftests.py ============================================================================== --- z3/jsonserver/trunk/ftests.py (original) +++ z3/jsonserver/trunk/ftests.py Sun Oct 8 16:08:59 2006 @@ -18,7 +18,7 @@ """ import zope.interface import zope.app.folder.folder -import zope.publisher.interfaces.xmlrpc +import zope.publisher.interfaces.browser from zope.app.testing import ztapi, functional, setup def setUp(test): @@ -33,19 +33,23 @@ # (OK, we could get it if we want. Maybe later.) ztapi.provideView(zope.app.folder.folder.IFolder, - zope.publisher.interfaces.IRequest, + zope.publisher.interfaces.browser.IBrowserRequest, zope.interface, 'folderlist', None, ) - ztapi.provideView(zope.app.folder.folder.IFolder, - zope.publisher.interfaces.xmlrpc.IXMLRPCRequest, + zope.publisher.interfaces.browser.IBrowserRequest, zope.interface, 'sum', None, ) - + ztapi.provideView(zope.app.folder.folder.IFolder, + zope.publisher.interfaces.browser.IBrowserRequest, + zope.interface, + 'sum_form.html', + None, + ) setup.tearDownTestAsModule(test) def test_suite(): Added: z3/jsonserver/trunk/tests/test_sum_form.pt ============================================================================== --- (empty file) +++ z3/jsonserver/trunk/tests/test_sum_form.pt Sun Oct 8 16:08:59 2006 @@ -0,0 +1,14 @@ + + + This is a form for testing stupid sums + + +

Stupid form test

+

Enter two values, and submit

+
+ + + +
+ + From jwashin at codespeak.net Sun Oct 8 20:18:07 2006 From: jwashin at codespeak.net (jwashin at codespeak.net) Date: Sun, 8 Oct 2006 20:18:07 +0200 (CEST) Subject: [z3-checkins] r33005 - z3/jsonserver/trunk Message-ID: <20061008181807.ED81110068@code0.codespeak.net> Author: jwashin Date: Sun Oct 8 20:18:05 2006 New Revision: 33005 Modified: z3/jsonserver/trunk/JSONViews.txt z3/jsonserver/trunk/jsonrpc.py Log: a bit more error handling for JSONView Modified: z3/jsonserver/trunk/JSONViews.txt ============================================================================== --- z3/jsonserver/trunk/JSONViews.txt (original) +++ z3/jsonserver/trunk/JSONViews.txt Sun Oct 8 20:18:05 2006 @@ -81,13 +81,14 @@ Pretty cool, yes? This is much smaller than a similar xmlrpc response. -But what about parameters? Let's create another class with some error handling. -There's no real standard on error handling in JSON, so you may need to commune -with the client implementation to see how to handle errors. +But what about parameters? Let's create another class with a parameter and an +optional parameter. We'll also do some local error handling. There's no real +standard on error handling in JSON, so you may need to commune with the client +implementation to see how to handle errors. >>> import decimal >>> class FolderStupidSum(JSONView): ... """return two values and their sum""" - ... def doResponse(self, a=0, b=0): + ... def doResponse(self, a, b=0): ... try: ... a = decimal.Decimal(a) ... b = decimal.Decimal(b) @@ -131,7 +132,7 @@ Let's do a couple of views. Browser is already authenticated. Asssure the parameters in the GET match the names in the doResponse method. Default values -are OK, and probably a good idea. +in the method signature are OK, and probably a good idea. >>> browser.open('/sum?a=5') We are expecting something that looks like '{"a":5,"sum":5,"b":0}' @@ -149,8 +150,25 @@ >>> browser.contents.count('15') == 1 True -Let's see if the error handling works. We should get an HTTP error and something -like '{"a":"zzz5","b":"10","error":"bad params"} +This request does not send enough parameters. + >>> browser.open('/sum') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 500: Internal Server Error + >>> browser.contents + '{"error":"doResponse() takes at least 2 arguments (1 given)"}' + +This request also does not send enough parameters, because the parameter +provided does not match the method signature. + >>> browser.open('/sum?d=20') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 500: Internal Server Error + >>> browser.contents + '{"error":"doResponse() takes at least 2 arguments (1 given)"}' + +Let's see if the local error handling works. We should get an HTTP error and +something like '{"a":"zzz5","b":"10","error":"bad params"} >>> browser.handleErrors = True >>> browser.open('/sum?a=zzz5&b=10') Traceback (most recent call last): Modified: z3/jsonserver/trunk/jsonrpc.py ============================================================================== --- z3/jsonserver/trunk/jsonrpc.py (original) +++ z3/jsonserver/trunk/jsonrpc.py Sun Oct 8 20:18:05 2006 @@ -360,7 +360,11 @@ for key in request.form.keys(): if key in params: kw[str(key)] = request.form.get(key) - resp = premarshal(self.doResponse(*args,**kw)) + try: + resp = premarshal(self.doResponse(*args,**kw)) + except TypeError, err: + request.response.setStatus('500') + resp = {'error':'%s' % err} if not isinstance(resp,dict) and not isinstance(resp,list): raise ValueError("JSON responses must be dicts or lists") From jwashin at codespeak.net Sun Oct 8 20:24:15 2006 From: jwashin at codespeak.net (jwashin at codespeak.net) Date: Sun, 8 Oct 2006 20:24:15 +0200 (CEST) Subject: [z3-checkins] r33007 - z3/jsonserver/trunk Message-ID: <20061008182415.2283210068@code0.codespeak.net> Author: jwashin Date: Sun Oct 8 20:24:13 2006 New Revision: 33007 Modified: z3/jsonserver/trunk/JSONViews.txt Log: Oops python error msgs are not always in English. Modified: z3/jsonserver/trunk/JSONViews.txt ============================================================================== --- z3/jsonserver/trunk/JSONViews.txt (original) +++ z3/jsonserver/trunk/JSONViews.txt Sun Oct 8 20:24:13 2006 @@ -150,22 +150,23 @@ >>> browser.contents.count('15') == 1 True -This request does not send enough parameters. +This request does not send enough parameters. The error I get is +'{"error":"doResponse() takes at least 2 arguments (1 given)"}' >>> browser.open('/sum') Traceback (most recent call last): ... HTTPError: HTTP Error 500: Internal Server Error - >>> browser.contents - '{"error":"doResponse() takes at least 2 arguments (1 given)"}' + >>> 'error' in browser.contents + True This request also does not send enough parameters, because the parameter -provided does not match the method signature. +provided does not match the method signature. Same error as above. >>> browser.open('/sum?d=20') Traceback (most recent call last): ... HTTPError: HTTP Error 500: Internal Server Error - >>> browser.contents - '{"error":"doResponse() takes at least 2 arguments (1 given)"}' + >>> 'error' in browser.contents + True Let's see if the local error handling works. We should get an HTTP error and something like '{"a":"zzz5","b":"10","error":"bad params"} From jwashin at codespeak.net Sun Oct 8 20:58:05 2006 From: jwashin at codespeak.net (jwashin at codespeak.net) Date: Sun, 8 Oct 2006 20:58:05 +0200 (CEST) Subject: [z3-checkins] r33011 - z3/jsonserver/trunk Message-ID: <20061008185805.4708810068@code0.codespeak.net> Author: jwashin Date: Sun Oct 8 20:58:03 2006 New Revision: 33011 Modified: z3/jsonserver/trunk/JSONViews.txt Log: small typo fixed in JSONViews.txt Modified: z3/jsonserver/trunk/JSONViews.txt ============================================================================== --- z3/jsonserver/trunk/JSONViews.txt (original) +++ z3/jsonserver/trunk/JSONViews.txt Sun Oct 8 20:58:03 2006 @@ -2,7 +2,7 @@ JSON-formatted data from the server, for example, if you have a javascript library that employs JSON GETs, e.g., Dojo. -A JSON View is simply a page that, instead of HTML, is a JSON.representation of +A JSON View is simply a page that, instead of HTML, is a JSON representation of some data. To do this you need to create a view class and register it in ZCML. From cabraham at codespeak.net Mon Oct 9 22:09:20 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 9 Oct 2006 22:09:20 +0200 (CEST) Subject: [z3-checkins] r33076 - z3/deliverance/branches/packaged/deliverance/tests Message-ID: <20061009200920.E439B100C8@code0.codespeak.net> Author: cabraham Date: Mon Oct 9 22:08:59 2006 New Revision: 33076 Removed: z3/deliverance/branches/packaged/deliverance/tests/ Log: deletes old tests From ltucker at codespeak.net Mon Oct 9 22:04:02 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 9 Oct 2006 22:04:02 +0200 (CEST) Subject: [z3-checkins] r33075 - in z3/deliverance/branches/packaged/deliverance: . test-data test-data/nabuur test-data/nycsr test-data/static Message-ID: <20061009200402.ED901100CC@code0.codespeak.net> Author: ltucker Date: Mon Oct 9 22:03:44 2006 New Revision: 33075 Added: z3/deliverance/branches/packaged/deliverance/handtransform.py z3/deliverance/branches/packaged/deliverance/htmlserialize.py z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/ z3/deliverance/branches/packaged/deliverance/test-data/nabuur/ z3/deliverance/branches/packaged/deliverance/test-data/nabuur/nabuur.html z3/deliverance/branches/packaged/deliverance/test-data/nabuur/nabuur.theme z3/deliverance/branches/packaged/deliverance/test-data/nabuur/rules.xml z3/deliverance/branches/packaged/deliverance/test-data/nabuur/standardrules.xml z3/deliverance/branches/packaged/deliverance/test-data/nycsr/ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.theme z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.xml z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr_expected.html z3/deliverance/branches/packaged/deliverance/test-data/nycsr/openplans.html z3/deliverance/branches/packaged/deliverance/test-data/nycsr/standardrules.xml z3/deliverance/branches/packaged/deliverance/test-data/static/ z3/deliverance/branches/packaged/deliverance/test-data/static/example.html z3/deliverance/branches/packaged/deliverance/test-data/static/example_expected.html z3/deliverance/branches/packaged/deliverance/test-data/static/rules.xml z3/deliverance/branches/packaged/deliverance/test-data/static/standardrules.xml z3/deliverance/branches/packaged/deliverance/test-data/static/standardrules2.xml z3/deliverance/branches/packaged/deliverance/test-data/static/text-rules.xml z3/deliverance/branches/packaged/deliverance/test-data/static/texttest_expected.html z3/deliverance/branches/packaged/deliverance/test-data/static/theme.html z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_expected.html z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_rules.xml z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_theme.html z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml z3/deliverance/branches/packaged/deliverance/test-data/test_baserules.xml z3/deliverance/branches/packaged/deliverance/test-data/test_comments.xml z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml z3/deliverance/branches/packaged/deliverance/test-data/test_submatch.xml z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml z3/deliverance/branches/packaged/deliverance/test_wsgi.py z3/deliverance/branches/packaged/deliverance/tests.py z3/deliverance/branches/packaged/deliverance/utils.py z3/deliverance/branches/packaged/deliverance/xinclude.py z3/deliverance/branches/packaged/deliverance/xslt.py Removed: z3/deliverance/branches/packaged/deliverance/ThemedHTTPServer.py z3/deliverance/branches/packaged/deliverance/main.py z3/deliverance/branches/packaged/deliverance/mpfilter.py z3/deliverance/branches/packaged/deliverance/renderer.xsl z3/deliverance/branches/packaged/deliverance/themecompiler.xsl Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: parallel python and xslt renderers, tests, wsgi filter Deleted: /z3/deliverance/branches/packaged/deliverance/ThemedHTTPServer.py ============================================================================== --- /z3/deliverance/branches/packaged/deliverance/ThemedHTTPServer.py Mon Oct 9 22:03:44 2006 +++ (empty file) @@ -1,92 +0,0 @@ -"""Simple HTTP Server. - -This module builds on BaseHTTPServer by implementing the standard GET -and HEAD requests in a fairly straightforward manner. - -""" - - -__version__ = "0.6" - -__all__ = ["ThemedHTTPRequestHandler"] - -import os -import mimetypes -import BaseHTTPServer -import SimpleHTTPServer -from StringIO import StringIO - -from deliverance import AppMap -appmap = AppMap() - - -class ThemedHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): - - def send_head(self): - """Common code for GET and HEAD commands. - - This sends the response code and MIME headers. - - Return value is either a file object (which has to be copied - to the outputfile by the caller unless the command was HEAD, - and must be closed by the caller under all circumstances), or - None, in which case the caller has nothing further to do. - - """ - path = self.translate_path(self.path) - f = None - if os.path.isdir(path): - for index in "index.html", "index.htm": - index = os.path.join(path, index) - if os.path.exists(index): - path = index - break - else: - return self.list_directory(path) - ctype = self.guess_type(path) - try: - # Always read in binary mode. Opening files in text mode may cause - # newline translations, making the actual size of the content - # transmitted *less* than the content-length! - - # This is where we apply theming - - # First check to see if there is a query string. If so, presume that - # to mean they want the source version. - qs = len(self.path.split("?")) - if ctype == "text/html" and qs == 99: - print "Applying theme to", path - xmlstring = open(path, "r").read() - response = appmap.publish(xmlstring) - f = StringIO(response) - responsesize = str(len(xmlstring)) - else: - f = open(path, 'rb') - responsesize = str(os.fstat(f.fileno())[6]) - except IOError: - self.send_error(404, "File not found") - return None - self.send_response(200) - self.send_header("Content-type", ctype) - self.send_header("Content-Length", responsesize) - self.end_headers() - return f - - extensions_map = mimetypes.types_map.copy() - extensions_map.update({ - '': 'application/octet-stream', # Default - '.py': 'text/plain', - '.c': 'text/plain', - '.h': 'text/plain', - '.ico': 'image/x-icon', - }) - - - -def test(HandlerClass = ThemedHTTPRequestHandler, - ServerClass = BaseHTTPServer.HTTPServer): - BaseHTTPServer.test(HandlerClass, ServerClass) - - -if __name__ == '__main__': - test() Added: z3/deliverance/branches/packaged/deliverance/handtransform.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/handtransform.py Mon Oct 9 22:03:44 2006 @@ -0,0 +1,124 @@ +import sys +from lxml import etree +from htmlserialize import tostring +import urllib +from interpreter import Renderer as PythonRenderer +from xslt import Renderer as XSLTRenderer +from optparse import OptionParser +import re +import os + +""" +Command line utility to run a deliverance transform +given the urls of the rules, theme and content. + + +themeurl, rulesfile and baseurl can be rolled into a file specified with -f +it should contain an element like + + + + +""" + + +DEFAULT_BASE_URL = "http://www.example.com" + + +def grab_url(url): + f = urllib.urlopen(url) + data = f.read() + f.close() + return data + +def do_transform(renderer_type, theme_url, base_url, rules_url, content_url): + rules = etree.XML(grab_url(rules_url)) + theme = etree.HTML(grab_url(theme_url)) + content = etree.HTML(grab_url(content_url)) + + def reference_resolver(href, parse, encoding=None): + if not href.startswith('/'): + href = os.path.join(os.path.dirname(rules_url),href) + text = grab_url(href) + if parse == "xml": + return etree.XML(text) + elif encoding: + return text.decode(encoding) + + renderer = None + if renderer_type == 'xslt': + renderer = XSLTRenderer(theme,base_url,rules,reference_resolver) + elif renderer_type == 'py': + renderer = PythonRenderer(theme,base_url,rules,reference_resolver) + else: + print "Unknown renderer type '" + renderer_type + "'" + return etree.Element("error") + + return renderer.render(content) + + +def parse_blend_file(filename): + b = etree.XML(open(filename).read()) + return b.get('theme'),b.get('baseurl'),b.get('rules') + + +def die(message,parser): + print message + parser.print_usage() + sys.exit(0) + +if __name__ == '__main__': + + + usage = "usage: %prog [options] " + parser = OptionParser(usage=usage) + parser.add_option("-t","--theme",dest="theme_url",help="url of theme html") + parser.add_option("-b","--baseurl",dest="base_url", + help="relative urls in the theme will be made absolute relative to this url [default %default]", + default=DEFAULT_BASE_URL) + parser.add_option("-r","--rules",dest="rules_file", + help="path to file containing the deliverance rules to apply") + parser.add_option("-f","--from-file",dest="blend_file", + help="take theme, baseurl and rules parameters from the referenced file") + parser.add_option("-R","--renderer",dest="renderer_type", + help="(xslt|py) [default %default]", default="xslt", choices=['xslt','py']) + + (options,args) = parser.parse_args() + + if len(args) == 0: + die("no content url specified.",parser) + + content_url = args[0] + theme_url = None + base_url = None + rules_file = None + + + if options.blend_file: + if (options.rules_file or options.theme_url or options.base_url != DEFAULT_BASE_URL): + die("cannot specify base url, rules file or theme url when taking parameters from file.",parser) + + try: + theme_url,base_url,rules_file = parse_blend_file(options.blend_file) + + except Exception,message: + die(message,parser) + + else: + theme_url = options.theme_url + rules_file = options.rules_file + base_url = options.base_url + + + if theme_url is None: + die("no theme url specified.",parser) + + if rules_file is None: + die("no rules file specified.",parser) + + if base_url is None: + die("no base url specified",parser) + + + print tostring(do_transform(options.renderer_type,theme_url,base_url,rules_file,content_url)) + Added: z3/deliverance/branches/packaged/deliverance/htmlserialize.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/htmlserialize.py Mon Oct 9 22:03:44 2006 @@ -0,0 +1,39 @@ +from lxml import etree + + +html_xsl = """ + + + + + + +""" + +# TODO: this should do real formatting +pretty_html_xsl = """ + + + + + + +""" + +html_transform = etree.XSLT(etree.XML(html_xsl)) +pretty_html_transform = etree.XSLT(etree.XML(pretty_html_xsl)) + + +# +# creates an HTML string representation of the document given +# +# note: this will create a meta http-equiv="Content" tag in the head +# and may replace any that are present +# +def tostring(doc,pretty = False): + if pretty: + return str(pretty_html_transform(doc)) + else: + return str(html_transform(doc)) + + Added: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Mon Oct 9 22:03:44 2006 @@ -0,0 +1,263 @@ +from lxml import etree +import xinclude +import copy +import utils +from utils import RuleSyntaxError +from utils import RendererBase + +class Renderer(RendererBase): + """ + implements a deliverance renderer programmatically using + lxml api. The rules, theme and content are all processed at + render time. + """ + + def __init__(self, theme, theme_uri, rules, reference_resolver=None): + self.theme = self.fixup_links(theme, theme_uri) + self.remove_http_equiv_metas(self.theme) + self.rules = rules + # perform xincludes on the rules + if reference_resolver: + xinclude.include(self.rules, loader=reference_resolver) + + + def render(self, content): + result = copy.deepcopy(self.theme) + input = copy.deepcopy(content) + self.remove_http_equiv_metas(input) + self.apply_rules(self.rules,result,input) + return result + + + def apply_rules(self,rules,theme,content): + for rule in rules: + self.apply_rule(rule,theme,content) + + + def apply_rule(self,rule,theme,content): + if rule.tag == self.APPEND_RULE_TAG: + self.apply_append(rule,theme,content) + elif rule.tag == self.PREPEND_RULE_TAG: + self.apply_prepend(rule,theme,content) + elif rule.tag == self.REPLACE_RULE_TAG: + self.apply_replace(rule,theme,content) + elif rule.tag == self.COPY_RULE_TAG: + self.apply_copy(rule,theme,content) + elif rule.tag == self.APPEND_OR_REPLACE_RULE_TAG: + self.apply_append_or_replace(rule,theme,content) + elif rule.tag == self.SUBRULES_TAG: + self.apply_rules(rule,theme,content) + elif rule.tag is etree.Comment: + pass + else: + raise RuleSyntaxError( + "Rule %s (%s) not understood" % ( + rule.tag, etree.tostring(rule))) + + def apply_append(self,rule,theme,content): + theme_el = self.get_theme_el(rule,theme) + if theme_el is None: + return + + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + + if (len(content_els) == 0): + return + + non_text_els = self.elements_in(content_els) + self.strip_tails(non_text_els) + + # the xpath may return a mixture of strings and elements, handle strings + # by attaching them to the proper element + if (type(content_els[0]) is type(str())): + # if the element we're appending to has children, the text is + # appended to the tail of the last child. + if len(theme_el): + if theme_el[-1].tail: + theme_el[-1].tail += content_els[0] + else: + theme_el[-1].tail = content_els[0] + # otherwise, the text is appeded to the text attribute of the + # element we're appending to + else: + if theme_el.text: + theme_el.text += content_els[0] + else: + theme_el.text = content_els[0] + + self.attach_tails(content_els) + theme_el.extend(non_text_els) + + def apply_prepend(self,rule,theme,content): + theme_el = self.get_theme_el(rule,theme) + if theme_el is None: + return + + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + + if (len(content_els) == 0): + return + + non_text_els = self.elements_in(content_els) + + # if we only get some text, just tack it on and return + if len(non_text_els) == 0 and type(content_els[0]) is type(str()): + if theme_el.text: + theme_el.text = content_els[0] + theme_el.text + else: + theme_el.text = content_els[0] + return + + # here we have some elements and possibly some text + + self.strip_tails(non_text_els) + + # the xpath may return a mixture of strings and elements, handle the + # first string by making it the text of the parent element. In any + # case if the parent element has text, we need put it after the + # elements we're prepending so we save it here + old_start_text = theme_el.text + if (type(content_els[0]) is type(str())): + theme_el.text = content_els[0] + else: + theme_el.text = None + + self.attach_tails(content_els) + for index,el in enumerate(non_text_els): + theme_el.insert(index,el) + + # tack on the previous text of the parent element + if old_start_text: + if (non_text_els[-1].tail): + non_text_els[-1].tail += old_start_text + else: + non_text_els[-1].tail = old_start_text + + def apply_replace(self,rule,theme,content): + theme_el = self.get_theme_el(rule,theme) + if theme_el is None: + return + + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + + if len(content_els) == 0: + self.attach_text_to_previous(theme_el,theme_el.tail) + theme_el.getparent().remove(theme_el) + return + + non_text_els = self.elements_in(content_els) + self.strip_tails(non_text_els) + + + # the xpath may return a mixture of strings and elements, handle strings + # by attaching them to the proper element + if (type(content_els[0]) is type(str())): + # text must be appended to the tail of the most recent sibling or appended + # to the text of the parent of the replaced element + self.attach_text_to_previous(theme_el,content_els[0]) + + if len(non_text_els) == 0: + self.attach_text_to_previous(theme_el,theme_el.tail) + theme_el.getparent().remove(theme_el) + return + + self.attach_tails(content_els) + + # this tail, if there is one, should stick around + preserve_tail = non_text_els[0].tail + + self.replace_element(theme_el, non_text_els[0]) + temptail = non_text_els[0].tail + non_text_els[0].tail = None + parent = non_text_els[0].getparent() + i = parent.index(non_text_els[0]) + for index,cel in enumerate(non_text_els[1:]): + parent.insert(i + index + 1,cel) + + if non_text_els[-1].tail: + non_text_els[-1].tail += temptail + else: + non_text_els[-1].tail = temptail + + # tack in any preserved tail we stored above + if preserve_tail: + if non_text_els[0].tail: + non_text_els[0].tail = preserve_tail + non_text_els[0].tail + else: + non_text_els[0].tail = preserve_tail + + + def apply_copy(self,rule,theme,content): + theme_el = self.get_theme_el(rule,theme) + if theme_el is None: + return + + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + + if len(content_els) == 0: + return + + non_text_els = self.elements_in(content_els) + self.strip_tails(non_text_els) + # attach any leading matched text as the text of the element + # we're copying into + if (type(content_els[0]) is type(str())): + theme_el.text = content_els[0] + # otherwise knock out any existing text + else: + theme_el.text = None + + self.attach_tails(content_els) + theme_el[:] = non_text_els + + def apply_append_or_replace(self,rule,theme,content): + theme_el = self.get_theme_el(rule,theme) + if theme_el is None: + return + + content_xpath = rule.attrib[self.RULE_CONTENT_KEY] + remove_tag = self.get_tag_from_xpath(content_xpath) + + if remove_tag is None: + self.add_to_body_start(theme,self.format_error("invalid xpath for content", rule=rule)) + return + + for el in theme_el: + if el.tag == remove_tag: + theme_el.remove(el) + + content_els = copy.deepcopy(content.xpath(content_xpath)) + self.strip_tails(content_els) + theme_el.extend(content_els) + + + def elements_in(self, els): + """ + return a list containing elements from els which are not strings + """ + return [x for x in els if type(x) is not type(str())] + + + + def strip_tails(self, els): + for el in els: + el.tail = None + + + def attach_tails(self,els): + """ + whereever an lxml element in the list is followed by + a string, set the tail of the lxml element to the string + """ + for index,el in enumerate(els): + # if we run into a string after the current element, + # attach it to the current element as the tail + if (type(el) is not type(str()) and + index + 1 < len(els) and + type(els[index+1]) is type(str())): + el.tail = els[index+1] + + + + + Deleted: /z3/deliverance/branches/packaged/deliverance/main.py ============================================================================== --- /z3/deliverance/branches/packaged/deliverance/main.py Mon Oct 9 22:03:44 2006 +++ (empty file) @@ -1,157 +0,0 @@ -import os -from lxml import etree -from time import time -from lxml.etree import Namespace, ElementBase, XMLParser -try: - from lxml.etree import ElementNamespaceClassLookup -except ImportError: - ElementNamespaceClassLookup = None - -nsmap = { - "dv": "http://www.plone.org/deliverance", - "html": "http://www.w3.org/1999/xhtml", - "xsl": "http://www.w3.org/1999/XSL/Transform", - "at": "http://plone.org/archetypes", - } - -parser = XMLParser() -if ElementNamespaceClassLookup is not None: - # Earlier versions of lxml did class lookup in all - # cases; newer versions require this explicit parser - # setup - lookup = ElementNamespaceClassLookup() - parser.setElementClassLookup(lookup) - -class AppMap: - - def __init__(self, layout_dir): - - # Open the appmap file, make a tree, and process XIncludes - self.module_dir = os.path.dirname(os.path.abspath(__file__)) - self.layout_dir = os.path.join(self.module_dir, layout_dir) - layoutsfn = os.path.join(self.layout_dir, "appmap.xml") - self.tree = etree.ElementTree( - file=layoutsfn, parser=parser) - self.tree.xinclude() - - # Make a themeprocessor to style all outgoing pages. Note that the - # .processor attribute comes from an lxml namespace binding, meaning it is - # defined via a custom Python class defined below (class LayoutElement) - root = self.tree.getroot() - layout = root.xpath("dv:layouts/dv:layout", nsmap)[0] - #self.themeprocessor = make_processor(layout) - self.themeprocessor = layout.processor - - - def publish(self, xmlstring): - """Given a string of XML, theme it""" - - resource = etree.XML(xmlstring) - response = str(self.themeprocessor(resource)) - - return response - -# The following are extensions based on lxml namespace extensions. It -# adds Python behavior to XML nodes. - -class DVRuleBase(ElementBase): - - def getThemeNode(self): - """Get a node in the theme doc""" - - # Current node is a rule, get xpath from the @theme attr - themedoc = self.xpath("../../dv:theme", nsmap)[0][0] - xpath = self.get("theme") - try: - themenode = themedoc.xpath(xpath, nsmap)[0] - except IndexError: - msg = "Themedoc has no node at: %s" % xpath - print msg - themenode = None - - return themenode - - -class LayoutElement(ElementBase): - - def processor(self): - """Make XSLT processor by changing theme based on rules""" - - # Apply all the rules - for rule in self.xpath("./dv:rules/*", nsmap): - rule.apply() - - # Merge applied rules into compilerdoc - compilerroot = self.xpath("../dv:compiler/xsl:stylesheet", nsmap)[0] - themeroot = self.xpath("dv:theme/html:html", nsmap)[0] - target = compilerroot.xpath("xsl:template[@match='/']", nsmap)[0] - target.append(themeroot) - - #print etree.tostring(compilerroot) - - return etree.XSLT(compilerroot) - - processor = property(processor) - - -class RuleReplaceElement(DVRuleBase): - - def apply(self): - # TODO: Someething here - themenode = self.getThemeNode() - if themenode is None: - return - del(themenode[:]) - themenode.text = None - xslvalueof = etree.SubElement(themenode, - "{%s}value-of" % nsmap["xsl"]) - xslvalueof.set("select", self.get("content")) - - -class RuleCopyElement(DVRuleBase): - - def apply(self): - themenode = self.getThemeNode() - if themenode is None: - return - del(themenode[:]) - themenode.text = None - xslvalueof = etree.SubElement(themenode, - "{%s}apply-templates" % nsmap["xsl"]) - xslvalueof.set("select", self.get("content")) - - -class RuleAppendElement(DVRuleBase): - - def apply(self): - themenode = self.getThemeNode() - if themenode is None: - return - xslvalueof = etree.SubElement(themenode, - "{%s}apply-templates" % nsmap["xsl"]) - xslvalueof.set("select", self.get("content")) - - -# Bind Python classes for lxml namespace support -namespace = Namespace(nsmap['dv']) -namespace['layout'] = LayoutElement -namespace['replace'] = RuleReplaceElement -namespace['copy'] = RuleCopyElement -namespace['append'] = RuleAppendElement - - -def timeit(xmlstring): - appmap = AppMap() - start = time() - iters = 50 - for i in range(iters): - result = appmap.publish(xmlstring) - print "*** Average time:", (time() - start) / iters, " ***\n" - print result[0:2000] - -def main(): - xmlstring = open("content/index.html").read() - timeit(xmlstring) - -if __name__ == "__main__": - main() Deleted: /z3/deliverance/branches/packaged/deliverance/mpfilter.py ============================================================================== --- /z3/deliverance/branches/packaged/deliverance/mpfilter.py Mon Oct 9 22:03:44 2006 +++ (empty file) @@ -1,70 +0,0 @@ -""" -Deliverance theming for mod_python filters - -Deliverance applies a theme to content. This mod_python module acts as an -Apache "filter", transforming content as it passes through Apache. - -This module gets imported by mod_python during its startup. Thus, the -appmap instance becomes a global, computed only once. If you need to -recompute the theme, for example, restart the Apache. -""" -import time -from cStringIO import StringIO - -from mod_python import apache -from deliverance.main import AppMap -appmap = AppMap() # Theme is generated once at module import time - -def outputfilter(filter): - if not hasattr(filter.req, 'notheme'): - # Check for a flag to not apply theme - args = filter.req.args - if args and args.find("notheme") > -1: - filter.req.notheme = True - else: - filter.req.notheme = False - - try: - streambuffer = filter.req.streambuffer - except AttributeError: - if filter.req.notheme: - # pass on if no theme - filter.pass_on() - return - elif not filter.req.headers_out.has_key("content-type"): - # pass on if no content type specified - filter.pass_on() - return - elif not filter.req.headers_out["content-type"].startswith("text/html"): - # pass on if not HTML - filter.pass_on() - return - - filter.req.streambuffer = StringIO() - streambuffer = filter.req.streambuffer - - streamlet = filter.readline() - while streamlet: - streambuffer.write(streamlet) - streamlet = filter.readline() - - if streamlet is None: - output = appmap.publish(streambuffer.getvalue()) - filter.req.headers_out["Content-Length"] = str(len(output)) - filter.write(output) - filter.close() - - -def handler(req): - """Basic filter applying to all mime types it is registered for""" - - # Get the path, strip off leading slash, and convert to a - # dotted notation for xml:id compatibility - path_info = req.path_info[1:] - dotted_path = path_info.replace("/", ".") - - response = appmap.publish(dotted_path) - req.content_type = "text/html" - req.write(response) - - return apache.OK Deleted: /z3/deliverance/branches/packaged/deliverance/renderer.xsl ============================================================================== --- /z3/deliverance/branches/packaged/deliverance/renderer.xsl Mon Oct 9 22:03:44 2006 +++ (empty file) @@ -1,67 +0,0 @@ - - - - localhello - /sandboxes/trois/trunk/deliverance/examples/plonenet.py - - - - - - <xsl:value-of select="$contentnode/@title"/> - - - - -
- - -
- - - -
- -
-

sitenav

- - -
-
- - -
    -
  • Item one
  • - -
  • - -
  • -
    -
-
- - -

- -

-
- - - - - -
Added: z3/deliverance/branches/packaged/deliverance/test-data/nabuur/nabuur.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nabuur/nabuur.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,556 @@ + + + + + + + + + + + +Nabuur volunteer opportunities | Volunteer in Bukavu DR of the Congo + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NABUUR.COM, the global Neighbour network + + + + +
   + Home + + + + | + Search + + | + + About NABUUR.COM + + | + + what can I do? + + | + + Login + + | + + + Join now +
+ + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + +
IssueStories & PhotosNeighboursWhat´s new
+ + + + + + + + +
+ + + + + + + + +
Bukavu: Women and young girls victims of violence
The context of war which characterized the city of Bukavu during several years has caused a procession of violence of all kinds. Its principal victims have been women and young girls. The large number of women and girls that fell victim to violence, rape, prostitution and abandonment is a big issue in the community. Read more...
 
+ + + + +
Help Bukavu
Join as an online volunteer
  + + + + + + + + + + + + + + + + + + +
+
+
The Local Representative represents the people of Bukavu  on these web pages
+
+
Amina Gis?le
Local Representative
+
Focus: Setting up a Women Trauma and Care Centre
100 women have united in ?Women Against Violence?. Their ambition is to start a Women Trauma and Care Centre. The Centre will assist women victims of violence and abuse. It will give them a space where they can see hope again, know about their health, learn self-help skills and help each other campaign for their rights. Read more... + +
 
+ +
+
The Facilitator is an online volunteer who coordinates the efforts of the other volunteers ('Neighbours') of this Village
+ +
+
Maria Samper
Facilitator
contact +
+
Here´s what YOU can do
+ + +
Contact organizations that can provide our village with useful information to create a good project proposal and that could guide us on how to establish a succesful trauma center.
»See the results of earlier actions
»Subscribe to the Bukavu newsletter
+
 
+ + +
+
+ + + + + + +
+ + + + + + + + + + + + + +
+ Volunteering in : + Africa + + - + Asia + - + America +
+ About NABUUR.COM + - + What can I do? + + - + Policy + - + FAQ + - + Contact + - + Sitemap + + + - + Home +
+ NABUUR.COM - Online Volunteering +
+ + + +
+ + + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nabuur/nabuur.theme ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nabuur/nabuur.theme Mon Oct 9 22:03:44 2006 @@ -0,0 +1,6 @@ + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nabuur/rules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nabuur/rules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,7 @@ + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nabuur/standardrules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nabuur/standardrules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,10 @@ + + + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.theme ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.theme Mon Oct 9 22:03:44 2006 @@ -0,0 +1,7 @@ + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,7 @@ + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr_expected.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr_expected.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + NYCSR + ??? + OpenPlans + + + + +
+ + +
+
+ + + + + + +
+ + +
+ + + + +
Views
+ + +
+ + + + + + + + + + + +
+ + +
+ + + + + + + + + + +
+ + +
Document Actions
+ + +
+ +

NYCSR

+ +
+ +
+ + + + + + last modified + + + 2006-09-15 11:18 + + + + + + + + + +
+ +
+ +
+ +
+ + + + + +
+

+Welcome to the NYC Streets Renaissance Campaign Headquarters
+

+

The goal of the NYCSR is to tranform New York City streets so that they are safer, more productive and more livable.

+

Streets can be places for neighbors to meet

+

New York City is defined by its vibrant and diverse streets and neighborhoods. Unfortunately, our neighborhoods and business districts are buckling under increasing amounts of dangerous car and truck traffic. Children can no longer + + + + + + + play on their own blocks + + + + + + + + +, while parents worry about turning cars smashing into baby carriages. Senior citizens are losing their independence, shut up in their homes for fear of crossing the street. And shoppers and investors are being turned away by chaotic, traffic-choked avenues.

+

This is unacceptable. The time is long overdue for our great city to strike a better balance between traffic and the needs of pedestrians.

+

The NYC Streets Renaissance Campaign aims to:

+
    +
  • +Educate New Yorkers about potential transportation policy changes that will improve quality of life across New York City
  • +
  • +Promote a rebalancing of this public space away from private vehicles and toward community needs
  • +
  • +Demonstrate the widespread public support for reform on these issues
  • +
  • +Tap the potential of New Yorkers to re-imagine their own streets
  • +
+

+

Our Initiatives:

+ +

+

+
  • Help neighborhood leaders in the fight for long overdue, common sense improvements to their neighborhood streets
+

+

+

To get involved, add your ideas for making New York City a better place to live and work to our Taking it Citywide + + + + + + + Neighborhoods + + + + + + + + + page, or visit us at http://www.nycsr.org/involved.php

+

+

+

+

+

old landing page

+


+

Together, we can re-imagine the streets of New York City.

+ + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + + +
+ + +
+ +
+ + +
+
+ + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/openplans.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/openplans.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,648 @@ + + + + + + + + + + + + + + + + NYCSR + — + OpenPlans + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ Skip to content + + Skip to navigation + +
+ + + +

+ OpenPlans +

+ + + + + + + + + +
+
+
+ +
+ + + +
+ +
+
+ + +
+ + + + +
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + +
+ + +
+ + + + +
Views
+ + + + + +
+ + + + + + + + + + + +
+ + +
+ + + + + + + + + + +
+ + +
Document Actions
+ + + + + + +
+ +

NYCSR

+ +
+ +
+ + + + + + last modified + + + 2006-09-15 11:18 + + + + + + + + + +
+ +
+ +
+ +
+ + + + + +
+

Welcome to the NYC Streets Renaissance Campaign Headquarters

The goal of the NYCSR is to tranform New York City streets so that they are safer, more productive and more livable.

Streets can be places for neighbors to meet

New York City is defined by its vibrant and diverse streets and neighborhoods. Unfortunately, our neighborhoods and business districts are buckling under increasing amounts of dangerous car and truck traffic. Children can no longer + + + + + + + play on their own blocks + + + + + + + + +, while parents worry about turning cars smashing into baby carriages. Senior citizens are losing their independence, shut up in their homes for fear of crossing the street. And shoppers and investors are being turned away by chaotic, traffic-choked avenues.

This is unacceptable. The time is long overdue for our great city to strike a better balance between traffic and the needs of pedestrians.

The NYC Streets Renaissance Campaign aims to:

  • Educate New Yorkers about potential transportation policy changes that will improve quality of life across New York City
  • Promote a rebalancing of this public space away from private vehicles and toward community needs
  • Demonstrate the widespread public support for reform on these issues
  • Tap the potential of New Yorkers to re-imagine their own streets

Our Initiatives:

  • Help neighborhood leaders in the fight for long overdue, common sense improvements to their neighborhood streets

To get involved, add your ideas for making New York City a better place to live and work to our Taking it Citywide + + + + + + + Neighborhoods + + + + + + + + + page, or visit us at http://www.nycsr.org/involved.php

old landing page


Together, we can re-imagine the streets of New York City.

+ + + +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + + +
+ + +
+ +
+ + +
+ +
+
+ +
+ + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/standardrules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/standardrules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,10 @@ + + + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/example.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/example.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,10 @@ + + + I am a title + + + Early text

Paragraph one

+

Paragraph two

+ extra + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/example_expected.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/example_expected.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,14 @@ + + + + I am a title + + + + Some text +
+

Paragraph one

+

Paragraph two

+
+ + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/rules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/rules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,9 @@ + + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/standardrules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/standardrules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,8 @@ + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/standardrules2.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/standardrules2.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,8 @@ + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/text-rules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/text-rules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,9 @@ + + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/texttest_expected.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/texttest_expected.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,16 @@ + + + + I am a title + + + + Some text +
+ Early text +

Paragraph one

+

Paragraph two

+ extra +
+ + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/theme.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/theme.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,9 @@ + + + Example + + + Some text +
replace this
+ + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_expected.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_expected.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,13 @@ + + + + + + I am a title + + + Early text

Paragraph one

+

Paragraph two

+ extra + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_rules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_rules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,11 @@ + + + + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_theme.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/xinclude_theme.html Mon Oct 9 22:03:44 2006 @@ -0,0 +1,7 @@ + + + + +
I should go away
+ + Added: z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,134 @@ + + + + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + +
Real Content
12

zzz

3 +
+ + + Blah
+
Dummy Content

HI!

13
+
+
+ + + + + + + + + + Blah + + + +
Real Content
+
+ + + + + Blah + + +
Deliverance error: no element found in theme
+ rule: <append theme=".//div[@id='foo']" content=".//div[@id='bar']"/> +
+ + +
+
+ + + + + + + + + + Blah
Dummy Content
Dummy Content
+
+ + +
Real Content
+
+ + + + + Blah + + +
Dummy Content
+ Deliverance error: multiple elements found in theme
rule: <append theme=".//div[@class='foo']" content=".//div[@id='bar']"/> +
+
Dummy Content
+ + +
+
+ + + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + + leading text
more

inside p

trailing text tail of body +
+ + + Blah
Dummy Content

HI!

+ leading text
more

inside p

trailing text
+ +
+
+ + + + + + + + + + Blah
Dummy Content
+ +
+ + + leading text
more

inside p

trailing text tail of body +
+ + + Blah
Dummy Content leading text
more +

inside p

trailing text
+ +
+
+ + +
Added: z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,170 @@ + + + + + + + + + + + Blah
Dummy Content

HI!

This should go away
+ +
+ + +
Real Content
1

zzz

3 +
+ + + Blah
+
Dummy Content

HI!

13
+
+
+ + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + +
Real Content
1

zzz

3 +
+ + + Blah
+
Dummy Content

HI!

13
+
+
+ + + + + + + + + + Blah + + + +
Real Content
+
+ + + + + Blah + + +
Deliverance error: no element found in theme
+ rule: <append-or-replace theme=".//div[@id='foo']" content=".//div"/> +
+ + +
+
+ + + + + + + + + + Blah
Dummy Content
Dummy Content
+
+ + +
Real Content
+
+ + + + + Blah + + +
Dummy Content
+ Deliverance error: multiple elements found in theme
rule: <append-or-replace theme=".//div" content=".//div"/> +
+
Dummy Content
+ + +
+
+ + + + + + + + + + Blah
Dummy Content

HI!

This should go away
+ +
+ + +
Real Content
1

zzz

3 +
+ + + + + Blah + + +
Deliverance error: invalid xpath for content
rule: <append-or-replace theme=".//div[@id='foo']" content="//span/child::node()"/> +
+
+
Dummy Content

HI!

This should go away
+ + + + + + + + + + + + + + Blah
Dummy Content

HI!

This should go away
+ +
+ + +
Real Content

in p

1

zzz

3 +
+ + + + + Blah + + +
Deliverance error: invalid xpath for content
rule: <append-or-replace theme=".//div[@id='foo']" content="//span/child::node()"/> +
+
+
Dummy Content

HI!

This should go away
+ + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/test_baserules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_baserules.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + Title to be replaced + + + + +
Dummy Content

HI!

+ +
+ + + + New Title + + + + +
Real Content
12

zzz

3 +
+ + + + + + + + + New Title + + + + + + +
+
Dummy Content

HI!

+ + +
+
+
+ Added: z3/deliverance/branches/packaged/deliverance/test-data/test_comments.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_comments.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + test + + +

some text

+ + + +
+ + + + +
+ +
+ + +
+ + + + + test + + +

some text

+ +
+ +
+ + +
+
+ + + + + + + + + + + test + + + +

some text

+ + + +
+ + + + + + + + blah blah blah + + + + + + + + test + + + + +

some text

+ + + +
+
+ + + +
Added: z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,123 @@ + + + + + + + + + + + Blah
Dummy Content
+
+ + +
Real Content
12

zzz

3 +
+ + + Blah
13
+
+
+ + + + + + + + + + Blah + + + +
Real Content
+
+ + + + + Blah + + +
Deliverance error: no element found in theme
rule: <copy theme=".//div[@id='foo']" content=".//div[@id='bar']"/> +
+ + +
+
+ + + + + + + + + + Blah
Dummy Content
Dummy Content
+
+ + +
Real Content
+
+ + + + + Blah + + +
Dummy Content
Deliverance error: multiple elements found in theme
rule: <copy theme=".//div[@class='foo']" content=".//div[@id='bar']"/> +
+
Dummy Content
+ + +
+
+ + + + + + + + + + Blah
Dummy Content
+
+ + + leading text
more

a p tag

trailing text body tail +
+ + + Blah
leading text
more

a p tag

trailing text
+
+
+ + + + + + + + + + Blah
Dummy Content
+
+ + + leading text
more

a p tag

trailing text body tail +
+ + + Blah

a p tag

+
+
+ + +
Added: z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,108 @@ + + + + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + +
Real Content
12

zzz

3 +
+ + + Blah
+
13Dummy Content

HI!

+
+
+ + + + + + + + + + Blah + + + +
Real Content
+
+ + + + + Blah + + +
Deliverance error: no element found in theme
+ rule: <prepend theme=".//div[@id='foo']" content=".//div[@id='bar']"/> +
+ + +
+
+ + + + + + + + + + Blah
Dummy Content
Dummy Content
+
+ + +
Real Content
+
+ + + + + Blah + + +
Dummy Content
+ Deliverance error: multiple elements found in theme
rule: <prepend theme=".//div[@class='foo']" content=".//div[@id='bar']"/> +
+
Dummy Content
+ + +
+
+ + + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + + leading text
more

inside p

trailing text tail of body +
+ + + Blah
leading text
more

inside p

trailing textDummy Content

HI!

+ +
+
+ +
Added: z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,171 @@ + + + + + + + + + + + Blah
Dummy Content
+
+ + +
Real Content
+
+ + + Blah
Real Content
+
+
+ + + + + + + + + Blah

first stuff

Dummy Content
last stuff +
+ + +
Real Content
More Real Content
+
+ + + Blah

first stuff

Real Content
More Real Content
last stuff +
+
+ + + + + + + + + Blah + + + +
Real Content
+
+ + + Blah
Deliverance error: no element found in theme
+ rule: <replace theme="//div[@id='foo']" content="//div[@id='bar']"/>
+ +
+
+ + + + + + + + + + Blah
Dummy Content
Dummy Content
+
+ + +
Real Content
+
+ + + + + Blah + + +
Dummy Content
Deliverance error: multiple elements found in theme
rule: <replace theme="//div[@class='foo']" content="//div[@id='bar']"/> +
+
Dummy Content
+ + +
+
+ + + + + + + + + + Blah
Dummy Content
+
+ + +
Real Content
+
+ + + BlahReal Content + +
+ + + + + + + + + Blah
Dummy Content
theme tail +
+ + +
Real Content

a nice p tag

mid textsome i textend tail
+
+ + + BlahReal Content

a nice p tag

mid textsome i textend tailtheme tail +
+
+ + + + + + + + + + Blah

some text

Dummy Content
theme tail +
+ + +
Real Content

a nice p tag

mid textsome i textend tail
+
+ + + Blah

some text

Real Content

a nice p tag

mid textsome i textend tailtheme tail +
+
+ + + + + + + + + Blahlead
Dummy Content
tail +
+ + +
Real Content
+
+ + + Blahleadtail + +
+ +
+ Added: z3/deliverance/branches/packaged/deliverance/test-data/test_submatch.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_submatch.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + test + + +

replaced text

+ + +
+ + + + +
+ outer div +
+ inner div +
+
+ + +
+ + + + + test + + +
+ outer div +
+ inner div +
+
+
+ inner div +
+ + +
+
+ + + + + + + + + + + test + + +

replaced text

+ + +
+ + + + +
+ outer div +
+ inner div +
+
+ + +
+ + + + + test + + +
+ outer div +
+ inner div +
+
+
+ inner div +
+ + +
+
+ + + + + + + + + + + test + + +

some text

+ + +
+ + + + +
+ outer div +
+ inner div +
+
+ + +
+ + + + + test + + +

some text

+
+ outer div +
+ inner div +
+
+
+ inner div +
+ + +
+
+ + + + + + + + + + + + test + + +

replaced text

+ + +
+ + + + +
+ outer div +
+ inner div +
+
+ + +
+ + + + + test + + +

replaced text

+
+ outer div +
+ inner div +
+
+
+ inner div +
+ + +
+
+ + + + + + + + + + + test + + +

replaced text

+
+ replace-me +
+ + +
+ + + + +
+ outer div +
+ inner div +
+
+ + +
+ + + + + test + + +

replaced text

+
+ outer div +
+ inner div +
+
+
+ inner div +
+ + +
+
+ + + +
Added: z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml Mon Oct 9 22:03:44 2006 @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + +
+ + +
+ +

+ New York is a city best enjoyed on foot, yet we plan our streets for cars. +

+

+ New York City's streets are the soul of its neighborhoods and the pathways to some of the world's most in-demand destinations. For generations, New Yorkers and visitors have strolled, shopped and socialized on sidewalks and street corners. Pedestrian friendly streets are the city's most fundamental assets. +

+

+ Unfortunately, we aren't making the most of these assets. Instead, our streets are being managed almost entirely for traffic flow, with neighborhoods and business districts buckling under increasing amounts of dangerous car and truck traffic. If we continue planning our streets for cars and traffic, we will get more cars and traffic; conversely, if we start planning our cities for people and places, we will get more people and places. +

+

+ Streets are more than just car corridors; they are valuable civic spaces and resources that need to be wisely allocated. The New York City Streets Renaissance Campaign is building the movement to re-imagine our streets as lively public places. +

+ +
+

+ Goals of the New York City Streets Renaissance +

+
    +
  • + Educate New Yorkers about potential transportation policy changes that will improve quality of life across New York City +
  • +
  • + Promote a rebalancing of this public space away from private vehicles and toward community needs +
  • +
  • + Demonstrate the widespread public support for reform on these issues +
  • +
  • + Tap the potential of New Yorkers to re-imagine their own streets +
  • +
+
+ +

+ The choice is clear: either we choose to be defined by worsening traffic and perilous streets or we can define ourselves through great public spaces and lively streets. Through action and dialogue New Yorkers can raise expectations for their public realm. Join our city-wide campaign for local improvements that reflect your neighborhood's unique character. +

+ +
+ + + + + + +
+ +
+ + +
+ + + + + + Added: z3/deliverance/branches/packaged/deliverance/test_speed.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test_speed.py Tue Oct 10 22:06:00 2006 @@ -0,0 +1,73 @@ +import sys +from lxml import etree +from htmlserialize import tostring +import urllib +from interpreter import Renderer as PythonRenderer +from xslt import Renderer as XSLTRenderer +from optparse import OptionParser +import re +import os +from time import time + +""" +Tests the relative speed of the Python and XSLT renderers + +""" + + +DEFAULT_BASE_URL = "http://www.example.com" + + +def grab_url(url): + f = open(url) + data = f.read() + f.close() + return data + +def do_transform(renderer_type, theme_url, base_url, rules_url, content_url): + rules = etree.XML(grab_url(rules_url)) + theme = etree.HTML(grab_url(theme_url)) + content = etree.HTML(grab_url(content_url)) + + def reference_resolver(href, parse, encoding=None): + if not href.startswith('/'): + href = os.path.join(os.path.dirname(rules_url),href) + text = grab_url(href) + if parse == "xml": + return etree.XML(text) + elif encoding: + return text.decode(encoding) + + start = time() + iters = 1000 + for i in range(iters): + renderer = None + if renderer_type == 'xslt': + renderer = XSLTRenderer(theme,base_url,rules,reference_resolver) + elif renderer_type == 'py': + renderer = PythonRenderer(theme,base_url,rules,reference_resolver) + else: + print "Unknown renderer type '" + renderer_type + "'" + return etree.Element("error") + renderer.render(content) + + print "Renderer: " + renderer_type + print "*** time:", time() - start , " for " , iters, " iterations ***\n" + + return + + +def parse_blend_file(filename): + b = etree.XML(open(filename).read()) + return b.get('theme'),b.get('baseurl'),b.get('rules') + + +def die(message,parser): + print message + parser.print_usage() + sys.exit(0) + +if __name__ == '__main__': + do_transform('xslt','test-data/nycsr/nycsr_speed.html','http://www.nycsr.org','test-data/nycsr/nycsr.xml','test-data/nycsr/openplans.html') + do_transform('py','test-data/nycsr/nycsr_speed.html','http://www.nycsr.org','test-data/nycsr/nycsr.xml','test-data/nycsr/openplans.html') + From cabraham at codespeak.net Tue Oct 10 22:50:59 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Tue, 10 Oct 2006 22:50:59 +0200 (CEST) Subject: [z3-checkins] r33142 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061010205059.2113F1011C@code0.codespeak.net> Author: cabraham Date: Tue Oct 10 22:50:57 2006 New Revision: 33142 Modified: z3/deliverance/branches/packaged/deliverance/test_speed.py Log: updated test_speed.py Modified: z3/deliverance/branches/packaged/deliverance/test_speed.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_speed.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_speed.py Tue Oct 10 22:50:57 2006 @@ -38,17 +38,18 @@ elif encoding: return text.decode(encoding) + renderer = None + if renderer_type == 'xslt': + renderer = XSLTRenderer(theme,base_url,rules,reference_resolver) + elif renderer_type == 'py': + renderer = PythonRenderer(theme,base_url,rules,reference_resolver) + else: + print "Unknown renderer type '" + renderer_type + "'" + return etree.Element("error") + start = time() - iters = 1000 + iters = 3000 for i in range(iters): - renderer = None - if renderer_type == 'xslt': - renderer = XSLTRenderer(theme,base_url,rules,reference_resolver) - elif renderer_type == 'py': - renderer = PythonRenderer(theme,base_url,rules,reference_resolver) - else: - print "Unknown renderer type '" + renderer_type + "'" - return etree.Element("error") renderer.render(content) print "Renderer: " + renderer_type From ltucker at codespeak.net Wed Oct 11 21:54:39 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 11 Oct 2006 21:54:39 +0200 (CEST) Subject: [z3-checkins] r33191 - in z3/deliverance/branches/packaged/deliverance: . test-data test-data/static Message-ID: <20061011195439.EE1CE101AA@code0.codespeak.net> Author: ltucker Date: Wed Oct 11 21:54:32 2006 New Revision: 33191 Modified: z3/deliverance/branches/packaged/deliverance/htmlserialize.py z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/static/rules.xml z3/deliverance/branches/packaged/deliverance/test-data/static/text-rules.xml z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml z3/deliverance/branches/packaged/deliverance/utils.py z3/deliverance/branches/packaged/deliverance/wsgifilter.py z3/deliverance/branches/packaged/deliverance/xslt.py Log: error handling for missing content, fix for foreign character sets Modified: z3/deliverance/branches/packaged/deliverance/htmlserialize.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/htmlserialize.py (original) +++ z3/deliverance/branches/packaged/deliverance/htmlserialize.py Wed Oct 11 21:54:32 2006 @@ -1,5 +1,5 @@ from lxml import etree - +import re html_xsl = """ @@ -37,3 +37,26 @@ return str(html_transform(doc)) + + +HTTP_EQUIV_MATCHER_PAT = re.compile(r"\<\s*meta\s+([^\>])*http-equiv\s*=\s*(\'|\")\s*content-type\s*(\'|\")([^\>])*charset\s*=\s*(?P[\w-]+)([^\>])*\>",re.I|re.M) +OTHER_HTTP_EQUIV_MATCHER_PAT = re.compile(r"\<\s*meta\s+([^\>])*charset\s*=\s*(?P[\w-]+)([^\>])*http-equiv\s*=\s*(\'|\")\s*content-type\s*(\'|\")([^\>])*\>",re.I|re.M) +def decodeAndParseHTML(text): + """ + if an html meta tag specifying a charset can be matched, + decode the text to a python unicode string before parsing + """ + m = HTTP_EQUIV_MATCHER_PAT.search(text) + if not m: + m = OTHER_HTTP_EQUIV_MATCHER_PAT.search(text) + + if m: + charset = m.group('charset') + text = text.decode(charset) + + return etree.HTML(text) + + + + + Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Wed Oct 11 21:54:32 2006 @@ -62,6 +62,7 @@ content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if (len(content_els) == 0): + self.add_to_body_start(theme, self.format_error("no content matched", rule)) return non_text_els = self.elements_in(content_els) @@ -96,6 +97,7 @@ content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if (len(content_els) == 0): + self.add_to_body_start(theme, self.format_error("no content matched", rule)) return non_text_els = self.elements_in(content_els) @@ -141,8 +143,7 @@ content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: - self.attach_text_to_previous(theme_el,theme_el.tail) - theme_el.getparent().remove(theme_el) + self.add_to_body_start(theme, self.format_error("no content matched", rule)) return non_text_els = self.elements_in(content_els) @@ -195,6 +196,7 @@ content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: + self.add_to_body_start(theme, self.format_error("no content matched", rule)) return non_text_els = self.elements_in(content_els) @@ -222,11 +224,16 @@ self.add_to_body_start(theme,self.format_error("invalid xpath for content", rule=rule)) return + content_els = copy.deepcopy(content.xpath(content_xpath)) + + if len(content_els) == 0: + self.add_to_body_start(theme, self.format_error("no content matched", rule)) + return + for el in theme_el: if el.tag == remove_tag: theme_el.remove(el) - content_els = copy.deepcopy(content.xpath(content_xpath)) self.strip_tails(content_els) theme_el.extend(content_els) Modified: z3/deliverance/branches/packaged/deliverance/test-data/static/rules.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/static/rules.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/rules.xml Wed Oct 11 21:54:32 2006 @@ -2,8 +2,8 @@ - - - + + + Modified: z3/deliverance/branches/packaged/deliverance/test-data/static/text-rules.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/static/text-rules.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/static/text-rules.xml Wed Oct 11 21:54:32 2006 @@ -2,8 +2,8 @@ - - - + + + Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml Wed Oct 11 21:54:32 2006 @@ -68,17 +68,51 @@ - - - Blah - - -
Dummy Content
- Deliverance error: multiple elements found in theme
rule: <append theme=".//div[@class='foo']" content=".//div[@id='bar']"/> -
-
Dummy Content
- - + + + Blah + + +
Deliverance error: multiple elements found in theme
rule: <append theme=".//div[@class='foo']" content=".//div[@id='bar']"/> +
+
Dummy Content
+
Dummy Content
+ + + +
+
+ + + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + + leading text
more

inside p

trailing text tail of body +
+ + + + + Blah + + +
Deliverance error: no content matched
rule: <append theme=".//div[@id='foo']" content="//div[@id='bar']"/> +
+
+
Dummy Content

HI!

+ + Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml Wed Oct 11 21:54:32 2006 @@ -91,18 +91,20 @@ - - - Blah - - -
Dummy Content
- Deliverance error: multiple elements found in theme
rule: <append-or-replace theme=".//div" content=".//div"/> -
-
Dummy Content
- - -
+ + + Blah + + +
Deliverance error: multiple elements found in theme
rule: <append-or-replace theme=".//div" content=".//div"/> +
+
Dummy Content
+
Dummy Content
+ + + @@ -167,4 +169,38 @@ + + + + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + + leading text
more

inside p

trailing text tail of body +
+ + + + + Blah + + +
Deliverance error: no content matched
rule: <append-or-replace theme=".//div[@id='foo']" content="//span[@id='bar']"/> +
+
+
Dummy Content

HI!

+ + + + + + Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml Wed Oct 11 21:54:32 2006 @@ -69,11 +69,15 @@ Blah -
Dummy Content
Deliverance error: multiple elements found in theme
rule: <copy theme=".//div[@class='foo']" content=".//div[@id='bar']"/> -
+
Deliverance error: multiple elements found in theme
rule: <copy theme=".//div[@class='foo']" content=".//div[@id='bar']"/> +
+
Dummy Content
Dummy Content
+ @@ -120,4 +124,35 @@ + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + + leading text
more

inside p

trailing text tail of body +
+ + + + + Blah + + +
Deliverance error: no content matched
rule: <copy theme=".//div[@id='foo']" content="//div[@id='bar']"/> +
+
+
Dummy Content

HI!

+ + + + + + Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml Wed Oct 11 21:54:32 2006 @@ -68,22 +68,25 @@ - - - Blah - - -
Dummy Content
- Deliverance error: multiple elements found in theme
rule: <prepend theme=".//div[@class='foo']" content=".//div[@id='bar']"/> -
-
Dummy Content
- - + + + Blah + + +
Deliverance error: multiple elements found in theme
rule: <prepend theme=".//div[@class='foo']" content=".//div[@id='bar']"/> +
+
Dummy Content
+
Dummy Content
+ + +
- @@ -105,4 +108,35 @@ + + + + + + + + + Blah
Dummy Content

HI!

+ +
+ + + leading text
more

inside p

trailing text tail of body +
+ + + + + Blah + + +
Deliverance error: no content matched
rule: <prepend theme=".//div[@id='foo']" content="//div[@id='bar']"/> +
+
+
Dummy Content

HI!

+ + + + + Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml Wed Oct 11 21:54:32 2006 @@ -76,16 +76,20 @@ - - + + Blah -
Dummy Content
Deliverance error: multiple elements found in theme
rule: <replace theme="//div[@class='foo']" content="//div[@id='bar']"/> -
+
Deliverance error: multiple elements found in theme
rule: <replace theme="//div[@class='foo']" content="//div[@id='bar']"/> +
+
Dummy Content
Dummy Content
+
@@ -148,22 +152,34 @@ - + + - + - Blahlead
Dummy Content
tail + Blah
Dummy Content

HI!

+
-
Real Content
+ leading text
more

inside p

trailing text tail of body
- + - Blahleadtail + + + Blah + + +
Deliverance error: no content matched
rule: <replace theme=".//div[@id='foo']" content="//div[@id='bar']"/> +
+
+
Dummy Content

HI!

+ + Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Wed Oct 11 21:54:32 2006 @@ -1,6 +1,7 @@ from lxml import etree import re import urlparse +import htmlserialize class RuleSyntaxError(Exception): """ @@ -38,8 +39,8 @@ self.add_to_body_start(theme, e) return None elif len(theme_els)> 1: - e = self.format_error("multiple elements found in theme", rule) - theme_els[0].append(e) + e = self.format_error("multiple elements found in theme", rule, theme_els) + self.add_to_body_start(theme, e) return None return theme_els[0] @@ -61,7 +62,15 @@ br.tail = 'rule: %s' % etree.tostring(rule) d.append(br) if elts: - d.extend(elts) + d.append(etree.Element('br')) + textArea = etree.Element('textarea') + textArea.attrib['rows'] = '24' + textArea.attrib['cols'] = '80' + textArea.attrib['readonly'] = 'readonly' + textArea.text = '' + for el in elts: + textArea.text += htmlserialize.tostring(el) + d.append(textArea) return d @@ -75,6 +84,8 @@ def add_to_body_start(self,theme, el): + if not el: + return body = theme.find('body') if body is None: body = theme[0] Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Wed Oct 11 21:54:32 2006 @@ -8,6 +8,8 @@ import urlparse import urllib from lxml import etree +#from lxml.etree import HTML as parseHTML +from htmlserialize import decodeAndParseHTML as parseHTML from paste.wsgilib import intercept_output from paste.request import construct_url from paste.response import header_value, replace_header @@ -36,7 +38,6 @@ try: self._lock.acquire() if not self._renderer or self.cache_expired(): - print "rebuild renderer" self._renderer = self.create_renderer(environ) self._cache_time = datetime.datetime.now() return self._renderer @@ -57,7 +58,7 @@ elif encoding: return text.decode(encoding) - return Renderer(etree.HTML(theme), full_theme_uri, etree.XML(rule), + return Renderer(parseHTML(theme), full_theme_uri, etree.XML(rule), reference_resolver=reference_resolver) @@ -86,6 +87,7 @@ if status is None: # should_intercept returned False return body + body = self.filter_body(environ, body) replace_header(headers, 'content-length', str(len(body))) replace_header(headers, 'content-type', 'text/html; charset=utf-8') @@ -97,8 +99,8 @@ return type.startswith('text/html') or type.startswith('application/xhtml+xml') def filter_body(self, environ, body): - content = self.get_renderer(environ).render(etree.HTML(body)) - return tostring(content) + content = self.get_renderer(environ).render(parseHTML(body)) + return tostring(content) def get_resource(self, environ, uri): internalBaseURL = environ.get(DELIVERANCE_BASE_URL,None) Modified: z3/deliverance/branches/packaged/deliverance/xslt.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/xslt.py (original) +++ z3/deliverance/branches/packaged/deliverance/xslt.py Wed Oct 11 21:54:32 2006 @@ -42,7 +42,9 @@ insertion_point = xslt_wrapper.xpath("//xsl:transform/xsl:template[@match='/']", nsmap)[0] insertion_point.append(theme_copy) + self.transform = etree.XSLT(xslt_wrapper) + def render(self,content): @@ -81,15 +83,24 @@ if theme_el is None: return + # add an element that produces an error in the theme if + # no content is matched + self.add_conditional_missing_content_error(theme,rule) + copier = etree.SubElement(theme_el, "{%s}copy-of" % nsmap["xsl"]) copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) + def apply_prepend(self,rule,theme): theme_el = self.get_theme_el(rule,theme) if theme_el is None: return + # add an element that produces an error in the theme if + # no content is matched + self.add_conditional_missing_content_error(theme,rule) + copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) @@ -102,11 +113,21 @@ theme_el = self.get_theme_el(rule,theme) if theme_el is None: return - + + self.add_conditional_missing_content_error(theme,rule) + copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) - self.replace_element(theme_el,copier) + + # if content is matched, replace the theme element, otherwise, keep the + # theme element + choose = self.make_when_otherwise("count(%s)=0" % + rule.attrib[self.RULE_CONTENT_KEY], + copy.deepcopy(theme_el), + copier) + + self.replace_element(theme_el,choose) def apply_copy(self,rule,theme): @@ -114,11 +135,30 @@ if theme_el is None: return - del(theme_el[:]) - theme_el.text = None + # add an element that produces an error in the theme if + # no content is matched + self.add_conditional_missing_content_error(theme,rule) + + # create an element that is like the target theme element + # with its children replaced by an xsl copy element + copy_theme_el = copy.deepcopy(theme_el) + del(copy_theme_el[:]) + copy_theme_el.text = None copier = etree.SubElement(theme_el, "{%s}copy-of" % nsmap["xsl"]) - copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) + copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) + copy_theme_el.append(copier) + + # create a copy of the current theme element + normal_theme_el = copy.deepcopy(theme_el) + + # create an xsl choose element that picks between them based + # on whether content was matched + choose = self.make_when_otherwise("count(%s)=0" % + rule.attrib[self.RULE_CONTENT_KEY], + normal_theme_el, + copy_theme_el) + self.replace_element(theme_el,choose) @@ -131,12 +171,21 @@ self.add_to_body_start(theme,self.format_error("invalid xpath for content", rule=rule)) return + # add an element that produces an error in the theme if + # no content is matched + self.add_conditional_missing_content_error(theme,rule) + for el in theme_el: if el.tag == remove_tag: - theme_el.remove(el) - copier = etree.SubElement(theme_el, - "{%s}copy-of" % nsmap["xsl"]) - copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) + conditional = etree.Element("{%s}if" % nsmap["xsl"]) + conditional.set("test","count(%s) = 0" % + rule.attrib[self.RULE_CONTENT_KEY]) + conditional.append(copy.deepcopy(el)) + self.replace_element(el,conditional) + + copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) + copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) + theme_el.append(copier) def xsl_escape_comments(self,doc): @@ -149,3 +198,24 @@ escaped.text = c.text self.replace_element(c,escaped) + def add_conditional_missing_content_error(self,theme,rule): + """ + """ + err = self.format_error("no content matched", rule) + if err: + conditional = etree.Element("{%s}if" % nsmap["xsl"]) + conditional.set("test", "count(%s)=0" % rule.attrib[self.RULE_CONTENT_KEY]) + conditional.append(err) + self.add_to_body_start(theme,conditional) + + + def make_when_otherwise(self, test, whenbody, otherwisebody): + choose = etree.Element("{%s}choose" % nsmap["xsl"]) + when = etree.Element("{%s}when" % nsmap["xsl"]) + when.set("test", test) + when.append(copy.deepcopy(whenbody)) + otherwise = etree.Element("{%s}otherwise" % nsmap["xsl"]) + otherwise.append(otherwisebody) + choose.append(when) + choose.append(otherwise) + return choose From ltucker at codespeak.net Wed Oct 11 23:41:34 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 11 Oct 2006 23:41:34 +0200 (CEST) Subject: [z3-checkins] r33197 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061011214134.67D30101B8@code0.codespeak.net> Author: ltucker Date: Wed Oct 11 23:40:57 2006 New Revision: 33197 Added: z3/deliverance/branches/packaged/deliverance/test-data/test_debug.xml Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/xslt.py Log: added preliminary debug support for xslt Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Wed Oct 11 23:40:57 2006 @@ -20,6 +20,12 @@ if reference_resolver: xinclude.include(self.rules, loader=reference_resolver) + debug = rules.get("debug", None) + if debug and debug.lower() == "true": + self.debug = True + else: + self.debug = False + def render(self, content): result = copy.deepcopy(self.theme) Added: z3/deliverance/branches/packaged/deliverance/test-data/test_debug.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_debug.xml Wed Oct 11 23:40:57 2006 @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + before the div
in the div
after the div + +
+ + + +
Real Content
+ +
+ + + + + before the div
in the div
after the div +
Real Content
+ +
+
+ + + + + + + + + + + + before the div
in the div
after the div + +
+ + + +
Real Content
+ +
+ + + + + before the divafter the div +
Real Content
+ +
+
+ + + + + + + + + + + + + before the div
in the div
after the div + +
+ + + +
Real Content
+ +
+ + + + +
Real Content
+ before the div
in the div
after the div + + +
+
+ + + + + + + + + + + + + i'm before the spani'm in a spani'm after the span + + + + + +
Real Content
+ +
+ + + + + i'm before the span +
Real Content
+ i'm after the span + + +
+
+ + + + + + + + + + + + + + + + + +
Real Content
+ +
+ + + +
Real Content
+ +
+
+ + +
+ Modified: z3/deliverance/branches/packaged/deliverance/xslt.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/xslt.py (original) +++ z3/deliverance/branches/packaged/deliverance/xslt.py Wed Oct 11 23:40:57 2006 @@ -37,6 +37,13 @@ if reference_resolver: xinclude.include(rules,loader=reference_resolver) + + debug = rules.get("debug", None) + if debug and debug.lower() == "true": + self.debug = True + else: + self.debug = False + self.apply_rules(rules,theme_copy) xslt_wrapper = etree.XML(xslt_wrapper_skel) insertion_point = xslt_wrapper.xpath("//xsl:transform/xsl:template[@match='/']", @@ -87,10 +94,12 @@ # no content is matched self.add_conditional_missing_content_error(theme,rule) - copier = etree.SubElement(theme_el, - "{%s}copy-of" % nsmap["xsl"]) + + copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) + self.debug_append(theme_el, copier, rule) + def apply_prepend(self,rule,theme): theme_el = self.get_theme_el(rule,theme) @@ -105,9 +114,8 @@ copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) - theme_el.insert(0,copier) - copier.tail = theme_el.text - theme_el.text = None + self.debug_prepend(theme_el, copier, rule) + def apply_replace(self,rule,theme): theme_el = self.get_theme_el(rule,theme) @@ -127,7 +135,7 @@ copy.deepcopy(theme_el), copier) - self.replace_element(theme_el,choose) + self.debug_replace(theme_el,choose,rule) def apply_copy(self,rule,theme): @@ -158,7 +166,7 @@ rule.attrib[self.RULE_CONTENT_KEY], normal_theme_el, copy_theme_el) - self.replace_element(theme_el,choose) + self.debug_replace(theme_el,choose,rule) @@ -185,8 +193,9 @@ copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) - theme_el.append(copier) + self.debug_append(theme_el, copier, rule) + def xsl_escape_comments(self,doc): """ @@ -219,3 +228,51 @@ choose.append(when) choose.append(otherwise) return choose + + + def debug_append(self, parent, child, rule): + if self.debug: + comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) + parent.append(comment_before) + + parent.append(child) + + if self.debug: + comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_after.text = "Deliverance: done applying rule %s" % etree.tostring(rule) + parent.append(comment_after) + + + def debug_replace(self, old_el, new_el, rule): + self.replace_element(old_el, new_el) + + if self.debug: + parent = new_el.getparent() + index = parent.index(new_el) + + comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) + comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_after.text = "Deliverance: done applying rule %s" % etree.tostring(rule) + comment_after.tail = new_el.tail + new_el.tail = None + + parent.insert(index, comment_before) + parent.insert(index+2, comment_after) + + def debug_prepend(self, parent, child, rule): + parent.insert(0,child) + child.tail = parent.text + parent.text = None + + if self.debug: + comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) + comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_after.text = "Deliverance: done applying rule %s" % etree.tostring(rule) + comment_after.tail = child.tail + child.tail = None + + parent.insert(0, comment_before) + parent.insert(2, comment_after) From ltucker at codespeak.net Wed Oct 11 23:47:19 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 11 Oct 2006 23:47:19 +0200 (CEST) Subject: [z3-checkins] r33198 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061011214719.708AA101B8@code0.codespeak.net> Author: ltucker Date: Wed Oct 11 23:47:17 2006 New Revision: 33198 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py Log: testing Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Wed Oct 11 23:47:17 2006 @@ -269,8 +269,3 @@ index + 1 < len(els) and type(els[index+1]) is type(str())): el.tail = els[index+1] - - - - - From ltucker at codespeak.net Thu Oct 12 18:23:22 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 12 Oct 2006 18:23:22 +0200 (CEST) Subject: [z3-checkins] r33234 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061012162322.DF75210060@code0.codespeak.net> Author: ltucker Date: Thu Oct 12 18:23:18 2006 New Revision: 33234 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml z3/deliverance/branches/packaged/deliverance/test-data/test_debug.xml z3/deliverance/branches/packaged/deliverance/test_wsgi.py z3/deliverance/branches/packaged/deliverance/utils.py z3/deliverance/branches/packaged/deliverance/xslt.py Log: preliminary debugging support for python version, fixes to xslt debugging Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Thu Oct 12 18:23:18 2006 @@ -67,12 +67,16 @@ content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) - if (len(content_els) == 0): + if len(content_els) == 0: self.add_to_body_start(theme, self.format_error("no content matched", rule)) return + if self.debug: + self.debug_append(theme_el, content_els, rule) + return + non_text_els = self.elements_in(content_els) - self.strip_tails(non_text_els) + self.strip_tails(non_text_els) # the xpath may return a mixture of strings and elements, handle strings # by attaching them to the proper element @@ -95,6 +99,20 @@ self.attach_tails(content_els) theme_el.extend(non_text_els) + def debug_append(self, theme_el, content_els, rule): + + comment_before,comment_after = self.make_debugging_comments(rule) + content_els[:0] = [comment_before] + content_els.append(comment_after) + + non_text_els = self.elements_in(content_els) + self.strip_tails(non_text_els) + + self.attach_tails(content_els) + theme_el.extend(non_text_els) + + + def apply_prepend(self,rule,theme,content): theme_el = self.get_theme_el(rule,theme) if theme_el is None: @@ -102,10 +120,14 @@ content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) - if (len(content_els) == 0): + if len(content_els) == 0: self.add_to_body_start(theme, self.format_error("no content matched", rule)) return + if self.debug: + self.debug_prepend(theme_el, content_els, rule) + return + non_text_els = self.elements_in(content_els) # if we only get some text, just tack it on and return @@ -131,8 +153,7 @@ theme_el.text = None self.attach_tails(content_els) - for index,el in enumerate(non_text_els): - theme_el.insert(index,el) + theme_el[:0] = non_text_els # tack on the previous text of the parent element if old_start_text: @@ -141,6 +162,22 @@ else: non_text_els[-1].tail = old_start_text + def debug_prepend(self, theme_el, content_els, rule): + + comment_before,comment_after = self.make_debugging_comments(rule) + content_els[:0] = [comment_before] + content_els.append(comment_after) + + if theme_el.text: + content_els.append(theme_el.text) + theme_el.text = None + + non_text_els = self.elements_in(content_els) + self.strip_tails(non_text_els) + self.attach_tails(content_els) + + theme_el[:0] = non_text_els + def apply_replace(self,rule,theme,content): theme_el = self.get_theme_el(rule,theme) if theme_el is None: @@ -152,6 +189,10 @@ self.add_to_body_start(theme, self.format_error("no content matched", rule)) return + if self.debug: + self.debug_replace(theme_el,content_els,rule) + return + non_text_els = self.elements_in(content_els) self.strip_tails(non_text_els) @@ -178,8 +219,7 @@ non_text_els[0].tail = None parent = non_text_els[0].getparent() i = parent.index(non_text_els[0]) - for index,cel in enumerate(non_text_els[1:]): - parent.insert(i + index + 1,cel) + parent[i+1:i+1] = non_text_els[1:] if non_text_els[-1].tail: non_text_els[-1].tail += temptail @@ -192,6 +232,24 @@ non_text_els[0].tail = preserve_tail + non_text_els[0].tail else: non_text_els[0].tail = preserve_tail + + def debug_replace(self,theme_el,content_els,rule): + comment_before,comment_after = self.make_debugging_comments(rule) + content_els[:0] = [comment_before] + content_els.append(comment_after) + + non_text_els = self.elements_in(content_els) + self.strip_tails(non_text_els) + self.attach_tails(content_els) + + parent = theme_el.getparent() + + if theme_el.tail: + comment_after.tail = theme_el.tail + + parent.replace(theme_el, non_text_els[0]) + i = parent.index(non_text_els[0]) + parent[i+1:i+1] = non_text_els[1:] def apply_copy(self,rule,theme,content): @@ -216,8 +274,18 @@ theme_el.text = None self.attach_tails(content_els) - theme_el[:] = non_text_els - + theme_el[:] = non_text_els + + if self.debug: + comment_before,comment_after = self.make_debugging_comments(rule) + parent = theme_el.getparent() + index = parent.index(theme_el) + parent.insert(index-1,comment_before) + parent.insert(index+2,comment_after) + comment_after.tail = theme_el.tail + theme_el.tail = None + + def apply_append_or_replace(self,rule,theme,content): theme_el = self.get_theme_el(rule,theme) if theme_el is None: @@ -238,12 +306,19 @@ for el in theme_el: if el.tag == remove_tag: + self.attach_text_to_previous(el,el.tail) theme_el.remove(el) + + if self.debug: + self.debug_append(theme_el, content_els, rule) + return + self.strip_tails(content_els) theme_el.extend(content_els) + def elements_in(self, els): """ return a list containing elements from els which are not strings @@ -269,3 +344,9 @@ index + 1 < len(els) and type(els[index+1]) is type(str())): el.tail = els[index+1] + + + def make_debugging_comments(self, rule): + comment_before = etree.Comment("Deliverance: applying rule %s" % etree.tostring(rule)) + comment_after = etree.Comment("Deliverance: done applying rule %s" % etree.tostring(rule)) + return comment_before, comment_after Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml Thu Oct 12 18:23:18 2006 @@ -44,6 +44,34 @@ + + + + + + + + + + before the div
in the div
after the div + +
+ + + +
Real Content
+ +
+ + + + + before the divafter the div +
Real Content
+ + +
+
Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_debug.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_debug.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_debug.xml Thu Oct 12 18:23:18 2006 @@ -135,26 +135,29 @@ - + + before spaninside spanafter span -
Real Content
+
Real Content
-
Real Content
+ before span +
Real Content
after span +
Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Thu Oct 12 18:23:18 2006 @@ -59,7 +59,7 @@ res2 = app.get('/xinclude_expected.html?notheme') html_string_compare(res.body, res2.body) - +4 def test_nycsr(): wsgi_app = DeliveranceMiddleware(nycsr_app, 'http://www.nycsr.org','nycsr.xml') app = TestApp(wsgi_app) Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Thu Oct 12 18:23:18 2006 @@ -92,7 +92,7 @@ body[:0] = [el] def replace_element(self,replace, new_el): - parent = replace.getparent() + parent = replace.getparent() for i in range(len(parent)): if parent[i] == replace: new_el.tail = replace.tail @@ -177,3 +177,5 @@ el.getparent().text += text else: el.getparent().text = text + + Modified: z3/deliverance/branches/packaged/deliverance/xslt.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/xslt.py (original) +++ z3/deliverance/branches/packaged/deliverance/xslt.py Thu Oct 12 18:23:18 2006 @@ -167,6 +167,8 @@ normal_theme_el, copy_theme_el) self.debug_replace(theme_el,choose,rule) + copy_theme_el.tail = None + normal_theme_el.tail = None @@ -230,18 +232,14 @@ return choose - def debug_append(self, parent, child, rule): + def debug_append(self, parent, child, rule): if self.debug: - comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) - comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) + comment_before,comment_after = self.make_debugging_comments(rule) parent.append(comment_before) - - parent.append(child) - - if self.debug: - comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) - comment_after.text = "Deliverance: done applying rule %s" % etree.tostring(rule) + parent.append(child) parent.append(comment_after) + else: + parent.append(child) def debug_replace(self, old_el, new_el, rule): @@ -250,11 +248,8 @@ if self.debug: parent = new_el.getparent() index = parent.index(new_el) - - comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) - comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) - comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) - comment_after.text = "Deliverance: done applying rule %s" % etree.tostring(rule) + + comment_before,comment_after = self.make_debugging_comments(rule) comment_after.tail = new_el.tail new_el.tail = None @@ -267,12 +262,17 @@ parent.text = None if self.debug: - comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) - comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) - comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) - comment_after.text = "Deliverance: done applying rule %s" % etree.tostring(rule) + comment_before,comment_after = self.make_debugging_comments(rule) comment_after.tail = child.tail child.tail = None parent.insert(0, comment_before) parent.insert(2, comment_after) + + + def make_debugging_comments(self, rule): + comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) + comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) + comment_after.text = "Deliverance: done applying rule %s" % etree.tostring(rule) + return comment_before, comment_after From ltucker at codespeak.net Thu Oct 12 20:22:03 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 12 Oct 2006 20:22:03 +0200 (CEST) Subject: [z3-checkins] r33237 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061012182203.CFAA610083@code0.codespeak.net> Author: ltucker Date: Thu Oct 12 20:22:00 2006 New Revision: 33237 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/tests.py z3/deliverance/branches/packaged/deliverance/utils.py z3/deliverance/branches/packaged/deliverance/wsgifilter.py z3/deliverance/branches/packaged/deliverance/xslt.py Log: comments, cleanup Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Thu Oct 12 20:22:00 2006 @@ -14,7 +14,6 @@ def __init__(self, theme, theme_uri, rules, reference_resolver=None): self.theme = self.fixup_links(theme, theme_uri) - self.remove_http_equiv_metas(self.theme) self.rules = rules # perform xincludes on the rules if reference_resolver: @@ -30,7 +29,6 @@ def render(self, content): result = copy.deepcopy(self.theme) input = copy.deepcopy(content) - self.remove_http_equiv_metas(input) self.apply_rules(self.rules,result,input) return result Modified: z3/deliverance/branches/packaged/deliverance/tests.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/tests.py (original) +++ z3/deliverance/branches/packaged/deliverance/tests.py Thu Oct 12 20:22:00 2006 @@ -2,8 +2,8 @@ import os from lxml import etree from formencode.doctest_xml_compare import xml_compare -#from deliverance.interpreter import Renderer -from deliverance.xslt import Renderer +from deliverance.interpreter import Renderer +#from deliverance.xslt import Renderer import copy class DeliveranceTestCase: Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Thu Oct 12 20:22:00 2006 @@ -48,8 +48,8 @@ def format_error(self, message, rule, elts=None): """ Returns a node containing the error message; - Checks the onerror attribute of the rule element to see if errors should - be ignored in which case returns None + If the onerror attribute of the rule element is set to ignore, + returns None """ if rule.attrib.get('onerror', None) == 'ignore': @@ -76,6 +76,9 @@ TAG_MATCHER = re.compile(r'^\.?/?/?(.*?/)*(?P[^*^(^)^:^[^.^/]+?)(\[.*\])*$',re.I) def get_tag_from_xpath(self,xpath): + """ + attemtps to extract the tag type that an xpath expression selects (if any) + """ match = self.TAG_MATCHER.match(xpath) if match: return match.group('tag') @@ -83,33 +86,38 @@ return None - def add_to_body_start(self,theme, el): + def add_to_body_start(self,doc,el): + """ + inserts the element el into the beginning of body + element of the document given + """ if not el: return - body = theme.find('body') + body = doc.find('body') if body is None: - body = theme[0] + body = doc[0] body[:0] = [el] - def replace_element(self,replace, new_el): - parent = replace.getparent() - for i in range(len(parent)): - if parent[i] == replace: - new_el.tail = replace.tail - parent[i] = new_el - break - - def mark_bad_elements(self,els): - for el in els: - if 'class' in el.attrib: - el.attrib['class'] += ' deliverance-bad-element' - else: - el.attrib['class'] = 'deliverance-bad-element' + def replace_element(self,old_el, new_el): + """ + replaces old_el with new_el in the parent + element of old_el. The tail of + new_el is replaced by the tail of old_el + """ + new_el.tail = old_el.tail + parent = old_el.getparent() + parent[parent.index(old_el)] = new_el + def fixup_links(self, doc, uri): - """ resolve all links in the ``doc`` element to be absolute; the links - should be considered relative to ``uri`` + """ + replaces relative urls found in the document given + with absolute urls by prepending the uri given. + tags are removed from the document. + + Affects urls in href attributes, src attributes and + css of the form url(...) in style elements """ base_uri = uri basetags = doc.xpath('//base[@href]') @@ -132,14 +140,18 @@ def fixup_link_attrs(self, elts, base_uri, attr): - """ makes all attr values in elts to be absolute uris based on base_uri """ + """ + prepends base_uri onto the attribute given by attr for + all elements given in elts + """ for el in elts: el.attrib[attr] = urlparse.urljoin(base_uri, el.attrib[attr]) CSS_URL_PAT = re.compile(r'url\((.*?)\)',re.I) def fixup_css_links(self, elts, base_uri): - """ fixes @import uris in css style elements to be + """ + prepends url(...) in css style elements to be absolute links based on base_uri """ @@ -150,18 +162,12 @@ if el.text: el.text = re.sub(self.CSS_URL_PAT,absuri,el.text) - def remove_http_equiv_metas(self,doc): - if not doc: - return - - metas = doc.xpath("//meta[translate(@http-equiv,'contenyp','CONTENYP') = 'CONTENT-TYPE']") - for elt in metas: - if elt.tail: - attach_text_to_previous(self,elt,elt.tail) - elt.getparent().remove(elt) - def attach_text_to_previous(self,el,text): + """ + attaches the text given to the nearest previous node to el, + ie its preceding sibling or parent + """ if text is None: return Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Thu Oct 12 20:22:00 2006 @@ -13,8 +13,8 @@ from paste.wsgilib import intercept_output from paste.request import construct_url from paste.response import header_value, replace_header -#from interpreter import Renderer -from xslt import Renderer +from interpreter import Renderer +#from xslt import Renderer from htmlserialize import tostring import sys import datetime Modified: z3/deliverance/branches/packaged/deliverance/xslt.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/xslt.py (original) +++ z3/deliverance/branches/packaged/deliverance/xslt.py Thu Oct 12 20:22:00 2006 @@ -32,7 +32,6 @@ theme_copy = copy.deepcopy(theme) self.fixup_links(theme_copy,theme_uri) - self.remove_http_equiv_metas(theme_copy) self.xsl_escape_comments(theme_copy) if reference_resolver: @@ -201,7 +200,9 @@ def xsl_escape_comments(self,doc): """ - replaces comment nodes with xsl:comment nodes + replaces comment nodes with xsl:comment nodes so they will + appear in the result of a transform rather than being + treated as comments in the transform """ comment_nodes = doc.xpath('//comment()') for c in comment_nodes: @@ -211,6 +212,9 @@ def add_conditional_missing_content_error(self,theme,rule): """ + adds a node to the body of theme which produces an error + message if no content is matched by a rule given + during the transformation """ err = self.format_error("no content matched", rule) if err: @@ -221,6 +225,11 @@ def make_when_otherwise(self, test, whenbody, otherwisebody): + """ + makes a conditional xlst node. when placed into a document, + if the xslt expression represented by the string test evaluates + to true, whenbody is produced, if false, otherwise body is produced + """ choose = etree.Element("{%s}choose" % nsmap["xsl"]) when = etree.Element("{%s}when" % nsmap["xsl"]) when.set("test", test) @@ -233,6 +242,11 @@ def debug_append(self, parent, child, rule): + """ + helper method for appending a node, if debugging is enabled, + the appended node is wrapped in comments referring to the + rule that performed the append + """ if self.debug: comment_before,comment_after = self.make_debugging_comments(rule) parent.append(comment_before) @@ -243,6 +257,11 @@ def debug_replace(self, old_el, new_el, rule): + """ + helper method for replacing a node, if debugging is enabled, + the new node is wrapped in comments referring to the + rule that performed the replace + """ self.replace_element(old_el, new_el) if self.debug: @@ -257,6 +276,11 @@ parent.insert(index+2, comment_after) def debug_prepend(self, parent, child, rule): + """ + helper method for prepending a node, if debugging is enabled, + the prepended node is wrapped in comments referring to the + rule that performed the append + """ parent.insert(0,child) child.tail = parent.text parent.text = None @@ -271,6 +295,10 @@ def make_debugging_comments(self, rule): + """ + helper method which prepares two xslt:comment nodes used + for wrapping inserted content nodes during debugging + """ comment_before = etree.Element("{%s}comment" % nsmap["xsl"]) comment_before.text = "Deliverance: applying rule %s" % etree.tostring(rule) comment_after = etree.Element("{%s}comment" % nsmap["xsl"]) From ltucker at codespeak.net Thu Oct 12 20:47:51 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 12 Oct 2006 20:47:51 +0200 (CEST) Subject: [z3-checkins] r33238 - in z3/deliverance/branches/packaged: . content themes Message-ID: <20061012184751.8C82210092@code0.codespeak.net> Author: ltucker Date: Thu Oct 12 20:47:45 2006 New Revision: 33238 Removed: z3/deliverance/branches/packaged/content/ z3/deliverance/branches/packaged/themes/ Modified: z3/deliverance/branches/packaged/README.txt Log: adding instructions for running tests, removing old test data Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Thu Oct 12 20:47:45 2006 @@ -1,77 +1,45 @@ -======================================= -Deliverance, high-speed themes for Zope -======================================= -Quick Start ------------ - -1) Install lxml. - -2) cd to the directory containing this README. - -3) python ./deliverance.py - -This runs the timeit function, showing average time to apply a simple theme. - - -Quick mod_python Start ----------------------- - -1) Edit mpfilter.conf and point it to where you put the SVN checkout. - -2) In your Apache httpd.conf file, add a line like this:: - - Include /Users/me/sandboxes/namespaced/mpfilter.conf - -3) Shut Apache down and restart. - -4) Keep an eye on the Apache error log:: - - tail -f logs/error_log - -5) Open a URL like this (or however you have your HTML files pointed to on -whichever port):: - - http://localhost:9000/sandboxes/namespaced/ +Quick Start to run tests +------------------------- -6) If that works, click on the on the "content" directory or go to this URL:: +get workingenv.py from +http://cheeseshop.python.org/pypi/workingenv.py - http://localhost:9000/sandboxes/namespaced/content/intro.html +Create a working enviornment for deliverance and its dependencies: -7) In the site menu on that page, try clicking on the 3 links. +workingenv.py deliverance_env +source deliverance_env/bin/activate +Install lxml using the buildout +(full instructions at http://faassen.n--tree.net/blog/view/weblog/2006/10/03/0, + alternatively, install a recent cvs version of libxml2,libxstl and svn lxml. + You are likely to encounter segfaults if recent versions are not used.) -Customization Quick Start -------------------------- +$ svn co https://infrae.com/svn/buildout/lxml-recent/trunk lxml-recent +$ cd lxml-recent +$ python bootstrap/bootstrap.py +$ bin/buildout -1) Edit ``themes/simple/sampletheme.xml`` and add the following snippet -**inside** the ``
``:: +put the lxml egg into your deliverance environment -
Theme section for author
+$ cp -r lxml-recent/develop-eggs/lxml-.egg deliverance_env/lib/python_2.4/ -2) Edit ``content/index.html`` and add the following in the ````: +add a line to deliverance_env/lib/easy-install.pth like: +./lxml-.egg - +$ easy_install nose +$ easy_install FormEncode +$ easy_install elementtree +$ easy_install paste -3) Edit ``etc/themerules.xml`` and add a rule like the following:: +checkout deliverance: +$ svn co http://codespeak.net/svn/z3/deliverance/branches/packaged deliverance - - -4) Restart Apache and reload the page. +$ cd deliverance +$ nosetests -How Does This Work? -------------------- -There are proposals on zope.org and other places that explain the idea. Here's -the short version: -1) A configuration "map" points at a pile of HTML artifacts that look the -way you'd like your site to look. Let's call this look-and-feel the "theme". -2) A rule file defines boxes in that theme that should get filled by boxes -coming from the dynamic side. -3) At startup, a one-time compilation processes turns the theme into a -high-speed XSLT transform. From ltucker at codespeak.net Thu Oct 12 21:15:49 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 12 Oct 2006 21:15:49 +0200 (CEST) Subject: [z3-checkins] r33239 - z3/deliverance/branches/packaged Message-ID: <20061012191549.2C1A310087@code0.codespeak.net> Author: ltucker Date: Thu Oct 12 21:15:47 2006 New Revision: 33239 Modified: z3/deliverance/branches/packaged/README.txt Log: notes on tests Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Thu Oct 12 21:15:47 2006 @@ -39,7 +39,63 @@ $ nosetests +Simple Tests +------------ +There are a number of tests in the test-data directory that follow the form: + + + + + + ... rules as described at http://www.openplans.org/projects/deliverance/specification + + + + ... theme html + + + + ... content html + + + + ... expected output of applying rules to theme and content + + + +... + + + + +WSGI Tests +---------- + +test_wsgi.py contains tests which take the theme and content from the +web and local pages found under test-data. + + +Hand Transform +-------------- + +a hand test may also be performed using the handtransform.py script +run python handtransform.py --help for instructions. The result of the +transform is output to standard out. + +To avoid lengthy command lines, the script can accept a file which describes +the theme and rules to apply using the -f flag eg: + +python handtransform.py -f test-data/nycsr/nycsr.theme ./test-data/nycsr/openplans.html + +where nycsr.theme contains something like: + + + +and the second argument points to the content From ltucker at codespeak.net Thu Oct 12 23:46:59 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 12 Oct 2006 23:46:59 +0200 (CEST) Subject: [z3-checkins] r33241 - z3/deliverance/branches/packaged Message-ID: <20061012214659.C42FC10092@code0.codespeak.net> Author: ltucker Date: Thu Oct 12 23:46:57 2006 New Revision: 33241 Modified: z3/deliverance/branches/packaged/README.txt Log: changed instructions, lxml buildout won't actually do right now Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Thu Oct 12 23:46:57 2006 @@ -1,6 +1,7 @@ Quick Start to run tests ------------------------- +running setup.py is probably going to do the wrong thing currently get workingenv.py from http://cheeseshop.python.org/pypi/workingenv.py @@ -10,22 +11,8 @@ workingenv.py deliverance_env source deliverance_env/bin/activate -Install lxml using the buildout -(full instructions at http://faassen.n--tree.net/blog/view/weblog/2006/10/03/0, - alternatively, install a recent cvs version of libxml2,libxstl and svn lxml. - You are likely to encounter segfaults if recent versions are not used.) - -$ svn co https://infrae.com/svn/buildout/lxml-recent/trunk lxml-recent -$ cd lxml-recent -$ python bootstrap/bootstrap.py -$ bin/buildout - -put the lxml egg into your deliverance environment - -$ cp -r lxml-recent/develop-eggs/lxml-.egg deliverance_env/lib/python_2.4/ - -add a line to deliverance_env/lib/easy-install.pth like: -./lxml-.egg +install a recent cvs version of libxml2,libxstl and svn lxml. +You are likely to encounter segfaults and other failures if recent versions are not used. $ easy_install nose $ easy_install FormEncode From ianb at codespeak.net Sat Oct 14 03:19:03 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Sat, 14 Oct 2006 03:19:03 +0200 (CEST) Subject: [z3-checkins] r33281 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061014011903.BEFD1100F3@code0.codespeak.net> Author: ianb Date: Sat Oct 14 03:18:50 2006 New Revision: 33281 Modified: z3/deliverance/branches/packaged/deliverance/utils.py Log: Added new key, NOCONTENT_KEY; warn if the version of libxml2 isn't new enough to parse ') +if html[0][0].text != 'some text': + import warnings + warnings.warn( + 'Deliverance requires the CVS HEAD version of libxml2') + class RuleSyntaxError(Exception): """ Raised when an invalid or unknown rule is encountered by a renderer @@ -32,6 +39,8 @@ RULE_CONTENT_KEY = "content" RULE_THEME_KEY = "theme" + NOCONTENT_KEY = "nocontent" + def get_theme_el(self,rule,theme): theme_els = theme.xpath(rule.attrib[self.RULE_THEME_KEY]) if len(theme_els)== 0: @@ -118,8 +127,8 @@ Affects urls in href attributes, src attributes and css of the form url(...) in style elements - """ - base_uri = uri + """ + base_uri = uri basetags = doc.xpath('//base[@href]') if (len(basetags)): base_uri = basetags[0].attrib['href'] From ianb at codespeak.net Sat Oct 14 03:21:49 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Sat, 14 Oct 2006 03:21:49 +0200 (CEST) Subject: [z3-checkins] r33282 - in z3/deliverance/branches/packaged: . Deliverance.egg-info deliverance deliverance/test-data/nycsr doc Message-ID: <20061014012149.1DB88100F3@code0.codespeak.net> Author: ianb Date: Sat Oct 14 03:21:39 2006 New Revision: 33282 Added: z3/deliverance/branches/packaged/Deliverance.egg-info/ (props changed) Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.xml z3/deliverance/branches/packaged/deliverance/test-data/nycsr/standardrules.xml z3/deliverance/branches/packaged/deliverance/wsgifilter.py z3/deliverance/branches/packaged/deliverance/xinclude.py z3/deliverance/branches/packaged/doc/NewWorld.txt z3/deliverance/branches/packaged/setup.py Log: Added a new attribute, nocontent='ignore' to rules to suppress error when there's no matching element in the content. Often this is not an error, such as when there's no + + +Todo list + + + + +
+ + +
+
+
+
+Logged in as: admin +Project: theproject +
+This is list deliverance.
+ Reorder +

+ + + +Task name +Status ? +Deadline ? +Assigned to? +Created by + + + +
    +
  • + + + + + + + + +nycsr + + + + + + + + + + + + + + + + +14 October, 2006 + + + +unassigned + + +admin + + + +
      +
    • + + + + + + + + +debug + + + + + + + + + + + + + + + + + + + + +admin + + +admin + + + +
        +
      • + + + + + + + +
      • + + + + + + + + +load test data + + + + + + + + + + + + + + + + + + + + +unassigned + + +admin + + + +
          +
        • + + + +
        +
      • + + + +
      + + + + + + +
      + +

      +Add a new task. +

      + + + + +
      + + + + + +
      +
      Edit list settings +| + + +Back to list of lists + + +
      +
      +
      +
      + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/tasktracker/tasktracker.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/tasktracker/tasktracker.xml Tue Oct 17 18:35:40 2006 @@ -0,0 +1,10 @@ + + + + + + + + + + Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Tue Oct 17 18:35:40 2006 @@ -8,9 +8,11 @@ from htmlserialize import tostring static_data = os.path.join(os.path.dirname(__file__), 'test-data', 'static') +tasktracker_data = os.path.join(os.path.dirname(__file__), 'test-data', 'tasktracker') nycsr_data = os.path.join(os.path.dirname(__file__), 'test-data', 'nycsr') static_app = StaticURLParser(static_data) +tasktracker_app = StaticURLParser(tasktracker_data) nycsr_app = StaticURLParser(nycsr_data) def html_string_compare(astr, bstr): @@ -51,6 +53,13 @@ res2 = app.get('/texttest_expected.html?notheme') html_string_compare(res.body, res2.body) +def test_tasktracker(): + wsgi_app = DeliveranceMiddleware(tasktracker_app, 'http://www.nycsr.org/nyc/video.php', 'tasktracker.xml') + app = TestApp(wsgi_app) + res = app.get('/content.html') + res2 = app.get('/expected.html?notheme') + html_string_compare(res.body, res2.body) + def test_xinclude(): wsgi_app = DeliveranceMiddleware(static_app, 'xinclude_theme.html', 'xinclude_rules.xml') @@ -59,7 +68,7 @@ res2 = app.get('/xinclude_expected.html?notheme') html_string_compare(res.body, res2.body) -4 + def test_nycsr(): wsgi_app = DeliveranceMiddleware(nycsr_app, 'http://www.nycsr.org','nycsr.xml') app = TestApp(wsgi_app) From cabraham at codespeak.net Tue Oct 17 20:38:52 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Tue, 17 Oct 2006 20:38:52 +0200 (CEST) Subject: [z3-checkins] r33388 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061017183852.54E9D1006F@code0.codespeak.net> Author: cabraham Date: Tue Oct 17 20:38:48 2006 New Revision: 33388 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py Log: Undoing change committed in r33384 because the lxml guys fixed their deepcopy bug so my workaround isn't needed anymore. Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Tue Oct 17 20:38:48 2006 @@ -66,7 +66,7 @@ if theme_el is None: return - content_els = self.deepcopy_elementlist(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: if rule.get(self.NOCONTENT_KEY) != 'ignore': @@ -120,7 +120,7 @@ if theme_el is None: return - content_els = self.deepcopy_elementlist(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': @@ -186,7 +186,7 @@ if theme_el is None: return - content_els = self.deepcopy_elementlist(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': @@ -261,7 +261,7 @@ if theme_el is None: return - content_els = self.deepcopy_elementlist(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': @@ -303,7 +303,7 @@ self.add_to_body_start(theme,self.format_error("invalid xpath for content", rule=rule)) return - content_els = self.deepcopy_elementlist(content.xpath(content_xpath)) + content_els = copy.deepcopy(content.xpath(content_xpath)) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': @@ -356,13 +356,3 @@ comment_before = etree.Comment("Deliverance: applying rule %s" % etree.tostring(rule)) comment_after = etree.Comment("Deliverance: done applying rule %s" % etree.tostring(rule)) return comment_before, comment_after - - def deepcopy_elementlist(self, els): - # converts etree._Comment list elements into strings and then performs copy - # this is necessary to avoid a bug in lxml which turns comments into None when - # perfoming a deepcopy - for index, el in enumerate(els): - if type(el) == etree._Comment: - els[index] = str(el) - - return copy.deepcopy(els) From cabraham at codespeak.net Tue Oct 17 22:49:24 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Tue, 17 Oct 2006 22:49:24 +0200 (CEST) Subject: [z3-checkins] r33393 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061017204924.1429010071@code0.codespeak.net> Author: cabraham Date: Tue Oct 17 22:49:22 2006 New Revision: 33393 Added: z3/deliverance/branches/packaged/deliverance/test-data/test_xinclude.xml z3/deliverance/branches/packaged/deliverance/test-data/xincluderules.xml Modified: z3/deliverance/branches/packaged/deliverance/tests.py Log: added test for rules xinclude that doesn't use wsgi; modified tests.py to accomodate this functionality Added: z3/deliverance/branches/packaged/deliverance/test-data/test_xinclude.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_xinclude.xml Tue Oct 17 22:49:22 2006 @@ -0,0 +1,27 @@ + + + + + + + + + + + Blah
      Dummy Content

      HI!

      + +
      + + +
      Real Content
      12

      zzz

      3 +
      + + + Blah
      +
      Dummy Content

      HI!

      13
      +
      +
      + + + +
      Added: z3/deliverance/branches/packaged/deliverance/test-data/xincluderules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/xincluderules.xml Tue Oct 17 22:49:22 2006 @@ -0,0 +1,6 @@ + + + + + + Modified: z3/deliverance/branches/packaged/deliverance/tests.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/tests.py (original) +++ z3/deliverance/branches/packaged/deliverance/tests.py Tue Oct 17 22:49:22 2006 @@ -5,6 +5,7 @@ from deliverance.interpreter import Renderer #from deliverance.xslt import Renderer import copy +import urllib class DeliveranceTestCase: @@ -17,10 +18,20 @@ self.output = output def __call__(self, name): + def reference_resolver(href, parse, encoding=None): + f = urllib.urlopen(href) + content = f.read() + f.close() + if parse == "xml": + return etree.XML(content) + elif encoding: + return content.decode(encoding) + renderer = Renderer( theme=self.theme, theme_uri=self.theme_uri, - rule=self.rules, rule_uri=self.rules_uri) + rule=self.rules, rule_uri=self.rules_uri, + reference_resolver=reference_resolver) actual = renderer.render(self.content) reporter = [] result = xml_compare(actual, self.output, reporter.append) @@ -80,10 +91,9 @@ outputbody = copy.deepcopy(output[0]) output[:] = [] - case = DeliveranceTestCase( rules=rules, - rules_uri = fn, # not sure about this + rules_uri = fn, theme=themebody, theme_uri=el.find('theme').attrib['base'], content=contentbody, From ltucker at codespeak.net Wed Oct 18 21:38:34 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 21:38:34 +0200 (CEST) Subject: [z3-checkins] r33417 - z3/deliverance/branches/packaged/deliverance/etc Message-ID: <20061018193834.2622610063@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 21:38:32 2006 New Revision: 33417 Removed: z3/deliverance/branches/packaged/deliverance/etc/ Log: removing some old style xml files From ltucker at codespeak.net Wed Oct 18 21:57:43 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 21:57:43 +0200 (CEST) Subject: [z3-checkins] r33419 - in z3/deliverance/branches/packaged/deliverance/test-data: . nabuur nycsr static tasktracker Message-ID: <20061018195743.64FCE10071@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 21:57:39 2006 New Revision: 33419 Added: z3/deliverance/branches/packaged/deliverance/test-data/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/nabuur/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/nycsr/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/static/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/tasktracker/__init__.py Log: roll these into the egg? Added: z3/deliverance/branches/packaged/deliverance/test-data/__init__.py ============================================================================== Added: z3/deliverance/branches/packaged/deliverance/test-data/nabuur/__init__.py ============================================================================== Added: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/__init__.py ============================================================================== Added: z3/deliverance/branches/packaged/deliverance/test-data/static/__init__.py ============================================================================== Added: z3/deliverance/branches/packaged/deliverance/test-data/tasktracker/__init__.py ============================================================================== From ltucker at codespeak.net Wed Oct 18 22:03:44 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 22:03:44 +0200 (CEST) Subject: [z3-checkins] r33420 - in z3/deliverance/branches/packaged/deliverance/test-data: . nabuur nycsr static tasktracker Message-ID: <20061018200344.70DB610074@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 22:03:40 2006 New Revision: 33420 Removed: z3/deliverance/branches/packaged/deliverance/test-data/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/nabuur/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/nycsr/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/static/__init__.py z3/deliverance/branches/packaged/deliverance/test-data/tasktracker/__init__.py Log: nope Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/__init__.py ============================================================================== Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/nabuur/__init__.py ============================================================================== Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/nycsr/__init__.py ============================================================================== Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/static/__init__.py ============================================================================== Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/tasktracker/__init__.py ============================================================================== From ltucker at codespeak.net Wed Oct 18 22:08:09 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 22:08:09 +0200 (CEST) Subject: [z3-checkins] r33421 - z3/deliverance/branches/packaged Message-ID: <20061018200809.C917610076@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 22:08:07 2006 New Revision: 33421 Modified: z3/deliverance/branches/packaged/setup.py Log: include tests in egg Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Wed Oct 18 22:08:07 2006 @@ -19,7 +19,9 @@ zip_safe=False, install_requires=[ 'lxml', + 'paste' ], + include_package_data=True, entry_points=""" [paste.filter_app_factory] main = deliverance.wsgifilter:make_filter From ltucker at codespeak.net Wed Oct 18 22:25:15 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 22:25:15 +0200 (CEST) Subject: [z3-checkins] r33424 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061018202515.E590210078@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 22:25:14 2006 New Revision: 33424 Modified: z3/deliverance/branches/packaged/deliverance/test_speed.py Log: fix test_speed to match new Renderer signature Modified: z3/deliverance/branches/packaged/deliverance/test_speed.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_speed.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_speed.py Wed Oct 18 22:25:14 2006 @@ -38,15 +38,16 @@ elif encoding: return text.decode(encoding) - renderer = None if renderer_type == 'xslt': - renderer = XSLTRenderer(theme,base_url,rules,reference_resolver) + renderer_class = XSLTRenderer elif renderer_type == 'py': - renderer = PythonRenderer(theme,base_url,rules,reference_resolver) + renderer_class = PythonRenderer else: print "Unknown renderer type '" + renderer_type + "'" return etree.Element("error") + renderer = renderer_class(theme,base_url,rules,'.',reference_resolver) + start = time() iters = 3000 for i in range(iters): From ltucker at codespeak.net Wed Oct 18 22:30:46 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 22:30:46 +0200 (CEST) Subject: [z3-checkins] r33427 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061018203046.8B43910074@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 22:30:45 2006 New Revision: 33427 Modified: z3/deliverance/branches/packaged/deliverance/tests.py Log: change import to local import Modified: z3/deliverance/branches/packaged/deliverance/tests.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/tests.py (original) +++ z3/deliverance/branches/packaged/deliverance/tests.py Wed Oct 18 22:30:45 2006 @@ -2,8 +2,8 @@ import os from lxml import etree from formencode.doctest_xml_compare import xml_compare -from deliverance.interpreter import Renderer -#from deliverance.xslt import Renderer +from interpreter import Renderer +#from xslt import Renderer import copy import urllib From ltucker at codespeak.net Wed Oct 18 22:49:41 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 22:49:41 +0200 (CEST) Subject: [z3-checkins] r33428 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061018204941.2000D10078@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 22:49:39 2006 New Revision: 33428 Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: fix internal routing decisions Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Wed Oct 18 22:49:39 2006 @@ -112,7 +112,7 @@ internalBaseURL = environ.get(DELIVERANCE_BASE_URL,None) uri = urlparse.urljoin(internalBaseURL, uri) - if internalBaseURL and uri.startswith(internalBaseURL): + if relative_url(uri) or (internalBaseURL and uri.startswith(internalBaseURL)): return self.get_internal_resource(environ, uri[len(internalBaseURL):]) else: return self.get_external_resource(uri) From ltucker at codespeak.net Wed Oct 18 22:59:33 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 18 Oct 2006 22:59:33 +0200 (CEST) Subject: [z3-checkins] r33430 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061018205933.C136B1007C@code0.codespeak.net> Author: ltucker Date: Wed Oct 18 22:59:31 2006 New Revision: 33430 Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: whoops Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Wed Oct 18 22:59:31 2006 @@ -112,7 +112,7 @@ internalBaseURL = environ.get(DELIVERANCE_BASE_URL,None) uri = urlparse.urljoin(internalBaseURL, uri) - if relative_url(uri) or (internalBaseURL and uri.startswith(internalBaseURL)): + if self.relative_uri(uri) or (internalBaseURL and uri.startswith(internalBaseURL)): return self.get_internal_resource(environ, uri[len(internalBaseURL):]) else: return self.get_external_resource(uri) From ltucker at codespeak.net Thu Oct 19 00:47:52 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 19 Oct 2006 00:47:52 +0200 (CEST) Subject: [z3-checkins] r33435 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061018224752.8C19F10078@code0.codespeak.net> Author: ltucker Date: Thu Oct 19 00:47:50 2006 New Revision: 33435 Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: remove query string from base url to avoid redirecting externally by accident Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Thu Oct 19 00:47:50 2006 @@ -77,7 +77,7 @@ def __call__(self, environ, start_response): qs = environ.get('QUERY_STRING', '') - environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False) + environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False) notheme = 'notheme' in qs if notheme: return self.app(environ, start_response) @@ -112,7 +112,7 @@ internalBaseURL = environ.get(DELIVERANCE_BASE_URL,None) uri = urlparse.urljoin(internalBaseURL, uri) - if self.relative_uri(uri) or (internalBaseURL and uri.startswith(internalBaseURL)): + if internalBaseURL and uri.startswith(internalBaseURL): return self.get_internal_resource(environ, uri[len(internalBaseURL):]) else: return self.get_external_resource(uri) From ianb at codespeak.net Thu Oct 19 03:03:56 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 19 Oct 2006 03:03:56 +0200 (CEST) Subject: [z3-checkins] r33436 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061019010356.55D2810053@code0.codespeak.net> Author: ianb Date: Thu Oct 19 03:03:53 2006 New Revision: 33436 Modified: z3/deliverance/branches/packaged/deliverance/htmlserialize.py Log: Make sure HTML() returns something, or else fail early. (With really bad content it can just return None, which causes problems later) Modified: z3/deliverance/branches/packaged/deliverance/htmlserialize.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/htmlserialize.py (original) +++ z3/deliverance/branches/packaged/deliverance/htmlserialize.py Thu Oct 19 03:03:53 2006 @@ -54,7 +54,9 @@ charset = m.group('charset') text = text.decode(charset) - return etree.HTML(text) + content = etree.HTML(text) + assert content is not None + return content From ianb at codespeak.net Thu Oct 19 03:09:02 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 19 Oct 2006 03:09:02 +0200 (CEST) Subject: [z3-checkins] r33437 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061019010902.05B8E10053@code0.codespeak.net> Author: ianb Date: Thu Oct 19 03:09:00 2006 New Revision: 33437 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py Log: Purely whitespace/aesthetic changes Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Thu Oct 19 03:09:00 2006 @@ -32,28 +32,28 @@ def render(self, content): result = copy.deepcopy(self.theme) input = copy.deepcopy(content) - self.apply_rules(self.rules,result,input) + self.apply_rules(self.rules, result, input) return result - def apply_rules(self,rules,theme,content): + def apply_rules(self, rules, theme, content): for rule in rules: - self.apply_rule(rule,theme,content) + self.apply_rule(rule, theme, content) - def apply_rule(self,rule,theme,content): + def apply_rule(self, rule, theme, content): if rule.tag == self.APPEND_RULE_TAG: - self.apply_append(rule,theme,content) + self.apply_append(rule, theme, content) elif rule.tag == self.PREPEND_RULE_TAG: - self.apply_prepend(rule,theme,content) + self.apply_prepend(rule, theme, content) elif rule.tag == self.REPLACE_RULE_TAG: - self.apply_replace(rule,theme,content) + self.apply_replace(rule, theme, content) elif rule.tag == self.COPY_RULE_TAG: - self.apply_copy(rule,theme,content) + self.apply_copy(rule, theme, content) elif rule.tag == self.APPEND_OR_REPLACE_RULE_TAG: - self.apply_append_or_replace(rule,theme,content) + self.apply_append_or_replace(rule, theme, content) elif rule.tag == self.SUBRULES_TAG: - self.apply_rules(rule,theme,content) + self.apply_rules(rule, theme, content) elif rule.tag is etree.Comment: pass else: @@ -62,15 +62,17 @@ rule.tag, etree.tostring(rule))) def apply_append(self,rule,theme,content): - theme_el = self.get_theme_el(rule,theme) + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return - content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = copy.deepcopy( + content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: if rule.get(self.NOCONTENT_KEY) != 'ignore': - self.add_to_body_start(theme, self.format_error("no content matched", rule)) + self.add_to_body_start( + theme, self.format_error("no content matched", rule)) return if self.debug: @@ -115,16 +117,18 @@ - def apply_prepend(self,rule,theme,content): - theme_el = self.get_theme_el(rule,theme) + def apply_prepend(self, rule, theme, content): + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return - content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + xpath = rule.attrib[self.RULE_CONTENT_KEY] + content_els = copy.deepcopy(content.xpath(xpath)) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': - self.add_to_body_start(theme, self.format_error("no content matched", rule)) + self.add_to_body_start( + theme, self.format_error("no content matched", rule)) return if self.debug: @@ -167,7 +171,7 @@ def debug_prepend(self, theme_el, content_els, rule): - comment_before,comment_after = self.make_debugging_comments(rule) + comment_before, comment_after = self.make_debugging_comments(rule) content_els[:0] = [comment_before] content_els.append(comment_after) @@ -181,20 +185,22 @@ theme_el[:0] = non_text_els - def apply_replace(self,rule,theme,content): - theme_el = self.get_theme_el(rule,theme) + def apply_replace(self, rule, theme, content): + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return - content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = copy.deepcopy( + content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': - self.add_to_body_start(theme, self.format_error("no content matched", rule)) + self.add_to_body_start( + theme, self.format_error("no content matched", rule)) return if self.debug: - self.debug_replace(theme_el,content_els,rule) + self.debug_replace(theme_el, content_els, rule) return non_text_els = self.elements_in(content_els) @@ -206,13 +212,13 @@ if (type(content_els[0]) is type(str())): # text must be appended to the tail of the most recent sibling or appended # to the text of the parent of the replaced element - self.attach_text_to_previous(theme_el,content_els[0]) + self.attach_text_to_previous(theme_el, content_els[0]) if len(non_text_els) == 0: - self.attach_text_to_previous(theme_el,theme_el.tail) + self.attach_text_to_previous(theme_el, theme_el.tail) theme_el.getparent().remove(theme_el) return - + self.attach_tails(content_els) # this tail, if there is one, should stick around @@ -238,7 +244,7 @@ non_text_els[0].tail = preserve_tail def debug_replace(self,theme_el,content_els,rule): - comment_before,comment_after = self.make_debugging_comments(rule) + comment_before, comment_after = self.make_debugging_comments(rule) content_els[:0] = [comment_before] content_els.append(comment_after) @@ -256,16 +262,18 @@ parent[i+1:i+1] = non_text_els[1:] - def apply_copy(self,rule,theme,content): + def apply_copy(self, rule, theme, content): theme_el = self.get_theme_el(rule,theme) if theme_el is None: - return + return - content_els = copy.deepcopy(content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = copy.deepcopy( + content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': - self.add_to_body_start(theme, self.format_error("no content matched", rule)) + self.add_to_body_start( + theme, self.format_error("no content matched", rule)) return non_text_els = self.elements_in(content_els) @@ -285,14 +293,14 @@ comment_before,comment_after = self.make_debugging_comments(rule) parent = theme_el.getparent() index = parent.index(theme_el) - parent.insert(index-1,comment_before) - parent.insert(index+2,comment_after) + parent.insert(index-1, comment_before) + parent.insert(index+2, comment_after) comment_after.tail = theme_el.tail theme_el.tail = None - def apply_append_or_replace(self,rule,theme,content): - theme_el = self.get_theme_el(rule,theme) + def apply_append_or_replace(self, rule, theme, content): + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return @@ -300,19 +308,21 @@ remove_tag = self.get_tag_from_xpath(content_xpath) if remove_tag is None: - self.add_to_body_start(theme,self.format_error("invalid xpath for content", rule=rule)) + self.add_to_body_start( + theme, self.format_error("invalid xpath for content", rule=rule)) return content_els = copy.deepcopy(content.xpath(content_xpath)) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': - self.add_to_body_start(theme, self.format_error("no content matched", rule)) + self.add_to_body_start( + theme, self.format_error("no content matched", rule)) return for el in theme_el: if el.tag == remove_tag: - self.attach_text_to_previous(el,el.tail) + self.attach_text_to_previous(el, el.tail) theme_el.remove(el) From ianb at codespeak.net Thu Oct 19 03:11:11 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 19 Oct 2006 03:11:11 +0200 (CEST) Subject: [z3-checkins] r33438 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061019011111.83E6810068@code0.codespeak.net> Author: ianb Date: Thu Oct 19 03:11:00 2006 New Revision: 33438 Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: Make sure the response won't be encoded, by removing the Accept-Encoding header. Technically we could de-gzip the response, but it's just busy work in this case Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Thu Oct 19 03:11:00 2006 @@ -81,6 +81,8 @@ notheme = 'notheme' in qs if notheme: return self.app(environ, start_response) + if 'HTTP_ACCEPT_ENCODING' in environ: + del environ['HTTP_ACCEPT_ENCODING'] status, headers, body = intercept_output( environ, self.app, From ianb at codespeak.net Thu Oct 19 03:13:49 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 19 Oct 2006 03:13:49 +0200 (CEST) Subject: [z3-checkins] r33439 - z3/deliverance/branches/packaged/deliverance/test-data/nycsr Message-ID: <20061019011349.26B5F10068@code0.codespeak.net> Author: ianb Date: Thu Oct 19 03:13:38 2006 New Revision: 33439 Added: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr-live.xml - copied, changed from r33437, z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.xml Log: Added another version of the nycsr rules that works for me right now against the live site Copied: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr-live.xml (from r33437, z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.xml) ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr-live.xml Thu Oct 19 03:13:38 2006 @@ -3,5 +3,14 @@ - + + + + + + From ianb at codespeak.net Thu Oct 19 03:14:29 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 19 Oct 2006 03:14:29 +0200 (CEST) Subject: [z3-checkins] r33440 - in z3/deliverance/branches/packaged: . deliverance Message-ID: <20061019011429.34A4210068@code0.codespeak.net> Author: ianb Date: Thu Oct 19 03:14:21 2006 New Revision: 33440 Added: z3/deliverance/branches/packaged/deliverance/proxyapp.py (contents, props changed) z3/deliverance/branches/packaged/deliverance/proxycommand.py (contents, props changed) Modified: z3/deliverance/branches/packaged/setup.py Log: Added a command-line script for setting up a proxy Added: z3/deliverance/branches/packaged/deliverance/proxyapp.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/proxyapp.py Thu Oct 19 03:14:21 2006 @@ -0,0 +1,34 @@ +""" +WSGI proxy application that applies a deliverance theme while +passing the request to another HTTP server +""" + +from paste.proxy import TransparentProxy +from deliverance import wsgifilter + +class ProxyDeliveranceApp(object): + + def __init__(self, theme_uri, rule_uri, proxy, + transparent=False): + self.theme_uri = theme_uri, + self.rule_uri = rule_uri, + self.proxy = proxy + self.transparent = transparent + self.subapp = self.make_app() + self.deliverance_app = wsgifilter.DeliveranceMiddleware( + self.subapp, theme_uri, rule_uri) + + def make_app(self): + if self.transparent: + force_host = self.proxy + else: + force_host = None + return TransparentProxy(force_host=force_host) + + def __call__(self, environ, start_response): + if not self.transparent: + # @@: Set forwarded header + environ['HTTP_HOST'] = self.proxy + return self.deliverance_app( + environ, start_response) + Added: z3/deliverance/branches/packaged/deliverance/proxycommand.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/proxycommand.py Thu Oct 19 03:14:21 2006 @@ -0,0 +1,83 @@ +import optparse +import pkg_resources +import sys +from deliverance import proxyapp + +my_package = pkg_resources.get_distribution('Deliverance') + +pkg_resources.require('Paste') + +from paste import httpserver + +help = """\ +""" + +parser = optparse.OptionParser( + version=str(my_package), + usage="%%prog [OPTIONS]\n\n%s" % help) +parser.add_option('-s', '--serve', + help="The interface to serve on (default 0.0.0.0:80)", + dest="serve", + default="0.0.0.0:80") +parser.add_option('-p', '--proxy', + help="The host and port to proxy to (default localhost:8080)", + dest="proxy", + default='localhost:8080') +parser.add_option('--theme', + help="The URI of the theme to use", + dest="theme") +parser.add_option('--rule', + help="The URI of the ruleset to use", + dest="rule") +parser.add_option('--transparent', + help="Do not rewrite the Host header when passing the request on", + action='store_true', + dest='transparent') +parser.add_option('--debug', + help="Show tracebacks when an error occurs (use twice for fancy/dangerous traceback)", + action="count", + dest="debug") + +def strip(prefix, string): + if string.startswith(prefix): + return string[len(prefix):] + else: + return string + +def main(args=None): + if args is None: + args = sys.argv[1:] + options, args = parser.parse_args(args) + serve = strip('http://', options.serve) + if ':' not in serve: + serve += ':80' + proxy = strip('http://', options.proxy) + if ':' not in proxy: + proxy += ':80' + if not options.rule or not options.theme: + if not options.rule: + op = '--rule' + else: + op = '--theme' + print 'You must provide the %s option' % op + sys.exit(2) + app = proxyapp.ProxyDeliveranceApp( + theme_uri=options.theme, + rule_uri=options.rule, + proxy=proxy, + transparent=options.transparent) + if options.debug: + if options.debug > 1: + from paste.evalexception.middleware import EvalException + app = EvalException(app) + else: + from paste.exceptions.errormiddleware import ErrorMiddleware + app = ErrorMiddleware(app, debug=True) + print 'Serving on http://%s' % serve + print 'Proxying from http://%s' % proxy + try: + httpserver.serve(app, host=serve) + except KeyboardInterrupt: + print 'Exiting.' + sys.exit() + Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Thu Oct 19 03:14:21 2006 @@ -19,12 +19,15 @@ zip_safe=False, install_requires=[ 'lxml', - 'paste' + 'paste==dev,>=0.9.9a' ], include_package_data=True, entry_points=""" [paste.filter_app_factory] main = deliverance.wsgifilter:make_filter + + [console_scripts] + deliverance-proxy = deliverance.proxycommand:main """, ) From ianb at codespeak.net Thu Oct 19 03:16:47 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 19 Oct 2006 03:16:47 +0200 (CEST) Subject: [z3-checkins] r33441 - z3/deliverance/branches/packaged/deliverance/test-data/nycsr Message-ID: <20061019011647.F34F810068@code0.codespeak.net> Author: ianb Date: Thu Oct 19 03:16:39 2006 New Revision: 33441 Modified: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr-live.xml Log: Oops, libxml doesn't like -- inside a comment Modified: z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr-live.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr-live.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/nycsr/nycsr-live.xml Thu Oct 19 03:16:39 2006 @@ -5,7 +5,7 @@ + not 'container'...? - ianb --> From ltucker at codespeak.net Fri Oct 20 19:19:50 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 19:19:50 +0200 (CEST) Subject: [z3-checkins] r33509 - z3/deliverance/branches/packaged Message-ID: <20061020171950.0D31C10075@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 19:19:48 2006 New Revision: 33509 Modified: z3/deliverance/branches/packaged/setup.py Log: add setuptools as a dependency, sort of wierd, but nice for the buildout Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Fri Oct 20 19:19:48 2006 @@ -20,6 +20,7 @@ install_requires=[ 'lxml', 'paste==dev,>=0.9.9a' + 'setuptools' ], include_package_data=True, entry_points=""" From ltucker at codespeak.net Fri Oct 20 19:34:15 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 19:34:15 +0200 (CEST) Subject: [z3-checkins] r33510 - z3/deliverance/branches/packaged Message-ID: <20061020173415.4740C10072@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 19:34:13 2006 New Revision: 33510 Modified: z3/deliverance/branches/packaged/setup.py Log: removing setuptools dependency, no good anyway Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Fri Oct 20 19:34:13 2006 @@ -20,7 +20,6 @@ install_requires=[ 'lxml', 'paste==dev,>=0.9.9a' - 'setuptools' ], include_package_data=True, entry_points=""" From ltucker at codespeak.net Fri Oct 20 19:56:34 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 19:56:34 +0200 (CEST) Subject: [z3-checkins] r33511 - z3/deliverance/branches/packaged Message-ID: <20061020175634.392E61006F@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 19:56:31 2006 New Revision: 33511 Modified: z3/deliverance/branches/packaged/setup.py Log: try again with setuptools dependency Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Fri Oct 20 19:56:31 2006 @@ -20,6 +20,7 @@ install_requires=[ 'lxml', 'paste==dev,>=0.9.9a' + 'setuptools' ], include_package_data=True, entry_points=""" From ltucker at codespeak.net Fri Oct 20 20:25:41 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 20:25:41 +0200 (CEST) Subject: [z3-checkins] r33512 - z3/deliverance/branches/packaged Message-ID: <20061020182541.3697D10053@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 20:25:38 2006 New Revision: 33512 Modified: z3/deliverance/branches/packaged/setup.py Log: missing comma Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Fri Oct 20 20:25:38 2006 @@ -19,7 +19,7 @@ zip_safe=False, install_requires=[ 'lxml', - 'paste==dev,>=0.9.9a' + 'paste==dev,>=0.9.9a', 'setuptools' ], include_package_data=True, From ltucker at codespeak.net Fri Oct 20 21:18:51 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 21:18:51 +0200 (CEST) Subject: [z3-checkins] r33513 - z3/deliverance/branches/packaged Message-ID: <20061020191851.3D2D710060@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 21:18:49 2006 New Revision: 33513 Modified: z3/deliverance/branches/packaged/README.txt Log: adding link to the buildout to the readme Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Fri Oct 20 21:18:49 2006 @@ -1,7 +1,17 @@ Quick Start to run tests ------------------------- -running setup.py is probably going to do the wrong thing currently + +The easiest way to get started is to check out the buildout: + +svn co https://svn.openplans.org/svn/deliverance.buildout deliverance.buildout + +If you follow the instructions there and install nose and it's dependencies, +you should be able to run tests by running nosetests from +this directory. + + +Otherwise to install manually: get workingenv.py from http://cheeseshop.python.org/pypi/workingenv.py From ltucker at codespeak.net Fri Oct 20 21:44:32 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 21:44:32 +0200 (CEST) Subject: [z3-checkins] r33514 - in z3/deliverance/branches/packaged: . deliverance Message-ID: <20061020194432.CBF1A10060@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 21:44:28 2006 New Revision: 33514 Modified: z3/deliverance/branches/packaged/deliverance/test_speed.py z3/deliverance/branches/packaged/deliverance/tests.py z3/deliverance/branches/packaged/setup.py Log: adjusted speed test to run from deliverance folder, added main functions to testing scripts, added testing tools to dependencies. Should adjust these all to be independent of where they are run from at some point Modified: z3/deliverance/branches/packaged/deliverance/test_speed.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_speed.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_speed.py Fri Oct 20 21:44:28 2006 @@ -69,7 +69,9 @@ parser.print_usage() sys.exit(0) -if __name__ == '__main__': - do_transform('xslt','test-data/nycsr/nycsr_speed.html','http://www.nycsr.org','test-data/nycsr/nycsr.xml','test-data/nycsr/openplans.html') - do_transform('py','test-data/nycsr/nycsr_speed.html','http://www.nycsr.org','test-data/nycsr/nycsr.xml','test-data/nycsr/openplans.html') +def main(args=None): + do_transform('xslt','deliverance/test-data/nycsr/nycsr_speed.html','http://www.nycsr.org','deliverance/test-data/nycsr/nycsr.xml','deliverance/test-data/nycsr/openplans.html') + do_transform('py','deliverance/test-data/nycsr/nycsr_speed.html','http://www.nycsr.org','deliverance/test-data/nycsr/nycsr.xml','deliverance/test-data/nycsr/openplans.html') +if __name__ == '__main__': + main() Modified: z3/deliverance/branches/packaged/deliverance/tests.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/tests.py (original) +++ z3/deliverance/branches/packaged/deliverance/tests.py Fri Oct 20 21:44:28 2006 @@ -104,6 +104,8 @@ +def main(args=None): + import nose; nose.main() if __name__ == '__main__': - import nose; nose.main() + main() Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Fri Oct 20 21:44:28 2006 @@ -20,6 +20,9 @@ install_requires=[ 'lxml', 'paste==dev,>=0.9.9a', + 'nose', + 'formencode', + 'elementtree', 'setuptools' ], include_package_data=True, @@ -29,6 +32,8 @@ [console_scripts] deliverance-proxy = deliverance.proxycommand:main + deliverance-tests = deliverance.tests:main + deliverance-speed = deliverance.test_speed:main """, ) From ltucker at codespeak.net Fri Oct 20 21:52:53 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 21:52:53 +0200 (CEST) Subject: [z3-checkins] r33515 - z3/deliverance/branches/packaged Message-ID: <20061020195253.7152410060@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 21:52:51 2006 New Revision: 33515 Modified: z3/deliverance/branches/packaged/README.txt Log: updating install instructions, removing steps covered by buildout and setup Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Fri Oct 20 21:52:51 2006 @@ -6,9 +6,7 @@ svn co https://svn.openplans.org/svn/deliverance.buildout deliverance.buildout -If you follow the instructions there and install nose and it's dependencies, -you should be able to run tests by running nosetests from -this directory. +If you follow the instructions there. Otherwise to install manually: @@ -24,17 +22,18 @@ install a recent cvs version of libxml2,libxstl and svn lxml. You are likely to encounter segfaults and other failures if recent versions are not used. -$ easy_install nose -$ easy_install FormEncode -$ easy_install elementtree -$ easy_install paste - checkout deliverance: $ svn co http://codespeak.net/svn/z3/deliverance/branches/packaged deliverance $ cd deliverance -$ nosetests +$ python setup.py develop +$ nosetests + +you can also run: +deliverance_env/bin/deliverance-tests +deliverance_env/bin/deliverance-speed +from the top level checkout directory Simple Tests ------------ From ltucker at codespeak.net Fri Oct 20 22:20:06 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 20 Oct 2006 22:20:06 +0200 (CEST) Subject: [z3-checkins] r33516 - z3/deliverance/branches/packaged Message-ID: <20061020202006.0FC5110060@code0.codespeak.net> Author: ltucker Date: Fri Oct 20 22:20:04 2006 New Revision: 33516 Modified: z3/deliverance/branches/packaged/README.txt Log: add prominent reference to specification page Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Fri Oct 20 22:20:04 2006 @@ -1,4 +1,7 @@ +See: http://www.openplans.org/projects/deliverance/specification +for more information + Quick Start to run tests ------------------------- From faassen at codespeak.net Mon Oct 23 18:01:33 2006 From: faassen at codespeak.net (faassen at codespeak.net) Date: Mon, 23 Oct 2006 18:01:33 +0200 (CEST) Subject: [z3-checkins] r33610 - in z3/hurry.file/trunk: . src/hurry/file/browser Message-ID: <20061023160133.8E84A10070@code0.codespeak.net> Author: faassen Date: Mon Oct 23 18:01:32 2006 New Revision: 33610 Modified: z3/hurry.file/trunk/CHANGES.txt z3/hurry.file/trunk/setup.py z3/hurry.file/trunk/src/hurry/file/browser/widget.py Log: Prepare for version 0.9.3. Modified: z3/hurry.file/trunk/CHANGES.txt ============================================================================== --- z3/hurry.file/trunk/CHANGES.txt (original) +++ z3/hurry.file/trunk/CHANGES.txt Mon Oct 23 18:01:32 2006 @@ -1,6 +1,12 @@ hurry.file changes ================== +0.9.3 (2006-10-23) +------------------ + +* Send tramline_ok header back when redisplaying widget, in case we're + working with tramline. + 0.9.2 (2006-09-28) ------------------ Modified: z3/hurry.file/trunk/setup.py ============================================================================== --- z3/hurry.file/trunk/setup.py (original) +++ z3/hurry.file/trunk/setup.py Mon Oct 23 18:01:32 2006 @@ -2,7 +2,7 @@ setup( name="hurry.file", - version="0.9.2", + version="0.9.3", packages=find_packages('src'), package_dir= {'':'src'}, Modified: z3/hurry.file/trunk/src/hurry/file/browser/widget.py ============================================================================== --- z3/hurry.file/trunk/src/hurry/file/browser/widget.py (original) +++ z3/hurry.file/trunk/src/hurry/file/browser/widget.py Mon Oct 23 18:01:32 2006 @@ -76,6 +76,8 @@ # if there was data in the input, pass along the data id if file_id is not None: + # tell tramline to store this file (if tramline is in use) + self.request.response.addHeader('tramline_ok', 'OK') if value: result += ' (%s)' % value.filename result += renderElement( From faassen at codespeak.net Mon Oct 23 18:02:09 2006 From: faassen at codespeak.net (faassen at codespeak.net) Date: Mon, 23 Oct 2006 18:02:09 +0200 (CEST) Subject: [z3-checkins] r33611 - z3/hurry.file/tag/0.9.3 Message-ID: <20061023160209.3656810070@code0.codespeak.net> Author: faassen Date: Mon Oct 23 18:02:08 2006 New Revision: 33611 Added: z3/hurry.file/tag/0.9.3/ - copied from r33610, z3/hurry.file/trunk/ Log: 0.9.3 release tag. From ltucker at codespeak.net Mon Oct 23 20:56:28 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 23 Oct 2006 20:56:28 +0200 (CEST) Subject: [z3-checkins] r33616 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061023185628.BA7B210063@code0.codespeak.net> Author: ltucker Date: Mon Oct 23 20:56:26 2006 New Revision: 33616 Modified: z3/deliverance/branches/packaged/deliverance/utils.py z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: added rudimentary error page and exception handling for certain errors like bad / missing rules or theme Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Mon Oct 23 20:56:26 2006 @@ -10,12 +10,36 @@ warnings.warn( 'Deliverance requires the CVS HEAD version of libxml2') -class RuleSyntaxError(Exception): +class DeliveranceError(Exception): + """ + General Deliverance Error. + """ + +class RuleSyntaxError(DeliveranceError): """ Raised when an invalid or unknown rule is encountered by a renderer during rule processing """ +DELIVERANCE_ERROR_PAGE = """ + + + Deliverance Error + + +

      Deliverance Error

      +

      An error occurred processing the request
      +

      +    %s
      +  
      +

      Stack Trace: +

      +    %s
      +  
      + + +""" + class RendererBase(object): """ Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Mon Oct 23 20:56:26 2006 @@ -16,12 +16,17 @@ from interpreter import Renderer #from xslt import Renderer from htmlserialize import tostring +from utils import DeliveranceError +from utils import DELIVERANCE_ERROR_PAGE import sys import datetime import threading +import traceback +from StringIO import StringIO DELIVERANCE_BASE_URL = 'deliverance.base-url' + class DeliveranceMiddleware(object): def __init__(self, app, theme_uri, rule_uri): @@ -58,10 +63,26 @@ elif encoding: return text.decode(encoding) + try: + parsedTheme = parseHTML(theme) + except Exception, message: + newmessage = "Unable to parse theme page (" + self.theme_uri + ")" + if message: + newmessage += ":" + str(message) + raise DeliveranceError(newmessage) + + try: + parsedRule = etree.XML(rule) + except Exception, message: + newmessage = "Unable to parse rules (" + self.rule_uri + ")" + if message: + newmessage += ":" + str(message) + raise DeliveranceError(newmessage) + return Renderer( - theme=parseHTML(theme), + theme=parsedTheme, theme_uri=full_theme_uri, - rule=etree.XML(rule), + rule=parsedRule, rule_uri=self.rule_uri, reference_resolver=reference_resolver) @@ -70,35 +91,62 @@ return self._cache_time + self._timeout < datetime.datetime.now() def rule(self, environ): - return self.get_resource(environ,self.rule_uri) + try: + return self.get_resource(environ,self.rule_uri) + except Exception, message: + newmessage = "Unable to retrieve rules from " + self.rule_uri + if message: + newmessage += ": " + str(message) + + raise DeliveranceError(newmessage) def theme(self, environ): - return self.get_resource(environ,self.theme_uri) + try: + return self.get_resource(environ,self.theme_uri) + except Exception, message: + newmessage = "Unable to retrieve theme page from " + self.theme_uri + if message: + newmessage += ": " + str(message) + raise DeliveranceError(newmessage) + def __call__(self, environ, start_response): - qs = environ.get('QUERY_STRING', '') - environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False) - notheme = 'notheme' in qs - if notheme: - return self.app(environ, start_response) - if 'HTTP_ACCEPT_ENCODING' in environ: - del environ['HTTP_ACCEPT_ENCODING'] - - status, headers, body = intercept_output( - environ, self.app, - self.should_intercept, - start_response) - - - if status is None: - # should_intercept returned False - return body - - body = self.filter_body(environ, body) - replace_header(headers, 'content-length', str(len(body))) - replace_header(headers, 'content-type', 'text/html; charset=utf-8') - start_response(status, headers) - return [body] + try: + qs = environ.get('QUERY_STRING', '') + environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False) + notheme = 'notheme' in qs + if notheme: + return self.app(environ, start_response) + if 'HTTP_ACCEPT_ENCODING' in environ: + del environ['HTTP_ACCEPT_ENCODING'] + + status, headers, body = intercept_output( + environ, self.app, + self.should_intercept, + start_response) + + + if status is None: + # should_intercept returned False + return body + + body = self.filter_body(environ, body) + replace_header(headers, 'content-length', str(len(body))) + replace_header(headers, 'content-type', 'text/html; charset=utf-8') + start_response(status, headers) + return [body] + + except DeliveranceError, message: + stack = StringIO() + traceback.print_exception(sys.exc_info()[0], + sys.exc_info()[1], + sys.exc_info()[2], + file=stack) + status = "500 Internal Server Error" + headers = [('Content-type','text/html')] + start_response(status,headers) + errpage = DELIVERANCE_ERROR_PAGE % (message,stack.getvalue()) + return [ errpage ] def should_intercept(self, status, headers): type = header_value(headers, 'content-type') @@ -150,7 +198,7 @@ loc = ' location=%r' % loc else: loc = '' - raise Exception( + raise DeliveranceError( "Request for internal resource at %s (%r) failed with status code %r%s" % (construct_url(environ), path_info, status, loc)) From ltucker at codespeak.net Mon Oct 23 23:25:47 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 23 Oct 2006 23:25:47 +0200 (CEST) Subject: [z3-checkins] r33620 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061023212547.6ED071006E@code0.codespeak.net> Author: ltucker Date: Mon Oct 23 23:25:45 2006 New Revision: 33620 Modified: z3/deliverance/branches/packaged/deliverance/utils.py Log: fix error when displaying errors on non ascii pages Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Mon Oct 23 23:25:45 2006 @@ -102,7 +102,7 @@ textArea.attrib['readonly'] = 'readonly' textArea.text = '' for el in elts: - textArea.text += htmlserialize.tostring(el) + textArea.append(el) d.append(textArea) return d From ltucker at codespeak.net Tue Oct 24 00:37:18 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Tue, 24 Oct 2006 00:37:18 +0200 (CEST) Subject: [z3-checkins] r33621 - z3/deliverance/branches/packaged Message-ID: <20061023223718.4FC2E10076@code0.codespeak.net> Author: ltucker Date: Tue Oct 24 00:37:16 2006 New Revision: 33621 Modified: z3/deliverance/branches/packaged/setup.py Log: use paste 1.0 Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Tue Oct 24 00:37:16 2006 @@ -19,10 +19,10 @@ zip_safe=False, install_requires=[ 'lxml', - 'paste==dev,>=0.9.9a', - 'nose', + 'paste', 'formencode', 'elementtree', + 'nose', 'setuptools' ], include_package_data=True, From ianb at codespeak.net Tue Oct 24 19:25:13 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Tue, 24 Oct 2006 19:25:13 +0200 (CEST) Subject: [z3-checkins] r33675 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061024172513.781C810063@code0.codespeak.net> Author: ianb Date: Tue Oct 24 19:25:11 2006 New Revision: 33675 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/utils.py Log: Style issue using len(); added new command for dropping elements from the theme or content. Note: no tests yet. Added better error message when xpath statements are bad (hasn't been applied everywhere it should be yet) Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Tue Oct 24 19:25:11 2006 @@ -52,6 +52,8 @@ self.apply_copy(rule, theme, content) elif rule.tag == self.APPEND_OR_REPLACE_RULE_TAG: self.apply_append_or_replace(rule, theme, content) + elif rule.tag == self.DROP_RULE_TAG: + self.apply_drop(rule, theme, content) elif rule.tag == self.SUBRULES_TAG: self.apply_rules(rule, theme, content) elif rule.tag is etree.Comment: @@ -261,14 +263,19 @@ i = parent.index(non_text_els[0]) parent[i+1:i+1] = non_text_els[1:] + def _xpath_copy(self, source, xpath): + try: + found_element = source.xpath(xpath) + except etree.XPathSyntaxError, e: + raise etree.XPathSyntaxError('%s (in expression %r)' % (e, xpath)) + return copy.deepcopy(found_element) def apply_copy(self, rule, theme, content): theme_el = self.get_theme_el(rule,theme) if theme_el is None: return - content_els = copy.deepcopy( - content.xpath(rule.attrib[self.RULE_CONTENT_KEY])) + content_els = self._xpath_copy(content, rule.attrib[self.RULE_CONTENT_KEY]) if len(content_els) == 0: if rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': @@ -334,6 +341,13 @@ theme_el.extend(content_els) + def apply_drop(self, rule, theme, content): + if 'theme' in rule.attrib: + for el in theme.xpath(rule.attrib['theme']): + el.getparent().remove(el) + if 'content' in rule.attrib: + for el in content.xpath(rule.attrib['content']): + el.getparent().remove(el) def elements_in(self, els): """ Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Tue Oct 24 19:25:11 2006 @@ -59,6 +59,7 @@ COPY_RULE_TAG = "{http://www.plone.org/deliverance}copy" APPEND_OR_REPLACE_RULE_TAG = "{http://www.plone.org/deliverance}append-or-replace" SUBRULES_TAG = "{http://www.plone.org/deliverance}rules" + DROP_RULE_TAG = "{http://www.plone.org/deliverance}drop" RULE_CONTENT_KEY = "content" RULE_THEME_KEY = "theme" @@ -154,7 +155,7 @@ """ base_uri = uri basetags = doc.xpath('//base[@href]') - if (len(basetags)): + if basetags: base_uri = basetags[0].attrib['href'] for b in basetags: From ianb at codespeak.net Tue Oct 24 19:25:52 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Tue, 24 Oct 2006 19:25:52 +0200 (CEST) Subject: [z3-checkins] r33676 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061024172552.5DA0710063@code0.codespeak.net> Author: ianb Date: Tue Oct 24 19:25:49 2006 New Revision: 33676 Added: z3/deliverance/branches/packaged/deliverance/fixuplinks.py (contents, props changed) z3/deliverance/branches/packaged/deliverance/relocateresponse.py (contents, props changed) Modified: z3/deliverance/branches/packaged/deliverance/proxyapp.py z3/deliverance/branches/packaged/deliverance/proxycommand.py Log: Added code to log requests more verbosely in the proxy app/command. Added some routines to fix up/translate links in a response, to help us proxy sites that don't want to be proxied Added: z3/deliverance/branches/packaged/deliverance/fixuplinks.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/fixuplinks.py Tue Oct 24 19:25:49 2006 @@ -0,0 +1,46 @@ +from htmlserialize import decodeAndParseHTML, tostring +import re + +def fixup_text_links(doc, link_repl_func, remove_base_tags=True): + """ + fixup_links(), but work on text and returns text + """ + doc = decodeAndParseHTML(doc) + fixup_links(doc, link_repl_func, remove_base_tags=remove_base_tags) + return tostring(doc) + +def fixup_links(doc, link_repl_func, + remove_base_tags=True): + """ + Takes a given document (already parsed by lxml) and modifies it + in-place. Every link is passed through link_repl_func, and the + output of that function replaces the link. + """ + if remove_base_tags: + remove_base_tags_from_document(doc) + + for attrib in 'href', 'src': + els = doc.xpath('//*[@%s]' % attrib) + for el in els: + el.attrib[attrib] = link_repl_func(el.attrib[attrib]) + + fixup_css_links(doc, link_repl_func) + +def remove_base_tags_from_document(doc): + basetags = doc.xpath('//base[@href]') + for b in basetags: + b.getparent().remove(b) + +CSS_URL_PAT = re.compile(r'url\((.*?)\)',re.I) +def fixup_css_links(doc, link_repl_func): + """ + prepends url(...) in css style elements to be + absolute links based on base_uri + """ + def absuri(matchobj): + return 'url(%s)' % link_repl_func(matchobj.group(1)) + els = doc.xpath('//head/style') + for el in els: + if el.text: + el.text = re.sub(self.CSS_URL_PAT,absuri,el.text) + Modified: z3/deliverance/branches/packaged/deliverance/proxyapp.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/proxyapp.py (original) +++ z3/deliverance/branches/packaged/deliverance/proxyapp.py Tue Oct 24 19:25:49 2006 @@ -5,30 +5,71 @@ from paste.proxy import TransparentProxy from deliverance import wsgifilter +from deliverance.relocateresponse import RelocateMiddleware class ProxyDeliveranceApp(object): def __init__(self, theme_uri, rule_uri, proxy, - transparent=False): + transparent=False, debug_headers=False, + relocate_content=False): self.theme_uri = theme_uri, self.rule_uri = rule_uri, self.proxy = proxy self.transparent = transparent + self.debug_headers = debug_headers self.subapp = self.make_app() self.deliverance_app = wsgifilter.DeliveranceMiddleware( self.subapp, theme_uri, rule_uri) + self.relocate_content = relocate_content def make_app(self): if self.transparent: force_host = self.proxy else: force_host = None - return TransparentProxy(force_host=force_host) + app = TransparentProxy(force_host=force_host) + if self.debug_headers: + app = DebugHeaders(app) + return app def __call__(self, environ, start_response): + if self.relocate_content: + reloc_app = RelocateMiddleware(self.run_subapp, old_href='http://'+self.proxy) + return reloc_app(environ, start_response) + else: + return self.run_subapp(environ, start_response) + + def run_subapp(self, environ, start_response): if not self.transparent: # @@: Set forwarded header environ['HTTP_HOST'] = self.proxy + if ':' in self.proxy: + server, port = self.proxy.split(':', 1) + else: + server, port = self.proxy, '80' + environ['SERVER_NAME'] = server + environ['SERVER_PORT'] = port return self.deliverance_app( environ, start_response) + +class DebugHeaders(object): + + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + from paste.request import construct_url + print 'Incoming headers: (%s %s)' % ( + environ['REQUEST_METHOD'], construct_url(environ)) + for name, value in sorted(environ.items()): + if not name.startswith('HTTP_'): + continue + name = name[5:].replace('_', '-').title() + print ' %s: %s' % (name, value) + def repl_start_response(status, headers, exc_info=None): + print 'Outgoing headers: (%s)' % status + for name, value in headers: + print ' %s: %s' % (name.title(), value) + start_response(status, headers, exc_info) + return self.app(environ, repl_start_response) Modified: z3/deliverance/branches/packaged/deliverance/proxycommand.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/proxycommand.py (original) +++ z3/deliverance/branches/packaged/deliverance/proxycommand.py Tue Oct 24 19:25:49 2006 @@ -18,10 +18,12 @@ parser.add_option('-s', '--serve', help="The interface to serve on (default 0.0.0.0:80)", dest="serve", + metavar="HOST", default="0.0.0.0:80") parser.add_option('-p', '--proxy', help="The host and port to proxy to (default localhost:8080)", dest="proxy", + metavar="PROXY_TO", default='localhost:8080') parser.add_option('--theme', help="The URI of the theme to use", @@ -37,6 +39,15 @@ help="Show tracebacks when an error occurs (use twice for fancy/dangerous traceback)", action="count", dest="debug") +parser.add_option('--request-log', + help="Show an apache-style log of requests (use twice for more logging)", + action="count", + dest="request_log", + default=0) +parser.add_option('--rewrite', + help="Rewrite all headers and links", + action="store_true", + dest="rewrite") def strip(prefix, string): if string.startswith(prefix): @@ -61,11 +72,17 @@ op = '--theme' print 'You must provide the %s option' % op sys.exit(2) + debug_headers = options.request_log > 1 app = proxyapp.ProxyDeliveranceApp( theme_uri=options.theme, rule_uri=options.rule, proxy=proxy, - transparent=options.transparent) + transparent=options.transparent, + debug_headers=debug_headers, + relocate_content=options.rewrite) + if options.request_log: + from paste.translogger import TransLogger + app = TransLogger(app) if options.debug: if options.debug > 1: from paste.evalexception.middleware import EvalException Added: z3/deliverance/branches/packaged/deliverance/relocateresponse.py ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/relocateresponse.py Tue Oct 24 19:25:49 2006 @@ -0,0 +1,72 @@ +""" +Takes a response (headers + content) and relocates it, changing domain +names and paths. +""" +import fixuplinks +import urlparse +from paste.request import construct_url +from paste.response import header_value + +def relocate_response(headers, content, base_href, old_href, new_href): + """ + Takes headers and content, and replaces all instances of old_href + with new_href. Returns (new_headers, new_content) + """ + new_headers = relocate_headers(headers, base_href, old_href, new_href) + new_content = relocate_content(content, base_href, old_href, new_href) + return new_headers, new_content + +def relocate_headers(headers, base_href, old_href, new_href): + new_headers = [] + for name, value in headers: + if name.lower() == 'location': + value = relocate_href(value, base_href, old_href, new_href) + new_headers.append((name, value)) + return new_headers + +def relocate_content(content, base_href, old_href, new_href): + def sub_link(href): + return relocate_href(href, base_href, old_href, new_href) + return fixuplinks.fixup_text_links(content, sub_link) + +def relocate_href(href, base_href, old_href, new_href): + real_href = urlparse.urljoin(base_href, href) + if not real_href.startswith(old_href): + return href + return new_href + real_href[len(old_href):] + +class RelocateMiddleware(object): + + def __init__(self, app, old_href): + self.app = app + if old_href.endswith(':80'): + old_href = old_href[:-3] + self.old_href = old_href + + def __call__(self, environ, start_response): + new_href = construct_url(environ, path_info='') + base_href = construct_url(environ) + skipped = [] + written = [] + stat_headers = [] + def repl_start_response(status, headers, exc_info=None): + headers = relocate_headers(headers, base_href, self.old_href, new_href) + content_type = header_value(headers, 'content-type') + if not content_type or not content_type.startswith('text/html'): + skipped.append(True) + return start_response(status, headers, exc_info) + stat_headers[:] = [status, headers] + return written.append + app_iter = self.app(environ, repl_start_response) + if skipped: + return app_iter + start_response(*stat_headers) + try: + for chunk in app_iter: + written.append(chunk) + finally: + if hasattr(app_iter, 'close'): + app_iter.close() + content = ''.join(written) + content = relocate_content(content, base_href, self.old_href, new_href) + return [content] From jinty at codespeak.net Tue Oct 24 19:25:58 2006 From: jinty at codespeak.net (jinty at codespeak.net) Date: Tue, 24 Oct 2006 19:25:58 +0200 (CEST) Subject: [z3-checkins] r33677 - z3/sqlos/trunk Message-ID: <20061024172558.1BA5810071@code0.codespeak.net> Author: jinty Date: Tue Oct 24 19:25:45 2006 New Revision: 33677 Modified: z3/sqlos/trunk/makefile Log: make sure a pythonpath is set. Modified: z3/sqlos/trunk/makefile ============================================================================== --- z3/sqlos/trunk/makefile (original) +++ z3/sqlos/trunk/makefile Tue Oct 24 19:25:45 2006 @@ -64,4 +64,4 @@ .PHONY: run-sampleapp run-sampleapp: develop Zope3/principals.zcml $(z3includes)/sqlos.ftesting-configure.zcml - cd Zope3; ./z3.py + cd Zope3; PYTHONPATH=src ./z3.py From jinty at codespeak.net Tue Oct 24 20:27:24 2006 From: jinty at codespeak.net (jinty at codespeak.net) Date: Tue, 24 Oct 2006 20:27:24 +0200 (CEST) Subject: [z3-checkins] r33682 - z3/sqlos/trunk/src/sqlos/ftests Message-ID: <20061024182724.8E64F10053@code0.codespeak.net> Author: jinty Date: Tue Oct 24 20:27:22 2006 New Revision: 33682 Modified: z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt Log: merge from kobold-sqlos branch: ------------------------------------------------------------------------ r31668 | kobold | 2006-08-26 09:19:00 +0200 (Sat, 26 Aug 2006) | 2 lines Small changes to ftests/localutilities.txt: without them, the functional test fails. Modified: z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt ============================================================================== --- z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt (original) +++ z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt Tue Oct 24 20:27:22 2006 @@ -63,19 +63,19 @@ there is currently no support for local sites in testcode. >>> cursor = localUtility().cursor() - >>> cursor.execute( + >>> c = cursor.execute( ... '''create table dog ( ... id integer primary key, ... fullname varchar(50) not null, ... owner varchar(20) not null)''') - >>> cursor.execute( + >>> c = cursor.execute( ... '''create table sample_isolated_person ( ... id integer primary key, ... domains text, ... fullname varchar(50) not null, ... username varchar(20) not null, ... password varchar(20) not null)''') - >>> cursor.execute( + >>> c = cursor.execute( ... '''create table sample_person ( ... id integer primary key, ... fullname varchar(50), @@ -114,6 +114,6 @@ And now try to see if the person has been actually created in the localUtility: >>> cursor = localUtility().cursor() - >>> cursor.execute("""select * from sample_person""") + >>> c = cursor.execute("""select * from sample_person""") >>> cursor.fetchone() [1, u'Bob', u'bob', u'obo'] From jinty at codespeak.net Tue Oct 24 20:39:12 2006 From: jinty at codespeak.net (jinty at codespeak.net) Date: Tue, 24 Oct 2006 20:39:12 +0200 (CEST) Subject: [z3-checkins] r33683 - in z3/sqlos/trunk: Zope2/FiveSQLOS src/sqlos src/sqlos/ftests src/sqlos/testing Message-ID: <20061024183912.4F53210053@code0.codespeak.net> Author: jinty Date: Tue Oct 24 20:39:07 2006 New Revision: 33683 Modified: z3/sqlos/trunk/Zope2/FiveSQLOS/README.txt z3/sqlos/trunk/Zope2/FiveSQLOS/dependencies-meta.zcml z3/sqlos/trunk/src/sqlos/adapter.py z3/sqlos/trunk/src/sqlos/connection.py z3/sqlos/trunk/src/sqlos/ftesting.zcml z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt z3/sqlos/trunk/src/sqlos/ftests/test_transaction.py z3/sqlos/trunk/src/sqlos/testing/testdb.py Log: zope.app.rdb -> zope.rdb Modified: z3/sqlos/trunk/Zope2/FiveSQLOS/README.txt ============================================================================== --- z3/sqlos/trunk/Zope2/FiveSQLOS/README.txt (original) +++ z3/sqlos/trunk/Zope2/FiveSQLOS/README.txt Tue Oct 24 20:39:07 2006 @@ -34,10 +34,10 @@ >>> from Products.Five import zcml >>> import sqlos >>> import Products.FiveSQLOS - >>> import zope.app.rdb + >>> import zope.rdb >>> zcml.load_config('configure.zcml', package=Products.Five) >>> zcml.load_config('meta.zcml', package=Products.FiveSQLOS) - >>> zcml.load_config('meta.zcml', package=zope.app.rdb) + >>> zcml.load_config('meta.zcml', package=zope.rdb) >>> zcml.load_config('meta.zcml', package=sqlos) >>> zcml.load_config('configure.zcml', package=Products.FiveSQLOS) >>> zcml.load_config('configure.zcml', package=sqlos) Modified: z3/sqlos/trunk/Zope2/FiveSQLOS/dependencies-meta.zcml ============================================================================== --- z3/sqlos/trunk/Zope2/FiveSQLOS/dependencies-meta.zcml (original) +++ z3/sqlos/trunk/Zope2/FiveSQLOS/dependencies-meta.zcml Tue Oct 24 20:39:07 2006 @@ -12,7 +12,7 @@ - + Modified: z3/sqlos/trunk/src/sqlos/adapter.py ============================================================================== --- z3/sqlos/trunk/src/sqlos/adapter.py (original) +++ z3/sqlos/trunk/src/sqlos/adapter.py Tue Oct 24 20:39:07 2006 @@ -21,7 +21,7 @@ from sqlobject import _mysql, _postgres, _sqlite from sqlobject.converters import registerConverter from sqlobject.mysql import mysqlconnection -from zope.app.rdb.interfaces import DatabaseException +from zope.rdb.interfaces import DatabaseException from zope.app.container.interfaces import INameChooser from zope.interface import implements @@ -54,12 +54,12 @@ def getConnection(self): # we override this because we really don't care about sqlobjects idea - # of threadsafe pool of db connections. zope.app.rdb takes care of + # of threadsafe pool of db connections. zope.rdb takes care of # that for us return self.makeConnection() def releaseConnection(self, conn, explicit=False): - # we simply lobotomize this method because zope.app.rdb + # we simply lobotomize this method because zope.rdb # takes care of all commits/rollbacks as well as all threading issues # with connections pass Modified: z3/sqlos/trunk/src/sqlos/connection.py ============================================================================== --- z3/sqlos/trunk/src/sqlos/connection.py (original) +++ z3/sqlos/trunk/src/sqlos/connection.py Tue Oct 24 20:39:07 2006 @@ -25,7 +25,7 @@ from zope.component import ComponentLookupError import zope.component -from zope.app.rdb.interfaces import IZopeDatabaseAdapter +from zope.rdb.interfaces import IZopeDatabaseAdapter from zope.thread import local from sqlos.interfaces import IZopeSQLConnection, IConnectionName @@ -52,7 +52,7 @@ This subscriber serves a dual purpose. Firstly it makes sure that local sites will work with the cache. Secondly it ensures that the cached - connections are not kept around forever, allowing zope.app.rdb to + connections are not kept around forever, allowing zope.rdb to recover from problems such as [1]. Subscribed to BeforeTraverseEvent and EndTraverseEvent. Modified: z3/sqlos/trunk/src/sqlos/ftesting.zcml ============================================================================== --- z3/sqlos/trunk/src/sqlos/ftesting.zcml (original) +++ z3/sqlos/trunk/src/sqlos/ftesting.zcml Tue Oct 24 20:39:07 2006 @@ -15,7 +15,7 @@ Modified: z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt ============================================================================== --- z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt (original) +++ z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt Tue Oct 24 20:39:07 2006 @@ -30,7 +30,7 @@ Now we set up a local database utility - >>> from zope.app.rdb.interfaces import IZopeDatabaseAdapter + >>> from zope.rdb.interfaces import IZopeDatabaseAdapter >>> from zope.app.component.interfaces.registration import ActiveStatus >>> from sqlos.testing.testdb import SQLiteda >>> from zope.app.utility import UtilityRegistration Modified: z3/sqlos/trunk/src/sqlos/ftests/test_transaction.py ============================================================================== --- z3/sqlos/trunk/src/sqlos/ftests/test_transaction.py (original) +++ z3/sqlos/trunk/src/sqlos/ftests/test_transaction.py Tue Oct 24 20:39:07 2006 @@ -17,7 +17,7 @@ from transaction import get, begin from zope.app.testing.functional import BrowserTestCase import zope.component -from zope.app.rdb.interfaces import IZopeDatabaseAdapter +from zope.rdb.interfaces import IZopeDatabaseAdapter from sqlos.interfaces import IConnectionName from sqlos.testing.sampleperson import SamplePerson Modified: z3/sqlos/trunk/src/sqlos/testing/testdb.py ============================================================================== --- z3/sqlos/trunk/src/sqlos/testing/testdb.py (original) +++ z3/sqlos/trunk/src/sqlos/testing/testdb.py Tue Oct 24 20:39:07 2006 @@ -18,7 +18,7 @@ import urlparse import transaction -from zope.app.rdb import ZopeDatabaseAdapter +from zope.rdb import ZopeDatabaseAdapter from sqlos.adapter import SQLiteAdapter From jinty at codespeak.net Tue Oct 24 20:59:03 2006 From: jinty at codespeak.net (jinty at codespeak.net) Date: Tue, 24 Oct 2006 20:59:03 +0200 (CEST) Subject: [z3-checkins] r33684 - z3/sqlos/trunk/src/sqlos/ftests Message-ID: <20061024185903.E1CBC10053@code0.codespeak.net> Author: jinty Date: Tue Oct 24 20:59:00 2006 New Revision: 33684 Modified: z3/sqlos/trunk/src/sqlos/ftests/adding.txt z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt Log: testbrowser warnings Modified: z3/sqlos/trunk/src/sqlos/ftests/adding.txt ============================================================================== --- z3/sqlos/trunk/src/sqlos/ftests/adding.txt (original) +++ z3/sqlos/trunk/src/sqlos/ftests/adding.txt Tue Oct 24 20:59:00 2006 @@ -11,7 +11,7 @@ Then get a browser: - >>> from zope.testbrowser import Browser + >>> from zope.testbrowser.testing import Browser >>> browser = Browser() >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw') >>> browser.handleErrors = False Modified: z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt ============================================================================== --- z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt (original) +++ z3/sqlos/trunk/src/sqlos/ftests/localutilities.txt Tue Oct 24 20:59:00 2006 @@ -90,7 +90,7 @@ So, get a testbrowser: - >>> from zope.testbrowser import Browser + >>> from zope.testbrowser.testing import Browser >>> browser = Browser() >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw') >>> browser.handleErrors = False From jinty at codespeak.net Tue Oct 24 21:00:53 2006 From: jinty at codespeak.net (jinty at codespeak.net) Date: Tue, 24 Oct 2006 21:00:53 +0200 (CEST) Subject: [z3-checkins] r33685 - z3/sqlos/trunk/src/sqlos/interfaces Message-ID: <20061024190053.EBC651005A@code0.codespeak.net> Author: jinty Date: Tue Oct 24 21:00:52 2006 New Revision: 33685 Modified: z3/sqlos/trunk/src/sqlos/interfaces/__init__.py Log: unused import Modified: z3/sqlos/trunk/src/sqlos/interfaces/__init__.py ============================================================================== --- z3/sqlos/trunk/src/sqlos/interfaces/__init__.py (original) +++ z3/sqlos/trunk/src/sqlos/interfaces/__init__.py Tue Oct 24 21:00:52 2006 @@ -11,7 +11,6 @@ """ from zope.schema import TextLine from zope.interface import Interface, Attribute -from zope.component import getService, ComponentLookupError from zope.interface import classImplements from zope.security.checker import NamesChecker, NoProxy, defineChecker from zope.schema.vocabulary import SimpleVocabulary From jinty at codespeak.net Tue Oct 24 21:05:07 2006 From: jinty at codespeak.net (jinty at codespeak.net) Date: Tue, 24 Oct 2006 21:05:07 +0200 (CEST) Subject: [z3-checkins] r33686 - z3/sqlos/trunk/src/sqlos Message-ID: <20061024190507.0C62D10034@code0.codespeak.net> Author: jinty Date: Tue Oct 24 21:05:04 2006 New Revision: 33686 Modified: z3/sqlos/trunk/src/sqlos/configure.zcml z3/sqlos/trunk/src/sqlos/ftesting.zcml Log: content -> class Modified: z3/sqlos/trunk/src/sqlos/configure.zcml ============================================================================== --- z3/sqlos/trunk/src/sqlos/configure.zcml (original) +++ z3/sqlos/trunk/src/sqlos/configure.zcml Tue Oct 24 21:05:04 2006 @@ -5,7 +5,7 @@ - + @@ -29,7 +29,7 @@ attributes="select" /> - + - + Modified: z3/hurry.file/trunk/src/hurry/file/file.py ============================================================================== --- z3/hurry.file/trunk/src/hurry/file/file.py (original) +++ z3/hurry.file/trunk/src/hurry/file/file.py Wed Oct 25 11:11:28 2006 @@ -1,7 +1,10 @@ +import sys, os, random, threading from StringIO import StringIO from persistent import Persistent from zope.interface import implements from hurry.file import interfaces +from zope import component +from zope.app.container.contained import Contained class HurryFile(Persistent): implements(interfaces.IHurryFile) @@ -12,10 +15,11 @@ self.headers = {} def _get_file(self): - return StringIO(self.data) + storage = component.getUtility(interfaces.IFileRetrieval) + return storage.getFile(self.data) file = property(_get_file) - + def __eq__(self, other): try: return (self.filename == other.filename and @@ -30,3 +34,74 @@ except AttributeError: return True +def createHurryFile(filename, f): + retrieval = component.getUtility(interfaces.IFileRetrieval) + return retrieval.createFile(filename, f) + +class IdFileRetrieval(Persistent, Contained): + """Very basic implementation of FileRetrieval. + + This implementation just returns a File object for the data. + """ + implements(interfaces.IFileRetrieval) + + def getFile(self, data): + return StringIO(data) + + def createFile(self, filename, f): + return HurryFile(filename, f.read()) + +class TramlineFileRetrievalBase(Persistent, Contained): + """File retrieval for tramline (base class). + """ + implements(interfaces.IFileRetrieval) + + def getTramlinePath(self): + raise NotImplementedError + + def isTramlineEnabled(self): + return True + + def getFile(self, data): + # tramline is disabled, so give fall-back behavior for testing + # without tramline + if not self.isTramlineEnabled(): + return StringIO(data) + # we need to retrieve the actual file from the filesystem + # it could be either a permanently stored file in the repository, + # or, if that isn't available, potentially a file in the upload + # directory + path = self.getTramlinePath() + if not path: + raise ValueError("No tramline path configured") + repository_path = os.path.join(path, 'repository', data) + try: + f = open(repository_path, 'rb') + except IOError: + upload_path = os.path.join(path, 'upload', data) + f = open(upload_path, 'rb') + return f + + def createFile(self, filename, f): + repository_path = os.path.join(self.getTramlinePath(), + 'repository') + # XXX try to make this thread-safe, but it's not 100% ZEO safe.. + lock = threading.Lock() + lock.acquire() + try: + while True: + file_id = str(random.randrange(sys.maxint)) + if os.path.exists(os.path.join(repository_path, + file_id)): + continue # try again + break + path = os.path.join(repository_path, file_id) + of = open(path, 'wb') + finally: + lock.release() + + # XXX this can be made more efficient + of.write(f.read()) + of.close() + + return HurryFile(filename, file_id) Modified: z3/hurry.file/trunk/src/hurry/file/interfaces.py ============================================================================== --- z3/hurry.file/trunk/src/hurry/file/interfaces.py (original) +++ z3/hurry.file/trunk/src/hurry/file/interfaces.py Wed Oct 25 11:11:28 2006 @@ -10,3 +10,12 @@ data = Bytes(title=u'Data in file') file = Attribute('File-like object with data') headers = Attribute('Headers associated with file') + +class IFileRetrieval(Interface): + def getFile(data): + """Get a file object for file data. + """ + + def createFile(filename, f): + """Given a file object, create a HurryFile with that data in it. + """ Added: z3/hurry.file/trunk/src/hurry/file/tests.py ============================================================================== --- (empty file) +++ z3/hurry.file/trunk/src/hurry/file/tests.py Wed Oct 25 11:11:28 2006 @@ -0,0 +1,24 @@ +import unittest + +from zope.testing import doctest +from zope.app.testing import placelesssetup +from zope import component + +from hurry.file.file import IdFileRetrieval +from hurry.file.interfaces import IFileRetrieval + +def fileSetUp(doctest): + placelesssetup.setUp() + component.provideUtility(IdFileRetrieval(), IFileRetrieval) + +def test_suite(): + return unittest.TestSuite(( + doctest.DocFileSuite( + 'README.txt', + setUp=fileSetUp, tearDown=placelesssetup.tearDown, + ), + )) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite') + From faassen at codespeak.net Wed Oct 25 11:12:40 2006 From: faassen at codespeak.net (faassen at codespeak.net) Date: Wed, 25 Oct 2006 11:12:40 +0200 (CEST) Subject: [z3-checkins] r33711 - z3/hurry.file/tag/hurry.file-1.0 Message-ID: <20061025091240.B266D10053@code0.codespeak.net> Author: faassen Date: Wed Oct 25 11:12:39 2006 New Revision: 33711 Added: z3/hurry.file/tag/hurry.file-1.0/ - copied from r33710, z3/hurry.file/trunk/ Log: Tag for 1.0 release. From ltucker at codespeak.net Wed Oct 25 21:57:05 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 25 Oct 2006 21:57:05 +0200 (CEST) Subject: [z3-checkins] r33739 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061025195705.A1B4810053@code0.codespeak.net> Author: ltucker Date: Wed Oct 25 21:57:02 2006 New Revision: 33739 Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml z3/deliverance/branches/packaged/deliverance/utils.py Log: this seems to be a far less horrible change to cover error generation for non-ascii pages Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_append.xml Wed Oct 25 21:57:02 2006 @@ -74,8 +74,7 @@
      Deliverance error: multiple elements found in theme
      rule: <append theme=".//div[@class='foo']" content=".//div[@id='bar']"/> -
      Dummy Content
      Dummy Content
      Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_appendorreplace.xml Wed Oct 25 21:57:02 2006 @@ -125,8 +125,7 @@
      Deliverance error: multiple elements found in theme
      rule: <append-or-replace theme=".//div" content=".//div"/> -
      Dummy Content
      Dummy Content
      Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_copy.xml Wed Oct 25 21:57:02 2006 @@ -70,8 +70,7 @@
      Deliverance error: multiple elements found in theme
      rule: <copy theme=".//div[@class='foo']" content=".//div[@id='bar']"/> -
      Dummy Content
      Dummy Content
      Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_prepend.xml Wed Oct 25 21:57:02 2006 @@ -74,8 +74,7 @@
      Deliverance error: multiple elements found in theme
      rule: <prepend theme=".//div[@class='foo']" content=".//div[@id='bar']"/> -
      Dummy Content
      Dummy Content
      Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml Wed Oct 25 21:57:02 2006 @@ -82,8 +82,7 @@
      Deliverance error: multiple elements found in theme
      rule: <replace theme="//div[@class='foo']" content="//div[@id='bar']"/> -
      Dummy Content
      Dummy Content
      Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Wed Oct 25 21:57:02 2006 @@ -103,7 +103,7 @@ textArea.attrib['readonly'] = 'readonly' textArea.text = '' for el in elts: - textArea.append(el) + textArea.text += etree.tostring(el) d.append(textArea) return d From rmarianski at codespeak.net Thu Oct 26 00:15:36 2006 From: rmarianski at codespeak.net (rmarianski at codespeak.net) Date: Thu, 26 Oct 2006 00:15:36 +0200 (CEST) Subject: [z3-checkins] r33744 - z3/deliverance/branches/packaged/deliverance/test-data Message-ID: <20061025221536.4C33F10053@code0.codespeak.net> Author: rmarianski Date: Thu Oct 26 00:15:26 2006 New Revision: 33744 Added: z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml Log: added tests for drop rule Added: z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml Thu Oct 26 00:15:26 2006 @@ -0,0 +1,168 @@ + + + + + + + + + + + Blah
      Dummy Content
      +
      + + + Real Content + + + + Blah + +
      + + + + + + + + + +
      foo
      bar
      urn
      +
      + + + Real Content + + + +
      urn
      +
      +
      + + + + + + + + + +
      +
      + + + + +
      shouldn't appear
      +
      should appear
      + + +
      + + +
      should appear
      +
      +
      + + + + + + + + + + + + +
      disappear
      + + +
      + + + + +
      disappear
      +
      appear
      + + +
      + + +
      appear
      +
      +
      + + + + + + + + + + +

      none

      of theseshould appear

      + + +
      + + + Real Content + + + + + +
      + + + + + + + + + + + + + Dummy Content + + + + Real Content + + + + Dummy Content + + + +
      + From cabraham at codespeak.net Thu Oct 26 23:32:59 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Thu, 26 Oct 2006 23:32:59 +0200 (CEST) Subject: [z3-checkins] r33788 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061026213259.583BA10053@code0.codespeak.net> Author: cabraham Date: Thu Oct 26 23:32:56 2006 New Revision: 33788 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml Log: errors for drop rules and debugging output Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Thu Oct 26 23:32:56 2006 @@ -342,12 +342,25 @@ def apply_drop(self, rule, theme, content): + if 'theme' in rule.attrib: + removed = False for el in theme.xpath(rule.attrib['theme']): el.getparent().remove(el) + removed = True + if not removed and rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': + self.add_to_body_start( + theme, self.format_error("no element found in theme", rule)) + if 'content' in rule.attrib: + removed = False for el in content.xpath(rule.attrib['content']): el.getparent().remove(el) + if not removed and rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': + self.add_to_body_start( + theme, self.format_error("no element found in content", rule)) + + def elements_in(self, els): """ Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml Thu Oct 26 23:32:56 2006 @@ -119,8 +119,7 @@ - - + + + + + + + + + + Dummy Content + + + + Real Content + + + + + + Dummy Content +
      Deliverance error: no element found in content
      rule: <drop content="//div[@id='foo']"/> +
      + + +
      +
      + From rmarianski at codespeak.net Fri Oct 27 00:58:48 2006 From: rmarianski at codespeak.net (rmarianski at codespeak.net) Date: Fri, 27 Oct 2006 00:58:48 +0200 (CEST) Subject: [z3-checkins] r33789 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061026225848.2EAA410068@code0.codespeak.net> Author: rmarianski Date: Fri Oct 27 00:58:38 2006 New Revision: 33789 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py Log: removed duplication in apply_drop rule Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Fri Oct 27 00:58:38 2006 @@ -342,25 +342,16 @@ def apply_drop(self, rule, theme, content): - - if 'theme' in rule.attrib: + for context in ('theme', 'content'): + if context not in rule.attrib: continue + document = locals()[context] removed = False - for el in theme.xpath(rule.attrib['theme']): + for el in document.xpath(rule.attrib[context]): el.getparent().remove(el) removed = True if not removed and rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': self.add_to_body_start( - theme, self.format_error("no element found in theme", rule)) - - if 'content' in rule.attrib: - removed = False - for el in content.xpath(rule.attrib['content']): - el.getparent().remove(el) - if not removed and rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': - self.add_to_body_start( - theme, self.format_error("no element found in content", rule)) - - + theme, self.format_error("no element found in %s" % context, rule)) def elements_in(self, els): """ From cabraham at codespeak.net Fri Oct 27 18:01:15 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Fri, 27 Oct 2006 18:01:15 +0200 (CEST) Subject: [z3-checkins] r33820 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061027160115.24CD3100A8@code0.codespeak.net> Author: cabraham Date: Fri Oct 27 18:01:11 2006 New Revision: 33820 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml Log: fixed tail handling in apply_drop; added failing tests for drop and replace Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Fri Oct 27 18:01:11 2006 @@ -347,6 +347,7 @@ document = locals()[context] removed = False for el in document.xpath(rule.attrib[context]): + self.attach_text_to_previous(el, el.tail) el.getparent().remove(el) removed = True if not removed and rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml Fri Oct 27 18:01:11 2006 @@ -189,5 +189,43 @@ + + + + + + + + Blahbefore
      Dummy Content
      after +
      + + + Real Content + + + + Blahbeforeafter + +
      + + + + Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml Fri Oct 27 18:01:11 2006 @@ -211,6 +211,24 @@ + + From cabraham at codespeak.net Fri Oct 27 21:27:41 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Fri, 27 Oct 2006 21:27:41 +0200 (CEST) Subject: [z3-checkins] r33822 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061027192741.EE6A4100AA@code0.codespeak.net> Author: cabraham Date: Fri Oct 27 21:27:39 2006 New Revision: 33822 Modified: z3/deliverance/branches/packaged/deliverance/xslt.py Log: Added drop rule to xsl renderer Modified: z3/deliverance/branches/packaged/deliverance/xslt.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/xslt.py (original) +++ z3/deliverance/branches/packaged/deliverance/xslt.py Fri Oct 27 21:27:39 2006 @@ -77,6 +77,8 @@ self.apply_copy(rule,theme) elif rule.tag == self.APPEND_OR_REPLACE_RULE_TAG: self.apply_append_or_replace(rule,theme) + elif rule.tag == self.DROP_RULE_TAG: + self.apply_drop(rule,theme) elif rule.tag == self.SUBRULES_TAG: self.apply_rules(rule,theme) elif rule.tag is etree.Comment: @@ -200,6 +202,42 @@ self.debug_append(theme_el, copier, rule) + def apply_drop(self,rule,theme): + + if self.RULE_THEME_KEY in rule.attrib: + if len(theme.xpath(rule.attrib[self.RULE_THEME_KEY])) == 0: + if rule.get(self.NOCONTENT_KEY) == 'ignore': + return + else: + e = self.format_error("no element found in theme", rule) + self.add_to_body_start(theme, e) + return + + for el in theme.xpath(rule.attrib[self.RULE_THEME_KEY]): + self.debug_drop(el,rule) + self.attach_text_to_previous(el, el.tail) + el.getparent().remove(el) + + + +# if 'content' in rule.attrib: +# self.add_conditional_missing_content_error(theme,rule) + + + +# copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) +# copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) + + +# # if content is matched, replace the theme element, otherwise, keep the +# # theme element +# choose = self.make_when_otherwise("count(%s)=0" % +# rule.attrib[self.RULE_CONTENT_KEY], +# copy.deepcopy(theme_el), +# copier) + + + def xsl_escape_comments(self,doc): """ replaces comment nodes with xsl:comment nodes so they will @@ -281,6 +319,21 @@ parent.insert(index, comment_before) parent.insert(index+2, comment_after) + def debug_drop(self, el, rule): + """ + helper method for deleting a node, if debugging is enabled, + comments are inserted referring to the + rule that performed the drop + """ + if self.debug: + parent = el.getparent() + index = parent.index(el) + + comment_before,comment_after = self.make_debugging_comments(rule) + + parent.insert(index, comment_before) + parent.insert(index+2, comment_after) + def debug_prepend(self, parent, child, rule): """ helper method for prepending a node, if debugging is enabled, From rmarianski at codespeak.net Sat Oct 28 00:11:16 2006 From: rmarianski at codespeak.net (rmarianski at codespeak.net) Date: Sat, 28 Oct 2006 00:11:16 +0200 (CEST) Subject: [z3-checkins] r33825 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061027221116.23747100B0@code0.codespeak.net> Author: rmarianski Date: Sat Oct 28 00:11:11 2006 New Revision: 33825 Modified: z3/deliverance/branches/packaged/deliverance/proxyapp.py z3/deliverance/branches/packaged/deliverance/proxycommand.py z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: add ability to specify renderer on command line Modified: z3/deliverance/branches/packaged/deliverance/proxyapp.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/proxyapp.py (original) +++ z3/deliverance/branches/packaged/deliverance/proxyapp.py Sat Oct 28 00:11:11 2006 @@ -11,7 +11,7 @@ def __init__(self, theme_uri, rule_uri, proxy, transparent=False, debug_headers=False, - relocate_content=False): + relocate_content=False, renderer='py'): self.theme_uri = theme_uri, self.rule_uri = rule_uri, self.proxy = proxy @@ -19,7 +19,7 @@ self.debug_headers = debug_headers self.subapp = self.make_app() self.deliverance_app = wsgifilter.DeliveranceMiddleware( - self.subapp, theme_uri, rule_uri) + self.subapp, theme_uri, rule_uri, renderer) self.relocate_content = relocate_content def make_app(self): Modified: z3/deliverance/branches/packaged/deliverance/proxycommand.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/proxycommand.py (original) +++ z3/deliverance/branches/packaged/deliverance/proxycommand.py Sat Oct 28 00:11:11 2006 @@ -48,6 +48,9 @@ help="Rewrite all headers and links", action="store_true", dest="rewrite") +parser.add_option('--renderer', + help="Select which renderer to use: 'py' or 'xslt'", + default='py') def strip(prefix, string): if string.startswith(prefix): Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Sat Oct 28 00:11:11 2006 @@ -13,7 +13,7 @@ from paste.wsgilib import intercept_output from paste.request import construct_url from paste.response import header_value, replace_header -from interpreter import Renderer +#from interpreter import Renderer #from xslt import Renderer from htmlserialize import tostring from utils import DeliveranceError @@ -29,7 +29,7 @@ class DeliveranceMiddleware(object): - def __init__(self, app, theme_uri, rule_uri): + def __init__(self, app, theme_uri, rule_uri, renderer='py'): self.app = app self.theme_uri = theme_uri self.rule_uri = rule_uri @@ -38,6 +38,14 @@ self._timeout = datetime.timedelta(0,10) self._lock = threading.Lock() + if renderer == 'py': + import interpreter + self._rendererType = interpreter.Renderer + elif renderer == 'xslt': + import xslt + self._rendererType = xslt.Renderer + else: + raise ValueError("Unknown Renderer: %s - Expecting 'py' or 'xslt'" % renderer) def get_renderer(self,environ): try: @@ -79,7 +87,7 @@ newmessage += ":" + str(message) raise DeliveranceError(newmessage) - return Renderer( + return self._rendererType( theme=parsedTheme, theme_uri=full_theme_uri, rule=parsedRule, From ltucker at codespeak.net Mon Oct 30 18:24:25 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 30 Oct 2006 18:24:25 +0100 (CET) Subject: [z3-checkins] r33919 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061030172425.A226A10086@code0.codespeak.net> Author: ltucker Date: Mon Oct 30 18:24:19 2006 New Revision: 33919 Modified: z3/deliverance/branches/packaged/deliverance/handtransform.py Log: update handtransformer to xinclude changes and changes to renderer init signature Modified: z3/deliverance/branches/packaged/deliverance/handtransform.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/handtransform.py (original) +++ z3/deliverance/branches/packaged/deliverance/handtransform.py Mon Oct 30 18:24:19 2006 @@ -37,8 +37,6 @@ content = etree.HTML(grab_url(content_url)) def reference_resolver(href, parse, encoding=None): - if not href.startswith('/'): - href = os.path.join(os.path.dirname(rules_url),href) text = grab_url(href) if parse == "xml": return etree.XML(text) @@ -47,9 +45,9 @@ renderer = None if renderer_type == 'xslt': - renderer = XSLTRenderer(theme,base_url,rules,reference_resolver) + renderer = XSLTRenderer(theme,base_url,rules,rules_url,reference_resolver) elif renderer_type == 'py': - renderer = PythonRenderer(theme,base_url,rules,reference_resolver) + renderer = PythonRenderer(theme,base_url,rules,rules_url,reference_resolver) else: print "Unknown renderer type '" + renderer_type + "'" return etree.Element("error") From cabraham at codespeak.net Mon Oct 30 20:18:37 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 30 Oct 2006 20:18:37 +0100 (CET) Subject: [z3-checkins] r33924 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061030191837.969C310068@code0.codespeak.net> Author: cabraham Date: Mon Oct 30 20:18:33 2006 New Revision: 33924 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml z3/deliverance/branches/packaged/deliverance/xslt.py Log: added error message fired when trying to replace the whole theme. Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Mon Oct 30 20:18:33 2006 @@ -201,6 +201,12 @@ theme, self.format_error("no content matched", rule)) return + if theme_el.getparent() is None: + self.add_to_body_start( + theme, self.format_error("cannot replace whole theme", rule)) + return + + if self.debug: self.debug_replace(theme_el, content_els, rule) return @@ -226,10 +232,13 @@ # this tail, if there is one, should stick around preserve_tail = non_text_els[0].tail + #replaces first element self.replace_element(theme_el, non_text_els[0]) temptail = non_text_els[0].tail non_text_els[0].tail = None parent = non_text_els[0].getparent() + + # appends the rest of the elements i = parent.index(non_text_els[0]) parent[i+1:i+1] = non_text_els[1:] Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_replace.xml Mon Oct 30 20:18:33 2006 @@ -211,6 +211,29 @@ + + + + + + + + Blah
      Dummy Content
      +
      + + +
      Real Content
      +
      + + + Blah
      Deliverance error: cannot replace whole theme
      + rule: <replace theme="//html" content="//html"/>
      Dummy Content
      + +
      + +
      + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/necoro/necoro.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/necoro.xml Mon Oct 30 20:26:02 2006 @@ -0,0 +1,7 @@ + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/necoro/openplans.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/openplans.html Mon Oct 30 20:26:02 2006 @@ -0,0 +1,648 @@ + + + + + + + + + + + + + + + + NYCSR + — + OpenPlans + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + Skip to content + + Skip to navigation + +
      + + + +

      + OpenPlans +

      + + + + + + + + + +
      +
      +
      + +
      + + + +
      + +
      +
      + + +
      + + + + +
      + +
      + +
      +
      + + + + + + + + + + + + + + + + + + +
      + + +
      + + + + +
      Views
      + + + + + +
      + + + + + + + + + + + +
      + + +
      + + + + + + + + + + +
      + + +
      Document Actions
      + + + + + + +
      + +

      NYCSR

      + +
      + +
      + + + + + + last modified + + + 2006-09-15 11:18 + + + + + + + + + +
      + +
      + +
      + +
      + + + + + +
      +

      Welcome to the NYC Streets Renaissance Campaign Headquarters

      The goal of the NYCSR is to tranform New York City streets so that they are safer, more productive and more livable.

      Streets can be places for neighbors to meet

      New York City is defined by its vibrant and diverse streets and neighborhoods. Unfortunately, our neighborhoods and business districts are buckling under increasing amounts of dangerous car and truck traffic. Children can no longer + + + + + + + play on their own blocks + + + + + + + + +, while parents worry about turning cars smashing into baby carriages. Senior citizens are losing their independence, shut up in their homes for fear of crossing the street. And shoppers and investors are being turned away by chaotic, traffic-choked avenues.

      This is unacceptable. The time is long overdue for our great city to strike a better balance between traffic and the needs of pedestrians.

      The NYC Streets Renaissance Campaign aims to:

      • Educate New Yorkers about potential transportation policy changes that will improve quality of life across New York City
      • Promote a rebalancing of this public space away from private vehicles and toward community needs
      • Demonstrate the widespread public support for reform on these issues
      • Tap the potential of New Yorkers to re-imagine their own streets

      Our Initiatives:

      • Help neighborhood leaders in the fight for long overdue, common sense improvements to their neighborhood streets

      To get involved, add your ideas for making New York City a better place to live and work to our Taking it Citywide + + + + + + + Neighborhoods + + + + + + + + + page, or visit us at http://www.nycsr.org/involved.php

      old landing page


      Together, we can re-imagine the streets of New York City.

      + + + +
      + +
      + + + + + + + +
      + + + + + +
      + + + + + +
      + + + + + + + +
      + + +
      + +
      + + +
      + +
      +
      + +
      + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/necoro/standardrules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/standardrules.xml Mon Oct 30 20:26:02 2006 @@ -0,0 +1,11 @@ + + + + + + + + + + From ltucker at codespeak.net Mon Oct 30 20:26:33 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 30 Oct 2006 20:26:33 +0100 (CET) Subject: [z3-checkins] r33926 - z3/deliverance/branches/packaged/deliverance/test-data/necoro Message-ID: <20061030192633.6C08010068@code0.codespeak.net> Author: ltucker Date: Mon Oct 30 20:26:31 2006 New Revision: 33926 Removed: z3/deliverance/branches/packaged/deliverance/test-data/necoro/__init__.py Log: this isn't a module Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/necoro/__init__.py ============================================================================== From ltucker at codespeak.net Mon Oct 30 21:45:43 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 30 Oct 2006 21:45:43 +0100 (CET) Subject: [z3-checkins] r33927 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061030204543.E7A3310068@code0.codespeak.net> Author: ltucker Date: Mon Oct 30 21:45:39 2006 New Revision: 33927 Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py z3/deliverance/branches/packaged/deliverance/tests.py Log: making tests test both renderers Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Mon Oct 30 21:45:39 2006 @@ -15,6 +15,7 @@ tasktracker_app = StaticURLParser(tasktracker_data) nycsr_app = StaticURLParser(nycsr_data) + def html_string_compare(astr, bstr): def reporter(x): print x @@ -39,44 +40,59 @@ "Comparison failed between actual:\n==================\n%s\n\nexpected:\n==================\n%s\n\nReport:\n%s" % (astr, bstr, '\n'.join(reporter))) -def test_basic(): - wsgi_app = DeliveranceMiddleware(static_app, 'theme.html', 'rules.xml') + + +def do_basic(renderer_type): + wsgi_app = DeliveranceMiddleware(static_app, 'theme.html', 'rules.xml', + renderer_type) app = TestApp(wsgi_app) res = app.get('/example.html') res2 = app.get('/example_expected.html?notheme') html_string_compare(res.body, res2.body) -def test_text(): - wsgi_app = DeliveranceMiddleware(static_app, 'theme.html', 'text-rules.xml') +def do_text(renderer_type): + wsgi_app = DeliveranceMiddleware(static_app, 'theme.html', 'text-rules.xml', + renderer_type) app = TestApp(wsgi_app) res = app.get('/example.html') res2 = app.get('/texttest_expected.html?notheme') html_string_compare(res.body, res2.body) -def test_tasktracker(): - wsgi_app = DeliveranceMiddleware(tasktracker_app, 'http://www.nycsr.org/nyc/video.php', 'tasktracker.xml') +def do_tasktracker(renderer_type): + wsgi_app = DeliveranceMiddleware(tasktracker_app, 'http://www.nycsr.org/nyc/video.php', + 'tasktracker.xml',renderer_type) app = TestApp(wsgi_app) res = app.get('/content.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) -def test_xinclude(): - wsgi_app = DeliveranceMiddleware(static_app, 'xinclude_theme.html', 'xinclude_rules.xml') +def do_xinclude(renderer_type): + wsgi_app = DeliveranceMiddleware(static_app, 'xinclude_theme.html', 'xinclude_rules.xml', + renderer_type) app = TestApp(wsgi_app) res = app.get('/example.html') res2 = app.get('/xinclude_expected.html?notheme') html_string_compare(res.body, res2.body) -def test_nycsr(): - wsgi_app = DeliveranceMiddleware(nycsr_app, 'http://www.nycsr.org','nycsr.xml') +def do_nycsr(renderer_type): + wsgi_app = DeliveranceMiddleware(nycsr_app, 'http://www.nycsr.org','nycsr.xml', + renderer_type) app = TestApp(wsgi_app) res = app.get('/openplans.html') res2 = app.get('/nycsr_expected.html?notheme') html_string_compare(res.body, res2.body) +RENDERER_TYPES = ['py','xslt'] +TEST_FUNCS = [ do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr ] +def test_all(): + for renderer_type in RENDERER_TYPES: + for test_func in TEST_FUNCS: + yield lambda(name): test_func(renderer_type), ("[%s] : %s" % (renderer_type, test_func.func_name)) + + if __name__ == '__main__': pass Modified: z3/deliverance/branches/packaged/deliverance/tests.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/tests.py (original) +++ z3/deliverance/branches/packaged/deliverance/tests.py Mon Oct 30 21:45:39 2006 @@ -2,20 +2,23 @@ import os from lxml import etree from formencode.doctest_xml_compare import xml_compare -from interpreter import Renderer -#from xslt import Renderer +from interpreter import Renderer as PyRenderer +from xslt import Renderer as XSLTRenderer import copy import urllib +RENDERER_CLASSES = [ PyRenderer, XSLTRenderer ] + class DeliveranceTestCase: - def __init__(self, rules, rules_uri, theme, theme_uri, content, output): + def __init__(self, rules, rules_uri, theme, theme_uri, content, output, renderer_class): self.rules = rules self.rules_uri = rules_uri self.theme = theme self.theme_uri = theme_uri self.content = content self.output = output + self.renderer_class = renderer_class def __call__(self, name): def reference_resolver(href, parse, encoding=None): @@ -27,7 +30,7 @@ elif encoding: return content.decode(encoding) - renderer = Renderer( + renderer = self.renderer_class( theme=self.theme, theme_uri=self.theme_uri, rule=self.rules, rule_uri=self.rules_uri, @@ -50,12 +53,13 @@ test_dir = os.path.join(os.path.dirname(__file__), 'test-data') def test_examples(): - for fn in os.listdir(test_dir): - fn = os.path.join(test_dir, fn) - for case in cases(fn): - yield case + for renderer_class in RENDERER_CLASSES: + for fn in os.listdir(test_dir): + fn = os.path.join(test_dir, fn) + for case in cases(fn,renderer_class): + yield case -def cases(fn): +def cases(fn, renderer_class): if not os.path.basename(fn).startswith('test_'): return if fn.endswith('~'): @@ -97,8 +101,9 @@ theme=themebody, theme_uri=el.find('theme').attrib['base'], content=contentbody, - output=outputbody) - yield case, ('%s:%s' % (fn, index)) + output=outputbody, + renderer_class=renderer_class) + yield case, ('[%s] %s:%s' % (renderer_class, fn, index)) From ltucker at codespeak.net Mon Oct 30 22:25:06 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 30 Oct 2006 22:25:06 +0100 (CET) Subject: [z3-checkins] r33928 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061030212506.1409B10068@code0.codespeak.net> Author: ltucker Date: Mon Oct 30 22:25:03 2006 New Revision: 33928 Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml z3/deliverance/branches/packaged/deliverance/utils.py Log: adds additional support for rewriting relative css imports Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml Mon Oct 30 22:25:03 2006 @@ -13,6 +13,9 @@ + + + + + + + + + + + + + + + Zope.org + + +
      +
      +

      ??????????

      +
      +

      ????????????1949????210?????????????????????????????????????????????????????????????
      +???????????????????????????????????
      ????????????????????????????????????????????

      + +
      +
      +
      + +
      +
      + +
      +
      + + +

      Welcome to Zope.org

      + +
      The Web Site for the Zope Community
      + +

      Zope is an open source application server for building + content management systems, intranets, portals, and custom + applications. The Zope community consists of hundreds of + companies and thousands of developers all over the world, + working on building the platform and Zope applications. Zope is + written in Python, a highly-productive, object-oriented + scripting language. more

      + + + + +

      Zope for...

      + + + + +
      + + + + + +
      +
      +

      What You can do on Zope.org

      +

      Membership gives you your own home folder on Zope.org where you can create + and manage your own Zope objects. The objects you create and maintain will + be available to all people who visit Zope.org.

      +

      Site visitors can find your content using the site search or by browsing + your member folder.

      +

      Many pages on the zope.org site are generated by search queries - by + providing metadata such as keywords with your content it can appear in + automated site pages such as product or news listings. more

      +
      + +
      + +

      Zope Training ...

      +
      + + +Send your Zope training announcements to webmaster at zope.org + +
      + +
      + +

      Plone Training ...

      +
      + + +Send your Plone training announcements to webmaster at zope.org + +
      + + +
      +
      Powered by?GUIDE 0.5.0 ? 2006 The Guide-Interpreter Search System +
      + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/guidesearch.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/guidesearch.xml Mon Oct 30 22:58:02 2006 @@ -0,0 +1,7 @@ + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/out.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/out.html Mon Oct 30 22:58:02 2006 @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + Zope.org + + +
      +
      +

      ???????????????????????????

      +
      +

      ?????????????????????????????????1949????????????210???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
      +???????????????????????????????????????????????????????????????????????????????????????????????????
      ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

      + +
      +
      +
      + +
      +
      + +
      +
      + + +

      Welcome to Zope.org

      + +
      The Web Site for the Zope Community
      + +

      Zope is an open source application server for building + content management systems, intranets, portals, and custom + applications. The Zope community consists of hundreds of + companies and thousands of developers all over the world, + working on building the platform and Zope applications. Zope is + written in Python, a highly-productive, object-oriented + scripting language. more

      + + + + +

      Zope for...

      + + + + +
      + + + + + +
      +
      +

      What You can do on Zope.org

      +

      Membership gives you your own home folder on Zope.org where you can create + and manage your own Zope objects. The objects you create and maintain will + be available to all people who visit Zope.org.

      +

      Site visitors can find your content using the site search or by browsing + your member folder.

      +

      Many pages on the zope.org site are generated by search queries - by + providing metadata such as keywords with your content it can appear in + automated site pages such as product or news listings. more

      +
      + +
      + +

      Zope Training ...

      +
      + + +Send your Zope training announcements to webmaster at zope.org + +
      + +
      + +

      Plone Training ...

      +
      + + +Send your Plone training announcements to webmaster at zope.org + +
      + + +
      +
      Powered by??GUIDE 0.5.0 ?? 2006 The Guide-Interpreter Search System +
      + + Added: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/standardrules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/standardrules.xml Mon Oct 30 22:58:02 2006 @@ -0,0 +1,11 @@ + + + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/zope.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/zope.html Mon Oct 30 22:58:02 2006 @@ -0,0 +1,751 @@ + + + + + + + + + + Zope.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      + + + + + + +
      + +
      + +
      + + +
      + +
        + + + + You are not logged in + + + + + + Log in + + + + + + + Join + + +
      + +
      + + + You are here: + + + + Home + + + +
      + +
      + +
      + + + + + + + + + + + + +
      + + +
      +
      + + + + + + + +
      +
      + + + + + + + +
      + +
      Log in
      + +
      + +
      +
      + + + Name
      + + +
      + + Password
      + + +
      +   +
      + + + + + +
      + +
      + + + + + +
      + +
      + + + + + +
      + + + +
      + +
      + + + + + + + + + + +
      + + + + + + + Print + +
      + + + +
      + + + + + + +
      +

      Welcome to Zope.org

      + +
      The Web Site for the Zope Community
      + +

      Zope is an open source application server for building + content management systems, intranets, portals, and custom + applications. The Zope community consists of hundreds of + companies and thousands of developers all over the world, + working on building the platform and Zope applications. Zope is + written in Python, a highly-productive, object-oriented + scripting language. more

      + + + + +

      Zope for...

      + + + + + + +
      + + + + + +
      + +
      +

      What You can do on Zope.org

      +

      Membership gives you your own home folder on Zope.org where you can create + and manage your own Zope objects. The objects you create and maintain will + be available to all people who visit Zope.org.

      +

      Site visitors can find your content using the site search or by browsing + your member folder.

      +

      Many pages on the zope.org site are generated by search queries - by + providing metadata such as keywords with your content it can appear in + automated site pages such as product or news listings. more

      +
      + +
      + +

      Zope Training ...

      +
      + + + + +Send your Zope training announcements to webmaster at zope.org + +
      + +
      + +

      Plone Training ...

      +
      + + +Send your Plone training announcements to webmaster at zope.org + +
      + +
      +
      + +
      + +
      Planets
      +
      +
      + + Planet Zope +
      Zope related news + + RSS Newsfeed +
      +
      +
      + + Planet Plone +
      Plone related news + + RSS Newsfeed +
      +
      +
      +
      + +
      + +
      News + + + RSS Newsfeed +
      +
      + +
      + ZopeDictDB 0.1 + + ZopeDictDB 0.1 + +
      October 30
      + +
      + + +
      + Russian Zope3 Maillist + + Russian Zope3 Maillist + +
      October 26
      + +
      + + + + + +
      + ZInformixDA 0.3 released + + ZInformixDA 0.3 released + +
      October 16
      + +
      + + + + +
      +
      +
      + +
      Products + + Products RSS
      +
      + + + + + + + +
      + ZopeEditArea 0.1 + + (0.1) + +
      October 08
      + +
      + + +
      + 2.10.0 + + Zope (2_10_0-final) + +
      October 03
      + +
      + + +
      + 3.2.2 + + Zope 3 (3.2.2) + +
      October 02
      + +
      + +
      +
      +
      + +
      +
      + + +
      + +
      + +
      +
      +
      + +
      + + + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/necoro/expected.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/expected.html Mon Oct 30 22:58:02 2006 @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + Zope.org + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + +
      Photo studioomron
      +
      +

      Welcome to Zope.org

      + +
      The Web Site for the Zope Community
      + +

      Zope is an open source application server for building + content management systems, intranets, portals, and custom + applications. The Zope community consists of hundreds of + companies and thousands of developers all over the world, + working on building the platform and Zope applications. Zope is + written in Python, a highly-productive, object-oriented + scripting language. more

      + + + + +

      Zope for...

      + + + + +
      + + + + + +
      +
      +

      What You can do on Zope.org

      +

      Membership gives you your own home folder on Zope.org where you can create + and manage your own Zope objects. The objects you create and maintain will + be available to all people who visit Zope.org.

      +

      Site visitors can find your content using the site search or by browsing + your member folder.

      +

      Many pages on the zope.org site are generated by search queries - by + providing metadata such as keywords with your content it can appear in + automated site pages such as product or news listings. more

      +
      + +
      + +

      Zope Training ...

      +
      + + +Send your Zope training announcements to webmaster at zope.org + +
      + +
      + +

      Plone Training ...

      +
      + + +Send your Plone training announcements to webmaster at zope.org + +
      + +
      + + + + +
      ?@ +


      ?g?b?v?@?b?@?X?^?W?I?@?b?@?l?R???????@?b?@?I?[?i?[???F?????? +?@?b?@?t?@???????h

      +

      OMRON + Corporation

      +
      + + + + + Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/necoro/necoro.theme ============================================================================== --- /z3/deliverance/branches/packaged/deliverance/test-data/necoro/necoro.theme Mon Oct 30 22:58:02 2006 +++ (empty file) @@ -1,7 +0,0 @@ - - - - Modified: z3/deliverance/branches/packaged/deliverance/test-data/necoro/necoro.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/necoro/necoro.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/necoro.xml Mon Oct 30 22:58:02 2006 @@ -3,5 +3,5 @@ - + Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/necoro/openplans.html ============================================================================== --- /z3/deliverance/branches/packaged/deliverance/test-data/necoro/openplans.html Mon Oct 30 22:58:02 2006 +++ (empty file) @@ -1,648 +0,0 @@ - - - - - - - - - - - - - - - - NYCSR - — - OpenPlans - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
      -
      - Skip to content - - Skip to navigation - -
      - - - -

      - OpenPlans -

      - - - - - - - - - -
      -
      -
      - -
      - - - -
      - -
      -
      - - -
      - - - - -
      - -
      - -
      -
      - - - - - - - - - - - - - - - - - - -
      - - -
      - - - - -
      Views
      - - - - - -
      - - - - - - - - - - - -
      - - -
      - - - - - - - - - - -
      - - -
      Document Actions
      - - - - - - -
      - -

      NYCSR

      - -
      - -
      - - - - - - last modified - - - 2006-09-15 11:18 - - - - - - - - - -
      - -
      - -
      - -
      - - - - - -
      -

      Welcome to the NYC Streets Renaissance Campaign Headquarters

      The goal of the NYCSR is to tranform New York City streets so that they are safer, more productive and more livable.

      Streets can be places for neighbors to meet

      New York City is defined by its vibrant and diverse streets and neighborhoods. Unfortunately, our neighborhoods and business districts are buckling under increasing amounts of dangerous car and truck traffic. Children can no longer - - - - - - - play on their own blocks - - - - - - - - -, while parents worry about turning cars smashing into baby carriages. Senior citizens are losing their independence, shut up in their homes for fear of crossing the street. And shoppers and investors are being turned away by chaotic, traffic-choked avenues.

      This is unacceptable. The time is long overdue for our great city to strike a better balance between traffic and the needs of pedestrians.

      The NYC Streets Renaissance Campaign aims to:

      • Educate New Yorkers about potential transportation policy changes that will improve quality of life across New York City
      • Promote a rebalancing of this public space away from private vehicles and toward community needs
      • Demonstrate the widespread public support for reform on these issues
      • Tap the potential of New Yorkers to re-imagine their own streets

      Our Initiatives:

      • Help neighborhood leaders in the fight for long overdue, common sense improvements to their neighborhood streets

      To get involved, add your ideas for making New York City a better place to live and work to our Taking it Citywide - - - - - - - Neighborhoods - - - - - - - - - page, or visit us at http://www.nycsr.org/involved.php

      old landing page


      Together, we can re-imagine the streets of New York City.

      - - - -
      - -
      - - - - - - - -
      - - - - - -
      - - - - - -
      - - - - - - - -
      - - -
      - -
      - - -
      - -
      -
      - -
      - - - - - Added: z3/deliverance/branches/packaged/deliverance/test-data/necoro/out.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/out.html Mon Oct 30 22:58:02 2006 @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + Zope.org + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + +
      Photo studioomron
      +
      +

      Welcome to Zope.org

      + +
      The Web Site for the Zope Community
      + +

      Zope is an open source application server for building + content management systems, intranets, portals, and custom + applications. The Zope community consists of hundreds of + companies and thousands of developers all over the world, + working on building the platform and Zope applications. Zope is + written in Python, a highly-productive, object-oriented + scripting language. more

      + + + + +

      Zope for...

      + + + + +
      + + + + + +
      +
      +

      What You can do on Zope.org

      +

      Membership gives you your own home folder on Zope.org where you can create + and manage your own Zope objects. The objects you create and maintain will + be available to all people who visit Zope.org.

      +

      Site visitors can find your content using the site search or by browsing + your member folder.

      +

      Many pages on the zope.org site are generated by search queries - by + providing metadata such as keywords with your content it can appear in + automated site pages such as product or news listings. more

      +
      + +
      + +

      Zope Training ...

      +
      + + +Send your Zope training announcements to webmaster at zope.org + +
      + +
      + +

      Plone Training ...

      +
      + + +Send your Plone training announcements to webmaster at zope.org + +
      + +
      + + + + +
      ??? +


      ?????????????????????????????????????????????????????????????????????????????????????????? +???????????????????????????

      +

      OMRON + Corporation

      +
      + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/necoro/out.html~ ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/out.html~ Mon Oct 30 22:58:02 2006 @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + Zope.org + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + +
      Photo studioomron
      +
      + +

      Welcome to Zope.org

      + +
      The Web Site for the Zope Community
      + +

      Zope is an open source application server for building + content management systems, intranets, portals, and custom + applications. The Zope community consists of hundreds of + companies and thousands of developers all over the world, + working on building the platform and Zope applications. Zope is + written in Python, a highly-productive, object-oriented + scripting language. more

      + + + + +

      Zope for...

      + + + + +
      + + + + + +
      +
      +

      What You can do on Zope.org

      +

      Membership gives you your own home folder on Zope.org where you can create + and manage your own Zope objects. The objects you create and maintain will + be available to all people who visit Zope.org.

      +

      Site visitors can find your content using the site search or by browsing + your member folder.

      +

      Many pages on the zope.org site are generated by search queries - by + providing metadata such as keywords with your content it can appear in + automated site pages such as product or news listings. more

      +
      + +
      + +

      Zope Training ...

      +
      + + +Send your Zope training announcements to webmaster at zope.org + +
      + +
      + +

      Plone Training ...

      +
      + + +Send your Plone training announcements to webmaster at zope.org + +
      + +
      + + + + +
      ??? +


      ?????????????????????????????????????????????????????????????????????????????????????????? +???????????????????????????

      +

      OMRON + Corporation

      +
      + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/necoro/zope.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/zope.html Mon Oct 30 22:58:02 2006 @@ -0,0 +1,751 @@ + + + + + + + + + + Zope.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      + + + + + + +
      + +
      + +
      + + +
      + +
        + + + + You are not logged in + + + + + + Log in + + + + + + + Join + + +
      + +
      + + + You are here: + + + + Home + + + +
      + +
      + +
      + + + + + + + + + + + + +
      + + +
      +
      + + + + + + + +
      +
      + + + + + + + +
      + +
      Log in
      + +
      + +
      +
      + + + Name
      + + +
      + + Password
      + + +
      +   +
      + + + + + +
      + +
      + + + + + +
      + +
      + + + + + +
      + + + +
      + +
      + + + + + + + + + + +
      + + + + + + + Print + +
      + + + +
      + + + + + + +
      +

      Welcome to Zope.org

      + +
      The Web Site for the Zope Community
      + +

      Zope is an open source application server for building + content management systems, intranets, portals, and custom + applications. The Zope community consists of hundreds of + companies and thousands of developers all over the world, + working on building the platform and Zope applications. Zope is + written in Python, a highly-productive, object-oriented + scripting language. more

      + + + + +

      Zope for...

      + + + + + + +
      + + + + + +
      + +
      +

      What You can do on Zope.org

      +

      Membership gives you your own home folder on Zope.org where you can create + and manage your own Zope objects. The objects you create and maintain will + be available to all people who visit Zope.org.

      +

      Site visitors can find your content using the site search or by browsing + your member folder.

      +

      Many pages on the zope.org site are generated by search queries - by + providing metadata such as keywords with your content it can appear in + automated site pages such as product or news listings. more

      +
      + +
      + +

      Zope Training ...

      +
      + + + + +Send your Zope training announcements to webmaster at zope.org + +
      + +
      + +

      Plone Training ...

      +
      + + +Send your Plone training announcements to webmaster at zope.org + +
      + +
      +
      + +
      + +
      Planets
      +
      +
      + + Planet Zope +
      Zope related news + + RSS Newsfeed +
      +
      +
      + + Planet Plone +
      Plone related news + + RSS Newsfeed +
      +
      +
      +
      + +
      + +
      News + + + RSS Newsfeed +
      +
      + +
      + ZopeDictDB 0.1 + + ZopeDictDB 0.1 + +
      October 30
      + +
      + + +
      + Russian Zope3 Maillist + + Russian Zope3 Maillist + +
      October 26
      + +
      + + + + + +
      + ZInformixDA 0.3 released + + ZInformixDA 0.3 released + +
      October 16
      + +
      + + + + +
      +
      +
      + +
      Products + + Products RSS
      +
      + + + + + + + +
      + ZopeEditArea 0.1 + + (0.1) + +
      October 08
      + +
      + + +
      + 2.10.0 + + Zope (2_10_0-final) + +
      October 03
      + +
      + + +
      + 3.2.2 + + Zope 3 (3.2.2) + +
      October 02
      + +
      + +
      +
      +
      + +
      +
      + + +
      + +
      + +
      +
      +
      + +
      + + + + + + + + Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Mon Oct 30 22:58:02 2006 @@ -10,10 +10,14 @@ static_data = os.path.join(os.path.dirname(__file__), 'test-data', 'static') tasktracker_data = os.path.join(os.path.dirname(__file__), 'test-data', 'tasktracker') nycsr_data = os.path.join(os.path.dirname(__file__), 'test-data', 'nycsr') +necoro_data = os.path.join(os.path.dirname(__file__), 'test-data', 'necoro') +guidesearch_data = os.path.join(os.path.dirname(__file__), 'test-data', 'guidesearch') static_app = StaticURLParser(static_data) tasktracker_app = StaticURLParser(tasktracker_data) nycsr_app = StaticURLParser(nycsr_data) +necoro_app = StaticURLParser(necoro_data) +guidesearch_app = StaticURLParser(guidesearch_data) def html_string_compare(astr, bstr): @@ -85,8 +89,23 @@ html_string_compare(res.body, res2.body) +def do_necoro(renderer_type): + wsgi_app = DeliveranceMiddleware(necoro_app, 'http://www.necoro.com/photo/index.html','necoro.xml', renderer_type) + app = TestApp(wsgi_app) + res = app.get('/zope.html') + res2 = app.get('/expected.html?notheme') + html_string_compare(res.body, res2.body) + +def do_guidesearch(renderer_type): + wsgi_app = DeliveranceMiddleware(guidesearch_app, 'http://www.guidesearch.jp/index.php?language=schinese','guidesearch.xml', renderer_type) + app = TestApp(wsgi_app) + res = app.get('/zope.html') + res2 = app.get('/expected.html?notheme') + html_string_compare(res.body, res2.body) + + RENDERER_TYPES = ['py','xslt'] -TEST_FUNCS = [ do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr ] +TEST_FUNCS = [ do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr, do_necoro, do_guidesearch ] def test_all(): for renderer_type in RENDERER_TYPES: for test_func in TEST_FUNCS: From cabraham at codespeak.net Tue Oct 31 17:56:11 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Tue, 31 Oct 2006 17:56:11 +0100 (CET) Subject: [z3-checkins] r33970 - in z3/deliverance/branches/packaged/deliverance: . test-data/guidesearch test-data/necoro Message-ID: <20061031165611.DB3EF10076@code0.codespeak.net> Author: cabraham Date: Tue Oct 31 17:56:07 2006 New Revision: 33970 Added: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/theme.html z3/deliverance/branches/packaged/deliverance/test-data/necoro/theme.html Modified: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/expected.html z3/deliverance/branches/packaged/deliverance/test-data/necoro/expected.html z3/deliverance/branches/packaged/deliverance/test_wsgi.py Log: fixed up tests for foreign character encodings Modified: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/expected.html ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/expected.html (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/expected.html Tue Oct 31 17:56:07 2006 @@ -18,7 +18,7 @@ function restChar(txtarea,maxlength) { len = txtarea.value.length; - if(len > maxlength) alert("max length "+maxlength+" ---------"); + if(len > maxlength) alert("max length "+maxlength+" ........."); txtarea.innerText = txtarea.value.substring(0, maxlength); } @@ -39,7 +39,7 @@ ?????????????????????????????????????????????????????????????????????????????????????????????????????????
      ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

      @@ -53,8 +53,8 @@
      Added: z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/theme.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/guidesearch/theme.html Tue Oct 31 17:56:07 2006 @@ -0,0 +1,58 @@ + + + + + + + + +???????????????????? + + + +
      +
      +

      ????????????????????

      +
      +

      ????????????????????????1949????????210??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
      +??????????????????????????????????????????????????????????????????????
      ????????????????????????????????????????????????????????????????????????????????????????

      + +
      +
      +
      + + +
      +
      + +
      +
      + +
      Special URL
      Admin URLAdmin
      User URLUser
      +
      Powered by GUIDE 0.5.0 © 2006 The Guide-Interpreter Search System +
      + + Modified: z3/deliverance/branches/packaged/deliverance/test-data/necoro/expected.html ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/necoro/expected.html (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/necoro/expected.html Tue Oct 31 17:56:07 2006 @@ -33,9 +33,9 @@ //--> - + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + + + +
      Photo studioomron
      +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +


      + Flash?????????????????????A
      + Flash Plugin(ver.5????)???K?v?????B

      +

      + + + + + + + + +
      +
      +

      ?@

      +
      +
      + + + + + + + +
      ?@ +


      +?g?b?v?@?b?@?X?^?W?I?@?b?@?l?R???????@?b?@?I?[?i?[???F?????? +?@?b?@?t?@???????h

      +

      OMRON + Corporation

      +
      + Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Tue Oct 31 17:56:07 2006 @@ -90,14 +90,14 @@ def do_necoro(renderer_type, name): - wsgi_app = DeliveranceMiddleware(necoro_app, 'http://www.necoro.com/photo/index.html','necoro.xml', renderer_type) + wsgi_app = DeliveranceMiddleware(necoro_app, 'theme.html','necoro.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/zope.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) def do_guidesearch(renderer_type, name): - wsgi_app = DeliveranceMiddleware(guidesearch_app, 'http://www.guidesearch.jp/index.php?language=schinese','guidesearch.xml', renderer_type) + wsgi_app = DeliveranceMiddleware(guidesearch_app, 'theme.html','guidesearch.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/zope.html') res2 = app.get('/expected.html?notheme') From ltucker at codespeak.net Tue Oct 31 20:43:42 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Tue, 31 Oct 2006 20:43:42 +0100 (CET) Subject: [z3-checkins] r33986 - in z3/deliverance/branches/packaged/deliverance: . test-data Message-ID: <20061031194342.494221005A@code0.codespeak.net> Author: ltucker Date: Tue Oct 31 20:43:38 2006 New Revision: 33986 Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml z3/deliverance/branches/packaged/deliverance/utils.py z3/deliverance/branches/packaged/deliverance/xslt.py Log: Drop rules now apply first. Added support for content dropping to xslt renderer. Content dropping happens in as a separate transform of the content. We should look at folding this into the normal transform if possible Modified: z3/deliverance/branches/packaged/deliverance/interpreter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/interpreter.py (original) +++ z3/deliverance/branches/packaged/deliverance/interpreter.py Tue Oct 31 20:43:38 2006 @@ -37,7 +37,14 @@ def apply_rules(self, rules, theme, content): - for rule in rules: + + drop_rules, other_rules = self.separate_drop_rules(rules) + + # process all drop rules first + for rule in drop_rules: + self.apply_rule(rule, theme, content) + + for rule in other_rules: self.apply_rule(rule, theme, content) @@ -361,7 +368,7 @@ removed = True if not removed and rule.attrib.get(self.NOCONTENT_KEY) != 'ignore': self.add_to_body_start( - theme, self.format_error("no element found in %s" % context, rule)) + theme, self.format_error("no %s matched" % context, rule)) def elements_in(self, els): """ Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_drop.xml Tue Oct 31 20:43:38 2006 @@ -136,7 +136,7 @@ Dummy Content -
      Deliverance error: no element found in theme
      rule: <drop theme="//div[@id='foo']"/> +
      Deliverance error: no theme matched
      rule: <drop theme="//div[@id='foo']"/>
      @@ -161,7 +161,7 @@ Dummy Content -
      Deliverance error: no element found in content
      rule: <drop content="//div[@id='foo']"/> +
      Deliverance error: no content matched
      rule: <drop content="//div[@id='foo']"/>
      Modified: z3/deliverance/branches/packaged/deliverance/utils.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/utils.py (original) +++ z3/deliverance/branches/packaged/deliverance/utils.py Tue Oct 31 20:43:38 2006 @@ -181,6 +181,24 @@ for el in elts: el.attrib[attr] = urlparse.urljoin(base_uri, el.attrib[attr]) + def separate_drop_rules(self, rules): + """ + separates out drop rules from a list of rules, returns two + lists. + + first the list of all drop rules, second all other rules + order is preserved. + """ + regular_rules = [] + drop_rules = [] + for rule in rules: + if rule.tag == self.DROP_RULE_TAG: + drop_rules.append(rule) + else: + regular_rules.append(rule) + return drop_rules, regular_rules + + CSS_URL_PAT = re.compile(r'url\([\"\']*(.*?)[\"\']*\)',re.I) CSS_IMPORT_PAT = re.compile(r'\@import\s*[\"\'](.*?)[\"\']',re.I) Modified: z3/deliverance/branches/packaged/deliverance/xslt.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/xslt.py (original) +++ z3/deliverance/branches/packaged/deliverance/xslt.py Tue Oct 31 20:43:38 2006 @@ -14,6 +14,19 @@ """ +xslt_dropper_skel = """ + + + + + + + + + + + +""" nsmap = { "dv": "http://www.plone.org/deliverance", @@ -45,7 +58,9 @@ else: self.debug = False + self.transform_drop = None self.apply_rules(self.rules,theme_copy) + xslt_wrapper = etree.XML(xslt_wrapper_skel) insertion_point = xslt_wrapper.xpath("//xsl:transform/xsl:template[@match='/']", nsmap)[0] @@ -57,15 +72,29 @@ def render(self,content): if content: + if self.transform_drop: + content = self.transform_drop(content) + return self.transform(content).getroot() + else: return self.transform(etree.Element("dummy")).getroot() def apply_rules(self,rules,theme): - for rule in rules: + + drop_rules, other_rules = self.separate_drop_rules(rules) + + if len(drop_rules): + self.xslt_dropper = etree.XML(xslt_dropper_skel) + for rule in drop_rules: + self.apply_drop(rule, theme) + self.transform_drop = etree.XSLT(self.xslt_dropper) + + for rule in other_rules: self.apply_rule(rule,theme) + def apply_rule(self,rule,theme): if rule.tag == self.APPEND_RULE_TAG: self.apply_append(rule,theme) @@ -214,7 +243,7 @@ if rule.get(self.NOCONTENT_KEY) == 'ignore': return else: - e = self.format_error("no element found in theme", rule) + e = self.format_error("no theme matched", rule) self.add_to_body_start(theme, e) return @@ -223,23 +252,16 @@ self.attach_text_to_previous(el, el.tail) el.getparent().remove(el) + if self.RULE_CONTENT_KEY in rule.attrib: + drop_template = etree.Element("{%s}template" % nsmap["xsl"]) + drop_template.set("match", rule.attrib[self.RULE_CONTENT_KEY]) + self.xslt_dropper[0:0] = [drop_template] + + # add an element that produces an error if + # no content is matched + self.add_conditional_missing_content_error(theme,rule) -# if 'content' in rule.attrib: -# self.add_conditional_missing_content_error(theme,rule) - - - -# copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) -# copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) - - -# # if content is matched, replace the theme element, otherwise, keep the -# # theme element -# choose = self.make_when_otherwise("count(%s)=0" % -# rule.attrib[self.RULE_CONTENT_KEY], -# copy.deepcopy(theme_el), -# copier) From cabraham at codespeak.net Tue Oct 31 23:50:03 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Tue, 31 Oct 2006 23:50:03 +0100 (CET) Subject: [z3-checkins] r33987 - z3/deliverance/branches/packaged/deliverance/test-data Message-ID: <20061031225003.6A76A1005A@code0.codespeak.net> Author: cabraham Date: Tue Oct 31 23:49:59 2006 New Revision: 33987 Added: z3/deliverance/branches/packaged/deliverance/test-data/test_ajax.xml Log: added AJAX test Added: z3/deliverance/branches/packaged/deliverance/test-data/test_ajax.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_ajax.xml Tue Oct 31 23:49:59 2006 @@ -0,0 +1,26 @@ + + + + + + + + + + + Blah
      Dummy Content
      +
      + + +
      Real Content
      12

      zzz

      3
      +
      + + +
      Real Content
      12

      zzz

      3
      +
      +
      + + + +
      From cabraham at codespeak.net Wed Nov 1 00:08:16 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Wed, 1 Nov 2006 00:08:16 +0100 (CET) Subject: [z3-checkins] r33988 - in z3/deliverance/branches/packaged/deliverance: . test-data test-data/ajax Message-ID: <20061031230816.DCB771005A@code0.codespeak.net> Author: cabraham Date: Wed Nov 1 00:08:12 2006 New Revision: 33988 Added: z3/deliverance/branches/packaged/deliverance/test-data/ajax/ z3/deliverance/branches/packaged/deliverance/test-data/ajax/content.html z3/deliverance/branches/packaged/deliverance/test-data/ajax/rules.xml z3/deliverance/branches/packaged/deliverance/test-data/ajax/theme.html Removed: z3/deliverance/branches/packaged/deliverance/test-data/test_ajax.xml Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py Log: made ajax test wsgi Added: z3/deliverance/branches/packaged/deliverance/test-data/ajax/content.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/ajax/content.html Wed Nov 1 00:08:12 2006 @@ -0,0 +1 @@ +
      Real Content
      12

      zzz

      3
      Added: z3/deliverance/branches/packaged/deliverance/test-data/ajax/rules.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/ajax/rules.xml Wed Nov 1 00:08:12 2006 @@ -0,0 +1 @@ + Added: z3/deliverance/branches/packaged/deliverance/test-data/ajax/theme.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/ajax/theme.html Wed Nov 1 00:08:12 2006 @@ -0,0 +1 @@ +Blah
      Dummy Content
      Deleted: /z3/deliverance/branches/packaged/deliverance/test-data/test_ajax.xml ============================================================================== --- /z3/deliverance/branches/packaged/deliverance/test-data/test_ajax.xml Wed Nov 1 00:08:12 2006 +++ (empty file) @@ -1,26 +0,0 @@ - - - - - - - - - - - Blah
      Dummy Content
      -
      - - -
      Real Content
      12

      zzz

      3
      -
      - - -
      Real Content
      12

      zzz

      3
      -
      -
      - - - -
      Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Wed Nov 1 00:08:12 2006 @@ -12,12 +12,14 @@ nycsr_data = os.path.join(os.path.dirname(__file__), 'test-data', 'nycsr') necoro_data = os.path.join(os.path.dirname(__file__), 'test-data', 'necoro') guidesearch_data = os.path.join(os.path.dirname(__file__), 'test-data', 'guidesearch') +ajax_data = os.path.join(os.path.dirname(__file__), 'test-data', 'ajax') static_app = StaticURLParser(static_data) tasktracker_app = StaticURLParser(tasktracker_data) nycsr_app = StaticURLParser(nycsr_data) necoro_app = StaticURLParser(necoro_data) guidesearch_app = StaticURLParser(guidesearch_data) +ajax_app = StaticURLParser(ajax_data) def html_string_compare(astr, bstr): @@ -103,6 +105,13 @@ res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) +def do_ajax(renderer_type, name): + wsgi_app = DeliveranceMiddleware(ajax_app, 'theme.html','rules.xml', renderer_type) + app = TestApp(wsgi_app) + res = app.get('/content.html') + res2 = app.get('/content.html?notheme') + html_string_compare(res.body, res2.body) + RENDERER_TYPES = ['py', 'xslt'] TEST_FUNCS = [ do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr, do_necoro, do_guidesearch ] From ltucker at codespeak.net Wed Nov 1 00:17:30 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 1 Nov 2006 00:17:30 +0100 (CET) Subject: [z3-checkins] r33989 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061031231730.687CC1005A@code0.codespeak.net> Author: ltucker Date: Wed Nov 1 00:17:28 2006 New Revision: 33989 Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py z3/deliverance/branches/packaged/deliverance/wsgifilter.py Log: preliminary heuristic to ignore ajax responses in the wsgifilter Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Wed Nov 1 00:17:28 2006 @@ -114,7 +114,7 @@ RENDERER_TYPES = ['py', 'xslt'] -TEST_FUNCS = [ do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr, do_necoro, do_guidesearch ] +TEST_FUNCS = [ do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr, do_necoro, do_guidesearch, do_ajax ] def test_all(): for renderer_type in RENDERER_TYPES: for test_func in TEST_FUNCS: Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/wsgifilter.py (original) +++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py Wed Nov 1 00:17:28 2006 @@ -133,12 +133,14 @@ self.should_intercept, start_response) - + # ignore non-html responses if status is None: - # should_intercept returned False return body - body = self.filter_body(environ, body) + # don't theme html snippets + if self.hasHTMLTag(body): + body = self.filter_body(environ, body) + replace_header(headers, 'content-length', str(len(body))) replace_header(headers, 'content-type', 'text/html; charset=utf-8') start_response(status, headers) @@ -212,6 +214,16 @@ loc)) return body + HTML_DOC_PAT = re.compile(r"^.*<\s*html(\s*|>).*$",re.I|re.M) + def hasHTMLTag(self, body): + """ + a quick and dirty check to see if some text contains + anything that looks like an html tag. This could + certainly be improved if needed or there are + ambiguous tags + """ + return self.HTML_DOC_PAT.search(body) is not None + def make_filter(app, global_conf, theme_uri=None, rule_uri=None): assert theme_uri is not None, ( From ltucker at codespeak.net Wed Nov 1 23:08:56 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 1 Nov 2006 23:08:56 +0100 (CET) Subject: [z3-checkins] r34049 - z3/deliverance/branches/packaged Message-ID: <20061101220856.AE04C1006E@code0.codespeak.net> Author: ltucker Date: Wed Nov 1 23:08:52 2006 New Revision: 34049 Modified: z3/deliverance/branches/packaged/README.txt Log: updating and fleshing out the current README Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Wed Nov 1 23:08:52 2006 @@ -1,15 +1,39 @@ -See: http://www.openplans.org/projects/deliverance/specification + +See: http://www.openplans.org/projects/deliverance for more information -Quick Start to run tests -------------------------- -The easiest way to get started is to check out the buildout: +Contents: +* What's Deliverance? +* Quick Start to build deliverance +* Deliverance Proxy +* WSGI Middleware +* Command Line Transformations +* Simple Tests +* WSGI Tests +* Quick Example + +---------------------------------- +What's Deliverance? +---------------------------------- + +Deliverance is a non-invasive mechanism for combining HTML content produced +by other systems and normal web pages that typify a desired look and feel +(themes) using a set of rules. This approach allows the "branding" aspects +of a design to remain separate from content production, allows designers to +avoid using and mixing in particular template syntaxes and allows reuse of +existing static designs. + + +----------------------------------- +Quick Start to build deliverance +----------------------------------- -svn co https://svn.openplans.org/svn/deliverance.buildout deliverance.buildout +The easiest way to get started is to checkout the buildout and follow the instructions +found there. -If you follow the instructions there. +svn co https://svn.openplans.org/svn/deliverance.buildout deliverance.buildout Otherwise to install manually: @@ -38,8 +62,63 @@ from the top level checkout directory +---------------------------------------------- +Deliverance Proxy +---------------------------------------------- + +The deliverance proxy is a standalone application which serves a "themed" version of some web +location given a theme page and a set of rules. + +eg: + +deliverance-proxy --serve=localhost:5001 --proxy=localhost:8080 + --theme=http://www.example.org + --rule=file:///some/path/somerulesfile.xml + +provides a themed version of a local webserver at port 8080 served on port 5001. +The theme page is http://www.example.org and somerulesfile.xml describes how to +put the content from localhost:8080 together with the look of the webpage at +http://www.example.org to produce the "themed" result. + +run deliverance-proxy --help for more options + +------------------------------------------------ +WSGI Middleware +------------------------------------------------ + +Deliverance theming can also used directly in a WSGI stack using +deliverance.wsgifilter.DeliveranceMiddleware + +see deliverance/wsgifilter.py and deliverance/test_wsgi.py for examples. + + +------------------------------------------------- +Command Line Transformations +------------------------------------------------- + +a command line transformation may also be performed using the +handtransform.py script. + +run python handtransform.py --help for instructions. The result of the +transform is output to standard out. + +To avoid lengthy command lines, the script can accept a file which describes +the theme and rules to apply using the -f flag eg: + +python handtransform.py -f ./example.theme http://www.example.org + + +The second argument refers to the content and example.theme contains something like: + + + + +------------------------------------------------ Simple Tests ------------- +------------------------------------------------ There are a number of tests in the test-data directory that follow the form: @@ -67,34 +146,95 @@ - +---------------------------------------------- WSGI Tests ----------- +---------------------------------------------- test_wsgi.py contains tests which take the theme and content from the web and local pages found under test-data. -Hand Transform --------------- +---------------------------------------------- +Quick Example +---------------------------------------------- + +Deliverance combines a content web page with a theme web page, containing no special markup, +according to a set of rules. Example: + + +This is an unstyled page produced by myBoringTodoList.com/deliverance_user/: +this page is the content page: + + + + my boring todo page + + +
      +

      Things To Do

      +
        +
      • Feed the cat
      • +
      • Wash the dishes
      • +
      +
      + + -a hand test may also be performed using the handtransform.py script -run python handtransform.py --help for instructions. The result of the -transform is output to standard out. - -To avoid lengthy command lines, the script can accept a file which describes -the theme and rules to apply using the -f flag eg: -python handtransform.py -f test-data/nycsr/nycsr.theme ./test-data/nycsr/openplans.html -where nycsr.theme contains something like: - - - -and the second argument points to the content +Here is another web page that typifies how we'd like to see the todo list +at excitingHomePage.com/deliverance_user/. +this page is the theme: + + + + + my exciting home page + + +

      Deliverance User's Exciting Page

      +
      + I wish my todo list looked this cool +
      + + + +Here are some deliverance rules that put the todo list into the +exciting home page and take away the wish. This tells deliverance +to replace the "wishes" div in the exciting home page with the +"todo" div in the content page. + + + + + +Here is the output: + + + + + + my exciting home page + + +

      Deliverance User's Exciting Page

      +
      +

      Things To Do

      +
        +
      • Feed the cat
      • +
      • Wash the dishes
      • +
          +
      + + +see http://www.openplans.org/projects/deliverance for more information. +There are many other examples in deliverance/test-data From ltucker at codespeak.net Thu Nov 2 00:30:08 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 2 Nov 2006 00:30:08 +0100 (CET) Subject: [z3-checkins] r34052 - in z3/deliverance/branches/packaged/deliverance: . test-data test-data/wsgiurl test-data/wsgiurl/foo test-data/wsgiurl/foo/bar Message-ID: <20061101233008.E589E1006E@code0.codespeak.net> Author: ltucker Date: Thu Nov 2 00:30:05 2006 New Revision: 34052 Added: z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/ z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/ z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/ z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url.xml z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_content.html z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_expected.html z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_theme.html Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml z3/deliverance/branches/packaged/deliverance/test_wsgi.py Log: more url tests Modified: z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml (original) +++ z3/deliverance/branches/packaged/deliverance/test-data/test_url.xml Thu Nov 2 00:30:05 2006 @@ -1,6 +1,41 @@ + + + + + + + + + + + zoop + + + + + + + + + + + + + + zoop + + + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url.xml ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url.xml Thu Nov 2 00:30:05 2006 @@ -0,0 +1,2 @@ + + Added: z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_content.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_content.html Thu Nov 2 00:30:05 2006 @@ -0,0 +1,4 @@ + + + + Added: z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_expected.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_expected.html Thu Nov 2 00:30:05 2006 @@ -0,0 +1,11 @@ + + + + + + + zoop + + Added: z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_theme.html ============================================================================== --- (empty file) +++ z3/deliverance/branches/packaged/deliverance/test-data/wsgiurl/foo/bar/test_url_theme.html Thu Nov 2 00:30:05 2006 @@ -0,0 +1,10 @@ + + + + + + zoop + + Modified: z3/deliverance/branches/packaged/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/test_wsgi.py (original) +++ z3/deliverance/branches/packaged/deliverance/test_wsgi.py Thu Nov 2 00:30:05 2006 @@ -13,6 +13,7 @@ necoro_data = os.path.join(os.path.dirname(__file__), 'test-data', 'necoro') guidesearch_data = os.path.join(os.path.dirname(__file__), 'test-data', 'guidesearch') ajax_data = os.path.join(os.path.dirname(__file__), 'test-data', 'ajax') +url_data = os.path.join(os.path.dirname(__file__), 'test-data', 'wsgiurl') static_app = StaticURLParser(static_data) tasktracker_app = StaticURLParser(tasktracker_data) @@ -20,6 +21,7 @@ necoro_app = StaticURLParser(necoro_data) guidesearch_app = StaticURLParser(guidesearch_data) ajax_app = StaticURLParser(ajax_data) +url_app = StaticURLParser(url_data) def html_string_compare(astr, bstr): @@ -112,9 +114,16 @@ res2 = app.get('/content.html?notheme') html_string_compare(res.body, res2.body) +def do_url(renderer_type, name): + wsgi_app = DeliveranceMiddleware(url_app, '/foo/bar/test_url_theme.html','/foo/bar/test_url.xml', renderer_type) + app = TestApp(wsgi_app) + res = app.get('/foo/bar/test_url_content.html') + res2 = app.get('/foo/bar/test_url_expected.html?notheme') + html_string_compare(res.body,res2.body) + RENDERER_TYPES = ['py', 'xslt'] -TEST_FUNCS = [ do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr, do_necoro, do_guidesearch, do_ajax ] +TEST_FUNCS = [ do_url, do_basic, do_text, do_tasktracker, do_xinclude, do_nycsr, do_necoro, do_guidesearch, do_ajax ] def test_all(): for renderer_type in RENDERER_TYPES: for test_func in TEST_FUNCS: From ltucker at codespeak.net Thu Nov 2 17:43:08 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Thu, 2 Nov 2006 17:43:08 +0100 (CET) Subject: [z3-checkins] r34066 - z3/deliverance/branches/packaged/deliverance Message-ID: <20061102164308.33B2B1006E@code0.codespeak.net> Author: ltucker Date: Thu Nov 2 17:43:06 2006 New Revision: 34066 Modified: z3/deliverance/branches/packaged/deliverance/fixuplinks.py Log: fix reference to CSS_URL_PAT in fixup_css_links, referred to non-existent self Modified: z3/deliverance/branches/packaged/deliverance/fixuplinks.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/fixuplinks.py (original) +++ z3/deliverance/branches/packaged/deliverance/fixuplinks.py Thu Nov 2 17:43:06 2006 @@ -42,5 +42,5 @@ els = doc.xpath('//head/style') for el in els: if el.text: - el.text = re.sub(self.CSS_URL_PAT,absuri,el.text) + el.text = re.sub(CSS_URL_PAT,absuri,el.text) From cabraham at codespeak.net Thu Nov 2 17:46:21 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Thu, 2 Nov 2006 17:46:21 +0100 (CET) Subject: [z3-checkins] r34067 - in z3/deliverance/branches/packaged: . deliverance Message-ID: <20061102164621.B77B21006E@code0.codespeak.net> Author: cabraham Date: Thu Nov 2 17:46:18 2006 New Revision: 34067 Modified: z3/deliverance/branches/packaged/README.txt z3/deliverance/branches/packaged/deliverance/handtransform.py z3/deliverance/branches/packaged/setup.py Log: made handtransform into an executable, installed in setup.py Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Thu Nov 2 17:46:18 2006 @@ -43,8 +43,8 @@ Create a working enviornment for deliverance and its dependencies: -workingenv.py deliverance_env -source deliverance_env/bin/activate +$ workingenv.py deliverance_env +$ source deliverance_env/bin/activate install a recent cvs version of libxml2,libxstl and svn lxml. You are likely to encounter segfaults and other failures if recent versions are not used. Modified: z3/deliverance/branches/packaged/deliverance/handtransform.py ============================================================================== --- z3/deliverance/branches/packaged/deliverance/handtransform.py (original) +++ z3/deliverance/branches/packaged/deliverance/handtransform.py Thu Nov 2 17:46:18 2006 @@ -24,6 +24,20 @@ DEFAULT_BASE_URL = "http://www.example.com" +usage = "usage: %prog [options] " +parser = OptionParser(usage=usage) +parser.add_option("-t","--theme",dest="theme_url",help="url of theme html") +parser.add_option("-b","--baseurl",dest="base_url", + help="relative urls in the theme will be made absolute relative to this url [default %default]", + default=DEFAULT_BASE_URL) +parser.add_option("-r","--rules",dest="rules_file", + help="path to file containing the deliverance rules to apply") +parser.add_option("-f","--from-file",dest="blend_file", + help="take theme, baseurl and rules parameters from the referenced file") +parser.add_option("-R","--renderer",dest="renderer_type", + help="(xslt|py) [default %default]", default="xslt", choices=['xslt','py']) + + def grab_url(url): f = urllib.urlopen(url) @@ -65,23 +79,11 @@ parser.print_usage() sys.exit(0) -if __name__ == '__main__': - +def main(args=None): + if args is None: + args = sys.argv[1:] - usage = "usage: %prog [options] " - parser = OptionParser(usage=usage) - parser.add_option("-t","--theme",dest="theme_url",help="url of theme html") - parser.add_option("-b","--baseurl",dest="base_url", - help="relative urls in the theme will be made absolute relative to this url [default %default]", - default=DEFAULT_BASE_URL) - parser.add_option("-r","--rules",dest="rules_file", - help="path to file containing the deliverance rules to apply") - parser.add_option("-f","--from-file",dest="blend_file", - help="take theme, baseurl and rules parameters from the referenced file") - parser.add_option("-R","--renderer",dest="renderer_type", - help="(xslt|py) [default %default]", default="xslt", choices=['xslt','py']) - - (options,args) = parser.parse_args() + options,args = parser.parse_args(args) if len(args) == 0: die("no content url specified.",parser) @@ -120,3 +122,6 @@ print tostring(do_transform(options.renderer_type,theme_url,base_url,rules_file,content_url)) + +if __name__ == '__main__': + main() Modified: z3/deliverance/branches/packaged/setup.py ============================================================================== --- z3/deliverance/branches/packaged/setup.py (original) +++ z3/deliverance/branches/packaged/setup.py Thu Nov 2 17:46:18 2006 @@ -34,6 +34,7 @@ deliverance-proxy = deliverance.proxycommand:main deliverance-tests = deliverance.tests:main deliverance-speed = deliverance.test_speed:main + deliverance-handtransform = deliverance.handtransform:main """, ) From cabraham at codespeak.net Thu Nov 2 21:44:51 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Thu, 2 Nov 2006 21:44:51 +0100 (CET) Subject: [z3-checkins] r34077 - z3/deliverance/branches/packaged Message-ID: <20061102204451.4311A10063@code0.codespeak.net> Author: cabraham Date: Thu Nov 2 21:44:49 2006 New Revision: 34077 Modified: z3/deliverance/branches/packaged/README.txt Log: touched up README Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Thu Nov 2 21:44:49 2006 @@ -5,7 +5,7 @@ Contents: -* What's Deliverance? +* What is Deliverance? * Quick Start to build deliverance * Deliverance Proxy * WSGI Middleware @@ -15,7 +15,7 @@ * Quick Example ---------------------------------- -What's Deliverance? +What is Deliverance? ---------------------------------- Deliverance is a non-invasive mechanism for combining HTML content produced @@ -27,95 +27,103 @@ ----------------------------------- -Quick Start to build deliverance +Quick Start to build Deliverance ----------------------------------- -The easiest way to get started is to checkout the buildout and follow the instructions -found there. +The easiest way to get Deliverance installed is to checkout the +buildout and follow the instructions found there. -svn co https://svn.openplans.org/svn/deliverance.buildout deliverance.buildout +$ svn co https://svn.openplans.org/svn/deliverance.buildout deliverance.buildout -Otherwise to install manually: +Otherwise, to install Deliverance manually, first get workingenv.py +from http://cheeseshop.python.org/pypi/workingenv.py. Create a working +environment for Deliverance and its dependencies: -get workingenv.py from -http://cheeseshop.python.org/pypi/workingenv.py - -Create a working enviornment for deliverance and its dependencies: - -$ workingenv.py deliverance_env +$ workingenv.py deliverance_env $ source deliverance_env/bin/activate -install a recent cvs version of libxml2,libxstl and svn lxml. -You are likely to encounter segfaults and other failures if recent versions are not used. -checkout deliverance: -$ svn co http://codespeak.net/svn/z3/deliverance/branches/packaged deliverance - -$ cd deliverance -$ python setup.py develop +Then install recent versions of libxml2, libxslt and lxml. You are +likely to encounter segfaults and other failures if recent versions +are not used. + +Checkout and setup Deliverance, then make sure your installation is +complete by running the tests: + +$ svn co http://codespeak.net/svn/z3/deliverance/branches/packaged deliverance +$ cd deliverance +$ python setup.py develop $ nosetests -you can also run: -deliverance_env/bin/deliverance-tests -deliverance_env/bin/deliverance-speed -from the top level checkout directory +You can also run the tests like this: + +$ deliverance_env/bin/deliverance-tests +$ deliverance_env/bin/deliverance-speed + ---------------------------------------------- Deliverance Proxy ---------------------------------------------- -The deliverance proxy is a standalone application which serves a "themed" version of some web -location given a theme page and a set of rules. +The deliverance proxy is a standalone application which serves a +themed version of some web location using a theme and a set of rules. eg: +$ deliverance-proxy --serve=localhost:5001 --proxy=localhost:8080 + --theme=http://www.example.org + --rule=file:///some/path/somerulesfile.xml + +This example provides a themed version of a local webserver at port +8080 served on port 5001. The theme page is http://www.example.org and +the rules are specified in somerulesfile.xml. + +For more options, run: -deliverance-proxy --serve=localhost:5001 --proxy=localhost:8080 - --theme=http://www.example.org - --rule=file:///some/path/somerulesfile.xml - -provides a themed version of a local webserver at port 8080 served on port 5001. -The theme page is http://www.example.org and somerulesfile.xml describes how to -put the content from localhost:8080 together with the look of the webpage at -http://www.example.org to produce the "themed" result. +$ deliverance-proxy --help -run deliverance-proxy --help for more options ------------------------------------------------ WSGI Middleware ------------------------------------------------ -Deliverance theming can also used directly in a WSGI stack using -deliverance.wsgifilter.DeliveranceMiddleware - -see deliverance/wsgifilter.py and deliverance/test_wsgi.py for examples. +Deliverance can also be used directly in a WSGI stack using the python +class in deliverance.wsgifilter.DeliveranceMiddleware. See +deliverance/wsgifilter.py and deliverance/test_wsgi.py for examples. + ------------------------------------------------- Command Line Transformations ------------------------------------------------- -a command line transformation may also be performed using the -handtransform.py script. -run python handtransform.py --help for instructions. The result of the -transform is output to standard out. +The command line tool used to execute Deliverance is called +deliverance-handtransform. For instructions, run: + +$ deliverance-handtransform --help -To avoid lengthy command lines, the script can accept a file which describes -the theme and rules to apply using the -f flag eg: +The theme, rules and other parameters are specified using command line +options -t, -r, etc. The result of the transform is output to +standard out. -python handtransform.py -f ./example.theme http://www.example.org +To avoid lengthy command lines, the tool can accept a "blend" file, +using the -f flag, which describes the theme and rules to apply. +eg: + +$ deliverance-handtransform -f ./blendfile.xml http://www.example.org -The second argument refers to the content and example.theme contains something like: +The second argument refers to the content; blendfile.xml contains +something like: - + ------------------------------------------------ Simple Tests ------------------------------------------------ From cabraham at codespeak.net Thu Nov 2 22:11:29 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Thu, 2 Nov 2006 22:11:29 +0100 (CET) Subject: [z3-checkins] r34078 - z3/deliverance/branches/packaged Message-ID: <20061102211129.596521006F@code0.codespeak.net> Author: cabraham Date: Thu Nov 2 22:11:26 2006 New Revision: 34078 Modified: z3/deliverance/branches/packaged/README.txt Log: README stuff Modified: z3/deliverance/branches/packaged/README.txt ============================================================================== --- z3/deliverance/branches/packaged/README.txt (original) +++ z3/deliverance/branches/packaged/README.txt Thu Nov 2 22:11:26 2006 @@ -1,4 +1,6 @@ - +----------------------------------- +Deliverance README +----------------------------------- See: http://www.openplans.org/projects/deliverance for more information @@ -33,7 +35,7 @@ The easiest way to get Deliverance installed is to checkout the buildout and follow the instructions found there. -$ svn co https://svn.openplans.org/svn/deliverance.buildout deliverance.buildout +$ svn co https://svn.openplans.org/svn/deliverance.buildout/trunk deliverance.buildout Otherwise, to install Deliverance manually, first get workingenv.py From cabraham at codespeak.net Thu Nov 2 22:25:25 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Thu, 2 Nov 2006 22:25:25 +0100 (CET) Subject: [z3-checkins] r34079 - in z3/deliverance/branches/packaged: attic doc Message-ID: <20061102212525.ABE0D10072@code0.codespeak.net> Author: cabraham Date: Thu Nov 2 22:25:23 2006 New Revision: 34079 Added: z3/deliverance/branches/packaged/attic/ - copied from r34078, z3/deliverance/branches/packaged/doc/ Removed: z3/deliverance/branches/packaged/doc/ Log: renamed doc to attic to house out-of-date docs From cabraham at codespeak.net Fri Nov 3 21:40:00 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Fri, 3 Nov 2006 21:40:00 +0100 (CET) Subject: [z3-checkins] r34148 - in z3/deliverance/branches/packaged: Attic attic Message-ID: <20061103204000.F2DB21006F@code0.codespeak.net> Author: cabraham Date: Fri Nov 3 21:39:56 2006 New Revision: 34148 Added: z3/deliverance/branches/packaged/Attic/ - copied from r34147, z3/deliverance/branches/packaged/attic/ Removed: z3/deliverance/branches/packaged/attic/ Log: Testing the move command From cabraham at codespeak.net Fri Nov 3 21:42:57 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Fri, 3 Nov 2006 21:42:57 +0100 (CET) Subject: [z3-checkins] r34149 - in z3/deliverance: branches/old trunk Message-ID: <20061103204257.6AAB51006F@code0.codespeak.net> Author: cabraham Date: Fri Nov 3 21:42:54 2006 New Revision: 34149 Added: z3/deliverance/branches/old/ - copied from r34148, z3/deliverance/trunk/ Removed: z3/deliverance/trunk/ Log: Retiring trunk for archival purposes From cabraham at codespeak.net Fri Nov 3 21:44:21 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Fri, 3 Nov 2006 21:44:21 +0100 (CET) Subject: [z3-checkins] r34150 - in z3/deliverance: branches/packaged trunk Message-ID: <20061103204421.97F741006F@code0.codespeak.net> Author: cabraham Date: Fri Nov 3 21:44:19 2006 New Revision: 34150 Added: z3/deliverance/trunk/ - copied from r34149, z3/deliverance/branches/packaged/ Removed: z3/deliverance/branches/packaged/ Log: Making the packaged branch the Deliverance trunk From cabraham at codespeak.net Fri Nov 3 21:49:41 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Fri, 3 Nov 2006 21:49:41 +0100 (CET) Subject: [z3-checkins] r34151 - z3/deliverance/trunk Message-ID: <20061103204941.30F521006F@code0.codespeak.net> Author: cabraham Date: Fri Nov 3 21:49:38 2006 New Revision: 34151 Modified: z3/deliverance/trunk/README.txt Log: Updated link for checkout directory Modified: z3/deliverance/trunk/README.txt ============================================================================== --- z3/deliverance/trunk/README.txt (original) +++ z3/deliverance/trunk/README.txt Fri Nov 3 21:49:38 2006 @@ -53,7 +53,7 @@ Checkout and setup Deliverance, then make sure your installation is complete by running the tests: -$ svn co http://codespeak.net/svn/z3/deliverance/branches/packaged deliverance +$ svn co http://codespeak.net/svn/z3/deliverance/trunk/ deliverance $ cd deliverance $ python setup.py develop $ nosetests From ltucker at codespeak.net Fri Nov 3 22:13:35 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 3 Nov 2006 22:13:35 +0100 (CET) Subject: [z3-checkins] r34152 - z3/deliverance/deliverance.buildout Message-ID: <20061103211335.E63C31006F@code0.codespeak.net> Author: ltucker Date: Fri Nov 3 22:13:33 2006 New Revision: 34152 Added: z3/deliverance/deliverance.buildout/ z3/deliverance/deliverance.buildout/EXTERNALS.txt z3/deliverance/deliverance.buildout/README.libraries z3/deliverance/deliverance.buildout/README.txt z3/deliverance/deliverance.buildout/buildout.cfg Log: initial import of deliverance buildout Added: z3/deliverance/deliverance.buildout/EXTERNALS.txt ============================================================================== --- (empty file) +++ z3/deliverance/deliverance.buildout/EXTERNALS.txt Fri Nov 3 22:13:33 2006 @@ -0,0 +1,4 @@ +bootstrap svn://svn.zope.org/repos/main/zc.buildout/trunk/bootstrap +zc.recipe.cmmi svn://svn.zope.org/repos/main/zc.recipe.cmmi/trunk +deliverance http://codespeak.net/svn/z3/deliverance/trunk + Added: z3/deliverance/deliverance.buildout/README.libraries ============================================================================== --- (empty file) +++ z3/deliverance/deliverance.buildout/README.libraries Fri Nov 3 22:13:33 2006 @@ -0,0 +1,27 @@ + +if you see output from the compiler during the buildout along the lines of: + +unrecognized option '-R/your/buildout/path/parts/libxml2/lib' + +or the message: +UserWarning: Deliverance requires the CVS HEAD version of libxml2 + +this indicates the build has not properly built lxml to use the versions of libxml2 and libxslt +that are included in this build. + +you should set your LD_LIBRARY_PATH to search the library directories under parts before +your normal library paths, eg: + +export DELIVERANCE_PATH="/your/buildout/path" +export LD_LIBRARY_PATH="$DELIVERANCE_PATH/parts/libxml2/lib:$DELIVERANCE_PATH/parts/libxslt/lib:$LD_LIBRARY_PATH" + + +you can check whether lxml is using the correct libraries by running +ldd develop-eggs/lxml*egg/lxml/etree.so + +libxml2 and libxslt should point within the buildout directory + +This issue is noted in distutils bugs: +https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1254718&group_id=5470 +https://sourceforge.net/tracker/?func=detail&atid=305470&aid=642019&group_id=5470 +http://sourceforge.net/tracker/?func=detail&atid=105470&aid=445902&group_id=5470 Added: z3/deliverance/deliverance.buildout/README.txt ============================================================================== --- (empty file) +++ z3/deliverance/deliverance.buildout/README.txt Fri Nov 3 22:13:33 2006 @@ -0,0 +1,25 @@ +----------------------------------- +Deliverance Buildout Instructions +----------------------------------- + +See: http://www.openplans.org/projects/deliverance +for more information on Deliverance + + +Deliverance is built by running: + +$ python ./bootstrap/bootstrap.py +$ ./bin/buildout + + +You should then be able to run the deliverance-handtransform and +deliverance-proxy in bin. + +To run tests: +cd deliverance +../bin/deliverance-tests + +To run speed test: +cd deliverance +../bin/deliverance-speed + Added: z3/deliverance/deliverance.buildout/buildout.cfg ============================================================================== --- (empty file) +++ z3/deliverance/deliverance.buildout/buildout.cfg Fri Nov 3 22:13:33 2006 @@ -0,0 +1,29 @@ +[buildout] +develop = zc.recipe.cmmi deliverance +parts = libxml2 libxslt lxml lxml-inst deliverance-inst + +[libxml2] +recipe = zc.recipe.cmmi +url = ftp://xmlsoft.org/libxml2/libxml2-cvs-snapshot.tar.gz +extra_options = --without-python + +[libxslt] +recipe = zc.recipe.cmmi +url = ftp://xmlsoft.org/libxml2/libxslt-cvs-snapshot.tar.gz +extra_options = --with-libxml-prefix=${buildout:directory}/parts/libxml2/ + --without-python + +[lxml] +recipe = zc.recipe.egg:custom +eggs = lxml +include-dirs = ${buildout:directory}/parts/libxml2/include:${buildout:directory}/parts/libxslt/include +rpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libxslt/lib + +[lxml-inst] +recipe = zc.recipe.egg +eggs = lxml + +[deliverance-inst] +recipe = zc.recipe.egg +eggs = deliverance + From ltucker at codespeak.net Fri Nov 3 22:16:03 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 3 Nov 2006 22:16:03 +0100 (CET) Subject: [z3-checkins] r34153 - z3/deliverance/deliverance.buildout Message-ID: <20061103211603.B01E91006F@code0.codespeak.net> Author: ltucker Date: Fri Nov 3 22:16:02 2006 New Revision: 34153 Modified: z3/deliverance/deliverance.buildout/ (props changed) Log: setting external dependencies From ltucker at codespeak.net Fri Nov 3 22:18:29 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 3 Nov 2006 22:18:29 +0100 (CET) Subject: [z3-checkins] r34154 - z3/deliverance/deliverance.buildout Message-ID: <20061103211829.5E31B1006F@code0.codespeak.net> Author: ltucker Date: Fri Nov 3 22:18:27 2006 New Revision: 34154 Modified: z3/deliverance/deliverance.buildout/README.txt Log: added purpose note to README.txt Modified: z3/deliverance/deliverance.buildout/README.txt ============================================================================== --- z3/deliverance/deliverance.buildout/README.txt (original) +++ z3/deliverance/deliverance.buildout/README.txt Fri Nov 3 22:18:27 2006 @@ -2,6 +2,9 @@ Deliverance Buildout Instructions ----------------------------------- +This package performs an automated self-contained +build of Deliverance and its dependencies. + See: http://www.openplans.org/projects/deliverance for more information on Deliverance From ltucker at codespeak.net Fri Nov 3 22:24:08 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Fri, 3 Nov 2006 22:24:08 +0100 (CET) Subject: [z3-checkins] r34155 - z3/deliverance/trunk Message-ID: <20061103212408.0E6421006F@code0.codespeak.net> Author: ltucker Date: Fri Nov 3 22:24:05 2006 New Revision: 34155 Modified: z3/deliverance/trunk/README.txt Log: changing buildout location in README.txt Modified: z3/deliverance/trunk/README.txt ============================================================================== --- z3/deliverance/trunk/README.txt (original) +++ z3/deliverance/trunk/README.txt Fri Nov 3 22:24:05 2006 @@ -35,7 +35,7 @@ The easiest way to get Deliverance installed is to checkout the buildout and follow the instructions found there. -$ svn co https://svn.openplans.org/svn/deliverance.buildout/trunk deliverance.buildout +$ svn co https://codespeak.net/svn/z3/deliverance/deliverance.buildout Otherwise, to install Deliverance manually, first get workingenv.py From philikon at codespeak.net Sat Nov 4 21:46:13 2006 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sat, 4 Nov 2006 21:46:13 +0100 (CET) Subject: [z3-checkins] r34206 - in z3/www/trunk: . text Message-ID: <20061104204613.5B74B10071@code0.codespeak.net> Author: philikon Date: Sat Nov 4 21:46:10 2006 New Revision: 34206 Modified: z3/www/trunk/mkwebsite.py z3/www/trunk/text/index.txt Log: new five releases Modified: z3/www/trunk/mkwebsite.py ============================================================================== --- z3/www/trunk/mkwebsite.py (original) +++ z3/www/trunk/mkwebsite.py Sat Nov 4 21:46:10 2006 @@ -144,36 +144,36 @@ 'http://codespeak.net/mailman/listinfo/z3-checkins'), ('Five 1.2.6 release', 'release/Five-1.2.6.tgz'), - ('Five 1.3.7 release', - 'release/Five-1.3.7.tgz'), - ('Five 1.4.1 release', - 'release/Five-1.4.tgz'), - ('Five 1.5 release', - 'release/Five-1.5.tgz'), + ('Five 1.3.8 release', + 'release/Five-1.3.8.tgz'), + ('Five 1.4.2 release', + 'release/Five-1.4.2.tgz'), + ('Five 1.5.1 release', + 'release/Five-1.5.1.tgz'), ] site.registerReleases([ Z3ReleaseResource( 'Five', 'svn://svn.zope.org/repos/main/Products.Five/tags/1.2.6'), Z3ReleaseResource( - 'Five', 'svn://svn.zope.org/repos/main/Products.Five/tags/1.3.7'), + 'Five', 'svn://svn.zope.org/repos/main/Products.Five/tags/1.3.8'), Z3ReleaseResource( - 'Five', 'svn://svn.zope.org/repos/main/Products.Five/tags/1.4.1'), + 'Five', 'svn://svn.zope.org/repos/main/Products.Five/tags/1.4.2'), Z3ReleaseResource( - 'Five', 'svn://svn.zope.org/repos/main/Products.Five/tags/1.5'), + 'Five', 'svn://svn.zope.org/repos/main/Products.Five/tags/1.5.1'), ], project.getName()) from z3publish import Z3TestPage site.registerPages([ - ZopeOrgPage('Products.Five/tags/1.5', 'doc/main.txt', 'index'), - ZopeOrgPage('Products.Five/tags/1.5', 'doc/features.txt'), - ZopeOrgPage('Products.Five/tags/1.5', 'doc/directives.txt'), - ZopeOrgPage('Products.Five/tags/1.5', 'doc/manual.txt'), - ZopeOrgPage('Products.Five/tags/1.5', 'doc/i18n.txt'), - ZopeOrgPage('Products.Five/tags/1.5', 'doc/localsite.txt'), - ZopeOrgPage('Products.Five/tags/1.5', 'doc/event.txt'), - ZopeOrgPage('Products.Five/tags/1.5', 'CHANGES.txt'), - ZopeOrgPage('Products.Five/tags/1.5', 'INSTALL.txt'),], + ZopeOrgPage('Products.Five/branches/1.5', 'doc/main.txt', 'index'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'doc/features.txt'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'doc/directives.txt'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'doc/manual.txt'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'doc/i18n.txt'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'doc/localsite.txt'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'doc/event.txt'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'CHANGES.txt'), + ZopeOrgPage('Products.Five/tags/1.5.1', 'INSTALL.txt'),], site.getProjectLayouter(project), project.getName(), nav_links=nav_links, @@ -199,21 +199,18 @@ pages = [Z3Page('CMFonFive/trunk', 'README.txt', 'index'),] - # You can test the pages before checking them in. Replace the above with the uncommented - # code below and rerun. Don't forget to change back! + # You can test the pages before checking them in. Replace the + # above with the uncommented code below and rerun. Don't forget to + # change back! + #from z3publish import Z3TestPage - #pages = [Z3TestPage('/the/path/to/the/file/on/disk/CMFonFive/README.txt', 'index'),] + #pages = [Z3TestPage('/the/path/to/the/file/on/disk/CMFonFive/README.txt', + # 'index'),] site.registerReleases([ - Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.0.0'), Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.0.1'), - Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.1.0'), Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.1.1'), - Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.2.0'), Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.2.1'), - Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.3.0'), - Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.3.1'), - Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.3.2'), Z3ReleaseResource('CMFonFive', 'http://codespeak.net/svn/z3/CMFonFive/tag/CMFonFive-1.3.3'), ], project.getName()) Modified: z3/www/trunk/text/index.txt ============================================================================== --- z3/www/trunk/text/index.txt (original) +++ z3/www/trunk/text/index.txt Sat Nov 4 21:46:10 2006 @@ -21,45 +21,16 @@ News ---- -* 2005-08-13 `Five`_ 1.2.6, 1.3.7, 1.4.1 and 1.5 released! +* 2006-11-04 `Five`_ 1.3.8, 1.4.2 and 1.5.1 released! -* 2005-05-29 `Five`_ 1.2.5, 1.3.6, 1.4 and 1.5c released! +* 2006-08-13 `Five`_ 1.2.6, 1.3.7, 1.4.1 and 1.5 released! -* 2005-05-04 `Five`_ 1.2.4, 1.3.5, 1.4c and 1.5b released! +* 2006-05-29 `Five`_ 1.2.5, 1.3.6, 1.4 and 1.5c released! -* 2005-02-25 `Five`_ 1.2.1 and 1.3.2 released! Download `Five 1.2.1`_ - and `Five 1.3.2`_ +* 2006-05-04 `Five`_ 1.2.4, 1.3.5, 1.4c and 1.5b released! -* 2005-01-07 `Five`_ 1.2 and 1.3 released! `Download Five 1.2`_ +* 2006-02-25 `Five`_ 1.2.1 and 1.3.2 released! -* 2005-11-02 `Five`_ 1.2b and 1.3b released! `Download Five 1.2b`_ - -* 2005-10-04 `Five`_ 1.1 released! `Download Five 1.1`_ - -* 2005-07-21 `Five`_ 1.1b released! `Download Five 1.1b`_ - -* 2005-07-21 `Five`_ 1.0.2 released! `Download Five 1.0.2`_ - -* 2005-05-31 `Five`_ 1.0.1 released! `Download Five 1.0.1`_ - -* 2005-04-27 `Five`_ 1.0 released! `Download Five 1.0`_ - -* 2005-03-11 `Five`_ 0.3 released! `Download Five 0.3`_ - -* 2004-09-24 `Five`_ 0.2b released! `Download Five 0.2b`_ - -* 2004-07-30 `Five`_ 0.1 released! `Download Five 0.1`_ +* 2006-01-07 `Five`_ 1.2 and 1.3 released! .. _`Five`: http://codespeak.net/z3/five -.. _`Download Five 0.1`: http://codespeak.net/z3/five/release/Five-0.1.tgz -.. _`Download Five 0.2b`: http://codespeak.net/z3/five/release/Five-0.2b.tgz -.. _`Download Five 0.3`: http://codespeak.net/z3/five/release/Five-0.3.tgz -.. _`Download Five 1.0`: http://codespeak.net/z3/five/release/Five-1.0.tgz -.. _`Download Five 1.0.1`: http://codespeak.net/z3/five/release/Five-1.0.1.tgz -.. _`Download Five 1.0.2`: http://codespeak.net/z3/five/release/Five-1.0.2.tgz -.. _`Download Five 1.1b`: http://codespeak.net/z3/five/release/Five-1.1b.tgz -.. _`Download Five 1.1`: http://codespeak.net/z3/five/release/Five-1.1.tgz -.. _`Download Five 1.2b`: http://codespeak.net/z3/five/release/Five-1.2b.tgz -.. _`Download Five 1.2`: http://codespeak.net/z3/five/release/Five-1.2.tgz -.. _`Five 1.2.1`: http://codespeak.net/z3/five/release/Five-1.2.1.tgz -.. _`Five 1.3.2`: http://codespeak.net/z3/five/release/Five-1.3.2.tgz From cabraham at codespeak.net Mon Nov 6 16:35:19 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 16:35:19 +0100 (CET) Subject: [z3-checkins] r34270 - z3/deliverance/buildout Message-ID: <20061106153519.02F5A10079@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 16:35:18 2006 New Revision: 34270 Added: z3/deliverance/buildout/ Log: making buildout directories From cabraham at codespeak.net Mon Nov 6 16:35:27 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 16:35:27 +0100 (CET) Subject: [z3-checkins] r34271 - z3/deliverance/buildout/trunk Message-ID: <20061106153527.3EAB810079@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 16:35:25 2006 New Revision: 34271 Added: z3/deliverance/buildout/trunk/ Log: making buildout directories From cabraham at codespeak.net Mon Nov 6 16:35:44 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 16:35:44 +0100 (CET) Subject: [z3-checkins] r34272 - in z3/deliverance: buildout/trunk/deliverance.buildout deliverance.buildout Message-ID: <20061106153544.16BE71007B@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 16:35:40 2006 New Revision: 34272 Added: z3/deliverance/buildout/trunk/deliverance.buildout/ - copied from r34271, z3/deliverance/deliverance.buildout/ Removed: z3/deliverance/deliverance.buildout/ Log: moving buildout to proper directory From cabraham at codespeak.net Mon Nov 6 16:41:19 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 16:41:19 +0100 (CET) Subject: [z3-checkins] r34275 - in z3/deliverance/buildout: del.b trunk/deliverance.buildout Message-ID: <20061106154119.97D0B1007B@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 16:41:16 2006 New Revision: 34275 Added: z3/deliverance/buildout/del.b/ - copied from r34274, z3/deliverance/buildout/trunk/deliverance.buildout/ Removed: z3/deliverance/buildout/trunk/deliverance.buildout/ Log: moving buildout to proper directory From cabraham at codespeak.net Mon Nov 6 16:42:06 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 16:42:06 +0100 (CET) Subject: [z3-checkins] r34276 - z3/deliverance/buildout/trunk Message-ID: <20061106154206.205531007B@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 16:42:04 2006 New Revision: 34276 Removed: z3/deliverance/buildout/trunk/ Log: deleting From cabraham at codespeak.net Mon Nov 6 16:42:46 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 16:42:46 +0100 (CET) Subject: [z3-checkins] r34277 - in z3/deliverance/buildout: del.b trunk Message-ID: <20061106154246.9A8C11007B@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 16:42:44 2006 New Revision: 34277 Added: z3/deliverance/buildout/trunk/ - copied from r34276, z3/deliverance/buildout/del.b/ Removed: z3/deliverance/buildout/del.b/ Log: moving buildout to proper directory From cabraham at codespeak.net Mon Nov 6 17:21:09 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:21:09 +0100 (CET) Subject: [z3-checkins] r34278 - z3/deliverance/trunk Message-ID: <20061106162109.66B801007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:21:06 2006 New Revision: 34278 Modified: z3/deliverance/trunk/README.txt Log: fixed buildout url Modified: z3/deliverance/trunk/README.txt ============================================================================== --- z3/deliverance/trunk/README.txt (original) +++ z3/deliverance/trunk/README.txt Mon Nov 6 17:21:06 2006 @@ -35,7 +35,7 @@ The easiest way to get Deliverance installed is to checkout the buildout and follow the instructions found there. -$ svn co https://codespeak.net/svn/z3/deliverance/deliverance.buildout +$ svn co http://codespeak.net/svn/z3/deliverance/buildout/trunk Otherwise, to install Deliverance manually, first get workingenv.py From cabraham at codespeak.net Mon Nov 6 17:28:22 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:28:22 +0100 (CET) Subject: [z3-checkins] r34279 - z3/deliverance/trunk/Attic/doc Message-ID: <20061106162822.4B38D1007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:28:20 2006 New Revision: 34279 Added: z3/deliverance/trunk/Attic/doc/ Log: new dir From cabraham at codespeak.net Mon Nov 6 17:31:53 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:31:53 +0100 (CET) Subject: [z3-checkins] r34280 - z3/deliverance/trunk/Attic/doc Message-ID: <20061106163153.C835D1007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:31:51 2006 New Revision: 34280 Removed: z3/deliverance/trunk/Attic/doc/ Log: removed docs From cabraham at codespeak.net Mon Nov 6 17:32:44 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:32:44 +0100 (CET) Subject: [z3-checkins] r34281 - z3/deliverance/trunk/tmp Message-ID: <20061106163244.CC0BA1007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:32:43 2006 New Revision: 34281 Added: z3/deliverance/trunk/tmp/ Log: new dir From cabraham at codespeak.net Mon Nov 6 17:33:01 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:33:01 +0100 (CET) Subject: [z3-checkins] r34282 - in z3/deliverance/trunk: Attic tmp/Attic Message-ID: <20061106163301.93D681007E@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:32:59 2006 New Revision: 34282 Added: z3/deliverance/trunk/tmp/Attic/ - copied from r34281, z3/deliverance/trunk/Attic/ Removed: z3/deliverance/trunk/Attic/ Log: moved docs From cabraham at codespeak.net Mon Nov 6 17:33:28 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:33:28 +0100 (CET) Subject: [z3-checkins] r34283 - z3/deliverance/trunk/Attic Message-ID: <20061106163328.F25771007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:33:27 2006 New Revision: 34283 Added: z3/deliverance/trunk/Attic/ Log: new dir From cabraham at codespeak.net Mon Nov 6 17:33:34 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:33:34 +0100 (CET) Subject: [z3-checkins] r34284 - z3/deliverance/trunk/Attic/doc Message-ID: <20061106163334.F35291007E@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:33:33 2006 New Revision: 34284 Added: z3/deliverance/trunk/Attic/doc/ Log: new dir From cabraham at codespeak.net Mon Nov 6 17:34:05 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:34:05 +0100 (CET) Subject: [z3-checkins] r34285 - z3/deliverance/trunk/Attic/doc Message-ID: <20061106163405.524151007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:34:03 2006 New Revision: 34285 Removed: z3/deliverance/trunk/Attic/doc/ Log: removed docs From cabraham at codespeak.net Mon Nov 6 17:34:41 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:34:41 +0100 (CET) Subject: [z3-checkins] r34286 - in z3/deliverance/trunk: Attic/Attic tmp/Attic Message-ID: <20061106163441.8B8A21007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:34:38 2006 New Revision: 34286 Added: z3/deliverance/trunk/Attic/Attic/ - copied from r34285, z3/deliverance/trunk/tmp/Attic/ Removed: z3/deliverance/trunk/tmp/Attic/ Log: moved docs From cabraham at codespeak.net Mon Nov 6 17:35:03 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:35:03 +0100 (CET) Subject: [z3-checkins] r34287 - in z3/deliverance/trunk/Attic: Attic doc Message-ID: <20061106163503.00B1E1007D@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:35:01 2006 New Revision: 34287 Added: z3/deliverance/trunk/Attic/doc/ - copied from r34286, z3/deliverance/trunk/Attic/Attic/ Removed: z3/deliverance/trunk/Attic/Attic/ Log: moved docs From cabraham at codespeak.net Mon Nov 6 17:35:17 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:35:17 +0100 (CET) Subject: [z3-checkins] r34288 - z3/deliverance/trunk/tmp Message-ID: <20061106163517.2A8F51007E@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:35:15 2006 New Revision: 34288 Removed: z3/deliverance/trunk/tmp/ Log: removed docs From cabraham at codespeak.net Mon Nov 6 17:37:32 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:37:32 +0100 (CET) Subject: [z3-checkins] r34289 - in z3/deliverance: branches/namespaced trunk/Attic Message-ID: <20061106163732.8E2F310090@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:37:28 2006 New Revision: 34289 Added: z3/deliverance/trunk/Attic/mpfilter.conf - copied unchanged from r34288, z3/deliverance/branches/namespaced/mpfilter.conf Removed: z3/deliverance/branches/namespaced/mpfilter.conf Log: moved old source Deleted: /z3/deliverance/branches/namespaced/mpfilter.conf ============================================================================== --- /z3/deliverance/branches/namespaced/mpfilter.conf Mon Nov 6 17:37:28 2006 +++ (empty file) @@ -1,11 +0,0 @@ -# This module can be pointed to from your main Apache -# configuration file to apply a theme to certain parts of your -# URL space. - -LoadModule python_module modules/mod_python.so - - - PythonOutputFilter mpfilter DELIVERANCE - AddOutputFilter DELIVERANCE .html - PythonDebug On - From cabraham at codespeak.net Mon Nov 6 17:37:51 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:37:51 +0100 (CET) Subject: [z3-checkins] r34290 - in z3/deliverance: branches/namespaced trunk/Attic Message-ID: <20061106163751.69ABD10094@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:37:46 2006 New Revision: 34290 Added: z3/deliverance/trunk/Attic/mpfilter.py - copied unchanged from r34289, z3/deliverance/branches/namespaced/mpfilter.py Removed: z3/deliverance/branches/namespaced/mpfilter.py Log: moved old source Deleted: /z3/deliverance/branches/namespaced/mpfilter.py ============================================================================== --- /z3/deliverance/branches/namespaced/mpfilter.py Mon Nov 6 17:37:46 2006 +++ (empty file) @@ -1,70 +0,0 @@ -""" -Deliverance theming for mod_python filters - -Deliverance applies a theme to content. This mod_python module acts as an -Apache "filter", transforming content as it passes through Apache. - -This module gets imported by mod_python during its startup. Thus, the -appmap instance becomes a global, computed only once. If you need to -recompute the theme, for example, restart the Apache. -""" -import time -from cStringIO import StringIO - -from mod_python import apache -from deliverance import AppMap -appmap = AppMap() # Theme is generated once at module import time - -def outputfilter(filter): - if not hasattr(filter.req, 'notheme'): - # Check for a flag to not apply theme - args = filter.req.args - if args and args.find("notheme") > -1: - filter.req.notheme = True - else: - filter.req.notheme = False - - try: - streambuffer = filter.req.streambuffer - except AttributeError: - if filter.req.notheme: - # pass on if no theme - filter.pass_on() - return - elif not filter.req.headers_out.has_key("content-type"): - # pass on if no content type specified - filter.pass_on() - return - elif not filter.req.headers_out["content-type"].startswith("text/html"): - # pass on if not HTML - filter.pass_on() - return - - filter.req.streambuffer = StringIO() - streambuffer = filter.req.streambuffer - - streamlet = filter.readline() - while streamlet: - streambuffer.write(streamlet) - streamlet = filter.readline() - - if streamlet is None: - output = appmap.publish(streambuffer.getvalue()) - filter.req.headers_out["Content-Length"] = str(len(output)) - filter.write(output) - filter.close() - - -def handler(req): - """Basic filter applying to all mime types it is registered for""" - - # Get the path, strip off leading slash, and convert to a - # dotted notation for xml:id compatibility - path_info = req.path_info[1:] - dotted_path = path_info.replace("/", ".") - - response = appmap.publish(dotted_path) - req.content_type = "text/html" - req.write(response) - - return apache.OK From cabraham at codespeak.net Mon Nov 6 17:40:01 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:40:01 +0100 (CET) Subject: [z3-checkins] r34291 - z3/deliverance/branches/namespaced Message-ID: <20061106164001.6157E10092@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:39:58 2006 New Revision: 34291 Removed: z3/deliverance/branches/namespaced/ Log: cleanup old code From cabraham at codespeak.net Mon Nov 6 17:40:10 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:40:10 +0100 (CET) Subject: [z3-checkins] r34292 - z3/deliverance/branches/noappmap Message-ID: <20061106164010.5858D10092@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:40:08 2006 New Revision: 34292 Removed: z3/deliverance/branches/noappmap/ Log: cleanup old code From cabraham at codespeak.net Mon Nov 6 17:40:15 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:40:15 +0100 (CET) Subject: [z3-checkins] r34293 - z3/deliverance/branches/old Message-ID: <20061106164015.E393610092@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:40:14 2006 New Revision: 34293 Removed: z3/deliverance/branches/old/ Log: cleanup old code From cabraham at codespeak.net Mon Nov 6 17:40:25 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 17:40:25 +0100 (CET) Subject: [z3-checkins] r34294 - z3/deliverance/branches/mphandler Message-ID: <20061106164025.1007E100A2@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 17:40:23 2006 New Revision: 34294 Removed: z3/deliverance/branches/mphandler/ Log: cleanup old code From cabraham at codespeak.net Mon Nov 6 18:14:04 2006 From: cabraham at codespeak.net (cabraham at codespeak.net) Date: Mon, 6 Nov 2006 18:14:04 +0100 (CET) Subject: [z3-checkins] r34297 - z3/deliverance/buildout/trunk Message-ID: <20061106171404.2D1061007F@code0.codespeak.net> Author: cabraham Date: Mon Nov 6 18:14:03 2006 New Revision: 34297 Modified: z3/deliverance/buildout/trunk/buildout.cfg Log: updated libxml2 and libxslt links to latest stable releases Modified: z3/deliverance/buildout/trunk/buildout.cfg ============================================================================== --- z3/deliverance/buildout/trunk/buildout.cfg (original) +++ z3/deliverance/buildout/trunk/buildout.cfg Mon Nov 6 18:14:03 2006 @@ -4,12 +4,12 @@ [libxml2] recipe = zc.recipe.cmmi -url = ftp://xmlsoft.org/libxml2/libxml2-cvs-snapshot.tar.gz +url = ftp://xmlsoft.org/libxml2/libxml2-2.6.27.tar.gz extra_options = --without-python [libxslt] recipe = zc.recipe.cmmi -url = ftp://xmlsoft.org/libxml2/libxslt-cvs-snapshot.tar.gz +url = ftp://xmlsoft.org/libxml2/libxslt-1.1.18.tar.gz extra_options = --with-libxml-prefix=${buildout:directory}/parts/libxml2/ --without-python From ltucker at codespeak.net Mon Nov 6 21:22:21 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 6 Nov 2006 21:22:21 +0100 (CET) Subject: [z3-checkins] r34298 - z3/deliverance/trunk/deliverance Message-ID: <20061106202221.E3C2710075@code0.codespeak.net> Author: ltucker Date: Mon Nov 6 21:22:17 2006 New Revision: 34298 Modified: z3/deliverance/trunk/deliverance/fixuplinks.py z3/deliverance/trunk/deliverance/handtransform.py z3/deliverance/trunk/deliverance/htmlserialize.py z3/deliverance/trunk/deliverance/interpreter.py z3/deliverance/trunk/deliverance/test_wsgi.py z3/deliverance/trunk/deliverance/utils.py z3/deliverance/trunk/deliverance/wsgifilter.py z3/deliverance/trunk/deliverance/xslt.py Log: some more rough documentation and cleanup Modified: z3/deliverance/trunk/deliverance/fixuplinks.py ============================================================================== --- z3/deliverance/trunk/deliverance/fixuplinks.py (original) +++ z3/deliverance/trunk/deliverance/fixuplinks.py Mon Nov 6 21:22:17 2006 @@ -1,3 +1,8 @@ +""" +utilities for manipulating html links +""" + + from htmlserialize import decodeAndParseHTML, tostring import re @@ -27,11 +32,15 @@ fixup_css_links(doc, link_repl_func) def remove_base_tags_from_document(doc): + """ + removes all html tags + from the document given. + """ basetags = doc.xpath('//base[@href]') for b in basetags: b.getparent().remove(b) -CSS_URL_PAT = re.compile(r'url\((.*?)\)',re.I) +CSS_URL_PAT = re.compile(r'url\((.*?)\)', re.I) def fixup_css_links(doc, link_repl_func): """ prepends url(...) in css style elements to be Modified: z3/deliverance/trunk/deliverance/handtransform.py ============================================================================== --- z3/deliverance/trunk/deliverance/handtransform.py (original) +++ z3/deliverance/trunk/deliverance/handtransform.py Mon Nov 6 21:22:17 2006 @@ -16,9 +16,6 @@ themeurl, rulesfile and baseurl can be rolled into a file specified with -f it should contain an element like - - - """ @@ -26,26 +23,37 @@ usage = "usage: %prog [options] " parser = OptionParser(usage=usage) -parser.add_option("-t","--theme",dest="theme_url",help="url of theme html") -parser.add_option("-b","--baseurl",dest="base_url", +parser.add_option("-t", "--theme", dest="theme_url", help="url of theme html") +parser.add_option("-b", "--baseurl", dest="base_url", help="relative urls in the theme will be made absolute relative to this url [default %default]", default=DEFAULT_BASE_URL) -parser.add_option("-r","--rules",dest="rules_file", +parser.add_option("-r", "--rules", dest="rules_file", help="path to file containing the deliverance rules to apply") -parser.add_option("-f","--from-file",dest="blend_file", +parser.add_option("-f", "--from-file", dest="blend_file", help="take theme, baseurl and rules parameters from the referenced file") -parser.add_option("-R","--renderer",dest="renderer_type", +parser.add_option("-R", "--renderer", dest="renderer_type", help="(xslt|py) [default %default]", default="xslt", choices=['xslt','py']) def grab_url(url): + """ + returns the data referenced by the url provided. + """ f = urllib.urlopen(url) data = f.read() f.close() return data def do_transform(renderer_type, theme_url, base_url, rules_url, content_url): + """ + Perform the deliverance transform using the rules referenced by rules_url + on the pages referenced by theme_url and content_url. Renderer type determines + which deliverance renderer class is used to perform the transform, which may be + either 'xslt' or 'py'. Relative urls in the theme page will rewritten as + absolute urls relative to the base_url given. returns the result of the + transformation + """ rules = etree.XML(grab_url(rules_url)) theme = etree.HTML(grab_url(theme_url)) content = etree.HTML(grab_url(content_url)) @@ -70,23 +78,37 @@ def parse_blend_file(filename): + """ + returns the theme url, base url and rules url + specified in the file given. filename is + expected to contain an xml document containing a + toplevel element with attributes 'theme', + 'baseurl' and 'rules' + """ b = etree.XML(open(filename).read()) return b.get('theme'),b.get('baseurl'),b.get('rules') def die(message,parser): + """ + prints an error message, the usage of the program, + then quits. + """ print message parser.print_usage() sys.exit(0) def main(args=None): + """ + main function, see usage information + """ if args is None: args = sys.argv[1:] - options,args = parser.parse_args(args) + options, args = parser.parse_args(args) if len(args) == 0: - die("no content url specified.",parser) + die("no content url specified.", parser) content_url = args[0] theme_url = None @@ -99,10 +121,10 @@ die("cannot specify base url, rules file or theme url when taking parameters from file.",parser) try: - theme_url,base_url,rules_file = parse_blend_file(options.blend_file) + theme_url, base_url, rules_file = parse_blend_file(options.blend_file) - except Exception,message: - die(message,parser) + except Exception, message: + die(message, parser) else: theme_url = options.theme_url @@ -120,7 +142,11 @@ die("no base url specified",parser) - print tostring(do_transform(options.renderer_type,theme_url,base_url,rules_file,content_url)) + print tostring(do_transform(options.renderer_type, + theme_url, + base_url, + rules_file, + content_url)) if __name__ == '__main__': Modified: z3/deliverance/trunk/deliverance/htmlserialize.py ============================================================================== --- z3/deliverance/trunk/deliverance/htmlserialize.py (original) +++ z3/deliverance/trunk/deliverance/htmlserialize.py Mon Nov 6 21:22:17 2006 @@ -24,13 +24,15 @@ pretty_html_transform = etree.XSLT(etree.XML(pretty_html_xsl)) -# -# creates an HTML string representation of the document given -# -# note: this will create a meta http-equiv="Content" tag in the head -# and may replace any that are present -# + def tostring(doc,pretty = False): + """ + return HTML string representation of the document given + + note: this will create a meta http-equiv="Content" tag in the head + and may replace any that are present + """ + if pretty: return str(pretty_html_transform(doc)) else: @@ -39,19 +41,21 @@ -HTTP_EQUIV_MATCHER_PAT = re.compile(r"\<\s*meta\s+([^\>])*http-equiv\s*=\s*(\'|\")\s*content-type\s*(\'|\")([^\>])*charset\s*=\s*(?P[\w-]+)([^\>])*\>",re.I|re.M) -OTHER_HTTP_EQUIV_MATCHER_PAT = re.compile(r"\<\s*meta\s+([^\>])*charset\s*=\s*(?P[\w-]+)([^\>])*http-equiv\s*=\s*(\'|\")\s*content-type\s*(\'|\")([^\>])*\>",re.I|re.M) +#HTTP_EQUIV_MATCHER_PAT = re.compile(r"\<\s*meta\s+([^\>])*http-equiv\s*=\s*(\'|\")\s*content-type\s*(\'|\")([^\>])*charset\s*=\s*(?P[\w-]+)([^\>])*\>",re.I|re.M) +#OTHER_HTTP_EQUIV_MATCHER_PAT = re.compile(r"\<\s*meta\s+([^\>])*charset\s*=\s*(?P[\w-]+)([^\>])*http-equiv\s*=\s*(\'|\")\s*content-type\s*(\'|\")([^\>])*\>",re.I|re.M) def decodeAndParseHTML(text): """ if an html meta tag specifying a charset can be matched, decode the text to a python unicode string before parsing - """ - m = HTTP_EQUIV_MATCHER_PAT.search(text) - if not m: - m = OTHER_HTTP_EQUIV_MATCHER_PAT.search(text) - if m: - charset = m.group('charset') + XXX - this is disabled and in camelCase for no good reason + """ +# m = HTTP_EQUIV_MATCHER_PAT.search(text) +# if not m: +# m = OTHER_HTTP_EQUIV_MATCHER_PAT.search(text) +# +# if m: +# charset = m.group('charset') # text = text.decode(charset) content = etree.HTML(text) Modified: z3/deliverance/trunk/deliverance/interpreter.py ============================================================================== --- z3/deliverance/trunk/deliverance/interpreter.py (original) +++ z3/deliverance/trunk/deliverance/interpreter.py Mon Nov 6 21:22:17 2006 @@ -15,6 +15,24 @@ def __init__(self, theme, theme_uri, rule, rule_uri, reference_resolver=None): + """ + initializer. + + theme: an lxml etree represenatation of the theme page + theme_uri: a uri referring to the theme page, used to + make relative links in the theme absolute + rule: an lxml etree representation of the deliverance rules + performed by this transformation + rule_uri: a uri representing the location of the rules document + + reference_resolver: a function taking a url a parse type and + and an encoding type returning the data referred to by the url + in the manner specified. if parse is set to 'xml', the result + should be an lxml etree structure, otherwise if encoding + is specified, the data should be decoded using this encoding + before being returned. + + """ self.theme = self.fixup_links(theme, theme_uri) self.rules = rule self.rules_uri = rule_uri @@ -30,6 +48,12 @@ def render(self, content): + """ + content: an lxml etree structure representing the content to render + returns an lxml etree structure representing the result of the + transformation represented by this class performed on the + given content. + """ result = copy.deepcopy(self.theme) input = copy.deepcopy(content) self.apply_rules(self.rules, result, input) @@ -37,7 +61,13 @@ def apply_rules(self, rules, theme, content): - + """ + applies the deliverance rules given on the + theme and content given. drop rules are + run before any other rules. + rules, theme and content should be lxml etree + structures. + """ drop_rules, other_rules = self.separate_drop_rules(rules) # process all drop rules first @@ -49,6 +79,12 @@ def apply_rule(self, rule, theme, content): + """ + calls proper rule application function for + the rule given on the theme and content + given. rule, theme and content should be + lxml etree structures. + """ if rule.tag == self.APPEND_RULE_TAG: self.apply_append(rule, theme, content) elif rule.tag == self.PREPEND_RULE_TAG: @@ -71,6 +107,11 @@ rule.tag, etree.tostring(rule))) def apply_append(self,rule,theme,content): + """ + function that performs the deliverance "append" + rule given by rule on the theme and content given. + see deliverance specification + """ theme_el = self.get_theme_el(rule, theme) if theme_el is None: return @@ -113,7 +154,11 @@ theme_el.extend(non_text_els) def debug_append(self, theme_el, content_els, rule): - + """ + debugging variant of the deliverance "append" + rule (run when the rule has debugging enabled) + see deliverance specification + """ comment_before,comment_after = self.make_debugging_comments(rule) content_els[:0] = [comment_before] content_els.append(comment_after) @@ -127,6 +172,11 @@ def apply_prepend(self, rule, theme, content): + """ + function that performs the deliverance "prepend" + rule given by rule on the theme and content given. + see deliverance specification + """ theme_el = self.get_theme_el(rule, theme) if theme_el is None: return @@ -179,7 +229,12 @@ non_text_els[-1].tail = old_start_text def debug_prepend(self, theme_el, content_els, rule): - + """ + debugging variant of the deliverance "prepend" + rule (run when the rule has debugging enabled) + see deliverance specification + """ + comment_before, comment_after = self.make_debugging_comments(rule) content_els[:0] = [comment_before] content_els.append(comment_after) @@ -195,6 +250,11 @@ theme_el[:0] = non_text_els def apply_replace(self, rule, theme, content): + """ + function that performs the deliverance "replace" + rule given by rule on the theme and content given. + see deliverance specification + """ theme_el = self.get_theme_el(rule, theme) if theme_el is None: return @@ -262,6 +322,11 @@ non_text_els[0].tail = preserve_tail def debug_replace(self,theme_el,content_els,rule): + """ + debugging variant of the deliverance "replace" + rule (run when the rule has debugging enabled) + see deliverance specification + """ comment_before, comment_after = self.make_debugging_comments(rule) content_els[:0] = [comment_before] content_els.append(comment_after) @@ -280,6 +345,12 @@ parent[i+1:i+1] = non_text_els[1:] def _xpath_copy(self, source, xpath): + """ + helper function that returns a deep copy of the + element referred to by 'xpath' in the 'source' + document given. raises XPathSyntaxError if + xpath is invalid. + """ try: found_element = source.xpath(xpath) except etree.XPathSyntaxError, e: @@ -287,6 +358,11 @@ return copy.deepcopy(found_element) def apply_copy(self, rule, theme, content): + """ + function that performs the deliverance "copy" + rule given by rule on the theme and content given. + see deliverance specification + """ theme_el = self.get_theme_el(rule,theme) if theme_el is None: return @@ -323,6 +399,11 @@ def apply_append_or_replace(self, rule, theme, content): + """ + function that performs the deliverance "append-or-replace" + rule given by rule on the theme and content given. + see deliverance specification + """ theme_el = self.get_theme_el(rule, theme) if theme_el is None: return @@ -358,6 +439,11 @@ def apply_drop(self, rule, theme, content): + """ + function that performs the deliverance "drop" + rule given by rule on the theme and content given. + see deliverance specification + """ for context in ('theme', 'content'): if context not in rule.attrib: continue document = locals()[context] @@ -379,6 +465,10 @@ def strip_tails(self, els): + """ + for each lxml etree element in the list els, + set the tail of the element to None + """ for el in els: el.tail = None @@ -386,7 +476,7 @@ def attach_tails(self,els): """ whereever an lxml element in the list is followed by - a string, set the tail of the lxml element to the string + a string, set the tail of the lxml element to that string """ for index,el in enumerate(els): # if we run into a string after the current element, @@ -398,6 +488,10 @@ def make_debugging_comments(self, rule): + """ + returns a pair of comments for insertion before and + after work done by the rule given during debugging. + """ comment_before = etree.Comment("Deliverance: applying rule %s" % etree.tostring(rule)) comment_after = etree.Comment("Deliverance: done applying rule %s" % etree.tostring(rule)) return comment_before, comment_after Modified: z3/deliverance/trunk/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/trunk/deliverance/test_wsgi.py (original) +++ z3/deliverance/trunk/deliverance/test_wsgi.py Mon Nov 6 21:22:17 2006 @@ -25,6 +25,12 @@ def html_string_compare(astr, bstr): + """ + compare to strings containing html based on html + equivalence. Raises ValueError if the strings are + not equivalent. + """ + def reporter(x): print x Modified: z3/deliverance/trunk/deliverance/utils.py ============================================================================== --- z3/deliverance/trunk/deliverance/utils.py (original) +++ z3/deliverance/trunk/deliverance/utils.py Mon Nov 6 21:22:17 2006 @@ -67,6 +67,11 @@ NOCONTENT_KEY = "nocontent" def get_theme_el(self,rule,theme): + """ + get the element referred to by the "theme" attribute of the + rule given in the theme document given. theme and rule + should be lxml etree structures. + """ theme_els = theme.xpath(rule.attrib[self.RULE_THEME_KEY]) if len(theme_els)== 0: e = self.format_error("no element found in theme", rule) Modified: z3/deliverance/trunk/deliverance/wsgifilter.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgifilter.py (original) +++ z3/deliverance/trunk/deliverance/wsgifilter.py Mon Nov 6 21:22:17 2006 @@ -1,20 +1,15 @@ """ Deliverance theming as WSGI middleware - -Deliverance applies a theme to content. """ import re import urlparse import urllib from lxml import etree -#from lxml.etree import HTML as parseHTML from htmlserialize import decodeAndParseHTML as parseHTML from paste.wsgilib import intercept_output from paste.request import construct_url from paste.response import header_value, replace_header -#from interpreter import Renderer -#from xslt import Renderer from htmlserialize import tostring from utils import DeliveranceError from utils import DELIVERANCE_ERROR_PAGE @@ -28,8 +23,21 @@ class DeliveranceMiddleware(object): + """ + a DeliveranceMiddleware object exposes a single deliverance + tranformation as a WSGI middleware component. + """ def __init__(self, app, theme_uri, rule_uri, renderer='py'): + """ + initializer + + app: wsgi application which this middleware wraps. + theme_uri: uri referring the the theme document + rule_uri: uri referring to the deliverance rules document + renderer: selects deliverance render class to utilize when + performing transformations, may be 'py' or 'xslt' + """ self.app = app self.theme_uri = theme_uri self.rule_uri = rule_uri @@ -48,6 +56,10 @@ raise ValueError("Unknown Renderer: %s - Expecting 'py' or 'xslt'" % renderer) def get_renderer(self,environ): + """ + retrieve the deliverance Renderer representing the transformation this + middlware represents. Renderer may change according to caching rules. + """ try: self._lock.acquire() if not self._renderer or self.cache_expired(): @@ -58,6 +70,11 @@ self._lock.release() def create_renderer(self,environ): + """ + construct a new deliverance Renderer from the + information passed to the initializer. A new copy + of the theme and rules is retrieved. + """ theme = self.theme(environ) rule = self.rule(environ) full_theme_uri = urlparse.urljoin( @@ -96,9 +113,16 @@ def cache_expired(self): + """ + returns true if the stored Renderer should be refreshed + """ return self._cache_time + self._timeout < datetime.datetime.now() def rule(self, environ): + """ + retrieves the data referred to by the rule_uri passed to the + initializer. + """ try: return self.get_resource(environ,self.rule_uri) except Exception, message: @@ -109,6 +133,10 @@ raise DeliveranceError(newmessage) def theme(self, environ): + """ + retrieves the data referred to by the theme_uri passed to the + initializer. + """ try: return self.get_resource(environ,self.theme_uri) except Exception, message: @@ -119,6 +147,13 @@ def __call__(self, environ, start_response): + """ + WSGI entrypoint, responds to the request in + environ. responses from the wrapped WSGI + application of type text/html are themed + using the transformation specified in the + initializer. + """ try: qs = environ.get('QUERY_STRING', '') environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False) @@ -159,16 +194,28 @@ return [ errpage ] def should_intercept(self, status, headers): + """ + returns true if the status and headers given + specify a response from the wrapped middleware + which deliverance may need to theme. + """ type = header_value(headers, 'content-type') if type is None: return False return type.startswith('text/html') or type.startswith('application/xhtml+xml') def filter_body(self, environ, body): + """ + returns the result of the deliverance transformation on the string 'body' + in the context of environ. The result is a string containing HTML. + """ content = self.get_renderer(environ).render(parseHTML(body)) return tostring(content) def get_resource(self, environ, uri): + """ + retrieve the data referred to by the uri given. + """ internalBaseURL = environ.get(DELIVERANCE_BASE_URL,None) uri = urlparse.urljoin(internalBaseURL, uri) @@ -178,18 +225,30 @@ return self.get_external_resource(uri) def relative_uri(self, uri): + """ + returns true if uri is relative, false if + the uri is absolute. + """ if re.search(r'^[a-zA-Z]+:', uri): return False else: return True def get_external_resource(self, uri): + """ + get the data referred to by the uri given + using urllib (not through the wrapped app) + """ f = urllib.urlopen(uri) content = f.read() f.close() return content def get_internal_resource(self, environ, uri): + """ + get the data referred to by the uri given + by using the wrapped WSGI application + """ environ = environ.copy() if not uri.startswith('/'): uri = '/' + uri Modified: z3/deliverance/trunk/deliverance/xslt.py ============================================================================== --- z3/deliverance/trunk/deliverance/xslt.py (original) +++ z3/deliverance/trunk/deliverance/xslt.py Mon Nov 6 21:22:17 2006 @@ -41,12 +41,30 @@ content at render time """ - def __init__(self,theme,theme_uri,rule, rule_uri, reference_resolver=None): + def __init__(self, theme, theme_uri, rule, rule_uri, reference_resolver=None): + """ + initializer. + + theme: an lxml etree represenatation of the theme page + theme_uri: a uri referring to the theme page, used to + make relative links in the theme absolute + rule: an lxml etree representation of the deliverance rules + performed by this transformation + rule_uri: a uri representing the location of the rules document + + reference_resolver: a function taking a url a parse type and + and an encoding type returning the data referred to by the url + in the manner specified. if parse is set to 'xml', the result + should be an lxml etree structure, otherwise if encoding + is specified, the data should be decoded using this encoding + before being returned. + + """ theme_copy = copy.deepcopy(theme) self.rules = rule self.rules_uri = rule_uri - self.fixup_links(theme_copy,theme_uri) + self.fixup_links(theme_copy, theme_uri) self.xsl_escape_comments(theme_copy) if reference_resolver: @@ -70,7 +88,13 @@ - def render(self,content): + def render(self, content): + """ + content: an lxml etree structure representing the content to render + returns an lxml etree structure representing the result of the + transformation represented by this class performed on the + given content. + """ if content: if self.transform_drop: content = self.transform_drop(content) @@ -81,8 +105,12 @@ return self.transform(etree.Element("dummy")).getroot() - def apply_rules(self,rules,theme): - + def apply_rules(self, rules, theme): + """ + prepares an xslt transforms which accpet a content document. + The transforms represent the application of + the rules given in the context of the theme given. + """ drop_rules, other_rules = self.separate_drop_rules(rules) if len(drop_rules): @@ -92,10 +120,14 @@ self.transform_drop = etree.XSLT(self.xslt_dropper) for rule in other_rules: - self.apply_rule(rule,theme) + self.apply_rule(rule, theme) - def apply_rule(self,rule,theme): + def apply_rule(self, rule, theme): + """ + dispatch to proper rule handling function for + the rule given. + """ if rule.tag == self.APPEND_RULE_TAG: self.apply_append(rule,theme) elif rule.tag == self.PREPEND_RULE_TAG: @@ -117,14 +149,17 @@ "Rule %s (%s) not understood" % ( rule.tag, etree.tostring(rule))) - def apply_append(self,rule,theme): - theme_el = self.get_theme_el(rule,theme) + def apply_append(self, rule, theme): + """ + prepare transform elements for "append" rule + """ + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return # add an element that produces an error in the theme if # no content is matched - self.add_conditional_missing_content_error(theme,rule) + self.add_conditional_missing_content_error(theme, rule) copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) @@ -133,14 +168,17 @@ self.debug_append(theme_el, copier, rule) - def apply_prepend(self,rule,theme): - theme_el = self.get_theme_el(rule,theme) + def apply_prepend(self, rule, theme): + """ + prepare transform elements for "prepend" rule + """ + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return # add an element that produces an error in the theme if # no content is matched - self.add_conditional_missing_content_error(theme,rule) + self.add_conditional_missing_content_error(theme, rule) copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) @@ -149,8 +187,11 @@ self.debug_prepend(theme_el, copier, rule) - def apply_replace(self,rule,theme): - theme_el = self.get_theme_el(rule,theme) + def apply_replace(self, rule, theme): + """ + prepare transform elements for "replace" rule + """ + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return @@ -159,7 +200,7 @@ theme, self.format_error("cannot replace whole theme", rule)) return - self.add_conditional_missing_content_error(theme,rule) + self.add_conditional_missing_content_error(theme, rule) copier = etree.Element("{%s}copy-of" % nsmap["xsl"]) copier.set("select",rule.attrib[self.RULE_CONTENT_KEY]) @@ -175,8 +216,12 @@ self.debug_replace(theme_el,choose,rule) - def apply_copy(self,rule,theme): - theme_el = self.get_theme_el(rule,theme) + def apply_copy(self, rule, theme): + """ + prepare transform elements for "prepend" rule + """ + + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return @@ -203,14 +248,17 @@ rule.attrib[self.RULE_CONTENT_KEY], normal_theme_el, copy_theme_el) - self.debug_replace(theme_el,choose,rule) + self.debug_replace(theme_el, choose,rule) copy_theme_el.tail = None normal_theme_el.tail = None - def apply_append_or_replace(self,rule,theme): - theme_el = self.get_theme_el(rule,theme) + def apply_append_or_replace(self, rule, theme): + """ + prepare transform elements for "append-or-replace" rule + """ + theme_el = self.get_theme_el(rule, theme) if theme_el is None: return remove_tag = self.get_tag_from_xpath(rule.attrib[self.RULE_CONTENT_KEY]) @@ -220,7 +268,7 @@ # add an element that produces an error in the theme if # no content is matched - self.add_conditional_missing_content_error(theme,rule) + self.add_conditional_missing_content_error(theme, rule) for el in theme_el: if el.tag == remove_tag: @@ -236,8 +284,10 @@ self.debug_append(theme_el, copier, rule) - def apply_drop(self,rule,theme): - + def apply_drop(self, rule, theme): + """ + prepare transform elements for "drop" rule + """ if self.RULE_THEME_KEY in rule.attrib: if len(theme.xpath(rule.attrib[self.RULE_THEME_KEY])) == 0: if rule.get(self.NOCONTENT_KEY) == 'ignore': @@ -265,7 +315,7 @@ - def xsl_escape_comments(self,doc): + def xsl_escape_comments(self, doc): """ replaces comment nodes with xsl:comment nodes so they will appear in the result of a transform rather than being @@ -275,7 +325,7 @@ for c in comment_nodes: escaped = etree.Element("{%s}comment" % nsmap["xsl"]) escaped.text = c.text - self.replace_element(c,escaped) + self.replace_element(c, escaped) def add_conditional_missing_content_error(self,theme,rule): """ @@ -292,7 +342,7 @@ conditional = etree.Element("{%s}if" % nsmap["xsl"]) conditional.set("test", "count(%s)=0" % rule.attrib[self.RULE_CONTENT_KEY]) conditional.append(err) - self.add_to_body_start(theme,conditional) + self.add_to_body_start(theme, conditional) def make_when_otherwise(self, test, whenbody, otherwisebody): From ltucker at codespeak.net Tue Nov 7 23:43:22 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Tue, 7 Nov 2006 23:43:22 +0100 (CET) Subject: [z3-checkins] r34351 - in z3/deliverance/buildout/trunk: . fixlibsearch fixlibsearch/topp fixlibsearch/topp.fixlibsearch.egg-info fixlibsearch/topp/fixlibsearch Message-ID: <20061107224322.DC35010075@code0.codespeak.net> Author: ltucker Date: Tue Nov 7 23:43:19 2006 New Revision: 34351 Added: z3/deliverance/buildout/trunk/fixlibsearch/ z3/deliverance/buildout/trunk/fixlibsearch/README.txt z3/deliverance/buildout/trunk/fixlibsearch/setup.py z3/deliverance/buildout/trunk/fixlibsearch/topp/ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/PKG-INFO z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/SOURCES.txt z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/dependency_links.txt z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/entry_points.txt z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/requires.txt z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/top_level.txt z3/deliverance/buildout/trunk/fixlibsearch/topp/__init__.py z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/ z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py Modified: z3/deliverance/buildout/trunk/README.libraries z3/deliverance/buildout/trunk/buildout.cfg Log: wraps distutils scripts to set LD_LIBRARY_PATH when using buildout binaries Modified: z3/deliverance/buildout/trunk/README.libraries ============================================================================== --- z3/deliverance/buildout/trunk/README.libraries (original) +++ z3/deliverance/buildout/trunk/README.libraries Tue Nov 7 23:43:19 2006 @@ -1,9 +1,6 @@ -if you see output from the compiler during the buildout along the lines of: -unrecognized option '-R/your/buildout/path/parts/libxml2/lib' - -or the message: +if you recieve the message: UserWarning: Deliverance requires the CVS HEAD version of libxml2 this indicates the build has not properly built lxml to use the versions of libxml2 and libxslt Modified: z3/deliverance/buildout/trunk/buildout.cfg ============================================================================== --- z3/deliverance/buildout/trunk/buildout.cfg (original) +++ z3/deliverance/buildout/trunk/buildout.cfg Tue Nov 7 23:43:19 2006 @@ -1,6 +1,6 @@ [buildout] -develop = zc.recipe.cmmi deliverance -parts = libxml2 libxslt lxml lxml-inst deliverance-inst +develop = zc.recipe.cmmi deliverance fixlibsearch +parts = libxml2 libxslt lxml lxml-inst deliverance-inst fix-deliverance-scripts [libxml2] recipe = zc.recipe.cmmi @@ -27,3 +27,8 @@ recipe = zc.recipe.egg eggs = deliverance +[fix-deliverance-scripts] +recipe = topp.fixlibsearch +eggs = deliverance +libpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libxslt/lib + Added: z3/deliverance/buildout/trunk/fixlibsearch/README.txt ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/README.txt Tue Nov 7 23:43:19 2006 @@ -0,0 +1,4 @@ +This is a recipe to hack runtime library search paths into +the scripts created by distutils. On certain platforms, +distutils does not pass the correct library flags to +gcc during linking. Added: z3/deliverance/buildout/trunk/fixlibsearch/setup.py ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/setup.py Tue Nov 7 23:43:19 2006 @@ -0,0 +1,23 @@ +from setuptools import setup, find_packages + +name = "topp.fixlibsearch" +setup( + name = name, + version = "1.0", + author = "", + author_email = "", + description = "ZC Buildout recipe to hack distutils scripts", + long_description = open('README.txt').read(), + license = "GPL", + keywords = "", + url='http://svn.zope.org/'+name, + + packages = find_packages(), + include_package_data = True, + data_files = [('.', ['README.txt'])], + install_requires = ['zc.buildout', 'zope.testing', 'zc.recipe.egg', + 'setuptools'], + dependency_links = ['http://download.zope.org/distribution/'], + entry_points = {'zc.buildout': + ['default = %s:Recipe' % name]}, + ) Added: z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/PKG-INFO ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/PKG-INFO Tue Nov 7 23:43:19 2006 @@ -0,0 +1,14 @@ +Metadata-Version: 1.0 +Name: topp.fixlibsearch +Version: 1.0 +Summary: ZC Buildout recipe to hack distutils scripts +Home-page: http://svn.zope.org/topp.fixlibsearch +Author: UNKNOWN +Author-email: UNKNOWN +License: GPL +Description: This is a recipe to hack runtime library search paths into + the scripts created by distutils. On certain platforms, + distutils does not pass the correct library flags to + gcc during linking. + +Platform: UNKNOWN Added: z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/SOURCES.txt ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/SOURCES.txt Tue Nov 7 23:43:19 2006 @@ -0,0 +1,10 @@ +README.txt +setup.py +topp/__init__.py +topp.fixlibsearch.egg-info/PKG-INFO +topp.fixlibsearch.egg-info/SOURCES.txt +topp.fixlibsearch.egg-info/dependency_links.txt +topp.fixlibsearch.egg-info/entry_points.txt +topp.fixlibsearch.egg-info/requires.txt +topp.fixlibsearch.egg-info/top_level.txt +topp/fixlibsearch/__init__.py Added: z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/dependency_links.txt ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/dependency_links.txt Tue Nov 7 23:43:19 2006 @@ -0,0 +1 @@ +http://download.zope.org/distribution/ Added: z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/entry_points.txt ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/entry_points.txt Tue Nov 7 23:43:19 2006 @@ -0,0 +1,3 @@ +[zc.buildout] +default = topp.fixlibsearch:Recipe + Added: z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/requires.txt ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/requires.txt Tue Nov 7 23:43:19 2006 @@ -0,0 +1,4 @@ +zc.buildout +zope.testing +zc.recipe.egg +setuptools \ No newline at end of file Added: z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/top_level.txt ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/top_level.txt Tue Nov 7 23:43:19 2006 @@ -0,0 +1 @@ +topp Added: z3/deliverance/buildout/trunk/fixlibsearch/topp/__init__.py ============================================================================== Added: z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py Tue Nov 7 23:43:19 2006 @@ -0,0 +1,53 @@ +from zc.recipe.egg import Egg +import pkg_resources +import os,stat + +class Recipe: + + def __init__(self, buildout, name, options): + self.options = options + self.buildout = buildout + self.name = name + + def install(self): + options = self.options + dists = [ + r.strip() + for r in options.get('eggs', self.name).split('\n') + if r.strip()] + + libpath = options.get('libpath').strip() + + bindir = self.buildout['buildout']['bin-directory'] + + for dist in dists: + for script in pkg_resources.get_entry_map(dist, 'console_scripts').keys(): + self.fixscript(os.path.join(bindir,script), libpath) + + + return () + + + + def fixscript(self, script, libpath): + """ + wraps distutils script to set LD_LIBRARY_PATH to libpath + """ + + oldscript = script + ".wrapped" + interpreter = open(script).readline()[2:].strip() + + os.rename(script,oldscript) + + s = open(script, 'w') + s.write(''.join(["#!%s\n\n" % interpreter, + "import os\n", + "import subprocess\n", + "os.environ['LD_LIBRARY_PATH'] = '%s'\n\n" % libpath, + "if __name__ == '__main__':\n", + " subprocess.call(['%s', '%s'])" % (interpreter,oldscript) + ])) + + + os.chmod(script, + stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH) From ltucker at codespeak.net Tue Nov 7 23:43:58 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Tue, 7 Nov 2006 23:43:58 +0100 (CET) Subject: [z3-checkins] r34352 - z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info Message-ID: <20061107224358.9980A10075@code0.codespeak.net> Author: ltucker Date: Tue Nov 7 23:43:56 2006 New Revision: 34352 Removed: z3/deliverance/buildout/trunk/fixlibsearch/topp.fixlibsearch.egg-info/ Log: removing generated egg-info From ltucker at codespeak.net Tue Nov 7 23:55:10 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Tue, 7 Nov 2006 23:55:10 +0100 (CET) Subject: [z3-checkins] r34353 - z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch Message-ID: <20061107225510.1A42710075@code0.codespeak.net> Author: ltucker Date: Tue Nov 7 23:55:07 2006 New Revision: 34353 Modified: z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py Log: right... scripts need command line arguments... Modified: z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py ============================================================================== --- z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py (original) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py Tue Nov 7 23:55:07 2006 @@ -42,10 +42,11 @@ s = open(script, 'w') s.write(''.join(["#!%s\n\n" % interpreter, "import os\n", + "import sys\n", "import subprocess\n", "os.environ['LD_LIBRARY_PATH'] = '%s'\n\n" % libpath, "if __name__ == '__main__':\n", - " subprocess.call(['%s', '%s'])" % (interpreter,oldscript) + " subprocess.call(['%s', '%s'] + sys.argv)" % (interpreter,oldscript) ])) From ltucker at codespeak.net Wed Nov 8 00:00:03 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 8 Nov 2006 00:00:03 +0100 (CET) Subject: [z3-checkins] r34354 - z3/deliverance/buildout/trunk Message-ID: <20061107230003.B4EE610075@code0.codespeak.net> Author: ltucker Date: Wed Nov 8 00:00:00 2006 New Revision: 34354 Modified: z3/deliverance/buildout/trunk/README.txt Log: adding brief proxy command line example Modified: z3/deliverance/buildout/trunk/README.txt ============================================================================== --- z3/deliverance/buildout/trunk/README.txt (original) +++ z3/deliverance/buildout/trunk/README.txt Wed Nov 8 00:00:00 2006 @@ -16,7 +16,13 @@ You should then be able to run the deliverance-handtransform and -deliverance-proxy in bin. +deliverance-proxy in bin, eg: + + ./bin/deliverance-proxy --serve=http://localhost:9999 + --proxy=http://www.openplans.org --rule=file:///home/ltucker/zcss.xml + --theme=http://www.csszengarden.org --rewrite + +run ./bin/deliverance-proxy --help for information To run tests: cd deliverance From ltucker at codespeak.net Wed Nov 8 00:01:46 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 8 Nov 2006 00:01:46 +0100 (CET) Subject: [z3-checkins] r34355 - z3/deliverance/buildout/trunk Message-ID: <20061107230146.9441410075@code0.codespeak.net> Author: ltucker Date: Wed Nov 8 00:01:45 2006 New Revision: 34355 Modified: z3/deliverance/buildout/trunk/README.txt Log: add pointer do deliverance README.txt Modified: z3/deliverance/buildout/trunk/README.txt ============================================================================== --- z3/deliverance/buildout/trunk/README.txt (original) +++ z3/deliverance/buildout/trunk/README.txt Wed Nov 8 00:01:45 2006 @@ -6,6 +6,7 @@ build of Deliverance and its dependencies. See: http://www.openplans.org/projects/deliverance +and ./deliverance/README.txt for more information on Deliverance @@ -16,7 +17,7 @@ You should then be able to run the deliverance-handtransform and -deliverance-proxy in bin, eg: +deliverance-proxy which are in bin, eg: ./bin/deliverance-proxy --serve=http://localhost:9999 --proxy=http://www.openplans.org --rule=file:///home/ltucker/zcss.xml From ltucker at codespeak.net Wed Nov 8 00:36:16 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 8 Nov 2006 00:36:16 +0100 (CET) Subject: [z3-checkins] r34356 - z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch Message-ID: <20061107233616.0584810075@code0.codespeak.net> Author: ltucker Date: Wed Nov 8 00:36:12 2006 New Revision: 34356 Modified: z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py Log: leave off sys.argv[0] when tacking on script arguments Modified: z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py ============================================================================== --- z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py (original) +++ z3/deliverance/buildout/trunk/fixlibsearch/topp/fixlibsearch/__init__.py Wed Nov 8 00:36:12 2006 @@ -46,7 +46,9 @@ "import subprocess\n", "os.environ['LD_LIBRARY_PATH'] = '%s'\n\n" % libpath, "if __name__ == '__main__':\n", - " subprocess.call(['%s', '%s'] + sys.argv)" % (interpreter,oldscript) + " args = ['%s', '%s']\n" % (interpreter,oldscript), + " args += sys.argv[1:]\n", + " subprocess.call(args)" ])) From ltucker at codespeak.net Wed Nov 8 00:37:40 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 8 Nov 2006 00:37:40 +0100 (CET) Subject: [z3-checkins] r34357 - z3/deliverance/buildout/trunk Message-ID: <20061107233740.8CDF210075@code0.codespeak.net> Author: ltucker Date: Wed Nov 8 00:37:38 2006 New Revision: 34357 Modified: z3/deliverance/buildout/trunk/README.txt Log: change example to not point at domain squatters Modified: z3/deliverance/buildout/trunk/README.txt ============================================================================== --- z3/deliverance/buildout/trunk/README.txt (original) +++ z3/deliverance/buildout/trunk/README.txt Wed Nov 8 00:37:38 2006 @@ -21,7 +21,7 @@ ./bin/deliverance-proxy --serve=http://localhost:9999 --proxy=http://www.openplans.org --rule=file:///home/ltucker/zcss.xml - --theme=http://www.csszengarden.org --rewrite + --theme=http://www.csszengarden.com --rewrite run ./bin/deliverance-proxy --help for information From ltucker at codespeak.net Mon Nov 13 22:53:06 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 13 Nov 2006 22:53:06 +0100 (CET) Subject: [z3-checkins] r34589 - z3/deliverance/buildout/trunk Message-ID: <20061113215306.AAAC8101CE@code0.codespeak.net> Author: ltucker Date: Mon Nov 13 22:53:05 2006 New Revision: 34589 Modified: z3/deliverance/buildout/trunk/buildout.cfg Log: include-path change for lxml Modified: z3/deliverance/buildout/trunk/buildout.cfg ============================================================================== --- z3/deliverance/buildout/trunk/buildout.cfg (original) +++ z3/deliverance/buildout/trunk/buildout.cfg Mon Nov 13 22:53:05 2006 @@ -16,7 +16,7 @@ [lxml] recipe = zc.recipe.egg:custom eggs = lxml -include-dirs = ${buildout:directory}/parts/libxml2/include:${buildout:directory}/parts/libxslt/include +include-dirs = ${buildout:directory}/parts/libxml2/include/libxml2:${buildout:directory}/parts/libxslt/include rpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libxslt/lib [lxml-inst] From ltucker at codespeak.net Wed Nov 15 06:34:39 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 15 Nov 2006 06:34:39 +0100 (CET) Subject: [z3-checkins] r34613 - in z3/deliverance/buildout/trunk: . fixlibsearch helpers helpers/topp helpers/topp/helpers Message-ID: <20061115053439.D882610087@code0.codespeak.net> Author: ltucker Date: Wed Nov 15 06:34:09 2006 New Revision: 34613 Added: z3/deliverance/buildout/trunk/helpers/ z3/deliverance/buildout/trunk/helpers/README.txt z3/deliverance/buildout/trunk/helpers/setup.py z3/deliverance/buildout/trunk/helpers/topp/ z3/deliverance/buildout/trunk/helpers/topp/__init__.py z3/deliverance/buildout/trunk/helpers/topp/helpers/ z3/deliverance/buildout/trunk/helpers/topp/helpers/__init__.py z3/deliverance/buildout/trunk/helpers/topp/helpers/addbinpath.py z3/deliverance/buildout/trunk/helpers/topp/helpers/fixlibsearch.py Removed: z3/deliverance/buildout/trunk/fixlibsearch/ Modified: z3/deliverance/buildout/trunk/buildout.cfg Log: partial work to remove dependency on existing libxml2/xslt install Modified: z3/deliverance/buildout/trunk/buildout.cfg ============================================================================== --- z3/deliverance/buildout/trunk/buildout.cfg (original) +++ z3/deliverance/buildout/trunk/buildout.cfg Wed Nov 15 06:34:09 2006 @@ -1,11 +1,11 @@ [buildout] -develop = zc.recipe.cmmi deliverance fixlibsearch -parts = libxml2 libxslt lxml lxml-inst deliverance-inst fix-deliverance-scripts +develop = zc.recipe.cmmi deliverance helpers +parts = fix-bin-path libxml2 libxslt lxml lxml-inst deliverance-inst fix-deliverance-scripts [libxml2] recipe = zc.recipe.cmmi url = ftp://xmlsoft.org/libxml2/libxml2-2.6.27.tar.gz -extra_options = --without-python +extra_options = --without-python [libxslt] recipe = zc.recipe.cmmi @@ -27,8 +27,11 @@ recipe = zc.recipe.egg eggs = deliverance +[fix-bin-path] +recipe = topp.helpers:addbinpath +path = ${buildout:directory}/parts/libxml2/bin:${buildout:directory}/parts/libxslt/bin + [fix-deliverance-scripts] -recipe = topp.fixlibsearch +recipe = topp.helpers:fixlibsearch eggs = deliverance libpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libxslt/lib - Added: z3/deliverance/buildout/trunk/helpers/README.txt ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/helpers/README.txt Wed Nov 15 06:34:09 2006 @@ -0,0 +1,4 @@ +This is a recipe to hack runtime library search paths into +the scripts created by distutils. On certain platforms, +distutils does not pass the correct library flags to +gcc during linking. Added: z3/deliverance/buildout/trunk/helpers/setup.py ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/helpers/setup.py Wed Nov 15 06:34:09 2006 @@ -0,0 +1,24 @@ +from setuptools import setup, find_packages + +name = "topp.helpers" +setup( + name = name, + version = "1.0", + author = "", + author_email = "", + description = "ZC Buildout recipe to hack distutils scripts", + long_description = open('README.txt').read(), + license = "GPL", + keywords = "", + url='http://svn.zope.org/'+name, + + packages = find_packages(), + include_package_data = True, + data_files = [('.', ['README.txt'])], + install_requires = ['zc.buildout', 'zope.testing', 'zc.recipe.egg', + 'setuptools'], + dependency_links = ['http://download.zope.org/distribution/'], + entry_points = {'zc.buildout': + ['addbinpath = topp.helpers.addbinpath:Recipe', + 'fixlibsearch = topp.helpers.fixlibsearch:Recipe']}, + ) Added: z3/deliverance/buildout/trunk/helpers/topp/__init__.py ============================================================================== Added: z3/deliverance/buildout/trunk/helpers/topp/helpers/__init__.py ============================================================================== Added: z3/deliverance/buildout/trunk/helpers/topp/helpers/addbinpath.py ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/helpers/topp/helpers/addbinpath.py Wed Nov 15 06:34:09 2006 @@ -0,0 +1,25 @@ +import os + +class Recipe: + + def __init__(self, buildout, name, options): + self.options = options + self.buildout = buildout + self.name = name + + def install(self): + options = self.options + path = options.get('path') + if path is None: + return () + + oldpath = os.environ.get('PATH','') + + newpathelts = path.split(':') + oldpathelts = oldpath.split(':') + os.environ['PATH'] = ':'.join(newpathelts + oldpathelts) + print "PATH =", os.environ['PATH'] + + return () + + Added: z3/deliverance/buildout/trunk/helpers/topp/helpers/fixlibsearch.py ============================================================================== --- (empty file) +++ z3/deliverance/buildout/trunk/helpers/topp/helpers/fixlibsearch.py Wed Nov 15 06:34:09 2006 @@ -0,0 +1,55 @@ +import pkg_resources +import os,stat + +class Recipe: + + def __init__(self, buildout, name, options): + self.options = options + self.buildout = buildout + self.name = name + + def install(self): + options = self.options + dists = [ + r.strip() + for r in options.get('eggs', self.name).split('\n') + if r.strip()] + + libpath = options.get('libpath').strip() + + bindir = self.buildout['buildout']['bin-directory'] + + for dist in dists: + for script in pkg_resources.get_entry_map(dist, 'console_scripts').keys(): + self.fixscript(os.path.join(bindir,script), libpath) + + + return () + + + + def fixscript(self, script, libpath): + """ + wraps distutils script to set LD_LIBRARY_PATH to libpath + """ + + oldscript = script + ".wrapped" + interpreter = open(script).readline()[2:].strip() + + os.rename(script,oldscript) + + s = open(script, 'w') + s.write(''.join(["#!%s\n\n" % interpreter, + "import os\n", + "import sys\n", + "import subprocess\n", + "os.environ['LD_LIBRARY_PATH'] = '%s'\n\n" % libpath, + "if __name__ == '__main__':\n", + " args = ['%s', '%s']\n" % (interpreter,oldscript), + " args += sys.argv[1:]\n", + " subprocess.call(args)" + ])) + + + os.chmod(script, + stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH) From ltucker at codespeak.net Wed Nov 15 06:52:17 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 15 Nov 2006 06:52:17 +0100 (CET) Subject: [z3-checkins] r34614 - z3/deliverance/buildout/trunk/helpers Message-ID: <20061115055217.ED07B10087@code0.codespeak.net> Author: ltucker Date: Wed Nov 15 06:52:14 2006 New Revision: 34614 Modified: z3/deliverance/buildout/trunk/helpers/README.txt z3/deliverance/buildout/trunk/helpers/setup.py Log: just documentation updates Modified: z3/deliverance/buildout/trunk/helpers/README.txt ============================================================================== --- z3/deliverance/buildout/trunk/helpers/README.txt (original) +++ z3/deliverance/buildout/trunk/helpers/README.txt Wed Nov 15 06:52:14 2006 @@ -1,4 +1,6 @@ -This is a recipe to hack runtime library search paths into +addbinpath is a recipe to insert entries into $PATH + +fixlibsearch is a recipe to hack runtime library search paths into the scripts created by distutils. On certain platforms, distutils does not pass the correct library flags to gcc during linking. Modified: z3/deliverance/buildout/trunk/helpers/setup.py ============================================================================== --- z3/deliverance/buildout/trunk/helpers/setup.py (original) +++ z3/deliverance/buildout/trunk/helpers/setup.py Wed Nov 15 06:52:14 2006 @@ -6,7 +6,7 @@ version = "1.0", author = "", author_email = "", - description = "ZC Buildout recipe to hack distutils scripts", + description = "ZC Buildout recipe to add entries to PATH and hack distutils scripts", long_description = open('README.txt').read(), license = "GPL", keywords = "", @@ -15,7 +15,7 @@ packages = find_packages(), include_package_data = True, data_files = [('.', ['README.txt'])], - install_requires = ['zc.buildout', 'zope.testing', 'zc.recipe.egg', + install_requires = ['zc.buildout', 'setuptools'], dependency_links = ['http://download.zope.org/distribution/'], entry_points = {'zc.buildout': From ltucker at codespeak.net Wed Nov 15 07:23:23 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Wed, 15 Nov 2006 07:23:23 +0100 (CET) Subject: [z3-checkins] r34615 - z3/deliverance/buildout/trunk Message-ID: <20061115062323.182F310083@code0.codespeak.net> Author: ltucker Date: Wed Nov 15 07:23:20 2006 New Revision: 34615 Modified: z3/deliverance/buildout/trunk/buildout.cfg Log: eliminates need for pre-existing libxml2/xslt by working around a bug in lxml setup.py Modified: z3/deliverance/buildout/trunk/buildout.cfg ============================================================================== --- z3/deliverance/buildout/trunk/buildout.cfg (original) +++ z3/deliverance/buildout/trunk/buildout.cfg Wed Nov 15 07:23:20 2006 @@ -1,13 +1,13 @@ [buildout] develop = zc.recipe.cmmi deliverance helpers -parts = fix-bin-path libxml2 libxslt lxml lxml-inst deliverance-inst fix-deliverance-scripts +parts = fix-bin-path libxml2 libXslt lxml lxml-inst deliverance-inst fix-deliverance-scripts [libxml2] recipe = zc.recipe.cmmi url = ftp://xmlsoft.org/libxml2/libxml2-2.6.27.tar.gz extra_options = --without-python -[libxslt] +[libXslt] recipe = zc.recipe.cmmi url = ftp://xmlsoft.org/libxml2/libxslt-1.1.18.tar.gz extra_options = --with-libxml-prefix=${buildout:directory}/parts/libxml2/ @@ -16,8 +16,8 @@ [lxml] recipe = zc.recipe.egg:custom eggs = lxml -include-dirs = ${buildout:directory}/parts/libxml2/include/libxml2:${buildout:directory}/parts/libxslt/include -rpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libxslt/lib +include-dirs = ${buildout:directory}/parts/libxml2/include/libxml2:${buildout:directory}/parts/libXslt/include +rpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libXslt/lib [lxml-inst] recipe = zc.recipe.egg @@ -29,9 +29,9 @@ [fix-bin-path] recipe = topp.helpers:addbinpath -path = ${buildout:directory}/parts/libxml2/bin:${buildout:directory}/parts/libxslt/bin +path = ${buildout:directory}/parts/libxml2/bin:${buildout:directory}/parts/libXslt/bin [fix-deliverance-scripts] recipe = topp.helpers:fixlibsearch eggs = deliverance -libpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libxslt/lib +libpath = ${buildout:directory}/parts/libxml2/lib:${buildout:directory}/parts/libXslt/lib From ianb at codespeak.net Thu Nov 16 19:17:43 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 16 Nov 2006 19:17:43 +0100 (CET) Subject: [z3-checkins] r34686 - z3/deliverance/trunk/deliverance Message-ID: <20061116181743.1DF2F100F8@code0.codespeak.net> Author: ianb Date: Thu Nov 16 19:17:40 2006 New Revision: 34686 Modified: z3/deliverance/trunk/deliverance/tests.py Log: Add some nose options that I like (also find doctests) Modified: z3/deliverance/trunk/deliverance/tests.py ============================================================================== --- z3/deliverance/trunk/deliverance/tests.py (original) +++ z3/deliverance/trunk/deliverance/tests.py Thu Nov 16 19:17:40 2006 @@ -110,6 +110,13 @@ def main(args=None): + # Kind of a crude way to pass info to nose... + os.environ.update(dict( + NOSE_WHERE=os.path.dirname(__file__), + NOSE_DETAILED_ERRORS='t', + NOSE_WITH_DOCTEST='t', + NOSE_DOCTEST_EXTENSION='.txt', + NOSE_WITH_MISSING_TESTS='t')) import nose; nose.main() if __name__ == '__main__': From ianb at codespeak.net Thu Nov 16 19:18:27 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 16 Nov 2006 19:18:27 +0100 (CET) Subject: [z3-checkins] r34687 - z3/deliverance/trunk/deliverance Message-ID: <20061116181827.B3CAE100F8@code0.codespeak.net> Author: ianb Date: Thu Nov 16 19:18:24 2006 New Revision: 34687 Added: z3/deliverance/trunk/deliverance/test_relocate.txt (contents, props changed) Modified: z3/deliverance/trunk/deliverance/fixuplinks.py z3/deliverance/trunk/deliverance/relocateresponse.py Log: Tests for link relocating, and some bug fixes: respect base href, and handling http://foo (with no trailing slash) as identical to http://foo/ Modified: z3/deliverance/trunk/deliverance/fixuplinks.py ============================================================================== --- z3/deliverance/trunk/deliverance/fixuplinks.py (original) +++ z3/deliverance/trunk/deliverance/fixuplinks.py Thu Nov 16 19:18:24 2006 @@ -4,6 +4,7 @@ from htmlserialize import decodeAndParseHTML, tostring +import urlparse import re def fixup_text_links(doc, link_repl_func, remove_base_tags=True): @@ -22,7 +23,7 @@ output of that function replaces the link. """ if remove_base_tags: - remove_base_tags_from_document(doc) + resolve_base_tags_in_document(doc) for attrib in 'href', 'src': els = doc.xpath('//*[@%s]' % attrib) @@ -31,14 +32,23 @@ fixup_css_links(doc, link_repl_func) -def remove_base_tags_from_document(doc): +def resolve_base_tags_in_document(doc): """ removes all html tags from the document given. """ + base_href = None basetags = doc.xpath('//base[@href]') for b in basetags: + base_href = b.attrib['href'] b.getparent().remove(b) + if base_href is None: + return + # Now that we have a base_href (blech) we have to fix up all the + # links in the document with this new information. + def link_repl(href): + return urlparse.urljoin(base_href, href) + fixup_links(doc, link_repl, remove_base_tags=False) CSS_URL_PAT = re.compile(r'url\((.*?)\)', re.I) def fixup_css_links(doc, link_repl_func): Modified: z3/deliverance/trunk/deliverance/relocateresponse.py ============================================================================== --- z3/deliverance/trunk/deliverance/relocateresponse.py (original) +++ z3/deliverance/trunk/deliverance/relocateresponse.py Thu Nov 16 19:18:24 2006 @@ -2,10 +2,11 @@ Takes a response (headers + content) and relocates it, changing domain names and paths. """ -import fixuplinks import urlparse +import re from paste.request import construct_url from paste.response import header_value +import fixuplinks def relocate_response(headers, content, base_href, old_href, new_href): """ @@ -29,8 +30,14 @@ return relocate_href(href, base_href, old_href, new_href) return fixuplinks.fixup_text_links(content, sub_link) +# This catches the case of http://foo, which is equivalent to +# http://foo/ : +_domain_no_slash_re = re.compile(r'^[a-z]+://[^/]+$', re.I) + def relocate_href(href, base_href, old_href, new_href): real_href = urlparse.urljoin(base_href, href) + if _domain_no_slash_re.search(real_href): + real_href += '/' if not real_href.startswith(old_href): return href return new_href + real_href[len(old_href):] Added: z3/deliverance/trunk/deliverance/test_relocate.txt ============================================================================== --- (empty file) +++ z3/deliverance/trunk/deliverance/test_relocate.txt Thu Nov 16 19:18:24 2006 @@ -0,0 +1,92 @@ +These are tests of relocateresponse:: + + >>> from deliverance.relocateresponse import * + +In all these examples we'll be using ``http://old`` for the old +(to-be-replaced) URL and ``https://new`` for the new URL (note the +scheme change). Out of laziness we'll define some keywords we use +with all these transformations:: + + >>> kw = dict(base_href='http://old/base/path.html', + ... old_href='http://old/', + ... new_href='https://new/') + +Now lets look at simple href rewriting. + +Normal rewrite:: + + >>> relocate_href('http://old/bar', **kw) + 'https://new/bar' + +Note that the trailing doesn't matter in this one case (since +``http://old`` and ``http://old/`` are entirely equivalent):: + + >>> relocate_href('http://old', **kw) + 'https://new/' + +It does in other cases:: + + >>> relocate_href('http://old-test/foo', + ... base_href='', + ... old_href='http://old-test/foo/', + ... new_href='https://new') + 'http://old-test/foo' + >>> relocate_href('http://old-test/foo/', + ... base_href='', + ... old_href='http://old-test/foo/', + ... new_href='https://new') + 'https://new' + +Rewriting a link that doesn't match old_href is a no-op:: + + >>> relocate_href('http://foo/bar', **kw) + 'http://foo/bar' + +Relative links are handled:: + + >>> relocate_href('index.html', **kw) + 'https://new/base/index.html' + +Now we look at header rewriting. Note that Location is rewritten, but +other headers are not. (Set-Cookie should also get some rewriting, +but does not yet):: + + >>> relocate_headers([('X-Unknown', 'http://old'), + ... ('Location', 'http://old/foo/bar')], + ... **kw) + [('X-Unknown', 'http://old'), ('Location', 'https://new/foo/bar')] + +But the location header won't be rewritten if it points to a +third-party site:: + + >>> relocate_headers([('Location', 'http://foo/bar')], + ... **kw) + [('Location', 'http://foo/bar')] + +Now for content. First, to make it easier on us, we need to trim the +normalized HTML we get from these functions:: + + >>> import re + >>> def pr_html(html): + ... html = re.sub(r'', '', html) + ... html = re.sub(r'', '', html) + ... print html.strip() + +Some basics:: + + >>> pr_html(relocate_content( + ... 'link', **kw)) + link + >>> pr_html(relocate_content( + ... '', **kw)) + + >>> pr_html(relocate_content( + ... '', **kw)) + + >>> pr_html(relocate_content('''\ + ... + ... + ... x\ + ... ''', **kw)) + + x From ianb at codespeak.net Thu Nov 16 19:37:21 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 16 Nov 2006 19:37:21 +0100 (CET) Subject: [z3-checkins] r34690 - z3/deliverance/trunk/deliverance Message-ID: <20061116183721.B246E100F8@code0.codespeak.net> Author: ianb Date: Thu Nov 16 19:37:17 2006 New Revision: 34690 Modified: z3/deliverance/trunk/deliverance/relocateresponse.py z3/deliverance/trunk/deliverance/test_relocate.txt Log: Added cookie domain rewriting Modified: z3/deliverance/trunk/deliverance/relocateresponse.py ============================================================================== --- z3/deliverance/trunk/deliverance/relocateresponse.py (original) +++ z3/deliverance/trunk/deliverance/relocateresponse.py Thu Nov 16 19:37:17 2006 @@ -22,6 +22,16 @@ for name, value in headers: if name.lower() == 'location': value = relocate_href(value, base_href, old_href, new_href) + if name.lower() == 'set-cookie': + if 'domain' in value: + # We have to rewrite the domain + old_domain = urlparse.urlsplit(old_href)[1].split(':')[0] + new_domain = urlparse.urlsplit(new_href)[1].split(':')[0] + def repl(match): + return match.group(1)+new_domain + value = re.sub( + r'(domain=[^ ",]*)%s' % re.escape(old_domain), + repl, value) new_headers.append((name, value)) return new_headers Modified: z3/deliverance/trunk/deliverance/test_relocate.txt ============================================================================== --- z3/deliverance/trunk/deliverance/test_relocate.txt (original) +++ z3/deliverance/trunk/deliverance/test_relocate.txt Thu Nov 16 19:37:17 2006 @@ -47,14 +47,23 @@ >>> relocate_href('index.html', **kw) 'https://new/base/index.html' -Now we look at header rewriting. Note that Location is rewritten, but -other headers are not. (Set-Cookie should also get some rewriting, -but does not yet):: +Now we look at header rewriting. Note that Location and Set-Cookie is +rewritten, but other headers are not:: - >>> relocate_headers([('X-Unknown', 'http://old'), - ... ('Location', 'http://old/foo/bar')], - ... **kw) - [('X-Unknown', 'http://old'), ('Location', 'https://new/foo/bar')] + >>> relocate_headers( + ... [('X-Unknown', 'http://old'), + ... ('Location', 'http://old/foo/bar'), + ... ('Set-Cookie', 'foo=bar; domain=old')], + ... **kw) + [('X-Unknown', 'http://old'), ('Location', 'https://new/foo/bar'), ('Set-Cookie', 'foo=bar; domain=new')] + +We'll even rewrite wildcard domains, though that might not be a good +idea:: + + >>> relocate_headers( + ... [('Set-Cookie', 'foo=bar; domain=*.old')], + ... **kw) + [('Set-Cookie', 'foo=bar; domain=*.new')] But the location header won't be rewritten if it points to a third-party site:: From ianb at codespeak.net Thu Nov 16 23:05:19 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 16 Nov 2006 23:05:19 +0100 (CET) Subject: [z3-checkins] r34696 - z3/deliverance/trunk/deliverance Message-ID: <20061116220519.86D8B100AA@code0.codespeak.net> Author: ianb Date: Thu Nov 16 23:05:15 2006 New Revision: 34696 Added: z3/deliverance/trunk/deliverance/wsgimiddleware.py - copied unchanged from r34683, z3/deliverance/trunk/deliverance/wsgifilter.py Removed: z3/deliverance/trunk/deliverance/wsgifilter.py Modified: z3/deliverance/trunk/deliverance/proxyapp.py z3/deliverance/trunk/deliverance/test_wsgi.py Log: Renamed wsgifilter module to wsgimiddleware, to avoid name conflict with WSGIFilter Modified: z3/deliverance/trunk/deliverance/proxyapp.py ============================================================================== --- z3/deliverance/trunk/deliverance/proxyapp.py (original) +++ z3/deliverance/trunk/deliverance/proxyapp.py Thu Nov 16 23:05:15 2006 @@ -4,7 +4,7 @@ """ from paste.proxy import TransparentProxy -from deliverance import wsgifilter +from deliverance.wsgimiddleware import DeliveranceMiddleware from deliverance.relocateresponse import RelocateMiddleware class ProxyDeliveranceApp(object): @@ -18,7 +18,7 @@ self.transparent = transparent self.debug_headers = debug_headers self.subapp = self.make_app() - self.deliverance_app = wsgifilter.DeliveranceMiddleware( + self.deliverance_app = DeliveranceMiddleware( self.subapp, theme_uri, rule_uri, renderer) self.relocate_content = relocate_content Modified: z3/deliverance/trunk/deliverance/test_wsgi.py ============================================================================== --- z3/deliverance/trunk/deliverance/test_wsgi.py (original) +++ z3/deliverance/trunk/deliverance/test_wsgi.py Thu Nov 16 23:05:15 2006 @@ -3,7 +3,7 @@ from lxml import etree from paste.fixture import TestApp from paste.urlparser import StaticURLParser -from wsgifilter import DeliveranceMiddleware +from deliverance.wsgimiddleware import DeliveranceMiddleware from formencode.doctest_xml_compare import xml_compare from htmlserialize import tostring Deleted: /z3/deliverance/trunk/deliverance/wsgifilter.py ============================================================================== --- /z3/deliverance/trunk/deliverance/wsgifilter.py Thu Nov 16 23:05:15 2006 +++ (empty file) @@ -1,294 +0,0 @@ -""" -Deliverance theming as WSGI middleware -""" - -import re -import urlparse -import urllib -from lxml import etree -from htmlserialize import decodeAndParseHTML as parseHTML -from paste.wsgilib import intercept_output -from paste.request import construct_url -from paste.response import header_value, replace_header -from htmlserialize import tostring -from utils import DeliveranceError -from utils import DELIVERANCE_ERROR_PAGE -import sys -import datetime -import threading -import traceback -from StringIO import StringIO - -DELIVERANCE_BASE_URL = 'deliverance.base-url' - - -class DeliveranceMiddleware(object): - """ - a DeliveranceMiddleware object exposes a single deliverance - tranformation as a WSGI middleware component. - """ - - def __init__(self, app, theme_uri, rule_uri, renderer='py'): - """ - initializer - - app: wsgi application which this middleware wraps. - theme_uri: uri referring the the theme document - rule_uri: uri referring to the deliverance rules document - renderer: selects deliverance render class to utilize when - performing transformations, may be 'py' or 'xslt' - """ - self.app = app - self.theme_uri = theme_uri - self.rule_uri = rule_uri - self._renderer = None - self._cache_time = datetime.datetime.now() - self._timeout = datetime.timedelta(0,10) - self._lock = threading.Lock() - - if renderer == 'py': - import interpreter - self._rendererType = interpreter.Renderer - elif renderer == 'xslt': - import xslt - self._rendererType = xslt.Renderer - else: - raise ValueError("Unknown Renderer: %s - Expecting 'py' or 'xslt'" % renderer) - - def get_renderer(self,environ): - """ - retrieve the deliverance Renderer representing the transformation this - middlware represents. Renderer may change according to caching rules. - """ - try: - self._lock.acquire() - if not self._renderer or self.cache_expired(): - self._renderer = self.create_renderer(environ) - self._cache_time = datetime.datetime.now() - return self._renderer - finally: - self._lock.release() - - def create_renderer(self,environ): - """ - construct a new deliverance Renderer from the - information passed to the initializer. A new copy - of the theme and rules is retrieved. - """ - theme = self.theme(environ) - rule = self.rule(environ) - full_theme_uri = urlparse.urljoin( - construct_url(environ, with_path_info=False), - self.theme_uri) - - def reference_resolver(href, parse, encoding=None): - text = self.get_resource(environ,href) - if parse == "xml": - return etree.XML(text) - elif encoding: - return text.decode(encoding) - - try: - parsedTheme = parseHTML(theme) - except Exception, message: - newmessage = "Unable to parse theme page (" + self.theme_uri + ")" - if message: - newmessage += ":" + str(message) - raise DeliveranceError(newmessage) - - try: - parsedRule = etree.XML(rule) - except Exception, message: - newmessage = "Unable to parse rules (" + self.rule_uri + ")" - if message: - newmessage += ":" + str(message) - raise DeliveranceError(newmessage) - - return self._rendererType( - theme=parsedTheme, - theme_uri=full_theme_uri, - rule=parsedRule, - rule_uri=self.rule_uri, - reference_resolver=reference_resolver) - - - def cache_expired(self): - """ - returns true if the stored Renderer should be refreshed - """ - return self._cache_time + self._timeout < datetime.datetime.now() - - def rule(self, environ): - """ - retrieves the data referred to by the rule_uri passed to the - initializer. - """ - try: - return self.get_resource(environ,self.rule_uri) - except Exception, message: - newmessage = "Unable to retrieve rules from " + self.rule_uri - if message: - newmessage += ": " + str(message) - - raise DeliveranceError(newmessage) - - def theme(self, environ): - """ - retrieves the data referred to by the theme_uri passed to the - initializer. - """ - try: - return self.get_resource(environ,self.theme_uri) - except Exception, message: - newmessage = "Unable to retrieve theme page from " + self.theme_uri - if message: - newmessage += ": " + str(message) - raise DeliveranceError(newmessage) - - - def __call__(self, environ, start_response): - """ - WSGI entrypoint, responds to the request in - environ. responses from the wrapped WSGI - application of type text/html are themed - using the transformation specified in the - initializer. - """ - try: - qs = environ.get('QUERY_STRING', '') - environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False) - notheme = 'notheme' in qs - if notheme: - return self.app(environ, start_response) - if 'HTTP_ACCEPT_ENCODING' in environ: - del environ['HTTP_ACCEPT_ENCODING'] - - status, headers, body = intercept_output( - environ, self.app, - self.should_intercept, - start_response) - - # ignore non-html responses - if status is None: - return body - - # don't theme html snippets - if self.hasHTMLTag(body): - body = self.filter_body(environ, body) - - replace_header(headers, 'content-length', str(len(body))) - replace_header(headers, 'content-type', 'text/html; charset=utf-8') - start_response(status, headers) - return [body] - - except DeliveranceError, message: - stack = StringIO() - traceback.print_exception(sys.exc_info()[0], - sys.exc_info()[1], - sys.exc_info()[2], - file=stack) - status = "500 Internal Server Error" - headers = [('Content-type','text/html')] - start_response(status,headers) - errpage = DELIVERANCE_ERROR_PAGE % (message,stack.getvalue()) - return [ errpage ] - - def should_intercept(self, status, headers): - """ - returns true if the status and headers given - specify a response from the wrapped middleware - which deliverance may need to theme. - """ - type = header_value(headers, 'content-type') - if type is None: - return False - return type.startswith('text/html') or type.startswith('application/xhtml+xml') - - def filter_body(self, environ, body): - """ - returns the result of the deliverance transformation on the string 'body' - in the context of environ. The result is a string containing HTML. - """ - content = self.get_renderer(environ).render(parseHTML(body)) - return tostring(content) - - def get_resource(self, environ, uri): - """ - retrieve the data referred to by the uri given. - """ - internalBaseURL = environ.get(DELIVERANCE_BASE_URL,None) - uri = urlparse.urljoin(internalBaseURL, uri) - - if internalBaseURL and uri.startswith(internalBaseURL): - return self.get_internal_resource(environ, uri[len(internalBaseURL):]) - else: - return self.get_external_resource(uri) - - def relative_uri(self, uri): - """ - returns true if uri is relative, false if - the uri is absolute. - """ - if re.search(r'^[a-zA-Z]+:', uri): - return False - else: - return True - - def get_external_resource(self, uri): - """ - get the data referred to by the uri given - using urllib (not through the wrapped app) - """ - f = urllib.urlopen(uri) - content = f.read() - f.close() - return content - - def get_internal_resource(self, environ, uri): - """ - get the data referred to by the uri given - by using the wrapped WSGI application - """ - environ = environ.copy() - if not uri.startswith('/'): - uri = '/' + uri - environ['PATH_INFO'] = uri - environ['SCRIPT_NAME'] = environ[DELIVERANCE_BASE_URL] - if environ['QUERY_STRING']: - environ['QUERY_STRING'] += '¬heme' - else: - environ['QUERY_STRING'] = 'notheme' - - path_info = environ['PATH_INFO'] - status, headers, body = intercept_output(environ, self.app) - if not status.startswith('200'): - loc = header_value(headers, 'location') - if loc: - loc = ' location=%r' % loc - else: - loc = '' - raise DeliveranceError( - "Request for internal resource at %s (%r) failed with status code %r%s" - % (construct_url(environ), path_info, status, - loc)) - return body - - HTML_DOC_PAT = re.compile(r"^.*<\s*html(\s*|>).*$",re.I|re.M) - def hasHTMLTag(self, body): - """ - a quick and dirty check to see if some text contains - anything that looks like an html tag. This could - certainly be improved if needed or there are - ambiguous tags - """ - return self.HTML_DOC_PAT.search(body) is not None - -def make_filter(app, global_conf, - theme_uri=None, rule_uri=None): - assert theme_uri is not None, ( - "You must give a theme_uri") - assert rule_uri is not None, ( - "You must give a rule_uri") - return DeliveranceMiddleware( - app, theme_uri, rule_uri) - From ianb at codespeak.net Thu Nov 16 23:06:54 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 16 Nov 2006 23:06:54 +0100 (CET) Subject: [z3-checkins] r34697 - z3/deliverance/trunk/deliverance Message-ID: <20061116220654.EA7E5100AA@code0.codespeak.net> Author: ianb Date: Thu Nov 16 23:06:52 2006 New Revision: 34697 Added: z3/deliverance/trunk/deliverance/exp_proxycommand.py (contents, props changed) Log: Added frontend like deliverance-proxy, but using WSGIFilter. Not quite ready to actually use it yet, though; hence putting it in its own module instead of replacing proxycommand and proxyapp Added: z3/deliverance/trunk/deliverance/exp_proxycommand.py ============================================================================== --- (empty file) +++ z3/deliverance/trunk/deliverance/exp_proxycommand.py Thu Nov 16 23:06:52 2006 @@ -0,0 +1,48 @@ +""" +Experimental proxy command using WSGIFilter +""" + +import sys +import pkg_resources +pkg_resources.require('WSGIFilter') +from wsgifilter.proxycommand import * +from deliverance.wsgimiddleware import DeliveranceMiddleware + +def make_middleware_factory(theme_uri, rule_uri, renderer='py'): + def make_middleware(app): + return DeliveranceMiddleware( + app, theme_uri=theme_uri, rule_uri=rule_uri, + renderer=renderer) + return make_middleware + +def main(args=None): + if args is None: + args = sys.argv[1:] + parser = make_basic_optparser( + 'Deliverance') + parser.add_option( + '--theme', + help="The URI of the theme to use", + dest="theme_uri") + parser.add_option( + '--rule', + help="The URI of the ruleset to use", + dest="rule_uri") + parser.add_option( + '--renderer', + help="Select which renderer to use: 'py' or 'xslt'", + default='py') + options, args = parser.parse_args(args) + middleware = make_middleware_factory( + theme_uri=options.theme_uri, + rule_uri=options.rule_uri, + renderer=options.renderer) + run_proxy_command( + options, args, middleware, parser) + +if __name__ == '__main__': + import pkg_resources + pkg_resources.require('Deliverance') + from deliverance.exp_proxycommand import main as exp_main + exp_main() + From ianb at codespeak.net Fri Nov 17 21:28:19 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Fri, 17 Nov 2006 21:28:19 +0100 (CET) Subject: [z3-checkins] r34722 - in z3/deliverance/DeliveranceDemo: . branches tags trunk Message-ID: <20061117202819.34067100B7@code0.codespeak.net> Author: ianb Date: Fri Nov 17 21:28:16 2006 New Revision: 34722 Added: z3/deliverance/DeliveranceDemo/ z3/deliverance/DeliveranceDemo/branches/ z3/deliverance/DeliveranceDemo/tags/ z3/deliverance/DeliveranceDemo/trunk/ Log: New project DeliveranceDemo From ianb at codespeak.net Fri Nov 17 21:30:19 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Fri, 17 Nov 2006 21:30:19 +0100 (CET) Subject: [z3-checkins] r34723 - in z3/deliverance/DeliveranceDemo/trunk: . DeliveranceDemo.egg-info ddemo ddemo/config ddemo/controllers ddemo/docs ddemo/i18n ddemo/lib ddemo/models ddemo/public ddemo/templates ddemo/tests ddemo/tests/functional Message-ID: <20061117203019.A362C100A6@code0.codespeak.net> Author: ianb Date: Fri Nov 17 21:30:05 2006 New Revision: 34723 Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/ (props changed) z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paster_plugins.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/README.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/ z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/config/ z3/deliverance/DeliveranceDemo/trunk/ddemo/config/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/config/environment.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/config/middleware.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/config/routing.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/error.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/template.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/docs/ z3/deliverance/DeliveranceDemo/trunk/ddemo/docs/index.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/i18n/ z3/deliverance/DeliveranceDemo/trunk/ddemo/i18n/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/ z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/app_globals.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/base.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/helpers.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/models/ z3/deliverance/DeliveranceDemo/trunk/ddemo/models/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/public/ z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/ z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/autohandler z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/test_models.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/websetup.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/development.ini z3/deliverance/DeliveranceDemo/trunk/setup.cfg z3/deliverance/DeliveranceDemo/trunk/setup.py (contents, props changed) Log: New project layout Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl Fri Nov 17 21:30:05 2006 @@ -0,0 +1,40 @@ +# +# DeliveranceDemo - Pylons configuration +# +# The %(here)s variable will be replaced with the parent directory of this file +# +[DEFAULT] +debug = true +email_to = you at yourdomain.com +smtp_server = localhost +error_email_from = paste at localhost + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 5000 + +[app:main] +use = egg:DeliveranceDemo +cache_dir = %(here)s/data +session_key = ddemo +session_secret = ${app_instance_secret} +app_instance_uuid = ${app_instance_uuid} + +# If you'd like to fine-tune the individual locations of the cache data dirs +# for Myghty, the Cache data, or the Session saves, un-comment the desired +# settings here: +#myghty_data_dir = %(here)s/data/templates +#cache_data_dir = %(here)s/data/cache +#session_data_dir = %(here)s/data/sessions + +# Specify the database for SQLObject to use via pylons.database.PackageHub. +# %(here) may include a ':' character on Windows environments; this can +# invalidate the URI when specifying a SQLite db via path name. Refer to the +# SQLObject documentation for a special syntax to preserve the URI. +#sqlobject.dburi = sqlite:%(here)s/somedb.db + +# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* +# Debug mode will enable the interactive debugging tool, allowing ANYONE to +# execute malicious code after an exception is raised. +set debug = false Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paster_plugins.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paster_plugins.txt Fri Nov 17 21:30:05 2006 @@ -0,0 +1,3 @@ +Pylons +WebHelpers +PasteScript Added: z3/deliverance/DeliveranceDemo/trunk/README.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/README.txt Fri Nov 17 21:30:05 2006 @@ -0,0 +1,19 @@ +This file is for you to describe the DeliveranceDemo application. Typically +you would include information such as the information below: + +Installation and Setup +====================== + +Install ``DeliveranceDemo`` using easy_install:: + + easy_install DeliveranceDemo + +Make a config file as follows:: + + paster make-config DeliveranceDemo config.ini + +Tweak the config file as appropriate and then setup the application:: + + paster setup-app config.ini + +Then you are ready to go. Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,8 @@ +""" +ddemo + +This file loads the finished app from ddemo.config.middleware. + +""" + +from ddemo.config.middleware import make_app Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/config/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/config/__init__.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1 @@ +# Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/config/environment.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/config/environment.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,29 @@ +import os + +import pylons.config +import webhelpers + +from ddemo.config.routing import make_map + +def load_environment(global_conf={}, app_conf={}): + map = make_map(global_conf, app_conf) + # Setup our paths + root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + paths = {'root_path': root_path, + 'controllers': os.path.join(root_path, 'controllers'), + 'templates': [os.path.join(root_path, path) for path in \ + ('components', 'templates')], + 'static_files': os.path.join(root_path, 'public') + } + + # The following options are passed directly into Myghty, so all configuration options + # available to the Myghty handler are available for your use here + myghty = {} + myghty['log_errors'] = True + myghty['escapes'] = dict(l=webhelpers.auto_link, s=webhelpers.simple_format) + + # Add your own Myghty config options here, note that all config options will override + # any Pylons config options + + # Return our loaded config object + return pylons.config.Config(myghty, map, paths) Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/config/middleware.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/config/middleware.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,59 @@ +from paste import httpexceptions +from paste.cascade import Cascade +from paste.urlparser import StaticURLParser +from paste.registry import RegistryManager +from paste.deploy.config import ConfigMiddleware +from paste.deploy.converters import asbool + +from pylons.error import error_template +from pylons.middleware import ErrorHandler, ErrorDocuments, StaticJavascripts, error_mapper +import pylons.wsgiapp + +from ddemo.config.environment import load_environment +import ddemo.lib.helpers +import ddemo.lib.app_globals as app_globals + +def make_app(global_conf, full_stack=True, **app_conf): + """Create a WSGI application and return it + + global_conf is a dict representing the Paste configuration options, the + paste.deploy.converters should be used when parsing Paste config options + to ensure they're treated properly. + + """ + # Load our Pylons configuration defaults + config = load_environment(global_conf, app_conf) + config.init_app(global_conf, app_conf, package='ddemo') + + # Load our default Pylons WSGI app and make g available + app = pylons.wsgiapp.PylonsApp(config, helpers=ddemo.lib.helpers, + g=app_globals.Globals) + g = app.globals + app = ConfigMiddleware(app, {'app_conf':app_conf, + 'global_conf':global_conf}) + + # YOUR MIDDLEWARE + # Put your own middleware here, so that any problems are caught by the error + # handling middleware underneath + + # If errror handling and exception catching will be handled by middleware + # for multiple apps, you will want to set full_stack = False in your config + # file so that it can catch the problems. + if asbool(full_stack): + # Change HTTPExceptions to HTTP responses + app = httpexceptions.make_middleware(app, global_conf) + + # Error Handling + app = ErrorHandler(app, global_conf, error_template=error_template, **config.errorware) + + # Display error documents for 401, 403, 404 status codes (if debug is disabled also + # intercepts 500) + app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf) + + # Establish the Registry for this application + app = RegistryManager(app) + + static_app = StaticURLParser(config.paths['static_files']) + javascripts_app = StaticJavascripts() + app = Cascade([static_app, javascripts_app, app]) + return app Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/config/routing.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/config/routing.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,23 @@ +""" +Setup your Routes options here +""" +import sys, os +from routes import Mapper + +def make_map(global_conf={}, app_conf={}): + root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + map = Mapper(directory=os.path.join(root_path, 'controllers')) + + # This route handles displaying the error page and graphics used in the 404/500 + # error pages. It should likely stay at the top to ensure that the error page is + # displayed properly. + map.connect('error/:action/:id', controller='error') + + # Define your routes. The more specific and detailed routes should be defined first, + # so they may take precedent over the more generic routes. For more information, refer + # to the routes manual @ http://routes.groovie.org/docs/ + map.connect(':controller/:action/:id') + map.connect('*url', controller='template', action='view') + + return map Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py ============================================================================== Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/error.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/error.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,33 @@ +import os.path +from paste import fileapp +from pylons.middleware import media_path, error_document_template +from pylons.util import get_prefix +from ddemo.lib.base import * + +class ErrorController(BaseController): + """ + Class to generate error documents as and when they are required. This behaviour of this + class can be altered by changing the parameters to the ErrorDocuments middleware in + your config/middleware.py file. + """ + + def document(self): + """ + Change this method to change how error documents are displayed + """ + page = error_document_template % { + 'prefix': get_prefix(request.environ), + 'code': request.params.get('code', ''), + 'message': request.params.get('message', ''), + } + return Response(page) + + def img(self, id): + return self._serve_file(os.path.join(media_path, 'img', id)) + + def style(self, id): + return self._serve_file(os.path.join(media_path, 'style', id)) + + def _serve_file(self, path): + fapp = fileapp.FileApp(path) + return fapp(request.environ, self.start_response) Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/template.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/template.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,28 @@ +from ddemo.lib.base import * + +class TemplateController(BaseController): + def view(self, url): + """ + This is the last place which is tried during a request to try to find a + file to serve. It could be used for example to display a template:: + + def view(self, url): + return render_response(url) + + Or, if you're using Myghty and would like to catch the component not + found error which will occur when the template doesn't exist; you + can use the following version which will provide a 404 if the template + doesn't exist:: + + import myghty.exception + + def view(self, url): + try: + return render_response('/'+url) + except myghty.exception.ComponentNotFound: + return Response(code=404) + + The default is just to abort the request with a 404 File not found + status message. + """ + abort(404) Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/docs/index.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/docs/index.txt Fri Nov 17 21:30:05 2006 @@ -0,0 +1,11 @@ +ddemo ++++++ + +This is the main index page of your documentation. It should be written in reStructuredText format. + +You can generate your documentation in HTML format by running this command:: + + setup.py pudge + +For this to work you will need to download and install ``buildutils`` and ``pudge``. + Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/i18n/__init__.py ============================================================================== Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/__init__.py ============================================================================== Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/app_globals.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/app_globals.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,33 @@ +class Globals(object): + + def __init__(self, global_conf, app_conf, **extra): + """ + You can put any objects which need to be initialised only once + here as class attributes and they will be available as globals + everywhere in your application and will be intialised only once, + not on every request. + + ``global_conf`` + The same as variable used throughout ``config/middleware.py`` + namely, the variables from the ``[DEFAULT]`` section of the + configuration file. + + ``app_conf`` + The same as the ``kw`` dictionary used throughout + ``config/middleware.py`` namely, the variables the section + in the config file for your application. + + ``extra`` + The configuration returned from ``load_config`` in + ``config/middleware.py`` which may be of use in the setup of + your global variables. + + """ + pass + + def __del__(self): + """ + Put any cleanup code to be run when the application finally exits + here. + """ + pass Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/base.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/base.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,14 @@ +from pylons import Response, c, g, cache, request, session +from pylons.controllers import WSGIController +from pylons.decorators import jsonify, validate +from pylons.templating import render, render_response +from pylons.helpers import abort, redirect_to, etag_cache, _ +import ddemo.models as model +import ddemo.lib.helpers as h + +class BaseController(WSGIController): + def __call__(self, environ, start_response): + # Insert any code to be run per request here. The Routes match + # is under environ['pylons.routes_dict'] should you want to check + # the action or route vars here + return WSGIController.__call__(self, environ, start_response) Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/helpers.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/lib/helpers.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,7 @@ +""" +Helper functions + +All names available in this module will be available under the Pylons h object. +""" +from webhelpers import * +from pylons.helpers import _, log, set_lang, get_lang Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/models/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/models/__init__.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,11 @@ +## NOTE +## If you plan on using SQLObject, the following should be un-commented and provides +## a starting point for setting up your schema + +#from sqlobject import * +#from pylons.database import PackageHub +#hub = PackageHub("ddemo") +#__connection__ = hub + +# You should then import your SQLObject classes +# from myclass import MyDataClass Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html Fri Nov 17 21:30:05 2006 @@ -0,0 +1,83 @@ + + + + Pylons Default Page + + + + +

      Welcome to your Pylons Web Application

      + +

      Weren't expecting to see this page?

      + +

      The ddemo/public/ directory is searched for static files + before your controllers are run. Remove this file (ddemo/public/index.html) and edit + the routes in ddemo/config/routing.py like so: +

       map.connect('', controller='hello', action='index')
      +

      + +

      Getting Started

      +

      You're now ready to start creating your own web application. Here's what a basic controller looks +like to print out 'Hello World' and respond to http://127.0.0.1:5000/hello: +

      +# ddemo/controllers/hello.py
      +# Note that the line above is the file you should create and put the following into...
      +
      +from ddemo.lib.base import *
      +
      +class HelloController(BaseController):
      +    def index(self):
      +        return Response('Hello World')
      +        
      +
      +

      + +

      Using a template

      +

      If you want to call a template and do something a little more complex, here's an example printing out some +request information from a Myghty template. +

      +# ddemo/templates/serverinfo.myt
      +
      +<p>Hi, here's the server environment: <br />
      +<% str(request.environ) %></p>
      +
      +<p>
      +here's the URL you called: <% h.url_for() %>
      +</p>
      +
      +<p>
      +and here's the name you set: <% c.name %>
      +</p>
      +
      +
      + +Then add this to your hello controller class: +
      +    def serverinfo(self):
      +        c.name = 'The Black Knight'
      +        return render_response('/serverinfo.myt')
      +
      + +You can now view the page at: http://127.0.0.1:5000/hello/serverinfo +

      + + Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/autohandler ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/autohandler Fri Nov 17 21:30:05 2006 @@ -0,0 +1 @@ +% m.call_next() \ No newline at end of file Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/__init__.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,28 @@ +import os, sys +from unittest import TestCase + +here_dir = os.path.dirname(__file__) +conf_dir = os.path.dirname(os.path.dirname(here_dir)) + +sys.path.insert(0, conf_dir) + +import pkg_resources + +pkg_resources.working_set.add_entry(conf_dir) + +pkg_resources.require('Paste') +pkg_resources.require('PasteScript') + +from paste.deploy import loadapp +import paste.fixture + +from ddemo.config.routing import * +from routes import request_config, url_for + +class TestController(TestCase): + def __init__(self, *args): + wsgiapp = loadapp('config:development.ini', relative_to=conf_dir) + self.app = paste.fixture.TestApp(wsgiapp) + TestCase.__init__(self, *args) + +__all__ = ['url_for', 'TestController'] Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/__init__.py ============================================================================== Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/test_models.py ============================================================================== Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/websetup.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/websetup.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,5 @@ +def setup_config(command, filename, section, vars): + """ + Place any commands to setup ddemo here. + """ + pass \ No newline at end of file Added: z3/deliverance/DeliveranceDemo/trunk/development.ini ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/development.ini Fri Nov 17 21:30:05 2006 @@ -0,0 +1,39 @@ +# +# DeliveranceDemo - Pylons development environment configuration +# +# The %(here)s variable will be replaced with the parent directory of this file +# +[DEFAULT] +debug = true +email_to = you at yourdomain.com +smtp_server = localhost +error_email_from = paste at localhost + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 5000 + +[app:main] +use = egg:DeliveranceDemo +cache_dir = %(here)s/data +session_key = ddemo +session_secret = somesecret + +# If you'd like to fine-tune the individual locations of the cache data dirs +# for Myghty, the Cache data, or the Session saves, un-comment the desired +# settings here: +#myghty_data_dir = %(here)s/data/templates +#cache_data_dir = %(here)s/data/cache +#session_data_dir = %(here)s/data/sessions + +# Specify the database for SQLObject to use via pylons.database.PackageHub. +# %(here) may include a ':' character on Windows environments; this can +# invalidate the URI when specifying a SQLite db via path name. Refer to the +# SQLObject documentation for a special syntax to preserve the URI. +#sqlobject.dburi = sqlite:%(here)s/somedb.db + +# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* +# Debug mode will enable the interactive debugging tool, allowing ANYONE to +# execute malicious code after an exception is raised. +#set debug = false Added: z3/deliverance/DeliveranceDemo/trunk/setup.cfg ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/setup.cfg Fri Nov 17 21:30:05 2006 @@ -0,0 +1,34 @@ +[egg_info] +tag_build = dev +tag_svn_revision = true + +[easy_install] +find_links = http://www.pylonshq.com/download/ + +[pudge] +theme = pythonpaste.org + +# Add extra doc files here with spaces between them +docs = ddemo/docs/index.txt + +# Doc Settings +doc_base = ddemo/docs/ +dest = ddemo/docs/html + +# Add extra modules here separated with commas +modules = ddemo +title = Ddemo +organization = Pylons + +# Optionally add extra links +#organization_url = http://pylons.groovie.org/ +#trac_url=http://pylons.groovie.org/ +settings = no_about=true + +# Optionally add extra settings +# link1=/community/ Community +# link2=/download/ Download + +[publish] +doc-dir=ddemo/docs/html +make-dirs=1 Added: z3/deliverance/DeliveranceDemo/trunk/setup.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/setup.py Fri Nov 17 21:30:05 2006 @@ -0,0 +1,21 @@ +from setuptools import setup, find_packages + +setup( + name='DeliveranceDemo', + version="", + #description="", + #author="", + #author_email="", + #url="", + install_requires=["Pylons>=0.9.3"], + packages=find_packages(), + include_package_data=True, + test_suite = 'nose.collector', + package_data={'ddemo': ['i18n/*/LC_MESSAGES/*.mo']}, + entry_points=""" + [paste.app_factory] + main=ddemo:make_app + [paste.app_install] + main=paste.script.appinstall:Installer + """, +) \ No newline at end of file From ianb at codespeak.net Fri Nov 17 23:30:12 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Fri, 17 Nov 2006 23:30:12 +0100 (CET) Subject: [z3-checkins] r34724 - z3/deliverance/DeliveranceDemo/trunk Message-ID: <20061117223012.1DE79100B3@code0.codespeak.net> Author: ianb Date: Fri Nov 17 23:30:09 2006 New Revision: 34724 Removed: z3/deliverance/DeliveranceDemo/trunk/ Log: Decided to start over on layout From ianb at codespeak.net Mon Nov 20 18:46:10 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Mon, 20 Nov 2006 18:46:10 +0100 (CET) Subject: [z3-checkins] r34802 - in z3/deliverance/DeliveranceDemo/trunk: . DeliveranceDemo.egg-info cache_data cache_data/templates cache_data/templates/lock cache_data/templates/obj data data/x.colorstudy.com ddemo ddemo/controllers ddemo/public ddemo/templates ddemo/tests Message-ID: <20061120174610.C658510077@code0.codespeak.net> Author: ianb Date: Mon Nov 20 18:45:57 2006 New Revision: 34802 Added: z3/deliverance/DeliveranceDemo/trunk/ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/PKG-INFO z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/SOURCES.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/dependency_links.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/entry_points.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paster_plugins.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/requires.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/top_level.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/README.txt (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/cache_data/ z3/deliverance/DeliveranceDemo/trunk/cache_data/templates/ z3/deliverance/DeliveranceDemo/trunk/cache_data/templates/lock/ z3/deliverance/DeliveranceDemo/trunk/cache_data/templates/obj/ z3/deliverance/DeliveranceDemo/trunk/data/ z3/deliverance/DeliveranceDemo/trunk/data/x.colorstudy.com/ z3/deliverance/DeliveranceDemo/trunk/ddemo/ z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/helpers.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/public/ z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/routing.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/ z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/autohandler z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/development.ini z3/deliverance/DeliveranceDemo/trunk/setup.cfg z3/deliverance/DeliveranceDemo/trunk/setup.py (contents, props changed) Log: Added project (new layout) Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/PKG-INFO ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/PKG-INFO Mon Nov 20 18:45:57 2006 @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: DeliveranceDemo +Version: 0.0.0dev +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/SOURCES.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/SOURCES.txt Mon Nov 20 18:45:57 2006 @@ -0,0 +1,16 @@ +README.txt +setup.cfg +setup.py +DeliveranceDemo.egg-info/PKG-INFO +DeliveranceDemo.egg-info/SOURCES.txt +DeliveranceDemo.egg-info/dependency_links.txt +DeliveranceDemo.egg-info/entry_points.txt +DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl +DeliveranceDemo.egg-info/requires.txt +DeliveranceDemo.egg-info/top_level.txt +ddemo/__init__.py +ddemo/helpers.py +ddemo/routing.py +ddemo/wsgiapp.py +ddemo/controllers/__init__.py +ddemo/tests/__init__.py Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/dependency_links.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/dependency_links.txt Mon Nov 20 18:45:57 2006 @@ -0,0 +1 @@ + Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/entry_points.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/entry_points.txt Mon Nov 20 18:45:57 2006 @@ -0,0 +1,6 @@ + + [paste.app_factory] + main=ddemo:make_app + [paste.app_install] + main=paste.script.appinstall:Installer + \ No newline at end of file Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl Mon Nov 20 18:45:57 2006 @@ -0,0 +1,40 @@ +# +# DeliveranceDemo - Pylons configuration +# +# The %(here)s variable will be replaced with the parent directory of this file +# +[DEFAULT] +debug = true +email_to = you at yourdomain.com +smtp_server = localhost +error_email_from = paste at localhost + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 5000 + +[app:main] +use = egg:DeliveranceDemo +cache_dir = %(here)s/data +session_key = ddemo +session_secret = ${app_instance_secret} +app_instance_uuid = ${app_instance_uuid} + +# If you'd like to fine-tune the individual locations of the cache data dirs +# for Myghty, the Cache data, or the Session saves, un-comment the desired +# settings here: +#myghty_data_dir = %(here)s/data/templates +#cache_data_dir = %(here)s/data/cache +#session_data_dir = %(here)s/data/sessions + +# Specify the database for SQLObject to use via pylons.database.PackageHub. +# %(here) may include a ':' character on Windows environments; this can +# invalidate the URI when specifying a SQLite db via path name. Refer to the +# SQLObject documentation for a special syntax to preserve the URI. +#sqlobject.dburi = sqlite:%(here)s/somedb.db + +# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* +# Debug mode will enable the interactive debugging tool, allowing ANYONE to +# execute malicious code after an exception is raised. +set debug = false Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paster_plugins.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/paster_plugins.txt Mon Nov 20 18:45:57 2006 @@ -0,0 +1,3 @@ +Pylons +WebHelpers +PasteScript Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/requires.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/requires.txt Mon Nov 20 18:45:57 2006 @@ -0,0 +1 @@ +Pylons>=0.9.3 \ No newline at end of file Added: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/top_level.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/top_level.txt Mon Nov 20 18:45:57 2006 @@ -0,0 +1 @@ +ddemo Added: z3/deliverance/DeliveranceDemo/trunk/README.txt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/README.txt Mon Nov 20 18:45:57 2006 @@ -0,0 +1,19 @@ +This file is for you to describe the DeliveranceDemo application. Typically +you would include information such as the information below: + +Installation and Setup +====================== + +Install ``DeliveranceDemo`` using easy_install:: + + easy_install DeliveranceDemo + +Make a config file as follows:: + + paster make-config DeliveranceDemo config.ini + +Tweak the config file as appropriate and then setup the application:: + + paster setup-app config.ini + +Then you are ready to go. Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,8 @@ +""" +ddemo + +This file loads the finished app from ddemo.config.middleware. + +""" + +from ddemo.wsgiapp import make_app Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,13 @@ +from pylons import Response, c, g, cache, request, session +from pylons.controllers import WSGIController +from pylons.decorators import jsonify, validate +from pylons.templating import render, render_response +from pylons.helpers import abort, redirect_to, etag_cache +import ddemo.helpers as h + +class BaseController(WSGIController): + def __call__(self, environ, start_response): + # Insert any code to be run per request here. The Routes match + # is under environ['pylons.routes_dict'] should you want to check + # the action or route vars here + return WSGIController.__call__(self, environ, start_response) Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,90 @@ +import re +import os + +domain_re = re.compile(r'^[a-z][a-z0-9.\-]+\.[a-z]+$', re.I) + +class DataProvider(object): + + def __init__(self, dir): + self.dir = dir + if not os.path.exists(self.dir): + print 'Creating data directory %s' % self.dir + os.makedirs(self.dir) + + def domain(self, domain_name): + domain_name = self.normalize(domain_name) + dir = os.path.join(self.dir, domain_name) + if not os.path.exists(dir): + os.mkdir(dir) + return DomainDataProvider(domain_name, dir) + + def normalize(self, domain_name): + domain_name = domain_name.strip().lower() + if not domain_re.search(domain_name): + raise ValueError( + 'Bad domain name: %r' % domain_name) + return domain_name + +class file_property(object): + + def __init__(self, basename): + self.basename = basename + + def filename(self, obj): + return os.path.join(obj.dir, self.basename) + + def __get__(self, obj, type=None): + if obj is None: + return self + if not os.path.exists(self.filename(obj)): + return None + f = open(filename, 'rb') + c = f.read() + f.close() + + def __set__(self, obj, value): + f = open(self.filename(obj), 'wb') + f.write(value) + f.close() + + def __del__(self, obj): + os.unlink(self.filename(obj)) + + def __repr__(self): + return '%s(%r)' % ( + self.__class__.__name__, self.basename) + +class DomainDataProvider(object): + + def __init__(self, domain_name, dir): + self.domain_name = domain_name + self.dir = dir + + def __repr__(self): + return '<%s %s for %s in %r>' % ( + self.__class__.__name__, + hex(id(self)), + self.domain_name, + self.dir) + + def initialize(self): + for dir in [self.dir, self.rule_dir, + self.static_dir]: + if not os.path.exists(dir): + os.mkdir(dir) + + @property + def initialized(self): + return os.path.exists( + os.path.join(self.dir, 'remote.txt')) + + @property + def rule_dir(self): + return os.path.join(self.dir, 'rules') + + @property + def static_dir(self): + return os.path.join(self.dir, 'static') + + remote = file_property('remote.txt') + theme_uri = file_property('theme_uri.txt') Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,65 @@ +import posixpath +import os +from paste.request import path_info_pop, construct_url +from paste import httpexceptions +from paste.urlparser import StaticURLParser +from paste.fileapp import FileApp +from wsgifilter import proxyapp +from deliverance.wsgimiddleware import DeliveranceMiddleware +from ddemo.dataprovider import DataProvider + +def norm_path(urlpath): + if not urlpath: + urlpath = '/' + assert urlpath.startswith('/') + urlpath = posixpath.normpath(posixpath.abspath(urlpath)) + return urlpath + +class DeliveranceDispatcher(object): + + def __init__(self, pylons_app, app_conf): + self.pylons_app = pylons_app + data_dir = app_conf['data_dir'] + self.provider = DataProvider(data_dir) + + def __call__(self, environ, start_response): + domain = environ['HTTP_HOST'] + if ':' in domain: + domain = domain.split(':', 1)[0] + domain_info = self.provider.domain(domain) + environ['ddemo.domain_info'] = domain_info + path_info = norm_path(environ.get('PATH_INFO', '')) + if path_info.startswith('/_deliverance'): + path_info_pop(environ) + return self.pylons_app(environ, start_response) + if not domain_info.initialized: + new_url = construct_url( + environ, with_query_string=False, + path_info='/_deliverance') + exc = httpexceptions.HTTPTemporaryRedirect( + headers=[('location', new_url)]) + return exc(environ, start_response) + if path_info.startswith('/_rules'): + path_info_pop(environ) + subapp = StaticURLParser( + domain_info.rule_dir) + return subapp(environ, start_response) + static_path = os.path.join(domain_info.static_dir, + path_info.lstrip('/')) + if os.path.exists(static_path): + # Explicit override of a file + app = FileApp(static_path) + return app(environ, start_response) + app = proxyapp.ForcedProxy( + remote=domain_info.remote, + force_host=True) + app = proxyapp.RelocateMiddleware( + app, old_href=domain_info.remote) + rule_uri = construct_url( + environ, with_query_string=False, + path_info='/_rules') + app = DeliveranceMiddleware( + app, + theme_uri=domain_info.theme_uri, + rule_uri=rule_uri) + return app(environ, start_response) Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/helpers.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/helpers.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,7 @@ +""" +Helper functions + +All names available in this module will be available under the Pylons h object. +""" +from webhelpers import * +from pylons.helpers import _, log, set_lang, get_lang Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html Mon Nov 20 18:45:57 2006 @@ -0,0 +1,83 @@ + + + + Pylons Default Page + + + + +

      Welcome to your Pylons Web Application

      + +

      Weren't expecting to see this page?

      + +

      The ddemo/public/ directory is searched for static files + before your controllers are run. Remove this file (ddemo/public/index.html) and edit + the routes in ddemo/config/routing.py like so: +

       map.connect('', controller='hello', action='index')
      +

      + +

      Getting Started

      +

      You're now ready to start creating your own web application. Here's what a basic controller looks +like to print out 'Hello World' and respond to http://127.0.0.1:5000/hello: +

      +# ddemo/controllers/hello.py
      +# Note that the line above is the file you should create and put the following into...
      +
      +from ddemo.lib.base import *
      +
      +class HelloController(BaseController):
      +    def index(self):
      +        return Response('Hello World')
      +        
      +
      +

      + +

      Using a template

      +

      If you want to call a template and do something a little more complex, here's an example printing out some +request information from a Myghty template. +

      +# ddemo/templates/serverinfo.myt
      +
      +<p>Hi, here's the server environment: <br />
      +<% str(request.environ) %></p>
      +
      +<p>
      +here's the URL you called: <% h.url_for() %>
      +</p>
      +
      +<p>
      +and here's the name you set: <% c.name %>
      +</p>
      +
      +
      + +Then add this to your hello controller class: +
      +    def serverinfo(self):
      +        c.name = 'The Black Knight'
      +        return render_response('/serverinfo.myt')
      +
      + +You can now view the page at: http://127.0.0.1:5000/hello/serverinfo +

      + + Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/routing.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/routing.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,9 @@ +"""Setup your Routes options here""" +import os +from routes import Mapper + +def make_map(global_conf={}, app_conf={}): + root_path = os.path.dirname(os.path.abspath(__file__)) + map = Mapper(directory=os.path.join(root_path, 'controllers')) + map.connect(':controller/:action/:id') + return map Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/autohandler ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/autohandler Mon Nov 20 18:45:57 2006 @@ -0,0 +1 @@ +% m.call_next() \ No newline at end of file Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/__init__.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,28 @@ +import os, sys +from unittest import TestCase + +here_dir = os.path.dirname(__file__) +conf_dir = os.path.dirname(os.path.dirname(here_dir)) + +sys.path.insert(0, conf_dir) + +import pkg_resources + +pkg_resources.working_set.add_entry(conf_dir) + +pkg_resources.require('Paste') +pkg_resources.require('PasteScript') + +from paste.deploy import loadapp +import paste.fixture + +from ddemo.config.routing import * +from routes import request_config, url_for + +class TestController(TestCase): + def __init__(self, *args): + wsgiapp = loadapp('config:development.ini', relative_to=conf_dir) + self.app = paste.fixture.TestApp(wsgiapp) + TestCase.__init__(self, *args) + +__all__ = ['url_for', 'TestController'] Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,61 @@ +import os + +from paste import httpexceptions +from paste.cascade import Cascade +from paste.urlparser import StaticURLParser +from paste.registry import RegistryManager +from paste.deploy.config import ConfigMiddleware +from paste.deploy.converters import asbool + +import pylons.wsgiapp +import pylons.config +from pylons.error import error_template +from pylons.middleware import ErrorHandler, ErrorDocuments, StaticJavascripts, error_mapper + +import ddemo.helpers +from ddemo.routing import make_map + +from ddemo.dispatcher import DeliveranceDispatcher + +def load_environment(global_conf={}, app_conf={}): + map = make_map(global_conf, app_conf) + root_path = os.path.dirname(os.path.abspath(__file__)) + paths = {'root_path': root_path, + 'controllers': os.path.join(root_path, 'controllers'), + 'templates': [os.path.join(root_path, 'templates')], + 'static_files': os.path.join(root_path, 'public') + } + myghty = dict(log_errors=True) + return pylons.config.Config(myghty, map, paths) + +class Globals(object): + def __init__(self, global_conf, app_conf, **extra): + pass + +def make_app(global_conf, full_stack=True, **app_conf): + """Create a WSGI application and return it""" + # Load our Pylons configuration defaults + config = load_environment(global_conf, app_conf) + config.init_app(global_conf, app_conf, package='ddemo') + + # Load our default Pylons WSGI app and make g available + app = pylons.wsgiapp.PylonsApp(config, helpers=ddemo.helpers, g=Globals) + g = app.globals + app = ConfigMiddleware(app, {'app_conf':app_conf, + 'global_conf':global_conf}) + + # <-- YOUR MIDDLEWARE HERE + + # Build the rest of the stack, see a full template for more details + if asbool(full_stack): + app = httpexceptions.make_middleware(app, global_conf) + + app = RegistryManager(app) + + static_app = StaticURLParser(config.paths['static_files']) + javascripts_app = StaticJavascripts() + app = Cascade([static_app, javascripts_app, app]) + app = DeliveranceDispatcher(app, app_conf) + if asbool(full_stack): + app = ErrorHandler(app, global_conf, error_template=error_template, **config.errorware) + return app Added: z3/deliverance/DeliveranceDemo/trunk/development.ini ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/development.ini Mon Nov 20 18:45:57 2006 @@ -0,0 +1,41 @@ +# +# DeliveranceDemo - Pylons development environment configuration +# +# The %(here)s variable will be replaced with the parent directory of this file +# +[DEFAULT] +debug = true +email_to = you at yourdomain.com +smtp_server = localhost +error_email_from = paste at localhost + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 5000 + +[app:main] +use = egg:DeliveranceDemo +full_stack = True +cache_dir = %(here)s/cache_data +data_dir = %(here)s/data +session_key = ddemo +session_secret = somesecret + +# If you'd like to fine-tune the individual locations of the cache data dirs +# for Myghty, the Cache data, or the Session saves, un-comment the desired +# settings here: +#myghty_data_dir = %(here)s/data/templates +#cache_data_dir = %(here)s/data/cache +#session_data_dir = %(here)s/data/sessions + +# Specify the database for SQLObject to use via pylons.database.PackageHub. +# %(here) may include a ':' character on Windows environments; this can +# invalidate the URI when specifying a SQLite db via path name. Refer to the +# SQLObject documentation for a special syntax to preserve the URI. +#sqlobject.dburi = sqlite:%(here)s/somedb.db + +# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* +# Debug mode will enable the interactive debugging tool, allowing ANYONE to +# execute malicious code after an exception is raised. +#set debug = false Added: z3/deliverance/DeliveranceDemo/trunk/setup.cfg ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/setup.cfg Mon Nov 20 18:45:57 2006 @@ -0,0 +1,34 @@ +[egg_info] +tag_build = dev +tag_svn_revision = true + +[easy_install] +find_links = http://www.pylonshq.com/download/ + +[pudge] +theme = pythonpaste.org + +# Add extra doc files here with spaces between them +docs = ddemo/docs/index.txt + +# Doc Settings +doc_base = ddemo/docs/ +dest = ddemo/docs/html + +# Add extra modules here separated with commas +modules = ddemo +title = Ddemo +organization = Pylons + +# Optionally add extra links +#organization_url = http://pylons.groovie.org/ +#trac_url=http://pylons.groovie.org/ +settings = no_about=true + +# Optionally add extra settings +# link1=/community/ Community +# link2=/download/ Download + +[publish] +doc-dir=ddemo/docs/html +make-dirs=1 Added: z3/deliverance/DeliveranceDemo/trunk/setup.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/setup.py Mon Nov 20 18:45:57 2006 @@ -0,0 +1,21 @@ +from setuptools import setup, find_packages + +setup( + name='DeliveranceDemo', + version="", + #description="", + #author="", + #author_email="", + #url="", + install_requires=["Pylons>=0.9.3"], + packages=find_packages(), + include_package_data=True, + test_suite = 'nose.collector', + package_data={'ddemo': ['i18n/*/LC_MESSAGES/*.mo']}, + entry_points=""" + [paste.app_factory] + main=ddemo:make_app + [paste.app_install] + main=paste.script.appinstall:Installer + """, +) \ No newline at end of file From ianb at codespeak.net Mon Nov 20 18:48:00 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Mon, 20 Nov 2006 18:48:00 +0100 (CET) Subject: [z3-checkins] r34803 - in z3/deliverance/DeliveranceDemo/trunk: . DeliveranceDemo.egg-info cache_data data Message-ID: <20061120174800.D97E910077@code0.codespeak.net> Author: ianb Date: Mon Nov 20 18:47:57 2006 New Revision: 34803 Removed: z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/PKG-INFO z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/SOURCES.txt z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/dependency_links.txt z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/entry_points.txt z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/requires.txt z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/top_level.txt z3/deliverance/DeliveranceDemo/trunk/cache_data/ z3/deliverance/DeliveranceDemo/trunk/data/ Modified: z3/deliverance/DeliveranceDemo/trunk/ (props changed) z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/ (props changed) Log: Cleaned out accidental committed files Deleted: /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/PKG-INFO ============================================================================== --- /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/PKG-INFO Mon Nov 20 18:47:57 2006 +++ (empty file) @@ -1,10 +0,0 @@ -Metadata-Version: 1.0 -Name: DeliveranceDemo -Version: 0.0.0dev -Summary: UNKNOWN -Home-page: UNKNOWN -Author: UNKNOWN -Author-email: UNKNOWN -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN Deleted: /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/SOURCES.txt ============================================================================== --- /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/SOURCES.txt Mon Nov 20 18:47:57 2006 +++ (empty file) @@ -1,16 +0,0 @@ -README.txt -setup.cfg -setup.py -DeliveranceDemo.egg-info/PKG-INFO -DeliveranceDemo.egg-info/SOURCES.txt -DeliveranceDemo.egg-info/dependency_links.txt -DeliveranceDemo.egg-info/entry_points.txt -DeliveranceDemo.egg-info/paste_deploy_config.ini_tmpl -DeliveranceDemo.egg-info/requires.txt -DeliveranceDemo.egg-info/top_level.txt -ddemo/__init__.py -ddemo/helpers.py -ddemo/routing.py -ddemo/wsgiapp.py -ddemo/controllers/__init__.py -ddemo/tests/__init__.py Deleted: /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/dependency_links.txt ============================================================================== --- /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/dependency_links.txt Mon Nov 20 18:47:57 2006 +++ (empty file) @@ -1 +0,0 @@ - Deleted: /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/entry_points.txt ============================================================================== --- /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/entry_points.txt Mon Nov 20 18:47:57 2006 +++ (empty file) @@ -1,6 +0,0 @@ - - [paste.app_factory] - main=ddemo:make_app - [paste.app_install] - main=paste.script.appinstall:Installer - \ No newline at end of file Deleted: /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/requires.txt ============================================================================== --- /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/requires.txt Mon Nov 20 18:47:57 2006 +++ (empty file) @@ -1 +0,0 @@ -Pylons>=0.9.3 \ No newline at end of file Deleted: /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/top_level.txt ============================================================================== --- /z3/deliverance/DeliveranceDemo/trunk/DeliveranceDemo.egg-info/top_level.txt Mon Nov 20 18:47:57 2006 +++ (empty file) @@ -1 +0,0 @@ -ddemo From ianb at codespeak.net Mon Nov 20 22:10:16 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Mon, 20 Nov 2006 22:10:16 +0100 (CET) Subject: [z3-checkins] r34811 - z3/deliverance/trunk/deliverance Message-ID: <20061120211016.E139410072@code0.codespeak.net> Author: ianb Date: Mon Nov 20 22:10:14 2006 New Revision: 34811 Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Added support for paste.recursive internal redirects Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Mon Nov 20 22:10:14 2006 @@ -249,6 +249,11 @@ get the data referred to by the uri given by using the wrapped WSGI application """ + if 'paste.recursive.include' in environ: + # Try to do the redirect this way... + includer = environ['paste.recursive.include'] + res = includer(uri) + return res.body environ = environ.copy() if not uri.startswith('/'): uri = '/' + uri From ianb at codespeak.net Mon Nov 20 22:12:30 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Mon, 20 Nov 2006 22:12:30 +0100 (CET) Subject: [z3-checkins] r34812 - in z3/deliverance/DeliveranceDemo/trunk: . ddemo ddemo/controllers ddemo/public ddemo/templates ddemo/tests/functional Message-ID: <20061120211230.CEF5210072@code0.codespeak.net> Author: ianb Date: Mon Nov 20 22:12:22 2006 New Revision: 34812 Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/index.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/index.myt z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/__init__.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/test_index.py (contents, props changed) Removed: z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py z3/deliverance/DeliveranceDemo/trunk/ddemo/helpers.py z3/deliverance/DeliveranceDemo/trunk/ddemo/routing.py z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py z3/deliverance/DeliveranceDemo/trunk/setup.py Log: Implemented the dispatching and admin portions Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py Mon Nov 20 22:12:22 2006 @@ -10,4 +10,7 @@ # Insert any code to be run per request here. The Routes match # is under environ['pylons.routes_dict'] should you want to check # the action or route vars here + di = c.domain_info = environ['ddemo.domain_info'] + if not di.initialized: + di.initialize() return WSGIController.__call__(self, environ, start_response) Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/index.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/index.py Mon Nov 20 22:12:22 2006 @@ -0,0 +1,18 @@ +from ddemo.controllers import * +import os + +class IndexController(BaseController): + def index(self): + if request.method == 'POST': + return self.update() + rule_fn = os.path.join(c.domain_info.rule_dir, 'rule.xml') + c.rule_text = open(rule_fn, 'rb').read() + return render_response('index.myt') + + def update(self): + params = request.params + di = c.domain_info + di.theme_uri = params['theme_uri'] + di.remote = params['remote'] + di.set_rule_file('rule.xml', params['rule_xml']) + redirect_to() Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py Mon Nov 20 22:12:22 2006 @@ -3,6 +3,28 @@ domain_re = re.compile(r'^[a-z][a-z0-9.\-]+\.[a-z]+$', re.I) +default_rule_xml = '''\ + + + + + + + +''' + +default_standardrules = '''\ + + + + + + + + +''' + class DataProvider(object): def __init__(self, dir): @@ -38,9 +60,10 @@ return self if not os.path.exists(self.filename(obj)): return None - f = open(filename, 'rb') + f = open(self.filename(obj), 'rb') c = f.read() f.close() + return c def __set__(self, obj, value): f = open(self.filename(obj), 'wb') @@ -72,11 +95,18 @@ self.static_dir]: if not os.path.exists(dir): os.mkdir(dir) + for filename, content in [ + ('rule.xml', default_rule_xml), + ('standardrules.xml', default_standardrules)]: + filename = os.path.join(self.rule_dir, filename) + if not os.path.exists(filename): + f = open(filename, 'w') + f.write(content) + f.close() @property def initialized(self): - return os.path.exists( - os.path.join(self.dir, 'remote.txt')) + return bool(self.remote) @property def rule_dir(self): @@ -88,3 +118,10 @@ remote = file_property('remote.txt') theme_uri = file_property('theme_uri.txt') + + def set_rule_file(self, filename, content): + filename = os.path.join(self.rule_dir, filename) + f = open(filename, 'wb') + f.write(content) + f.close() + Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py Mon Nov 20 22:12:22 2006 @@ -5,6 +5,7 @@ from paste.urlparser import StaticURLParser from paste.fileapp import FileApp from wsgifilter import proxyapp +from wsgifilter import relocateresponse from deliverance.wsgimiddleware import DeliveranceMiddleware from ddemo.dataprovider import DataProvider @@ -29,10 +30,13 @@ domain_info = self.provider.domain(domain) environ['ddemo.domain_info'] = domain_info path_info = norm_path(environ.get('PATH_INFO', '')) + print 'request: %r' % path_info if path_info.startswith('/_deliverance'): path_info_pop(environ) return self.pylons_app(environ, start_response) - if not domain_info.initialized: + if (not domain_info.initialized + or not domain_info.remote + or not domain_info.theme_uri): new_url = construct_url( environ, with_query_string=False, path_info='/_deliverance') @@ -46,20 +50,28 @@ return subapp(environ, start_response) static_path = os.path.join(domain_info.static_dir, path_info.lstrip('/')) - if os.path.exists(static_path): + static_fn = self.find_file(static_path) + if static_fn is not None: # Explicit override of a file - app = FileApp(static_path) + app = FileApp(static_fn) return app(environ, start_response) app = proxyapp.ForcedProxy( remote=domain_info.remote, force_host=True) - app = proxyapp.RelocateMiddleware( + app = relocateresponse.RelocateMiddleware( app, old_href=domain_info.remote) rule_uri = construct_url( environ, with_query_string=False, - path_info='/_rules') + path_info='/_rules/rule.xml') app = DeliveranceMiddleware( app, theme_uri=domain_info.theme_uri, rule_uri=rule_uri) return app(environ, start_response) + + def find_file(self, path): + if os.path.isdir(path): + path = os.path.join(path, 'index.html') + if os.path.exists(path): + return path + return None Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/helpers.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/helpers.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/helpers.py Mon Nov 20 22:12:22 2006 @@ -4,4 +4,5 @@ All names available in this module will be available under the Pylons h object. """ from webhelpers import * +from webhelpers.util import * from pylons.helpers import _, log, set_lang, get_lang Deleted: /z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html ============================================================================== --- /z3/deliverance/DeliveranceDemo/trunk/ddemo/public/index.html Mon Nov 20 22:12:22 2006 +++ (empty file) @@ -1,83 +0,0 @@ - - - - Pylons Default Page - - - - -

      Welcome to your Pylons Web Application

      - -

      Weren't expecting to see this page?

      - -

      The ddemo/public/ directory is searched for static files - before your controllers are run. Remove this file (ddemo/public/index.html) and edit - the routes in ddemo/config/routing.py like so: -

       map.connect('', controller='hello', action='index')
      -

      - -

      Getting Started

      -

      You're now ready to start creating your own web application. Here's what a basic controller looks -like to print out 'Hello World' and respond to http://127.0.0.1:5000/hello: -

      -# ddemo/controllers/hello.py
      -# Note that the line above is the file you should create and put the following into...
      -
      -from ddemo.lib.base import *
      -
      -class HelloController(BaseController):
      -    def index(self):
      -        return Response('Hello World')
      -        
      -
      -

      - -

      Using a template

      -

      If you want to call a template and do something a little more complex, here's an example printing out some -request information from a Myghty template. -

      -# ddemo/templates/serverinfo.myt
      -
      -<p>Hi, here's the server environment: <br />
      -<% str(request.environ) %></p>
      -
      -<p>
      -here's the URL you called: <% h.url_for() %>
      -</p>
      -
      -<p>
      -and here's the name you set: <% c.name %>
      -</p>
      -
      -
      - -Then add this to your hello controller class: -
      -    def serverinfo(self):
      -        c.name = 'The Black Knight'
      -        return render_response('/serverinfo.myt')
      -
      - -You can now view the page at: http://127.0.0.1:5000/hello/serverinfo -

      - - Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/routing.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/routing.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/routing.py Mon Nov 20 22:12:22 2006 @@ -6,4 +6,5 @@ root_path = os.path.dirname(os.path.abspath(__file__)) map = Mapper(directory=os.path.join(root_path, 'controllers')) map.connect(':controller/:action/:id') + map.connect('', controller='index') return map Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/index.myt ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/index.myt Mon Nov 20 22:12:22 2006 @@ -0,0 +1,28 @@ + + + Administration for <% c.domain_info.domain_name | h %> + + + +

      Administration for <% c.domain_info.domain_name | h %>

      + +

      Visit the site

      + +
      + Remote URL:
      +
      + Theme URL:
      +
      + Rule:
      +
      + +
      + + + + Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/__init__.py Mon Nov 20 22:12:22 2006 @@ -0,0 +1 @@ +# Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/test_index.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/test_index.py Mon Nov 20 22:12:22 2006 @@ -0,0 +1,6 @@ +from ddemo.tests import * + +class TestIndexController(TestController): + def test_index(self): + response = self.app.get(url_for(controller='index')) + # Test response... \ No newline at end of file Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py Mon Nov 20 22:12:22 2006 @@ -6,6 +6,7 @@ from paste.registry import RegistryManager from paste.deploy.config import ConfigMiddleware from paste.deploy.converters import asbool +from paste.recursive import RecursiveMiddleware import pylons.wsgiapp import pylons.config @@ -49,6 +50,7 @@ # Build the rest of the stack, see a full template for more details if asbool(full_stack): app = httpexceptions.make_middleware(app, global_conf) + app = ErrorHandler(app, global_conf, error_template=error_template, **config.errorware) app = RegistryManager(app) @@ -56,6 +58,9 @@ javascripts_app = StaticJavascripts() app = Cascade([static_app, javascripts_app, app]) app = DeliveranceDispatcher(app, app_conf) - if asbool(full_stack): - app = ErrorHandler(app, global_conf, error_template=error_template, **config.errorware) + app = RecursiveMiddleware(app) + if (asbool(full_stack) + and asbool(app_conf.get('debug', global_conf.get('debug')))): + from paste.evalexception import EvalException + app = EvalException(app) return app Modified: z3/deliverance/DeliveranceDemo/trunk/setup.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/setup.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/setup.py Mon Nov 20 22:12:22 2006 @@ -2,12 +2,16 @@ setup( name='DeliveranceDemo', - version="", - #description="", + version="0.1", + description="A demo setup of Deliverance, self-configuring", #author="", #author_email="", #url="", - install_requires=["Pylons>=0.9.3"], + install_requires=[ + "Pylons>=0.9.3", + 'Deliverance', + 'WSGIFilter', + ], packages=find_packages(), include_package_data=True, test_suite = 'nose.collector', @@ -18,4 +22,4 @@ [paste.app_install] main=paste.script.appinstall:Installer """, -) \ No newline at end of file +) From ianb at codespeak.net Mon Nov 20 23:25:47 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Mon, 20 Nov 2006 23:25:47 +0100 (CET) Subject: [z3-checkins] r34815 - in z3/deliverance/DeliveranceDemo/trunk: . ddemo Message-ID: <20061120222547.5FFEC10070@code0.codespeak.net> Author: ianb Date: Mon Nov 20 23:25:44 2006 New Revision: 34815 Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py z3/deliverance/DeliveranceDemo/trunk/development.ini Log: Option to debug the request/response headers Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py Mon Nov 20 23:25:44 2006 @@ -7,6 +7,7 @@ from paste.deploy.config import ConfigMiddleware from paste.deploy.converters import asbool from paste.recursive import RecursiveMiddleware +from wsgifilter import proxyapp import pylons.wsgiapp import pylons.config @@ -59,6 +60,8 @@ app = Cascade([static_app, javascripts_app, app]) app = DeliveranceDispatcher(app, app_conf) app = RecursiveMiddleware(app) + if asbool(app_conf.get('debug_headers')): + app = proxyapp.DebugHeaders(app) if (asbool(full_stack) and asbool(app_conf.get('debug', global_conf.get('debug')))): from paste.evalexception import EvalException Modified: z3/deliverance/DeliveranceDemo/trunk/development.ini ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/development.ini (original) +++ z3/deliverance/DeliveranceDemo/trunk/development.ini Mon Nov 20 23:25:44 2006 @@ -21,6 +21,7 @@ data_dir = %(here)s/data session_key = ddemo session_secret = somesecret +debug_headers = true # If you'd like to fine-tune the individual locations of the cache data dirs # for Myghty, the Cache data, or the Session saves, un-comment the desired From rocky at codespeak.net Mon Nov 27 13:30:21 2006 From: rocky at codespeak.net (rocky at codespeak.net) Date: Mon, 27 Nov 2006 13:30:21 +0100 (CET) Subject: [z3-checkins] r35026 - z3/CMFonFive/trunk Message-ID: <20061127123021.D024E1007B@code0.codespeak.net> Author: rocky Date: Mon Nov 27 13:30:17 2006 New Revision: 35026 Modified: z3/CMFonFive/trunk/CHANGES.txt z3/CMFonFive/trunk/fiveactionstool.py z3/CMFonFive/trunk/version.txt Log: Browser menu items now have their filter expressions checked manually using CMF Expressions instead of testing item.available() which in turn would use the Zope 3 TALES engine. This only happens if a portal is available in the object's acquisition chain. Modified: z3/CMFonFive/trunk/CHANGES.txt ============================================================================== --- z3/CMFonFive/trunk/CHANGES.txt (original) +++ z3/CMFonFive/trunk/CHANGES.txt Mon Nov 27 13:30:17 2006 @@ -1,6 +1,12 @@ CMFonFive Product Changelog - CMFonFive 1.3.3 (unreleased) + CMFonFive 1.3.4 (unreleased) + + - Browser menu items now have their filter expressions checked manually + using CMF Expressions instead of testing item.available() which in + turn would use the Zope 3 TALES engine. + + CMFonFive 1.3.3 (2006-05-15) - Got rid of some i18n warnings. Modified: z3/CMFonFive/trunk/fiveactionstool.py ============================================================================== --- z3/CMFonFive/trunk/fiveactionstool.py (original) +++ z3/CMFonFive/trunk/fiveactionstool.py Mon Nov 27 13:30:17 2006 @@ -12,17 +12,18 @@ """ from AccessControl import ClassSecurityInfo -from Acquisition import aq_base +from Acquisition import aq_base, aq_inner, aq_parent from Globals import InitializeClass from OFS.SimpleItem import SimpleItem from Products.CMFCore.ActionInformation import ActionInformation from Products.CMFCore.ActionProviderBase import ActionProviderBase -from Products.CMFCore.Expression import Expression -from Products.CMFCore.utils import UniqueObject +from Products.CMFCore.Expression import createExprContext, Expression +from Products.CMFCore.utils import UniqueObject, getToolByName from zope.interface import providedBy from zope.app import zapi +from zope.app.pagetemplate import engine from zope.app.publisher.interfaces.browser import IBrowserMenu from zope.app.publisher.interfaces.browser import IBrowserSubMenuItem from zope.security.proxy import removeSecurityProxy @@ -30,15 +31,56 @@ def _listMenuIds(): return [id for id, utility in zapi.getUtilitiesFor(IBrowserMenu)] -def getMenu(id, object, request): - """Return menu item entries in a TAL-friendly form.""" - menu = zapi.getUtility(IBrowserMenu, id) - +def _getItemsWithCMFFilter(portal, object, request, menu): result = [] + folder = aq_parent(aq_inner(object)) + econtext = createExprContext(folder, portal, object) + + # Originally the code simply tested item.available() which is a standard + # Zope 3 technique. The problem was that this in turn evaluated + # the filter TAL expression with the Zope 3 TALES engine. This needed + # to be changed to instead using the CMF expression mechanism so that + # property security (among other things) was taken into account. - Rocky for name, item in zapi.getAdapters((object, request), menu.getMenuItemType()): - if item.available(): + + filter_ = item.filter + if filter_ is None: result.append(item) + else: + exprtext = None + if hasattr(filter_, 'text'): + # python TAL expr + exprtext = 'python:' + filter_.text + elif hasattr(filter_, '_s'): + # standard path TAL expr + exprtext = filter_._s + + if exprtext is not None: + expr = Expression(text=exprtext) + if expr(econtext): + result.append(item) + elif item.available(): + result.append(item) + return result + +def getMenu(id, object, request): + """Return menu item entries in a TAL-friendly form.""" + menu = zapi.getUtility(IBrowserMenu, id) + + try: + portal = getToolByName(object, 'portal_url').getPortalObject() + except AttributeError: + # there is no accessible portal in the aq chain, fall back to + # previous behaviour + result = [] + for name, item in zapi.getAdapters((object, request), + menu.getMenuItemType()): + if item.available(): + result.append(item) + else: + # use CMF / Zope 2 TAL expression filtering + result = _getItemsWithCMFFilter(portal, object, request, menu) # Now order the result. This is not as easy as it seems. # Modified: z3/CMFonFive/trunk/version.txt ============================================================================== --- z3/CMFonFive/trunk/version.txt (original) +++ z3/CMFonFive/trunk/version.txt Mon Nov 27 13:30:17 2006 @@ -1 +1 @@ -CMFonFive-1.3.3 +CMFonFive-1.3.4 (svn/unreleased) From ianb at codespeak.net Wed Nov 29 09:33:42 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Wed, 29 Nov 2006 09:33:42 +0100 (CET) Subject: [z3-checkins] r35099 - z3/deliverance/trunk/deliverance Message-ID: <20061129083342.6626E1006F@code0.codespeak.net> Author: ianb Date: Wed Nov 29 09:33:26 2006 New Revision: 35099 Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Allow for a Renderer class to be passed into the middleware Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Wed Nov 29 09:33:26 2006 @@ -36,7 +36,8 @@ theme_uri: uri referring the the theme document rule_uri: uri referring to the deliverance rules document renderer: selects deliverance render class to utilize when - performing transformations, may be 'py' or 'xslt' + performing transformations, may be 'py' or 'xslt' or a + Renderer class """ self.app = app self.theme_uri = theme_uri @@ -52,8 +53,10 @@ elif renderer == 'xslt': import xslt self._rendererType = xslt.Renderer - else: + elif renderer is None or isinstance(renderer, basestring): raise ValueError("Unknown Renderer: %s - Expecting 'py' or 'xslt'" % renderer) + else: + self._rendererType = renderer def get_renderer(self,environ): """ From ianb at codespeak.net Wed Nov 29 09:34:26 2006 From: ianb at codespeak.net (ianb at codespeak.net) Date: Wed, 29 Nov 2006 09:34:26 +0100 (CET) Subject: [z3-checkins] r35100 - in z3/deliverance/DeliveranceDemo/trunk: . ddemo ddemo/controllers ddemo/public ddemo/templates ddemo/tests/functional Message-ID: <20061129083426.95CF71006F@code0.codespeak.net> Author: ianb Date: Wed Nov 29 09:34:07 2006 New Revision: 35100 Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/remote_getter.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/debuginterp.py (contents, props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/public/selector.js z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/test_remote_getter.py (contents, props changed) Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/index.py z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py z3/deliverance/DeliveranceDemo/trunk/ddemo/public/ (props changed) z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/index.myt z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py z3/deliverance/DeliveranceDemo/trunk/development.ini z3/deliverance/DeliveranceDemo/trunk/setup.py Log: Updates to make it more automated, especially with the #openplans app Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/__init__.py Wed Nov 29 09:34:07 2006 @@ -5,4 +5,11 @@ """ +__all__ = ['current_environ', 'make_app'] + +from paste import registry + +current_environ = registry.StackedObjectProxy( + name='environ') + from ddemo.wsgiapp import make_app Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/__init__.py Wed Nov 29 09:34:07 2006 @@ -3,6 +3,7 @@ from pylons.decorators import jsonify, validate from pylons.templating import render, render_response from pylons.helpers import abort, redirect_to, etag_cache +from paste.deploy import CONFIG import ddemo.helpers as h class BaseController(WSGIController): Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/index.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/index.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/index.py Wed Nov 29 09:34:07 2006 @@ -1,18 +1,98 @@ from ddemo.controllers import * import os +import re +import urlparse +from paste.request import construct_url + +var_re = re.compile(r'[{](.*?)[}]') + +def find_template_values(template, value): + """ + Parses the name/value out of a value, based on the template + """ + if not value: + value = '' + regex = '^' + last_match = 0 + for match in var_re.finditer(template): + regex += re.escape(template[last_match:match.start()]) + regex += '(?P<%s>.*?)' % match.group(1) + last_match = match.end() + regex += re.escape(template[last_match:]) + '$' + result = {} + for match in var_re.finditer(template): + result[match.group(1)] = None + print 'regex: %r' % regex + match = re.search(regex, value) + if match: + result.update(match.groupdict()) + return result + +def sub_template(template, vars): + def repl(match): + return vars[match.group(1)] + return var_re.sub(repl, template) class IndexController(BaseController): + + builtin_vars = ['scheme', 'domain', 'port'] + def index(self): if request.method == 'POST': return self.update() rule_fn = os.path.join(c.domain_info.rule_dir, 'rule.xml') c.rule_text = open(rule_fn, 'rb').read() + conf = CONFIG['app_conf'] + if conf.get('remote_template'): + c.remote_template = find_template_values( + conf['remote_template'], c.domain_info.remote) + for key in self.builtin_vars: + c.remote_template.pop(key, None) + if conf.get('rule_template'): + c.rule_template = find_template_values( + conf['rule_template'], c.rule_text) + print c.rule_template, c.remote_template return render_response('index.myt') def update(self): params = request.params + conf = CONFIG['app_conf'] + base = request.environ['ddemo.base_url'] di = c.domain_info + base_parts = urlparse.urlsplit(base) + scheme, netloc, path, query, fragment = base_parts + if ':' in netloc: + domain, port = netloc.split(':', 1) + else: + domain = netloc + if scheme == 'http': + port = '80' + else: + port = '443' + if conf.get('remote_template'): + vars = {} + for name, value in params.items(): + if not name.startswith('remote.'): + continue + vars[name[len('remote.'):]] = value + vars['scheme'] = scheme + vars['netloc'] = netloc + vars['path'] = path + vars['domain'] = domain + vars['port'] = port + di.remote = sub_template(conf['remote_template'], vars) + else: + di.remote = params['remote'] di.theme_uri = params['theme_uri'] - di.remote = params['remote'] - di.set_rule_file('rule.xml', params['rule_xml']) + if conf.get('rule_template'): + vars = {} + for name, value in params.items(): + if not name.startswith('rule.'): + continue + vars[name[len('rule.'):]] = value + text = sub_template(conf['rule_template'], vars) + else: + text = params['rule_xml'] + text = text.strip() + di.set_rule_file('rule.xml', text) redirect_to() Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/remote_getter.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/controllers/remote_getter.py Wed Nov 29 09:34:07 2006 @@ -0,0 +1,28 @@ +from ddemo.controllers import * +from wsgiremote.lxmlformat import xml as lxml_format +from wsgiremote.json import json as json_format +from wsgiremote import BadRequestError + +class RemoteGetterController(BaseController): + + good_tags = 'body div td'.split() + + def index(self): + url = request.params['url'] + print 'getting', url + try: + data = lxml_format.GET(url) + except BadRequestError, e: + result = {'error': 'Bad request to %s: %s' % (url, e)} + else: + result = [] + for el in data.xpath('//*[@id]'): + if el.tag.lower() not in self.good_tags: + continue + if not len(el): + # Empty elements aren't good candidates + continue + result.append(el.attrib['id']) + app = json_format.responder(result) + return app(request.environ, self.start_response) + Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/dataprovider.py Wed Nov 29 09:34:07 2006 @@ -5,7 +5,6 @@ default_rule_xml = '''\ - @@ -13,6 +12,17 @@ ''' +marker = '' +abstract_rule_xml = '''\ + +MARKER + + + + + +'''.replace('MARKER', marker) + default_standardrules = '''\ @@ -118,6 +128,8 @@ remote = file_property('remote.txt') theme_uri = file_property('theme_uri.txt') + theme_id = file_property('theme_id.txt') + rule_ids = file_property('rule_ids.txt') def set_rule_file(self, filename, content): filename = os.path.join(self.rule_dir, filename) @@ -125,3 +137,4 @@ f.write(content) f.close() + Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/debuginterp.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/debuginterp.py Wed Nov 29 09:34:07 2006 @@ -0,0 +1,31 @@ +from deliverance.interpreter import Renderer as PyRenderer +from lxml import etree +from paste.request import construct_url +from ddemo import current_environ + +class Renderer(PyRenderer): + + error_style = "background-color: #ff9; color: #000; border: 1px solid #000;" + + def format_error(self, message, rule, elts=None): + error = super(PyRenderer, self).format_error(message, rule, elts) + error_container = etree.Element('div') + error_container.attrib['style'] = self.error_style + if not current_environ.get('ddemo.has_errors'): + current_environ['ddemo.has_errors'] = True + domain_info = current_environ['ddemo.domain_info'] + remote = domain_info.remote + remote += current_environ.get('PATH_INFO', '') + if current_environ.get('QUERY_STRING'): + remote += '?' + current_environ['QUERY_STRING'] + link = etree.Element('a') + link.attrib['href'] = remote + link.attrib['target'] = '_blank' + link.text = 'View original content source' + container = etree.Element('div') + container.append(link) + error_container.append(container) + error_container.append(error) + return error_container + + Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/dispatcher.py Wed Nov 29 09:34:07 2006 @@ -8,6 +8,8 @@ from wsgifilter import relocateresponse from deliverance.wsgimiddleware import DeliveranceMiddleware from ddemo.dataprovider import DataProvider +from ddemo import current_environ +from ddemo.debuginterp import Renderer def norm_path(urlpath): if not urlpath: @@ -24,13 +26,17 @@ self.provider = DataProvider(data_dir) def __call__(self, environ, start_response): + if 'paste.registry' in environ: + environ['paste.registry'].register(current_environ, environ) domain = environ['HTTP_HOST'] if ':' in domain: domain = domain.split(':', 1)[0] domain_info = self.provider.domain(domain) environ['ddemo.domain_info'] = domain_info + environ['ddemo.base_url'] = construct_url( + environ, with_query_string=False, + path_info='') path_info = norm_path(environ.get('PATH_INFO', '')) - print 'request: %r' % path_info if path_info.startswith('/_deliverance'): path_info_pop(environ) return self.pylons_app(environ, start_response) @@ -66,7 +72,8 @@ app = DeliveranceMiddleware( app, theme_uri=domain_info.theme_uri, - rule_uri=rule_uri) + rule_uri=rule_uri, + renderer=Renderer) return app(environ, start_response) def find_file(self, path): Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/public/selector.js ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/public/selector.js Wed Nov 29 09:34:07 2006 @@ -0,0 +1,66 @@ +function selectId(button, destName) { + var oldHTML = button.innerHTML; + button.innerHTML = 'reading...'; + button.disabled = true; + selectIdSafe(destName); + button.innerHTML = oldHTML; + button.disabled = false; + return false; +} + +function selectIdSafe(destName) { + var form = document.forms[0]; + var url = form.elements.theme_uri.value; + if (! url) { + alert('You must first give a theme URI'); + return; + } + var real_url = remote_getter_url + '?url=' + escape(url); + req = loadJSONDoc(real_url); + req.addCallbacks(function (req) { + selectIdSuccess(req, destName); + }, + function (err) { + selectIdFail(err, destName); + }); +} + +function selectIdSuccess(ids, destName) { + try { + selectIdSuccessNoError(ids, destName); + } catch (e) { + alert('Error: '+e); + } +} + +function selectIdSuccessNoError(ids, destName) { + if (ids.error) { + alert('Error fetching Theme URL: '+ids.error); + return; + } + var form = document.forms[0]; + var el = form[destName]; + var selected = el.value; + var parent = el.parentNode; + var newEl = SELECT({name: destName}); + for (var i=0; i Administration for <% c.domain_info.domain_name | h %> + + + +

      Administration for <% c.domain_info.domain_name | h %>

      -

      Visit the site

      +

      Visit the site

      + +% if c.remote_template: +% for name, value in sorted(c.remote_template.items()): + <% name %>:
      +
      +% #endfor +% else: Remote URL:

      +% #endif + Theme URL:

      + style="width: 80%"> + view +
      + +% if c.rule_template: +% for name, value in sorted(c.rule_template.items()): + <% name %>:
      + +% if name.endswith('_id'): + + read ids + +% #endif +
      +% #endfor +% else: Rule:

      +% #endif +
      +% if c.rule_template: +
      +Current rules: +
      <% c.rule_text | h %>
      +% #endif Added: z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/test_remote_getter.py ============================================================================== --- (empty file) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/tests/functional/test_remote_getter.py Wed Nov 29 09:34:07 2006 @@ -0,0 +1,6 @@ +from ddemo.tests import * + +class TestRemoteGetterController(TestController): + def test_index(self): + response = self.app.get(url_for(controller='remote_getter')) + # Test response... \ No newline at end of file Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/ddemo/wsgiapp.py Wed Nov 29 09:34:07 2006 @@ -53,8 +53,6 @@ app = httpexceptions.make_middleware(app, global_conf) app = ErrorHandler(app, global_conf, error_template=error_template, **config.errorware) - app = RegistryManager(app) - static_app = StaticURLParser(config.paths['static_files']) javascripts_app = StaticJavascripts() app = Cascade([static_app, javascripts_app, app]) @@ -62,6 +60,7 @@ app = RecursiveMiddleware(app) if asbool(app_conf.get('debug_headers')): app = proxyapp.DebugHeaders(app) + app = RegistryManager(app) if (asbool(full_stack) and asbool(app_conf.get('debug', global_conf.get('debug')))): from paste.evalexception import EvalException Modified: z3/deliverance/DeliveranceDemo/trunk/development.ini ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/development.ini (original) +++ z3/deliverance/DeliveranceDemo/trunk/development.ini Wed Nov 29 09:34:07 2006 @@ -39,4 +39,13 @@ # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. -#set debug = false +set debug = true + +[app:openplans] +use = main +remote_template = http://norewrite.openplans.org/VirtualHostBase/{scheme}/{domain}:{port}/openplans/projects/{project}/VirtualHostRoot/ +rule_template = + + + + Modified: z3/deliverance/DeliveranceDemo/trunk/setup.py ============================================================================== --- z3/deliverance/DeliveranceDemo/trunk/setup.py (original) +++ z3/deliverance/DeliveranceDemo/trunk/setup.py Wed Nov 29 09:34:07 2006 @@ -11,6 +11,7 @@ "Pylons>=0.9.3", 'Deliverance', 'WSGIFilter', + 'WSGIRemote', ], packages=find_packages(), include_package_data=True, From ltucker at codespeak.net Mon Dec 4 21:42:55 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 4 Dec 2006 21:42:55 +0100 (CET) Subject: [z3-checkins] r35269 - in z3/deliverance/trunk/deliverance/test-data: nycsr tasktracker Message-ID: <20061204204255.83B021007B@code0.codespeak.net> Author: ltucker Date: Mon Dec 4 21:42:52 2006 New Revision: 35269 Added: z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_theme.html z3/deliverance/trunk/deliverance/test-data/tasktracker/nycsr_theme.html Log: adding static pages to test Added: z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_theme.html ============================================================================== --- (empty file) +++ z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_theme.html Mon Dec 4 21:42:52 2006 @@ -0,0 +1,1155 @@ + + + + + + + + + + StreetFilms Video Gallery - The New York City Streets Renaissance + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + + + + + + + +
      + + +
      + + + +
      + + + + + + +

      StreetFilms Video Gallery

      + + +

      + Recently Added Videos +

      + +
      + +

      + Previous Videos +

      + +
      + +
      + + +
      + +
      + + + +
      + + + + + + Added: z3/deliverance/trunk/deliverance/test-data/tasktracker/nycsr_theme.html ============================================================================== --- (empty file) +++ z3/deliverance/trunk/deliverance/test-data/tasktracker/nycsr_theme.html Mon Dec 4 21:42:52 2006 @@ -0,0 +1,1155 @@ + + + + + + + + + + StreetFilms Video Gallery - The New York City Streets Renaissance + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + + + + + + + +
      + + +
      + + + +
      + + + + + + +

      StreetFilms Video Gallery

      + + +

      + Recently Added Videos +

      + +
      + +

      + Previous Videos +

      + +
      + +
      + + +
      + +
      + + + +
      + + + + + + From ltucker at codespeak.net Mon Dec 4 21:45:42 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 4 Dec 2006 21:45:42 +0100 (CET) Subject: [z3-checkins] r35270 - z3/deliverance/trunk/deliverance/test-data/tasktracker Message-ID: <20061204204542.CD0C01007B@code0.codespeak.net> Author: ltucker Date: Mon Dec 4 21:45:41 2006 New Revision: 35270 Removed: z3/deliverance/trunk/deliverance/test-data/tasktracker/nycsr_theme.html Log: only need one of these Deleted: /z3/deliverance/trunk/deliverance/test-data/tasktracker/nycsr_theme.html ============================================================================== --- /z3/deliverance/trunk/deliverance/test-data/tasktracker/nycsr_theme.html Mon Dec 4 21:45:41 2006 +++ (empty file) @@ -1,1155 +0,0 @@ - - - - - - - - - - StreetFilms Video Gallery - The New York City Streets Renaissance - - - - - - - - - - - - - - - - - - - - - -
      - - - - - - - - - - - - -
      - - -
      - - - -
      - - - - - - -

      StreetFilms Video Gallery

      - - -

      - Recently Added Videos -

      - -
      - -

      - Previous Videos -

      - -
      - -
      - - -
      - -
      - - - -
      - - - - - - From ltucker at codespeak.net Mon Dec 4 21:57:59 2006 From: ltucker at codespeak.net (ltucker at codespeak.net) Date: Mon, 4 Dec 2006 21:57:59 +0100 (CET) Subject: [z3-checkins] r35271 - in z3/deliverance/trunk: . deliverance deliverance/test-data/nycsr deliverance/test-data/tasktracker Message-ID: <20061204205759.5A67D10077@code0.codespeak.net> Author: ltucker Date: Mon Dec 4 21:57:54 2006 New Revision: 35271 Modified: z3/deliverance/trunk/deliverance/fixuplinks.py z3/deliverance/trunk/deliverance/handtransform.py z3/deliverance/trunk/deliverance/interpreter.py z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_expected.html z3/deliverance/trunk/deliverance/test-data/tasktracker/expected.html z3/deliverance/trunk/deliverance/test_speed.py z3/deliverance/trunk/deliverance/test_wsgi.py z3/deliverance/trunk/deliverance/tests.py z3/deliverance/trunk/deliverance/wsgimiddleware.py z3/deliverance/trunk/deliverance/xslt.py z3/deliverance/trunk/setup.py Log: test few things remotely using svn, make certain imports specific to deliverance Modified: z3/deliverance/trunk/deliverance/fixuplinks.py ============================================================================== --- z3/deliverance/trunk/deliverance/fixuplinks.py (original) +++ z3/deliverance/trunk/deliverance/fixuplinks.py Mon Dec 4 21:57:54 2006 @@ -3,7 +3,7 @@ """ -from htmlserialize import decodeAndParseHTML, tostring +from deliverance.htmlserialize import decodeAndParseHTML, tostring import urlparse import re Modified: z3/deliverance/trunk/deliverance/handtransform.py ============================================================================== --- z3/deliverance/trunk/deliverance/handtransform.py (original) +++ z3/deliverance/trunk/deliverance/handtransform.py Mon Dec 4 21:57:54 2006 @@ -1,9 +1,9 @@ import sys from lxml import etree -from htmlserialize import tostring +from deliverance.htmlserialize import tostring import urllib -from interpreter import Renderer as PythonRenderer -from xslt import Renderer as XSLTRenderer +from deliverance.interpreter import Renderer as PythonRenderer +from deliverance.xslt import Renderer as XSLTRenderer from optparse import OptionParser import re import os Modified: z3/deliverance/trunk/deliverance/interpreter.py ============================================================================== --- z3/deliverance/trunk/deliverance/interpreter.py (original) +++ z3/deliverance/trunk/deliverance/interpreter.py Mon Dec 4 21:57:54 2006 @@ -1,9 +1,9 @@ from lxml import etree -import xinclude +from deliverance import xinclude import copy -import utils -from utils import RuleSyntaxError -from utils import RendererBase +from deliverance import utils +from deliverance.utils import RuleSyntaxError +from deliverance.utils import RendererBase class Renderer(RendererBase): """ Modified: z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_expected.html ============================================================================== --- z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_expected.html (original) +++ z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_expected.html Mon Dec 4 21:57:54 2006 @@ -20,8 +20,8 @@ - - + + @@ -52,8 +52,8 @@ OpenPlans - - + +
      @@ -369,22 +375,22 @@