• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

allura


Commit MetaInfo

Revisión15ed07eac5a3e5abd07f655e35178545f4d2d9e4 (tree)
Tiempo2011-04-30 02:08:35
AutorRick Copeland <rcopeland@geek...>
CommiterRick Copeland

Log Message

[#1831] Refactor tg compatibility shim

Signed-off-by: Rick Copeland <rcopeland@geek.net>

Cambiar Resumen

Diferencia incremental

--- a/Allura/allura/factory.py
+++ b/Allura/allura/factory.py
@@ -9,9 +9,11 @@ from paste.registry import RegistryManager
99 from pyramid.config import Configurator
1010 from pyramid.session import UnencryptedCookieSessionFactoryConfig
1111
12-import tg.error
1312 import ew
1413 import ming
14+import tg.view
15+import tg.error
16+import tg.traversal
1517 from ming.orm.middleware import MingMiddleware
1618 from tg.shim import RootFactory
1719
@@ -45,10 +47,11 @@ def main(global_config, **settings):
4547 secret=settings['session.secret'],
4648 cookie_name=settings['session.key']))
4749 config.add_view(
48- tg.shim.tg_view,
49- context='tg.shim.Resource',
50- renderer='allura:templates/mytemplate.pt')
51- config.add_view(tg.shim.error_view, context=exc.WSGIHTTPException)
50+ tg.view.tg_view,
51+ context=tg.traversal.Resource)
52+ config.add_view(
53+ tg.view.error_view,
54+ context=exc.WSGIHTTPException)
5255 app = config.make_wsgi_app()
5356
5457 if asbool(conf.get('auth.method', 'local')=='sfx'):
--- a/Allura/tg/__init__.py
+++ b/Allura/tg/__init__.py
@@ -1,3 +1,3 @@
11 from .tg_globals import c, g, response, request, config, session, environ
2-from .shim import redirect, url
2+from .util import redirect, url
33 from .decorators import expose, validate
--- a/Allura/tg/decorators.py
+++ b/Allura/tg/decorators.py
@@ -16,7 +16,9 @@ class _tg_deco(object):
1616 class expose(_tg_deco): pass
1717 class validate(_tg_deco): pass
1818 class before_validate(_tg_deco): pass
19-class override_template(_tg_deco): pass
19+
20+def override_template(func, template):
21+ c.override_template = template
2022
2123 def without_trailing_slash(func):
2224 from tg import redirect
@@ -54,6 +56,7 @@ class Decoration(object):
5456
5557 def expose(self, template=None, content_type=None):
5658 self.exposed = True
59+ assert not self._templates, 'Multiple @expose not supported in shim'
5760 if template or content_type:
5861 self._templates[content_type] = template
5962
@@ -86,24 +89,32 @@ class Decoration(object):
8689 return params
8790
8891 def do_render_response(self, result):
89- if len(self._templates) == 1:
90- ct, tname = self._templates.items()[0]
91- if ct is not None:
92- response.content_type = ct
93- if tname in ('json', 'json:'):
94- engine, tname = 'json', 'json'
95- response.content_type = 'application/json'
96- else:
97- engine, tname = tname.split(':', 1)
98- f = ew.render.File(tname, engine)
99- rendered_result = f(result)
100- elif self._templates:
101- assert False, 'Multiple @expose not supported in shim'
92+ tname = self._lookup_template()
93+ if tname in ('json', 'json:'):
94+ engine, tname = 'json', 'json'
95+ response.content_type = 'application/json'
96+ elif tname is None:
97+ return self._make_iter(result)
10298 else:
103- rendered_result = result
104- if isinstance(rendered_result, unicode):
105- return [ rendered_result.encode('utf-8') ]
106- elif isinstance(rendered_result, str):
107- return [ rendered_result ]
99+ engine, tname = tname.split(':', 1)
100+ f = ew.render.File(tname, engine)
101+ return self._make_iter(f(result))
102+
103+ def _lookup_template(self):
104+ tpl = getattr(c, 'override_template', None)
105+ if tpl is not None: return tpl
106+ if len(self._templates) > 1:
107+ assert False, 'Multiple @expose not supported in shim'
108+ if not self._templates: return None
109+ ct, tname = self._templates.items()[0]
110+ if ct is not None:
111+ response.content_type = ct
112+ return tname
113+
114+ def _make_iter(self, result):
115+ if isinstance(result, unicode):
116+ return [ result.encode('utf-8') ]
117+ elif isinstance(result, str):
118+ return [ result ]
108119 else:
109- return rendered_result
120+ return result
--- a/Allura/tg/shim.py
+++ b/Allura/tg/shim.py
@@ -1,21 +1,11 @@
11 '''TG compatibility shim
22 '''
3-import types
4-import urllib
5-
6-import tg
73 import pkg_resources
84 import pyramid.response
9-from formencode import Invalid
10-from webob import exc
11-
12-from decorators import Decoration
135
146 from . import tg_globals
157 from .traversal import Resource
168
17-__all__ = [ 'redirect', 'url' ]
18-
199 class RootFactory(object):
2010
2111 def __init__(self, root):
@@ -43,89 +33,3 @@ class RootFactory(object):
4333 if hasattr(root_obj, '_cleanup_request'):
4434 root_obj._cleanup_request()
4535
46-def tg_view(context, request):
47- deco, func = context.get_deco()
48- try:
49- if not deco or not deco.exposed: raise exc.HTTPNotFound()
50- try:
51- # Validate params
52- params = deco.do_validate_params(request.params.mixed())
53- result = func(**params)
54- except Invalid, inv:
55- tg.c.validation_exception = inv
56- eh = deco.error_handler
57- if eh:
58- result = eh(func.im_self, **request.params)
59- deco = Decoration.get(deco.error_handler, False)
60- else:
61- result = func(**request.params)
62- tg_globals.response.app_iter = deco.do_render_response(result)
63- except exc.WSGIHTTPException, err:
64- registry = request.environ['paste.registry']
65- response = request.get_response(err)
66- registry.register(tg_globals.response, response)
67- return tg_globals.response
68-
69-def error_view(context, request):
70- return context
71-
72-def redirect(*args, **kwargs):
73- found = exc.HTTPFound(location=url(*args, **kwargs))
74- raise found.exception
75-
76-def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
77- """
78- Returns a bytestring version of 's', encoded as specified in 'encoding'.
79-
80- If strings_only is True, don't convert (some) non-string-like objects.
81-
82- This function was borrowed from Django
83- """
84- if strings_only and isinstance(s, (types.NoneType, int)):
85- return s
86- elif not isinstance(s, basestring):
87- try:
88- return str(s)
89- except UnicodeEncodeError:
90- if isinstance(s, Exception):
91- # An Exception subclass containing non-ASCII data that doesn't
92- # know how to print itself properly. We shouldn't raise a
93- # further exception.
94- return ' '.join([smart_str(arg, encoding, strings_only,
95- errors) for arg in s])
96- return unicode(s).encode(encoding, errors)
97- elif isinstance(s, unicode):
98- r = s.encode(encoding, errors)
99- return r
100- elif s and encoding != 'utf-8':
101- return s.decode('utf-8', errors).encode(encoding, errors)
102- else:
103- return s
104-
105-def generate_smart_str(params):
106- for key, value in params.iteritems():
107- if value is None: continue
108- if isinstance(value, (list, tuple)):
109- for item in value:
110- yield smart_str(key), smart_str(item)
111- else:
112- yield smart_str(key), smart_str(value)
113-
114-def urlencode(params):
115- """
116- A version of Python's urllib.urlencode() function that can operate on
117- unicode strings. The parameters are first case to UTF-8 encoded strings and
118- then encoded as per normal.
119- """
120- return urllib.urlencode([i for i in generate_smart_str(params)])
121-
122-def url(base_url=None, params=None):
123- if base_url is None: base_url = '/'
124- if params is None: params = {}
125- if hasattr(base_url, '__iter__' ) and not isinstance(base_url, basestring):
126- base_url = '/'.join(base_url)
127- if base_url.startswith('/'):
128- base_url = tg.request.environ['SCRIPT_NAME'] + base_url
129- if params:
130- return '?'.join((base_url, urlencode(params)))
131- return base_url
--- a/Allura/tg/util.py
+++ b/Allura/tg/util.py
@@ -1,3 +1,10 @@
1+import types
2+import urllib
3+
4+from webob import exc
5+
6+from .tg_globals import request
7+
18 def call_wsgi_application(application, environ, catch_exc_info=False):
29 """
310 Call the given WSGI application, returning ``(status_string,
@@ -30,3 +37,65 @@ def call_wsgi_application(application, environ, catch_exc_info=False):
3037 return (captured[0], captured[1], app_iter, captured[2])
3138 else:
3239 return (captured[0], captured[1], app_iter)
40+
41+
42+def redirect(*args, **kwargs):
43+ found = exc.HTTPFound(location=url(*args, **kwargs))
44+ raise found.exception
45+
46+def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
47+ """
48+ Returns a bytestring version of 's', encoded as specified in 'encoding'.
49+
50+ If strings_only is True, don't convert (some) non-string-like objects.
51+
52+ This function was borrowed from Django
53+ """
54+ if strings_only and isinstance(s, (types.NoneType, int)):
55+ return s
56+ elif not isinstance(s, basestring):
57+ try:
58+ return str(s)
59+ except UnicodeEncodeError:
60+ if isinstance(s, Exception):
61+ # An Exception subclass containing non-ASCII data that doesn't
62+ # know how to print itself properly. We shouldn't raise a
63+ # further exception.
64+ return ' '.join([smart_str(arg, encoding, strings_only,
65+ errors) for arg in s])
66+ return unicode(s).encode(encoding, errors)
67+ elif isinstance(s, unicode):
68+ r = s.encode(encoding, errors)
69+ return r
70+ elif s and encoding != 'utf-8':
71+ return s.decode('utf-8', errors).encode(encoding, errors)
72+ else:
73+ return s
74+
75+def generate_smart_str(params):
76+ for key, value in params.iteritems():
77+ if value is None: continue
78+ if isinstance(value, (list, tuple)):
79+ for item in value:
80+ yield smart_str(key), smart_str(item)
81+ else:
82+ yield smart_str(key), smart_str(value)
83+
84+def urlencode(params):
85+ """
86+ A version of Python's urllib.urlencode() function that can operate on
87+ unicode strings. The parameters are first case to UTF-8 encoded strings and
88+ then encoded as per normal.
89+ """
90+ return urllib.urlencode([i for i in generate_smart_str(params)])
91+
92+def url(base_url=None, params=None):
93+ if base_url is None: base_url = '/'
94+ if params is None: params = {}
95+ if hasattr(base_url, '__iter__' ) and not isinstance(base_url, basestring):
96+ base_url = '/'.join(base_url)
97+ if base_url.startswith('/'):
98+ base_url = request.environ['SCRIPT_NAME'] + base_url
99+ if params:
100+ return '?'.join((base_url, urlencode(params)))
101+ return base_url
--- /dev/null
+++ b/Allura/tg/view.py
@@ -0,0 +1,31 @@
1+from formencode import Invalid
2+from webob import exc
3+
4+from . import tg_globals
5+from .decorators import Decoration
6+
7+def tg_view(context, request):
8+ deco, func = context.get_deco()
9+ try:
10+ if not deco or not deco.exposed: raise exc.HTTPNotFound()
11+ try:
12+ # Validate params
13+ params = deco.do_validate_params(request.params.mixed())
14+ result = func(**params)
15+ except Invalid, inv:
16+ tg_globals.c.validation_exception = inv
17+ eh = deco.error_handler
18+ if eh:
19+ result = eh(func.im_self, **request.params)
20+ deco = Decoration.get(deco.error_handler, False)
21+ else:
22+ result = func(**request.params)
23+ tg_globals.response.app_iter = deco.do_render_response(result)
24+ except exc.WSGIHTTPException, err:
25+ registry = request.environ['paste.registry']
26+ response = request.get_response(err)
27+ registry.register(tg_globals.response, response)
28+ return tg_globals.response
29+
30+def error_view(context, request):
31+ return context
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -303,9 +303,9 @@ class TestForum(TestController):
303303 # beautiful soup is getting some unicode error here - test without it
304304 assert thread.html.findAll('div',{'class':'display_post'})[0].find('p').string == 'aaa'
305305 assert thread.html.findAll('div',{'class':'display_post'})[1].find('p').string == 'bbb'
306- assert thread.response.body.count('<div class="promote_to_thread_form') == 1
307- assert thread.response.body.count('<div class="row reply_post_form') == 2
308- assert thread.response.body.count('<div class="edit_post_form') == 2
306+ assert thread.body.count('<div class="promote_to_thread_form') == 1
307+ assert thread.body.count('<div class="row reply_post_form') == 2
308+ assert thread.body.count('<div class="edit_post_form') == 2
309309
310310 def get_table_rows(self, response, closest_id):
311311 tbody = response.html.find('div', {'id': closest_id}).find('tbody')