home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / util / net.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  34.4 KB  |  1,301 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. import sys
  6. import traceback
  7. import re
  8. import struct
  9. import logging
  10. import random
  11. import socks
  12. import socket
  13. import asynchat
  14. import urllib
  15. import urllib2
  16. import urlparse
  17. import httplib
  18. import httplib2
  19. import cookielib
  20. from httplib import HTTPConnection
  21. from httplib import NotConnected
  22. import primitives
  23. import proxy_settings
  24. from Events import EventMixin
  25. from callbacks import callsback
  26.  
  27. try:
  28.     sentinel
  29. except NameError:
  30.     
  31.     class Sentinel(object):
  32.         
  33.         def __repr__(self):
  34.             return '<Sentinel (%r backup) %#x>' % (__file__, id(self))
  35.  
  36.  
  37.     sentinel = Sentinel()
  38.  
  39. log = logging.getLogger('util.net')
  40. default_chunksize = 4096
  41.  
  42. def get_ips_s(hostname = ''):
  43.     if not hostname:
  44.         pass
  45.     return socket.gethostbyname_ex(socket.gethostname())[2]
  46.  
  47.  
  48. def get_ips(hostname = ''):
  49.     return [ socket.inet_aton(ip) for ip in get_ips_s(hostname) ]
  50.  
  51. myips = get_ips
  52.  
  53. def myip():
  54.     return myips()[0]
  55.  
  56.  
  57. def ip_from_bytes(bytes):
  58.     return socket.inet_ntoa(bytes)
  59.  
  60.  
  61. class FileChunker:
  62.     
  63.     def __init__(self, fileobj, chunksize = default_chunksize, close_when_done = False, progress_cb = (lambda bytes: pass), bytecounter = None):
  64.         self.fileobj = fileobj
  65.         self.chunksize = chunksize
  66.         self.close_when_done = close_when_done
  67.         if bytecounter is None:
  68.             bytecounter = fileobj.tell
  69.         
  70.         self.total = bytecounter()
  71.         self.progress_cb = progress_cb
  72.         self.cancelled = False
  73.  
  74.     
  75.     def more(self):
  76.         
  77.         try:
  78.             data_read = self.fileobj.read(self.chunksize)
  79.         except ValueError:
  80.             
  81.             try:
  82.                 self.fileobj.close()
  83.             except:
  84.                 pass
  85.  
  86.             return ''
  87.  
  88.         sz = len(data_read)
  89.         if sz == 0 and self.close_when_done:
  90.             self.fileobj.close()
  91.         
  92.         self.total += sz
  93.         self.progress_cb(self.total)
  94.         return data_read
  95.  
  96.     
  97.     def tofile(cls, sourcefile, outfile, progress_callback = (lambda : pass), bytecounter = None):
  98.         gen = cls.tofile_gen(sourcefile, outfile, progress_callback, bytecounter)
  99.         gen.next()
  100.         
  101.         try:
  102.             gen.next()
  103.         except StopIteration:
  104.             pass
  105.  
  106.  
  107.     tofile = classmethod(tofile)
  108.     
  109.     def tofile_gen(cls, sourcefile, outfile, progress_callback = (lambda : pass), bytecounter = None):
  110.         fc = cls(sourcefile, close_when_done = True, bytecounter = bytecounter)
  111.         yield fc
  112.         chunk = fc.more()
  113.         bytes_written = 0
  114.         write = outfile.write
  115.         tell = outfile.tell
  116.         more = fc.more
  117.         while chunk and not (fc.cancelled):
  118.             write(chunk)
  119.             bytes_written += len(chunk)
  120.             progress_callback(tell())
  121.             chunk = more()
  122.         outfile.close()
  123.  
  124.     tofile_gen = classmethod(tofile_gen)
  125.  
  126.  
  127. def httpjoin(base, path, keepquery = False):
  128.     if path.startswith('http'):
  129.         return path
  130.     else:
  131.         joined = urlparse.urljoin(base, path)
  132.         if not keepquery:
  133.             parsed = list(urlparse.urlparse(joined))
  134.             parsed[4] = ''
  135.             return urlparse.urlunparse(parsed)
  136.         else:
  137.             return joined
  138.  
  139.  
  140. class UrlQuery(str):
  141.     
  142.     def parse(cls, url, parse_query = True):
  143.         (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
  144.         if parse_query:
  145.             querymap = { }
  146.             for elem in query.split('&'):
  147.                 (key, value) = None if '=' in elem else (elem, True)
  148.                 querymap[key] = value
  149.             
  150.             query = querymap
  151.         
  152.         return dict(scheme = scheme, netloc = netloc, path = path, params = params, query = query, fragment = fragment)
  153.  
  154.     parse = classmethod(parse)
  155.     
  156.     def __new__(cls, link, d = { }, **kwargs):
  157.         if link.endswith('?'):
  158.             link = link[:-1]
  159.         
  160.         if '?' in link:
  161.             joiner = '&'
  162.         else:
  163.             joiner = '?'
  164.         return str.__new__(cls, ''.join([
  165.             link,
  166.             joiner,
  167.             WebFormData(d = d, **kwargs)]))
  168.  
  169.  
  170.  
  171. class WebFormData(str):
  172.     
  173.     def __new__(cls, d = { }, **kwargs):
  174.         if d and kwargs:
  175.             kwargs.update(d)
  176.         elif not kwargs:
  177.             pass
  178.         kwargs = d
  179.         base = urllib.urlencode(kwargs)
  180.         return str.__new__(cls, base)
  181.  
  182.  
  183.  
  184. def int_to_ip(s, byteorder = '<'):
  185.     return '.'.join((lambda .0: for c in .0:
  186. str(ord(c)))(struct.pack(byteorder + 'I', int(s))))
  187.  
  188. spacify_pattern = re.compile('( {2,})')
  189.  
  190. def spacify_repl(m):
  191.     l = len(m.group())
  192.     if l == 2:
  193.         return '  '
  194.     else:
  195.         return ' ' + ''.join([
  196.             ' '] * (l - 2)) + ' '
  197.  
  198.  
  199. def spacify(s):
  200.     return spacify_pattern.sub(spacify_repl, s)
  201.  
  202. urlregex = re.compile("([A-Za-z][A-Za-z0-9+.-]{1,120}:[A-Za-z0-9/](([A-Za-z0-9$_.+!*,;/?:@&~=-])|%[A-Fa-f0-9]{2}){1,333}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*,;/?:@&~=%-']{0,1000}))?)[^\\. <]")
  203. TLDs = [
  204.     'arpa',
  205.     'root',
  206.     'aero',
  207.     'asia',
  208.     'biz',
  209.     'com',
  210.     'coop',
  211.     'edu',
  212.     'gov',
  213.     'info',
  214.     'int',
  215.     'museum',
  216.     'name',
  217.     'net',
  218.     'org',
  219.     'pro',
  220.     'ac',
  221.     'ad',
  222.     'ae',
  223.     'af',
  224.     'ag',
  225.     'ai',
  226.     'al',
  227.     'am',
  228.     'an',
  229.     'ao',
  230.     'aq',
  231.     'ar',
  232.     'as',
  233.     'at',
  234.     'au',
  235.     'aw',
  236.     'ax',
  237.     'az',
  238.     'ba',
  239.     'bb',
  240.     'bd',
  241.     'be',
  242.     'bf',
  243.     'bg',
  244.     'bh',
  245.     'bi',
  246.     'bj',
  247.     'bm',
  248.     'bn',
  249.     'bo',
  250.     'br',
  251.     'bs',
  252.     'bt',
  253.     'bv',
  254.     'bw',
  255.     'by',
  256.     'bz',
  257.     'ca',
  258.     'cc',
  259.     'cd',
  260.     'cf',
  261.     'cg',
  262.     'ch',
  263.     'ci',
  264.     'ck',
  265.     'cl',
  266.     'cm',
  267.     'cn',
  268.     'co',
  269.     'cr',
  270.     'cu',
  271.     'cv',
  272.     'cx',
  273.     'cy',
  274.     'cz',
  275.     'de',
  276.     'dj',
  277.     'dk',
  278.     'dm',
  279.     'do',
  280.     'dz',
  281.     'ec',
  282.     'ee',
  283.     'eg',
  284.     'er',
  285.     'es',
  286.     'et',
  287.     'eu',
  288.     'fi',
  289.     'fj',
  290.     'fk',
  291.     'fm',
  292.     'fo',
  293.     'fr',
  294.     'ga',
  295.     'gb',
  296.     'gd',
  297.     'ge',
  298.     'gf',
  299.     'gg',
  300.     'gh',
  301.     'gi',
  302.     'gl',
  303.     'gm',
  304.     'gn',
  305.     'gp',
  306.     'gq',
  307.     'gr',
  308.     'gs',
  309.     'gt',
  310.     'gu',
  311.     'gw',
  312.     'gy',
  313.     'hk',
  314.     'hm',
  315.     'hn',
  316.     'hr',
  317.     'ht',
  318.     'hu',
  319.     'id',
  320.     'ie',
  321.     'il',
  322.     'im',
  323.     'in',
  324.     'io',
  325.     'iq',
  326.     'ir',
  327.     'is',
  328.     'it',
  329.     'je',
  330.     'jm',
  331.     'jo',
  332.     'jp',
  333.     'ke',
  334.     'kg',
  335.     'kh',
  336.     'ki',
  337.     'km',
  338.     'kn',
  339.     'kp',
  340.     'kr',
  341.     'kw',
  342.     'ky',
  343.     'kz',
  344.     'la',
  345.     'lb',
  346.     'lc',
  347.     'li',
  348.     'lk',
  349.     'lr',
  350.     'ls',
  351.     'lt',
  352.     'lu',
  353.     'lv',
  354.     'ly',
  355.     'ma',
  356.     'mc',
  357.     'md',
  358.     'me',
  359.     'mg',
  360.     'mh',
  361.     'mk',
  362.     'ml',
  363.     'mm',
  364.     'mn',
  365.     'mo',
  366.     'mp',
  367.     'mq',
  368.     'mr',
  369.     'ms',
  370.     'mt',
  371.     'mu',
  372.     'mv',
  373.     'mw',
  374.     'mx',
  375.     'my',
  376.     'mz',
  377.     'na',
  378.     'nc',
  379.     'ne',
  380.     'nf',
  381.     'ng',
  382.     'ni',
  383.     'nl',
  384.     'no',
  385.     'np',
  386.     'nr',
  387.     'nu',
  388.     'nz',
  389.     'om',
  390.     'pa',
  391.     'pe',
  392.     'pf',
  393.     'pg',
  394.     'ph',
  395.     'pk',
  396.     'pl',
  397.     'pm',
  398.     'pn',
  399.     'pr',
  400.     'ps',
  401.     'pt',
  402.     'pw',
  403.     'py',
  404.     'qa',
  405.     're',
  406.     'ro',
  407.     'rs',
  408.     'ru',
  409.     'rw',
  410.     'sa',
  411.     'sb',
  412.     'sc',
  413.     'sd',
  414.     'se',
  415.     'sg',
  416.     'sh',
  417.     'si',
  418.     'sj',
  419.     'sk',
  420.     'sl',
  421.     'sm',
  422.     'sn',
  423.     'so',
  424.     'sr',
  425.     'st',
  426.     'su',
  427.     'sv',
  428.     'sy',
  429.     'sz',
  430.     'tc',
  431.     'td',
  432.     'tf',
  433.     'tg',
  434.     'th',
  435.     'tj',
  436.     'tk',
  437.     'tl',
  438.     'tm',
  439.     'tn',
  440.     'to',
  441.     'tp',
  442.     'tr',
  443.     'tt',
  444.     'tv',
  445.     'tw',
  446.     'tz',
  447.     'ua',
  448.     'ug',
  449.     'uk',
  450.     'um',
  451.     'us',
  452.     'uy',
  453.     'uz',
  454.     'va',
  455.     'vc',
  456.     've',
  457.     'vg',
  458.     'vi',
  459.     'vn',
  460.     'vu',
  461.     'wf',
  462.     'ws',
  463.     'ye',
  464.     'yt',
  465.     'yu',
  466.     'za',
  467.     'zm',
  468.     'zw']
  469. domains = '(?:%s)' % '|'.join(TLDs)
  470. email_regex_string = '(([a-zA-Z0-9_][a-zA-Z0-9_\\-\\.]*)(\\+[a-zA-Z0-9_\\-\\.]+)?@(([a-zA-Z0-9\\-_]+\\.?)*[a-zA-Z]{1,4}))'
  471. email_regex = re.compile(email_regex_string)
  472. email_wholestring_regex = re.compile('^' + email_regex_string + '$')
  473. is_email = primitives.ischeck((lambda s: bool(email_wholestring_regex.match(s))))
  474.  
  475. class EmailAddress(tuple):
  476.     
  477.     def __new__(cls, addr, default_domain = sentinel):
  478.         
  479.         try:
  480.             (name, label, domain) = parse_email(addr)
  481.         except:
  482.             if default_domain is sentinel:
  483.                 raise 
  484.             else:
  485.                 (name, label, domain) = parse_email(addr + '@' + default_domain)
  486.  
  487.         return tuple.__new__(cls, (name, label, domain))
  488.  
  489.     
  490.     def name(self):
  491.         return self[0]
  492.  
  493.     name = property(name)
  494.     
  495.     def label(self):
  496.         return self[1]
  497.  
  498.     label = property(label)
  499.     
  500.     def domain(self):
  501.         return self[2]
  502.  
  503.     domain = property(domain)
  504.     
  505.     def __str__(self):
  506.         if self.label:
  507.             return '%s+%s@%s' % self
  508.         else:
  509.             return '%s@%s' % (self.name, self.domain)
  510.  
  511.     
  512.     def __repr__(self):
  513.         return '<EmailAddress %s>' % (self,)
  514.  
  515.  
  516.  
  517. def parse_email(s):
  518.     match = email_wholestring_regex.match(s)
  519.     (wholething, user, lbl, dom, __) = match.groups()
  520.     if lbl:
  521.         lbl = lbl.strip('+')
  522.     else:
  523.         lbl = ''
  524.     return (user, lbl, dom)
  525.  
  526. protocols = 'ftp|https?|gopher|msnim|icq|telnet|nntp|aim|file|svn|svn+(?:\\w)+'
  527. linkify_url_pattern = re.compile('(?=[a-zA-Z0-9])                             # Must start correctly\n      ((?:                                        # Match the leading part (proto://hostname, or just hostname)\n          (?:(?P<protocol>%s)                     #     protocol\n          ://                                     #     ://\n          (?:                                     #     Optional \'username:password@\'\n              (?P<username>\\w+)                   #         username\n              (?::(?P<password>\\w+))?             #         optional :password\n              @                                   #         @\n          )?)?                                    #\n          (?P<hostname>                           # hostname (sub.example.com). single-letter\n          (?:[iqxz]|(?:[-\\w]+))                   # domains are not allowed, except those listed:\n          (?:\\.\\w[-\\w]*)*)                        # http://en.wikipedia.org/wiki/Single-letter_second-level_domains\n      )?                                          #\n      (?::(?P<port>\\d+))?                         # Optional port number\n      (?P<selector>\n        (?:                                       # Rest of the URL, optional\n          /?                                      #     Start with \'/\'\n          [^.!,?;:"<>\\[\\]{}\\s\\x7F-\\xFF]*          #     Can\'t start with these\n          (?:                                     #\n              [.!,?;:]+                           #     One or more of these\n              [^.!,?;:"<>\\[\\]{}\\s\\x7F-\\xFF]+      #     Can\'t finish with these\n              #\'"                                 #     # or \' or "\n          )*)                                     #\n      )?)                                         #\n   ' % protocols, re.VERBOSE)
  528.  
  529. def isurl(text):
  530.     m = linkify_url_pattern.match(text)
  531.     if not m:
  532.         return False
  533.     
  534.     protocol = m.group('protocol')
  535.     host = m.group('hostname')
  536.     if host is not None:
  537.         if protocol is None:
  538.             myTLDs = None if '.' in host else [
  539.                 host]
  540.             if len(myTLDs) < 2 or myTLDs[-1] not in TLDs:
  541.                 return False
  542.             
  543.         
  544.     
  545.     return True
  546.  
  547.  
  548. def _dolinkify(text):
  549.     
  550.     def repl(m):
  551.         protocol = m.group('protocol')
  552.         host = m.group('hostname')
  553.         url = m.group()
  554.         after = ''
  555.         if url.endswith(')') and '(' not in url:
  556.             url = url[:-1]
  557.             after = ')'
  558.         
  559.         if host is not None:
  560.             if protocol is None:
  561.                 myTLDs = None if '.' in host else [
  562.                     host]
  563.                 if len(myTLDs) < 2 or myTLDs[-1] not in TLDs:
  564.                     return url + after
  565.                 
  566.             
  567.             href = None if protocol is None else url
  568.             return '<a href="%s">%s</a>' % (href, url) + after
  569.         
  570.         return url
  571.  
  572.     text = linkify_url_pattern.sub(repl, text)
  573.     return text
  574.  
  575.  
  576. def linkify(text):
  577.     if not re.search('<.*>', text):
  578.         return _dolinkify(text)
  579.     else:
  580.         lines = []
  581.         for line in re.split('(<.*?>)', text):
  582.             if not re.match('<.*?>', line):
  583.                 line = _dolinkify(line)
  584.             
  585.             lines.append(line)
  586.         
  587.         return ''.join(lines)
  588.  
  589.  
  590. class QueueableMixin(object):
  591.     
  592.     def __init__(self):
  593.         object.__init__(self)
  594.         self._on_queue = False
  595.  
  596.     
  597.     def queue(self):
  598.         if not self._on_queue:
  599.             self._queue()
  600.             self._on_queue = True
  601.         
  602.  
  603.     
  604.     def unqueue(self):
  605.         if self._on_queue:
  606.             self._unqueue()
  607.             self._on_queue = False
  608.         
  609.  
  610.  
  611.  
  612. class ProducerQueuable(QueueableMixin):
  613.     
  614.     def __init__(self, sck):
  615.         QueueableMixin.__init__(self)
  616.         self.sck = sck
  617.  
  618.     
  619.     def _queue(self):
  620.         self.sck.push_with_producer(self)
  621.  
  622.     
  623.     def _unqueue(self):
  624.         
  625.         try:
  626.             self.sck.producer_fifo.remove(self)
  627.         except ValueError:
  628.             pass
  629.  
  630.  
  631.  
  632.  
  633. class RoundRobinProducer(ProducerQueuable):
  634.     
  635.     def __init__(self, sck):
  636.         ProducerQueuable.__init__(self, sck)
  637.         self.list = []
  638.  
  639.     
  640.     def add(self, prod):
  641.         
  642.         try:
  643.             if not callable(prod.more):
  644.                 raise AssertionError('Producers must have a "more" method')
  645.         except:
  646.             traceback.print_exc()
  647.             raise 
  648.  
  649.         self.unqueue()
  650.         self.list.append(prod)
  651.         self.queue()
  652.  
  653.     
  654.     def more(self):
  655.         self._on_queue = True
  656.         d = None
  657.         l = self.list
  658.         prod = None
  659.         while not d and l:
  660.             prod = l.pop(0)
  661.             d = prod.more()
  662.         if d:
  663.             l.append(prod)
  664.         else:
  665.             self.unqueue()
  666.             if self.list:
  667.                 self.queue()
  668.             
  669.         return d
  670.  
  671.  
  672.  
  673. class PriorityProducer(ProducerQueuable):
  674.     
  675.     def __init__(self, sck):
  676.         ProducerQueuable.__init__(self, sck)
  677.         self.high = []
  678.         self.mid = []
  679.         self.low = []
  680.  
  681.     
  682.     def add(self, prod, pri = 'mid'):
  683.         self.unqueue()
  684.         getattr(self, pri).append(prod)
  685.         self.queue()
  686.  
  687.     
  688.     def more(self):
  689.         self._on_queue = True
  690.         d = None
  691.         for l in (self.high, self.mid, self.low):
  692.             if not l:
  693.                 continue
  694.             
  695.             while not d and l:
  696.                 prod = l.pop(0)
  697.                 d = prod.more()
  698.             if d:
  699.                 l.insert(0, prod)
  700.                 break
  701.                 continue
  702.         
  703.         return d
  704.  
  705.  
  706.  
  707. class HTTPConnProgress(HTTPConnection):
  708.     
  709.     def send_file_cb(self, fileobj, progress_cb, blocksize = default_chunksize, progressDelta = 0):
  710.         if self.sock is None:
  711.             if self.auto_open:
  712.                 self.connect()
  713.             else:
  714.                 raise NotConnected()
  715.         
  716.         if self.debuglevel > 0:
  717.             print 'sending contents of', fileobj
  718.         
  719.         
  720.         try:
  721.             read = fileobj.read
  722.             sendall = self.sock.sendall
  723.             chunk = read(blocksize)
  724.             total = 0
  725.             while chunk:
  726.                 total += len(chunk)
  727.                 sendall(chunk)
  728.                 progress_cb(total - progressDelta)
  729.                 chunk = read(blocksize)
  730.         except socket.error:
  731.             v = None
  732.             if v[0] == 32:
  733.                 self.close()
  734.             
  735.             raise 
  736.  
  737.  
  738.  
  739.  
  740. class SocketEventMixin(EventMixin):
  741.     events = EventMixin.events | set(('connected', 'connection_failed', 'socket_error', 'socket_closed'))
  742.     
  743.     def post_connect_error(self, e = None):
  744.         self.event('socket_error')
  745.         self.post_connect_disconnect()
  746.  
  747.     
  748.     def post_connect_expt(self):
  749.         self.event('socket_error')
  750.         self.post_connect_disconnect()
  751.  
  752.     
  753.     def post_connect_disconnect(self):
  754.         self.close()
  755.         self.event('socket_closed')
  756.  
  757.     
  758.     def post_connect_close(self):
  759.         self.close()
  760.         self.event('socket_closed')
  761.  
  762.     
  763.     def reassign(self):
  764.         self.handle_expt = self.post_connect_expt
  765.         self.handle_error = self.post_connect_error
  766.         self.handle_close = self.post_connect_close
  767.         self.do_disconnect = self.post_connect_disconnect
  768.  
  769.  
  770.  
  771. def build_cookie(name, value, version = 0, domain = sentinel, port = sentinel, path = sentinel, secure = False, expires = None, discard = False, comment = None, comment_url = None, rest = {
  772.     'httponly': None }, rfc2109 = False):
  773.     if domain is sentinel:
  774.         domain = None
  775.         domain_specified = False
  776.         domain_initial_dot = False
  777.     else:
  778.         domain_specified = True
  779.         domain_initial_dot = domain.startswith('.')
  780.     if port is sentinel:
  781.         port = None
  782.         port_specified = False
  783.     else:
  784.         port_specified = True
  785.     if path is sentinel:
  786.         path = None
  787.         path_specified = False
  788.     else:
  789.         path_specified = True
  790.     return cookielib.Cookie(**locals())
  791.  
  792.  
  793. def GetSocketType():
  794.     d = GetProxyInfo()
  795.     if d:
  796.         return socks.socksocket
  797.     else:
  798.         return socket.socket
  799.  
  800. NONE = 'NONPROX'
  801. SYSDEFAULT = 'SYSPROX'
  802. CUSTOM = 'SETPROX'
  803.  
  804. def GetProxyInfo():
  805.     ps = proxy_settings
  806.     
  807.     try:
  808.         pd = ps.get_proxy_dict()
  809.     except Exception:
  810.         e = None
  811.         print >>sys.stderr, 'No proxies because: %r' % e
  812.         pd = { }
  813.  
  814.     get = pd.get
  815.     proxytype = get('proxytype')
  816.     port = get('port')
  817.     
  818.     try:
  819.         port = int(port)
  820.     except:
  821.         port = None
  822.  
  823.     addr = get('addr')
  824.     username = get('username')
  825.     password = get('password')
  826.     override = get('override')
  827.     
  828.     try:
  829.         override = int(override)
  830.     except:
  831.         if override not in (SYSDEFAULT, CUSTOM, NONE):
  832.             override = SYSDEFAULT
  833.         
  834.  
  835.     if override:
  836.         override = CUSTOM
  837.     else:
  838.         override = SYSDEFAULT
  839.     if override == NONE:
  840.         return { }
  841.     elif override == SYSDEFAULT:
  842.         px = urllib._getproxies()
  843.         if not px:
  844.             return { }
  845.         
  846.         url = px.get('http', None)
  847.         if url is None:
  848.             return { }
  849.         
  850.         url = urlparse.urlparse(url)
  851.         if not url.hostname:
  852.             pass
  853.         addr = ''
  854.         if not addr:
  855.             return { }
  856.         
  857.         if not url.port:
  858.             pass
  859.         port = 80
  860.         if not url.username and username:
  861.             pass
  862.         username = None
  863.         if not url.password and password:
  864.             pass
  865.         password = None
  866.         proxytype = 'http'
  867.     
  868.     if all((type, port, addr)):
  869.         proxytype = getattr(socks, ('proxy_type_%s' % proxytype).upper(), None)
  870.         return dict(addr = addr, port = port, username = username, password = password, proxytype = proxytype)
  871.     else:
  872.         return { }
  873.  
  874.  
  875. def GetProxyInfoHttp2():
  876.     i = GetProxyInfo()
  877.     if not i:
  878.         return None
  879.     
  880.     return httplib2.ProxyInfo(proxy_type = i['proxytype'], proxy_host = i['addr'], proxy_port = i['port'], proxy_user = i['username'], proxy_pass = i['password'], proxy_rdns = True)
  881.  
  882.  
  883. def getproxies_digsby():
  884.     pinfo = GetProxyInfo()
  885.     proxies = { }
  886.     if pinfo.get('username', None) and pinfo.get('password', None):
  887.         unpw = '%s:%s@' % (pinfo['username'], pinfo['password'])
  888.     else:
  889.         unpw = ''
  890.     if pinfo.get('port', None):
  891.         port = ':' + str(pinfo['port'])
  892.     else:
  893.         port = ''
  894.     host = pinfo.get('addr', None)
  895.     if not host:
  896.         return proxies
  897.     
  898.     all = unpw + host + port
  899.     proxies = urllib.OneProxy()
  900.     proxies._proxyServer = all
  901.     if pinfo['proxytype'] != socks.PROXY_TYPE_HTTP:
  902.         proxy_url = None % 'socks%d://' if pinfo['proxytype'] == socks.PROXY_TYPE_SOCKS4 else 5 + all
  903.         return dict(socks = proxy_url, http = proxy_url, https = proxy_url)
  904.     
  905.     proxies['https'] = 'http://' + all
  906.     proxies['http'] = 'http://' + all
  907.     proxies['ftp'] = 'http://' + all
  908.     return proxies
  909.  
  910.  
  911. class SocksProxyHandler(urllib2.ProxyHandler):
  912.     handler_order = 100
  913.     
  914.     def proxy_open(self, req, type):
  915.         
  916.         try:
  917.             req._proxied
  918.         except AttributeError:
  919.             proxyinfo = self.proxies.get(type, '')
  920.             proxytype = urllib2._parse_proxy(proxyinfo)[0]
  921.             if proxytype is None:
  922.                 req._proxied = False
  923.                 return urllib2.ProxyHandler.proxy_open(self, req, type)
  924.             else:
  925.                 req._proxytype = proxytype
  926.                 req._proxied = True
  927.                 if proxytype == 'http' and type != 'https':
  928.                     return urllib2.ProxyHandler.proxy_open(self, req, type)
  929.                 else:
  930.                     return None
  931.         except:
  932.             proxytype is None
  933.  
  934.         return None
  935.  
  936.     
  937.     def socks4_open(self, req):
  938.         return self.socks_open(req, 4)
  939.  
  940.     
  941.     def socks5_open(self, req):
  942.         return self.socks_open(req, 5)
  943.  
  944.     
  945.     def socks_open(self, req, sockstype):
  946.         (orig_url_type, __, __, orighostport) = urllib2._parse_proxy(req.get_full_url())
  947.         req.set_proxy(orighostport, orig_url_type)
  948.         endpoint = req.get_host()
  949.         if ':' in endpoint:
  950.             (host, port) = endpoint.rsplit(':', 1)
  951.             port = int(port)
  952.         else:
  953.             host = endpoint
  954.             port = 80
  955.         req._proxied = True
  956.         return self.parent.open(req)
  957.  
  958.  
  959. if hasattr(httplib, 'HTTPS'):
  960.     
  961.     class SocksHttpsOpener(urllib2.HTTPSHandler):
  962.         handler_order = 101
  963.         
  964.         def https_open(self, req):
  965.             if getattr(req, '_proxied', False) and getattr(req, '_proxytype', None) is not None:
  966.                 return urllib2.HTTPSHandler.do_open(self, SocksHttpsConnection, req)
  967.             else:
  968.                 return urllib2.HTTPSHandler.https_open(self, req)
  969.  
  970.  
  971.     
  972.     class SocksHttpsConnection(httplib.HTTPSConnection):
  973.         _sockettype = socks.socksocket
  974.         
  975.         def connect(self):
  976.             pd = urllib.getproxies().get('https', None)
  977.             if pd is None:
  978.                 sockstype = ''
  979.             else:
  980.                 (sockstype, user, password, hostport) = urllib2._parse_proxy(pd)
  981.             (host, port) = hostport.rsplit(':', 1)
  982.             port = int(port)
  983.             sock = self._sockettype(socket.AF_INET, socket.SOCK_STREAM)
  984.             sock.setproxy(proxytype = getattr(socks, 'PROXY_TYPE_%s' % sockstype.upper()), addr = host, port = port, rdns = True, username = user, password = password)
  985.             sock.connect((self.host, self.port))
  986.             ssl = socket.ssl(sock, self.key_file, self.cert_file)
  987.             self.sock = httplib.FakeSocket(sock, ssl)
  988.  
  989.  
  990.  
  991.  
  992. class SocksHttpOpener(urllib2.HTTPHandler):
  993.     handler_order = 101
  994.     
  995.     def http_open(self, req):
  996.         proxytype = getattr(req, '_proxytype', None)
  997.         if getattr(req, '_proxied', False) and proxytype not in ('http', None):
  998.             return urllib2.HTTPHandler.do_open(self, SocksConnection, req)
  999.         else:
  1000.             return urllib2.HTTPHandler.http_open(self, req)
  1001.  
  1002.  
  1003.  
  1004. class SocksConnection(httplib.HTTPConnection):
  1005.     _sockettype = socks.socksocket
  1006.     
  1007.     def connect(self):
  1008.         pd = urllib.getproxies().get('http', None)
  1009.         if pd is None:
  1010.             sockstype = ''
  1011.         else:
  1012.             (sockstype, user, password, hostport) = urllib2._parse_proxy(pd)
  1013.         if 'socks' not in sockstype:
  1014.             return httplib.HTTPConnection.connect(self)
  1015.         
  1016.         (host, port) = hostport.rsplit(':', 1)
  1017.         port = int(port)
  1018.         for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
  1019.             (af, socktype, proto, canonname, sa) = res
  1020.             
  1021.             try:
  1022.                 self.sock = self._sockettype(af, socktype, proto)
  1023.                 self.sock.setproxy(proxytype = getattr(socks, 'PROXY_TYPE_%s' % sockstype.upper()), addr = host, port = port, rdns = False, username = user, password = password)
  1024.                 if self.debuglevel > 0:
  1025.                     print 'connect: (%s, %s)' % (self.host, self.port)
  1026.                 
  1027.                 self.sock.connect(sa)
  1028.             except socket.error:
  1029.                 msg = None
  1030.                 if self.debuglevel > 0:
  1031.                     print 'connect fail:', (self.host, self.port)
  1032.                 
  1033.                 if self.sock:
  1034.                     self.sock.close()
  1035.                 
  1036.                 self.sock = None
  1037.                 continue
  1038.  
  1039.         
  1040.         if not self.sock:
  1041.             raise socket.error, msg
  1042.         
  1043.  
  1044.  
  1045.  
  1046. class DigsbyHttpProxyPasswordManager(urllib2.HTTPPasswordMgr):
  1047.     
  1048.     def find_user_password(self, realm, uri):
  1049.         pi = GetProxyInfo()
  1050.         if not pi['username']:
  1051.             pass
  1052.         if not pi['password']:
  1053.             pass
  1054.         return (None, None)
  1055.  
  1056.  
  1057. if not hasattr(urllib, '_getproxies'):
  1058.     urllib._getproxies = urllib.getproxies
  1059.     urllib.getproxies = getproxies_digsby
  1060.     urllib2.UnknownHandler.handler_order = sys.maxint
  1061.     urllib2.ProxyDigestAuthHandler.__bases__ = urllib2.ProxyDigestAuthHandler.__bases__[::-1]
  1062.     urllib2.ProxyBasicAuthHandler.handler_order = 499
  1063.     httplib2.ProxyInfo.get_default_proxy = staticmethod(GetProxyInfoHttp2)
  1064.  
  1065.  
  1066. def GetDefaultHandlers():
  1067.     handlers = [
  1068.         SocksProxyHandler,
  1069.         SocksHttpOpener]
  1070.     httpsopener = globals().get('SocksHttpsOpener', None)
  1071.     if httpsopener is not None:
  1072.         handlers.append(httpsopener)
  1073.     
  1074.     pwdmgr = DigsbyHttpProxyPasswordManager()
  1075.     for auth_handler_type in (urllib2.ProxyBasicAuthHandler, urllib2.ProxyDigestAuthHandler):
  1076.         handlers.append(auth_handler_type(pwdmgr))
  1077.     
  1078.     return handlers
  1079.  
  1080.  
  1081. def build_opener(*a, **k):
  1082.     if 'default_classes' not in k:
  1083.         k['default_classes'] = GetDefaultHandlers()
  1084.     
  1085.     return urllib2.build_opener(*a, **k)
  1086.  
  1087. opener = urllib2.build_opener(*GetDefaultHandlers())
  1088. urllib2.install_opener(opener)
  1089. _hostprog = re.compile('^//([^/?]*)(.*)$')
  1090.  
  1091. def splithost(url):
  1092.     match = _hostprog.match(url)
  1093.     if match:
  1094.         groups = match.group(1, 2)
  1095.         if groups[0] == '':
  1096.             return (groups[0], '/' + groups[1])
  1097.         else:
  1098.             return groups
  1099.     
  1100.     return (None, url)
  1101.  
  1102. urllib.splithost = urllib2.splithost = splithost
  1103.  
  1104. def httpok(_code):
  1105.     return getattr(_code, 'status', _code) // 100 == 2
  1106.  
  1107.  
  1108. class CallbackProducerMixin(object):
  1109.     
  1110.     def __init__(self):
  1111.         bases = self.__class__.__bases__
  1112.         found_self = False
  1113.         self._siblingClass = None
  1114.         for base in bases:
  1115.             if base is CallbackProducerMixin:
  1116.                 found_self = True
  1117.                 continue
  1118.             if hasattr(base, 'more') and found_self:
  1119.                 self._siblingClass = base
  1120.                 break
  1121.                 continue
  1122.         
  1123.         if self._siblingClass is None:
  1124.             raise AssertionError("This mix-in requires there is a sibling class with a 'more' method. Additionally, CallbackProducerMixin must be *before* that class in the inheritance list (for method resolution reasons).")
  1125.         
  1126.  
  1127.     
  1128.     def set_callback(self, callback = None):
  1129.         self._callback = callback
  1130.  
  1131.     set_callback = callsback(set_callback)
  1132.     
  1133.     def more(self):
  1134.         if not hasattr(self, '_siblingClass'):
  1135.             result = ''
  1136.         else:
  1137.             result = self._siblingClass.more(self)
  1138.         if result == '':
  1139.             if getattr(self, '_callback', None) is not None:
  1140.                 self._callback.success()
  1141.             
  1142.             if getattr(self, '_callback', None) is not None:
  1143.                 del self._callback
  1144.             
  1145.         
  1146.         return result
  1147.  
  1148.  
  1149.  
  1150. class SimpleCallbackProducer(CallbackProducerMixin, asynchat.simple_producer):
  1151.     
  1152.     def __init__(self, data):
  1153.         asynchat.simple_producer.__init__(self, data)
  1154.         CallbackProducerMixin.__init__(self)
  1155.  
  1156.  
  1157.  
  1158. def _fifo_remove(self, val):
  1159.     
  1160.     try:
  1161.         self.list.remove(val)
  1162.     except Exception:
  1163.         return False
  1164.  
  1165.     return True
  1166.  
  1167. asynchat.fifo.remove = _fifo_remove
  1168.  
  1169. def producer_cb(data, callback = None):
  1170.     prod = SimpleCallbackProducer(data)
  1171.     prod.set_callback(callback = callback)
  1172.     return prod
  1173.  
  1174. producer_cb = callsback(producer_cb)
  1175.  
  1176. def get_snurl(url):
  1177.     return get_short_url(url, 'snurl')
  1178.  
  1179.  
  1180. def get_isgd(url):
  1181.     return get_short_url(url, 'isgd')
  1182.  
  1183.  
  1184. def get_tinyurl(url):
  1185.     return get_short_url(url, 'tinyurl')
  1186.  
  1187.  
  1188. class UrlShortener(object):
  1189.     endpoint = None
  1190.     
  1191.     def shorten(self, url):
  1192.         
  1193.         try:
  1194.             resp = urllib2.urlopen(UrlQuery(self.endpoint, d = self.get_args(url.encode('utf-8'))))
  1195.         except urllib2.HTTPError:
  1196.             e = None
  1197.             resp = e
  1198.  
  1199.         return self.process_response(resp)
  1200.  
  1201.     
  1202.     def get_args(self, url):
  1203.         raise NotImplementedError
  1204.  
  1205.     
  1206.     def process_response(self, resp):
  1207.         if resp.code != 200:
  1208.             body = resp.read()
  1209.             raise Exception(body)
  1210.         
  1211.         ret = resp.read()
  1212.         return ret
  1213.  
  1214.  
  1215.  
  1216. class isgd_shortener(UrlShortener):
  1217.     endpoint = 'http://is.gd/api.php'
  1218.     
  1219.     def get_args(self, url):
  1220.         return dict(longurl = url)
  1221.  
  1222.  
  1223.  
  1224. class tinyurl_shortener(UrlShortener):
  1225.     endpoint = 'http://tinyurl.com/api-create.php'
  1226.     
  1227.     def get_args(self, url):
  1228.         return dict(url = url)
  1229.  
  1230.  
  1231.  
  1232. class snipr_shortener(UrlShortener):
  1233.     endpoint = 'http://snipr.com/site/snip'
  1234.     
  1235.     def get_args(self, url):
  1236.         return dict(r = 'simple', link = url.encode('url'))
  1237.  
  1238.     
  1239.     def process_response(self, resp):
  1240.         ret = UrlShortener.process_response(self, resp)
  1241.         if not ret.startswith('http'):
  1242.             raise Exception('bad url', ret)
  1243.         
  1244.         return ret
  1245.  
  1246.  
  1247. _shorteners = {
  1248.     'snipr': snipr_shortener,
  1249.     'snurl': snipr_shortener,
  1250.     'snipurl': snipr_shortener,
  1251.     'isgd': isgd_shortener,
  1252.     'tinyurl': tinyurl_shortener,
  1253.     'tiny': tinyurl_shortener }
  1254.  
  1255. def get_short_url(url, provider = None, choices = None):
  1256.     if provider is None:
  1257.         if choices is None:
  1258.             choices = list(_shorteners.keys())
  1259.         
  1260.         random.shuffle(choices)
  1261.     else:
  1262.         choices = [
  1263.             provider]
  1264.     while choices:
  1265.         
  1266.         try:
  1267.             provider = choices.pop()
  1268.             shortener = _shorteners.get(provider)
  1269.             if shortener is None:
  1270.                 raise Exception('UrlShortener provider %r not found', provider)
  1271.             
  1272.             return shortener().shorten(url)
  1273.         continue
  1274.         except Exception:
  1275.             e = None
  1276.             log.error('error getting short URL from %r: %r', provider, e)
  1277.             shortener = None
  1278.             provider = None
  1279.             continue
  1280.         
  1281.  
  1282.         None<EXCEPTION MATCH>Exception
  1283.     raise e
  1284.  
  1285.  
  1286. def wget(url, data = None):
  1287.     closing = closing
  1288.     import contextlib
  1289.     import urllib2
  1290.     
  1291.     try:
  1292.         web = _[2]
  1293.         return web.read()
  1294.     finally:
  1295.         pass
  1296.  
  1297.  
  1298. if __name__ == '__main__':
  1299.     print get_snurl('http://www.google.com')
  1300.  
  1301.