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