Additional changes to speed up the IESG agenda docs page: Changed telechat_page_count() to accept a list of documents if that's already been generated, to avoid double work. Changed the reviewed_by_teams list to provide acronyms directly, to avoid group lookups during template rendering. Provided page counts directly to the template instead of repeated (costly) filtering through telechat_page_count, with new document lookups. Removed the telechat_page_count template filter, due to its cost. Tweaked some lookups in fill_in_document_table_attributes() . Added to the select_related() list for documents in IESG agenda_documents().
- Legacy-Id: 14988
This commit is contained in:
parent
60a60de94b
commit
675c652052
|
@ -26,7 +26,7 @@ class TelechatForm(forms.Form):
|
|||
self.page_count = {}
|
||||
choice_display = {}
|
||||
for d in dates:
|
||||
self.page_count[d] = telechat_page_count(d).for_approval
|
||||
self.page_count[d] = telechat_page_count(date=d).for_approval
|
||||
choice_display[d] = '%s (%s pages)' % (d.strftime("%Y-%m-%d"),self.page_count[d])
|
||||
if d-datetime.date.today() < datetime.timedelta(days=13):
|
||||
choice_display[d] += ' : WARNING - this may not leave enough time for directorate reviews!'
|
||||
|
|
|
@ -43,7 +43,7 @@ def fill_in_document_table_attributes(docs):
|
|||
seen.add(e.doc_id)
|
||||
|
||||
# on agenda in upcoming meetings
|
||||
presentations = SessionPresentation.objects.filter(session__timeslotassignments__timeslot__time__gte=datetime.datetime.today()).distinct().select_related('session', 'document')
|
||||
presentations = SessionPresentation.objects.filter(session__meeting__date__gte=datetime.date.today()-datetime.timedelta(days=7)).select_related('session', 'document')
|
||||
session_list = [ (p.document, p.session) for p in presentations ]
|
||||
sessions = dict( (d, []) for (d, s) in session_list )
|
||||
for (d, s) in session_list:
|
||||
|
@ -74,9 +74,8 @@ def fill_in_document_table_attributes(docs):
|
|||
d.expirable = expirable_draft(d)
|
||||
|
||||
if d.get_state_slug() != "rfc":
|
||||
d.milestones = sorted((m for m in d.groupmilestone_set.all() if m.state_id == "active"), key=lambda m: m.time)
|
||||
|
||||
d.reviewed_by_teams = sorted(set(r.team for r in d.reviewrequest_set.filter(state__in=["requested","accepted","part-completed","completed"])), key=lambda g: g.acronym)
|
||||
d.milestones = [ m for (t, m) in sorted(((m.time, m) for m in d.groupmilestone_set.all() if m.state_id == "active")) ]
|
||||
d.reviewed_by_teams = sorted(set(r.team.acronym for r in d.reviewrequest_set.filter(state__in=["requested","accepted","part-completed","completed"]).distinct().select_related('team')))
|
||||
|
||||
d.sessions = sessions[d] if d in sessions else []
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
from django import template
|
||||
|
||||
from ietf.iesg.utils import telechat_page_count as page_counter
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter
|
||||
def telechat_page_count(telechat):
|
||||
return page_counter(telechat['date']).for_approval
|
|
@ -1,15 +1,19 @@
|
|||
from collections import namedtuple
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.models import Document, TelechatDocEvent, STATUSCHANGE_RELATIONS
|
||||
from ietf.iesg.agenda import get_doc_section
|
||||
|
||||
TelechatPageCount = namedtuple('TelechatPageCount',['for_approval','for_action','related'])
|
||||
|
||||
def telechat_page_count(date):
|
||||
def telechat_page_count(date=None, docs=None):
|
||||
if not date and not docs:
|
||||
return TelechatPageCount(0, 0, 0)
|
||||
|
||||
candidates = Document.objects.filter(docevent__telechatdocevent__telechat_date=date).distinct()
|
||||
|
||||
docs = [ doc for doc in candidates if doc.latest_event(TelechatDocEvent,type='scheduled_for_telechat').telechat_date==date ]
|
||||
if not docs:
|
||||
candidates = Document.objects.filter(docevent__telechatdocevent__telechat_date=date).distinct()
|
||||
docs = [ doc for doc in candidates if doc.latest_event(TelechatDocEvent,type='scheduled_for_telechat').telechat_date==date ]
|
||||
|
||||
for_action =[d for d in docs if get_doc_section(d).endswith('.3')]
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ def agenda_json(request, date=None):
|
|||
res = {
|
||||
"telechat-date": str(data["date"]),
|
||||
"as-of": str(datetime.datetime.utcnow()),
|
||||
"page-counts": telechat_page_count(get_agenda_date(date))._asdict(),
|
||||
"page-counts": telechat_page_count(date=get_agenda_date(date))._asdict(),
|
||||
"sections": {},
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,10 @@ def agenda_documents(request):
|
|||
dates = list(TelechatDate.objects.active().order_by('date').values_list("date", flat=True)[:4])
|
||||
|
||||
docs_by_date = dict((d, []) for d in dates)
|
||||
for doc in Document.objects.filter(docevent__telechatdocevent__telechat_date__in=dates).select_related("stream", "group").distinct():
|
||||
for doc in (Document.objects
|
||||
.filter(docevent__telechatdocevent__telechat_date__in=dates)
|
||||
.select_related('stream', 'group', 'intended_std_level')
|
||||
.distinct()):
|
||||
d = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date
|
||||
if d in docs_by_date:
|
||||
docs_by_date[d].append(doc)
|
||||
|
@ -379,9 +382,11 @@ def agenda_documents(request):
|
|||
# the search_result_row view to display them (which expects them)
|
||||
fill_in_document_table_attributes(docs_by_date[date])
|
||||
fill_in_agenda_docs(date, sections, docs_by_date[date])
|
||||
pages = telechat_page_count(docs=docs_by_date[date]).for_approval
|
||||
|
||||
telechats.append({
|
||||
"date":date,
|
||||
"pages":pages,
|
||||
"sections": sorted((num, section) for num, section in sections.iteritems()
|
||||
if "2" <= num < "5")
|
||||
})
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
{% if doc.reviewed_by_teams %}
|
||||
<br>Reviews:
|
||||
{% for g in doc.reviewed_by_teams %}
|
||||
{{ g.acronym }}{% if not forloop.last %}, {% endif %}
|
||||
{% for acronym in doc.reviewed_by_teams %}
|
||||
{{ acronym }}{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
{% load ballot_icon %}
|
||||
{% load ietf_filters %}
|
||||
{% load iesg_filters %}
|
||||
|
||||
{% block pagehead %}
|
||||
<link rel="alternate" type="application/atom+xml" href="/feed/iesg-agenda/">
|
||||
|
@ -39,10 +38,8 @@
|
|||
|
||||
{% for t in telechats %}
|
||||
<h2>IESG telechat {{t.date}}
|
||||
{% with t|telechat_page_count as pages %}
|
||||
<small class="text-muted">{{pages}} page{{pages|pluralize}}</small>
|
||||
{% endwith %}
|
||||
</h2>
|
||||
<small class="text-muted">{{t.pages}} page{{t.pages|pluralize}}</small>
|
||||
</h2>
|
||||
<p>
|
||||
<a class="btn btn-default" role="button" href="/iesg/agenda/">
|
||||
<span class="fa fa-list"></span>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import datetime
|
||||
|
||||
from decorator import decorator
|
||||
from decorator import decorator, decorate
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import login
|
||||
|
@ -74,3 +74,29 @@ def require_api_key(f, request, *args, **kwargs):
|
|||
PersonApiKeyEvent.objects.create(person=person, type='apikey_login', key=key, desc="Logged in with key ID %s, endpoint %s" % (key.id, key.endpoint))
|
||||
# Execute decorated function
|
||||
return f(request, *args, **kwargs)
|
||||
|
||||
|
||||
def _memoize(func, self, *args, **kwargs):
|
||||
''''Memoize wrapper for instance methouds. Use @lru_cache for functions.'''
|
||||
if kwargs: # frozenset is used to ensure hashability
|
||||
key = args, frozenset(kwargs.items())
|
||||
else:
|
||||
key = args
|
||||
# instance method, set up cache if needed
|
||||
if not hasattr(self, '_cache'):
|
||||
self._cache = {}
|
||||
if not func in self._cache:
|
||||
self._cache[func] = {}
|
||||
#
|
||||
cache = self._cache[func]
|
||||
if key not in cache:
|
||||
cache[key] = func(self, *args, **kwargs)
|
||||
return cache[key]
|
||||
def memoize(func):
|
||||
if not hasattr(func, '__class__'):
|
||||
raise NotImplementedError("Use @lru_cache instead of memoize() for funcitons.")
|
||||
# For methods, we want the cache on the object, not on the class, in order
|
||||
# to not having to think about cache bloat and content becoming stale, so
|
||||
# we cannot set up the cache here.
|
||||
return decorate(func, _memoize)
|
||||
|
||||
|
|
Loading…
Reference in a new issue