Merge lp:~deadlight/canonical-identity-provider/email-template into lp:~deadlight/canonical-identity-provider/vanilla
- email-template
- Merge into vanilla
Proposed by
Karl Williams
Status: | Merged |
---|---|
Approved by: | Karl Williams |
Approved revision: | 1715 |
Merged at revision: | 1715 |
Proposed branch: | lp:~deadlight/canonical-identity-provider/email-template |
Merge into: | lp:~deadlight/canonical-identity-provider/vanilla |
Diff against target: |
393 lines (+274/-17) 2 files modified
src/identityprovider/emailutils.py (+27/-17) src/webui/templates/email/html/email.html (+247/-0) |
To merge this branch: | bzr merge lp:~deadlight/canonical-identity-provider/email-template |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Anthony Dillon (community) | Approve | ||
Review via email: mp+372011@code.launchpad.net |
Commit message
Description of the change
Added an HTML email template
QA:
In terminal 1:
- npm i
- ./node_
- source env/bin/activate
- make start-db
- make run
In terminal 2:
- source env/bin/activate
- make mail-debug
- Visit http://[CONTAINER IP]:8000/
- Create an account
- Check the output of terminal 2 and see the email text
- Copy the HTML email into a file and open it in a browser to view ityo
To post a comment you must log in.
Revision history for this message
Karl Williams (deadlight) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/identityprovider/emailutils.py' | |||
2 | --- src/identityprovider/emailutils.py 2018-08-22 22:33:08 +0000 | |||
3 | +++ src/identityprovider/emailutils.py 2019-08-29 15:29:29 +0000 | |||
4 | @@ -64,22 +64,28 @@ | |||
5 | 64 | return formataddr((name, address)) | 64 | return formataddr((name, address)) |
6 | 65 | 65 | ||
7 | 66 | 66 | ||
9 | 67 | def send_templated_email(subject, template, context, email, from_address=None): | 67 | def send_templated_email(subject, template, context, email, from_address=None, title=None): |
10 | 68 | msg = render_to_string(template, context=context) | 68 | msg = render_to_string(template, context=context) |
11 | 69 | 69 | ||
12 | 70 | if from_address is None: | 70 | if from_address is None: |
13 | 71 | from_address = format_address(settings.NOREPLY_FROM_ADDRESS) | 71 | from_address = format_address(settings.NOREPLY_FROM_ADDRESS) |
14 | 72 | if title is None: | ||
15 | 73 | title = 'Ubuntu One' | ||
16 | 74 | |||
17 | 75 | html = render_to_string('email/html/email.html', {'title':title, 'content':msg}) | ||
18 | 76 | |||
19 | 72 | if not isinstance(email, (tuple, list)): | 77 | if not isinstance(email, (tuple, list)): |
20 | 73 | email = [email] | 78 | email = [email] |
21 | 74 | return send_mail( | 79 | return send_mail( |
26 | 75 | subject, | 80 | subject = subject, |
27 | 76 | msg, | 81 | message = msg, |
28 | 77 | from_address, | 82 | from_email = from_address, |
29 | 78 | [format_address(e) for e in email] | 83 | recipient_list = [format_address(e) for e in email], |
30 | 84 | html_message = html | ||
31 | 79 | ) | 85 | ) |
32 | 80 | 86 | ||
33 | 81 | 87 | ||
35 | 82 | def send_fancy_email(subject, template, context, email, from_address=None): | 88 | def send_fancy_email(subject, template, context, email, from_address=None, title=None): |
36 | 83 | if from_address is None: | 89 | if from_address is None: |
37 | 84 | from_address = format_address( | 90 | from_address = format_address( |
38 | 85 | settings.NOREPLY_FROM_ADDRESS, | 91 | settings.NOREPLY_FROM_ADDRESS, |
39 | @@ -87,7 +93,7 @@ | |||
40 | 87 | ) | 93 | ) |
41 | 88 | subject = u"%s: %s" % (settings.NOREPLY_FROM_NAME, subject) | 94 | subject = u"%s: %s" % (settings.NOREPLY_FROM_NAME, subject) |
42 | 89 | return send_templated_email(subject, template, context, email, | 95 | return send_templated_email(subject, template, context, email, |
44 | 90 | from_address) | 96 | from_address, title) |
45 | 91 | 97 | ||
46 | 92 | 98 | ||
47 | 93 | def _should_add_invalidation_link(email): | 99 | def _should_add_invalidation_link(email): |
48 | @@ -178,7 +184,7 @@ | |||
49 | 178 | template = 'email/desktop-newuser.txt' | 184 | template = 'email/desktop-newuser.txt' |
50 | 179 | 185 | ||
51 | 180 | send_fancy_email( | 186 | send_fancy_email( |
53 | 181 | _('Finish your registration'), template, context, email) | 187 | _('Finish your registration'), template, context, email, None, 'Finish your registration') |
54 | 182 | return token, invalidate_email_token | 188 | return token, invalidate_email_token |
55 | 183 | 189 | ||
56 | 184 | 190 | ||
57 | @@ -219,7 +225,7 @@ | |||
58 | 219 | context, token, invalidate_email_token = _context_for_email_request( | 225 | context, token, invalidate_email_token = _context_for_email_request( |
59 | 220 | root_url, account, email, AuthTokenType.PASSWORDRECOVERY, | 226 | root_url, account, email, AuthTokenType.PASSWORDRECOVERY, |
60 | 221 | redirection_url, requester_email=email) | 227 | redirection_url, requester_email=email) |
62 | 222 | send_fancy_email(subject, template, context, email) | 228 | send_fancy_email(subject, template, context, email, None, 'Password reset') |
63 | 223 | return token, invalidate_email_token | 229 | return token, invalidate_email_token |
64 | 224 | 230 | ||
65 | 225 | 231 | ||
66 | @@ -236,7 +242,7 @@ | |||
67 | 236 | send_fancy_email( | 242 | send_fancy_email( |
68 | 237 | _("Password change notification"), | 243 | _("Password change notification"), |
69 | 238 | 'email/password-changed.txt', | 244 | 'email/password-changed.txt', |
71 | 239 | context=context, email=email.email) | 245 | context=context, email=email.email, from_address=None, title='Password changed') |
72 | 240 | 246 | ||
73 | 241 | 247 | ||
74 | 242 | def send_printed_codes_renewal_email(root_url, account, devices): | 248 | def send_printed_codes_renewal_email(root_url, account, devices): |
75 | @@ -257,7 +263,7 @@ | |||
76 | 257 | send_fancy_email( | 263 | send_fancy_email( |
77 | 258 | _("Printed list of backup codes is nearly used up"), | 264 | _("Printed list of backup codes is nearly used up"), |
78 | 259 | 'email/printed-codes-nearly-exhausted-warning.txt', | 265 | 'email/printed-codes-nearly-exhausted-warning.txt', |
80 | 260 | context=context, email=email) | 266 | context=context, email=email, from_address=None, title='Backup codes') |
81 | 261 | 267 | ||
82 | 262 | 268 | ||
83 | 263 | def send_validation_email_request(root_url, account, email, | 269 | def send_validation_email_request(root_url, account, email, |
84 | @@ -281,7 +287,7 @@ | |||
85 | 281 | requester_email=preferredemail_email, oid_token=oid_token) | 287 | requester_email=preferredemail_email, oid_token=oid_token) |
86 | 282 | send_fancy_email( | 288 | send_fancy_email( |
87 | 283 | _("Validate your email address"), 'email/validate-email.txt', | 289 | _("Validate your email address"), 'email/validate-email.txt', |
89 | 284 | context, email) | 290 | context, email, None, 'Validate your email address') |
90 | 285 | return token, invalidate_email_token | 291 | return token, invalidate_email_token |
91 | 286 | 292 | ||
92 | 287 | 293 | ||
93 | @@ -300,7 +306,8 @@ | |||
94 | 300 | send_fancy_email( | 306 | send_fancy_email( |
95 | 301 | _("The email address {email} was removed from your account").format( | 307 | _("The email address {email} was removed from your account").format( |
96 | 302 | email=invalidated_email), | 308 | email=invalidated_email), |
98 | 303 | 'email/email-invalidated.txt', context=context, email=email) | 309 | 'email/email-invalidated.txt', context=context, email=email, |
99 | 310 | from_address=None, title='Email address removed') | ||
100 | 304 | 311 | ||
101 | 305 | 312 | ||
102 | 306 | def send_notification_to_invalidated_email_address(root_url, account, | 313 | def send_notification_to_invalidated_email_address(root_url, account, |
103 | @@ -315,14 +322,16 @@ | |||
104 | 315 | ), | 322 | ), |
105 | 316 | 'email/invalidate_email_confirmation.txt', | 323 | 'email/invalidate_email_confirmation.txt', |
106 | 317 | context=context, | 324 | context=context, |
108 | 318 | email=invalidated_email | 325 | email=invalidated_email, |
109 | 326 | from_address=None, | ||
110 | 327 | title='Email address invalidated' | ||
111 | 319 | ) | 328 | ) |
112 | 320 | 329 | ||
113 | 321 | 330 | ||
114 | 322 | def send_preferred_changed_notification(email, new_preferred): | 331 | def send_preferred_changed_notification(email, new_preferred): |
115 | 323 | send_fancy_email( | 332 | send_fancy_email( |
116 | 324 | _('E-mail change notification'), 'email/preferred-changed.txt', | 333 | _('E-mail change notification'), 'email/preferred-changed.txt', |
118 | 325 | {'new_preferred': new_preferred}, email) | 334 | {'new_preferred': new_preferred}, email, None, 'Preferred email changed') |
119 | 326 | 335 | ||
120 | 327 | 336 | ||
121 | 328 | def send_invitation_after_password_reset(root_url, email): | 337 | def send_invitation_after_password_reset(root_url, email): |
122 | @@ -330,7 +339,7 @@ | |||
123 | 330 | url = urljoin(root_url, reverse('new_account')) | 339 | url = urljoin(root_url, reverse('new_account')) |
124 | 331 | send_fancy_email( | 340 | send_fancy_email( |
125 | 332 | _("Password reset request"), 'email/invitation.txt', | 341 | _("Password reset request"), 'email/invitation.txt', |
127 | 333 | {'email': email, 'signup': url}, email, | 342 | {'email': email, 'signup': url}, email, None, 'Password reset request' |
128 | 334 | ) | 343 | ) |
129 | 335 | 344 | ||
130 | 336 | 345 | ||
131 | @@ -363,7 +372,8 @@ | |||
132 | 363 | else: | 372 | else: |
133 | 364 | subject = _('Account to be deleted - action required') | 373 | subject = _('Account to be deleted - action required') |
134 | 365 | send_fancy_email( | 374 | send_fancy_email( |
136 | 366 | subject, 'email/account-action-required.txt', context, email, | 375 | subject, 'email/account-action-required.txt', context, email, None, |
137 | 376 | 'Action required' | ||
138 | 367 | ) | 377 | ) |
139 | 368 | return token, invalidate_email_token | 378 | return token, invalidate_email_token |
140 | 369 | 379 | ||
141 | 370 | 380 | ||
142 | === added directory 'src/webui/templates/email/html' | |||
143 | === added file 'src/webui/templates/email/html/email.html' | |||
144 | --- src/webui/templates/email/html/email.html 1970-01-01 00:00:00 +0000 | |||
145 | +++ src/webui/templates/email/html/email.html 2019-08-29 15:29:29 +0000 | |||
146 | @@ -0,0 +1,247 @@ | |||
147 | 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
148 | 2 | <html xmlns="http://www.w3.org/1999/xhtml" | ||
149 | 3 | xmlns:v="urn:schemas-microsoft-com:vml" | ||
150 | 4 | xmlns:o="urn:schemas-microsoft-com:office:office"> | ||
151 | 5 | |||
152 | 6 | <head> | ||
153 | 7 | <!--[if gte mso 9]><xml> | ||
154 | 8 | <o:OfficeDocumentSettings> | ||
155 | 9 | <o:AllowPNG/> | ||
156 | 10 | <o:PixelsPerInch>96</o:PixelsPerInch> | ||
157 | 11 | </o:OfficeDocumentSettings> | ||
158 | 12 | </xml><![endif]--> | ||
159 | 13 | |||
160 | 14 | <!-- Define Charset --> | ||
161 | 15 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
162 | 16 | |||
163 | 17 | <!-- Responsive Meta Tag --> | ||
164 | 18 | <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> | ||
165 | 19 | |||
166 | 20 | <link href="https://fonts.googleapis.com/css?family=Ubuntu:100,300,400,500,700" rel="stylesheet"> | ||
167 | 21 | |||
168 | 22 | <title>{{ title }}</title> | ||
169 | 23 | |||
170 | 24 | <!-- Responsive Styles and Valid Styles --> | ||
171 | 25 | |||
172 | 26 | <style type="text/css"> | ||
173 | 27 | /* iOS BLUE LINKS */ | ||
174 | 28 | a[x-apple-data-detectors] { | ||
175 | 29 | color: inherit !important; | ||
176 | 30 | text-decoration: none !important; | ||
177 | 31 | font-size: inherit !important; | ||
178 | 32 | font-family: inherit !important; | ||
179 | 33 | font-weight: inherit !important; | ||
180 | 34 | line-height: inherit !important; | ||
181 | 35 | } | ||
182 | 36 | |||
183 | 37 | body{ | ||
184 | 38 | width: 100%; | ||
185 | 39 | background-color: #E1E1E1; | ||
186 | 40 | margin:0; | ||
187 | 41 | padding:0; | ||
188 | 42 | -webkit-font-smoothing: antialiased; | ||
189 | 43 | mso-margin-top-alt:0px; | ||
190 | 44 | mso-margin-bottom-alt:0px; | ||
191 | 45 | mso-padding-alt: 0px 0px 0px 0px; | ||
192 | 46 | -webkit-text-size-adjust:none; | ||
193 | 47 | } | ||
194 | 48 | |||
195 | 49 | p,h1,h2,h3,h4{ | ||
196 | 50 | margin-top:0; | ||
197 | 51 | margin-bottom:0; | ||
198 | 52 | padding-top:0; | ||
199 | 53 | padding-bottom:0; | ||
200 | 54 | } | ||
201 | 55 | |||
202 | 56 | p { | ||
203 | 57 | margin-bottom: 1em; | ||
204 | 58 | } | ||
205 | 59 | |||
206 | 60 | [style*="Ubuntu"] { | ||
207 | 61 | font-family: Ubuntu, Sans Serif, Arial, Helvetica !important; | ||
208 | 62 | } | ||
209 | 63 | |||
210 | 64 | span.Preheader{display: none; font-size: 1px;} | ||
211 | 65 | |||
212 | 66 | html{ | ||
213 | 67 | width: 100%; | ||
214 | 68 | } | ||
215 | 69 | |||
216 | 70 | .ZedFix { | ||
217 | 71 | display:none; | ||
218 | 72 | display:none!important; | ||
219 | 73 | } | ||
220 | 74 | |||
221 | 75 | /* ----------- responsivity ----------- */ | ||
222 | 76 | @media only screen and (max-width: 640px){ | ||
223 | 77 | /*-------- Table --------*/ | ||
224 | 78 | *[class=Table800] {width: 100% !important;} | ||
225 | 79 | *[class=Table799] {width: 90% !important;} | ||
226 | 80 | *[class=Table740] {width: 100% !important;} | ||
227 | 81 | *[class=Tds200] {width: 150px !important; padding-left:0 !important;} | ||
228 | 82 | *[class=Tds540] {width: 610px !important;} | ||
229 | 83 | |||
230 | 84 | /*----- Image -------*/ | ||
231 | 85 | *[class=Inbox] img{width: 50% !important; height: auto !important;} | ||
232 | 86 | |||
233 | 87 | /*----- Others -------*/ | ||
234 | 88 | *[class=Zwidth] {min-width:100% !important;} | ||
235 | 89 | *[class=MobileHide] {display:none !important;} | ||
236 | 90 | *[class=TextC] {text-align:center !important;} | ||
237 | 91 | } | ||
238 | 92 | |||
239 | 93 | @media only screen and (max-width: 479px){ | ||
240 | 94 | /*-------- Table --------*/ | ||
241 | 95 | *[class=Table800] {width: 100% !important; min-width:360px !important;} | ||
242 | 96 | *[class=Tds200] {width: 110px !important; padding-left:0 !important;} | ||
243 | 97 | *[class=Tds540] {width: 210px !important;} | ||
244 | 98 | |||
245 | 99 | /*----- Image -------*/ | ||
246 | 100 | *[class=Inbox] img{width: 50% !important; height: auto !important;} | ||
247 | 101 | |||
248 | 102 | /*----- Others -------*/ | ||
249 | 103 | *[class=Zwidth] {min-width:100% !important;} | ||
250 | 104 | *[class=MobileHide] {display:none !important;} | ||
251 | 105 | *[class=TextC] {text-align:center !important;} | ||
252 | 106 | *[class=Fonts48] {font-size:35.65px !important; line-height:48px !important;} | ||
253 | 107 | } | ||
254 | 108 | </style> | ||
255 | 109 | </head> | ||
256 | 110 | |||
257 | 111 | <body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"> | ||
258 | 112 | <table border="0" width="100%" cellpadding="0" cellspacing="0" bgcolor="#E1E1E1"> | ||
259 | 113 | <tr> | ||
260 | 114 | <td align="center" class="Zwidth" style="min-width:800px;"> | ||
261 | 115 | <div class="mktEditable" id="Header"> | ||
262 | 116 | <table align="center" width="800" border="0" cellspacing="0" cellpadding="0" bgcolor="#380426" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:800px;" class="Table800"> | ||
263 | 117 | <tr> | ||
264 | 118 | <td background="https://assets.ubuntu.com/v1/1d8ce799-email-hero-background.png?w=800" bgcolor="#380426" width="800" height="289" valign="top" style="background-image:url(https://assets.ubuntu.com/v1/1d8ce799-email-hero-background.png?w=800); background-position:top center; background-size:cover;"> | ||
265 | 119 | <!--[if gte mso 9]> | ||
266 | 120 | <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="width:800px;height:289px;"> | ||
267 | 121 | <v:fill type="tile" src="https://assets.ubuntu.com/v1/1d8ce799-email-hero-background.png?w=800" color="#7D335B" /> | ||
268 | 122 | <v:textbox inset="0,0,0,0"> | ||
269 | 123 | <![endif]--> | ||
270 | 124 | <div> | ||
271 | 125 | <table align="center" width="800" border="0" cellspacing="0" cellpadding="0" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:800px;" class="Table799"> | ||
272 | 126 | <tr> | ||
273 | 127 | <td align="center"> | ||
274 | 128 | <table align="center" width="740" border="0" cellspacing="0" cellpadding="0" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:740px;" class="Table740"> | ||
275 | 129 | <tr> | ||
276 | 130 | <td align="left" valign="bottom" style="padding: 65px 0 0;"> | ||
277 | 131 | <img height="55" width="120" src="https://assets.ubuntu.com/v1/d738f754-Ubuntu_One_Mono_Logo.svg" /> | ||
278 | 132 | </td> | ||
279 | 133 | </tr> | ||
280 | 134 | <tr> | ||
281 | 135 | <td align="left" valign="bottom" class="Fonts48" style="color:#FFFFFF; font-family: Arial, Sans Serif, Ubuntu; font-size:46.5667px; line-height:56px; font-weight:100; font-style:normal; padding:30px 0 50px 0;"> | ||
282 | 136 | {{ title }} | ||
283 | 137 | </td> | ||
284 | 138 | </tr> | ||
285 | 139 | </table> | ||
286 | 140 | </td> | ||
287 | 141 | </tr> | ||
288 | 142 | </table> | ||
289 | 143 | </div> | ||
290 | 144 | <!--[if gte mso 9]> | ||
291 | 145 | </v:textbox> | ||
292 | 146 | </v:rect> | ||
293 | 147 | <![endif]--> | ||
294 | 148 | </td> | ||
295 | 149 | </tr> | ||
296 | 150 | </table> | ||
297 | 151 | </div> | ||
298 | 152 | </td> | ||
299 | 153 | </tr> | ||
300 | 154 | |||
301 | 155 | <tr> | ||
302 | 156 | <td align="center" class="Zwidth" style="min-width:800px;"> | ||
303 | 157 | <div class="mktEditable" id="Primary_talking"> | ||
304 | 158 | <table align="center" width="800" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:800px;" class="Table800"> | ||
305 | 159 | <tr> | ||
306 | 160 | <td align="center" style="padding:54px 20px"> | ||
307 | 161 | <table align="center" width="740" border="0" cellspacing="0" cellpadding="0" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:740px;" class="Table740"> | ||
308 | 162 | <tr> | ||
309 | 163 | <td align="left" style="color:#0E0E0E; font-family: Arial, Sans Serif, Ubuntu; font-size:16px; line-height:24px; font-weight:300; font-style:normal; padding:16px 0 0 0"> | ||
310 | 164 | {{ content|linebreaks|urlize }} | ||
311 | 165 | </td> | ||
312 | 166 | </tr> | ||
313 | 167 | </table> | ||
314 | 168 | </td> | ||
315 | 169 | </tr> | ||
316 | 170 | </table> | ||
317 | 171 | </div> | ||
318 | 172 | </td> | ||
319 | 173 | </tr> | ||
320 | 174 | |||
321 | 175 | <tr> | ||
322 | 176 | <td align="center" class="Zwidth" style="min-width:800px;"> | ||
323 | 177 | <div class="mktEditable" id="Footer"> | ||
324 | 178 | <table align="center" width="800" cellpadding="0" bgcolor="#F7F7F7" border="0" cellspacing="0" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:800px;" class="Table800"> | ||
325 | 179 | <tr> | ||
326 | 180 | <td align="center" style="padding:40px 20px 0 20px;"> | ||
327 | 181 | <table align="center" width="740" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:740px;" class="Table740"> | ||
328 | 182 | <tr> | ||
329 | 183 | <td align="left"> | ||
330 | 184 | <table align="left" width="167" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:167px;" class="Table740"> | ||
331 | 185 | <tr> | ||
332 | 186 | <td align="center"> | ||
333 | 187 | <table align="center" width="167" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt;"> | ||
334 | 188 | <tr> | ||
335 | 189 | <td align="left" valign="middle" width="32"> | ||
336 | 190 | <a href="https://www.linkedin.com/company/ubuntu/" target="_blank"> <img src="https://assets.ubuntu.com/v1/885320bd-social-linkedin.png" width="32" height="32" border="0" style="display:block; width:32px; height:32px" alt="" /> </a> | ||
337 | 191 | </td> | ||
338 | 192 | <td align="left" valign="middle" width="13"> </td> | ||
339 | 193 | <td align="left" valign="middle" width="32"> | ||
340 | 194 | <a href="https://twitter.com/ubuntu" target="_blank"> <img src="https://assets.ubuntu.com/v1/28569fb0-social-twitter.png" width="32" height="32" border="0" style="display:block; width:32px; height:32px" alt="" /> </a> | ||
341 | 195 | </td> | ||
342 | 196 | <td align="left" valign="middle" width="13"> </td> | ||
343 | 197 | <td align="left" valign="middle" width="32"> | ||
344 | 198 | <a href="https://www.facebook.com/ubuntulinux/" target="_blank"> <img src="https://assets.ubuntu.com/v1/63b1275f-social-facebook.png" width="32" height="32" border="0" style="display:block; width:32px; height:32px" alt="" /> </a> | ||
345 | 199 | </td> | ||
346 | 200 | </tr> | ||
347 | 201 | </table> | ||
348 | 202 | </td> | ||
349 | 203 | </tr> | ||
350 | 204 | </table> | ||
351 | 205 | </td> | ||
352 | 206 | </tr> | ||
353 | 207 | <tr> | ||
354 | 208 | <td align="left" class="TextC" style="color:#000000; font-family: Arial, Sans Serif, Ubuntu; font-size:16px; line-height:24px; font-weight:300; font-style:normal; padding:20px 0 5px 0"> | ||
355 | 209 | <a style="color:#000000; text-decoration:none" href="http://www.canonical.com" target="_blank">www.canonical.com</a> | <a style="color:#000000; text-decoration:none" href="http://www.ubuntu.com" target="_blank">www.ubuntu.com</a> | ||
356 | 210 | </td> | ||
357 | 211 | </tr> | ||
358 | 212 | <tr> | ||
359 | 213 | <td align="left" class="TextC" style="color:#000000; font-family: Arial, Sans Serif, Ubuntu; font-size:14px; line-height:22px; font-weight:300; font-style:normal; padding:0 0 50px 0"> | ||
360 | 214 | © 2019 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd. | ||
361 | 215 | </td> | ||
362 | 216 | </tr> | ||
363 | 217 | </table> | ||
364 | 218 | </td> | ||
365 | 219 | </tr> | ||
366 | 220 | </table> | ||
367 | 221 | </div> | ||
368 | 222 | </td> | ||
369 | 223 | </tr> | ||
370 | 224 | |||
371 | 225 | <tr> | ||
372 | 226 | <td align="center" class="Zwidth" style="min-width:800px"> | ||
373 | 227 | <table align="center" width="800" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; width:800px;" class="Table800"> | ||
374 | 228 | <tr> | ||
375 | 229 | <td align="left" class="Inbox" valign="top" width="50%"> | ||
376 | 230 | <img src="https://assets.ubuntu.com/v1/99e75450-inbox.png" width="400" height="1" border="0" style="display:block; width:400px; height:1px;" alt="" /> | ||
377 | 231 | </td> | ||
378 | 232 | <td align="right" class="Inbox" valign="top" width="50%"> | ||
379 | 233 | <img src="https://assets.ubuntu.com/v1/99e75450-inbox.png" width="400" height="1" border="0" style="display:block; width:400px; height:1px;" alt="" /> | ||
380 | 234 | </td> | ||
381 | 235 | </tr> | ||
382 | 236 | </table> | ||
383 | 237 | </td> | ||
384 | 238 | </tr> | ||
385 | 239 | </table> | ||
386 | 240 | <div class="ZedFix" style="white-space:nowrap; font:15px courier; line-height:0;"> | ||
387 | 241 | | ||
388 | 242 | | ||
389 | 243 | | ||
390 | 244 | </div> | ||
391 | 245 | |||
392 | 246 | </body> | ||
393 | 247 | </html> |
Example email output: https:/ /pastebin. canonical. com/p/77QvsTF4B Y/