Skip to content

Commit

Permalink
Added host name schema field to z3c.schema
Browse files Browse the repository at this point in the history
  • Loading branch information
projekt01 committed Nov 24, 2006
1 parent b3215c9 commit 67af1a6
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/z3c/schema/hostname/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
========
Hostname
========

Let's first create the hostname field:

>>> from z3c.schema.hostname import HostName
>>> hostname = HostName()

Let's first check the validation of some common hostnames. Hostnames can be
either domain or IP addresses.

>>> hostname.validate("www.python.org")
>>> hostname.validate("123.123.123.123")

A port specification is also allowed:

>>> hostname.validate("www.python.org:389")

However, the protocol is not permitted:

>>> hostname.validate("http://www.python.org")
Traceback (most recent call last):
...
InvalidHostName: http://www.python.org

>>> hostname.validate("ldap://www.python.org/foo")
Traceback (most recent call last):
...
InvalidHostName: ldap://www.python.org/foo

Let's check some other invalid forms:

>>> hostname.validate("$www.python.org")
Traceback (most recent call last):
...
InvalidHostName: $www.python.org

>>> hostname.validate("333.123.123.123")
Traceback (most recent call last):
...
InvalidHostName: 333.123.123.123

Let's also ensure that we can convert to hostnames from unicode:

>>> hostname.fromUnicode("www.python.org:389")
'www.python.org:389'
>>> hostname.fromUnicode(" www.python.org:389")
'www.python.org:389'
>>> hostname.fromUnicode(" \n www.python.org:389\n")
'www.python.org:389'

>>> hostname.fromUnicode("www.pyt hon.org:389")
Traceback (most recent call last):
...
InvalidHostName: www.pyt hon.org:389
20 changes: 20 additions & 0 deletions src/z3c/schema/hostname/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id$
"""

from z3c.schema.hostname.interfaces import *
from z3c.schema.hostname.field import isValidHostName
from z3c.schema.hostname.field import HostName
57 changes: 57 additions & 0 deletions src/z3c/schema/hostname/field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
###############################################################################
#
# Copyright 2006 by refline (Schweiz) AG, CH-5630 Muri
#
###############################################################################
"""Special Fields
$Id$
"""
__docformat__ = "reStructuredText"

import re

import zope.interface
import zope.schema
import zope.schema.interfaces

from z3c.schema.hostname import interfaces


isValidHostName = re.compile(

# BEGIN: host
r"([a-zA-Z]+([a-zA-Z\d\-]*[a-zA-Z\d])*"
r"(\.[a-zA-Z\d]+([a-zA-Z\d\-]*[a-zA-Z\d])*)*"
# END: host

# or
r"|"

# BEGIN: IP
r"([1-9][\d]{0,1}|1[\d]{0,2}|2[0-5]{0,2})"
r"(\.([\d]{1,2}|1[\d]{0,2}|2[0-5]{0,2})){3})"
# END: IP

# port
r"(:[\d]{1,5})?$"
).match


class HostName(zope.schema.URI):
"""HostName schema field.
This is a IP Address or a host name.
"""

zope.interface.implements(interfaces.IHostName)

def _validate(self, value):
if isValidHostName(value):
return
raise interfaces.InvalidHostName, value

def fromUnicode(self, value):
v = str(value.strip())
self.validate(v)
return v
31 changes: 31 additions & 0 deletions src/z3c/schema/hostname/interfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id$
"""
__docformat__ = "reStructuredText"

import zope.schema
import zope.schema.interfaces

from z3c.i18n import MessageFactory as _


class IHostName(zope.schema.interfaces.IURI,
zope.schema.interfaces.IFromUnicode):
"""Host name field."""


class InvalidHostName(zope.schema.ValidationError):
__doc__ = _("""The specified HostName is not valid.""")
61 changes: 61 additions & 0 deletions src/z3c/schema/hostname/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
###############################################################################
#
# Copyright 2006 by refline (Schweiz) AG, CH-5630 Muri
#
###############################################################################
"""Refline Recruiter Tests
$Id$
"""
__docformat__ = 'restructuredtext'

import unittest
from zope.schema.interfaces import RequiredMissing
from zope.schema.tests.test_field import FieldTestBase
from zope.testing import doctest
from zope.testing.doctestunit import DocFileSuite

from z3c.schema.hostname import HostName
from z3c.schema.hostname import InvalidHostName


class HostNameTest(FieldTestBase):

_Field_Factory = HostName
_convert = str

def testValidate(self):
field = self._Field_Factory(title=u'HostName field', description=u'',
readonly=False, required=False)
field.validate(None)
field.validate(self._convert('host'))
field.validate(self._convert('123.123.123.123'))
field.validate(self._convert('host:123'))
field.validate(self._convert('www.host.com:123'))
field.validate(self._convert('123.123.123.123:123'))

def testValidateRequired(self):
field = self._Field_Factory(title=u'HostName field', description=u'',
readonly=False, required=True)
field.validate(self._convert('host'))
self.assertRaises(RequiredMissing, field.validate, None)

def testBadStringType(self):
field = self._Field_Factory(title=u'HostName field')
self.assertRaises(InvalidHostName, field.validate, u'123.123')

def test_newlines(self):
field = self._Field_Factory(title=u'HostName field')
self.assertRaises(InvalidHostName, field.validate,
self._convert('host\nfoo'))


def test_suite():
return unittest.TestSuite((
DocFileSuite('README.txt',
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,),
unittest.makeSuite(HostNameTest),
))

if __name__ == '__main__':
unittest.main(defaultTest='test_suite')

0 comments on commit 67af1a6

Please sign in to comment.