forked from SonyMobile/aosp-digest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoutput_formatter.py
125 lines (110 loc) · 3.75 KB
/
output_formatter.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
116
117
118
119
120
121
122
123
124
125
#
# Copyright 2019 Sony Mobile Communications Inc.
# SPDX-License-Identifier: MIT
#
"""
Format cached Gerrit structure in an:
- html appropriate for email display.
- json appropriate for debug
"""
import json
class OutputFormatter:
"""
See file docstring.
"""
_CSS = """\
<style type="text/css">
{}
</style>
"""
_HEADER = """\
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{} digest</title>
"""
_BODY_START = """\
</head>
<body>
<h1>{} Gerrit digest</h1>
"""
_BODY_END = """\
</body>
</html>
"""
def __init__(self, cache, project, anchor, css, filters):
self._project = project
self._cache = cache
self._anchor = anchor
self._css = css
self._filters = filters
def _filter_cache(self):
tree = []
for (title, predicate) in self._filters:
node = []
matches = self._cache.get_by_predicate(predicate)
for project in {x["project"] for x in matches}:
node.append((project, [x for x in matches if x["project"] == project]))
tree.append((title, node))
return tree
def _format_body(self):
tree = self._filter_cache()
if not tree:
raise Exception("No content")
html = ""
for (title, node) in sorted(tree):
html += f"<h2>{str(title)}</h2>\n"
html += "<ul>\n"
if not node:
html += "<li>No changes</li>\n"
else:
for (project, changes) in sorted(node):
html += f"<li>{str(project)}\n"
html += "<ul>\n"
for change in sorted(changes, key=lambda x: x["number"]):
def _format_size(chgs):
(insertions, deletions) = chgs
if insertions > 0 and deletions > 0:
out = f"(+{insertions}, -{deletions})"
elif insertions > 0:
out = f"(+{insertions})"
elif deletions > 0:
out = f"(-{deletions})"
else:
out = ""
return out
number = str(change["number"])
size = _format_size(change["size"])
author = str(change["author"]["name"]).replace(" ", " ")
email = str(change["author"]["email"])
subject = str(change["subject"])
html += "<li>"
html += f"<a href='{self._anchor}{number}'>{number}</a>"
html += f" {subject} {size} {author} <{email}></li>\n"
html += "</ul>\n"
html += "</li>\n"
html += "</ul>\n"
return html
def format_html(self):
"""
Return a simple html for the body of report. Response from
Gerrit acquired from the cached json is munged into an html.
"""
return (
self._HEADER.format(self._project)
+ self._CSS.format(self._css)
+ self._BODY_START.format(self._project)
+ self._format_body()
+ self._BODY_END
)
def format_json(self):
"""
Return a json representation of underlying cache.
"""
tree = self._filter_cache()
if not tree:
return json.dumps(dict(), indent=4, sort_keys=True)
return json.dumps(dict(tree), indent=4, sort_keys=True)