diff options
Diffstat (limited to 'project.py')
| -rw-r--r-- | project.py | 132 |
1 files changed, 30 insertions, 102 deletions
| @@ -20,19 +20,9 @@ import random | |||
| 20 | import re | 20 | import re |
| 21 | import shutil | 21 | import shutil |
| 22 | import stat | 22 | import stat |
| 23 | import subprocess | ||
| 23 | import sys | 24 | import sys |
| 24 | import time | 25 | import time |
| 25 | import urllib2 | ||
| 26 | |||
| 27 | try: | ||
| 28 | import threading as _threading | ||
| 29 | except ImportError: | ||
| 30 | import dummy_threading as _threading | ||
| 31 | |||
| 32 | try: | ||
| 33 | from os import SEEK_END | ||
| 34 | except ImportError: | ||
| 35 | SEEK_END = 2 | ||
| 36 | 26 | ||
| 37 | from color import Coloring | 27 | from color import Coloring |
| 38 | from git_command import GitCommand | 28 | from git_command import GitCommand |
| @@ -41,11 +31,10 @@ from error import DownloadError | |||
| 41 | from error import GitError, HookError, ImportError, UploadError | 31 | from error import GitError, HookError, ImportError, UploadError |
| 42 | from error import ManifestInvalidRevisionError | 32 | from error import ManifestInvalidRevisionError |
| 43 | from progress import Progress | 33 | from progress import Progress |
| 34 | from trace import IsTrace, Trace | ||
| 44 | 35 | ||
| 45 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M | 36 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M |
| 46 | 37 | ||
| 47 | _urllib_lock = _threading.Lock() | ||
| 48 | |||
| 49 | def _lwrite(path, content): | 38 | def _lwrite(path, content): |
| 50 | lock = '%s.lock' % path | 39 | lock = '%s.lock' % path |
| 51 | 40 | ||
| @@ -1553,100 +1542,39 @@ class Project(object): | |||
| 1553 | return ok | 1542 | return ok |
| 1554 | 1543 | ||
| 1555 | def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet): | 1544 | def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet): |
| 1556 | keep = True | 1545 | if os.path.exists(dstPath): |
| 1557 | done = False | 1546 | os.remove(dstPath) |
| 1558 | dest = open(tmpPath, 'a+b') | ||
| 1559 | try: | ||
| 1560 | dest.seek(0, SEEK_END) | ||
| 1561 | pos = dest.tell() | ||
| 1562 | 1547 | ||
| 1563 | _urllib_lock.acquire() | 1548 | cmd = ['curl', '--output', tmpPath, '--netrc', '--location'] |
| 1564 | try: | 1549 | if quiet: |
| 1565 | req = urllib2.Request(srcUrl) | 1550 | cmd += ['--silent'] |
| 1566 | if pos > 0: | 1551 | if os.path.exists(tmpPath): |
| 1567 | req.add_header('Range', 'bytes=%d-' % (pos,)) | 1552 | size = os.stat(tmpPath).st_size |
| 1568 | 1553 | if size >= 1024: | |
| 1569 | try: | 1554 | cmd += ['--continue-at', '%d' % (size,)] |
| 1570 | r = urllib2.urlopen(req) | 1555 | else: |
| 1571 | except urllib2.HTTPError, e: | 1556 | os.remove(tmpPath) |
| 1572 | def _content_type(): | 1557 | if 'http_proxy' in os.environ and 'darwin' == sys.platform: |
| 1573 | try: | 1558 | cmd += ['--proxy', os.environ['http_proxy']] |
| 1574 | return e.info()['content-type'] | 1559 | cmd += [srcUrl] |
| 1575 | except: | ||
| 1576 | return None | ||
| 1577 | |||
| 1578 | if e.code in (401, 403, 404): | ||
| 1579 | keep = False | ||
| 1580 | return False | ||
| 1581 | elif _content_type() == 'text/plain': | ||
| 1582 | try: | ||
| 1583 | msg = e.read() | ||
| 1584 | if len(msg) > 0 and msg[-1] == '\n': | ||
| 1585 | msg = msg[0:-1] | ||
| 1586 | msg = ' (%s)' % (msg,) | ||
| 1587 | except: | ||
| 1588 | msg = '' | ||
| 1589 | else: | ||
| 1590 | try: | ||
| 1591 | from BaseHTTPServer import BaseHTTPRequestHandler | ||
| 1592 | res = BaseHTTPRequestHandler.responses[e.code] | ||
| 1593 | msg = ' (%s: %s)' % (res[0], res[1]) | ||
| 1594 | except: | ||
| 1595 | msg = '' | ||
| 1596 | raise DownloadError('HTTP %s%s' % (e.code, msg)) | ||
| 1597 | except urllib2.URLError, e: | ||
| 1598 | raise DownloadError('%s: %s ' % (req.get_host(), str(e))) | ||
| 1599 | finally: | ||
| 1600 | _urllib_lock.release() | ||
| 1601 | |||
| 1602 | p = None | ||
| 1603 | try: | ||
| 1604 | size = pos + int(r.headers.get('content-length', 0)) | ||
| 1605 | unit = 1 << 10 | ||
| 1606 | 1560 | ||
| 1607 | if size and not quiet: | 1561 | if IsTrace(): |
| 1608 | if size > 1024 * 1.3: | 1562 | Trace('%s', ' '.join(cmd)) |
| 1609 | unit = 1 << 20 | 1563 | try: |
| 1610 | desc = 'MB' | 1564 | proc = subprocess.Popen(cmd) |
| 1611 | else: | 1565 | except OSError: |
| 1612 | desc = 'KB' | 1566 | return False |
| 1613 | p = Progress( | ||
| 1614 | 'Downloading %s' % (self.relpath,), | ||
| 1615 | int(size) / unit, | ||
| 1616 | units=desc) | ||
| 1617 | if pos > 0: | ||
| 1618 | p.update(pos / unit) | ||
| 1619 | |||
| 1620 | s = 0 | ||
| 1621 | while True: | ||
| 1622 | d = r.read(8192) | ||
| 1623 | if d == '': | ||
| 1624 | done = True | ||
| 1625 | return True | ||
| 1626 | dest.write(d) | ||
| 1627 | if p: | ||
| 1628 | s += len(d) | ||
| 1629 | if s >= unit: | ||
| 1630 | p.update(s / unit) | ||
| 1631 | s = s % unit | ||
| 1632 | if p: | ||
| 1633 | if s >= unit: | ||
| 1634 | p.update(s / unit) | ||
| 1635 | else: | ||
| 1636 | p.update(1) | ||
| 1637 | finally: | ||
| 1638 | r.close() | ||
| 1639 | if p: | ||
| 1640 | p.end() | ||
| 1641 | finally: | ||
| 1642 | dest.close() | ||
| 1643 | 1567 | ||
| 1644 | if os.path.exists(dstPath): | 1568 | ok = proc.wait() == 0 |
| 1645 | os.remove(dstPath) | 1569 | if os.path.exists(tmpPath): |
| 1646 | if done: | 1570 | if ok and os.stat(tmpPath).st_size > 16: |
| 1647 | os.rename(tmpPath, dstPath) | 1571 | os.rename(tmpPath, dstPath) |
| 1648 | elif not keep: | 1572 | return True |
| 1573 | else: | ||
| 1649 | os.remove(tmpPath) | 1574 | os.remove(tmpPath) |
| 1575 | return False | ||
| 1576 | else: | ||
| 1577 | return False | ||
| 1650 | 1578 | ||
| 1651 | def _Checkout(self, rev, quiet=False): | 1579 | def _Checkout(self, rev, quiet=False): |
| 1652 | cmd = ['checkout'] | 1580 | cmd = ['checkout'] |
