dready avatar dready committed 6dd37c0

enable multiple email addresses in notify field

Comments (0)

Files changed (4)

src/factory/admin.py

 from django.contrib import admin
+from .forms import FabfileRecipeForm
 from factory.models import FabfileRecipe, Build
 
 class FabfileRecipeAdmin(admin.ModelAdmin):
     prepopulated_fields = {"slug": ("name",)}
+    form = FabfileRecipeForm
     
 class BuildAdmin(admin.ModelAdmin):
     list_display = ('name', 'task', 'executed', 'success')

src/factory/forms.py

 from django.forms.models import ModelForm
+from django import forms
+from .widgets import SeparatedValuesTextInput
+from factory.models import Build, FabfileRecipe
 
-from factory.models import Build, FabfileRecipe
+
+class JoinableList(list):
+    def __init__(self, seq=[], separator=','):
+        super(JoinableList, self).__init__(seq)
+        self.separator = separator
+
+    def __unicode__(self):
+        return ','.join(self)
+
+
+
+# Inspired from snippet: http://www.djangosnippets.org/snippets/497/
+class SeparatedValuesField(forms.Field):
+    def __init__(self, base_field=None, separator=",", strip=True, discard_duplicates=False, *args, **kwargs):
+        super(SeparatedValuesField, self).__init__(*args, **kwargs)
+        self.base_field = base_field
+        self.separator = separator
+        self.strip = strip
+        self.discard_duplicates = discard_duplicates
+
+
+    def to_python(self, data):
+        
+        raw_value_list = data.split(self.separator)
+        result_value_list = JoinableList(separator=self.separator)
+        for value in raw_value_list:
+            if self.strip:
+                value = value.strip()
+            if value != u'':
+                if not (self.discard_duplicates and value in result_value_list):
+                    result_value_list.append(value)
+
+        return result_value_list
+
+
+    def validate(self, value):
+        if self.base_field is not None:
+            base_field = self.base_field()
+            for v in value:
+                self.base_field().clean(v)
+
+
+    """
+    def clean(self, data):
+        value = self.to_python(data)
+        self.validate(value)
+        self.run_validators(value)
+        return data
+    """
+
+
+
+
+
+
+
+
+tests = r"""
+
+########################
+# SeparatedValuesField #
+########################
+
+>>> from custom_django_utils.forms import SeparatedValuesField
+>>> from django import forms
+
+
+>>> f = SeparatedValuesField(base_field=forms.EmailField)
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter at least one value.']
+
+>>> f.clean(',,')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter at least one value.']
+
+>>> f.clean('12345')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid e-mail address.']
+
+>>> f.clean('test@example.com,12345')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid e-mail address.']
+
+>>> f.clean('test@example.com,test2@example.com')
+['test@example.com', 'test2@example.com']
+
+# With spaces
+>>> f.clean('  test@example.com,    test2@example.com   , test3@example.com  ')
+['test@example.com', 'test2@example.com', 'test3@example.com']
+
+# Duplicates
+>>> f = SeparatedValuesField(base_field=forms.EmailField)
+>>> f.clean('test@example.com,test2@example.com,test@example.com')
+['test@example.com', 'test2@example.com', 'test@example.com']
+>>> f = SeparatedValuesField(base_field=forms.EmailField, discard_duplicates=True)
+>>> f.clean('test@example.com,test2@example.com,test@example.com')
+['test@example.com', 'test2@example.com']
+
+"""
+
 
 class BuildForm(ModelForm):
     class Meta:
         model = Build
-        exclude = ('fabfile_recipe',) 
+        exclude = ('fabfile_recipe',) 
+
+
+class FabfileRecipeForm(ModelForm):
+    notify = SeparatedValuesField(base_field=forms.EmailField,
+                                  help_text='Comma-separated email addresses of people to notify of build results')
+    class Meta:
+        model = FabfileRecipe
+

src/factory/models.py

 import logging
 from cStringIO import StringIO
 
-
-
 from django.db import models
 from django.conf import settings
 from factory.storage import FileSystemStorageUuidName
 from factory import signals
 from datetime import datetime
 
+
 # Create your models here.
 class FabfileRecipe(models.Model):
     name = models.CharField(max_length=255)
     slug = models.SlugField()
-    notify = models.EmailField(blank=True)
+    notify = models.CharField(max_length=255, blank=True,
+                              help_text='Comma-separated email addresses of people to notify of build results')
     schedule = models.BooleanField() # or a charfield that lets you specify a job ID that matches the cronjob that will call schedule.py
     file = models.FileField(upload_to='factory/fabfiles')
 

src/factory/signals.py

                error=instance.error)
 
     try:
+        recipients = [v.strip() for v in instance.fabfile_recipe.notify.split(',')]
         send_mail(subject, msg, settings.SERVER_EMAIL,
-                  [instance.fabfile_recipe.notify], fail_silently=False)
+                  recipients, fail_silently=False)
     except:
         if settings.DEBUG:
             raise
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.