Tag pro odkazy na poslání mailu #22
Merged
ledoian
merged 7 commits from maillink
into master
2 years ago
5 changed files with 121 additions and 4 deletions
@ -0,0 +1,48 @@ |
|||||
|
from django import template |
||||
|
from django.utils.safestring import mark_safe |
||||
|
from urllib.request import quote as urlencode |
||||
|
register = template.Library() |
||||
|
|
||||
|
@register.simple_tag |
||||
|
def mailurl(*, subject=None, body=None, to=[], cc=[], bcc=[]): |
||||
|
"""Tag na vytváření správně zakódované mailto: adresy |
||||
|
|
||||
|
Ref: RFC 6068, <https://en.wikipedia.org/wiki/Mailto>""" |
||||
|
if isinstance(to, str): |
||||
|
to = [to] |
||||
|
if isinstance(cc, str): |
||||
|
cc = [cc] |
||||
|
if isinstance(bcc, str): |
||||
|
bcc = [bcc] |
||||
|
assert isinstance(to, list) |
||||
|
assert isinstance(cc, list) |
||||
|
assert isinstance(bcc, list) |
||||
|
# FIXME: adresa není správně zakódovaná, rozbije se to na adresách s divnými znaky |
||||
|
parts = [ |
||||
|
f'mailto:{str.join(",", to)}', |
||||
|
] |
||||
|
if len(to) + len(cc) + len(bcc) < 1: |
||||
|
raise ValueError('Cannot mail to empty set of people') |
||||
|
|
||||
|
if subject: |
||||
|
parts.append(f'subject={urlencode(subject)}') |
||||
|
if body: |
||||
|
parts.append(f'body={urlencode(body)}') |
||||
|
if len(cc) > 0: |
||||
|
parts.append(f'cc={str.join(",", cc)}') |
||||
|
if len(bcc) > 0: |
||||
|
parts.append(f'bcc={str.join(",", bcc)}') |
||||
|
|
||||
|
if len(parts) > 1: |
||||
|
url = parts[0] + '?' + str.join('&', parts[1:]) |
||||
|
else: |
||||
|
url = parts[0] |
||||
|
return url |
||||
|
|
||||
|
@register.simple_tag |
||||
|
def maillink(text, subject=None, body=None, to=[], cc=[], bcc=[], attrs=None): |
||||
|
url = mailurl(subject=subject, body=body, to=to, cc=cc, bcc=bcc) |
||||
|
if not attrs: attrs = '' |
||||
|
mezera = ' '*bool(attrs) |
||||
|
full_link = f'<a href="{url}"{mezera}{attrs}>{text}</a>' |
||||
|
return mark_safe(full_link) |
@ -1,3 +1,60 @@ |
|||||
from django.test import TestCase |
from django.test import TestCase |
||||
|
# TODO: Možná vyrobit separátní soubory v tests/… než mít všechny testy v jednom souboru? |
||||
|
from various.templatetags.mail import maillink, mailurl |
||||
|
|
||||
# Create your tests here. |
class MailTagsTest(TestCase): |
||||
|
"""Testuje template tagy ohledně mailů.""" |
||||
|
def test_maillink(self): |
||||
|
# Tohle nedává smysl dělit do víc funkcí, bylo by v nich víc boilerplatu než užitečného kódu. |
||||
|
self.assertEquals(maillink('Hello', to='some@body.test'), r'<a href="mailto:some@body.test">Hello</a>') |
||||
|
self.assertEquals(maillink('Hello', to=['some@body.test']), r'<a href="mailto:some@body.test">Hello</a>') |
||||
|
self.assertEquals( |
||||
|
maillink('Hello', to=['alice@test.test', 'bob@jinde.test']), |
||||
|
r'<a href="mailto:alice@test.test,bob@jinde.test">Hello</a>', |
||||
|
) |
||||
|
self.assertEquals( |
||||
|
maillink('Hello', to='some@body.test', attrs='class="trida" id="id"'), |
||||
|
r'<a href="mailto:some@body.test" class="trida" id="id">Hello</a>', |
||||
|
) |
||||
|
# Následující test toho testuje moc zároveň, měly by předcházet dedikované testy… (kašlu na ně :-P) |
||||
|
self.assertEquals( |
||||
|
maillink('Text odkazu', to='prijemce@wtf.test', subject="Předmět", body="Čau"), |
||||
|
r'<a href="mailto:prijemce@wtf.test?subject=P%C5%99edm%C4%9Bt&body=%C4%8Cau">Text odkazu</a>', |
||||
|
) |
||||
|
self.assertRaises(ValueError, lambda: maillink('Nemám příjemce')) |
||||
|
self.assertRaises(TypeError, lambda: maillink()) # Nemá text, takže to shodí python |
||||
|
|
||||
|
def test_mailurl(self): |
||||
|
self.assertEquals(mailurl(to='some@body.test'), r'mailto:some@body.test') |
||||
|
self.assertEquals(mailurl(to=['some@body.test']), r'mailto:some@body.test') |
||||
|
self.assertEquals(mailurl(to=['alice@test.test', 'bob@jinde.test']), r'mailto:alice@test.test,bob@jinde.test') |
||||
|
self.assertEquals( |
||||
|
mailurl(to='some@body.test', body='Tělo', subject='Předmět'), |
||||
|
r'mailto:some@body.test?subject=P%C5%99edm%C4%9Bt&body=T%C4%9Blo', |
||||
|
) |
||||
|
self.assertRaises(ValueError, lambda: mailurl()) |
||||
|
|
||||
|
def test_render_in_template(self): |
||||
|
# Pomocná funkce: vykreslí template do stringu |
||||
|
# Ref: https://stackoverflow.com/a/1690879 |
||||
|
def render_template(template, context=None): |
||||
|
from django.template import Template, Context |
||||
|
context = context or {} |
||||
|
context = Context(context) |
||||
|
return Template(template).render(context) |
||||
|
|
||||
|
template = ( |
||||
|
r'{% load mail %}' |
||||
|
# TODO: Vyzkoušet i víc adresátů. (Nepamatuji si z hlavy syntaxi…) |
||||
|
r'{% maillink "Text" to="alice@test.test" subject="Oprava řešení" %}' |
||||
|
) |
||||
|
self.assertEquals( |
||||
|
render_template(template), |
||||
|
r'<a href="mailto:alice@test.test?subject=Oprava%20%C5%99e%C5%A1en%C3%AD">Text</a>', |
||||
|
) |
||||
|
|
||||
|
mailurltemplate = ( |
||||
|
r'{% load mail %}' |
||||
|
r'{% mailurl to="alice@test.test" subject="Čau Alice" %}' |
||||
|
) |
||||
|
self.assertEquals(render_template(mailurltemplate), r'mailto:alice@test.test?subject=%C4%8Cau%20Alice') |
||||
|
Loading…
Reference in new issue