##// END OF EJS Templates
integrations: update emails integration with nicer emails
marcink -
r650:6e54c581 default
parent child Browse files
Show More
@@ -1,127 +1,222 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2012-2016 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
23 22 import deform
24 23 import logging
25 24 import colander
26 25
27 26 from mako.template import Template
28 27
29 28 from rhodecode import events
30 29 from rhodecode.translation import _, lazy_ugettext
31 30 from rhodecode.lib.celerylib import run_task
32 31 from rhodecode.lib.celerylib import tasks
33 32 from rhodecode.integrations.types.base import IntegrationTypeBase
34 33 from rhodecode.integrations.schema import IntegrationSettingsSchemaBase
35 34
36 35
37 log = logging.getLogger()
36 log = logging.getLogger(__name__)
37
38 repo_push_template_plaintext = Template('''
39 Commits:
40
41 % for commit in data['push']['commits']:
42 ${commit['url']} by ${commit['author']} at ${commit['date']}
43 ${commit['message']}
44 ----
45
46 % endfor
47 ''')
48
49 ## TODO (marcink): think about putting this into a file, or use base.mako email 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">
53 <html xmlns="http://www.w3.org/1999/xhtml">
54 <head>
55 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
56 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
57 <title>${subject}</title>
58 <style type="text/css">
59 /* Based on The MailChimp Reset INLINE: Yes. */
60 #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;}
62 /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
63 .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%;}
65 /* 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;}
67 /* End reset */
68
69 /* defaults for images*/
70 img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
71 a img {border:none;}
72 .image_fix {display:block;}
73
74 body {line-height:1.2em;}
75 p {margin: 0 0 20px;}
76 h1, h2, h3, h4, h5, h6 {color:#323232!important;}
77 a {color:#427cc9;text-decoration:none;outline:none;cursor:pointer;}
78 a:focus {outline:none;}
79 a:hover {color: #305b91;}
80 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;}
82 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;}
84 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;}
86 input:focus {outline: 1px solid #979797}
87 @media only screen and (-webkit-min-device-pixel-ratio: 2) {
88 /* Put your iPhone 4g styles in here */
89 }
38 90
91 /* Android targeting */
92 @media only screen and (-webkit-device-pixel-ratio:.75){
93 /* Put CSS for low density (ldpi) Android layouts in here */
94 }
95 @media only screen and (-webkit-device-pixel-ratio:1){
96 /* Put CSS for medium density (mdpi) Android layouts in here */
97 }
98 @media only screen and (-webkit-device-pixel-ratio:1.5){
99 /* Put CSS for high density (hdpi) Android layouts in here */
100 }
101 /* end Android targeting */
102
103 </style>
104
105 <!-- Targeting Windows Mobile -->
106 <!--[if IEMobile 7]>
107 <style type="text/css">
108
109 </style>
110 <![endif]-->
111
112 <!--[if gte mso 9]>
113 <style>
114 /* Target Outlook 2007 and 2010 */
115 </style>
116 <![endif]-->
117 </head>
118 <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. -->
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">
121 <tr>
122 <td valign="top" style="padding:0;">
123 <table cellpadding="0" cellspacing="0" border="0" align="left" width="100%">
124 <tr><td style="width:100%;padding:7px;background-color:#202020" valign="top">
125 <a style="color:#eeeeee;text-decoration:none;" href="${instance_url}">
126 ${'RhodeCode'}
127 </a>
128 </td></tr>
129 <tr>
130 <td style="padding:15px;" valign="top">
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 </td>
137 </tr>
138 </table>
139 </td>
140 </tr>
141 </table>
142 <!-- End of wrapper table -->
143 <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}">
144 ${'This is a notification from RhodeCode. %(instance_url)s' % {'instance_url': instance_url}}
145 </a></p>
146 </body>
147 </html>
148 ''')
39 149
40 150
41 151 class EmailSettingsSchema(IntegrationSettingsSchemaBase):
42 152 @colander.instantiate(validator=colander.Length(min=1))
43 153 class recipients(colander.SequenceSchema):
44 154 title = lazy_ugettext('Recipients')
45 155 description = lazy_ugettext('Email addresses to send push events to')
46 156 widget = deform.widget.SequenceWidget(min_len=1)
47 157
48 158 recipient = colander.SchemaNode(
49 159 colander.String(),
50 160 title=lazy_ugettext('Email address'),
51 161 description=lazy_ugettext('Email address'),
52 162 default='',
53 163 validator=colander.Email(),
54 164 widget=deform.widget.TextInputWidget(
55 165 placeholder='user@domain.com',
56 166 ),
57 167 )
58 168
59 169
60 170 class EmailIntegrationType(IntegrationTypeBase):
61 171 key = 'email'
62 172 display_name = lazy_ugettext('Email')
63 173 SettingsSchema = EmailSettingsSchema
64 174
65 175 def settings_schema(self):
66 176 schema = EmailSettingsSchema()
67 177 return schema
68 178
69 179 def send_event(self, event):
70 180 data = event.as_dict()
71 181 log.debug('got event: %r', event)
72 182
73 183 if isinstance(event, events.RepoPushEvent):
74 184 repo_push_handler(data, self.settings)
75 185 else:
76 186 log.debug('ignoring event: %r', event)
77 187
78 188
79 189 def repo_push_handler(data, settings):
80 for commit in data['push']['commits']:
190 commit_num = len(data['push']['commits'])
191 server_url = data['server_url']
192
193 if commit_num == 0:
194 subject = '[{repo_name}] {author} pushed {commit_num} commit on branches: {branches}'.format(
195 author=data['actor']['username'],
196 repo_name=data['repo']['repo_name'],
197 commit_num=commit_num,
198 branches=', '.join(
199 branch['name'] for branch in data['push']['branches'])
200 )
201 else:
202 subject = '[{repo_name}] {author} pushed {commit_num} commits on branches: {branches}'.format(
203 author=data['actor']['username'],
204 repo_name=data['repo']['repo_name'],
205 commit_num=commit_num,
206 branches=', '.join(
207 branch['name'] for branch in data['push']['branches']))
208
81 209 email_body_plaintext = repo_push_template_plaintext.render(
82 210 data=data,
83 commit=commit,
84 commit_msg=commit['message'],
85 )
211 subject=subject,
212 instance_url=server_url)
213
86 214 email_body_html = repo_push_template_html.render(
87 215 data=data,
88 commit=commit,
89 commit_msg=commit['message_html'],
90 )
216 subject=subject,
217 instance_url=server_url)
91 218
92 subject = '[%(repo_name)s] %(commit_id)s: %(commit_msg)s' % {
93 'repo_name': data['repo']['repo_name'],
94 'commit_id': commit['short_id'],
95 'commit_msg': commit['message'].split('\n')[0][:150]
96 }
97 219 for email_address in settings['recipients']:
98 task = run_task(
220 run_task(
99 221 tasks.send_email, email_address, subject,
100 222 email_body_plaintext, email_body_html)
101
102
103 # TODO: dan: add changed files, make html pretty
104 repo_push_template_plaintext = Template('''
105 User: ${data['actor']['username']}
106 Branches: ${', '.join(branch['name'] for branch in data['push']['branches'])}
107 Repository: ${data['repo']['url']}
108 Commit: ${commit['raw_id']}
109 URL: ${commit['url']}
110 Author: ${commit['author']}
111 Date: ${commit['date']}
112 Commit Message:
113
114 ${commit_msg}
115 ''')
116
117 repo_push_template_html = Template('''
118 User: ${data['actor']['username']}<br>
119 Branches: ${', '.join(branch['name'] for branch in data['push']['branches'])}<br>
120 Repository: ${data['repo']['url']}<br>
121 Commit: ${commit['raw_id']}<br>
122 URL: ${commit['url']}<br>
123 Author: ${commit['author']}<br>
124 Date: ${commit['date']}<br>
125 Commit Message:<br>
126 <p>${commit_msg}</p>
127 ''')
General Comments 0
You need to be logged in to leave comments. Login now