@@ -96,7 +96,12 @@ class ViewType(Enum):
9696 ViewType .fragment : 'overview.md' ,
9797 ViewType .page : 'overview.html' ,
9898}
99- REQUIRED_TEMPLATES = tuple (set (fn for view in (VIEW_DETAIL , VIEW_TABLE ) for fn in view .values ()))
99+ VIEW_SCOPE = {
100+ ViewType .markdown : 'scope.md' ,
101+ ViewType .fragment : 'scope.md' ,
102+ ViewType .page : 'overview.html' ,
103+ }
104+ REQUIRED_TEMPLATES = tuple (set (fn for view in (VIEW_DETAIL , VIEW_TABLE , VIEW_SCOPE ) for fn in view .values ()))
100105
101106
102107# do I hate these globals, but I don't see another way with these frameworks
@@ -540,14 +545,15 @@ async def get_status(
540545 return convert_result_rows_to_dict2 (rows2 , get_scopes (), include_report = True )
541546
542547
543- def render_view (view , view_type , results , base_url = '/' , title = None ):
548+ def render_view (view , view_type , base_url = '/' , title = None , ** kwargs ):
544549 media_type = {ViewType .markdown : 'text/markdown' }.get (view_type , 'text/html' )
545550 stage1 = stage2 = view [view_type ]
546551 if view_type is ViewType .page :
547552 stage1 = view [ViewType .fragment ]
553+ def scope_url (uuid ): return f"{ base_url } page/scope/{ uuid } " # noqa: E306,E704
548554 def detail_url (subject , scope ): return f"{ base_url } page/detail/{ subject } /{ scope } " # noqa: E306,E704
549555 def report_url (report ): return f"{ base_url } reports/{ report } " # noqa: E306,E704
550- fragment = templates_map [stage1 ].render (results = results , detail_url = detail_url , report_url = report_url )
556+ fragment = templates_map [stage1 ].render (detail_url = detail_url , report_url = report_url , scope_url = scope_url , ** kwargs )
551557 if view_type != ViewType .markdown and stage1 .endswith ('.md' ):
552558 fragment = markdown (fragment , extensions = ['extra' ])
553559 if stage1 != stage2 :
@@ -569,7 +575,7 @@ async def get_detail(
569575 rows2 , get_scopes (), grace_period_days = GRACE_PERIOD_DAYS ,
570576 subjects = (subject , ), scopes = (scopeuuid , ),
571577 )
572- return render_view (VIEW_DETAIL , view_type , results2 , base_url = settings .base_url , title = f'{ subject } compliance' )
578+ return render_view (VIEW_DETAIL , view_type , results = results2 , base_url = settings .base_url , title = f'{ subject } compliance' )
573579
574580
575581@app .get ("/{view_type}/detail_full/{subject}/{scopeuuid}" )
@@ -587,7 +593,7 @@ async def get_detail_full(
587593 results2 = convert_result_rows_to_dict2 (
588594 rows2 , get_scopes (), include_report = True , subjects = (subject , ), scopes = (scopeuuid , ),
589595 )
590- return render_view (VIEW_DETAIL , view_type , results2 , base_url = settings .base_url , title = f'{ subject } compliance' )
596+ return render_view (VIEW_DETAIL , view_type , results = results2 , base_url = settings .base_url , title = f'{ subject } compliance' )
591597
592598
593599@app .get ("/{view_type}/table" )
@@ -599,7 +605,7 @@ async def get_table(
599605 with conn .cursor () as cur :
600606 rows2 = db_get_relevant_results2 (cur , approved_only = True )
601607 results2 = convert_result_rows_to_dict2 (rows2 , get_scopes (), grace_period_days = GRACE_PERIOD_DAYS )
602- return render_view (VIEW_TABLE , view_type , results2 , base_url = settings .base_url , title = "SCS compliance overview" )
608+ return render_view (VIEW_TABLE , view_type , results = results2 , base_url = settings .base_url , title = "SCS compliance overview" )
603609
604610
605611@app .get ("/{view_type}/table_full" )
@@ -613,7 +619,29 @@ async def get_table_full(
613619 with conn .cursor () as cur :
614620 rows2 = db_get_relevant_results2 (cur , approved_only = False )
615621 results2 = convert_result_rows_to_dict2 (rows2 , get_scopes ())
616- return render_view (VIEW_TABLE , view_type , results2 , base_url = settings .base_url , title = "SCS compliance overview" )
622+ return render_view (VIEW_TABLE , view_type , results = results2 , base_url = settings .base_url , title = "SCS compliance overview" )
623+
624+
625+ @app .get ("/{view_type}/scope/{scopeuuid}" )
626+ async def get_scope (
627+ request : Request ,
628+ conn : Annotated [connection , Depends (get_conn )],
629+ view_type : ViewType ,
630+ scopeuuid : str ,
631+ ):
632+ spec = get_scopes ()[scopeuuid ].spec
633+ versions = spec ['versions' ]
634+ relevant = sorted ([name for name , version in versions .items () if version ['_explicit_validity' ]])
635+ modules_chart = {}
636+ for name in relevant :
637+ for include in versions [name ]['include' ]:
638+ module_id = include ['module' ]['id' ]
639+ row = modules_chart .get (module_id )
640+ if row is None :
641+ row = modules_chart [module_id ] = {'module' : include ['module' ], 'columns' : {}}
642+ row ['columns' ][name ] = include
643+ rows = sorted (list (modules_chart .values ()), key = lambda row : row ['module' ]['id' ])
644+ return render_view (VIEW_SCOPE , view_type , spec = spec , relevant = relevant , rows = rows , base_url = settings .base_url , title = spec ['name' ])
617645
618646
619647@app .get ("/pages" )
0 commit comments