{{ event.title }}
- {% if event.main_image %}+ This is not a KCDC event. It is produced by another organization. + We include it because we think that it will be of interest to our students. +
+ {% endif %} + {% if event.documentation %}Documentation
{{ event.documentation|safe }} @@ -67,6 +87,7 @@Additional meetings
{% endif %}Location
+ {% if event.location_text %}{{ event.location_text|safe }}
{% endif %}
{% ifnotequal event.location.name event.location.address1 %}{{ event.location.name }}
{% endifnotequal %}
{% if event.location.address1 and event.location.show_exact %}
@@ -95,8 +116,8 @@
Past event
{% elif event.registration_status == "HIDE" %} {% else %} - {% if event.registration_status == "AUTO" %} -Registration is not yet open.
+ {% if event.registration_status == "AUTO" and not event.is_registration_open %} +Registration for this class opens {{ event.registration_opens|date:"l, j F, P" }}
{% elif event.registration_status == "PREVENT" %}Registration is closed.
{% elif registration_count >= event.max_students %} @@ -105,7 +126,7 @@This class is full, but there is a waitlist available.
{% else %}This class is full.
{% endif %} - {% else %} + {% else%}Register
{% endif %} {% endif %} @@ -166,10 +187,14 @@Register
diff --git a/kcdc3/templates/classes/event_list.html b/kcdc3/apps/classes/templates/classes/event_list.html similarity index 64% rename from kcdc3/templates/classes/event_list.html rename to kcdc3/apps/classes/templates/classes/event_list.html index 6401673e..c439bb26 100644 --- a/kcdc3/templates/classes/event_list.html +++ b/kcdc3/apps/classes/templates/classes/event_list.html @@ -1,12 +1,18 @@ {% extends "classes/event_base.html" %} +{% load pinata_filters %} + {% block title %} / Classes and Events{% endblock %} {% block content %}Classes + Events
-As always, KCDC classes are free – and they fill up fast!
+ {% for session in selected_session %} + {% if forloop.last %} +{{ session.kicker|safe }}
+ {% endif %} + {% endfor %}Upcoming classes
{% endifchanged %} -- - {{ event.title }} + {% if event.type == "EXTERNAL" %}Partner Event:{% endif %} + {{ event.title | smartquotes | safe }}
+ + {% if event.thumbnail %}user Instructor{{ event.num_teachers|pluralize }}: {% for bio in event.teacher_bios.all %}{% if not forloop.first %}, {% endif %}{{ bio.name }}{% endfor %}
@@ -102,21 +120,30 @@Recent classes
{% endifchanged %} {% endifchanged %} -- - {{ event.title }} + {% if event.type == "EXTERNAL" %}Partner Event:{% endif %} + {{ event.title | smartquotes | safe }}
+ {% if event.thumbnail %}user Instructor{{ event.num_teachers|pluralize }}: {% for bio in event.teacher_bios.all %}{% if not forloop.first %}, {% endif %}{{ bio.name }}{% endfor %} + {% if event.teacher_text %}{{ event.teacher_text|safe }}{% endif %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/kcdc3/templates/classes/event_session.html b/kcdc3/apps/classes/templates/classes/event_session.html
similarity index 100%
rename from kcdc3/templates/classes/event_session.html
rename to kcdc3/apps/classes/templates/classes/event_session.html
diff --git a/kcdc3/templates/classes/facilitator_event_detail.html b/kcdc3/apps/classes/templates/classes/facilitator_event_detail.html
similarity index 89%
rename from kcdc3/templates/classes/facilitator_event_detail.html
rename to kcdc3/apps/classes/templates/classes/facilitator_event_detail.html
index 47ea948c..c140c5cb 100644
--- a/kcdc3/templates/classes/facilitator_event_detail.html
+++ b/kcdc3/apps/classes/templates/classes/facilitator_event_detail.html
@@ -16,6 +16,9 @@ Registered students ({{ registration_count }})
email
+
+ phone
+
date registered
@@ -34,6 +37,9 @@ Registered students ({{ registration_count }})
{{ registration.student.email }}
+
+ {{ registration.student.extendedprofile.phone_number }}
+
{{ registration.date_registered }}
@@ -65,6 +71,9 @@ Waitlisted students ({{ waitlist_count }})
email
+
+ phone
+
date registered
@@ -80,6 +89,9 @@ Waitlisted students ({{ waitlist_count }})
{{ registration.student.email }}
+
+ {{ registration.student.extendedprofile.phone_number }}
+
{{ registration.date_registered }}
diff --git a/kcdc3/templates/classes/registration_list.html b/kcdc3/apps/classes/templates/classes/registration_list.html
similarity index 100%
rename from kcdc3/templates/classes/registration_list.html
rename to kcdc3/apps/classes/templates/classes/registration_list.html
diff --git a/kcdc3/templates/classes/response.html b/kcdc3/apps/classes/templates/classes/response.html
similarity index 100%
rename from kcdc3/templates/classes/response.html
rename to kcdc3/apps/classes/templates/classes/response.html
diff --git a/kcdc3/apps/classes/templates/classes/staff.html b/kcdc3/apps/classes/templates/classes/staff.html
new file mode 100644
index 00000000..d68f02d2
--- /dev/null
+++ b/kcdc3/apps/classes/templates/classes/staff.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+ Knowledge Commons DC {% block title %}{% endblock %}
+
+
+
+
+
+
+
+
+
+
+
+ Knowledge Commons DC
+ skip to content
+
+
+
+
+
+
+
+
+
+
+
+ {% block pre_content %}{% endblock %}
+
+ {% block content_shell %}
+
+
+ {% block content %}{% endblock %}
+ {% block sidebar %}{% endblock %}
+
+
+ {% endblock %}
+
+ {% block post_content %}{% endblock %}
+
+ {% comment %}
+
+ {% endcomment %}
+
+
+
+
+
+
+
+
+ {% block local_scripts %}{% endblock %}
+
+
+
diff --git a/kcdc3/apps/classes/templates/classes/staff_registration_list.html b/kcdc3/apps/classes/templates/classes/staff_registration_list.html
new file mode 100644
index 00000000..315d5d5b
--- /dev/null
+++ b/kcdc3/apps/classes/templates/classes/staff_registration_list.html
@@ -0,0 +1,77 @@
+
+
+{% block content %}
+
+ Registrations
+
Knowledge Commons DC
+ skip to content +| + name + | ++ username + | ++ email + | ++ class + | ++ class date + | ++ date registered + | ++ date cancelled + | ++ date promoted + | ++ late promotion + | ++ attended + | +
| + {{ registration.student.first_name }} {{ registration.student.last_name }} + | ++ {{ registration.student.username }} + | ++ {{ registration.student.email }} + | ++ {{ registration.event }} + | ++ {{ registration.event.date }} + | ++ {{ registration.date_registered }} + | ++ {{ registration.date_cancelled }} + | ++ {{ registration.date_promoted }} + | ++ {{ registration.late_promotion }} + | ++ {{ registration.attended }} + | +
+ +
Sessions
+| + | ++ Session + | ++ Status + | ++ Regular classes + | ++ Registrations + | ++ Attended + | ++ Reports + | +|
| + Edit + | ++ {{ session.long_title }} + | ++ {{ session.status }} + | ++ {{ session.get_live_classes.count }} + | ++ {{ session.get_registrations.count }} + | ++ {{ session.get_attended_registrations.count }} + | ++ Teachers + | ++ Registrations + | +
+ + + + +{% endblock %} + diff --git a/kcdc3/apps/classes/templates/classes/staff_teacher_list.html b/kcdc3/apps/classes/templates/classes/staff_teacher_list.html new file mode 100644 index 00000000..c6ddabce --- /dev/null +++ b/kcdc3/apps/classes/templates/classes/staff_teacher_list.html @@ -0,0 +1,72 @@ + + +{% block content %} + +
Teachers
+| + | ++ | ++ name + | ++ email + | ++ rating + | ++ comments + | ++ total + | ++ classes + | +
| + Edit + | ++ {{ forloop.counter }} + | ++ {{ bio.name }} + | ++ {{ bio.get_email }} + | ++ {% if bio.rating %}{{ bio.rating }}{% endif %} + | ++ {% if bio.comments %}{{ bio.comments }}{% endif %} + | ++ {{ bio.get_classes.count }} + | ++ {% for event in bio.get_classes.all %} + {{ event.title }} + {% endfor %} + | +
+ + {% for bio in teacher_list %} + {{ bio.get_email }}, + {% endfor %} + + + +{% endblock %} + diff --git a/kcdc3/classes/tests.py b/kcdc3/apps/classes/tests.py similarity index 100% rename from kcdc3/classes/tests.py rename to kcdc3/apps/classes/tests.py diff --git a/kcdc3/apps/classes/urls.py b/kcdc3/apps/classes/urls.py new file mode 100644 index 00000000..d1c5491d --- /dev/null +++ b/kcdc3/apps/classes/urls.py @@ -0,0 +1,20 @@ +from django.conf.urls import patterns, include, url +from models import Event, Registration +from views import EventListView, EventDetailView, ResponseTemplateView, EventArchiveView, SessionView, RegistrationListView, SessionAdminListView, TeacherAdminListView, FilteredTeacherAdminListView + +urlpatterns = patterns('kcdc3.apps.classes.views', + + url(r'^$', EventListView.as_view()), + url(r'^staff/$', SessionAdminListView.as_view()), + url(r'^staff/teachers/$', TeacherAdminListView.as_view()), + url(r'^staff/teachers/session/(?P
{{ post.department_label }}
{% endif %} +{{ post.title }}
+ ++ {% for bio in post.author.all %} + {{ bio.get_staff_description|safe }} + {% endfor %} + {% endif %} + +
Blog
+-
+
+ {% for post in recent_posts %}
+
+ {% ifchanged %}
+
- + {{ post.date|date:"j F Y" }} + + {% endifchanged %} + +
-
+
+
+
+ {% if post.department_label %}{{ post.department_label }}: {% endif %} + {{ post.title }} +
+ + {% if post.author.count > 0 %} +By + {% for bio in post.author.all %} + {% if forloop.last %}{% if forloop.counter > 1 %} and {% endif %}{% endif %} + {{ bio.name }}{% if not forloop.last %}{% if post.author.all|length > 2 %}, {% endif %}{% endif %} + {% endfor %} +
+ {% endif %} + + {{ post.teaser|safe }} + + +
+
+
+ {% endfor %}
+
+
+
+
+ Knowledge Commons DC is a free school for thinkers, doers, and tinkerers – taught anywhere, by anyone, for everyone. +
+ +Blog
+ + {% for post in posts %} + + {% endfor %} +{{ title }}
+-
+ {% for page in siblings %}
+
- ▻{{ page.short_title }} + {% endfor %} + {% for page in children %} +
- ▻{{ page.short_title }} + {% endfor %} +
-
+ {% for page in siblings %}
+
- {{ page.short_title }} + {% endfor %} + {% for page in children %} +
- {{ page.short_title }} + {% endfor %} +
{{ title }}
+{{ title }}
+{{ short_title }}
+{{ pressclipping.publication }}
+ {% endif %} + +
+ {% if pressclipping.title %}{{ pressclipping.title }}
{% endif %}
+ {{ pressclipping.date|date:"j F Y" }}
+
“{{ pressclipping.excerpt }}”
+ {% endif %} + + {% if pressclipping.destination_url %} + + {% endif %} + +{{ title }}
+{{ title }}
+The Wonder Dojo
+ {{ dojo_role.description|safe }} +{{ bio.name }}
+{{ bio.title }}
+ {% if bio.website %}{% endif %} +Volunteers
+ {{ volunteers_role.description|safe }} + {% if volunteers %} +{{ bio.name }}
+{{ bio.title }}
+Dojo-at-Large and Emeritus
+ + {#Dojo-at-Large
#} + {# {{ dojo_at_large_role.description|safe }} #} + {% if dojo_at_large %} ++ At-Large: + {% for bio in dojo_at_large %} + {{ bio.name }}{% if bio.title %} ({{ bio.title }}){% endif %}{% if not forloop.last %}, {% endif %} + {% endfor %} +
+ {% endif %} + {{ dojo_at_large_role.extended_description|safe }} + + {#Dojo Emeritus
#} + {# {{ dojo_emeritus_role.description|safe }} #} + {% if dojo_emeritus %} ++ Emeritus: + {% for bio in dojo_emeritus %} + {{ bio.name }}{% if bio.title %} ({{ bio.title }}){% endif %}{% if not forloop.last %}, {% endif %} + {% endfor %} +
+ {% endif %} + {{ dojo_emeritus_role.extended_description|safe }} + +Please Login
- - - -""" - -class AuthFormHandler(object): - """ - HTML-based login middleware - - This causes a HTML form to be returned if ``REMOTE_USER`` is - not found in the ``environ``. If the form is returned, the - ``username`` and ``password`` combination are given to a - user-supplied authentication function, ``authfunc``. If this - is successful, then application processing continues. - - Parameters: - - ``application`` - - The application object is called only upon successful - authentication, and can assume ``environ['REMOTE_USER']`` - is set. If the ``REMOTE_USER`` is already set, this - middleware is simply pass-through. - - ``authfunc`` - - This is a mandatory user-defined function which takes a - ``environ``, ``username`` and ``password`` for its first - three arguments. It should return ``True`` if the user is - authenticated. - - ``template`` - - This is an optional (a default is provided) HTML - fragment that takes exactly one ``%s`` substution - argument; which *must* be used for the form's ``action`` - to ensure that this middleware component does not alter - the current path. The HTML form must use ``POST`` and - have two input names: ``username`` and ``password``. - - Since the authentication form is submitted (via ``POST``) - neither the ``PATH_INFO`` nor the ``QUERY_STRING`` are accessed, - and hence the current path remains _unaltered_ through the - entire authentication process. If authentication succeeds, the - ``REQUEST_METHOD`` is converted from a ``POST`` to a ``GET``, - so that a redirect is unnecessary (unlike most form auth - implementations) - """ - - def __init__(self, application, authfunc, template=None): - self.application = application - self.authfunc = authfunc - self.template = template or TEMPLATE - - def __call__(self, environ, start_response): - username = environ.get('REMOTE_USER','') - if username: - return self.application(environ, start_response) - - if 'POST' == environ['REQUEST_METHOD']: - formvars = parse_formvars(environ, include_get_vars=False) - username = formvars.get('username') - password = formvars.get('password') - if username and password: - if self.authfunc(environ, username, password): - environ['AUTH_TYPE'] = 'form' - environ['REMOTE_USER'] = username - environ['REQUEST_METHOD'] = 'GET' - environ['CONTENT_LENGTH'] = '' - environ['CONTENT_TYPE'] = '' - del environ['paste.parsed_formvars'] - return self.application(environ, start_response) - - content = self.template % construct_url(environ) - start_response("200 OK", [('Content-Type', 'text/html'), - ('Content-Length', str(len(content)))]) - return [content] - -middleware = AuthFormHandler - -__all__ = ['AuthFormHandler'] - -def make_form(app, global_conf, realm, authfunc, **kw): - """ - Grant access via form authentication - - Config looks like this:: - - [filter:grant] - use = egg:Paste#auth_form - realm=myrealm - authfunc=somepackage.somemodule:somefunction - - """ - from paste.util.import_string import eval_import - import types - authfunc = eval_import(authfunc) - assert isinstance(authfunc, types.FunctionType), "authfunc must resolve to a function" - template = kw.get('template') - if template is not None: - template = eval_import(template) - assert isinstance(template, str), "template must resolve to a string" - - return AuthFormHandler(app, authfunc, template) - -if "__main__" == __name__: - import doctest - doctest.testmod(optionflags=doctest.ELLIPSIS) diff --git a/kcdc3/paste/auth/grantip.py b/kcdc3/paste/auth/grantip.py deleted file mode 100644 index 94b39000..00000000 --- a/kcdc3/paste/auth/grantip.py +++ /dev/null @@ -1,113 +0,0 @@ -# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) -# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php -""" -Grant roles and logins based on IP address. -""" -from paste.util import ip4 - -class GrantIPMiddleware(object): - - """ - On each request, ``ip_map`` is checked against ``REMOTE_ADDR`` - and logins and roles are assigned based on that. - - ``ip_map`` is a map of {ip_mask: (username, roles)}. Either - ``username`` or ``roles`` may be None. Roles may also be prefixed - with ``-``, like ``'-system'`` meaning that role should be - revoked. ``'__remove__'`` for a username will remove the username. - - If ``clobber_username`` is true (default) then any user - specification will override the current value of ``REMOTE_USER``. - ``'__remove__'`` will always clobber the username. - - ``ip_mask`` is something that `paste.util.ip4:IP4Range -%s' - else: - fmt = 'Could not find OpenID information in
%s' - - message = fmt % (cgi.escape(openid_url),) - return self.render(request, message, css_class='error', form_contents=openid_url) - elif status == consumer.SUCCESS: - # The URL was a valid identity URL. Now we construct a URL - # that will get us to process the server response. We will - # need the token from the beginAuth call when processing - # the response. A cookie or a session object could be used - # to accomplish this, but for simplicity here we just add - # it as a query parameter of the return-to URL. - return_to = self.build_url(request, 'process', token=info.token) - - # Now ask the library for the URL to redirect the user to - # his OpenID server. It is required for security that the - # return_to URL must be under the specified trust_root. We - # just use the base_url for this server as a trust root. - redirect_url = oidconsumer.constructRedirect( - info, return_to, trust_root=request['base_url']) - - # Send the redirect response - return self.redirect(request, redirect_url) - else: - assert False, 'Not reached' - - def do_process(self, request): - """Handle the redirect from the OpenID server. - """ - oidconsumer = self.oidconsumer - - # retrieve the token from the environment (in this case, the URL) - token = request['query'].get('token', '') - - # Ask the library to check the response that the server sent - # us. Status is a code indicating the response type. info is - # either None or a string containing more information about - # the return type. - status, info = oidconsumer.completeAuth(token, request['query']) - - css_class = 'error' - openid_url = None - if status == consumer.FAILURE and info: - # In the case of failure, if info is non-None, it is the - # URL that we were verifying. We include it in the error - # message to help the user figure out what happened. - openid_url = info - fmt = "Verification of %s failed." - message = fmt % (cgi.escape(openid_url),) - elif status == consumer.SUCCESS: - # Success means that the transaction completed without - # error. If info is None, it means that the user cancelled - # the verification. - css_class = 'alert' - if info: - # This is a successful verification attempt. If this - # was a real application, we would do our login, - # comment posting, etc. here. - openid_url = info - if self.url_to_username: - username = self.url_to_username(request['environ'], openid_url) - else: - username = openid_url - if 'paste.auth_tkt.set_user' in request['environ']: - request['environ']['paste.auth_tkt.set_user'](username) - if not self.login_redirect: - fmt = ("If you had supplied a login redirect path, you would have " - "been redirected there. " - "You have successfully verified %s as your identity.") - message = fmt % (cgi.escape(openid_url),) - else: - # @@: This stuff doesn't make sense to me; why not a remote redirect? - request['environ']['paste.auth.open_id'] = openid_url - request['environ']['PATH_INFO'] = self.login_redirect - return self.app(request['environ'], request['start']) - #exc = httpexceptions.HTTPTemporaryRedirect(self.login_redirect) - #return exc.wsgi_application(request['environ'], request['start']) - else: - # cancelled - message = 'Verification cancelled' - else: - # Either we don't understand the code or there is no - # openid_url included with the error. Give a generic - # failure message. The library should supply debug - # information in a log. - message = 'Verification failed.' - - return self.render(request, message, css_class, openid_url) - - def build_url(self, request, action, **query): - """Build a URL relative to the server base_url, with the given - query parameters added.""" - base = urlparse.urljoin(request['base_url'], self.auth_prefix + '/' + action) - return appendArgs(base, query) - - def redirect(self, request, redirect_url): - """Send a redirect response to the given URL to the browser.""" - response_headers = [('Content-type', 'text/plain'), - ('Location', redirect_url)] - request['start']('302 REDIRECT', response_headers) - return ["Redirecting to %s" % redirect_url] - - def not_found(self, request): - """Render a page with a 404 return code and a message.""" - fmt = 'The path
%swas not understood by this server.' - msg = fmt % (request['parsed_uri'],) - openid_url = request['query'].get('openid_url') - return self.render(request, msg, 'error', openid_url, status='404 Not Found') - - def render(self, request, message=None, css_class='alert', form_contents=None, - status='200 OK', title="Python OpenID Consumer"): - """Render a page.""" - response_headers = [('Content-type', 'text/html')] - request['start'](str(status), response_headers) - - self.page_header(request, title) - if message: - request['body'].append("
%s
-- This example consumer uses the Python OpenID library. It - just verifies that the URL that you enter is your identity URL. -
-''' % (title, title)) - - def page_footer(self, request, form_contents): - """Render the page footer""" - if not form_contents: - form_contents = '' - - request['body'].append('''\ -Error in .close():
%s' - % close_response) - yield response - - def exception_handler(self, exc_info, environ): - dummy_file = StringIO() - hook = cgitb.Hook(file=dummy_file, - display=self.display, - logdir=self.logdir, - context=self.context, - format=self.format) - hook(*exc_info) - return dummy_file.getvalue() - -def make_cgitb_middleware(app, global_conf, - display=NoDefault, - logdir=None, - context=5, - format='html'): - """ - Wraps the application in the ``cgitb`` (standard library) - error catcher. - - display: - If true (or debug is set in the global configuration) - then the traceback will be displayed in the browser - - logdir: - Writes logs of all errors in that directory - - context: - Number of lines of context to show around each line of - source code - """ - from paste.deploy.converters import asbool - if display is not NoDefault: - display = asbool(display) - if 'debug' in global_conf: - global_conf['debug'] = asbool(global_conf['debug']) - return CgitbMiddleware( - app, global_conf=global_conf, - display=display, - logdir=logdir, - context=context, - format=format) diff --git a/kcdc3/paste/config.py b/kcdc3/paste/config.py deleted file mode 100644 index c5315797..00000000 --- a/kcdc3/paste/config.py +++ /dev/null @@ -1,120 +0,0 @@ -# (c) 2006 Ian Bicking, Philip Jenvey and contributors -# Written for Paste (http://pythonpaste.org) -# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php -"""Paste Configuration Middleware and Objects""" -from paste.registry import RegistryManager, StackedObjectProxy - -__all__ = ['DispatchingConfig', 'CONFIG', 'ConfigMiddleware'] - -class DispatchingConfig(StackedObjectProxy): - """ - This is a configuration object that can be used globally, - imported, have references held onto. The configuration may differ - by thread (or may not). - - Specific configurations are registered (and deregistered) either - for the process or for threads. - """ - # @@: What should happen when someone tries to add this - # configuration to itself? Probably the conf should become - # resolved, and get rid of this delegation wrapper - - def __init__(self, name='DispatchingConfig'): - super(DispatchingConfig, self).__init__(name=name) - self.__dict__['_process_configs'] = [] - - def push_thread_config(self, conf): - """ - Make ``conf`` the active configuration for this thread. - Thread-local configuration always overrides process-wide - configuration. - - This should be used like:: - - conf = make_conf() - dispatching_config.push_thread_config(conf) - try: - ... do stuff ... - finally: - dispatching_config.pop_thread_config(conf) - """ - self._push_object(conf) - - def pop_thread_config(self, conf=None): - """ - Remove a thread-local configuration. If ``conf`` is given, - it is checked against the popped configuration and an error - is emitted if they don't match. - """ - self._pop_object(conf) - - def push_process_config(self, conf): - """ - Like push_thread_config, but applies the configuration to - the entire process. - """ - self._process_configs.append(conf) - - def pop_process_config(self, conf=None): - self._pop_from(self._process_configs, conf) - - def _pop_from(self, lst, conf): - popped = lst.pop() - if conf is not None and popped is not conf: - raise AssertionError( - "The config popped (%s) is not the same as the config " - "expected (%s)" - % (popped, conf)) - - def _current_obj(self): - try: - return super(DispatchingConfig, self)._current_obj() - except TypeError: - if self._process_configs: - return self._process_configs[-1] - raise AttributeError( - "No configuration has been registered for this process " - "or thread") - current = current_conf = _current_obj - -CONFIG = DispatchingConfig() - -no_config = object() -class ConfigMiddleware(RegistryManager): - """ - A WSGI middleware that adds a ``paste.config`` key (by default) - to the request environment, as well as registering the - configuration temporarily (for the length of the request) with - ``paste.config.CONFIG`` (or any other ``DispatchingConfig`` - object). - """ - - def __init__(self, application, config, dispatching_config=CONFIG, - environ_key='paste.config'): - """ - This delegates all requests to `application`, adding a *copy* - of the configuration `config`. - """ - def register_config(environ, start_response): - popped_config = environ.get(environ_key, no_config) - current_config = environ[environ_key] = config.copy() - environ['paste.registry'].register(dispatching_config, - current_config) - - try: - app_iter = application(environ, start_response) - finally: - if popped_config is no_config: - environ.pop(environ_key, None) - else: - environ[environ_key] = popped_config - return app_iter - - super(self.__class__, self).__init__(register_config) - -def make_config_filter(app, global_conf, **local_conf): - conf = global_conf.copy() - conf.update(local_conf) - return ConfigMiddleware(app, conf) - -make_config_middleware = ConfigMiddleware.__doc__ diff --git a/kcdc3/paste/cowbell/__init__.py b/kcdc3/paste/cowbell/__init__.py deleted file mode 100644 index 43b7097b..00000000 --- a/kcdc3/paste/cowbell/__init__.py +++ /dev/null @@ -1,104 +0,0 @@ -# Cowbell images: http://commons.wikimedia.org/wiki/Image:Cowbell-1.jpg -import os -import re -from paste.fileapp import FileApp -from paste.response import header_value, remove_header - -SOUND = "http://www.c-eye.net/eyeon/WalkenWAVS/explorestudiospace.wav" - -class MoreCowbell(object): - def __init__(self, app): - self.app = app - def __call__(self, environ, start_response): - path_info = environ.get('PATH_INFO', '') - script_name = environ.get('SCRIPT_NAME', '') - for filename in ['bell-ascending.png', 'bell-descending.png']: - if path_info == '/.cowbell/'+ filename: - app = FileApp(os.path.join(os.path.dirname(__file__), filename)) - return app(environ, start_response) - type = [] - body = [] - def repl_start_response(status, headers, exc_info=None): - ct = header_value(headers, 'content-type') - if ct and ct.startswith('text/html'): - type.append(ct) - remove_header(headers, 'content-length') - start_response(status, headers, exc_info) - return body.append - return start_response(status, headers, exc_info) - app_iter = self.app(environ, repl_start_response) - if type: - # Got text/html - body.extend(app_iter) - body = ''.join(body) - body = insert_head(body, self.javascript.replace('__SCRIPT_NAME__', script_name)) - body = insert_body(body, self.resources.replace('__SCRIPT_NAME__', script_name)) - return [body] - else: - return app_iter - - javascript = '''\ - -''' - - resources = '''\ - - -''' - -def insert_head(body, text): - end_head = re.search(r'', body, re.I) - if end_head: - return body[:end_head.start()] + text + body[end_head.end():] - else: - return text + body - -def insert_body(body, text): - end_body = re.search(r'

-
-