##// END OF EJS Templates
largefiles: add abstract methods in remotestore class...
liscju -
r28442:3be2e89c default
parent child Browse files
Show More
@@ -1,98 +1,113 b''
1 1 # Copyright 2010-2011 Fog Creek Software
2 2 # Copyright 2010-2011 Unity Technologies
3 3 #
4 4 # This software may be used and distributed according to the terms of the
5 5 # GNU General Public License version 2 or any later version.
6 6
7 7 '''remote largefile store; the base class for wirestore'''
8 8
9 9 import urllib2
10 10
11 11 from mercurial import util, wireproto, error
12 12 from mercurial.i18n import _
13 13
14 14 import lfutil
15 15 import basestore
16 16
17 17 class remotestore(basestore.basestore):
18 18 '''a largefile store accessed over a network'''
19 19 def __init__(self, ui, repo, url):
20 20 super(remotestore, self).__init__(ui, repo, url)
21 21
22 22 def put(self, source, hash):
23 23 if self.sendfile(source, hash):
24 24 raise error.Abort(
25 25 _('remotestore: could not put %s to remote store %s')
26 26 % (source, util.hidepassword(self.url)))
27 27 self.ui.debug(
28 28 _('remotestore: put %s to remote store %s\n')
29 29 % (source, util.hidepassword(self.url)))
30 30
31 31 def exists(self, hashes):
32 32 return dict((h, s == 0) for (h, s) in # dict-from-generator
33 33 self._stat(hashes).iteritems())
34 34
35 35 def sendfile(self, filename, hash):
36 36 self.ui.debug('remotestore: sendfile(%s, %s)\n' % (filename, hash))
37 37 fd = None
38 38 try:
39 39 fd = lfutil.httpsendfile(self.ui, filename)
40 40 return self._put(hash, fd)
41 41 except IOError as e:
42 42 raise error.Abort(
43 43 _('remotestore: could not open file %s: %s')
44 44 % (filename, str(e)))
45 45 finally:
46 46 if fd:
47 47 fd.close()
48 48
49 49 def _getfile(self, tmpfile, filename, hash):
50 50 try:
51 51 chunks = self._get(hash)
52 52 except urllib2.HTTPError as e:
53 53 # 401s get converted to error.Aborts; everything else is fine being
54 54 # turned into a StoreError
55 55 raise basestore.StoreError(filename, hash, self.url, str(e))
56 56 except urllib2.URLError as e:
57 57 # This usually indicates a connection problem, so don't
58 58 # keep trying with the other files... they will probably
59 59 # all fail too.
60 60 raise error.Abort('%s: %s' %
61 61 (util.hidepassword(self.url), e.reason))
62 62 except IOError as e:
63 63 raise basestore.StoreError(filename, hash, self.url, str(e))
64 64
65 65 return lfutil.copyandhash(chunks, tmpfile)
66 66
67 67 def _verifyfile(self, cctx, cset, contents, standin, verified):
68 68 filename = lfutil.splitstandin(standin)
69 69 if not filename:
70 70 return False
71 71 fctx = cctx[standin]
72 72 key = (filename, fctx.filenode())
73 73 if key in verified:
74 74 return False
75 75
76 76 verified.add(key)
77 77
78 78 expecthash = fctx.data()[0:40]
79 79 stat = self._stat([expecthash])[expecthash]
80 80 if not stat:
81 81 return False
82 82 elif stat == 1:
83 83 self.ui.warn(
84 84 _('changeset %s: %s: contents differ\n')
85 85 % (cset, filename))
86 86 return True # failed
87 87 elif stat == 2:
88 88 self.ui.warn(
89 89 _('changeset %s: %s missing\n')
90 90 % (cset, filename))
91 91 return True # failed
92 92 else:
93 93 raise RuntimeError('verify failed: unexpected response from '
94 94 'statlfile (%r)' % stat)
95 95
96 96 def batch(self):
97 97 '''Support for remote batching.'''
98 98 return wireproto.remotebatch(self)
99
100 def _put(self, hash, fd):
101 '''Put file with the given hash in the remote store.'''
102 raise NotImplementedError('abstract method')
103
104 def _get(self, hash):
105 '''Get file with the given hash from the remote store.'''
106 raise NotImplementedError('abstract method')
107
108 def _stat(self, hashes):
109 '''Get information about availability of files specified by
110 hashes in the remote store. Return dictionary mapping hashes
111 to return code where 0 means that file is available, other
112 values if not.'''
113 raise NotImplementedError('abstract method')
General Comments 0
You need to be logged in to leave comments. Login now