[z3-checkins] r35100 - in z3/deliverance/DeliveranceDemo/trunk: . ddemo ddemo/controllers ddemo/public ddemo/templates ddemo/tests/functional
ianb at codespeak.net
ianb at codespeak.net
Wed Nov 29 09:34:26 CET 2006
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 = '''\
<?xml version="1.0" encoding="UTF-8"?>
-
<rules xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://www.plone.org/deliverance" >
<xi:include href="standardrules.xml" />
@@ -13,6 +12,17 @@
</rules>
'''
+marker = '<!-- Generated, do not edit! -->'
+abstract_rule_xml = '''\
+<?xml version="1.0" encoding="UTF-8"?>
+MARKER
+<rules xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://www.plone.org/deliverance" >
+ <xi:include href="standardrules.xml" />
+
+ <copy theme="//*[%(theme_expr)s]" content="//*[%(content_expr)s]" />
+</rules>
+'''.replace('MARKER', marker)
+
default_standardrules = '''\
<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://www.plone.org/deliverance">
@@ -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<ids.length; i++) {
+ var newOp = OPTION({value: ids[i]}, ids[i]);
+ if (ids[i] == selected) {
+ newOp.selected = true;
+ }
+ newEl.appendChild(newOp);
+ }
+ parent.insertBefore(newEl, el);
+ parent.removeChild(el);
+}
+
+function selectIdFail(err, destName) {
+ alert(err);
+}
+
+function visitTheme() {
+ var form = document.forms[0];
+ var url = form.theme_uri.value;
+ window.open(url);
+ return false;
+}
\ No newline at end of file
Modified: z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/index.myt
==============================================================================
--- z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/index.myt (original)
+++ z3/deliverance/DeliveranceDemo/trunk/ddemo/templates/index.myt Wed Nov 29 09:34:07 2006
@@ -1,28 +1,68 @@
<html>
<head>
<title>Administration for <% c.domain_info.domain_name | h %></title>
+ <script type="text/javascript" src="<% h.url_for('MochiKit/MochiKit.js') %>"></script>
+ <script type="text/javascript" src="<% h.url_for('selector.js') %>"></script>
+ <script type="text/javascript">
+ remote_getter_url = '<% h.url_for(controller='remote_getter') %>';
+ </script>
+
</head>
<body>
<h1>Administration for <% c.domain_info.domain_name | h %></h1>
-<p><a href="/">Visit the site</a></p>
+<p><a href="/" target="_blank">Visit the site</a></p>
<form action="<% h.url_for(controller='index') %>" method="POST">
+
+% if c.remote_template:
+% for name, value in sorted(c.remote_template.items()):
+ <% name %>:<br>
+ <input type="text" name="remote.<% name | h%>"
+ value="<% value | h %>"
+ style="width: 100%"><br>
+% #endfor
+% else:
Remote URL:<br>
<input type="text" name="remote"
value="<% c.domain_info.remote | h %>"
style="width: 100%"><br>
+% #endif
+
Theme URL:<br>
<input type="text" name="theme_uri"
value="<% c.domain_info.theme_uri | h %>"
- style="width: 100%"><br>
+ style="width: 80%">
+ <a href="#" onclick="return visitTheme()">view</a>
+ <br>
+
+% if c.rule_template:
+% for name, value in sorted(c.rule_template.items()):
+ <% name %>:<br>
+ <input type="text" name="rule.<% name | h %>"
+ value="<% value | h %>">
+% if name.endswith('_id'):
+ <a href="#" onclick="return selectId(this, 'rule.<% name | h %>')">
+ read ids
+ </a>
+% #endif
+ <br>
+% #endfor
+% else:
Rule:<br>
<textarea name="rule_xml" rows=10
style="width: 100%"><% c.rule_text | h %></textarea><br>
+% #endif
+
<button type="submit">Save</button>
</form>
+% if c.rule_template:
+<hr noshade>
+Current rules:
+<pre><% c.rule_text | h %></pre>
+% #endif
</body>
</html>
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 = <?xml version="1.0" encoding="UTF-8"?>
+ <rules xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://www.plone.org/deliverance" >
+ <xi:include href="standardrules.xml" />
+ <copy theme="//*[@id='{theme_id}']" content="//*[@id='content']" />
+ </rules>
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,
More information about the z3-checkins
mailing list