Brad Montgomery avatar Brad Montgomery committed ea01117 Draft

pep8 and minor refactoring

Comments (0)

Files changed (9)

 from django.contrib import admin
-from forms import FieldSanitizerAdminForm
-from models import FieldSanitizer
+
+from .forms import FieldSanitizerAdminForm
+from .models import FieldSanitizer
+
 
 class FieldSanitizerAdmin(admin.ModelAdmin):
-    list_display = ('content_type', 'app_name', 'model_name', 'field_name', ) 
+    list_display = ('content_type', 'app_name', 'model_name', 'field_name', )
     form = FieldSanitizerAdminForm
+
 admin.site.register(FieldSanitizer, FieldSanitizerAdmin)
 from django.contrib.contenttypes.models import ContentType
 from django.forms import ModelChoiceField, ModelForm
-from models import FieldSanitizer
+
+from .models import FieldSanitizer
+
 
 class ContentTypeChoiceFieldWithAppLabel(ModelChoiceField):
-    """
-    A ModelChoiceField for ContentTypes that displays the 
-    app_label in addition to the name. 
+    """A ModelChoiceField for ContentTypes that displays the app_label in
+    addition to the name.
     """
     def label_from_instance(self, obj):
-        return "%s/%s" % (obj.app_label, obj.name)
+        return u"{0}/{1}".format(obj.app_label, obj.name)
+
 
 class FieldSanitizerAdminForm(ModelForm):
-    content_type = ContentTypeChoiceFieldWithAppLabel(ContentType.objects.all().order_by('app_label', 'model'))
+    content_type = ContentTypeChoiceFieldWithAppLabel(
+        ContentType.objects.all().order_by('app_label', 'model')
+    )
+
     class Meta:
         model = FieldSanitizer

janitor/management/commands/clean_all.py

 """
 Management utility to clean Models that are registered with a FieldSanitizer.
 """
-
 from django.core.management.base import NoArgsCommand
 from janitor.models import FieldSanitizer, _clean_class_objects
 
+
 class Command(NoArgsCommand):
 
     help = "Cleans all Models that have a related FieldSanitizer"
     def __init__(self, *args, **kwargs):
         super(Command, self).__init__(*args, **kwargs)
 
-        # BaseCommand doesn't have stdout included in Django < 1.2 
+        # BaseCommand doesn't have stdout included in Django < 1.2
         # So, let's add it in if it's not already there.
         if not hasattr(self, 'stdout'):
             from sys import stdout
             self.stdout = stdout
- 
+
     def handle_noargs(self, **options):
-        klass_list = [fs.content_type.model_class() for fs in FieldSanitizer.objects.all()]
+        sanitizers = FieldSanitizer.objects.all()
+        klass_list = [fs.content_type.model_class() for fs in sanitizers]
         object_count = _clean_class_objects(klass_list)
 
-        self.stdout.write("\nCleaned %s Objects\n" % object_count)
+        self.stdout.write("\nCleaned {0} Objects\n".format(object_count))

janitor/management/commands/clean_model.py

 """
-Management utility to clean a specific Model that is registered with a FieldSanitizer.
+Management utility to clean a specific Model that is registered with a
+FieldSanitizer.
 """
-from optparse import make_option
 from django.core.management.base import CommandError, LabelCommand
 from janitor.models import FieldSanitizer, _clean_class_objects
 
+
 class Command(LabelCommand):
 
     help = "Cleans fields for a specified Model"
     label = 'application name.model name'
 
     can_import_settings = False
-   
+
     def __init__(self, *args, **kwargs):
         super(Command, self).__init__(*args, **kwargs)
-       
-        # BaseCommand doesn't have stdout included in Django < 1.2 
+
+        # BaseCommand doesn't have stdout included in Django < 1.2
         # So, let's add it in if it's not already there.
         if not hasattr(self, 'stdout'):
             from sys import stdout
         try:
             app_label, model = label.lower().split('.')
         except ValueError:
-            raise CommandError("Invalid app_label.model_name: %s" % label)
+            raise CommandError(
+                "Invalid app_label.model_name: {0}".format(label)
+            )
 
-        self.stdout.write("\nCleaning %s.%s\n" % (app_label, model))
+        self.stdout.write("\nCleaning {0}.{1}\n".format(app_label, model))
 
-        qs = FieldSanitizer.objects.filter(content_type__app_label=app_label, content_type__model=model)
+        qs = FieldSanitizer.objects.filter(
+            content_type__app_label=app_label,
+            content_type__model=model
+        )
         try:
             assert qs.count() > 0
         except AssertionError:
-            raise CommandError("It looks like there are no FieldSanitizers defined for %s.%s" % (app_label, model)) 
+            raise CommandError("It looks like there are no FieldSanitizers "
+                "defined for {0}.{1}".format(app_label, model)
+            )
 
         klass_list = [fs.content_type.model_class() for fs in qs]
         object_count = _clean_class_objects(klass_list)
 
-        self.stdout.write("Cleaned %s Objects\n" % object_count)
+        self.stdout.write("Cleaned {0} Objects\n".format(object_count))

janitor/management/commands/list_html_elements.py

 """
 
 from django.core.management.base import NoArgsCommand
-from janitor.models import FieldSanitizer, _clean_class_objects, _get_tags_used_in_content
+from janitor.models import _get_tags_used_in_content
+
 
 class Command(NoArgsCommand):
 
-    help = "Lists HTML elements used in all Models that have a related FieldSanitizer"
+    help = ("Lists HTML elements used in all Models that have a"
+            "related FieldSanitizer")
 
     def __init__(self, *args, **kwargs):
         super(Command, self).__init__(*args, **kwargs)
 
-        # BaseCommand doesn't have stdout included in Django < 1.2 
+        # BaseCommand doesn't have stdout included in Django < 1.2
         # So, let's add it in if it's not already there.
         if not hasattr(self, 'stdout'):
             from sys import stdout
             self.stdout = stdout
- 
+
+    def _tag_output(self, tag_list):
+        p = "- {0}\n"
+        return ''.join(p.format(t) for t in tag_list)
+
     def handle_noargs(self, **options):
         tag_list = _get_tags_used_in_content()
-        self.stdout.write("\nTags used in content:\n\n    %s\n\n" % '\n    '.join(tag_list))
+        self.stdout.write(
+            "\nTags used in content:\n{0}\n".format(self._tag_output(tag_list))
+        )

janitor/management/commands/list_html_elements_for_model.py

+"""Management utility to clean a specific Model that is registered with a
+FieldSanitizer.
 """
-Management utility to clean a specific Model that is registered with a FieldSanitizer.
-"""
-from optparse import make_option
 from django.core.management.base import CommandError, LabelCommand
-from janitor.models import FieldSanitizer, _clean_class_objects, _get_tags_used_in_content
+from janitor.models import _get_tags_used_in_content
+
 
 class Command(LabelCommand):
 
     label = 'application name.model name'
 
     can_import_settings = False
-   
+
     def __init__(self, *args, **kwargs):
         super(Command, self).__init__(*args, **kwargs)
-       
-        # BaseCommand doesn't have stdout included in Django < 1.2 
+
+        # BaseCommand doesn't have stdout included in Django < 1.2
         # So, let's add it in if it's not already there.
         if not hasattr(self, 'stdout'):
             from sys import stdout
             self.stdout = stdout
 
+    def _tag_output(self, tag_list):
+        p = "- {0}\n"
+        return ''.join(p.format(t) for t in tag_list)
+
     def handle_label(self, label, **options):
         try:
             app_label, model = label.lower().split('.')
         except ValueError:
-            raise CommandError("Invalid app_label.model_name: %s" % label)
-        
+            raise CommandError(
+                "Invalid app_label.model_name: {0}".format(label)
+            )
+
         tag_list = _get_tags_used_in_content(app_label, model)
-        self.stdout.write("\nTags used in content:\n\n    %s\n\n" % '\n    '.join(tag_list))
+        self.stdout.write(
+            "\nTags used in content:\n{0}\n".format(self._tag_output(tag_list))
+        )

janitor/models.py

 from django.contrib.contenttypes.models import ContentType
+from django.db import DatabaseError
 from django.db import models
+from django.db import transaction
 from django.db.models.signals import pre_save
-from django.db import DatabaseError
-from django.db import transaction
 
-from bleach import clean 
+from bleach import clean
 from html5lib import html5parser
 from janitor import whitelists
 
+
 def _register(callback, content_type_list):
+    """Connects the ``callback`` function to each content type in the
+    ``content_type_list`` with the ``pre_save``."""
     for ct in content_type_list:
-        pre_save.connect(callback, sender=ct.model_class(), dispatch_uid=ct.model)
+        pre_save.connect(
+            callback,
+            sender=ct.model_class(),
+            dispatch_uid=ct.model
+        )
+
 
 def _j(some_list):
+    """Shortcut for ``', '.join(some_list)``."""
     return ', '.join(some_list)
 
+
 class FieldSanitizer(models.Model):
     content_type = models.ForeignKey(ContentType)
-    field_name = models.CharField(max_length=255, help_text="The name of a field in the selected Model. It probably should be a TextField or some sublcass of TextField.")
-    tags = models.TextField(blank=True, default=_j(whitelists.basic_content_tags), help_text="A comma-separated whitelist of HTML tags that are allowed in the selected field")
-    attributes = models.TextField(blank=True, default=_j(whitelists.attributes), help_text="A comma-separated whitelist of attributes that are allowed in the selected field")
-    styles = models.TextField(blank=True, help_text="A comma-separated whitelist of allowed CSS properties within a style attribute. NOTE: For this to work, 'style' must be in the list of attributes.")
-    strip = models.BooleanField(default=False, help_text="Strip disallowed HTML instead of escaping it.")
-    strip_comments = models.BooleanField(default=True, help_text="Strip HTML comments.")
+    field_name = models.CharField(max_length=255,
+        help_text="The name of a field in the selected Model. It probably "
+                  "should be a TextField or some sublcass of TextField.")
+    tags = models.TextField(blank=True,
+        default=_j(whitelists.basic_content_tags),
+        help_text="A comma-separated whitelist of HTML tags that are allowed "
+                  "in the selected field")
+    attributes = models.TextField(blank=True,
+        default=_j(whitelists.attributes),
+        help_text="A comma-separated whitelist of attributes that are "
+                  "allowed in the selected field")
+    styles = models.TextField(blank=True,
+        help_text="A comma-separated whitelist of allowed CSS properties "
+                  "within a style attribute. NOTE: For this to work, 'style' "
+                  "must be in the list of attributes.")
+    strip = models.BooleanField(default=False,
+        help_text="Strip disallowed HTML instead of escaping it.")
+    strip_comments = models.BooleanField(default=True,
+        help_text="Strip HTML comments.")
 
     def __unicode__(self):
         return u"%s - %s" % (self.content_type, self.field_name)
 
     @property
     def app_name(self):
-        """ return the name of the App to which this sanitizer is associated """
+        """The name of the App to which this sanitizer is associated"""
         return self.content_type.app_label
-    
+
     @property
     def model_name(self):
-        """ return the name of the Model to which this sanitizer is associated """
+        """The name of the Model to which this sanitizer is associated """
         return self.content_type.model
 
     def save(self, *args, **kwargs):
+        """Checks to see that ``field_name`` is an attribute of the selected
+        Model, then registers the signal handler with the appropriate model.
         """
-        Checks to see that ``field_name`` is an attribute of the selected Model,
-        then registers the signal handler with the appropriate model.
-        """
-        assert self._field_name_in_model(), "The field_name '%s' does not exist in the model '%s'" % (self.field_name, self.content_type.model)
+        msg = u"The field_name '{0}' does not exist in the model '{1}'".format(
+            self.field_name,
+            self.content_type.model
+        )
+        assert self._field_name_in_model(), msg
         super(FieldSanitizer, self).save(*args, **kwargs)
-        _register(sanitize_fields, [self.content_type]) 
+        _register(sanitize_fields, [self.content_type])
 
     def _field_name_in_model(self):
         m = self.content_type.model_class()
         return self.field_name in [f.name for f in m._meta.fields]
 
+    def _split(self, text, delimiter=","):
+        """Split text by delimiter and and filter out empty values."""
+        items = [i.strip() for i in text.split(delimiter)]
+        items.filter(lambda i: len(i) > 0, items)  # remove blanks
+        return items
+
     def get_tags_list(self):
-        return [tag.strip() for tag in self.tags.split(',') if len(tag.strip()) > 0]
+        return self._split(self.tags)
 
     def get_attributes_list(self):
-        return [attr.strip() for attr in self.attributes.split(',') if len(attr.strip()) > 0]
+        return self._split(self.attributes)
 
     def get_styles_list(self):
-        return [s.strip() for s in self.styles.split(',') if len(s.strip()) > 0]
+        return self._split(self.styles)
 
     def get_bleach_clean_args(self):
-        """ Return a dict appropriate for passing into ``bleach.clean`` """
-        return {'tags': self.get_tags_list(),
-                'attributes':self.get_attributes_list(),
-                'styles':self.get_styles_list(),
-                'strip':self.strip,
-                'strip_comments':self.strip_comments }
+        """Return a dict appropriate for passing into ``bleach.clean``."""
+        return {
+            'tags': self.get_tags_list(),
+            'attributes': self.get_attributes_list(),
+            'styles': self.get_styles_list(),
+            'strip': self.strip,
+            'strip_comments': self.strip_comments
+        }
+
 
 def sanitize_fields(sender, **kwargs):
-    """
-    The signal handler for a FieldSanitizer
+    """The signal handler for a FieldSanitizer
 
-    ``sender`` - the model class
-    ``instance`` - an instance of the sender
+    * ``sender`` - the model class
+    * ``instance`` - an instance of the sender
 
     """
     sender_content_type = ContentType.objects.get_for_model(sender)
     sender_instance = kwargs['instance']
-     
-    for sanitizer in FieldSanitizer.objects.filter(content_type=sender_content_type):
+
+    sanitizers = FieldSanitizer.objects.filter(
+        content_type=sender_content_type)
+    for sanitizer in sanitizers:
         if hasattr(sender_instance, sanitizer.field_name):
-            field_content = getattr(sender_instance, sanitizer.field_name)
+            field_content = getattr(
+                sender_instance,
+                sanitizer.field_name
+            )
             # Clean with bleach!
-            field_content = clean(field_content, **sanitizer.get_bleach_clean_args())
+            field_content = clean(field_content,
+                **sanitizer.get_bleach_clean_args())
             setattr(sender_instance, sanitizer.field_name, field_content)
 
+
 def _clean_class_objects(klass_list):
-    """
-    Cleans the content for all classes in the provided list.
+    """Cleans the content for all classes in the provided list.
     This is done by forcing each instance of the class to
     invoke it's ``save`` method.
 
     object_count = 0
     for klass in klass_list:
         for object in klass.objects.all():
-            object.save() 
+            object.save()
             object_count += 1
-    
+
     return object_count
 
+
 def _get_tags_used_in_content(app_label=None, model=None):
     """
     Use html5lib's parser to get a list of HTML tags used in content
     associated with a FieldSanitizer.
 
     This can be useful when determining what to include in a whitelist,
-    and is used in the ``list_html_elements`` and ``list_html_elements_for_model``
-    management commands.
+    and is used in the ``list_html_elements`` and
+    ``list_html_elements_for_model`` management commands.
 
     """
     queryset = FieldSanitizer.objects.all()
     if app_label and model:
-        queryset = queryset.filter(content_type__app_label=app_label, content_type__model=model)
+        queryset = queryset.filter(content_type__app_label=app_label,
+            content_type__model=model)
 
     tag_list = []
 
     for fs in queryset:
         model_class = fs.content_type.model_class()
-        content_list = model_class.objects.values_list(fs.field_name, flat=True)
+        content_list = model_class.objects.values_list(
+            fs.field_name,
+            flat=True
+        )
 
         for content in content_list:
             doc = html5parser.parse(content)
             tag_list.extend([str(tag.name) for tag in doc if tag.name])
 
-    tag_list = list(set(tag_list)) # remove duplicates
+    tag_list = list(set(tag_list))  # remove duplicates
     tag_list.sort()
     return tag_list
 
+
 @transaction.commit_manually
 def register_everything():
     """
     This function attempts to register all ``FieldSanitizer`` instances
-    with the ``sanitize_fields`` callback. 
+    with the ``sanitize_fields`` callback.
 
-    When you initially install this app and run ``syncdb``, the model 
+    When you initially install this app and run ``syncdb``, the model
     doesn't exist in the database. This raises a ``DatabaseError`` exception,
     and in some DBMSs (PostgreSQL) ``syncdb`` will refuse to continute if a
-    transaction did not get commited successfully. Hence the reason for all 
+    transaction did not get commited successfully. Hence the reason for all
     transaction managment stuff.
     """
     transaction.commit()
     try:
-        _content_type_ids = FieldSanitizer.objects.values_list('content_type').distinct()
-        _content_types = [ct for ct in ContentType.objects.filter(id__in=_content_type_ids)]
+        _content_type_ids = FieldSanitizer.objects.values_list('content_type')
+        _content_type_ids = _content_type_ids.distinct()
+        _content_types = [
+            ct for ct in ContentType.objects.filter(id__in=_content_type_ids)
+        ]
         _register(sanitize_fields, _content_types)
     except DatabaseError:
         transaction.rollback()
     else:
         transaction.commit()
-register_everything() # try to register the signal callbacks when this file is loaded
+register_everything()  # register the signal callbacks

janitor/whitelists.py

 """
-This module contains various lists of HTML tags that 
+This module contains various lists of HTML tags that
 can be used as a  whitelist for Bleach.
 
 """
-structure_tags = ['div', 'span', ]
-basic_content_tags = ['a','abbr', 'acronym', 'blockquote', 'cite', 'code', 'dd', 'del', 'dfn', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'img', 'ins', 'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'strong', 'ul', ]
-table_tags = ['caption','col', 'colgroup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', ]
-form_tags = ['button', 'fieldset', 'form', 'input', 'label', 'legend', 'optgroup', 'option', 'select', 'textarea', ]
-script_tags = ['script', 'noscript', ]
+structure_tags = ['div', 'span']
+basic_content_tags = [
+    'a', 'abbr', 'acronym', 'blockquote', 'cite', 'code', 'dd', 'del', 'dfn',
+    'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'img', 'ins',
+    'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'strong', 'ul',
+]
+table_tags = [
+    'caption', 'col', 'colgroup', 'table', 'tbody', 'td', 'tfoot', 'th',
+    'thead', 'tr',
+]
+form_tags = [
+    'button', 'fieldset', 'form', 'input', 'label', 'legend', 'optgroup',
+    'option', 'select', 'textarea',
+]
+script_tags = ['script', 'noscript']
 
 # The Whole Shebang, as listed at http://htmldog.com/reference/htmltags/
-the_whole_shebang = ['a','abbr', 'acronym', 'address', 'area', 'b', 'base', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'caption', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'div', 'dl', 'DOCTYPE', 'dt', 'em', 'fieldset', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html', 'hr', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link', 'map', 'meta', 'noscript', 'object', 'ol', 'optgroup', 'option', 'p', 'param', 'pre', 'q', 'samp', 'script', 'select', 'small', 'span', 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', ]
+the_whole_shebang = [
+    'a', 'abbr', 'acronym', 'address', 'area', 'b', 'base', 'bdo', 'big',
+    'blockquote', 'body', 'br', 'button', 'caption', 'cite', 'code', 'col',
+    'colgroup', 'dd', 'del', 'dfn', 'div', 'dl', 'DOCTYPE', 'dt', 'em',
+    'fieldset', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html',
+    'hr', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link',
+    'map', 'meta', 'noscript', 'object', 'ol', 'optgroup', 'option', 'p',
+    'param', 'pre', 'q', 'samp', 'script', 'select', 'small', 'span', 'strong',
+    'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th',
+    'thead', 'title', 'tr', 'tt', 'ul', 'var',
+]
 
 # A very small whitelist of HTML Attributes
-attributes = ['alt', 'class', 'href', 'id', 'src', 'title',]
+attributes = ['alt', 'class', 'href', 'id', 'src', 'title']
 from setuptools import setup
 from janitor import __version__
 
+short_desc = (
+    "django-janitor allows you to use bleach to clean HTML stored in a "
+    "Model's field."
+)
+
 setup(
     name='django-janitor',
     version=__version__,
-    description="django-janitor allows you to use bleach to clean HTML stored in a Model's field.",
+    description=short_desc,
     long_description=open('README.rst').read(),
     author='Brad Montgomery',
     author_email='brad@bradmontgomery.net',
     license='BSD',
     packages=['janitor'],
     include_package_data=True,
-    package_data = { '': ['README.rst'] },
+    package_data={'': ['README.rst']},
     zip_safe=False,
     install_requires=['django', 'bleach'],
     classifiers=[
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.