294
297
"""Return a timezone-aware timestamp for the current time."""
295
298
return datetime.now(tz=pytz.UTC)
301
# This is a regular expression that matches email address embedded in
302
# text. It is not RFC 2821 compliant, nor does it need to be. This
303
# expression strives to identify probable email addresses so that they
304
# can be obfuscated when viewed by unauthenticated users. See
305
# http://www.email-unlimited.com/stuff/email_address_validator.htm
307
# localnames do not have [&?%!@<>,;:`|{}()#*^~ ] in practice
308
# (regardless of RFC 2821) because they conflict with other systems.
309
# See https://lists.ubuntu.com
310
# /mailman/private/launchpad-reviews/2007-June/006081.html
312
# This verson of the re is more than 5x faster that the orginal
313
# version used in ftest/test_tales.testObfuscateEmail.
314
re_email_address = re.compile(r"""
315
\b[a-zA-Z0-9._/="'+-]{1,64}@ # The localname.
316
[a-zA-Z][a-zA-Z0-9-]{1,63} # The hostname.
317
\.[a-zA-Z0-9.-]{1,251}\b # Dot starts one or more domains.
318
""", re.VERBOSE) # ' <- font-lock turd
321
def obfuscate_email(text_to_obfuscate):
322
"""Obfuscate an email address.
324
The email address is obfuscated as <email address hidden>.
326
The pattern used to identify an email address is not 2822. It strives
327
to match any possible email address embedded in the text. For example,
328
mailto:person@domain.dom and http://person:password@domain.dom both
329
match, though the http match is in fact not an email address.
331
text = re_email_address.sub(
332
r'<email address hidden>', text_to_obfuscate)
334
"<<email address hidden>>", "<email address hidden>")