diff --git a/uber/decorators.py b/uber/decorators.py index 039abd5c7..e3912e8d7 100644 --- a/uber/decorators.py +++ b/uber/decorators.py @@ -574,7 +574,8 @@ def renderable_data(data=None): # render using the first template that actually exists in template_name_list -def render(template_name_list, data=None, encoding='utf-8'): +# Returns a generator that streams the template result to the client +def render_stream(template_name_list, data=None, encoding='utf-8'): data = renderable_data(data) env = JinjaEnv.env() template = env.get_or_select_template(template_name_list) @@ -585,6 +586,17 @@ def render(template_name_list, data=None, encoding='utf-8'): return rendered +# render using the first template that actually exists in template_name_list +def render(template_name_list, data=None, encoding='utf-8'): + data = renderable_data(data) + env = JinjaEnv.env() + template = env.get_or_select_template(template_name_list) + rendered = template.render(data) + if encoding: + return rendered.encode(encoding) + return rendered + + def render_empty(template_name_list): env = JinjaEnv.env() template = env.get_or_select_template(template_name_list) @@ -653,12 +665,19 @@ def with_rendering(*args, **kwargs): if c.UBER_SHUT_DOWN and not cherrypy.request.path_info.startswith('/schedule'): return render('closed.html') elif isinstance(result, dict): + cp_config = getattr(func, "_cp_config", {}) + if cp_config.get("response.stream", False): + return render_stream(_get_template_filename(func), result) return render(_get_template_filename(func), result) else: return result return with_rendering +def streamable(func): + func._cp_config = getattr(func, "_cp_config", {}) + func._cp_config['response.stream'] = True + return func def public(func): func.public = True diff --git a/uber/site_sections/reg_reports.py b/uber/site_sections/reg_reports.py index a5cbd5a5e..54e824fc4 100644 --- a/uber/site_sections/reg_reports.py +++ b/uber/site_sections/reg_reports.py @@ -3,7 +3,7 @@ from sqlalchemy.orm import subqueryload from uber.config import c -from uber.decorators import all_renderable, log_pageview +from uber.decorators import all_renderable, log_pageview, streamable from uber.models import Attendee, Group, PromoCode, ReceiptTransaction, ModelReceipt @@ -38,6 +38,7 @@ def found_how(self, session): key=lambda s: s.lower())} @log_pageview + @streamable def attendee_receipt_discrepancies(self, session, include_pending=False, page=1): filters = [Attendee.default_cost_cents != ModelReceipt.item_total] if include_pending: @@ -60,7 +61,6 @@ def attendee_receipt_discrepancies(self, session, include_pending=False, page=1) 'attendees': receipt_query.limit(50).offset(offset), 'include_pending': include_pending, } - attendee_receipt_discrepancies._cp_config = {'response.stream': True} @log_pageview def attendees_nonzero_balance(self, session, include_no_receipts=False):