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