323
318
""", re.VERBOSE) # ' <- font-lock turd
326
def obfuscate_email(text_to_obfuscate, replacement=None):
321
def obfuscate_email(text_to_obfuscate):
327
322
"""Obfuscate an email address.
329
The email address is obfuscated as <email address hidden> by default,
330
or with the given replacement.
324
The email address is obfuscated as <email address hidden>.
332
326
The pattern used to identify an email address is not 2822. It strives
333
327
to match any possible email address embedded in the text. For example,
334
328
mailto:person@domain.dom and http://person:password@domain.dom both
335
329
match, though the http match is in fact not an email address.
337
if replacement is None:
338
replacement = '<email address hidden>'
339
331
text = re_email_address.sub(
340
replacement, text_to_obfuscate)
341
# Avoid doubled angle brackets.
332
r'<email address hidden>', text_to_obfuscate)
342
333
text = text.replace(
343
334
"<<email address hidden>>", "<email address hidden>")
347
def save_bz2_pickle(obj, filename):
348
"""Save a bz2 compressed pickle of `obj` to `filename`."""
349
fout = bz2.BZ2File(filename, "w")
351
pickle.dump(obj, fout, pickle.HIGHEST_PROTOCOL)
356
def load_bz2_pickle(filename):
357
"""Load and return a bz2 compressed pickle from `filename`."""
358
fin = bz2.BZ2File(filename, "r")
360
return pickle.load(fin)
365
def obfuscate_structure(o):
366
"""Obfuscate the strings of a json-serializable structure.
368
Note: tuples are converted to lists because json encoders do not
369
distinguish between lists and tuples.
371
:param o: Any json-serializable object.
372
:return: a possibly-new structure in which all strings, list and tuple
373
elements, and dict keys and values have undergone obfuscate_email
376
if isinstance(o, basestring):
377
return obfuscate_email(o)
378
elif isinstance(o, (list, tuple)):
379
return [obfuscate_structure(value) for value in o]
380
elif isinstance(o, (dict)):
382
(obfuscate_structure(key), obfuscate_structure(value))
383
for key, value in o.iteritems())