##// END OF EJS Templates
integrations: use all caps template names.
marcink -
r3117:99ff31e3 default
parent child Browse files
Show More
@@ -1,300 +1,298 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 (
32 from rhodecode.integrations.types.base import (
33 IntegrationTypeBase, render_with_traceback)
33 IntegrationTypeBase, render_with_traceback)
34
34
35
35
36 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
37
37
38 repo_push_template_plaintext = Template('''
38 REPO_PUSH_TEMPLATE_PLAINTEXT = Template('''
39 Commits:
39 Commits:
40
40
41 % for commit in data['push']['commits']:
41 % for commit in data['push']['commits']:
42 ${commit['url']} by ${commit['author']} at ${commit['date']}
42 ${commit['url']} by ${commit['author']} at ${commit['date']}
43 ${commit['message']}
43 ${commit['message']}
44 ----
44 ----
45
45
46 % endfor
46 % endfor
47 ''')
47 ''')
48
48
49 ## TODO (marcink): think about putting this into a file, or use base.mako email template
49 REPO_PUSH_TEMPLATE_HTML = Template('''
50
51 repo_push_template_html = Template('''
52 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
50 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
53 <html xmlns="http://www.w3.org/1999/xhtml">
51 <html xmlns="http://www.w3.org/1999/xhtml">
54 <head>
52 <head>
55 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
53 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
56 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
54 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
57 <title>${subject}</title>
55 <title>${subject}</title>
58 <style type="text/css">
56 <style type="text/css">
59 /* Based on The MailChimp Reset INLINE: Yes. */
57 /* Based on The MailChimp Reset INLINE: Yes. */
60 #outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
58 #outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
61 body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0;}
59 body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0;}
62 /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
60 /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
63 .ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
61 .ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
64 .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
62 .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
65 /* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
63 /* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
66 #backgroundTable {margin:0; padding:0; line-height: 100% !important;}
64 #backgroundTable {margin:0; padding:0; line-height: 100% !important;}
67 /* End reset */
65 /* End reset */
68
66
69 /* defaults for images*/
67 /* defaults for images*/
70 img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
68 img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
71 a img {border:none;}
69 a img {border:none;}
72 .image_fix {display:block;}
70 .image_fix {display:block;}
73
71
74 body {line-height:1.2em;}
72 body {line-height:1.2em;}
75 p {margin: 0 0 20px;}
73 p {margin: 0 0 20px;}
76 h1, h2, h3, h4, h5, h6 {color:#323232!important;}
74 h1, h2, h3, h4, h5, h6 {color:#323232!important;}
77 a {color:#427cc9;text-decoration:none;outline:none;cursor:pointer;}
75 a {color:#427cc9;text-decoration:none;outline:none;cursor:pointer;}
78 a:focus {outline:none;}
76 a:focus {outline:none;}
79 a:hover {color: #305b91;}
77 a:hover {color: #305b91;}
80 h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color:#427cc9!important;text-decoration:none!important;}
78 h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color:#427cc9!important;text-decoration:none!important;}
81 h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {color: #305b91!important;}
79 h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {color: #305b91!important;}
82 h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {color: #305b91!important;}
80 h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {color: #305b91!important;}
83 table {font-size:13px;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;}
81 table {font-size:13px;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;}
84 table td {padding:.65em 1em .65em 0;border-collapse:collapse;vertical-align:top;text-align:left;}
82 table td {padding:.65em 1em .65em 0;border-collapse:collapse;vertical-align:top;text-align:left;}
85 input {display:inline;border-radius:2px;border-style:solid;border: 1px solid #dbd9da;padding:.5em;}
83 input {display:inline;border-radius:2px;border-style:solid;border: 1px solid #dbd9da;padding:.5em;}
86 input:focus {outline: 1px solid #979797}
84 input:focus {outline: 1px solid #979797}
87 @media only screen and (-webkit-min-device-pixel-ratio: 2) {
85 @media only screen and (-webkit-min-device-pixel-ratio: 2) {
88 /* Put your iPhone 4g styles in here */
86 /* Put your iPhone 4g styles in here */
89 }
87 }
90
88
91 /* Android targeting */
89 /* Android targeting */
92 @media only screen and (-webkit-device-pixel-ratio:.75){
90 @media only screen and (-webkit-device-pixel-ratio:.75){
93 /* Put CSS for low density (ldpi) Android layouts in here */
91 /* Put CSS for low density (ldpi) Android layouts in here */
94 }
92 }
95 @media only screen and (-webkit-device-pixel-ratio:1){
93 @media only screen and (-webkit-device-pixel-ratio:1){
96 /* Put CSS for medium density (mdpi) Android layouts in here */
94 /* Put CSS for medium density (mdpi) Android layouts in here */
97 }
95 }
98 @media only screen and (-webkit-device-pixel-ratio:1.5){
96 @media only screen and (-webkit-device-pixel-ratio:1.5){
99 /* Put CSS for high density (hdpi) Android layouts in here */
97 /* Put CSS for high density (hdpi) Android layouts in here */
100 }
98 }
101 /* end Android targeting */
99 /* end Android targeting */
102
100
103 </style>
101 </style>
104
102
105 <!-- Targeting Windows Mobile -->
103 <!-- Targeting Windows Mobile -->
106 <!--[if IEMobile 7]>
104 <!--[if IEMobile 7]>
107 <style type="text/css">
105 <style type="text/css">
108
106
109 </style>
107 </style>
110 <![endif]-->
108 <![endif]-->
111
109
112 <!--[if gte mso 9]>
110 <!--[if gte mso 9]>
113 <style>
111 <style>
114 /* Target Outlook 2007 and 2010 */
112 /* Target Outlook 2007 and 2010 */
115 </style>
113 </style>
116 <![endif]-->
114 <![endif]-->
117 </head>
115 </head>
118 <body>
116 <body>
119 <!-- 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. -->
117 <!-- 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. -->
120 <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">
118 <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">
121 <tr>
119 <tr>
122 <td valign="top" style="padding:0;">
120 <td valign="top" style="padding:0;">
123 <table cellpadding="0" cellspacing="0" border="0" align="left" width="100%">
121 <table cellpadding="0" cellspacing="0" border="0" align="left" width="100%">
124 <tr><td style="width:100%;padding:7px;background-color:#202020" valign="top">
122 <tr><td style="width:100%;padding:7px;background-color:#202020" valign="top">
125 <a style="color:#eeeeee;text-decoration:none;" href="${instance_url}">
123 <a style="color:#eeeeee;text-decoration:none;" href="${instance_url}">
126 ${'RhodeCode'}
124 ${'RhodeCode'}
127 </a>
125 </a>
128 </td></tr>
126 </td></tr>
129 <tr>
127 <tr>
130 <td style="padding:15px;" valign="top">
128 <td style="padding:15px;" valign="top">
131 % if data['push']['commits']:
129 % if data['push']['commits']:
132 % for commit in data['push']['commits']:
130 % for commit in data['push']['commits']:
133 <a href="${commit['url']}">${commit['short_id']}</a> by ${commit['author']} at ${commit['date']} <br/>
131 <a href="${commit['url']}">${commit['short_id']}</a> by ${commit['author']} at ${commit['date']} <br/>
134 ${commit['message_html']} <br/>
132 ${commit['message_html']} <br/>
135 <br/>
133 <br/>
136 % endfor
134 % endfor
137 % else:
135 % else:
138 No commit data
136 No commit data
139 % endif
137 % endif
140 </td>
138 </td>
141 </tr>
139 </tr>
142 </table>
140 </table>
143 </td>
141 </td>
144 </tr>
142 </tr>
145 </table>
143 </table>
146 <!-- End of wrapper table -->
144 <!-- End of wrapper table -->
147 <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}">
145 <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}">
148 ${'This is a notification from RhodeCode. %(instance_url)s' % {'instance_url': instance_url}}
146 ${'This is a notification from RhodeCode. %(instance_url)s' % {'instance_url': instance_url}}
149 </a></p>
147 </a></p>
150 </body>
148 </body>
151 </html>
149 </html>
152 ''')
150 ''')
153
151
154
152
155 class EmailSettingsSchema(colander.Schema):
153 class EmailSettingsSchema(colander.Schema):
156 @colander.instantiate(validator=colander.Length(min=1))
154 @colander.instantiate(validator=colander.Length(min=1))
157 class recipients(colander.SequenceSchema):
155 class recipients(colander.SequenceSchema):
158 title = _('Recipients')
156 title = _('Recipients')
159 description = _('Email addresses to send push events to')
157 description = _('Email addresses to send push events to')
160 widget = deform.widget.SequenceWidget(min_len=1)
158 widget = deform.widget.SequenceWidget(min_len=1)
161
159
162 recipient = colander.SchemaNode(
160 recipient = colander.SchemaNode(
163 colander.String(),
161 colander.String(),
164 title=_('Email address'),
162 title=_('Email address'),
165 description=_('Email address'),
163 description=_('Email address'),
166 default='',
164 default='',
167 validator=colander.Email(),
165 validator=colander.Email(),
168 widget=deform.widget.TextInputWidget(
166 widget=deform.widget.TextInputWidget(
169 placeholder='user@domain.com',
167 placeholder='user@domain.com',
170 ),
168 ),
171 )
169 )
172
170
173
171
174 class EmailIntegrationType(IntegrationTypeBase):
172 class EmailIntegrationType(IntegrationTypeBase):
175 key = 'email'
173 key = 'email'
176 display_name = _('Email')
174 display_name = _('Email')
177 description = _('Send repo push summaries to a list of recipients via email')
175 description = _('Send repo push summaries to a list of recipients via email')
178
176
179 @classmethod
177 @classmethod
180 def icon(cls):
178 def icon(cls):
181 return '''
179 return '''
182 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
180 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
183 <svg
181 <svg
184 xmlns:dc="http://purl.org/dc/elements/1.1/"
182 xmlns:dc="http://purl.org/dc/elements/1.1/"
185 xmlns:cc="http://creativecommons.org/ns#"
183 xmlns:cc="http://creativecommons.org/ns#"
186 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
184 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
187 xmlns:svg="http://www.w3.org/2000/svg"
185 xmlns:svg="http://www.w3.org/2000/svg"
188 xmlns="http://www.w3.org/2000/svg"
186 xmlns="http://www.w3.org/2000/svg"
189 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
187 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
190 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
188 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
191 viewBox="0 -256 1850 1850"
189 viewBox="0 -256 1850 1850"
192 id="svg2989"
190 id="svg2989"
193 version="1.1"
191 version="1.1"
194 inkscape:version="0.48.3.1 r9886"
192 inkscape:version="0.48.3.1 r9886"
195 width="100%"
193 width="100%"
196 height="100%"
194 height="100%"
197 sodipodi:docname="envelope_font_awesome.svg">
195 sodipodi:docname="envelope_font_awesome.svg">
198 <metadata
196 <metadata
199 id="metadata2999">
197 id="metadata2999">
200 <rdf:RDF>
198 <rdf:RDF>
201 <cc:Work
199 <cc:Work
202 rdf:about="">
200 rdf:about="">
203 <dc:format>image/svg+xml</dc:format>
201 <dc:format>image/svg+xml</dc:format>
204 <dc:type
202 <dc:type
205 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
203 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
206 </cc:Work>
204 </cc:Work>
207 </rdf:RDF>
205 </rdf:RDF>
208 </metadata>
206 </metadata>
209 <defs
207 <defs
210 id="defs2997" />
208 id="defs2997" />
211 <sodipodi:namedview
209 <sodipodi:namedview
212 pagecolor="#ffffff"
210 pagecolor="#ffffff"
213 bordercolor="#666666"
211 bordercolor="#666666"
214 borderopacity="1"
212 borderopacity="1"
215 objecttolerance="10"
213 objecttolerance="10"
216 gridtolerance="10"
214 gridtolerance="10"
217 guidetolerance="10"
215 guidetolerance="10"
218 inkscape:pageopacity="0"
216 inkscape:pageopacity="0"
219 inkscape:pageshadow="2"
217 inkscape:pageshadow="2"
220 inkscape:window-width="640"
218 inkscape:window-width="640"
221 inkscape:window-height="480"
219 inkscape:window-height="480"
222 id="namedview2995"
220 id="namedview2995"
223 showgrid="false"
221 showgrid="false"
224 inkscape:zoom="0.13169643"
222 inkscape:zoom="0.13169643"
225 inkscape:cx="896"
223 inkscape:cx="896"
226 inkscape:cy="896"
224 inkscape:cy="896"
227 inkscape:window-x="0"
225 inkscape:window-x="0"
228 inkscape:window-y="25"
226 inkscape:window-y="25"
229 inkscape:window-maximized="0"
227 inkscape:window-maximized="0"
230 inkscape:current-layer="svg2989" />
228 inkscape:current-layer="svg2989" />
231 <g
229 <g
232 transform="matrix(1,0,0,-1,37.966102,1282.678)"
230 transform="matrix(1,0,0,-1,37.966102,1282.678)"
233 id="g2991">
231 id="g2991">
234 <path
232 <path
235 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 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"
236 id="path2993"
234 id="path2993"
237 inkscape:connector-curvature="0"
235 inkscape:connector-curvature="0"
238 style="fill:currentColor" />
236 style="fill:currentColor" />
239 </g>
237 </g>
240 </svg>
238 </svg>
241 '''
239 '''
242
240
243 def settings_schema(self):
241 def settings_schema(self):
244 schema = EmailSettingsSchema()
242 schema = EmailSettingsSchema()
245 return schema
243 return schema
246
244
247 def send_event(self, event):
245 def send_event(self, event):
248 data = event.as_dict()
246 data = event.as_dict()
249 log.debug('got event: %r', event)
247 log.debug('got event: %r', event)
250
248
251 if isinstance(event, events.RepoPushEvent):
249 if isinstance(event, events.RepoPushEvent):
252 repo_push_handler(data, self.settings)
250 repo_push_handler(data, self.settings)
253 else:
251 else:
254 log.debug('ignoring event: %r', event)
252 log.debug('ignoring event: %r', event)
255
253
256
254
257 def repo_push_handler(data, settings):
255 def repo_push_handler(data, settings):
258 commit_num = len(data['push']['commits'])
256 commit_num = len(data['push']['commits'])
259 server_url = data['server_url']
257 server_url = data['server_url']
260
258
261 if commit_num == 1:
259 if commit_num == 1:
262 if data['push']['branches']:
260 if data['push']['branches']:
263 _subject = '[{repo_name}] {author} pushed {commit_num} commit on branches: {branches}'
261 _subject = '[{repo_name}] {author} pushed {commit_num} commit on branches: {branches}'
264 else:
262 else:
265 _subject = '[{repo_name}] {author} pushed {commit_num} commit'
263 _subject = '[{repo_name}] {author} pushed {commit_num} commit'
266 subject = _subject.format(
264 subject = _subject.format(
267 author=data['actor']['username'],
265 author=data['actor']['username'],
268 repo_name=data['repo']['repo_name'],
266 repo_name=data['repo']['repo_name'],
269 commit_num=commit_num,
267 commit_num=commit_num,
270 branches=', '.join(
268 branches=', '.join(
271 branch['name'] for branch in data['push']['branches'])
269 branch['name'] for branch in data['push']['branches'])
272 )
270 )
273 else:
271 else:
274 if data['push']['branches']:
272 if data['push']['branches']:
275 _subject = '[{repo_name}] {author} pushed {commit_num} commits on branches: {branches}'
273 _subject = '[{repo_name}] {author} pushed {commit_num} commits on branches: {branches}'
276 else:
274 else:
277 _subject = '[{repo_name}] {author} pushed {commit_num} commits'
275 _subject = '[{repo_name}] {author} pushed {commit_num} commits'
278 subject = _subject.format(
276 subject = _subject.format(
279 author=data['actor']['username'],
277 author=data['actor']['username'],
280 repo_name=data['repo']['repo_name'],
278 repo_name=data['repo']['repo_name'],
281 commit_num=commit_num,
279 commit_num=commit_num,
282 branches=', '.join(
280 branches=', '.join(
283 branch['name'] for branch in data['push']['branches']))
281 branch['name'] for branch in data['push']['branches']))
284
282
285 email_body_plaintext = render_with_traceback(
283 email_body_plaintext = render_with_traceback(
286 repo_push_template_plaintext,
284 REPO_PUSH_TEMPLATE_PLAINTEXT,
287 data=data,
285 data=data,
288 subject=subject,
286 subject=subject,
289 instance_url=server_url)
287 instance_url=server_url)
290
288
291 email_body_html = render_with_traceback(
289 email_body_html = render_with_traceback(
292 repo_push_template_html,
290 REPO_PUSH_TEMPLATE_HTML,
293 data=data,
291 data=data,
294 subject=subject,
292 subject=subject,
295 instance_url=server_url)
293 instance_url=server_url)
296
294
297 for email_address in settings['recipients']:
295 for email_address in settings['recipients']:
298 run_task(
296 run_task(
299 tasks.send_email, email_address, subject,
297 tasks.send_email, email_address, subject,
300 email_body_plaintext, email_body_html)
298 email_body_plaintext, email_body_html)
General Comments 0
You need to be logged in to leave comments. Login now