⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remote_installer.rb

📁 Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 经过两年开发后
💻 RB
📖 第 1 页 / 共 2 页
字号:
#--# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.# All rights reserved.# See LICENSE.txt for permissions.#++require 'rubygems'require 'socket'require 'fileutils'module Gem  class DependencyError < Gem::Exception; end  class RemoteSourceException < Gem::Exception; end  class GemNotFoundException < Gem::Exception; end  class RemoteInstallationCancelled < Gem::Exception; end  ####################################################################  # RemoteSourceFetcher handles the details of fetching gems and gem  # information from a remote source.    class RemoteSourceFetcher    include UserInteraction    # Initialize a remote fetcher using the source URI (and possible    # proxy information).      # +proxy+    # * [String]: explicit specification of proxy; overrides any    #   environment variable setting    # * nil: respect environment variables (HTTP_PROXY, HTTP_PROXY_USER, HTTP_PROXY_PASS)    # * <tt>:no_proxy</tt>: ignore environment variables and _don't_    #   use a proxy    def initialize(source_uri, proxy)      @uri = normalize_uri(source_uri)      @proxy_uri =      case proxy      when :no_proxy        nil      when nil        env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']        uri = env_proxy ? URI.parse(env_proxy) : nil        if uri and uri.user.nil? and uri.password.nil?          #Probably we have http_proxy_* variables?          uri.user = ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']          uri.password = ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']        end        uri      else        URI.parse(proxy.to_str)      end    end    # The uncompressed +size+ of the source's directory (e.g. source    # info).    def size      @size ||= get_size("/yaml")    end    # Fetch the data from the source at the given path.    def fetch_path(path="")      read_data(@uri + path)    end    # Get the source index from the gem source.  The source index is a    # directory of the gems available on the source, formatted as a    # Gem::Cache object.  The cache object allows easy searching for    # gems by name and version requirement.    #    # Notice that the gem specs in the cache are adequate for searches    # and queries, but may have some information elided (hence    # "abbreviated").    def source_index      say "Bulk updating Gem source index for: #{@uri}"      begin        require 'zlib'        yaml_spec = fetch_path("/yaml.Z")        yaml_spec = Zlib::Inflate.inflate(yaml_spec)      rescue        yaml_spec = nil      end      begin	yaml_spec = fetch_path("/yaml") unless yaml_spec	convert_spec(yaml_spec)      rescue SocketError => e	raise RemoteSourceException.new("Error fetching remote gem cache: #{e.to_s}")      end    end    private    # Normalize the URI by adding "http://" if it is missing.    def normalize_uri(uri)      (uri =~ /^(https?|ftp|file):/) ? uri : "http://#{uri}"    end    # Connect to the source host/port, using a proxy if needed.    def connect_to(host, port)      if @proxy_uri        Net::HTTP::Proxy(@proxy_uri.host, @proxy_uri.port, @proxy_uri.user, @proxy_uri.password).new(host, port)      else	Net::HTTP.new(host, port)      end    end        # Get the size of the (non-compressed) data from the source at the    # given path.    def get_size(path)      read_size(@uri + path)    end    # Read the size of the (source based) URI using an HTTP HEAD    # command.    def read_size(uri)      return File.size(get_file_uri_path(uri)) if is_file_uri(uri)      require 'net/http'      require 'uri'      u = URI.parse(uri)      http = connect_to(u.host, u.port)      path = (u.path == "") ? "/" : u.path      resp = http.head(path)      fail RemoteSourceException, "HTTP Response #{resp.code}" if resp.code !~ /^2/      resp['content-length'].to_i    end    # Read the data from the (source based) URI.    def read_data(uri)      begin    	open_uri_or_path(uri) do |input|    	  input.read    	end      rescue    	old_uri = uri    	uri = uri.downcase    	retry if old_uri != uri    	raise      end    end        # Read the data from the (source based) URI, but if it is a    # file:// URI, read from the filesystem instead.    def open_uri_or_path(uri, &block)      require 'rubygems/open-uri'      if is_file_uri(uri)        open(get_file_uri_path(uri), &block)      else        connection_options = {"User-Agent" => "RubyGems/#{Gem::RubyGemsVersion}"}        if @proxy_uri          http_proxy_url = "#{@proxy_uri.scheme}://#{@proxy_uri.host}:#{@proxy_uri.port}"            connection_options[:proxy_http_basic_authentication] = [http_proxy_url, @proxy_uri.user||'', @proxy_uri.password||'']        end                open(uri, connection_options, &block)      end    end        # Checks if the provided string is a file:// URI.    def is_file_uri(uri)      uri =~ %r{\Afile://}    end        # Given a file:// URI, returns its local path.    def get_file_uri_path(uri)      uri.sub(%r{\Afile://}, '')    end        # Convert the yamlized string spec into a real spec (actually,    # these are hashes of specs.).    def convert_spec(yaml_spec)      YAML.load(reduce_spec(yaml_spec)) or	fail "Didn't get a valid YAML document"    end    # This reduces the source spec in size so that YAML bugs with    # large data sets will be dodged.  Obviously this is a workaround,    # but it allows Gems to continue to work until the YAML bug is    # fixed.      def reduce_spec(yaml_spec)      result = ""      state = :copy      yaml_spec.each do |line|	if state == :copy && line =~ /^\s+files:\s*$/	  state = :skip	  result << line.sub(/$/, " []")	elsif state == :skip	  if line !~ /^\s+-/	    state = :copy	  end	end	result << line if state == :copy      end      result    end    class << self      # Sent by the client when it is done with all the sources,      # allowing any cleanup activity to take place.      def finish	# Nothing to do      end    end  end  ####################################################################  # Entrys held by a SourceInfoCache.  class SourceInfoCacheEntry    # The source index for this cache entry.    attr_reader :source_index    # The size of the of the source entry.  Used to determine if the    # source index has changed.    attr_reader :size    # Create a cache entry.    def initialize(si, size)      replace_source_index(si, size)    end    # Replace the source index and the index size with given values.    def replace_source_index(si, size)      @source_index = si || SourceIndex.new({})      @size = size    end  end  ####################################################################  # SourceInfoCache implements the cache management policy on where  # the source info is stored on local file system.  There are two  # possible cache locations: (1) the system wide cache, and (2) the  # user specific cache.  #  # * The system cache is prefered if it is writable (or can be  #   created).  # * The user cache is used if the system cache is not writable (or  #   can not be created).  #  # Once a cache is selected, it will be used for all operations.  It  # will not switch between cache files dynamically.  #  # Cache data is a simple hash indexed by the source URI.  Retrieving  # and entry from the cache data will return a SourceInfoCacheEntry.  #  class SourceInfoCache    # The most recent cache data.    def cache_data      @dirty = false      @cache_data ||= read_cache     end    # Write data to the proper cache.    def write_cache      data = cache_data      open(writable_file, "wb") do |f|        f.write Marshal.dump(data)      end    end    # The name of the system cache file.    def system_cache_file      @sysetm_cache ||= File.join(Gem.dir, "source_cache")    end    # The name of the user cache file.    def user_cache_file      @user_cache ||=	ENV['GEMCACHE'] || File.join(Gem.user_home, ".gem/source_cache")    end    # Mark the cache as updated (i.e. dirty).    def update      @dirty = true    end    # Write the cache to a local file (if it is dirty).    def flush      write_cache if @dirty      @dirty = false    end    private     # Find a writable cache file.    def writable_file      @cache_file    end    # Read the most current cache data.    def read_cache      @cache_file = select_cache_file      begin	open(@cache_file, "rb") { |f| load_local_cache(f) } || {}      rescue StandardError => ex	{}      end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -