~sil/+junk/trublrweb

« back to all changes in this revision

Viewing changes to web/net.py

  • Committer: stuart.langridge at canonical
  • Date: 2012-10-30 15:50:55 UTC
  • Revision ID: stuart.langridge@canonical.com-20121030155055-5zp6lan222yzhzuu
firstĀ import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Network Utilities
 
3
(from web.py)
 
4
"""
 
5
 
 
6
__all__ = [
 
7
  "validipaddr", "validipport", "validip", "validaddr", 
 
8
  "urlquote",
 
9
  "httpdate", "parsehttpdate", 
 
10
  "htmlquote", "htmlunquote", "websafe",
 
11
]
 
12
 
 
13
import urllib, time
 
14
try: import datetime
 
15
except ImportError: pass
 
16
 
 
17
def validipaddr(address):
 
18
    """
 
19
    Returns True if `address` is a valid IPv4 address.
 
20
    
 
21
        >>> validipaddr('192.168.1.1')
 
22
        True
 
23
        >>> validipaddr('192.168.1.800')
 
24
        False
 
25
        >>> validipaddr('192.168.1')
 
26
        False
 
27
    """
 
28
    try:
 
29
        octets = address.split('.')
 
30
        if len(octets) != 4:
 
31
            return False
 
32
        for x in octets:
 
33
            if not (0 <= int(x) <= 255):
 
34
                return False
 
35
    except ValueError:
 
36
        return False
 
37
    return True
 
38
 
 
39
def validipport(port):
 
40
    """
 
41
    Returns True if `port` is a valid IPv4 port.
 
42
    
 
43
        >>> validipport('9000')
 
44
        True
 
45
        >>> validipport('foo')
 
46
        False
 
47
        >>> validipport('1000000')
 
48
        False
 
49
    """
 
50
    try:
 
51
        if not (0 <= int(port) <= 65535):
 
52
            return False
 
53
    except ValueError:
 
54
        return False
 
55
    return True
 
56
 
 
57
def validip(ip, defaultaddr="0.0.0.0", defaultport=8080):
 
58
    """Returns `(ip_address, port)` from string `ip_addr_port`"""
 
59
    addr = defaultaddr
 
60
    port = defaultport
 
61
    
 
62
    ip = ip.split(":", 1)
 
63
    if len(ip) == 1:
 
64
        if not ip[0]:
 
65
            pass
 
66
        elif validipaddr(ip[0]):
 
67
            addr = ip[0]
 
68
        elif validipport(ip[0]):
 
69
            port = int(ip[0])
 
70
        else:
 
71
            raise ValueError, ':'.join(ip) + ' is not a valid IP address/port'
 
72
    elif len(ip) == 2:
 
73
        addr, port = ip
 
74
        if not validipaddr(addr) and validipport(port):
 
75
            raise ValueError, ':'.join(ip) + ' is not a valid IP address/port'
 
76
        port = int(port)
 
77
    else:
 
78
        raise ValueError, ':'.join(ip) + ' is not a valid IP address/port'
 
79
    return (addr, port)
 
80
 
 
81
def validaddr(string_):
 
82
    """
 
83
    Returns either (ip_address, port) or "/path/to/socket" from string_
 
84
    
 
85
        >>> validaddr('/path/to/socket')
 
86
        '/path/to/socket'
 
87
        >>> validaddr('8000')
 
88
        ('0.0.0.0', 8000)
 
89
        >>> validaddr('127.0.0.1')
 
90
        ('127.0.0.1', 8080)
 
91
        >>> validaddr('127.0.0.1:8000')
 
92
        ('127.0.0.1', 8000)
 
93
        >>> validaddr('fff')
 
94
        Traceback (most recent call last):
 
95
            ...
 
96
        ValueError: fff is not a valid IP address/port
 
97
    """
 
98
    if '/' in string_:
 
99
        return string_
 
100
    else:
 
101
        return validip(string_)
 
102
 
 
103
def urlquote(val):
 
104
    """
 
105
    Quotes a string for use in a URL.
 
106
    
 
107
        >>> urlquote('://?f=1&j=1')
 
108
        '%3A//%3Ff%3D1%26j%3D1'
 
109
        >>> urlquote(None)
 
110
        ''
 
111
        >>> urlquote(u'\u203d')
 
112
        '%E2%80%BD'
 
113
    """
 
114
    if val is None: return ''
 
115
    if not isinstance(val, unicode): val = str(val)
 
116
    else: val = val.encode('utf-8')
 
117
    return urllib.quote(val)
 
118
 
 
119
def httpdate(date_obj):
 
120
    """
 
121
    Formats a datetime object for use in HTTP headers.
 
122
    
 
123
        >>> import datetime
 
124
        >>> httpdate(datetime.datetime(1970, 1, 1, 1, 1, 1))
 
125
        'Thu, 01 Jan 1970 01:01:01 GMT'
 
126
    """
 
127
    return date_obj.strftime("%a, %d %b %Y %H:%M:%S GMT")
 
128
 
 
129
def parsehttpdate(string_):
 
130
    """
 
131
    Parses an HTTP date into a datetime object.
 
132
 
 
133
        >>> parsehttpdate('Thu, 01 Jan 1970 01:01:01 GMT')
 
134
        datetime.datetime(1970, 1, 1, 1, 1, 1)
 
135
    """
 
136
    try:
 
137
        t = time.strptime(string_, "%a, %d %b %Y %H:%M:%S %Z")
 
138
    except ValueError:
 
139
        return None
 
140
    return datetime.datetime(*t[:6])
 
141
 
 
142
def htmlquote(text):
 
143
    """
 
144
    Encodes `text` for raw use in HTML.
 
145
    
 
146
        >>> htmlquote("<'&\\">")
 
147
        '&lt;&#39;&amp;&quot;&gt;'
 
148
    """
 
149
    text = text.replace("&", "&amp;") # Must be done first!
 
150
    text = text.replace("<", "&lt;")
 
151
    text = text.replace(">", "&gt;")
 
152
    text = text.replace("'", "&#39;")
 
153
    text = text.replace('"', "&quot;")
 
154
    return text
 
155
 
 
156
def htmlunquote(text):
 
157
    """
 
158
    Decodes `text` that's HTML quoted.
 
159
 
 
160
        >>> htmlunquote('&lt;&#39;&amp;&quot;&gt;')
 
161
        '<\\'&">'
 
162
    """
 
163
    text = text.replace("&quot;", '"')
 
164
    text = text.replace("&#39;", "'")
 
165
    text = text.replace("&gt;", ">")
 
166
    text = text.replace("&lt;", "<")
 
167
    text = text.replace("&amp;", "&") # Must be done last!
 
168
    return text
 
169
 
 
170
def websafe(val):
 
171
    """
 
172
    Converts `val` so that it's safe for use in UTF-8 HTML.
 
173
    
 
174
        >>> websafe("<'&\\">")
 
175
        '&lt;&#39;&amp;&quot;&gt;'
 
176
        >>> websafe(None)
 
177
        ''
 
178
        >>> websafe(u'\u203d')
 
179
        '\\xe2\\x80\\xbd'
 
180
    """
 
181
    if val is None:
 
182
        return ''
 
183
    if isinstance(val, unicode):
 
184
        val = val.encode('utf-8')
 
185
    val = str(val)
 
186
    return htmlquote(val)
 
187
 
 
188
if __name__ == "__main__":
 
189
    import doctest
 
190
    doctest.testmod()