summaryrefslogtreecommitdiff
path: root/hgext/largefiles/proto.py
diff options
context:
space:
mode:
Diffstat (limited to 'hgext/largefiles/proto.py')
-rw-r--r--hgext/largefiles/proto.py173
1 files changed, 0 insertions, 173 deletions
diff --git a/hgext/largefiles/proto.py b/hgext/largefiles/proto.py
deleted file mode 100644
index de89e32..0000000
--- a/hgext/largefiles/proto.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright 2011 Fog Creek Software
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import os
-import urllib2
-
-from mercurial import error, httppeer, util, wireproto
-from mercurial.wireproto import batchable, future
-from mercurial.i18n import _
-
-import lfutil
-
-LARGEFILES_REQUIRED_MSG = ('\nThis repository uses the largefiles extension.'
- '\n\nPlease enable it in your Mercurial config '
- 'file.\n')
-
-def putlfile(repo, proto, sha):
- '''Put a largefile into a repository's local store and into the
- user cache.'''
- proto.redirect()
-
- path = lfutil.storepath(repo, sha)
- util.makedirs(os.path.dirname(path))
- tmpfp = util.atomictempfile(path, createmode=repo.store.createmode)
-
- try:
- try:
- proto.getfile(tmpfp)
- tmpfp._fp.seek(0)
- if sha != lfutil.hexsha1(tmpfp._fp):
- raise IOError(0, _('largefile contents do not match hash'))
- tmpfp.close()
- lfutil.linktousercache(repo, sha)
- except IOError, e:
- repo.ui.warn(_('largefiles: failed to put %s into store: %s') %
- (sha, e.strerror))
- return wireproto.pushres(1)
- finally:
- tmpfp.discard()
-
- return wireproto.pushres(0)
-
-def getlfile(repo, proto, sha):
- '''Retrieve a largefile from the repository-local cache or system
- cache.'''
- filename = lfutil.findfile(repo, sha)
- if not filename:
- raise util.Abort(_('requested largefile %s not present in cache') % sha)
- f = open(filename, 'rb')
- length = os.fstat(f.fileno())[6]
-
- # Since we can't set an HTTP content-length header here, and
- # Mercurial core provides no way to give the length of a streamres
- # (and reading the entire file into RAM would be ill-advised), we
- # just send the length on the first line of the response, like the
- # ssh proto does for string responses.
- def generator():
- yield '%d\n' % length
- for chunk in f:
- yield chunk
- return wireproto.streamres(generator())
-
-def statlfile(repo, proto, sha):
- '''Return '2\n' if the largefile is missing, '1\n' if it has a
- mismatched checksum, or '0\n' if it is in good condition'''
- filename = lfutil.findfile(repo, sha)
- if not filename:
- return '2\n'
- fd = None
- try:
- fd = open(filename, 'rb')
- return lfutil.hexsha1(fd) == sha and '0\n' or '1\n'
- finally:
- if fd:
- fd.close()
-
-def wirereposetup(ui, repo):
- class lfileswirerepository(repo.__class__):
- def putlfile(self, sha, fd):
- # unfortunately, httprepository._callpush tries to convert its
- # input file-like into a bundle before sending it, so we can't use
- # it ...
- if issubclass(self.__class__, httppeer.httppeer):
- res = None
- try:
- res = self._call('putlfile', data=fd, sha=sha,
- headers={'content-type':'application/mercurial-0.1'})
- d, output = res.split('\n', 1)
- for l in output.splitlines(True):
- self.ui.warn(_('remote: '), l, '\n')
- return int(d)
- except (ValueError, urllib2.HTTPError):
- self.ui.warn(_('unexpected putlfile response: %s') % res)
- return 1
- # ... but we can't use sshrepository._call because the data=
- # argument won't get sent, and _callpush does exactly what we want
- # in this case: send the data straight through
- else:
- try:
- ret, output = self._callpush("putlfile", fd, sha=sha)
- if ret == "":
- raise error.ResponseError(_('putlfile failed:'),
- output)
- return int(ret)
- except IOError:
- return 1
- except ValueError:
- raise error.ResponseError(
- _('putlfile failed (unexpected response):'), ret)
-
- def getlfile(self, sha):
- stream = self._callstream("getlfile", sha=sha)
- length = stream.readline()
- try:
- length = int(length)
- except ValueError:
- self._abort(error.ResponseError(_("unexpected response:"),
- length))
- return (length, stream)
-
- @batchable
- def statlfile(self, sha):
- f = future()
- result = {'sha': sha}
- yield result, f
- try:
- yield int(f.value)
- except (ValueError, urllib2.HTTPError):
- # If the server returns anything but an integer followed by a
- # newline, newline, it's not speaking our language; if we get
- # an HTTP error, we can't be sure the largefile is present;
- # either way, consider it missing.
- yield 2
-
- repo.__class__ = lfileswirerepository
-
-# advertise the largefiles=serve capability
-def capabilities(repo, proto):
- return capabilitiesorig(repo, proto) + ' largefiles=serve'
-
-# duplicate what Mercurial's new out-of-band errors mechanism does, because
-# clients old and new alike both handle it well
-def webprotorefuseclient(self, message):
- self.req.header([('Content-Type', 'application/hg-error')])
- return message
-
-def sshprotorefuseclient(self, message):
- self.ui.write_err('%s\n-\n' % message)
- self.fout.write('\n')
- self.fout.flush()
-
- return ''
-
-def heads(repo, proto):
- if lfutil.islfilesrepo(repo):
- return wireproto.ooberror(LARGEFILES_REQUIRED_MSG)
- return wireproto.heads(repo, proto)
-
-def sshrepocallstream(self, cmd, **args):
- if cmd == 'heads' and self.capable('largefiles'):
- cmd = 'lheads'
- if cmd == 'batch' and self.capable('largefiles'):
- args['cmds'] = args['cmds'].replace('heads ', 'lheads ')
- return ssholdcallstream(self, cmd, **args)
-
-def httprepocallstream(self, cmd, **args):
- if cmd == 'heads' and self.capable('largefiles'):
- cmd = 'lheads'
- if cmd == 'batch' and self.capable('largefiles'):
- args['cmds'] = args['cmds'].replace('heads ', 'lheads ')
- return httpoldcallstream(self, cmd, **args)