# HG changeset patch # User Benoit Boissinot # Date 1168897563 -3600 # Node ID 84e469ce64082c16a80d0fde84fc476e8c7d937f # Parent c9160748c0944a70aec247f66f30c1267c172ae0# Parent 9210fba03d169309b50507937392d84dce529735 merge with jsmith diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py --- a/hgext/patchbomb.py +++ b/hgext/patchbomb.py @@ -63,9 +63,9 @@ # # That should be all. Now your patchbomb is on its way out. -import os, errno, socket, time +import os, errno, socket import email.MIMEMultipart, email.MIMEText, email.Utils -from mercurial import cmdutil, commands, hg, mail, ui, patch +from mercurial import cmdutil, commands, hg, mail, ui, patch, util from mercurial.i18n import _ from mercurial.node import * @@ -164,10 +164,10 @@ def patchbomb(ui, repo, *revs, **opts): msg['X-Mercurial-Node'] = node return msg - start_time = int(time.time()) + start_time = util.makedate() def genmsgid(id): - return '<%s.%s@%s>' % (id[:20], start_time, socket.getfqdn()) + return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn()) patches = [] @@ -243,13 +243,6 @@ def patchbomb(ui, repo, *revs, **opts): mailer = mail.connect(ui) parent = None - # Calculate UTC offset - if time.daylight: offset = time.altzone - else: offset = time.timezone - if offset <= 0: sign, offset = '+', -offset - else: sign = '-' - offset = '%s%02d%02d' % (sign, offset / 3600, (offset % 3600) / 60) - sender_addr = email.Utils.parseaddr(sender)[1] for m in msgs: try: @@ -260,9 +253,10 @@ def patchbomb(ui, repo, *revs, **opts): m['In-Reply-To'] = parent else: parent = m['Message-Id'] - m['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(start_time)) + ' ' + offset + m['Date'] = util.datestr(date=start_time, + format="%a, %d %b %Y %H:%M:%S", timezone=True) - start_time += 1 + start_time = (start_time[0] + 1, start_time[1]) m['From'] = sender m['To'] = ', '.join(to) if cc: m['Cc'] = ', '.join(cc) @@ -280,7 +274,8 @@ def patchbomb(ui, repo, *revs, **opts): elif opts['mbox']: ui.status('Writing ', m['Subject'], ' ...\n') fp = open(opts['mbox'], m.has_key('In-Reply-To') and 'ab+' or 'wb+') - date = time.asctime(time.localtime(start_time)) + date = util.datestr(date=start_time, + format='%a %b %d %H:%M:%S %Y', timezone=False) fp.write('From %s %s\n' % (sender_addr, date)) fp.write(m.as_string(0)) fp.write('\n\n') diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -92,7 +92,7 @@ class bundlerevlog(revlog.revlog): if revb == rev1: return self.chunk(rev2) elif not self.bundle(rev1) and not self.bundle(rev2): - return revlog.revlog.chunk(self, rev1, rev2) + return revlog.revlog.revdiff(self, rev1, rev2) return self.diff(self.revision(self.node(rev1)), self.revision(self.node(rev2))) diff --git a/mercurial/httprepo.py b/mercurial/httprepo.py --- a/mercurial/httprepo.py +++ b/mercurial/httprepo.py @@ -75,17 +75,25 @@ def netlocunsplit(host, port, user=None, return userpass + '@' + hostport return hostport -class httpconnection(keepalive.HTTPConnection): - # must be able to send big bundle as stream. +class httpsendfile(file): + def __len__(self): + return os.fstat(self.fileno()).st_size - def send(self, data): - if isinstance(data, str): - keepalive.HTTPConnection.send(self, data) - else: +def _gen_sendfile(connection): + def _sendfile(self, data): + # send a file + if isinstance(data, httpsendfile): # if auth required, some data sent twice, so rewind here data.seek(0) for chunk in util.filechunkiter(data): - keepalive.HTTPConnection.send(self, chunk) + connection.send(self, chunk) + else: + connection.send(self, data) + return _sendfile + +class httpconnection(keepalive.HTTPConnection): + # must be able to send big bundle as stream. + send = _gen_sendfile(keepalive.HTTPConnection) class basehttphandler(keepalive.HTTPHandler): def http_open(self, req): @@ -96,15 +104,7 @@ if has_https: class httpsconnection(httplib.HTTPSConnection): response_class = keepalive.HTTPResponse # must be able to send big bundle as stream. - - def send(self, data): - if isinstance(data, str): - httplib.HTTPSConnection.send(self, data) - else: - # if auth required, some data sent twice, so rewind here - data.seek(0) - for chunk in util.filechunkiter(data): - httplib.HTTPSConnection.send(self, chunk) + send = _gen_sendfile(httplib.HTTPSConnection) class httphandler(basehttphandler, urllib2.HTTPSHandler): def https_open(self, req): @@ -344,14 +344,12 @@ class httprepository(remoterepository): break tempname = changegroup.writebundle(cg, None, type) - fp = file(tempname, "rb") + fp = httpsendfile(tempname, "rb") try: - length = os.stat(tempname).st_size try: rfp = self.do_cmd( 'unbundle', data=fp, - headers={'content-length': str(length), - 'content-type': 'application/octet-stream'}, + headers={'content-type': 'application/octet-stream'}, heads=' '.join(map(hex, heads))) try: ret = int(rfp.readline()) diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py --- a/mercurial/keepalive.py +++ b/mercurial/keepalive.py @@ -17,6 +17,9 @@ # This file is part of urlgrabber, a high-level cross-protocol url-grabber # Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko +# Modified by Benoit Boissinot: +# - fix for digest auth (inspired from urllib2.py @ Python v2.4) + """An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive. >>> import urllib2 @@ -302,28 +305,15 @@ class HTTPHandler(urllib2.HTTPHandler): return r def _start_transaction(self, h, req): + headers = req.headers.copy() + body = req.data + if sys.version_info >= (2, 4): + headers.update(req.unredirected_hdrs) try: - if req.has_data(): - data = req.get_data() - h.putrequest('POST', req.get_selector()) - if not req.headers.has_key('Content-type'): - h.putheader('Content-type', - 'application/x-www-form-urlencoded') - if not req.headers.has_key('Content-length'): - h.putheader('Content-length', '%d' % len(data)) - else: - h.putrequest('GET', req.get_selector()) - except (socket.error, httplib.HTTPException), err: + h.request(req.get_method(), req.get_selector(), body, headers) + except socket.error, err: # XXX what error? raise urllib2.URLError(err) - for args in self.parent.addheaders: - h.putheader(*args) - for k, v in req.headers.items(): - h.putheader(k, v) - h.endheaders() - if req.has_data(): - h.send(data) - class HTTPResponse(httplib.HTTPResponse): # we need to subclass HTTPResponse in order to # 1) add readline() and readlines() methods