home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_2428 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  23.5 KB  |  618 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import sys
  5. import os.path as os
  6. import re
  7. import urlparse
  8. import urllib2
  9. import shutil
  10. import random
  11. import socket
  12. import cStringIO
  13. from pkg_resources import *
  14. from distutils import log
  15. from distutils.errors import DistutilsError
  16.  
  17. try:
  18.     from hashlib import md5
  19. except ImportError:
  20.     from md5 import md5
  21.  
  22. from fnmatch import translate
  23. EGG_FRAGMENT = re.compile('^egg=([-A-Za-z0-9_.]+)$')
  24. HREF = re.compile('href\\s*=\\s*[\'"]?([^\'"> ]+)', re.I)
  25. PYPI_MD5 = re.compile('<a href="([^"#]+)">([^<]+)</a>\n\\s+\\(<a (?:title="MD5 hash"\n\\s+)href="[^?]+\\?:action=show_md5&digest=([0-9a-f]{32})">md5</a>\\)')
  26. URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match
  27. EXTENSIONS = '.tar.gz .tar.bz2 .tar .zip .tgz'.split()
  28. __all__ = [
  29.     'PackageIndex',
  30.     'distros_for_url',
  31.     'parse_bdist_wininst',
  32.     'interpret_distro_name']
  33.  
  34. def parse_bdist_wininst(name):
  35.     lower = name.lower()
  36.     (base, py_ver) = (None, None)
  37.     if lower.endswith('.exe'):
  38.         if lower.endswith('.win32.exe'):
  39.             base = name[:-10]
  40.         elif lower.startswith('.win32-py', -16):
  41.             py_ver = name[-7:-4]
  42.             base = name[:-16]
  43.         
  44.     
  45.     return (base, py_ver)
  46.  
  47.  
  48. def egg_info_for_url(url):
  49.     (scheme, server, path, parameters, query, fragment) = urlparse.urlparse(url)
  50.     base = urllib2.unquote(path.split('/')[-1])
  51.     if '#' in base:
  52.         (base, fragment) = base.split('#', 1)
  53.     
  54.     return (base, fragment)
  55.  
  56.  
  57. def distros_for_url(url, metadata = None):
  58.     (base, fragment) = egg_info_for_url(url)
  59.     for dist in distros_for_location(url, base, metadata):
  60.         yield dist
  61.     
  62.     if fragment:
  63.         match = EGG_FRAGMENT.match(fragment)
  64.         if match:
  65.             for dist in interpret_distro_name(url, match.group(1), metadata, precedence = CHECKOUT_DIST):
  66.                 yield dist
  67.             
  68.         
  69.     
  70.  
  71.  
  72. def distros_for_location(location, basename, metadata = None):
  73.     if basename.endswith('.egg.zip'):
  74.         basename = basename[:-4]
  75.     
  76.     if basename.endswith('.egg') and '-' in basename:
  77.         return [
  78.             Distribution.from_location(location, basename, metadata)]
  79.     for ext in EXTENSIONS:
  80.         if basename.endswith(ext):
  81.             basename = basename[:-len(ext)]
  82.             return interpret_distro_name(location, basename, metadata)
  83.     
  84.     return []
  85.  
  86.  
  87. def distros_for_filename(filename, metadata = None):
  88.     return distros_for_location(normalize_path(filename), os.path.basename(filename), metadata)
  89.  
  90.  
  91. def interpret_distro_name(location, basename, metadata, py_version = None, precedence = SOURCE_DIST, platform = None):
  92.     parts = basename.split('-')
  93.     if not py_version:
  94.         for i, p in enumerate(parts[2:]):
  95.             if len(p) == 5 and p.startswith('py2.'):
  96.                 return None
  97.         
  98.     
  99.     for p in range(1, len(parts) + 1):
  100.         yield Distribution(location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]), py_version = py_version, precedence = precedence, platform = platform)
  101.     
  102.  
  103. REL = re.compile('<([^>]*\\srel\\s*=\\s*[\'"]?([^\'">]+)[^>]*)>', re.I)
  104.  
  105. def find_external_links(url, page):
  106.     for match in REL.finditer(page):
  107.         (tag, rel) = match.groups()
  108.         rels = map(str.strip, rel.lower().split(','))
  109.         if 'homepage' in rels or 'download' in rels:
  110.             for match in HREF.finditer(tag):
  111.                 yield urlparse.urljoin(url, htmldecode(match.group(1)))
  112.             
  113.     
  114.     for tag in ('<th>Home Page', '<th>Download URL'):
  115.         pos = page.find(tag)
  116.         if pos != -1:
  117.             match = HREF.search(page, pos)
  118.             if match:
  119.                 yield urlparse.urljoin(url, htmldecode(match.group(1)))
  120.             
  121.         match
  122.     
  123.  
  124. user_agent = 'Python-urllib/%s setuptools/%s' % (urllib2.__version__, require('setuptools')[0].version)
  125.  
  126. class PackageIndex(Environment):
  127.     
  128.     def __init__(self, index_url = 'http://pypi.python.org/simple', hosts = ('*',), *args, **kw):
  129.         Environment.__init__(self, *args, **kw)
  130.         self.index_url = index_url + '/'[:not index_url.endswith('/')]
  131.         self.scanned_urls = { }
  132.         self.fetched_urls = { }
  133.         self.package_pages = { }
  134.         self.allows = re.compile('|'.join(map(translate, hosts))).match
  135.         self.to_scan = []
  136.  
  137.     
  138.     def process_url(self, url, retrieve = False):
  139.         if url in self.scanned_urls and not retrieve:
  140.             return None
  141.         self.scanned_urls[url] = True
  142.         if not URL_SCHEME(url):
  143.             self.process_filename(url)
  144.             return None
  145.         dists = list(distros_for_url(url))
  146.         if dists and not retrieve or url in self.fetched_urls:
  147.             map(self.add, dists)
  148.             return None
  149.         if not self.url_ok(url):
  150.             self.fetched_urls[url] = True
  151.             return None
  152.         self.info('Reading %s', url)
  153.         f = self.open_url(url, 'Download error: %s -- Some packages may not be found!')
  154.         if f is None:
  155.             return None
  156.         if 'html' not in f.headers.get('content-type', '').lower():
  157.             f.close()
  158.             return None
  159.         base = f.url
  160.         page = f.read()
  161.         f.close()
  162.         for match in HREF.finditer(page):
  163.             link = urlparse.urljoin(base, htmldecode(match.group(1)))
  164.             self.process_url(link)
  165.         
  166.  
  167.     
  168.     def process_filename(self, fn, nested = False):
  169.         if not os.path.exists(fn):
  170.             self.warn('Not found: %s', fn)
  171.             return None
  172.         if os.path.isdir(fn) and not nested:
  173.             path = os.path.realpath(fn)
  174.             for item in os.listdir(path):
  175.                 self.process_filename(os.path.join(path, item), True)
  176.             
  177.         
  178.         dists = distros_for_filename(fn)
  179.         if dists:
  180.             self.debug('Found: %s', fn)
  181.             map(self.add, dists)
  182.         
  183.  
  184.     
  185.     def url_ok(self, url, fatal = False):
  186.         s = URL_SCHEME(url)
  187.         if s or s.group(1).lower() == 'file' or self.allows(urlparse.urlparse(url)[1]):
  188.             return True
  189.         msg = '\nLink to % s ***BLOCKED*** by --allow-hosts\n'
  190.         if fatal:
  191.             raise DistutilsError(msg % url)
  192.         fatal
  193.         self.warn(msg, url)
  194.  
  195.     
  196.     def scan_egg_links(self, search_path):
  197.         for item in search_path:
  198.             if os.path.isdir(item):
  199.                 for entry in os.listdir(item):
  200.                     if entry.endswith('.egg-link'):
  201.                         self.scan_egg_link(item, entry)
  202.                         continue
  203.                 
  204.         
  205.  
  206.     
  207.     def scan_egg_link(self, path, entry):
  208.         lines = filter(None, map(str.strip, file(os.path.join(path, entry))))
  209.         if len(lines) == 2:
  210.             for dist in find_distributions(os.path.join(path, lines[0])):
  211.                 dist.location = os.path.join(path, *lines)
  212.                 dist.precedence = SOURCE_DIST
  213.                 self.add(dist)
  214.             
  215.         
  216.  
  217.     
  218.     def process_index(self, url, page):
  219.         
  220.         def scan(link):
  221.             if link.startswith(self.index_url):
  222.                 parts = map(urllib2.unquote, link[len(self.index_url):].split('/'))
  223.                 if len(parts) == 2 and '#' not in parts[1]:
  224.                     pkg = safe_name(parts[0])
  225.                     ver = safe_version(parts[1])
  226.                     self.package_pages.setdefault(pkg.lower(), { })[link] = True
  227.                     return (to_filename(pkg), to_filename(ver))
  228.             
  229.             return (None, None)
  230.  
  231.         for match in HREF.finditer(page):
  232.             scan(urlparse.urljoin(url, htmldecode(match.group(1))))
  233.         
  234.         (pkg, ver) = scan(url)
  235.         if pkg:
  236.             for new_url in find_external_links(url, page):
  237.                 (base, frag) = egg_info_for_url(new_url)
  238.                 if base.endswith('.py') and not frag:
  239.                     if ver:
  240.                         new_url += '#egg=%s-%s' % (pkg, ver)
  241.                     else:
  242.                         self.need_version_info(url)
  243.                 
  244.                 self.scan_url(new_url)
  245.             
  246.             return PYPI_MD5.sub((lambda m: '<a href="%s#md5=%s">%s</a>' % m.group(1, 3, 2)), page)
  247.         return ''
  248.  
  249.     
  250.     def need_version_info(self, url):
  251.         self.scan_all('Page at %s links to .py file(s) without version info; an index scan is required.', url)
  252.  
  253.     
  254.     def scan_all(self, msg = None, *args):
  255.         if self.index_url not in self.fetched_urls:
  256.             if msg:
  257.                 self.warn(msg, *args)
  258.             
  259.             self.info('Scanning index of all packages (this may take a while)')
  260.         
  261.         self.scan_url(self.index_url)
  262.  
  263.     
  264.     def find_packages(self, requirement):
  265.         self.scan_url(self.index_url + requirement.unsafe_name + '/')
  266.         if not self.package_pages.get(requirement.key):
  267.             self.scan_url(self.index_url + requirement.project_name + '/')
  268.         
  269.         if not self.package_pages.get(requirement.key):
  270.             self.not_found_in_index(requirement)
  271.         
  272.         for url in list(self.package_pages.get(requirement.key, ())):
  273.             self.scan_url(url)
  274.         
  275.  
  276.     
  277.     def obtain(self, requirement, installer = None):
  278.         self.prescan()
  279.         self.find_packages(requirement)
  280.         for dist in self[requirement.key]:
  281.             if dist in requirement:
  282.                 return dist
  283.             self.debug('%s does not match %s', requirement, dist)
  284.         
  285.         return super(PackageIndex, self).obtain(requirement, installer)
  286.  
  287.     
  288.     def check_md5(self, cs, info, filename, tfp):
  289.         if re.match('md5=[0-9a-f]{32}$', info):
  290.             self.debug('Validating md5 checksum for %s', filename)
  291.             if cs.hexdigest() != info[4:]:
  292.                 tfp.close()
  293.                 os.unlink(filename)
  294.                 raise DistutilsError('MD5 validation failed for ' + os.path.basename(filename) + '; possible download problem?')
  295.             cs.hexdigest() != info[4:]
  296.         
  297.  
  298.     
  299.     def add_find_links(self, urls):
  300.         for url in urls:
  301.             if self.to_scan is None and not URL_SCHEME(url) and url.startswith('file:') or list(distros_for_url(url)):
  302.                 self.scan_url(url)
  303.                 continue
  304.             self.to_scan.append(url)
  305.         
  306.  
  307.     
  308.     def prescan(self):
  309.         if self.to_scan:
  310.             map(self.scan_url, self.to_scan)
  311.         
  312.         self.to_scan = None
  313.  
  314.     
  315.     def not_found_in_index(self, requirement):
  316.         if self[requirement.key]:
  317.             meth = self.info
  318.             msg = "Couldn't retrieve index page for %r"
  319.         else:
  320.             meth = self.warn
  321.             msg = "Couldn't find index page for %r (maybe misspelled?)"
  322.         meth(msg, requirement.unsafe_name)
  323.         self.scan_all()
  324.  
  325.     
  326.     def download(self, spec, tmpdir):
  327.         if not isinstance(spec, Requirement):
  328.             scheme = URL_SCHEME(spec)
  329.             if scheme:
  330.                 found = self._download_url(scheme.group(1), spec, tmpdir)
  331.                 (base, fragment) = egg_info_for_url(spec)
  332.                 if base.endswith('.py'):
  333.                     found = self.gen_setup(found, fragment, tmpdir)
  334.                 
  335.                 return found
  336.             if os.path.exists(spec):
  337.                 return spec
  338.             
  339.             try:
  340.                 spec = Requirement.parse(spec)
  341.             except ValueError:
  342.                 os.path.exists(spec)
  343.                 os.path.exists(spec)
  344.                 scheme
  345.                 raise DistutilsError('Not a URL, existing file, or requirement spec: %r' % (spec,))
  346.             except:
  347.                 os.path.exists(spec)<EXCEPTION MATCH>ValueError
  348.             
  349.  
  350.         os.path.exists(spec)
  351.         return getattr(self.fetch_distribution(spec, tmpdir), 'location', None)
  352.  
  353.     
  354.     def fetch_distribution(self, requirement, tmpdir, force_scan = False, source = False, develop_ok = False):
  355.         self.info('Searching for %s', requirement)
  356.         skipped = { }
  357.         
  358.         def find(req):
  359.             for dist in self[req.key]:
  360.                 if dist.precedence == DEVELOP_DIST and not develop_ok:
  361.                     if dist not in skipped:
  362.                         self.warn('Skipping development or system egg: %s', dist)
  363.                         skipped[dist] = 1
  364.                         continue
  365.                     continue
  366.                 
  367.                 if dist in req:
  368.                     if dist.precedence <= SOURCE_DIST or not source:
  369.                         self.info('Best match: %s', dist)
  370.                         return dist.clone(location = self.download(dist.location, tmpdir))
  371.  
  372.         if force_scan:
  373.             self.prescan()
  374.             self.find_packages(requirement)
  375.         
  376.         dist = find(requirement)
  377.         if dist is None and self.to_scan is not None:
  378.             self.prescan()
  379.             dist = find(requirement)
  380.         
  381.         if dist is None and not force_scan:
  382.             self.find_packages(requirement)
  383.             dist = find(requirement)
  384.         
  385.         if dist is None:
  386.             if not source or 'a source distribution of ':
  387.                 pass
  388.             self.warn('No local packages or download links found for %s%s', '', requirement)
  389.         
  390.         return dist
  391.  
  392.     
  393.     def fetch(self, requirement, tmpdir, force_scan = False, source = False):
  394.         dist = self.fetch_distribution(requirement, tmpdir, force_scan, source)
  395.         if dist is not None:
  396.             return dist.location
  397.  
  398.     
  399.     def gen_setup(self, filename, fragment, tmpdir):
  400.         match = EGG_FRAGMENT.match(fragment)
  401.         if not match or _[1]:
  402.             pass
  403.         dists = []
  404.         if len(dists) == 1:
  405.             basename = os.path.basename(filename)
  406.             file = open(os.path.join(tmpdir, 'setup.py'), 'w')
  407.             file.write('from setuptools import setup\nsetup(name=%r, version=%r, py_modules=[%r])\n' % (dists[0].project_name, dists[0].version, os.path.splitext(basename)[0]))
  408.             file.close()
  409.             return filename
  410.         if match:
  411.             raise DistutilsError("Can't unambiguously interpret project/version identifier %r; any dashes in the name or version should be escaped using underscores. %r" % (fragment, dists))
  412.         match
  413.         raise DistutilsError("Can't process plain .py files without an '#egg=name-version' suffix to enable automatic setup script generation.")
  414.  
  415.     dl_blocksize = 8192
  416.     
  417.     def _download_to(self, url, filename):
  418.         self.info('Downloading %s', url)
  419.         (fp, tfp, info) = (None, None, None)
  420.         
  421.         try:
  422.             if '#' in url:
  423.                 (url, info) = url.split('#', 1)
  424.             
  425.             fp = self.open_url(url)
  426.             if isinstance(fp, urllib2.HTTPError):
  427.                 raise DistutilsError("Can't download %s: %s %s" % (url, fp.code, fp.msg))
  428.             isinstance(fp, urllib2.HTTPError)
  429.             cs = md5()
  430.             headers = fp.info()
  431.             blocknum = 0
  432.             bs = self.dl_blocksize
  433.             size = -1
  434.             if 'content-length' in headers:
  435.                 size = int(headers['Content-Length'])
  436.                 self.reporthook(url, filename, blocknum, bs, size)
  437.             
  438.             tfp = open(filename, 'wb')
  439.             while True:
  440.                 block = fp.read(bs)
  441.                 if block:
  442.                     cs.update(block)
  443.                     tfp.write(block)
  444.                     blocknum += 1
  445.                     self.reporthook(url, filename, blocknum, bs, size)
  446.                     continue
  447.                 break
  448.             if info:
  449.                 self.check_md5(cs, info, filename, tfp)
  450.             
  451.             return headers
  452.         finally:
  453.             if fp:
  454.                 fp.close()
  455.             
  456.             if tfp:
  457.                 tfp.close()
  458.             
  459.  
  460.  
  461.     
  462.     def reporthook(self, url, filename, blocknum, blksize, size):
  463.         pass
  464.  
  465.     
  466.     def open_url(self, url, warning = None):
  467.         if url.startswith('file:'):
  468.             return local_open(url)
  469.         
  470.         try:
  471.             return open_with_auth(url)
  472.         except urllib2.HTTPError:
  473.             url.startswith('file:')
  474.             v = url.startswith('file:')
  475.             return v
  476.             except urllib2.URLError:
  477.                 v = None
  478.                 if warning:
  479.                     self.warn(warning, v.reason)
  480.                 else:
  481.                     raise DistutilsError('Download error for %s: %s' % (url, v.reason))
  482.                 warning
  483.             else:
  484.                 return None
  485.  
  486.  
  487.     
  488.     def _download_url(self, scheme, url, tmpdir):
  489.         name = filter(None, urlparse.urlparse(url)[2].split('/'))
  490.         if name:
  491.             name = name[-1]
  492.             while '..' in name:
  493.                 name = name.replace('..', '.').replace('\\', '_')
  494.         else:
  495.             name = '__downloaded__'
  496.         if name.endswith('.egg.zip'):
  497.             name = name[:-4]
  498.         
  499.         filename = os.path.join(tmpdir, name)
  500.         if scheme == 'svn' or scheme.startswith('svn+'):
  501.             return self._download_svn(url, filename)
  502.         if scheme == 'file':
  503.             return urllib2.url2pathname(urlparse.urlparse(url)[2])
  504.         self.url_ok(url, True)
  505.         return self._attempt_download(url, filename)
  506.  
  507.     
  508.     def scan_url(self, url):
  509.         self.process_url(url, True)
  510.  
  511.     
  512.     def _attempt_download(self, url, filename):
  513.         headers = self._download_to(url, filename)
  514.         if 'html' in headers.get('content-type', '').lower():
  515.             return self._download_html(url, headers, filename)
  516.         return filename
  517.  
  518.     
  519.     def _download_html(self, url, headers, filename):
  520.         file = open(filename)
  521.         for line in file:
  522.             if line.strip():
  523.                 if re.search('<title>([^- ]+ - )?Revision \\d+:', line):
  524.                     file.close()
  525.                     os.unlink(filename)
  526.                     return self._download_svn(url, filename)
  527.                 break
  528.                 continue
  529.             re.search('<title>([^- ]+ - )?Revision \\d+:', line)
  530.         
  531.         file.close()
  532.         os.unlink(filename)
  533.         raise DistutilsError('Unexpected HTML page found at ' + url)
  534.  
  535.     
  536.     def _download_svn(self, url, filename):
  537.         url = url.split('#', 1)[0]
  538.         self.info('Doing subversion checkout from %s to %s', url, filename)
  539.         os.system('svn checkout -q %s %s' % (url, filename))
  540.         return filename
  541.  
  542.     
  543.     def debug(self, msg, *args):
  544.         log.debug(msg, *args)
  545.  
  546.     
  547.     def info(self, msg, *args):
  548.         log.info(msg, *args)
  549.  
  550.     
  551.     def warn(self, msg, *args):
  552.         log.warn(msg, *args)
  553.  
  554.  
  555. entity_sub = re.compile('&(#(\\d+|x[\\da-fA-F]+)|[\\w.:-]+);?').sub
  556.  
  557. def uchr(c):
  558.     if not isinstance(c, int):
  559.         return c
  560.     if c > 255:
  561.         return unichr(c)
  562.     return chr(c)
  563.  
  564.  
  565. def decode_entity(match):
  566.     what = match.group(1)
  567.     if what.startswith('#x'):
  568.         what = int(what[2:], 16)
  569.     elif what.startswith('#'):
  570.         what = int(what[1:])
  571.     else:
  572.         name2codepoint = name2codepoint
  573.         import htmlentitydefs
  574.         what = name2codepoint.get(what, match.group(0))
  575.     return uchr(what)
  576.  
  577.  
  578. def htmldecode(text):
  579.     return entity_sub(decode_entity, text)
  580.  
  581.  
  582. def open_with_auth(url):
  583.     (scheme, netloc, path, params, query, frag) = urlparse.urlparse(url)
  584.     if scheme in ('http', 'https'):
  585.         (auth, host) = urllib2.splituser(netloc)
  586.     else:
  587.         auth = None
  588.     if auth:
  589.         auth = 'Basic ' + urllib2.unquote(auth).encode('base64').strip()
  590.         new_url = urlparse.urlunparse((scheme, host, path, params, query, frag))
  591.         request = urllib2.Request(new_url)
  592.         request.add_header('Authorization', auth)
  593.     else:
  594.         request = urllib2.Request(url)
  595.     request.add_header('User-Agent', user_agent)
  596.     fp = urllib2.urlopen(request)
  597.     if auth:
  598.         (s2, h2, path2, param2, query2, frag2) = urlparse.urlparse(fp.url)
  599.         if s2 == scheme and h2 == host:
  600.             fp.url = urlparse.urlunparse((s2, netloc, path2, param2, query2, frag2))
  601.         
  602.     
  603.     return fp
  604.  
  605.  
  606. def fix_sf_url(url):
  607.     return url
  608.  
  609.  
  610. def local_open(url):
  611.     (scheme, server, path, param, query, frag) = urlparse.urlparse(url)
  612.     filename = urllib2.url2pathname(path)
  613.     if os.path.isfile(filename):
  614.         return urllib2.urlopen(url)
  615.     return urllib2.HTTPError(url, status, message, {
  616.         'content-type': 'text/html' }, cStringIO.StringIO(body))
  617.  
  618.