1
1
import textwrap
2
- from collections import defaultdict
3
2
4
3
import structlog
5
- from django .utils . html import escape
4
+ from django .template import Context , Template
6
5
from django .utils .translation import gettext_noop as _
7
6
8
7
from readthedocs .doc_builder .exceptions import (
@@ -34,26 +33,8 @@ def __repr__(self):
34
33
def __str__ (self ):
35
34
return f"Message: { self .id } | { self .header } "
36
35
37
- def _escape_format_values (self , format_values ):
38
- """
39
- Escape all potential HTML tags included in format values.
40
-
41
- This is a protection against rendering potential values defined by the user.
42
- It uses the Django's util function ``escape`` (similar to ``|escape`` template tag filter)
43
- to convert HTML characters into regular characters.
44
-
45
- NOTE: currently, we don't support values that are not ``str`` or ``int``.
46
- If we want to support other types or nested dictionaries,
47
- we will need to iterate recursively to apply the ``escape`` function.
48
- """
49
- return {
50
- key : escape (value )
51
- for key , value in format_values .items ()
52
- if isinstance (value , (str , int ))
53
- }
54
-
55
36
def set_format_values (self , format_values ):
56
- self .format_values = self . _escape_format_values ( format_values )
37
+ self .format_values = format_values
57
38
58
39
def get_display_icon_classes (self ):
59
40
if self .icon_classes :
@@ -78,20 +59,12 @@ def get_display_icon_classes(self):
78
59
return " " .join (classes )
79
60
80
61
def get_rendered_header (self ):
81
- try :
82
- return self .header .format (** self .format_values )
83
- except KeyError :
84
- # There was a key missing
85
- log .exception ("There was a missing key when formating a header's Message." )
86
- return self .header .format_map (defaultdict (str , ** self .format_values ))
62
+ template = Template (self .header )
63
+ return template .render (context = Context (self .format_values ))
87
64
88
65
def get_rendered_body (self ):
89
- try :
90
- return self .body .format (** self .format_values )
91
- except KeyError :
92
- # There was a key missing
93
- log .exception ("There was a missing key when formating a body's Message." )
94
- return self .body .format_map (defaultdict (str , ** self .format_values ))
66
+ template = Template (self .body )
67
+ return template .render (context = Context (self .format_values ))
95
68
96
69
97
70
# TODO: review the copy of these notifications/messages on PR review and adapt them.
@@ -109,7 +82,7 @@ def get_rendered_body(self):
109
82
There was a problem with Read the Docs while building your documentation.
110
83
Please try again later.
111
84
If this problem persists,
112
- report this error to us with your build id ({instance.pk}).
85
+ report this error to us with your build id ({{ instance.pk} }).
113
86
"""
114
87
).strip (),
115
88
),
@@ -123,7 +96,7 @@ def get_rendered_body(self):
123
96
"""
124
97
This build was terminated due to inactivity.
125
98
If you continue to encounter this error,
126
- file a support request and reference this build id ({instance.pk}).
99
+ file a support request and reference this build id ({{ instance.pk} }).
127
100
"""
128
101
).strip (),
129
102
),
@@ -149,7 +122,7 @@ def get_rendered_body(self):
149
122
body = _ (
150
123
textwrap .dedent (
151
124
"""
152
- Concurrency limit reached ({limit}), retrying in 5 minutes.
125
+ Concurrency limit reached ({{ limit} }), retrying in 5 minutes.
153
126
"""
154
127
).strip (),
155
128
),
@@ -210,7 +183,7 @@ def get_rendered_body(self):
210
183
body = _ (
211
184
textwrap .dedent (
212
185
"""
213
- Build exited due to unknown error: {message}
186
+ Build exited due to unknown error: {{ message} }
214
187
"""
215
188
).strip (),
216
189
),
@@ -236,7 +209,7 @@ def get_rendered_body(self):
236
209
body = _ (
237
210
textwrap .dedent (
238
211
"""
239
- Your project, organization, or user is currently building the maximum concurrency builds allowed ({limit}).
212
+ Your project, organization, or user is currently building the maximum concurrency builds allowed ({{ limit} }).
240
213
It will automatically retry in 5 minutes.
241
214
"""
242
215
).strip (),
@@ -261,7 +234,7 @@ def get_rendered_body(self):
261
234
body = _ (
262
235
textwrap .dedent (
263
236
"""
264
- Build output directory for format "{artifact_type}" is not a directory.
237
+ Build output directory for format "{{ artifact_type} }" is not a directory.
265
238
"""
266
239
).strip (),
267
240
),
@@ -273,7 +246,7 @@ def get_rendered_body(self):
273
246
body = _ (
274
247
textwrap .dedent (
275
248
"""
276
- Build output directory for format "{artifact_type}" does not contain any files.
249
+ Build output directory for format "{{ artifact_type} }" does not contain any files.
277
250
It seems the build process created the directory but did not save any file to it.
278
251
"""
279
252
).strip (),
@@ -286,9 +259,9 @@ def get_rendered_body(self):
286
259
body = _ (
287
260
textwrap .dedent (
288
261
"""
289
- Build output directory for format "{artifact_type}" contains multiple files
262
+ Build output directory for format "{{ artifact_type} }" contains multiple files
290
263
and it is not currently supported.
291
- Please, remove all the files but the "{artifact_type}" you want to upload.
264
+ Please, remove all the files but the "{{ artifact_type} }" you want to upload.
292
265
"""
293
266
).strip (),
294
267
),
@@ -421,7 +394,7 @@ def get_rendered_body(self):
421
394
body = _ (
422
395
textwrap .dedent (
423
396
"""
424
- Problem parsing MkDocs YAML configuration. {exception}
397
+ Problem parsing MkDocs YAML configuration. {{ exception} }
425
398
"""
426
399
).strip (),
427
400
),
@@ -457,7 +430,7 @@ def get_rendered_body(self):
457
430
body = _ (
458
431
textwrap .dedent (
459
432
"""
460
- The "{config}" config from your MkDocs YAML config file has to be a
433
+ The "{{ config} }" config from your MkDocs YAML config file has to be a
461
434
list of relative paths.
462
435
"""
463
436
).strip (),
0 commit comments