-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathreport.py
115 lines (93 loc) · 3.3 KB
/
report.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
__all__ = [
'JinjaTranslator',
'Jinja2Report',
'SetTranslationJinja2',
]
from base64 import b64encode
import jinja2
from trytond.pool import Pool, PoolMeta
from trytond.report.report import TranslateFactory
class JinjaExtensionsMixin():
JINJA_EXTENSIONS = [
'jinja2.ext.i18n',
'jinja2.ext.do',
'jinja2.ext.loopcontrols',
]
@classmethod
def get_extensions(cls):
return cls.JINJA_EXTENSIONS
class JinjaTranslator(object):
def __init__(self, method):
self.gettext = method
self.ngettext = method
self.ugettext = method
self.ungettext = method
class Jinja2Report(JinjaExtensionsMixin, metaclass=PoolMeta):
@classmethod
def render(cls, action, context):
env = cls.get_environ()
template = env.from_string(action.report_content.decode())
return template.render(**context)
@classmethod
def get_environ(cls):
env = jinja2.Environment(extensions=cls.get_extensions())
translations = cls.get_translations()
env.install_gettext_translations(translations)
env.filters['b64encode'] = b64encode
env.filters['decode'] = bytes.decode
return env
@classmethod
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
report_context['attachment'] = cls.get_attachment
report_context['attachments'] = cls.get_attachments
return report_context
@classmethod
def get_translations(cls):
translate = TranslateFactory(
cls.__name__,
Pool().get('ir.translation'),
)
return JinjaTranslator(lambda text: translate(text))
@classmethod
def get_attachment(cls, record, name):
Attachment = Pool().get('ir.attachment')
try:
attachment, = Attachment.search([
('resource', '=', record),
('name', '=', name),
])
data = attachment.data
except ValueError:
data = None
finally:
return data
@classmethod
def get_attachments(cls, record, name):
Attachment = Pool().get('ir.attachment')
try:
attachments = Attachment.search([
('resource', '=', record),
('name', 'ilike', f"{name}%"),
])
data = [attachment.data for attachment in attachments]
except ValueError:
data = []
finally:
return data
class SetTranslationJinja2(JinjaExtensionsMixin, metaclass=PoolMeta):
__name__ = 'ir.translation.set'
def extract_report_html(self, content):
try:
yield from super().extract_report_html(content)
except Exception:
# Because trytond tries to manage any (x|ht)ml report
# content with the picky genshi translation extractor,
# the set-translations process will fail in presence of
# reports tailored for other template languages like jinja2.
env = jinja2.Environment(extensions=self.get_extensions())
for _, _, str_ in env.extract_translations(content.decode()):
if str_:
yield str_
def register():
Pool.register(SetTranslationJinja2, module='jinja_report', type_='wizard')