Commits

dsm...@localhost  committed 2efdc8b

Supports writing to a configuration file.

  • Participants
  • Parent commits 607dddd

Comments (0)

Files changed (4)

File helptext/management/__init__.py

+#

File helptext/management/commands/__init__.py

+#

File helptext/management/commands/helptext_save.py

+from django.core.management.base import NoArgsCommand
+from helptext.models import FieldHelp
+
+class Command(NoArgsCommand):
+    help = (
+        'Loads the help text from the database and prints out a string which '
+        'can be saved to a configuration file. Help text will then be the '
+        'value from the database if there is one, followed by the value from '
+        'configuration if there is on, finally followed by the programmed '
+        'help text.\n\nFor example, you could call\n\n'
+        './manage.py helptext_save > helptext_configuration.py\n\nThen in '
+        'settings.py you need to point HELPTEXT_CONFIGURATION to the python '
+        'path of your configruation file by doing something like this:\n\n'
+        'HELPTEXT_CONFIGURATION = \'my_program.helptext_configuration\'')
+
+    def handle_noargs(self, **options):
+        to_save = {}
+        for help in FieldHelp.objects.all():
+            if help.help_text:
+                to_save[help.lookup_key()] = help.help_text
+        print "helptext_configuration = %s" % str(to_save)

File helptext/models.py

 from itertools import groupby
 
+from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ImproperlyConfigured
 from django.db import models
+from django.utils.importlib import import_module
 
 def register_app(app_label):
-    model_list=models.get_models(app_label)
+    model_list = models.get_models(app_label)
     register_model(*model_list)
 
 
 def _is_synced(*mods):
     from django.db import connection
-    all_tables=connection.introspection.table_names()
-    return set(connection.introspection.table_name_converter(x._meta.db_table) for x in mods).issubset(all_tables)
+    all_tables = connection.introspection.table_names()
+    converter = connection.introspection.table_name_converter
+    return set(converter(x._meta.db_table) for x in mods).issubset(all_tables)
+
 
 def register_model(*model_list):
     if not ContentType._meta.installed:
-        raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS "
-                                   "setting in order to use the helptext application.")
+        raise ImproperlyConfigured(
+            "Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting "
+            "in order to use the helptext application.")
 
     if not _is_synced(ContentType, FieldHelp):
         # syncdb not run yet -- return silently
         return
 
     for model in model_list:
-
         for mod, fields in groupby(model._meta.get_fields_with_model(),
                                    lambda x: x[1]):
             if mod is None:
-                mod=model
+                mod = model
             if not _is_synced(mod):
                 # probably not synced yet
                 continue
-            fields=[x[0] for x in fields]
+            fields = [x[0] for x in fields]
 
-            content_type=ContentType.objects.get_for_model(mod)
-            for field in (f for f in fields if f.editable and not f.auto_created):
-                fh=FieldHelp.objects.filter(content_type=content_type,
-                                            field_name=field.name)
+            content_type = ContentType.objects.get_for_model(mod)
+            can_help_text = lambda f: all((
+                f.editable,
+                not f.auto_created,
+                not isinstance(f.help_text, FieldHelpProxy),))
+            for field in (f for f in fields if can_help_text(f)):
+                fh = FieldHelp.objects.filter(content_type=content_type,
+                                              field_name=field.name)
                 if fh:
-                    assert len(fh)==1
-                    fh=fh[0]
+                    assert len(fh) == 1
+                    fh = fh[0]
+                    if fh.original_help_text != field.help_text:
+                        fh.original_help_text = field.help_text
+                        fh.save()
                 else:
-                    fh=FieldHelp(content_type=content_type,
-                                 field_name=field.name,
-                                 help_text=field.help_text,
-                                 original_help_text=field.help_text)
+                    fh = FieldHelp(content_type=content_type,
+                                   field_name=field.name,
+                                   help_text='',
+                                   original_help_text=field.help_text)
                     fh.save()
-                field.help_text=FieldHelpProxy(fh)
+                field.help_text = FieldHelpProxy(fh)
+
 
 class FieldHelpProxy(object):
     def __init__(self, fh):
-        self.content_type=fh.content_type
-        self.field_name=fh.field_name
+        self . content_type=fh.content_type
+        self . field_name=fh.field_name
 
     def __unicode__(self):
         try:
-            fh=FieldHelp.objects.get(content_type=self.content_type,
-                                     field_name=self.field_name)
+            fh = FieldHelp.objects.get(content_type=self.content_type,
+                                       field_name=self.field_name)
+            return fh.get_help_text()
         except FieldHelp.DoesNotExist:
             # shouldn't happen
             return ''
+
+
+_configuration = None
+def _get_configuration():
+    global _configuration
+    if None == _configuration:
+        if hasattr(settings, 'HELPTEXT_CONFIGURATION'):
+            path = settings.HELPTEXT_CONFIGURATION
+            try:
+                mod = import_module(path)
+            except ImportError, e:
+                str = 'Error importing helptext configuration %s: "%s"'
+                raise ImproperlyConfigured(str % (path, e))
+            try:
+                helptext_configuration = mod.helptext_configuration
+            except AttributeError:
+                str = ("%s should contain a dictionary called "
+                       "helptext_configuration.")
+                raise ImproperlyConfigured(str % path)
+            if not isinstance(helptext_configuration, dict):
+                str = "%s.helptext_configuration should be a dictionary."
+                raise ImproperlyConfigured(str % path)
+            _configuration = helptext_configuration
         else:
-            return fh.help_text 
+            _configuration = False
+    return _configuration
+
 
 class FieldHelp(models.Model):
-    content_type=models.ForeignKey(ContentType)
-    field_name=models.CharField(max_length=120)
-    help_text=models.TextField(blank=True)
-    original_help_text=models.TextField(blank=True)
+    content_type = models.ForeignKey(ContentType)
+    field_name = models.CharField(max_length=120)
+    help_text = models.TextField(blank=True)
+    original_help_text = models.TextField(blank=True)
+
+    def get_help_text(self):
+        configured = self.get_configured_help_text()
+        return self.help_text or configured or self.original_help_text
+
+    def get_configured_help_text(self):
+        helptext_configuration = _get_configuration()
+        if _configuration:
+            return helptext_configuration.get(self.lookup_key(), "")
+        return ""
 
     @property
     def model(self):
         return self.content_type.model_class()
-    
+
     @property
     def field(self):
         return self.model._meta.get_field(self.field_name)
 
-
     def app_title(self):
         return self.model._meta.app_label.title()
-    app_title.short_description='Application'
-
+    app_title.short_description = 'Application'
 
     def model_title(self):
         return self.model._meta.verbose_name.title()
-    model_title.short_description='Model'
-
+    model_title.short_description = 'Model'
 
     def field_title(self):
         return self.field.verbose_name.title()
-    field_title.short_description='Field'
+    field_title.short_description = 'Field'
+
+    def lookup_key(self):
+        args = (self.app_title(), self.model_title(), self.field_title(),)
+        return "%s.%s.%s" % args
 
     class Meta:
-        ordering=('content_type', 'field_name')
-        unique_together=(('content_type', 'field_name'),)
-        verbose_name_plural="Field Help"
+        ordering = ('content_type', 'field_name')
+        unique_together = (('content_type', 'field_name'),)
+        verbose_name_plural = "Field Help"
 
     def __repr__(self):
         return '<FieldHelp for %r: %r>' % \
         return u"%s - %s: %s" % (self.model._meta.app_label.title(),
                                  self.model._meta.verbose_name.title(),
                                  self.field.verbose_name.title())
-    
 
     def delete(self):
-        self.field.help_text=self.original_help_text
+        self.field.help_text = self.original_help_text
         super(FieldHelp, self).delete()