Package brisa :: Package core :: Module network
[hide private]
[frames] | no frames]

Source Code for Module brisa.core.network

  1  # Licensed under the MIT license 
  2  # http://opensource.org/licenses/mit-license.php or see LICENSE file. 
  3  # Copyright 2007-2008 Brisa Team <brisa-develop@garage.maemo.org> 
  4   
  5  """ Network related functions, such as get_ip_address(), http_call(), 
  6  parse_url() and others. 
  7  """ 
  8   
  9  import urllib2 
 10  import httplib 
 11  import shutil 
 12  import socket 
 13  import fcntl 
 14  from time import time, sleep 
 15  from struct import pack 
 16  from urlparse import urlparse 
 17  from xml.etree import ElementTree 
 18   
 19  import brisa 
 20  from brisa.core import log 
 21   
 22  socket.setdefaulttimeout(15) 
 23   
 24   
25 -def get_ip_address(ifname):
26 """ Determine the IP address given the interface name 27 28 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/439094 29 (c) Paul Cannon 30 Uses the Linux SIOCGIFADDR ioctl to find the IP address associated 31 with a network interface, given the name of that interface, e.g. "eth0". 32 The address is returned as a string containing a dotted quad. 33 34 @param ifname: interface name 35 @type ifname: string 36 37 @return: ip address in the interface specified 38 @rtype: string 39 """ 40 try: 41 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 42 ip = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, 43 pack('256s', 44 str(ifname[:15])))[20:24]) 45 return ip 46 except: 47 return socket.gethostbyname(socket.gethostname())
48 49
50 -def get_active_ifaces():
51 """ Return a list of the active network interfaces 52 53 Default route of /proc/net/route has the destination field set to 00000000 54 55 56 @return: active network interfaces 57 @rtype: list 58 """ 59 try: 60 rd = open('/proc/net/route').readlines() 61 except (IOError, OSError): 62 return [] 63 net = [line.split('\t')[0:2] for line in rd] 64 return [v[0] for v in net if v[1] == '00000000']
65 66
67 -def http_call(method, url, body='', headers={}):
68 """ Returns a HTTPResponse object for the given call. 69 70 @param method: HTTP method (NOTIFY, POST, etc...) 71 @param url: receiver URL 72 @param body: body of the message 73 @param headers: additional headers 74 75 @type method: string 76 @type url: string 77 @type body: string 78 @type headers: dictionary 79 """ 80 parsed_url = urlparse(url) 81 u = parsed_url[1] 82 83 (host, ip, port) = ('', '', 80) 84 85 if ':' in u: 86 # host:port 87 u = u.split(':') 88 89 host = u[0] 90 if len(u) == 2: 91 port = int(u[1]) 92 93 if host: 94 ip = socket.gethostbyname(host) 95 else: 96 log.debug('error: host is empty') 97 98 log.debug('http call (host, port, ip): (%s, %d, %s)' % \ 99 (host, port, str(ip))) 100 101 con = httplib.HTTPConnection("%s:%d" % (ip, port)) 102 con.connect() 103 104 if body or headers: 105 con.request(method, parsed_url[2], body=body, headers=headers) 106 else: 107 return None 108 109 return con.getresponse()
110 111
112 -def url_fetch(url, filename='', attempts=0, interval=0):
113 """ Fetches an URL into a file or returns a file descriptor. If attempts 114 and interval are not specified, they get their values from 115 brisa.url_fetch_attempts and brisa.url_fetch_attempts_interval. 116 117 @param url: URL to be fetched 118 @param filename: if specified fetch result gets written on this path 119 @param attempts: number of attempts 120 @param interval: interval between attempts in seconds 121 122 @type url: string 123 @type filename: string 124 @type attempts: integer 125 @type interval: float 126 """ 127 if not attempts: 128 attempts = brisa.url_fetch_attempts 129 if not interval: 130 interval = brisa.url_fetch_attempts_interval 131 132 handle = None 133 last_exception = None 134 for k in range(attempts): 135 log.debug('Fetching %r (attempt %d)' % (url, k)) 136 req = urllib2.Request(url) 137 try: 138 handle = urllib2.urlopen(req) 139 except IOError, e: 140 if hasattr(e, 'reason'): 141 log.warning('Attempt %d: failed to reach a server. Reason: %s'% 142 (k, e.reason)) 143 elif hasattr(e, 'code'): 144 log.warning('Attempt %d: the server couldn\'t fulfill the '\ 145 'request. Error code: %s' % (k, e.code)) 146 handle = None 147 last_exception = e 148 finally: 149 if handle != None: 150 if not filename: 151 # Return mode 152 log.debug('url %r fetched successfully' % url) 153 return handle 154 else: 155 log.debug('writing data to filename %s' % filename) 156 # Writing mode 157 shutil.copyfile(handle, open(filename, 'w')) 158 return None 159 sleep(interval) 160 161 if last_exception: 162 raise last_exception 163 else: 164 return None
165 166
167 -def decode(text):
168 """ Converts an arbitrary string to byte string in UTF-8. On failure 169 returns the given string. 170 171 @param text: string to be converted 172 @type text: string 173 """ 174 175 if type(text) is unicode: 176 return text.encode("utf-8") 177 178 encoding_lst = [("iso-8859-15", ), ("utf-8", ), ("latin-1", ), 179 ("utf-8", "replace")] 180 for encoding in encoding_lst: 181 try: 182 return text.decode(*encoding).encode("utf-8") 183 except: 184 return text
185 186
187 -def parse_xml(data):
188 """ Parses XML data into an ElementTree. 189 190 @param data: raw XML data 191 @type data: string 192 193 @rtype: ElementTree 194 """ 195 p = ElementTree.XMLParser() 196 p.feed(decode(data)) 197 return ElementTree.ElementTree(p.close())
198 199
200 -def parse_http_response(data):
201 """ Parses HTTP response data into a tuple in the form (cmd, headers). 202 203 @param data: HTTP response data 204 @type data: string 205 206 @return: (cmd, headers) for the given data 207 @rtype: tuple 208 """ 209 header, payload = data.split('\r\n\r\n') 210 lines = header.split('\r\n') 211 cmd = lines[0].split(' ') 212 lines = map(lambda x: x.replace(': ', ':', 1), lines[1:]) 213 lines = filter(lambda x: len(x) > 0, lines) 214 headers = [x.split(':', 1) for x in lines] 215 headers = dict(map(lambda x: (x[0].lower(), x[1]), headers)) 216 217 return cmd, headers
218 219
220 -def parse_url(url):
221 """ Parse a URL into 6 components. 222 223 @param url: scheme://netloc/path;params?query#fragment 224 @type url: string 225 226 @return: a 6-tuple: (scheme, netloc, path, params, query, fragment). Note 227 that we don't break the components up in smaller bits (e.g. netloc is a 228 single string) and we don't expand % escapes. 229 @rtype: tuple 230 """ 231 return urlparse(url)
232