7
7
8
8
import sys
9
9
10
+ from itertools import groupby
11
+
10
12
from slack import WebClient
11
13
from slack .errors import SlackApiError
12
14
15
17
16
18
from .check_source import check_source
17
19
20
+
18
21
def run_module ():
19
22
20
23
params = read_params ()
21
24
meta = covidcast .metadata ()
22
25
23
26
complaints = []
24
27
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 )))
26
30
27
31
if len (complaints ) > 0 :
28
32
for complaint in complaints :
@@ -32,11 +36,13 @@ def run_module():
32
36
33
37
sys .exit (1 )
34
38
39
+
35
40
def split_complaints (complaints , n = 49 ):
36
41
"""Yield successive n-sized chunks from complaints list."""
37
42
for i in range (0 , len (complaints ), n ):
38
43
yield complaints [i :i + n ]
39
44
45
+
40
46
def report_complaints (all_complaints , params ):
41
47
"""Post complaints to Slack."""
42
48
if not params ["slack_token" ]:
@@ -46,7 +52,7 @@ def report_complaints(all_complaints, params):
46
52
client = WebClient (token = params ["slack_token" ])
47
53
48
54
for complaints in split_complaints (all_complaints ):
49
- blocks = format_complaints (complaints )
55
+ blocks = format_complaints_aggregated_by_source (complaints )
50
56
print (f"blocks: { len (blocks )} " )
51
57
try :
52
58
client .chat_postMessage (
@@ -57,6 +63,66 @@ def report_complaints(all_complaints, params):
57
63
# You will get a SlackApiError if "ok" is False
58
64
assert False , e .response ["error" ]
59
65
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
+
60
126
def format_complaints (complaints ):
61
127
"""Build a formatted Slack message for posting to the API.
62
128
@@ -65,31 +131,17 @@ def format_complaints(complaints):
65
131
66
132
"""
67
133
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 )]
82
135
83
136
for complaint in complaints :
84
137
blocks .append (
85
138
{
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
+ }
92
145
)
93
146
94
-
95
147
return blocks
0 commit comments