hgext/lfs/blobstore.py
changeset 40661 380f5131ee7b
parent 40660 9f78d10742af
child 40662 93e5d18251d6
equal deleted inserted replaced
40660:9f78d10742af 40661:380f5131ee7b
    15 import socket
    15 import socket
    16 
    16 
    17 from mercurial.i18n import _
    17 from mercurial.i18n import _
    18 
    18 
    19 from mercurial import (
    19 from mercurial import (
       
    20     encoding,
    20     error,
    21     error,
    21     pathutil,
    22     pathutil,
    22     pycompat,
    23     pycompat,
    23     url as urlmod,
    24     url as urlmod,
    24     util,
    25     util,
    25     vfs as vfsmod,
    26     vfs as vfsmod,
    26     worker,
    27     worker,
       
    28 )
       
    29 
       
    30 from mercurial.utils import (
       
    31     stringutil,
    27 )
    32 )
    28 
    33 
    29 from ..largefiles import lfutil
    34 from ..largefiles import lfutil
    30 
    35 
    31 # 64 bytes for SHA256
    36 # 64 bytes for SHA256
   228 
   233 
   229     def has(self, oid):
   234     def has(self, oid):
   230         """Returns True if the local blobstore contains the requested blob,
   235         """Returns True if the local blobstore contains the requested blob,
   231         False otherwise."""
   236         False otherwise."""
   232         return self.cachevfs.exists(oid) or self.vfs.exists(oid)
   237         return self.cachevfs.exists(oid) or self.vfs.exists(oid)
       
   238 
       
   239 def _urlerrorreason(urlerror):
       
   240     '''Create a friendly message for the given URLError to be used in an
       
   241     LfsRemoteError message.
       
   242     '''
       
   243     inst = urlerror
       
   244 
       
   245     if isinstance(urlerror.reason, Exception):
       
   246         inst = urlerror.reason
       
   247 
       
   248     if util.safehasattr(inst, 'reason'):
       
   249         try: # usually it is in the form (errno, strerror)
       
   250             reason = inst.reason.args[1]
       
   251         except (AttributeError, IndexError):
       
   252             # it might be anything, for example a string
       
   253             reason = inst.reason
       
   254         if isinstance(reason, pycompat.unicode):
       
   255             # SSLError of Python 2.7.9 contains a unicode
       
   256             reason = encoding.unitolocal(reason)
       
   257         return reason
       
   258     elif getattr(inst, "strerror", None):
       
   259         return encoding.strtolocal(inst.strerror)
       
   260     else:
       
   261         return stringutil.forcebytestr(urlerror)
   233 
   262 
   234 class _gitlfsremote(object):
   263 class _gitlfsremote(object):
   235 
   264 
   236     def __init__(self, repo, url):
   265     def __init__(self, repo, url):
   237         ui = repo.ui
   266         ui = repo.ui
   277                 404: _('the "lfs.url" config may be used to override %s')
   306                 404: _('the "lfs.url" config may be used to override %s')
   278                        % self.baseurl,
   307                        % self.baseurl,
   279             }
   308             }
   280             hint = hints.get(ex.code, _('api=%s, action=%s') % (url, action))
   309             hint = hints.get(ex.code, _('api=%s, action=%s') % (url, action))
   281             raise LfsRemoteError(_('LFS HTTP error: %s') % ex, hint=hint)
   310             raise LfsRemoteError(_('LFS HTTP error: %s') % ex, hint=hint)
       
   311         except util.urlerr.urlerror as ex:
       
   312             hint = (_('the "lfs.url" config may be used to override %s')
       
   313                     % self.baseurl)
       
   314             raise LfsRemoteError(_('LFS error: %s') % _urlerrorreason(ex),
       
   315                                  hint=hint)
   282         try:
   316         try:
   283             response = json.loads(rawjson)
   317             response = json.loads(rawjson)
   284         except ValueError:
   318         except ValueError:
   285             raise LfsRemoteError(_('LFS server returns invalid JSON: %s')
   319             raise LfsRemoteError(_('LFS server returns invalid JSON: %s')
   286                                  % rawjson)
   320                                  % rawjson)
   407         except util.urlerr.httperror as ex:
   441         except util.urlerr.httperror as ex:
   408             if self.ui.debugflag:
   442             if self.ui.debugflag:
   409                 self.ui.debug('%s: %s\n' % (oid, ex.read()))
   443                 self.ui.debug('%s: %s\n' % (oid, ex.read()))
   410             raise LfsRemoteError(_('HTTP error: %s (oid=%s, action=%s)')
   444             raise LfsRemoteError(_('HTTP error: %s (oid=%s, action=%s)')
   411                                  % (ex, oid, action))
   445                                  % (ex, oid, action))
       
   446         except util.urlerr.urlerror as ex:
       
   447             hint = (_('attempted connection to %s')
       
   448                     % util.urllibcompat.getfullurl(request))
       
   449             raise LfsRemoteError(_('LFS error: %s') % _urlerrorreason(ex),
       
   450                                  hint=hint)
   412 
   451 
   413     def _batch(self, pointers, localstore, action):
   452     def _batch(self, pointers, localstore, action):
   414         if action not in ['upload', 'download']:
   453         if action not in ['upload', 'download']:
   415             raise error.ProgrammingError('invalid Git-LFS action: %s' % action)
   454             raise error.ProgrammingError('invalid Git-LFS action: %s' % action)
   416 
   455