[debug_toolbar] add a uicfg declarations panel

authorLaurent Peuch <cortex@worlddomination.be>
changesetd9292ce0698f
branchdefault
phasedraft
hiddenno
parent revision#25b42cbd8c13 [debug/DBG_UICFG] add syntaxe highlight
child revision#25611c5925a9 [debug_toolbar] add a uicfg content panel
files modified by this revision
cubicweb/pyramid/debug_toolbar_templates/uicfg_declarations.dbtmako
cubicweb/pyramid/debugtoolbar_panels.py
cubicweb/rtags.py
# HG changeset patch
# User Laurent Peuch <cortex@worlddomination.be>
# Date 1611742836 -3600
# Wed Jan 27 11:20:36 2021 +0100
# Node ID d9292ce0698ff4124389cb4edc9e273d632aa3fc
# Parent 25b42cbd8c13f2bb8310c1ae8b8baa0707b0e28c
[debug_toolbar] add a uicfg declarations panel

diff --git a/cubicweb/pyramid/debug_toolbar_templates/uicfg_declarations.dbtmako b/cubicweb/pyramid/debug_toolbar_templates/uicfg_declarations.dbtmako
@@ -0,0 +1,35 @@
1 +## reversed to show user cubes first
2 +% for package, sections in reversed(declarations_by_packages.items()):
3 +
4 +<h3>${package}</h3>
5 +
6 +% for section, entities in sections.items():
7 +
8 +<h4>${section}</h4>
9 +
10 +% for entity, declarations in entities.items():
11 +
12 +
13 +<table class="table table-bordered table-striped declaration-table">
14 +<tr>
15 +    <th colspan=2>${entity} ${source_code_url(entity) | n}</th>
16 +</tr>
17 +% for declaration in declarations:
18 +<tr>
19 +    <td>${highlight("\n".join(declaration["inspect_frame"].code_context).strip(), "python") | n} ${source_code_url_simple(declaration["inspect_frame"].filename, declaration["inspect_frame"].lineno) | n}</td>
20 +    <td>${highlight(repr(declaration["key"]), "python") | n} = ${highlight(repr(declaration["value"]), "python") | n}</td>
21 +</tr>
22 +% endfor
23 +</table>
24 +
25 +% endfor
26 +% endfor
27 +% endfor
28 +
29 +<style>
30 +.declaration-table .highlight {
31 +    display: inline-flex;
32 +}
33 +
34 +${generate_css() | n}
35 +</style>
diff --git a/cubicweb/pyramid/debugtoolbar_panels.py b/cubicweb/pyramid/debugtoolbar_panels.py
@@ -14,15 +14,17 @@
36  # details.
37  #
38  # You should have received a copy of the GNU Lesser General Public License along
39  # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
40 
41 +from collections import defaultdict, OrderedDict
42 +
43  from pyramid_debugtoolbar.panels import DebugPanel
44 
45  from cubicweb.debug import subscribe_to_debug_channel, unsubscribe_to_debug_channel
46  from cubicweb.misc.source_highlight import highlight_html, generate_css, has_pygments
47 -from cubicweb.pyramid.debug_source_code import source_code_url, source_code_url_in_stack
48 +from cubicweb.pyramid.debug_source_code import source_code_url, source_code_url_simple, source_code_url_in_stack
49 
50 
51  class CubicWebDebugPanel(DebugPanel):
52      """
53      CubicWeb general debug panel
@@ -286,10 +288,79 @@
54              'generate_css': generate_css,
55          }
56          self.rendering_classes = []
57 
58 
59 +class UicfgDeclarationsDebugPanel(DebugPanel):
60 +    """
61 +    CubicWeb uicfg rules declarations
62 +    """
63 +
64 +    name = 'uicfg_declarations'
65 +    has_content = True
66 +    template = 'cubicweb.pyramid:debug_toolbar_templates/uicfg_declarations.dbtmako'
67 +
68 +    def __init__(self, request):
69 +        self.data = {'vreg': []}
70 +        self.vreg = []  # we use a list in case of but that should only be one item
71 +        subscribe_to_debug_channel("vreg", self.collect_vreg)
72 +
73 +    def collect_vreg(self, vreg):
74 +        self.vreg.append(vreg)
75 +
76 +    @property
77 +    def title(self):
78 +        return 'uicfg declarations'
79 +
80 +    @property
81 +    def nav_title(self):
82 +        return 'uicfg declarations'
83 +
84 +    def organize_declarations(self, vreg):
85 +        """
86 +        Organize declarations by modules then by reg
87 +        """
88 +
89 +        declarations_by_packages = OrderedDict()
90 +
91 +        for section, entities in vreg["uicfg"].items():
92 +            for entity in entities:
93 +                for declaration in entity._tagdefs.declarations:
94 +                    module = declaration["inspect_frame"].frame.f_locals["__name__"]
95 +                    package = module.split(".")[0]
96 +
97 +                    if package not in declarations_by_packages:
98 +                        declarations_by_packages[package] = OrderedDict()
99 +
100 +                    if section not in declarations_by_packages[package]:
101 +                        declarations_by_packages[package][section] = OrderedDict()
102 +
103 +                    if entity not in declarations_by_packages[package][section]:
104 +                        declarations_by_packages[package][section][entity] = [declaration]
105 +                    else:
106 +                        declarations_by_packages[package][section][entity].append(declaration)
107 +
108 +        return declarations_by_packages
109 +
110 +    def process_response(self, response):
111 +        unsubscribe_to_debug_channel("vreg", self.collect_vreg)
112 +
113 +        if self.vreg:
114 +            declarations_by_packages = self.organize_declarations(self.vreg[0]["vreg"])
115 +        else:
116 +            declarations_by_packages = []
117 +
118 +        # clear on every new response
119 +        self.data = {
120 +            'declarations_by_packages': declarations_by_packages,
121 +            'highlight': highlight_html,
122 +            'generate_css': generate_css,
123 +            'source_code_url': source_code_url,
124 +            'source_code_url_simple': source_code_url_simple,
125 +        }
126 +
127 +
128  class RQLDebugPanel(DebugPanel):
129      """
130      CubicWeb RQL debug panel
131      """
132 
@@ -406,7 +477,9 @@
133  def includeme(config):
134      config.add_debugtoolbar_panel(CubicWebDebugPanel)
135      config.add_debugtoolbar_panel(RegistryDecisionsDebugPanel)
136      config.add_debugtoolbar_panel(RegistryDebugPanel)
137      config.add_debugtoolbar_panel(RenderingDebugPanel)
138 +    config.add_debugtoolbar_panel(UicfgDeclarationsDebugPanel)
139      config.add_debugtoolbar_panel(RQLDebugPanel)
140      config.add_debugtoolbar_panel(SQLDebugPanel)
141 +    config.add_debugtoolbar_panel(HooksDebugPanel)
diff --git a/cubicweb/rtags.py b/cubicweb/rtags.py
@@ -136,10 +136,13 @@
142                  highlight("\n".join(declaration["inspect_frame"].code_context), "python").strip(),
143                  declaration["inspect_frame"].filename,
144                  declaration["inspect_frame"].lineno,
145              ))
146 
147 +        if declaration:
148 +            self.declarations.append(declaration)
149 +
150          return super(DebugDict, self).__setitem__(key, value)
151 
152 
153  class RegistrableRtags(RegistrableInstance):
154      __registry__ = 'uicfg'