import re
from django import forms as forms
from django.utils.translation import ugettext_lazy as _

email_re = re.compile(
    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    r')$', re.IGNORECASE)
class LocalPartEmailField(forms.EmailField):

    default_error_messages = {
        'invalid': _(u'Enter a valid e-mail local_part.'),
    }

    def __init__(self, max_length=None, min_length=None, *args, **kwargs):
        forms.RegexField.__init__(self, email_re, max_length, min_length, *args,
                            **kwargs)

class SeparatedValuesField(forms.Field):
    """
    A Django newforms field which takes another newforms field during
    initialization and validates every item in a separated list with
    this field class. Please use it like this::

        from django.newforms import EmailField
        emails = SeparatedValuesField(EmailField)

    You would be able to enter a string like "john@doe.com,guido@python.org"
    because every email address would be validated when clean() is executed.
    This of course also applies to any other Field class.

    You can define the sepator (default: ",") during initialization with the
    ``separator`` parameter like this::

        from django.newforms import EmailField
        emails = SeparatedValuesField(EmailField, separator="###")

    If validation succeeds it returns the original data, though the already
    splitted value list can be accessed with the get_list() method.

    >>> f = SeparatedValuesField(forms.EmailField)
    >>> f.clean("foo@bar.com,bar@foo.com")
    'foo@bar.com,bar@foo.com'
    >>> f.get_list()
    ['foo@bar.com', 'bar@foo.com']
    >>> f.clean("foobar,foo@bar.com,bar@foo.com")
    Traceback (most recent call last):
        ...
    ValidationError: <unprintable ValidationError object>
    >>> u = SeparatedValuesField(forms.URLField)
    >>> u.clean("http://foo.bar.com,http://foobar.com")
    'http://foo.bar.com,http://foobar.com'
    >>> u.clean("http:foo.bar.com")
    Traceback (most recent call last):
        ...
    ValidationError: <unprintable ValidationError object>
    >>> f = SeparatedValuesField(forms.EmailField, separator="###")
    >>> f.clean("foo@bar.com###bar@foo.com")
    'foo@bar.com###bar@foo.com'
    >>> f.clean("foobar###foo@bar.com###bar@foo.com")
    Traceback (most recent call last):
        ...
    ValidationError: <unprintable ValidationError object>

    """
    def __init__(self, base_field=None, separator=",", strip=False, *args, **kwargs):
        super(SeparatedValuesField, self).__init__(*args, **kwargs)
        self.base_field = base_field
        self.separator = separator
        self.strip = strip

    def clean(self, data):
        if not data:
            if self.required:
                raise forms.ValidationError('Enter at least one value.')
            else:
                return None
        self.value_list = data.split(self.separator)
        if self.base_field is not None:
            base_field = self.base_field()
            for value in self.value_list:
                if self.strip:
                    value = value.strip()
                base_field.clean(value)
        return data

    def get_list(self):
        return self.value_list

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()


