##// END OF EJS Templates
integrations: show no commits for email integration
dan -
r2645:f48c0619 default
parent child Browse files
Show More
@@ -1,295 +1,297 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2018 RhodeCode GmbH
3 # Copyright (C) 2012-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 from __future__ import unicode_literals
21 from __future__ import unicode_literals
22 import deform
22 import deform
23 import logging
23 import logging
24 import colander
24 import colander
25
25
26 from mako.template import Template
26 from mako.template import Template
27
27
28 from rhodecode import events
28 from rhodecode import events
29 from rhodecode.translation import _
29 from rhodecode.translation import _
30 from rhodecode.lib.celerylib import run_task
30 from rhodecode.lib.celerylib import run_task
31 from rhodecode.lib.celerylib import tasks
31 from rhodecode.lib.celerylib import tasks
32 from rhodecode.integrations.types.base import IntegrationTypeBase
32 from rhodecode.integrations.types.base import IntegrationTypeBase
33
33
34
34
35 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
36
36
37 repo_push_template_plaintext = Template('''
37 repo_push_template_plaintext = Template('''
38 Commits:
38 Commits:
39
39
40 % for commit in data['push']['commits']:
40 % for commit in data['push']['commits']:
41 ${commit['url']} by ${commit['author']} at ${commit['date']}
41 ${commit['url']} by ${commit['author']} at ${commit['date']}
42 ${commit['message']}
42 ${commit['message']}
43 ----
43 ----
44
44
45 % endfor
45 % endfor
46 ''')
46 ''')
47
47
48 ## TODO (marcink): think about putting this into a file, or use base.mako email template
48 ## TODO (marcink): think about putting this into a file, or use base.mako email template
49
49
50 repo_push_template_html = Template('''
50 repo_push_template_html = Template('''
51 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
51 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
52 <html xmlns="http://www.w3.org/1999/xhtml">
52 <html xmlns="http://www.w3.org/1999/xhtml">
53 <head>
53 <head>
54 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
54 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
55 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
55 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
56 <title>${subject}</title>
56 <title>${subject}</title>
57 <style type="text/css">
57 <style type="text/css">
58 /* Based on The MailChimp Reset INLINE: Yes. */
58 /* Based on The MailChimp Reset INLINE: Yes. */
59 #outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
59 #outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
60 body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0;}
60 body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0;}
61 /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
61 /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
62 .ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
62 .ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
63 .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
63 .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
64 /* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
64 /* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
65 #backgroundTable {margin:0; padding:0; line-height: 100% !important;}
65 #backgroundTable {margin:0; padding:0; line-height: 100% !important;}
66 /* End reset */
66 /* End reset */
67
67
68 /* defaults for images*/
68 /* defaults for images*/
69 img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
69 img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
70 a img {border:none;}
70 a img {border:none;}
71 .image_fix {display:block;}
71 .image_fix {display:block;}
72
72
73 body {line-height:1.2em;}
73 body {line-height:1.2em;}
74 p {margin: 0 0 20px;}
74 p {margin: 0 0 20px;}
75 h1, h2, h3, h4, h5, h6 {color:#323232!important;}
75 h1, h2, h3, h4, h5, h6 {color:#323232!important;}
76 a {color:#427cc9;text-decoration:none;outline:none;cursor:pointer;}
76 a {color:#427cc9;text-decoration:none;outline:none;cursor:pointer;}
77 a:focus {outline:none;}
77 a:focus {outline:none;}
78 a:hover {color: #305b91;}
78 a:hover {color: #305b91;}
79 h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color:#427cc9!important;text-decoration:none!important;}
79 h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color:#427cc9!important;text-decoration:none!important;}
80 h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {color: #305b91!important;}
80 h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {color: #305b91!important;}
81 h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {color: #305b91!important;}
81 h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {color: #305b91!important;}
82 table {font-size:13px;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;}
82 table {font-size:13px;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;}
83 table td {padding:.65em 1em .65em 0;border-collapse:collapse;vertical-align:top;text-align:left;}
83 table td {padding:.65em 1em .65em 0;border-collapse:collapse;vertical-align:top;text-align:left;}
84 input {display:inline;border-radius:2px;border-style:solid;border: 1px solid #dbd9da;padding:.5em;}
84 input {display:inline;border-radius:2px;border-style:solid;border: 1px solid #dbd9da;padding:.5em;}
85 input:focus {outline: 1px solid #979797}
85 input:focus {outline: 1px solid #979797}
86 @media only screen and (-webkit-min-device-pixel-ratio: 2) {
86 @media only screen and (-webkit-min-device-pixel-ratio: 2) {
87 /* Put your iPhone 4g styles in here */
87 /* Put your iPhone 4g styles in here */
88 }
88 }
89
89
90 /* Android targeting */
90 /* Android targeting */
91 @media only screen and (-webkit-device-pixel-ratio:.75){
91 @media only screen and (-webkit-device-pixel-ratio:.75){
92 /* Put CSS for low density (ldpi) Android layouts in here */
92 /* Put CSS for low density (ldpi) Android layouts in here */
93 }
93 }
94 @media only screen and (-webkit-device-pixel-ratio:1){
94 @media only screen and (-webkit-device-pixel-ratio:1){
95 /* Put CSS for medium density (mdpi) Android layouts in here */
95 /* Put CSS for medium density (mdpi) Android layouts in here */
96 }
96 }
97 @media only screen and (-webkit-device-pixel-ratio:1.5){
97 @media only screen and (-webkit-device-pixel-ratio:1.5){
98 /* Put CSS for high density (hdpi) Android layouts in here */
98 /* Put CSS for high density (hdpi) Android layouts in here */
99 }
99 }
100 /* end Android targeting */
100 /* end Android targeting */
101
101
102 </style>
102 </style>
103
103
104 <!-- Targeting Windows Mobile -->
104 <!-- Targeting Windows Mobile -->
105 <!--[if IEMobile 7]>
105 <!--[if IEMobile 7]>
106 <style type="text/css">
106 <style type="text/css">
107
107
108 </style>
108 </style>
109 <![endif]-->
109 <![endif]-->
110
110
111 <!--[if gte mso 9]>
111 <!--[if gte mso 9]>
112 <style>
112 <style>
113 /* Target Outlook 2007 and 2010 */
113 /* Target Outlook 2007 and 2010 */
114 </style>
114 </style>
115 <![endif]-->
115 <![endif]-->
116 </head>
116 </head>
117 <body>
117 <body>
118 <!-- Wrapper/Container Table: Use a wrapper table to control the width and the background color consistently of your email. Use this approach instead of setting attributes on the body tag. -->
118 <!-- Wrapper/Container Table: Use a wrapper table to control the width and the background color consistently of your email. Use this approach instead of setting attributes on the body tag. -->
119 <table cellpadding="0" cellspacing="0" border="0" id="backgroundTable" align="left" style="margin:1%;width:97%;padding:0;font-family:sans-serif;font-weight:100;border:1px solid #dbd9da">
119 <table cellpadding="0" cellspacing="0" border="0" id="backgroundTable" align="left" style="margin:1%;width:97%;padding:0;font-family:sans-serif;font-weight:100;border:1px solid #dbd9da">
120 <tr>
120 <tr>
121 <td valign="top" style="padding:0;">
121 <td valign="top" style="padding:0;">
122 <table cellpadding="0" cellspacing="0" border="0" align="left" width="100%">
122 <table cellpadding="0" cellspacing="0" border="0" align="left" width="100%">
123 <tr><td style="width:100%;padding:7px;background-color:#202020" valign="top">
123 <tr><td style="width:100%;padding:7px;background-color:#202020" valign="top">
124 <a style="color:#eeeeee;text-decoration:none;" href="${instance_url}">
124 <a style="color:#eeeeee;text-decoration:none;" href="${instance_url}">
125 ${'RhodeCode'}
125 ${'RhodeCode'}
126 </a>
126 </a>
127 </td></tr>
127 </td></tr>
128 <tr>
128 <tr>
129 <td style="padding:15px;" valign="top">
129 <td style="padding:15px;" valign="top">
130 % for commit in data['push']['commits']:
130 % if data['push']['commits']:
131 <a href="${commit['url']}">${commit['short_id']}</a> by ${commit['author']} at ${commit['date']} <br/>
131 % for commit in data['push']['commits']:
132 ${commit['message_html']} <br/>
132 <a href="${commit['url']}">${commit['short_id']}</a> by ${commit['author']} at ${commit['date']} <br/>
133 <br/>
133 ${commit['message_html']} <br/>
134 % endfor
134 <br/>
135 % endfor
136 % else:
137 No commit data
138 % endif
135 </td>
139 </td>
136 </tr>
140 </tr>
137 </table>
141 </table>
138 </td>
142 </td>
139 </tr>
143 </tr>
140 </table>
144 </table>
141 <!-- End of wrapper table -->
145 <!-- End of wrapper table -->
142 <p><a style="margin-top:15px;margin-left:1%;font-family:sans-serif;font-weight:100;font-size:11px;color:#666666;text-decoration:none;" href="${instance_url}">
146 <p><a style="margin-top:15px;margin-left:1%;font-family:sans-serif;font-weight:100;font-size:11px;color:#666666;text-decoration:none;" href="${instance_url}">
143 ${'This is a notification from RhodeCode. %(instance_url)s' % {'instance_url': instance_url}}
147 ${'This is a notification from RhodeCode. %(instance_url)s' % {'instance_url': instance_url}}
144 </a></p>
148 </a></p>
145 </body>
149 </body>
146 </html>
150 </html>
147 ''')
151 ''')
148
152
149
153
150
151
152 class EmailSettingsSchema(colander.Schema):
154 class EmailSettingsSchema(colander.Schema):
153 @colander.instantiate(validator=colander.Length(min=1))
155 @colander.instantiate(validator=colander.Length(min=1))
154 class recipients(colander.SequenceSchema):
156 class recipients(colander.SequenceSchema):
155 title = _('Recipients')
157 title = _('Recipients')
156 description = _('Email addresses to send push events to')
158 description = _('Email addresses to send push events to')
157 widget = deform.widget.SequenceWidget(min_len=1)
159 widget = deform.widget.SequenceWidget(min_len=1)
158
160
159 recipient = colander.SchemaNode(
161 recipient = colander.SchemaNode(
160 colander.String(),
162 colander.String(),
161 title=_('Email address'),
163 title=_('Email address'),
162 description=_('Email address'),
164 description=_('Email address'),
163 default='',
165 default='',
164 validator=colander.Email(),
166 validator=colander.Email(),
165 widget=deform.widget.TextInputWidget(
167 widget=deform.widget.TextInputWidget(
166 placeholder='user@domain.com',
168 placeholder='user@domain.com',
167 ),
169 ),
168 )
170 )
169
171
170
172
171 class EmailIntegrationType(IntegrationTypeBase):
173 class EmailIntegrationType(IntegrationTypeBase):
172 key = 'email'
174 key = 'email'
173 display_name = _('Email')
175 display_name = _('Email')
174 description = _('Send repo push summaries to a list of recipients via email')
176 description = _('Send repo push summaries to a list of recipients via email')
175
177
176 @classmethod
178 @classmethod
177 def icon(cls):
179 def icon(cls):
178 return '''
180 return '''
179 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
181 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
180 <svg
182 <svg
181 xmlns:dc="http://purl.org/dc/elements/1.1/"
183 xmlns:dc="http://purl.org/dc/elements/1.1/"
182 xmlns:cc="http://creativecommons.org/ns#"
184 xmlns:cc="http://creativecommons.org/ns#"
183 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
185 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
184 xmlns:svg="http://www.w3.org/2000/svg"
186 xmlns:svg="http://www.w3.org/2000/svg"
185 xmlns="http://www.w3.org/2000/svg"
187 xmlns="http://www.w3.org/2000/svg"
186 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
188 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
187 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
189 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
188 viewBox="0 -256 1850 1850"
190 viewBox="0 -256 1850 1850"
189 id="svg2989"
191 id="svg2989"
190 version="1.1"
192 version="1.1"
191 inkscape:version="0.48.3.1 r9886"
193 inkscape:version="0.48.3.1 r9886"
192 width="100%"
194 width="100%"
193 height="100%"
195 height="100%"
194 sodipodi:docname="envelope_font_awesome.svg">
196 sodipodi:docname="envelope_font_awesome.svg">
195 <metadata
197 <metadata
196 id="metadata2999">
198 id="metadata2999">
197 <rdf:RDF>
199 <rdf:RDF>
198 <cc:Work
200 <cc:Work
199 rdf:about="">
201 rdf:about="">
200 <dc:format>image/svg+xml</dc:format>
202 <dc:format>image/svg+xml</dc:format>
201 <dc:type
203 <dc:type
202 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
204 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
203 </cc:Work>
205 </cc:Work>
204 </rdf:RDF>
206 </rdf:RDF>
205 </metadata>
207 </metadata>
206 <defs
208 <defs
207 id="defs2997" />
209 id="defs2997" />
208 <sodipodi:namedview
210 <sodipodi:namedview
209 pagecolor="#ffffff"
211 pagecolor="#ffffff"
210 bordercolor="#666666"
212 bordercolor="#666666"
211 borderopacity="1"
213 borderopacity="1"
212 objecttolerance="10"
214 objecttolerance="10"
213 gridtolerance="10"
215 gridtolerance="10"
214 guidetolerance="10"
216 guidetolerance="10"
215 inkscape:pageopacity="0"
217 inkscape:pageopacity="0"
216 inkscape:pageshadow="2"
218 inkscape:pageshadow="2"
217 inkscape:window-width="640"
219 inkscape:window-width="640"
218 inkscape:window-height="480"
220 inkscape:window-height="480"
219 id="namedview2995"
221 id="namedview2995"
220 showgrid="false"
222 showgrid="false"
221 inkscape:zoom="0.13169643"
223 inkscape:zoom="0.13169643"
222 inkscape:cx="896"
224 inkscape:cx="896"
223 inkscape:cy="896"
225 inkscape:cy="896"
224 inkscape:window-x="0"
226 inkscape:window-x="0"
225 inkscape:window-y="25"
227 inkscape:window-y="25"
226 inkscape:window-maximized="0"
228 inkscape:window-maximized="0"
227 inkscape:current-layer="svg2989" />
229 inkscape:current-layer="svg2989" />
228 <g
230 <g
229 transform="matrix(1,0,0,-1,37.966102,1282.678)"
231 transform="matrix(1,0,0,-1,37.966102,1282.678)"
230 id="g2991">
232 id="g2991">
231 <path
233 <path
232 d="m 1664,32 v 768 q -32,-36 -69,-66 -268,-206 -426,-338 -51,-43 -83,-67 -32,-24 -86.5,-48.5 Q 945,256 897,256 h -1 -1 Q 847,256 792.5,280.5 738,305 706,329 674,353 623,396 465,528 197,734 160,764 128,800 V 32 Q 128,19 137.5,9.5 147,0 160,0 h 1472 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 0,1051 v 11 13.5 q 0,0 -0.5,13 -0.5,13 -3,12.5 -2.5,-0.5 -5.5,9 -3,9.5 -9,7.5 -6,-2 -14,2.5 H 160 q -13,0 -22.5,-9.5 Q 128,1133 128,1120 128,952 275,836 468,684 676,519 682,514 711,489.5 740,465 757,452 774,439 801.5,420.5 829,402 852,393 q 23,-9 43,-9 h 1 1 q 20,0 43,9 23,9 50.5,27.5 27.5,18.5 44.5,31.5 17,13 46,37.5 29,24.5 35,29.5 208,165 401,317 54,43 100.5,115.5 46.5,72.5 46.5,131.5 z m 128,37 V 32 q 0,-66 -47,-113 -47,-47 -113,-47 H 160 Q 94,-128 47,-81 0,-34 0,32 v 1088 q 0,66 47,113 47,47 113,47 h 1472 q 66,0 113,-47 47,-47 47,-113 z"
234 d="m 1664,32 v 768 q -32,-36 -69,-66 -268,-206 -426,-338 -51,-43 -83,-67 -32,-24 -86.5,-48.5 Q 945,256 897,256 h -1 -1 Q 847,256 792.5,280.5 738,305 706,329 674,353 623,396 465,528 197,734 160,764 128,800 V 32 Q 128,19 137.5,9.5 147,0 160,0 h 1472 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 0,1051 v 11 13.5 q 0,0 -0.5,13 -0.5,13 -3,12.5 -2.5,-0.5 -5.5,9 -3,9.5 -9,7.5 -6,-2 -14,2.5 H 160 q -13,0 -22.5,-9.5 Q 128,1133 128,1120 128,952 275,836 468,684 676,519 682,514 711,489.5 740,465 757,452 774,439 801.5,420.5 829,402 852,393 q 23,-9 43,-9 h 1 1 q 20,0 43,9 23,9 50.5,27.5 27.5,18.5 44.5,31.5 17,13 46,37.5 29,24.5 35,29.5 208,165 401,317 54,43 100.5,115.5 46.5,72.5 46.5,131.5 z m 128,37 V 32 q 0,-66 -47,-113 -47,-47 -113,-47 H 160 Q 94,-128 47,-81 0,-34 0,32 v 1088 q 0,66 47,113 47,47 113,47 h 1472 q 66,0 113,-47 47,-47 47,-113 z"
233 id="path2993"
235 id="path2993"
234 inkscape:connector-curvature="0"
236 inkscape:connector-curvature="0"
235 style="fill:currentColor" />
237 style="fill:currentColor" />
236 </g>
238 </g>
237 </svg>
239 </svg>
238 '''
240 '''
239
241
240 def settings_schema(self):
242 def settings_schema(self):
241 schema = EmailSettingsSchema()
243 schema = EmailSettingsSchema()
242 return schema
244 return schema
243
245
244 def send_event(self, event):
246 def send_event(self, event):
245 data = event.as_dict()
247 data = event.as_dict()
246 log.debug('got event: %r', event)
248 log.debug('got event: %r', event)
247
249
248 if isinstance(event, events.RepoPushEvent):
250 if isinstance(event, events.RepoPushEvent):
249 repo_push_handler(data, self.settings)
251 repo_push_handler(data, self.settings)
250 else:
252 else:
251 log.debug('ignoring event: %r', event)
253 log.debug('ignoring event: %r', event)
252
254
253
255
254 def repo_push_handler(data, settings):
256 def repo_push_handler(data, settings):
255 commit_num = len(data['push']['commits'])
257 commit_num = len(data['push']['commits'])
256 server_url = data['server_url']
258 server_url = data['server_url']
257
259
258 if commit_num == 1:
260 if commit_num == 1:
259 if data['push']['branches']:
261 if data['push']['branches']:
260 _subject = '[{repo_name}] {author} pushed {commit_num} commit on branches: {branches}'
262 _subject = '[{repo_name}] {author} pushed {commit_num} commit on branches: {branches}'
261 else:
263 else:
262 _subject = '[{repo_name}] {author} pushed {commit_num} commit'
264 _subject = '[{repo_name}] {author} pushed {commit_num} commit'
263 subject = _subject.format(
265 subject = _subject.format(
264 author=data['actor']['username'],
266 author=data['actor']['username'],
265 repo_name=data['repo']['repo_name'],
267 repo_name=data['repo']['repo_name'],
266 commit_num=commit_num,
268 commit_num=commit_num,
267 branches=', '.join(
269 branches=', '.join(
268 branch['name'] for branch in data['push']['branches'])
270 branch['name'] for branch in data['push']['branches'])
269 )
271 )
270 else:
272 else:
271 if data['push']['branches']:
273 if data['push']['branches']:
272 _subject = '[{repo_name}] {author} pushed {commit_num} commits on branches: {branches}'
274 _subject = '[{repo_name}] {author} pushed {commit_num} commits on branches: {branches}'
273 else:
275 else:
274 _subject = '[{repo_name}] {author} pushed {commit_num} commits'
276 _subject = '[{repo_name}] {author} pushed {commit_num} commits'
275 subject = _subject.format(
277 subject = _subject.format(
276 author=data['actor']['username'],
278 author=data['actor']['username'],
277 repo_name=data['repo']['repo_name'],
279 repo_name=data['repo']['repo_name'],
278 commit_num=commit_num,
280 commit_num=commit_num,
279 branches=', '.join(
281 branches=', '.join(
280 branch['name'] for branch in data['push']['branches']))
282 branch['name'] for branch in data['push']['branches']))
281
283
282 email_body_plaintext = repo_push_template_plaintext.render(
284 email_body_plaintext = repo_push_template_plaintext.render(
283 data=data,
285 data=data,
284 subject=subject,
286 subject=subject,
285 instance_url=server_url)
287 instance_url=server_url)
286
288
287 email_body_html = repo_push_template_html.render(
289 email_body_html = repo_push_template_html.render(
288 data=data,
290 data=data,
289 subject=subject,
291 subject=subject,
290 instance_url=server_url)
292 instance_url=server_url)
291
293
292 for email_address in settings['recipients']:
294 for email_address in settings['recipients']:
293 run_task(
295 run_task(
294 tasks.send_email, email_address, subject,
296 tasks.send_email, email_address, subject,
295 email_body_plaintext, email_body_html)
297 email_body_plaintext, email_body_html)
General Comments 0
You need to be logged in to leave comments. Login now