3939import copy
4040import operator
4141
42+ from collections import defaultdict
4243from functools import reduce
44+
4345from django import forms
4446from django .conf import settings
4547from django .core .cache import cache , caches
@@ -360,32 +362,52 @@ def cached_redirect(cache_key, url):
360362 return cached_redirect (cache_key , urlreverse ('ietf.doc.views_search.search' ) + search_args )
361363
362364
363- def state_name (doc_type , state , shorten = True ):
364- name = ""
365- # Note doc_type rfc here is _not_ necessarily Document.type - for some callers
366- # it is a type derived from draft... The ad_workload view needs more rework so that
367- # the code isn't having to shadow-box so much.
368- if doc_type == "rfc" :
369- if state == "rfc" :
370- name = "RFC"
371- if name == "" :
372- s = State .objects .filter (type = "rfc" ,slug = state ).first ()
373- if s :
374- name = s .name
375- if name == "" :
376- name = State .objects .get (type__in = ["draft" , "draft-iesg" ], slug = state ).name
377- elif doc_type == "draft" and state not in ["rfc" , "expired" ]:
378- name = State .objects .get (type__in = ["draft" , "draft-iesg" ], slug = state ).name
379- elif doc_type == "draft" and state == "rfc" :
380- name = "RFC"
381- elif doc_type == "conflrev" and state .startswith ("appr" ):
382- name = "Approved"
383- else :
384- name = State .objects .get (type = doc_type , slug = state ).name
365+ def get_state_name_calculator ():
366+ """Get a function to calculate state names
367+
368+ Queries the database once when called, then uses cached look-up table for name calculations.
369+ """
370+ # state_lut always has at least rfc, draft, and draft-iesg keys
371+ state_lut = defaultdict (dict , ** {"rfc" : {}, "draft" :{}, "draft-iesg" : {}})
372+ for state in State .objects .filter (used = True ):
373+ state_lut [state .type_id ][state .slug ] = state .name
374+ state_lut = dict (state_lut ) # convert to dict to freeze key changes
375+
376+ def _get_state_name (doc_type , state_slug ):
377+ """Get display name for a doc type / state slug
378+
379+ Note doc_type rfc here is _not_ necessarily Document.type - for some callers
380+ it is a type derived from draft... The ad_workload view needs more rework so that
381+ the code isn't having to shadow-box so much.
382+ """
383+ if doc_type == "rfc" :
384+ if state_slug == "rfc" :
385+ return "RFC"
386+ elif state_slug in state_lut ["rfc" ]:
387+ return state_lut ["rfc" ][state_slug ]
388+ else :
389+ return state_lut ["draft" ].get (
390+ state_slug ,
391+ state_lut ["draft-iesg" ][state_slug ],
392+ )
393+ elif doc_type == "draft" and state_slug not in ["rfc" , "expired" ]:
394+ return state_lut ["draft" ].get (
395+ state_slug ,
396+ state_lut ["draft-iesg" ][state_slug ],
397+ )
398+ elif doc_type == "draft" and state_slug == "rfc" :
399+ return "RFC"
400+ elif doc_type == "conflrev" and state_slug .startswith ("appr" ):
401+ return "Approved"
402+ else :
403+ return state_lut [doc_type ][state_slug ]
404+
405+ # return the function as a closure
406+ return _get_state_name
385407
386- if not shorten :
387- return name
388408
409+ def shorten_state_name (name ):
410+ """Get abbreviated display name for a state"""
389411 for pat , sub in [
390412 (r" \(Internal Steering Group/IAB Review\)" , "" ),
391413 ("Writeup" , "Write-up" ),
@@ -412,31 +434,27 @@ def state_name(doc_type, state, shorten=True):
412434 (r"\(Message to Community, Selected by Secretariat\)" , "" ),
413435 ]:
414436 name = re .sub (pat , sub , name )
415-
416437 return name .strip ()
417438
418439
419- STATE_SLUGS = {
420- dt : {state_name (dt , ds , shorten = False ): ds for ds in AD_WORKLOAD [dt ]} # type: ignore
421- for dt in AD_WORKLOAD
422- }
423-
424-
425- def state_to_doc_type (state ):
426- for dt in STATE_SLUGS :
427- if state in STATE_SLUGS [dt ]:
428- return dt
429- return None
430-
431-
432- IESG_STATES = State .objects .filter (type = "draft-iesg" ).values_list ("name" , flat = True )
433-
434-
435440def date_to_bucket (date , now , num_buckets ):
436441 return num_buckets - int ((now .date () - date .date ()).total_seconds () / 60 / 60 / 24 )
437442
438443
439444def ad_workload (request ):
445+ _calculate_state_name = get_state_name_calculator ()
446+ IESG_STATES = State .objects .filter (type = "draft-iesg" ).values_list ("name" , flat = True )
447+ STATE_SLUGS = {
448+ dt : {_calculate_state_name (dt , ds ): ds for ds in AD_WORKLOAD [dt ]} # type: ignore
449+ for dt in AD_WORKLOAD .keys ()
450+ }
451+
452+ def _state_to_doc_type (state ):
453+ for dt in STATE_SLUGS :
454+ if state in STATE_SLUGS [dt ]:
455+ return dt
456+ return None
457+
440458 # number of days (= buckets) to show in the graphs
441459 days = 120 if has_role (request .user , ["Area Director" , "Secretariat" ]) else 1
442460 now = timezone .now ()
@@ -483,7 +501,7 @@ def ad_workload(request):
483501 to_state = None
484502 if dt == "charter" :
485503 if e .type == "closed_ballot" :
486- to_state = state_name (dt , state , shorten = False )
504+ to_state = _calculate_state_name (dt , state )
487505 elif e .desc .endswith ("has been replaced" ):
488506 # stop tracking
489507 last = e .time
@@ -512,7 +530,7 @@ def ad_workload(request):
512530 to_state = "RFC"
513531
514532 if dt == "rfc" :
515- new_dt = state_to_doc_type (to_state )
533+ new_dt = _state_to_doc_type (to_state )
516534 if new_dt is not None and new_dt != dt :
517535 dt = new_dt
518536
@@ -549,7 +567,9 @@ def ad_workload(request):
549567 metadata = [
550568 {
551569 "type" : (dt , doc_type_name (dt )),
552- "states" : [(state , state_name (dt , state )) for state in ad .buckets [dt ]],
570+ "states" : [
571+ (state , shorten_state_name (_calculate_state_name (dt , state ))) for state in ad .buckets [dt ]
572+ ],
553573 "ads" : ads ,
554574 }
555575 for dt in AD_WORKLOAD
@@ -617,9 +637,10 @@ def sort_key(doc):
617637 )
618638 ]
619639
640+ _calculate_state_name = get_state_name_calculator ()
620641 for d in results :
621642 dt = d .type .slug
622- d .search_heading = state_name (dt , doc_state (d ), shorten = False )
643+ d .search_heading = _calculate_state_name (dt , doc_state (d ))
623644 if d .search_heading != "RFC" :
624645 d .search_heading += f" { doc_type_name (dt )} "
625646
0 commit comments