import re from django.db.models import EmailField field_replacers = { 'AutoField': '"SKIP"', 'ForeignKey': '"SKIP"', 'ManyToManyField': '"SKIP"', 'OneToOneField': '"SKIP"', 'SlugField': '"SKIP"', # we probably don't want to change slugs 'DateField': '"date"', 'DateTimeField': '"datetime"', 'BooleanField': '"bool"', 'NullBooleanField': '"bool"', 'IntegerField': '"integer"', 'SmallIntegerField': '"small_integer"', 'PositiveIntegerField': '"positive_integer"', 'PositiveSmallIntegerField': '"positive_small_integer"', 'DecimalField': '"decimal"', } # NB - order matters. 'address' is more generic so should be at the end. charfield_replacers = [ (r'(\b|_)full_name\d*', '"name"'), (r'(\b|_)first_name\d*', '"first_name"'), (r'(\b|_)last_name\d*', '"last_name"'), (r'(\b|_)user_name\d*', '"username"'), (r'(\b|_)username\d*', '"username"'), (r'(\b|_)name\d*', '"name"'), (r'(\b|_)email\d*', '"email"'), (r'(\b|_)town\d*', '"city"'), (r'(\b|_)city\d*', '"city"'), (r'(\b|_)zip\d*', '"zip_code"'), (r'(\b|_)zipcode\d*', '"zip_code"'), (r'(\b|_)zip_code\d*', '"zip_code"'), (r'(\b|_)telephone\d*', '"phonenumber"'), (r'(\b|_)phone\d*', '"phonenumber"'), (r'(\b|_)mobile\d*', '"phonenumber"'), (r'(\b|_)tel\d*\b', '"phonenumber"'), (r'(\b|_)state\d*\b', '"state"'), (r'(\b|_)address\d*', '"full_address"'), ] def get_replacer_for_field(field): # Some obvious ones: if isinstance(field, EmailField): return '"email"' # Use choices, if available. choices = getattr(field, 'choices', None) if choices is not None and len(choices) > 0: return '"choice"' field_type = field.get_internal_type() if field_type == "CharField" or field_type == "TextField": # Guess by the name # First, go for complete match for pattern, result in charfield_replacers: if re.match(pattern + "$", field.attname): return result # Then, go for a partial match. for pattern, result in charfield_replacers: if re.search(pattern, field.attname): return result # Nothing matched. if field_type == "TextField": return '"lorem"' # Just try some random chars return '"varchar"' try: r = field_replacers[field_type] except KeyError: r = "UNKNOWN_FIELD" return r attribute_template = " ('%(attname)s', %(replacer)s)," class_template = """ class %(modelname)sAnonymizer(Anonymizer): model = %(modelname)s attributes = [ %(attributes)s ] """ def create_anonymizer(model): attributes = [] for f in model._meta.fields: replacer = get_replacer_for_field(f) attributes.append(attribute_template % {'attname': f.attname, 'replacer': replacer}) return class_template % {'modelname': model.__name__, 'attributes': "\n".join(attributes)} def create_anonymizers_module(app_config): model_names = [] imports = [] output = [] output.append("") imports.append("from anonymizer import Anonymizer") for model in app_config.models.values(): model_names.append(model.__name__) output.append(create_anonymizer(model)) imports.insert(0, "from %s import %s" % (app_config.models_module.__name__, ", ".join(model_names))) return "\n".join(imports) + "\n".join(output)