Example #1
0
  def exists (self, filename):
    """Test whether `filename` is present at the remote host.

    :Parameters:
        `filename`: string
            Path to remote file relative to remote repository.

    :Return:
        - True unless remote file cannot be found.
    """

    # save full url in case of error
    _url = urljoin (self.pkg_url, filename)

    try:
      self._perform ({
        pycurl.URL: _url,
        pycurl.WRITEDATA: open ('/dev/null', 'wb'),  # discard headers
        pycurl.RANGE: '0-0',                         # fetch 1st byte only
        pycurl.NOPROGRESS: 1,
        pycurl.FAILONERROR: 1,
      })
    except depot.DepotFileNotFoundError:
      return False

    return True
Example #2
0
  def xml_file_filter (self, valid_depots, dep, found_depot_db_xml):
    # depot has suffixed file. Either:
    #   the package name + self.DB_SUFFIX
    #   or just self.XML_FILE
    db_filename = ''
    if dep.exists (self.XML_FILE):
      db_filename = self.XML_FILE
    else:
      for package in dep.packages:
        if dep.exists (package + self.DB_SUFFIX):
          db_filename = package + self.DB_SUFFIX
          break
      else:
        if found_depot_db_xml:
          valid_depots.append (dep)
        return True

    valid_depots.append (dep)

    self.msg_callback ('begin', 'reading ' +
                       urljoin (dep.pkg_url, db_filename), 2, VERBOSE_DEPOT)

    dep.fetch (db_filename)		# copy to local depot

    try:
      self.read_db_xml (dep, dep, db_filename)
      self.msg_callback ('end', 'done', 2, VERBOSE_DEPOT)

    except XMLError, msg:
      # Finish the callback output, and reraise the exception
      self.msg_callback ('end', 'failed', 2, VERBOSE_DEPOT)
      raise XMLError (str (msg))
Example #3
0
  def exists (self, filename):
    """Test whether `filename` is present at the remote host.

    :Parameters:
        `filename`: string
            Path to remote file relative to remote repository.

    :Return:
        - True unless remote file cannot be found.
    """

    # save full url in case of error
    _url = urljoin (self.pkg_url, filename)

    try:
      self._perform ({
        pycurl.URL: _url,
        pycurl.NOBODY: 1,
        pycurl.NOPROGRESS: 1,
        pycurl.FAILONERROR: 1,
      })
    except depot.DepotFileNotFoundError:
      return False

    return True
Example #4
0
  def __init__ (self, var, local_depot, dep, sub_depot):
    """Return an HTTP `Depot` object."""

    # This is better, but doesn't work for classic classes:
    #    super (http, self).__init__ (dep)
    # So, we're forced to hardcode the superclass for now:
    Depot.__init__ (self, dep)

    if type (dep) == types.InstanceType:
      self.var = dep.var
    else:
      self.var = var

    # full URL path where packages are to be found
    pkg_path = None
    if type (dep) == types.InstanceType:
      self.pkg_url = urljoin (dep.pkg_url, sub_depot)
    elif var is not None:
      # path to "root" of package directory
      pkg_path = var['dist']

      if pkg_path:
        self.pkg_url = urljoin (self.pkg_url, pkg_path)

    if not local_depot:
      return

    # make local depot mirror the directory structure of the
    # remote depot. This is to make it possible to specify the
    # path of the local depot as a depot to future sessions.
    if type (dep) == types.InstanceType:
      self.local_path = os.path.join (dep.local_path, sub_depot)
    else:
      if pkg_path:
        self.local_path = os.path.join (local_depot, pkg_path)
      else:
        self.local_path = local_depot

    if not os.path.exists (self.local_path):
      os.makedirs (self.local_path)
Example #5
0
  def __init__ (self, var, dep, sub_depot):
    # This is better, but doesn't work for classic classes:
    #    super (file, self).__init__ (dep)
    # So, we're forced to hardcode the superclass for now:
    Depot.__init__ (self, dep)

    if type (dep) == types.InstanceType:
      url = dep.url
      self.var = dep.var
    else:
      url = dep
      self.var = var

    self.local_path = urlparse (url).path

    # add to existing depot path
    if type (dep) == types.InstanceType:
      self.local_path = os.path.join (dep.local_path, sub_depot)
      self.pkg_url = urljoin (dep.pkg_url, sub_depot)
    else:
      if var and var['dist'] and os.path.exists (os.path.join (self.local_path, var['dist'])):
        self.local_path = os.path.join (self.local_path, var['dist'])
        self.pkg_url = urljoin (self.pkg_url, var['dist'])
Example #6
0
  def fetch (self, filename, progressmeter = None, fetched_bytes = 0,
             additional_bytes = 0):
    """Fetch a local copy of `filename` from the remote machine.

    :Parameters:
        `filename`: string
            Path to remote file relative to remote repository, also
            used for the name of the local copy.
        `progressmeter`: TextProgressMeter
            Re-use `progressmeter` for fetching related files.
        `fetched_bytes`: integer
            Number of bytes already fetched as previous files using
            this `progressmeter`.
        `additional_bytes`: integer
            Additional bytes yet to be downloaded with further files
            using this `progressmeter`.

    :Return:
        - Running total number of bytes downloaded so far in this file
          group.
    """

    # save full url in case of error
    _url = urljoin (self.pkg_url, filename)

    options = {
      pycurl.URL: _url,
      pycurl.WRITEDATA: open (os.path.join (self.local_path, filename), 'wb'),
      pycurl.NOPROGRESS: 1,
    }

    if progressmeter:
      # instantiate a new ProgressAdaptor for every file in the group
      adaptor = ProgressAdaptor (progressmeter, fetched_bytes, 
                                 additional_bytes)
      options[pycurl.PROGRESSFUNCTION] = adaptor.progress_cb
      options[pycurl.NOPROGRESS] = 0

    self._perform (options)

    if progressmeter is not None:
      fetched_bytes = adaptor.get_running_total ()

    return fetched_bytes
Example #7
0
  def set (self, depot_names, options = []):
    valid_depots = []			# depots we can use
    search_depots = False
    search_package_names = []		# packages to search for

    # make copy as invalid_package_callback might modify in place
    for package_name in self.package_names[:]:
      if not package_name.isfile ():
        # Unless we already have a local file, try to fetch the file from
        # (remote) url into a temporary local depot for processing later on.
        try:
          self.temp_package_dir = misclib.mkstempdir ()
        except misclib.MisclibTempDirCreationError, msg:
          raise DepotTempdirCreationError (src (msg))

        mysig.register (self.remove_temp_package_dir)

        dep = init (None, self.temp_package_dir,
                    package_name.remote_depot ())
        dep.indent_progressmeter = 2
        dep.verify_checksum = False
        self.depot_init (dep)

        if dep.exists (package_name.remote_path ()):
          # mysig.register() call above avoids a race if the program
          # exits with a signal, and the atexit.register() call below
          # ensures we also clean up when the program exits normally.
          atexit.register (self.remove_temp_package_dir, self.msg_callback)

          # To minimize chatter, only admit that we created a temporary
          # directory if we actually need it...
          self.msg_callback ('begin', 'creating temporary \
directory', 0, VERBOSE_LOCAL_DEPOT)
          self.msg_callback ('end', self.temp_package_dir,
                                     0, VERBOSE_LOCAL_DEPOT)
          io.stdout (0, '', 'retrieving ' +
                     package_name.geturl () + ' ...\n')
        elif package_name.getscheme () != 'file':
          raise DepotFileNotFoundError ('%s: File not found.' %
                                        package_name.geturl ())
        else:
          # ...otherwise, quietly remove it and pretend it was never
          # here (in which case we won't be needing the atexit handler
          # either):
          self.remove_temp_package_dir ()

        self.assign_depot_vars (dep)

        # If we successfully fetched a local copy of the remote file,
        # replace the remote package_name object with a file:// scheme
        # package_name:
        pkgfile = package_name.basename ()
        if dep.exists (pkgfile):
          dep.get (pkgfile, show_progress = True)
          package_name = \
            PackageName (os.path.join (self.temp_package_dir,
                                       pkgfile))

      if package_name.isfile ():
        path = package_name.normpath ()

        dep = init (None, self.local_depot, os.path.dirname (path))

        self.assign_depot_vars (dep)

        self.msg_callback ('begin', 'reading ' +
                urljoin (dep.pkg_url, os.path.basename (path)),
                0, VERBOSE_DEPOT)

        try:
          archive = self.archive_init (path)
          if archive:
            archive.path = path

            # set depot path to the archive file
            dep.local_path = path
            dep.url = package_name.getscheme () + "://" + path
            dep.archive = archive

            if archive.exists (self.XML_FILE):
              db_entry = self.read_db_xml (archive, dep, self.XML_FILE)
            elif archive.exists (os.path.basename (path)):
              db_entry = self.read_db_xml (archive, dep,
                                           os.path.basename (path))
            else:
              if self.invalid_package_callback:
                self.invalid_package_callback (package_name.name)

              self.msg_callback ('end', 'failed', 0, VERBOSE_DEPOT)
              self.msg_callback ('error', 'an input archive \
was specified but did not contain either a "%s" or "%s".  Archives \
must contain one of these files. skipping.' % (self.XML_FILE,
                                                 os.path.basename (path)))
              continue
          else:
            db_entry = self.read_db_xml (dep, dep, path)

          if not db_entry:
            self.msg_callback ('end', 'failed', 0, VERBOSE_DEPOT)
            self.msg_callback ('error', 'unable to parse the \
XML file. please check "%s". it does not appear to follow \
%s(4). skipping.' % (path, self.XML_FILE))
            continue

        except DepotArchiveInitError, msg:
          if self.invalid_package_callback:
            self.invalid_package_callback (package_name.name)

          self.msg_callback ('end', 'failed', 0, VERBOSE_DEPOT)
          self.msg_callback ('error', str (msg))
          continue
        except XMLError, msg:
          self.msg_callback ('end', 'failed', 0, VERBOSE_DEPOT)
          self.msg_callback ('error', str (msg))
          continue
Example #8
0
 def open (self, path, mode):
   if self.local_path and os.path.exists (self.local_path + '/' + path):
     return open (self.local_path + '/' + path, 'r')
   else:
     return (self.urlopen (urljoin (self.pkg_url, path)))
Example #9
0
        self.depots.append (dep)

      self.msg_callback ('end', 'reading depot databases', 0,
                         VERBOSE_DEPOT)

      #??? self.depots = self.verify_depots_callback (self.depots, options)

      for dep in self.depots:
        depot_db_xml = False		# if depot-db.xml exists
        db_xml = False			# if xx-db.xml exists

        if dep.archive:			# skip archives
          continue

        # if parent depot contains more depots, add to list
        self.msg_callback ('begin', urljoin (dep.pkg_url, 'depot-db.xml'),
                           2, VERBOSE_DEPOT)

        try:
          if dep.exists ('depot-db.xml'):
            depot_db_xml = True

            dep.fetch ('depot-db.xml')	# make copy in local depot

            self.msg_callback ('end', 'done', 2, VERBOSE_DEPOT)

            self.validate_xml_callback ('depot-db.xml', dep)

            sub_depots = depotdb.read_depotdb_xml ('depot-db.xml', dep)

            # create new depots
Example #10
0
 def sbdb_path (self, filename):
   return urljoin (self.pkg_url, filename)