<commit_before>import re
import string
from api import FancyValidator, _
from validators import Regex, Invalid, PostalCode

# @todo     utilize pycountry
from dbmanager.util.i18n import get_country, get_countries

class GermanPostalCode(Regex):

    """
    German Postal codes (aka Zip Codes).

    ::

        >>> GermanPostalCode.to_python('55555')
        '55555'
        >>> GermanPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a zip code (5 digits)
    """

    regex = r'^\d\d\d\d\d$'
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("5 digits"),
        }

class FourDigitsPostalCode(Regex):

    """
    Postal codes consisting of 4 digits.

    ::

        >>> FourDigitsPostalCode.to_python('5555')
        '5555'
        >>> FourDigitsPostalCode.to_python('56655')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a zip code (4 digits)
    """

    regex = r'^\d\d\d\d$'
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("4 digits"),
        }

class PolishPostalCode(Regex):

    """
    Polish Postal codes (aka Zip Codes).

    ::

        >>> PolishPostalCode.to_python('55555')
        '55-555'
        >>> PolishPostalCode.to_python('55-555')
        '55-555'
        >>> PolishPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a zip code (5 digits)
    """

    regex = re.compile(r'^(\d\d)\-?(\d\d\d)$')
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("5 digits"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return '%s-%s' % (match.group(1), match.group(2))

class ArgentinianPostalCode(Regex):

    """
    Argentinian Postal codes.

    ::

        >>> ArgentinianPostalCode.to_python('C1070AAM')
        'C1070AAM'
        >>> ArgentinianPostalCode.to_python('c 1070 aam')
        'C1070AAM'
        >>> ArgentinianPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a valid postal code (CNNNNCCC)
    """

    regex = re.compile(r'^([a-zA-Z]{1})\s*(\d{4})\s*([a-zA-Z]{3})$')
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("CNNNNCCC"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return '%s%s%s' % (match.group(1).upper(),
                           match.group(2),
                           match.group(3).upper())

class CanadianPostalCode(Regex):

    """
    Canadian Postal codes.

    ::

        >>> CanadianPostalCode.to_python('V3H 1Z7')
        'V3H 1Z7'
        >>> CanadianPostalCode.to_python('v3h1z7')
        'V3H 1Z7'
        >>> CanadianPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a valid postal code (CNC NCN)
    """

    regex = re.compile(r'^([a-zA-Z]\d[a-zA-Z])\s?(\d[a-zA-Z]\d)$')
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("CNC NCN"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return '%s %s' % (match.group(1).upper(), match.group(2).upper())

class UKPostalCode(Regex):

    """
    UK Postal codes. Please see BS 7666.

    ::

        >>> UKPostalCode.to_python('BFPO 3')
        'BFPO 3'
        >>> UKPostalCode.to_python('LE11 3GR')
        'LE11 3GR'
        >>> UKPostalCode.to_python('l1a 3gr')
        'L1A 3GR'
        >>> UKPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a valid postal code (for format see BS 7666)
    """

    regex = re.compile(r'^((ASCN|BBND|BIQQ|FIQQ|PCRN|SIQQ|STHL|TDCU|TKCA) 1ZZ|BFPO (c\/o )?[1-9]{1,4}|GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW]) [0-9][ABD-HJLNP-UW-Z]{2})$')
    strip = True

    messages = {
        'invalid': _("Please enter a valid postal code (for format see BS 7666)"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return match.group(1).upper()

class CountryValidator(FancyValidator):

    key_ok = True

    messages = {
        'valueNotFound': _("That country is not listed in ISO-3166"),
        }

    def _to_python(self, value, state):
        upval = value.upper()
        if self.key_ok:
            try:
                c = get_country(upval)
                return upval
            except:
                pass
        for k, v in get_countries():
            if v.upper() == upval:
                return k
        raise Invalid(self.message('valueNotFound', state), value, state)

    def _from_python(self, value, state):
        try:
            return get_country(value.upper())
        except KeyError:
            return value

class PostalCodeInCountryFormat(FancyValidator):
    """
    Makes sure the postal code is in the country's format.<commit_msg>doctests in addressing for trivial classes<commit_after>import re
import string
from api import FancyValidator, _
from validators import Regex, Invalid, PostalCode

# @todo     utilize pycountry or http://opencountrycodes.appspot.com/python/
from dbmanager.util.i18n import get_country, get_countries

class GermanPostalCode(Regex):

    """
    German Postal codes (aka Zip Codes).

    ::

        >>> GermanPostalCode.to_python('55555')
        '55555'
        >>> GermanPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a zip code (5 digits)
    """

    regex = r'^\d\d\d\d\d$'
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("5 digits"),
        }

class FourDigitsPostalCode(Regex):

    """
    Postal codes consisting of 4 digits.

    ::

        >>> FourDigitsPostalCode.to_python('5555')
        '5555'
        >>> FourDigitsPostalCode.to_python('56655')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a zip code (4 digits)
    """

    regex = r'^\d\d\d\d$'
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("4 digits"),
        }

class PolishPostalCode(Regex):

    """
    Polish Postal codes (aka Zip Codes).

    ::

        >>> PolishPostalCode.to_python('55555')
        '55-555'
        >>> PolishPostalCode.to_python('55-555')
        '55-555'
        >>> PolishPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a zip code (5 digits)
    """

    regex = re.compile(r'^(\d\d)\-?(\d\d\d)$')
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("5 digits"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return '%s-%s' % (match.group(1), match.group(2))

class ArgentinianPostalCode(Regex):

    """
    Argentinian Postal codes.

    ::

        >>> ArgentinianPostalCode.to_python('C1070AAM')
        'C1070AAM'
        >>> ArgentinianPostalCode.to_python('c 1070 aam')
        'C1070AAM'
        >>> ArgentinianPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a valid postal code (CNNNNCCC)
    """

    regex = re.compile(r'^([a-zA-Z]{1})\s*(\d{4})\s*([a-zA-Z]{3})$')
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("CNNNNCCC"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return '%s%s%s' % (match.group(1).upper(),
                           match.group(2),
                           match.group(3).upper())

class CanadianPostalCode(Regex):

    """
    Canadian Postal codes.

    ::

        >>> CanadianPostalCode.to_python('V3H 1Z7')
        'V3H 1Z7'
        >>> CanadianPostalCode.to_python('v3h1z7')
        'V3H 1Z7'
        >>> CanadianPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a valid postal code (CNC NCN)
    """

    regex = re.compile(r'^([a-zA-Z]\d[a-zA-Z])\s?(\d[a-zA-Z]\d)$')
    strip = True

    messages = {
        'invalid': _("Please enter a zip code (%s)") % _("CNC NCN"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return '%s %s' % (match.group(1).upper(), match.group(2).upper())

class UKPostalCode(Regex):

    """
    UK Postal codes. Please see BS 7666.

    ::

        >>> UKPostalCode.to_python('BFPO 3')
        'BFPO 3'
        >>> UKPostalCode.to_python('LE11 3GR')
        'LE11 3GR'
        >>> UKPostalCode.to_python('l1a 3gr')
        'L1A 3GR'
        >>> UKPostalCode.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a valid postal code (for format see BS 7666)
    """

    regex = re.compile(r'^((ASCN|BBND|BIQQ|FIQQ|PCRN|SIQQ|STHL|TDCU|TKCA) 1ZZ|BFPO (c\/o )?[1-9]{1,4}|GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW]) [0-9][ABD-HJLNP-UW-Z]{2})$')
    strip = True

    messages = {
        'invalid': _("Please enter a valid postal code (for format see BS 7666)"),
        }

    def _to_python(self, value, state):
        self.assert_string(value, state)
        match = self.regex.search(value)
        if not match:
            raise Invalid(
                self.message('invalid', state),
                value, state)
        return match.group(1).upper()

class CountryValidator(FancyValidator):
    """
    Will convert a country's name into its ISO-3166 abbreviation for unified
    storage in databases etc. and return a localized country name in the
    reverse step.

    @See http://www.iso.org/iso/country_codes/iso_3166_code_lists.htm

    ::

        >>> CountryValidator.to_python('Germany')
        'DE'
        >>> CountryValidator.to_python('Finland')
        'FR'
        >>> CountryValidator.to_python('UNITED STATES')
        'US'
        >>> CountryValidator.to_python('Krakovia')
        Traceback (most recent call last):
            ...
        Invalid: That country is not listed in ISO-3166
    """

    key_ok = True

    messages = {
        'valueNotFound': _("That country is not listed in ISO-3166"),
        }

    def _to_python(self, value, state):
        upval = value.upper()
        if self.key_ok:
            try:
                c = get_country(upval)
                return upval
            except:
                pass
        for k, v in get_countries():
            if v.upper() == upval:
                return k
        raise Invalid(self.message('valueNotFound', state), value, state)

    def _from_python(self, value, state):
        try:
            return get_country(value.upper())
        except KeyError:
            return value

class PostalCodeInCountryFormat(FancyValidator):
    """
    Makes sure the postal code is in the country's format.
{'fraction_non_alphanumeric': 0.14264978630755584, 'fraction_numerical': 0.0267720345133457, 'mean_word_length': 2.0145843461351483, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 117, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4116806', 'n_tokens_mistral': 4258, 'n_tokens_neox': 3894, 'n_words': 910}