home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / launchpadbugs / http_connection.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  15.5 KB  |  451 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''
  5. TODO (thekorn20080709):
  6.     * auto fetching of edge cookie is not working
  7.        - no idea why an edge cookies is not created when accessing edge.launchpad.net
  8.     * cookie lifetime (auto extend?)
  9.     * adjust almost all testcases and connector
  10. '''
  11. import urllib2
  12. import multipartpost_handler
  13. import cookielib
  14. import cStringIO as StringIO
  15. import time
  16. import urlparse
  17. import cPickle
  18. import base64
  19. from tempfile import mkstemp
  20.  
  21. try:
  22.     import sqlite3 as sqlite
  23. except ImportError:
  24.     
  25.     try:
  26.         from pysqlite2 import dbapi2 as sqlite
  27.     except ImportError:
  28.         raise ImportError, 'no module named sqlite3 or pysqlite2.dbapi2'
  29.     except:
  30.         None<EXCEPTION MATCH>ImportError
  31.     
  32.  
  33.     None<EXCEPTION MATCH>ImportError
  34.  
  35. import os
  36. import exceptions
  37. import utils
  38. from lpconstants import BASEURL, HTTPCONNECTION
  39. from config import Config
  40.  
  41. class _result(object):
  42.     ''' represents an object returned by HTTPConnection. '''
  43.     
  44.     def __init__(self, contenttype = None, text = None, url = None):
  45.         if not contenttype and text and url:
  46.             raise AssertionError, 'at least one argument needed'
  47.         self.contenttype = contenttype
  48.         self.text = text
  49.         self.url = url
  50.  
  51.  
  52.  
  53. class LPCookieProcessor(urllib2.HTTPCookieProcessor):
  54.     ''' CookieProcessor with special functionality regarding launchpad.net
  55.         cookies.
  56.     '''
  57.     
  58.     def sqlite_to_txt(cookiefile, domain):
  59.         match = '%%%s%%' % domain
  60.         con = sqlite.connect(cookiefile)
  61.         cur = con.cursor()
  62.         cur.execute('select host, path, isSecure, expiry, name, value from moz_cookies where host like ?', [
  63.             match])
  64.         ftstr = [
  65.             'FALSE',
  66.             'TRUE']
  67.         (tmp, tmpname) = mkstemp()
  68.         os.write(tmp, '# HTTP Cookie File\n')
  69.         for item in cur.fetchall():
  70.             str = '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (item[0], ftstr[item[0].startswith('.')], item[1], ftstr[item[2]], item[3], item[4], item[5])
  71.             os.write(tmp, str)
  72.         
  73.         os.close(tmp)
  74.         return tmpname
  75.  
  76.     sqlite_to_txt = staticmethod(sqlite_to_txt)
  77.     
  78.     def __nonzero__(self):
  79.         return [] in [ i.domain for i in self.cookiejar ]
  80.  
  81.     
  82.     def load_file(self, cookiefile):
  83.         if cookiefile:
  84.             cj = cookielib.MozillaCookieJar()
  85.             if cookiefile[-6:] == 'sqlite':
  86.                 cookies = self.sqlite_to_txt(cookiefile, 'launchpad.net')
  87.                 
  88.                 try:
  89.                     cj.load(cookies)
  90.                 except:
  91.                     os.unlink(cookies)
  92.                     raise IOError, 'Invalid cookie file'
  93.  
  94.                 os.unlink(cookies)
  95.             else:
  96.                 cj.load(cookiefile)
  97.             for cookie in cj:
  98.                 self.cookiejar.set_cookie(cookie)
  99.             
  100.             return True
  101.         raise IOError, 'No cookie file given'
  102.  
  103.     
  104.     def get_cookie(self, name, domain = None):
  105.         if not domain:
  106.             pass
  107.         domain = '.launchpad.net'
  108.         for i in self.cookiejar:
  109.             if i.name == name and i.domain == domain:
  110.                 return i
  111.         
  112.         return False
  113.  
  114.     
  115.     def change_inhibit_beta_redirect(self, mode):
  116.         '''
  117.         cj.clear(".launchpad.net", "/", "inhibit_beta_redirect")
  118.  
  119.         name inhibit_beta_redirect
  120.         domain .launchpad.net
  121.         path /
  122.         Cookie(version=0, name=\'inhibit_beta_redirect\', value=\'1\', port=None, port_specified=False, domain=\'.launchpad.net\', domain_specified=True, domain_initial_dot=True, path=\'/\', path_specified=False, secure=True, expires=1202139678, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False)
  123.         '''
  124.         if mode in (HTTPCONNECTION.MODE.DEFAULT, HTTPCONNECTION.MODE.EDGE):
  125.             
  126.             try:
  127.                 self.cookiejar.clear('.launchpad.net', '/', 'inhibit_beta_redirect')
  128.             except KeyError:
  129.                 pass
  130.             except:
  131.                 None<EXCEPTION MATCH>KeyError
  132.             
  133.  
  134.         None<EXCEPTION MATCH>KeyError
  135.         if mode == HTTPCONNECTION.MODE.STABLE:
  136.             c_expires = int(time.time()) + 7200
  137.             c = self.get_cookie('inhibit_beta_redirect')
  138.             if not c:
  139.                 
  140.                 try:
  141.                     c = cookielib.Cookie(version = 0, name = 'inhibit_beta_redirect', value = '1', port = None, port_specified = False, domain = '.launchpad.net', domain_specified = True, domain_initial_dot = True, path = '/', path_specified = False, secure = True, expires = c_expires, discard = False, comment = None, comment_url = None, rest = { }, rfc2109 = False)
  142.                 except TypeError:
  143.                     c = cookielib.Cookie(version = 0, name = 'inhibit_beta_redirect', value = '1', port = None, port_specified = False, domain = '.launchpad.net', domain_specified = True, domain_initial_dot = True, path = '/', path_specified = False, secure = True, expires = c_expires, discard = False, comment = None, comment_url = None, rest = { })
  144.  
  145.                 self.cookiejar.set_cookie(c)
  146.             
  147.         
  148.         return self.get_cookie('inhibit_beta_redirect')
  149.  
  150.     
  151.     def save_cookie(self, filename):
  152.         cj = cookielib.MozillaCookieJar()
  153.         for cookie in self.cookiejar:
  154.             cj.set_cookie(cookie)
  155.         
  156.         cj.save(filename)
  157.  
  158.  
  159.  
  160. def pickle_cookie_load(cookie_string):
  161.     ''' load a cookie instance from the value of the config file '''
  162.     
  163.     try:
  164.         cookie_string = base64.decodestring(cookie_string)
  165.     except Exception:
  166.         pass
  167.  
  168.     
  169.     try:
  170.         c = cPickle.loads(cookie_string)
  171.         if isinstance(c, cookielib.Cookie):
  172.             return c
  173.         return None
  174.     except Exception:
  175.         return None
  176.  
  177.  
  178.  
  179. def pickle_cookie_dump(cookie_obj):
  180.     ''' dump a cookie object and encode the resulting string '''
  181.     if not isinstance(cookie_obj, cookielib.Cookie):
  182.         if cookie_obj is None:
  183.             return ''
  184.         raise TypeError
  185.     isinstance(cookie_obj, cookielib.Cookie)
  186.     return base64.encodestring(cPickle.dumps(cookie_obj))
  187.  
  188.  
  189. class HTTPConnectionConfig(Config):
  190.     ''' read the configuration of the HTTPConnection from a config file. '''
  191.     Config.MAPPING['cookies'] = {
  192.         'lp': (pickle_cookie_load, pickle_cookie_dump),
  193.         'edge': (pickle_cookie_load, pickle_cookie_dump),
  194.         'staging': (pickle_cookie_load, pickle_cookie_dump),
  195.         'inhibit_beta_redirect': (pickle_cookie_load, pickle_cookie_dump) }
  196.  
  197.  
  198. class HTTPConnection(object):
  199.     ''' class to manage a https connection to launchpad.net. '''
  200.     
  201.     def __init__(self, cookiefile = None, attempts = 5, content_types = None, config_file = None, config_ignore = None):
  202.         self._HTTPConnection__config = HTTPConnectionConfig(config_file, config_ignore)
  203.         self._HTTPConnection__username = None
  204.         version = 'python-launchpad-bugs/%s (Python-urllib2/%s) (user: %s)' % (utils.find_version_number(show_nick = True), urllib2.__version__, self.user)
  205.         self._HTTPConnection__cookiefile = cookiefile
  206.         self._HTTPConnection__cookie_handler = LPCookieProcessor()
  207.         self._HTTPConnection__opener = urllib2.build_opener(self._HTTPConnection__cookie_handler)
  208.         self._HTTPConnection__opener.addheaders = [
  209.             ('User-agent', version)]
  210.         self._HTTPConnection__poster = urllib2.build_opener(self._HTTPConnection__cookie_handler, multipartpost_handler.MultipartPostHandler)
  211.         self._HTTPConnection__poster.addheaders = [
  212.             ('User-agent', version)]
  213.         self._HTTPConnection__attempts = attempts
  214.         if not content_types:
  215.             pass
  216.         self.content_types = [
  217.             'text/html',
  218.             'text/plain']
  219.         self._HTTPConnection__progress_hook = None
  220.         self._HTTPConnection__mode = HTTPCONNECTION.MODE.DEFAULT
  221.         self._HTTPConnection__cookies_to_dump = []
  222.         for key, value in self._HTTPConnection__config['cookies'].iteritems():
  223.             if value is None:
  224.                 self._HTTPConnection__cookies_to_dump.append(key)
  225.                 continue
  226.             self._HTTPConnection__cookie_handler.cookiejar.set_cookie(value)
  227.         
  228.  
  229.     
  230.     def get_auth(self):
  231.         return self._HTTPConnection__cookie_handler
  232.  
  233.     
  234.     def set_auth(self, auth):
  235.         if isinstance(auth, str):
  236.             self._HTTPConnection__cookiefile = auth
  237.             
  238.             try:
  239.                 return self._HTTPConnection__cookie_handler.load_file(self._HTTPConnection__cookiefile)
  240.             except IOError:
  241.                 e = None
  242.                 raise exceptions.PythonLaunchpadBugsIOError(str(e))
  243.             except:
  244.                 None<EXCEPTION MATCH>IOError
  245.             
  246.  
  247.         None<EXCEPTION MATCH>IOError
  248.         if isinstance(auth, dict):
  249.             
  250.             try:
  251.                 email = auth['email']
  252.                 password = auth['password']
  253.             except KeyError:
  254.                 raise ValueError, "The argument of .set_auth() needs to be either a path to a valid mozilla cookie-file or a dict like {'email':<lp-email-address>,'password':<password>}, but it is %s" % auth
  255.  
  256.             self._do_login(email, password)
  257.         else:
  258.             raise ValueError, "The argument of .set_auth() needs to be either a path to a valid mozilla cookie-file or a dict like {'email':<lp-email-address>,'password':<password>}, but it is %s" % auth
  259.         return isinstance(auth, dict)
  260.  
  261.     
  262.     def _do_login(self, email, password, server = None):
  263.         if server is None:
  264.             server = ('https://bugs.launchpad.net/+login', 'https://bugs.edge.launchpad.net/+login', 'https://bugs.staging.launchpad.net/+login')
  265.         
  266.         for url in server:
  267.             
  268.             try:
  269.                 r = self.post(url, {
  270.                     'loginpage_email': email,
  271.                     'loginpage_password': password,
  272.                     'loginpage_submit_login': 'Log In' })
  273.             continue
  274.             except exceptions.LaunchpadLoginError:
  275.                 raise exceptions.LaunchpadLoginFailed(url)
  276.                 continue
  277.                 except exceptions.LaunchpadError:
  278.                     e = None
  279.                     raise exceptions.LaunchpadLoginError(url, 'Connection failed with %s' % e)
  280.                     continue
  281.                 
  282.             return None
  283.  
  284.  
  285.     
  286.     def user(self):
  287.         if not self._HTTPConnection__username and self._HTTPConnection__config['user']['lplogin']:
  288.             pass
  289.         return 'unknown'
  290.  
  291.     user = property(user)
  292.     
  293.     def set_username(self, user):
  294.         self._HTTPConnection__username = user
  295.  
  296.     
  297.     def needs_login(self, url = None):
  298.         ''' checks if authentication is needed.
  299.         this considers connection-mode and cookies
  300.         '''
  301.         if not url:
  302.             pass
  303.         url = self._change_url('https://launchpad.net/people/+me')
  304.         url = self._HTTPConnection__opener.open(url).geturl()
  305.         return url.endswith('+login')
  306.  
  307.     
  308.     def get(self, url):
  309.         return self._safe_urlopen(url, None, False)
  310.  
  311.     
  312.     def post(self, url, data):
  313.         return self._safe_urlopen(url, data, True)
  314.  
  315.     
  316.     def set_mode(self, mode):
  317.         if not mode in (HTTPCONNECTION.MODE.DEFAULT, HTTPCONNECTION.MODE.EDGE, HTTPCONNECTION.MODE.STABLE, HTTPCONNECTION.MODE.STAGING):
  318.             raise AssertionError, 'Unknown mode'
  319.         self._HTTPConnection__mode = mode
  320.         c = self._HTTPConnection__cookie_handler.change_inhibit_beta_redirect(self._HTTPConnection__mode)
  321.         if not c:
  322.             pass
  323.         self._HTTPConnection__config['cookies']['inhibit_beta_redirect'] = None
  324.         if 'inhibit_beta_redirect' in self._HTTPConnection__cookies_to_dump:
  325.             self._HTTPConnection__cookies_to_dump.remove('inhibit_beta_redirect')
  326.         
  327.         self._HTTPConnection__config.save()
  328.  
  329.     
  330.     def _change_url(self, url):
  331.         u = list(urlparse.urlsplit(url))
  332.         if self._HTTPConnection__mode == HTTPCONNECTION.MODE.EDGE:
  333.             u[1] = u[1].replace('staging.', '')
  334.             u[1] = u[1].replace('edge.', '')
  335.             u[1] = u[1].replace('launchpad.net', 'edge.launchpad.net')
  336.         elif self._HTTPConnection__mode == HTTPCONNECTION.MODE.STAGING:
  337.             u[1] = u[1].replace('staging.', '')
  338.             u[1] = u[1].replace('edge.', '')
  339.             u[1] = u[1].replace('launchpad.net', 'staging.launchpad.net')
  340.             u[1] = u[1].replace('launchpadlibrarian.net', 'staging.launchpadlibrarian.net')
  341.         elif self._HTTPConnection__mode == HTTPCONNECTION.MODE.STABLE:
  342.             u[1] = u[1].replace('staging.', '')
  343.             u[1] = u[1].replace('edge.', '')
  344.         
  345.         return urlparse.urlunsplit(u)
  346.  
  347.     
  348.     def _safe_urlopen(self, url, data, post):
  349.         url = self._change_url(url)
  350.         count = 0
  351.         text = None
  352.         contenttype = None
  353.         geturl = None
  354.         sock = None
  355.         if post:
  356.             opener = self._HTTPConnection__poster
  357.         else:
  358.             opener = self._HTTPConnection__opener
  359.         while count < self._HTTPConnection__attempts:
  360.             
  361.             try:
  362.                 if url[:4] != 'http':
  363.                     url_old = url
  364.                     url = 'https://' + url
  365.                     print 'wrong url <%s>, try <%s>' % (url_old, url)
  366.                 
  367.                 if data:
  368.                     sock = opener.open(url, data)
  369.                 else:
  370.                     sock = opener.open(url)
  371.                 contenttype = sock.info()['Content-type']
  372.                 if sock.geturl().endswith('+login'):
  373.                     raise exceptions.LaunchpadLoginError(url)
  374.                 sock.geturl().endswith('+login')
  375.                 for ct in self.content_types:
  376.                     if contenttype.startswith(ct):
  377.                         if self._HTTPConnection__progress_hook is None:
  378.                             text = sock.read()
  379.                             geturl = sock.geturl()
  380.                             sock.close()
  381.                         else:
  382.                             tmp_text = StringIO.StringIO()
  383.                             i = 0
  384.                             counter = 0
  385.                             size = int(sock.info()['Content-Length'])
  386.                             while i < size:
  387.                                 tmp_text.write(sock.read(self._HTTPConnection__block_size))
  388.                                 i += self._HTTPConnection__block_size
  389.                                 counter += 1
  390.                                 self._HTTPConnection__progress_hook(counter, self._HTTPConnection__block_size, size)
  391.                             text = tmp_text.getvalue()
  392.                             geturl = sock.geturl()
  393.                             sock.close()
  394.                             tmp_text.close()
  395.                         x = self._HTTPConnection__cookies_to_dump[:]
  396.                         for i in x:
  397.                             c = self._HTTPConnection__cookie_handler.get_cookie(i)
  398.                             if c:
  399.                                 self._HTTPConnection__config['cookies'][i] = c
  400.                                 self._HTTPConnection__cookies_to_dump.remove(i)
  401.                                 continue
  402.                         
  403.                         if not self._HTTPConnection__cookies_to_dump == x:
  404.                             self._HTTPConnection__config.save()
  405.                         
  406.                         return _result(contenttype = contenttype, text = text, url = geturl)
  407.                 
  408.                 sock.close()
  409.                 raise IOError, 'unsupported contenttype (contenttype=%s, url=%s)' % (contenttype, url)
  410.             continue
  411.             except urllib2.URLError:
  412.                 e = None
  413.                 
  414.                 try:
  415.                     error = e.code
  416.                 except AttributeError:
  417.                     error = e.reason
  418.  
  419.                 count += 1
  420.                 continue
  421.             
  422.  
  423.             None<EXCEPTION MATCH>urllib2.URLError
  424.         raise exceptions.choose_LaunchpadError(error, url)
  425.  
  426.     
  427.     def set_progress_hook(self, hook_func, blocksize = 4096):
  428.         if not blocksize:
  429.             raise AssertionError, 'blocksize needs to be an integer greater than 0'
  430.         self._HTTPConnection__block_size = blocksize
  431.         if not callable(hook_func):
  432.             raise AssertionError, 'hook_func needs to be callable with three arguments'
  433.         self._HTTPConnection__progress_hook = hook_func
  434.  
  435.     
  436.     def save_cookie(self, filename):
  437.         self._HTTPConnection__cookie_handler.save_cookie(filename)
  438.  
  439.  
  440. if __name__ == '__main__':
  441.     c = HTTPConnection()
  442.     print repr(c.user), c.user
  443.     
  444.     def example_hook(counter, block_size, size):
  445.         print (counter, block_size, size)
  446.  
  447.     c.set_progress_hook(example_hook)
  448.     x = c.get('https://bugs.edge.launchpad.net/ubuntu/+source/linux/+bug/200500/')
  449.     print len(x.text)
  450.  
  451.