Mercurial > libervia-backend
annotate sat_frontends/jp/output_template.py @ 3732:0fac164ff2d8
tools (xml_tools): fix `widget_args` modification in `_dataFormField2XMLUIData`:
in `textbox` widget, the first arg was modified with all values, lettings other ones
unchanger, resulting in invalid number of arguments. This has been fixed by replacing all
args with the new value.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 31 Jan 2022 18:35:52 +0100 |
parents | be6d91572633 |
children | 524856bd7b19 |
rev | line source |
---|---|
3137 | 1 #! /usr/bin/env python3 |
2 | |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
3 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
4 # jp: a SàT command line tool |
3479 | 5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
7 # This program is free software: you can redistribute it and/or modify |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
8 # it under the terms of the GNU Affero General Public License as published by |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
9 # the Free Software Foundation, either version 3 of the License, or |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
10 # (at your option) any later version. |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
12 # This program is distributed in the hope that it will be useful, |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
15 # GNU Affero General Public License for more details. |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
17 # You should have received a copy of the GNU Affero General Public License |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
19 """Standard outputs""" |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
20 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
21 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
22 from sat_frontends.jp.constants import Const as C |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
23 from sat.core.i18n import _ |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
24 from sat.core import log |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
25 from sat.tools.common import template |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
26 from functools import partial |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
27 import logging |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
28 import webbrowser |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
29 import tempfile |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
30 import os.path |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
31 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
32 __outputs__ = ["Template"] |
3028 | 33 TEMPLATE = "template" |
34 OPTIONS = {"template", "browser", "inline-css"} | |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
35 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
36 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
37 class Template(object): |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 """outputs data using SàT templates""" |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 def __init__(self, jp): |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
41 self.host = jp |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
42 jp.register_output(C.OUTPUT_COMPLEX, TEMPLATE, self.render) |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
43 |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
44 def _front_url_tmp_dir(self, ctx, relative_url, tmp_dir): |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
45 """Get front URL for temporary directory""" |
3028 | 46 template_data = ctx['template_data'] |
47 return "file://" + os.path.join(tmp_dir, template_data.theme, relative_url) | |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
48 |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
49 def _do_render(self, template_path, css_inline, **kwargs): |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
50 try: |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
51 return self.renderer.render(template_path, css_inline=css_inline, **kwargs) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
52 except template.TemplateNotFound: |
3028 | 53 self.host.disp(_("Can't find requested template: {template_path}") |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
54 .format(template_path=template_path), error=True) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
55 self.host.quit(C.EXIT_NOT_FOUND) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
56 |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
57 def render(self, data): |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
58 """render output data using requested template |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
59 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
60 template to render the data can be either command's TEMPLATE or |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
61 template output_option requested by user. |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
62 @param data(dict): data is a dict which map from variable name to use in template |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
63 to the variable itself. |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
64 command's template_data_mapping attribute will be used if it exists to convert |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
65 data to a dict usable by the template. |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
66 """ |
2530
0cb32e503aff
jp (output/template): fixed template output (media_dir was missing)
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
67 # media_dir is needed for the template |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
68 self.host.media_dir = self.host.bridge.getConfig("", "media_dir") |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
69 cmd = self.host.command |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
70 try: |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
71 template_path = cmd.TEMPLATE |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
72 except AttributeError: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
73 if not "template" in cmd.args.output_opts: |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
74 self.host.disp(_( |
3028 | 75 "no default template set for this command, you need to specify a " |
76 "template using --oo template=[path/to/template.html]"), | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
77 error=True, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
78 ) |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
79 self.host.quit(C.EXIT_BAD_ARG) |
2348
18d71226b3a8
jp (output/template): check if there is a template before initializing Renderer
Goffi <goffi@goffi.org>
parents:
2248
diff
changeset
|
80 |
18d71226b3a8
jp (output/template): check if there is a template before initializing Renderer
Goffi <goffi@goffi.org>
parents:
2248
diff
changeset
|
81 options = self.host.parse_output_options() |
18d71226b3a8
jp (output/template): check if there is a template before initializing Renderer
Goffi <goffi@goffi.org>
parents:
2248
diff
changeset
|
82 self.host.check_output_options(OPTIONS, options) |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
83 try: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
84 template_path = options["template"] |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
85 except KeyError: |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
86 # template is not specified, we use default one |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
87 pass |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
88 if template_path is None: |
3028 | 89 self.host.disp(_("Can't parse template, please check its syntax"), |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
90 error=True) |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
91 self.host.quit(C.EXIT_BAD_ARG) |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
92 |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
93 try: |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
94 mapping_cb = cmd.template_data_mapping |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
95 except AttributeError: |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
96 kwargs = data |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
97 else: |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
98 kwargs = mapping_cb(data) |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
99 |
3028 | 100 css_inline = "inline-css" in options |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
101 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
102 if "browser" in options: |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
103 template_name = os.path.basename(template_path) |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
104 tmp_dir = tempfile.mkdtemp() |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
105 front_url_filter = partial(self._front_url_tmp_dir, tmp_dir=tmp_dir) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
106 self.renderer = template.Renderer( |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
107 self.host, front_url_filter=front_url_filter, trusted=True) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
108 rendered = self._do_render(template_path, css_inline=css_inline, **kwargs) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
109 self.host.disp(_( |
3028 | 110 "Browser opening requested.\n" |
111 "Temporary files are put in the following directory, you'll have to " | |
112 "delete it yourself once finished viewing: {}").format(tmp_dir)) | |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
113 tmp_file = os.path.join(tmp_dir, template_name) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
114 with open(tmp_file, "w") as f: |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
115 f.write(rendered.encode("utf-8")) |
2169
f472179305a1
tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents:
2163
diff
changeset
|
116 theme, theme_root_path = self.renderer.getThemeAndRoot(template_path) |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
117 if theme is None: |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
118 # we have an absolute path |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
119 webbrowser |
2169
f472179305a1
tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents:
2163
diff
changeset
|
120 static_dir = os.path.join(theme_root_path, C.TEMPLATE_STATIC_DIR) |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
121 if os.path.exists(static_dir): |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
122 # we have to copy static files in a subdirectory, to avoid file download |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
123 # to be blocked by same origin policy |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
124 import shutil |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
125 shutil.copytree( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
126 static_dir, os.path.join(tmp_dir, theme, C.TEMPLATE_STATIC_DIR) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
127 ) |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
128 webbrowser.open(tmp_file) |
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
129 else: |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
130 # FIXME: Q&D way to disable template logging |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
131 # logs are overcomplicated, and need to be reworked |
3028 | 132 template_logger = log.getLogger("sat.tools.common.template") |
2671
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
133 template_logger.log = lambda *args: None |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
134 |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
135 logging.disable(logging.WARNING) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
136 self.renderer = template.Renderer(self.host, trusted=True) |
0fa217fafabf
tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
137 rendered = self._do_render(template_path, css_inline=css_inline, **kwargs) |
2163
75667727c500
jp (output): template output first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
138 self.host.disp(rendered) |