Mercurial > libervia-backend
annotate sat_frontends/jp/output_template.py @ 3211:4252176ad993
plugin download: clean unfinished files and re-raise exception in case of download error
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 06 Mar 2020 18:19:03 +0100 |
parents | 559a625a236b |
children | be6d91572633 |
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 |
3136 | 5 # Copyright (C) 2009-2020 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) |