Skip to content

Commit 7dae849

Browse files
committed
[ADD] util/report: util.add_report
Add a new function that replaces util.add_to_migration_reports. The new function can automatically parse the provided data as a list of records. It can also limit the number of displayed records to prevent the upgrade report from growing too large. The structure of the note is now defined within the function itself, standardizing its appearance.
1 parent 6fbf957 commit 7dae849

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

src/util/report.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,95 @@ def add_to_migration_reports(message, category="Other", format="text"):
126126
_logger.warning("Upgrade report is growing suspiciously long: %s characters so far.", migration_reports_length)
127127

128128

129+
def add_report(
130+
header,
131+
summary,
132+
data=None,
133+
columns=None,
134+
links=None,
135+
row_format=None,
136+
limit=100,
137+
report_format="html",
138+
):
139+
"""Append the upgrade report with a new entry.
140+
141+
The entry consists of a header (title) and a summary (body).
142+
The entry can also display a list of records previously returned by an SQL query. In such case, in addition to the output of
143+
the query passed as "data", parameters "row_format" and "columns" must also be provided.
144+
145+
146+
:param str header: Title of a report entry.
147+
:param str summary: Description of a report entry.
148+
:param List[Tuple] data: Any data in the form of a list of tuples, e.g. the output of cr.fetchall().
149+
:param Tuple[str] columns: Arbitrary names for each column in "data". All columns must be named and
150+
the order of these names must be the same as in "data".
151+
:param Dict[str, Tuple[str, str, str]] links: Optional model/record links, e.g.:
152+
{
153+
"partner_link": ("res.partner", "id", "name"),
154+
"company_link": ("res.company", "company_id", "company_name"),
155+
}
156+
:param str row_format: The way a row in a list is formatted, using named placeholders, e.g.:
157+
"Partner {partner_link} that lives in {city} works at company {company_link}."
158+
:param int limit: The number of records that are going to be displayed in the report.
159+
:param str report_format: Format of the input "summary"; must be one of {"text", "html", "md", "rst"}
160+
"""
161+
assert report_format in {"text", "html", "md", "rst"}
162+
if report_format == "md":
163+
summary = md2html(dedent(summary))
164+
elif report_format == "rst":
165+
summary = rst2html(dedent(summary))
166+
167+
if data:
168+
assert columns is not None
169+
assert row_format is not None
170+
rows = []
171+
172+
for row in data[:limit]:
173+
row_dict = dict(zip(columns, row))
174+
175+
if links:
176+
for link_name, (link_model, id_column, name_column) in links.items():
177+
row_dict[link_name] = get_anchor_link_to_record(
178+
link_model,
179+
row_dict[id_column],
180+
row_dict[name_column],
181+
)
182+
183+
row_text = row_format.format(**row_dict)
184+
rows.append("<li>{}</li>".format(row_text))
185+
186+
rows = "<ul>\n" + "\n".join(rows) + "\n</ul>"
187+
188+
total = len(data)
189+
disclaimer = "The total number of affected records is {}.".format(total)
190+
if total > limit:
191+
disclaimer += " This list is limited to {} records.".format(limit)
192+
193+
msg = """
194+
<summary>
195+
{}
196+
<details>
197+
<i>{}</i>
198+
{}
199+
</details>
200+
</summary>
201+
""".format(summary, disclaimer, rows)
202+
else:
203+
msg = """
204+
<summary>
205+
{}
206+
</summary>
207+
""".format(summary)
208+
209+
raw = False
210+
if report_format != "text":
211+
if Markup:
212+
msg = Markup(msg)
213+
else:
214+
raw = True
215+
migration_reports.setdefault(header, []).append((msg, raw))
216+
217+
129218
def announce_release_note(cr):
130219
filepath = os.path.join(os.path.dirname(__file__), "release-note.xml")
131220
with open(filepath, "rb") as fp:

0 commit comments

Comments
 (0)