Skip to content

Commit 4a36c58

Browse files
authored
Merge pull request #500 from benjaminysmith/main
Aggregate SirCAL messages by source and error
2 parents 1328595 + 2e6567b commit 4a36c58

File tree

1 file changed

+75
-23
lines changed
  • sir_complainsalot/delphi_sir_complainsalot

1 file changed

+75
-23
lines changed

sir_complainsalot/delphi_sir_complainsalot/run.py

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import sys
99

10+
from itertools import groupby
11+
1012
from slack import WebClient
1113
from slack.errors import SlackApiError
1214

@@ -15,14 +17,16 @@
1517

1618
from .check_source import check_source
1719

20+
1821
def run_module():
1922

2023
params = read_params()
2124
meta = covidcast.metadata()
2225

2326
complaints = []
2427
for data_source in params["sources"].keys():
25-
complaints.extend(check_source(data_source, meta, params["sources"], params.get("grace", 0)))
28+
complaints.extend(check_source(data_source, meta,
29+
params["sources"], params.get("grace", 0)))
2630

2731
if len(complaints) > 0:
2832
for complaint in complaints:
@@ -32,11 +36,13 @@ def run_module():
3236

3337
sys.exit(1)
3438

39+
3540
def split_complaints(complaints, n=49):
3641
"""Yield successive n-sized chunks from complaints list."""
3742
for i in range(0, len(complaints), n):
3843
yield complaints[i:i + n]
3944

45+
4046
def report_complaints(all_complaints, params):
4147
"""Post complaints to Slack."""
4248
if not params["slack_token"]:
@@ -46,7 +52,7 @@ def report_complaints(all_complaints, params):
4652
client = WebClient(token=params["slack_token"])
4753

4854
for complaints in split_complaints(all_complaints):
49-
blocks = format_complaints(complaints)
55+
blocks = format_complaints_aggregated_by_source(complaints)
5056
print(f"blocks: {len(blocks)}")
5157
try:
5258
client.chat_postMessage(
@@ -57,6 +63,66 @@ def report_complaints(all_complaints, params):
5763
# You will get a SlackApiError if "ok" is False
5864
assert False, e.response["error"]
5965

66+
def get_maintainers_block(complaints):
67+
"""Build a Slack block to alert maintainers to pay attention."""
68+
maintainers = set()
69+
for c in complaints:
70+
maintainers.update(c.maintainers)
71+
72+
maintainers_block = {
73+
"type": "section",
74+
"text": {
75+
"type": "mrkdwn",
76+
"text": "Hi, this is Sir Complains-a-Lot. I need to speak to " +
77+
(", ".join("<@{0}>".format(m)
78+
for m in maintainers)) + "."
79+
}
80+
}
81+
82+
return maintainers_block
83+
84+
85+
def format_complaints_aggregated_by_source(complaints):
86+
"""Build formatted Slack message for posting to the API, aggregating
87+
complaints by source to reduce the number of blocks."""
88+
89+
blocks = [get_maintainers_block(complaints)]
90+
91+
def message_for_source(complaint):
92+
return "{main_text} - (last update: {last_updated})".format(
93+
main_text=complaint.message,
94+
last_updated=complaint.last_updated.strftime("%Y-%m-%d"))
95+
96+
for source, complaints_by_source in groupby(
97+
complaints, key=lambda x: x.data_source):
98+
for message, complaint_list in groupby(
99+
complaints_by_source, key=message_for_source):
100+
signal_and_geo_types = ""
101+
for complaint in complaint_list:
102+
signal_and_geo_types += "`{signal}: [{geo_types}]`\n".format(
103+
signal=complaint.signal,
104+
geo_types=", ".join(complaint.geo_types))
105+
106+
blocks.extend([
107+
{
108+
"type": "divider"
109+
},
110+
{
111+
"type": "section",
112+
"text": {
113+
"type": "mrkdwn",
114+
"text": "*{source_name}* {message}:\n{signals}"
115+
.format(
116+
source_name=source.upper(),
117+
message=message,
118+
signals=signal_and_geo_types)
119+
}
120+
}
121+
])
122+
123+
return blocks
124+
125+
60126
def format_complaints(complaints):
61127
"""Build a formatted Slack message for posting to the API.
62128
@@ -65,31 +131,17 @@ def format_complaints(complaints):
65131
66132
"""
67133

68-
maintainers = set()
69-
for c in complaints:
70-
maintainers.update(c.maintainers)
71-
72-
blocks = [
73-
{
74-
"type": "section",
75-
"text": {
76-
"type": "mrkdwn",
77-
"text": "Hi, this is Sir Complains-a-Lot. I need to speak to " +
78-
(", ".join("<@{0}>".format(m) for m in maintainers)) + "."
79-
}
80-
}
81-
]
134+
blocks = [get_maintainers_block(complaints)]
82135

83136
for complaint in complaints:
84137
blocks.append(
85138
{
86-
"type": "section",
87-
"text": {
88-
"type": "mrkdwn",
89-
"text": complaint.to_md()
90-
}
91-
}
139+
"type": "section",
140+
"text": {
141+
"type": "mrkdwn",
142+
"text": complaint.to_md()
143+
}
144+
}
92145
)
93146

94-
95147
return blocks

0 commit comments

Comments
 (0)