How can I obfuscate email addresses contained in 'free input' text fields in Django
Asked Answered
C

3

6

In my models I often use text fields that are intended to contain large pieces of textile-formatted input. I'd like to automatically obfuscate any email addresses that are entered into these text fields, so that when they're printed in a template they're not visible to spiders.

Is there a smart way to do this?

Update:

Based on lazerscience's answer below, this was the code i ended up using. I named the file encode_mailto.py, and put it in a templatetags directory, inside a 'utilities' type app that i install into most of my django projects.

import re
import random
from django.utils.safestring import mark_safe
from django import template
register = template.Library()

email_link_pat = re.compile(r'<a\s+href=("|\')?mailto:[^>]+>[^<]*</a>')
email_pat = re.compile(r'\b[-.\w]+@[-.\w]+\.[a-z]{2,4}\b')

def get_script(m):
    code_list = []
    for c in m.group(0):
        d = ord(c)
        x = random.randint(0, d)
        code_list.append("%d+%d" % (x, d-x))

    return '<script type="text/javascript">document.write(String.fromCharCode(%s))</script>' % \
        ",".join(code_list)

def encode_mailto(text):
    text = email_link_pat.sub(get_script, text)
    text = email_pat.sub(get_script, text)
    return mark_safe(text)

register.filter('encode_mailto', encode_mailto)</pre>

Then use it in templates as follows:

{% load encode_mailto %}
{{"A bunch of text with an email address [email protected]"|encode_mailto }}
Christianachristiane answered 19/5, 2010 at 9:19 Comment(0)
H
2

If you just want to use it as Template tag filter:

import re
import random
from django.utils.safestring import mark_safe


email_link_pat = re.compile(r'<a\s+href=("|\')?mailto:[^>]+>[^<]*</a>')
email_pat = re.compile(r'\b[-.\w]+@[-.\w]+\.[a-z]{2,4}\b')

def get_script(m):
    code_list = []
    for c in m.group(0):
        d = ord(c)
        x = random.randint(0, d)
        code_list.append("%d+%d" % (x, d-x))

    return '<script type="text/javascript">document.write(String.fromCharCode(%s))</script>' % \
        ",".join(code_list)

@register.filter
def encode_mailto(text):
    text = email_link_pat.sub(get_script, text)
    text = email_pat.sub(get_script, text)
    return mark_safe(text)

Then you can use it in your templates eg:

{{ "<a href='mailto:[email protected]'>Send Mail</a>"|encode_mailto }}
Hakluyt answered 19/5, 2010 at 11:26 Comment(1)
Perfect, thanks. I updated my question with a description of how i got this approach working in my project.Christianachristiane
A
2

Here's something that can be used.

Trick is to add a email obfuscation code that will make your email addresses hard to be captured using a non-js client.

Add it as a middlware, or rather as a simpletag that can act on objects containing textile data.

Avoidance answered 19/5, 2010 at 9:49 Comment(0)
H
2

If you just want to use it as Template tag filter:

import re
import random
from django.utils.safestring import mark_safe


email_link_pat = re.compile(r'<a\s+href=("|\')?mailto:[^>]+>[^<]*</a>')
email_pat = re.compile(r'\b[-.\w]+@[-.\w]+\.[a-z]{2,4}\b')

def get_script(m):
    code_list = []
    for c in m.group(0):
        d = ord(c)
        x = random.randint(0, d)
        code_list.append("%d+%d" % (x, d-x))

    return '<script type="text/javascript">document.write(String.fromCharCode(%s))</script>' % \
        ",".join(code_list)

@register.filter
def encode_mailto(text):
    text = email_link_pat.sub(get_script, text)
    text = email_pat.sub(get_script, text)
    return mark_safe(text)

Then you can use it in your templates eg:

{{ "<a href='mailto:[email protected]'>Send Mail</a>"|encode_mailto }}
Hakluyt answered 19/5, 2010 at 11:26 Comment(1)
Perfect, thanks. I updated my question with a description of how i got this approach working in my project.Christianachristiane
H
0

You can use django-email-obfuscator. First, install it:

$ pip install django-email-obfuscator

Then, add email_obfuscator to INSTALLED_APPS in settings.py:

INSTALLED_APPS = (
    # ...
    'email_obfuscator',
)

In your templates, you can protect email addresses with the obfuscate filter:

{% load email_obfuscator %}
{{ '[email protected]'|obfuscate }}
Hangnail answered 9/12, 2015 at 23:59 Comment(1)
as far as I see, django-email-obfuscator can only obfuscate plain email adresses, no block of (html) text...?!Vogue

© 2022 - 2024 — McMap. All rights reserved.