HOWTO : easily create a Boot-Info summary

Boot-Repair is a simple tool to repair frequent boot issues you may encounter in Ubuntu like when you can’t boot Ubuntu after installing Windows or another Linux distribution, or when you can’t boot Windows after installing Ubuntu, or when GRUB is not displayed anymore, some upgrade breaks GRUB, etc.

Boot-Repair lets you fix these issues with a simple click, which (generally reinstalls GRUB and) restores access to the operating systems you had installed before the issue.

Boot-Repair also has advanced options to backup table partitions, backup bootsectors, create a Boot-Info-Summary (to get help by email or forum), or change the default repair parameters: configure GRUB, add kernel options (acpi=off …), purge GRUB, change the default OS, restore a Windows-compatible MBR, repair a broken filesystem, specify the disk where GRUB should be installed, etc.

Boot-Repair is a free software, licensed under GNU-GPL. Boot-Repair should be soon included in Ubuntu official repositories, until then use it at your own risks.

http://pix.toile-libre.org/upload/original/1335260967.png

 

Getting Boot-Repair

 

1st option : get a CD including Boot-Repair

The easiest way to use Boot-Repair is to burn one of the following disks and boot on it.

  • Boot-Repair-Disk is a CD starting Boot-Repair automatically. (English only, 32&64bits compatible, based on Debian-live so Wifi drivers are not recent).
  • Boot-Repair is also included in Ubuntu-Secure-Remix (multi-languages, ok for Wifi, based on Ubuntu 12.04 LTS, run Boot-Repair from the Dash)

Remark : you can also install the ISO on a live-USB (eg via UnetBootin, LiliUSB or MultiSystem).

 

2nd option : install Boot-Repair in Ubuntu

Remark: this can also be performed from a live-CD or live-USB.

Either add ‘ppa:yannubuntu/boot-repair’ to your Software Sources via the Software Centre or, for speeds-sake, add it using a new Terminal session:

 

sudo add-apt-repository ppa:yannubuntu/boot-repair && sudo apt-get update
sudo apt-get install -y boot-repair && boot-repair

Boot-Repair can be installed & used from any Ubuntu session (normal session, or live-CD, or live-USB). PPA packages are available for Ubuntu 10.04, 10.10, 11.04, 11.10 and 12.04.

 

Adding this PPA to your system

You can update your system with unsupported packages from this untrusted PPA by adding ppa:yannubuntu/boot-repair to your system’s Software Sources. (Read about installing)

This PPA can be added to your system manually by copying the lines below and adding them to your system’s software sources.

Display sources.list entries for:
deb http://ppa.launchpad.net/yannubuntu/boot-repair/ubuntu precise main
deb-src http://ppa.launchpad.net/yannubuntu/boot-repair/ubuntu precise main
Signing key:
1024R/60D8DA0B (What is this?)

Using Boot-Repair

 

  • launch Boot-Repair from either :
    • the dash (Unity)
    • System->Administration->Boot-Repair menu (Gnome)
    • by typing ‘boot-repair’ in a terminal
  • Then try “Recommended repair” button. When repair is finished, note the URL that appeared on a paper, then reboot and check if you recovered access to your OSs.

If the repair did not succeed, indicate the URL to people who help you by email or forum.

 

Advanced options

http://pix.toile-libre.org/upload/img/1335263156.png http://pix.toile-libre.org/upload/img/1335263804.png http://pix.toile-libre.org/upload/img/1335263271.png http://pix.toile-libre.org/upload/img/1335263417.png http://pix.toile-libre.org/upload/img/1335263366.png

 

External Links

Posted in Uncategorized

find_city

1. base on sina api

 

 
require 'json'

class FindCity
CityHash = JSON.parse `curl http://api.t.sina.com.cn/provinces.json`
def initialize
@cityhash=CityHash
@municipality=[6,11,12,50,81,82]
end
def getcity(province_id=nil, city_id=nil)
province_id.to_i
city_id.to_i
if @municipality.include? province_id
@cityhash["provinces"].each do |provinces|
if provinces["id"] == province_id
return provinces["name"]
end
end
else
@cityhash["provinces"].each do |provinces|
if provinces["id"] == province_id
provinces["citys"].each do |city|
return city[city_id.to_s] if city[city_id.to_s]
end
end
end
end
return nil
end
end

if __FILE__==$0
#************************以下测试代码*****************
time_start = Time.now
city = FindCity.new
list=[[6,2],[11,1],[43,2]]

list.each do |l|
puts city.getcity l[0],l[1]
end

puts "total time:#{Time.now-time_start}"
end

Posted in Uncategorized

Parse a web page and extract some json arrays

So I have some basic code below, which fetches the json from http://www.highcharts.com/demo/. But I want to be able to extract a hash, more specifically this:

series: [{
                    name: 'Tokyo',
                    data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
                }, {
                    name: 'New York',
                    data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
                }, {
                    name: 'Berlin',
                    data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
                }, {
                    name: 'London',
                    data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
                }]
            });

 

Into to a hash so that I can access the different data points. Currently the script just spits out everything. Code below:

require "json"
require "open-uri"


$LOAD_PATH << File.dirname(__FILE__)

result = JSON.parse(open("http://www.highcharts.com/demo/").read)

 

There is no direct conversion since source is JavaScript code (not even valid JSON). There are many ways to accomplish this task (one ways more strict than others, generic escaping control may be tricky), but that’s how I’d do it: HTML -> JS -> JSON -> Ruby array.

require 'open-uri'
require 'json'

html = open("http://www.highcharts.com/demo/").read
js = html.match(/series: ([{.*?}])/m)[1]
json = js.gsub(/(w+):/i, '"1":').gsub(/'/, '"')
series = JSON.parse(json)
# => [{"name"=>"Tokyo", "data"=>[7.0, 6.9, 9.5, 14.5, 18.2, ... 

 

Posted in Uncategorized

Devise logout link non-functional

Resources: http://stackoverflow.com/questions/6110047/rails-devise-override-sessionscontroller

the problem: In a nutshell, when I try to install a logout link to my app it fails to work. Here’s as much context as I can think to put here (if you want anything else, please poke me)…

I’ve got this in a haml view:

= link_to("Logout", destroy_user_session_path, :method => :delete) 

It generates this in the view:

<a href="/users/sign_out" data-method="delete" rel="nofollow">Logout</a> 

I verified that in my config/initializers/devise.rb I have this setting uncommented and correct:

config.sign_out_via = :delete 

I validated the following route:

destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"} 

I also have this bit of trickery in my routes.rb, and I suspect this is related to my issue:

devise_for :users, :controllers => {:sessions => "devise/sessions", :registrations => "users"} resources :users 

This last bit is because I want to manage (edit, create and delete) users in my own controller.

The error message I’m getting is as follows:

ActiveRecord::RecordNotFound in UsersController#show Couldn't find User with ID=sign_out Rails.root: /home/jaydel/projects/mbsquared-projects/Wilson-Goldrick app/controllers/users_controller.rb:16:in `show' 

In my server logs I see this for the request:

Started GET "/users/sign_out" for 127.0.0.1 at 2011-08-04 13:08:51 -0500   Processing by UsersController#show as HTML   Parameters: {"id"=>"sign_out"} 

Outside it’s slightly overcast and in the mid 80s. I’m wearing a red shirt.

Anyone have any ideas?

1

The problem lies in the fact that in your logs the signout request is a GET request.

Started GET "/users/sign_out" 

But the signout route is a DELETE

destroy_user_session DELETE /users/sign_out(.:format) 

The reason why you are getting the exception is that is it getting confused with one of the routes created by resources :users which would be something like

edit_user GET /users/(:id)(.:format) {:action=>"edit", :controller=>"users"} 

Basically ‘sign_out’ is being mistaken as a id.

I’m not sure why the delete link is not going through as a DELETE request. Though changing

config.sign_out_via = :delete 

to be :get might solve the problem.

2

I think the more correct way to fix this, REST-wise, would be to change your logout links to use the DELETE method. It’s a very easy fix, changing this:

link_to “Log out”, destroy_user_session_path

to this:

link_to “Log out”, destroy_user_session_path, :method => :delete

3

I had the same problem with rails 3.2 when I deleted from application.js this line:

//= require jquery_ujs 

So, I think you have to insert this line in your application.js if you haven’t it there.

PS. This behavior means that rails adapter for jquery doesn’t function. So you should make sure if it is loaded in your html in browser. You should test it in development mode because you will have compressed js in production and it will be very difficult to find something there.

 

 

Posted in Uncategorized

数据迁移(rake )

有时候我们的Rails应用是在已有数据库上的,我们需要把基于SQL的schema转化成ActiveRecord的schema

1,dump schema
运行rake db:schema:dump来将数据库中的表结构复制到db/schema.rb文件中
这时运行rake db:schema:load或者将schema.rb的内容copy到一个migration中并运行rake db:migrate会生成表
其中:force => true表示会覆盖数据库已存在的表,这样会让我们丢失数据库已有的data

2,migration的版本
Rails会自动生成schema_info表,该表的version列表示当前的migration的version,即migration文件开头的number
可以修改schema_info的version来控制要执行的migrate任务

3,避免丢失数据
一种方式是先从数据库extract fixtures,然后rake db:schema:load或rake db:migrate,并且:force => true,然后rake db:fixtures:load
另一种方式是修改schema_info的version来控制要执行的migrate任务

Posted in Uncategorized

使用ruby解析纯真IP库-qqwry.dat

在写一个地区相关的节能时,需要用到根据IP判断地区的功能,就想着找一个能够解析IP到地址的库。找了一下资料,国内用的比较多的IP库是早年就开始流行到现在的纯真IP库(QQrwy.dat),至于用ruby来解析纯真IP库的,则没找到几个,文章是不少,不过引用的几乎都是同样的代码,那个是比较早的ruby版本了,在1.9.2下跑的话,会有问题,我小改了一下,发现还是会有些问题,于是索性自己写一个吧。

要解析纯真IP库,对于该库的数据结构是必须要了解的,不多说,网上几乎唯一的纯真数据格式的说明就是这篇了  纯真IP数据库格式解析

格式并不算太复杂,主要是要注意偏移。纯真IP库的字符编码是GB2312的,而Windows下的命令行窗口也是GB2312编码,所以就不用转编码了。不过我是在linux下写的,所以默认编码用的是utf8,这也算是大势所趋么(也提供了GB编码的取得方式)。

代码如下,如果看过IP库格式的话,配上代码注释,应该是比较容易就懂的。

试了一下,查询1000次用时大概200毫秒左右

require 'iconv'

class IpSearch
def initialize(file='qqwry.dat')
filename = file
@file = File.open(filename,"r")
@index_first,@index_last = @file.read(8).unpack('L2')
@index_total = (@index_last - @index_first)/7 + 1
@location = {}
end

#把IP转换为长整形
def ip2long(ip)
long = 0
ip.split(/./).each_with_index do |b, i|
long += b.to_i << 8*(3-i)
end
long
end

#读取偏移值
def read_offset(position)
@file.seek position
chars = @file.read(3).unpack('C3')
(chars[2]<<16) + (chars[1]<<8) + chars[0]
end

#读取记录中的4字节作为一个long值
def read_long(position)
@file.seek position
@file.read(4).unpack('L')[0]
end

#读取模式信息,1和2为正常,其他值异常
#position:字符串偏移量
def read_mode(position)
@file.seek position #前4位为IP值
@file.read(1).unpack('C')[0]
end

#根据IP在索引中查找具体位置
def find_str_offset(ip_long)
offset_min,offset_max = @index_first,@index_last

while offset_min <= offset_max
offset_mid = offset_min + (offset_max - offset_min) / 14*7
mid = read_long(offset_mid)

if ip_long < mid
offset_max = offset_mid - 7
elsif ip_long == mid
return read_offset(offset_mid+4)
else
offset_min = offset_mid + 7
end
end

return read_offset(offset_max+4)
end

#读取字符串
def read_str(position)
@file.seek position
str = []
while c = @file.getc
break if str.size > 60 #地址不会太长,防止有异常数据
break if c == "

Posted in Uncategorized

How To: Allow users to sign in using their username or email address

For this example, we will assume your model is called User

Create a username field in the users table

  1. Create a migration:
     rails generate migration add_username_to_users username:string
  2. Run the migration:
     rake db:migrate
  3. Modify the User model and add username to attr_accessible
     attr_accessible :username

Create a login virtual attribute in Users

  1. Add login as an attr_accessor
    # Virtual attribute for authenticating by either username or email
    # This is in addition to a real persisted field like 'username'
    attr_accessor :login
  2. Add login to attr_accessible
    attr_accessible :login

Tell Devise to use :login in the authentication_keys

  1. Modify config/initializers/devise.rb to have:
     config.authentication_keys = [ :login ]
  • If you are using multiple models with Devise, it is best to set the authentication_keys on the model itself if the keys may differ:
    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable,
           :validatable, :authentication_keys => [:login]
  1. Overwrite Devise’s find_for_database_authentication method in Users model
  • For ActiveRecord:
     def self.find_for_database_authentication(warden_conditions)
       conditions = warden_conditions.dup
       login = conditions.delete(:login)
       where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.strip.downcase }]).first
     end
  • For Mongoid:
    Note: This code for Mongoid does some small things differently then the ActiveRecord code above. Would be great if someone could port the complete functionality of the ActiveRecord code over to Mongoid [basically you need to port the ‘where(conditions)’]. It is not required but will allow greater flexibility.

    field :email
    
    def self.find_for_database_authentication(conditions)
      login = conditions.delete(:login)
      self.any_of({ :username => login }, { :email => login }).first
    end
  • For MongoMapper:
    def self.find_for_database_authentication(conditions)
      login = conditions.delete(:login).downcase
      where('$or' => [{:username => login}, {:email => login}]).first
    end

Update your views

  1. Make sure you have the Devise views in your project so that you can customize them
    Rails 3:

     rails g devise:views

    Rails 2:

     script/generate devise_views
  2. Modify the views
    • sessions/new.html.erb:
      -  <p><%= f.label :email %><br />
      -  <%= f.email_field :email %></p>
      +  <p><%= f.label :login %><br />
      +  <%= f.text_field :login %></p>
    • registrations/new.html.erb
      +  <p><%= f.label :username %><br />
      +  <%= f.text_field :username %></p>
         <p><%= f.label :email %><br />
         <%= f.email_field :email %></p>
    • registrations/edit.html.erb
      +  <p><%= f.label :username %><br />
      +  <%= f.text_field :username %></p>
         <p><%= f.label :email %><br />
         <%= f.email_field :email %></p>

Manipulate the :login label that Rails will display

  1. Modify config/locales/en.yml to contain something like:
    Rails 2:

    activemodel:
      attributes:
        user:
          login: "Username or email"

    Rails 3:

    en:
      activerecord:
        attributes:
          user:
            login: "Username or email"

Allow users to recover their password using either username or email address

This section assumes you have run through the steps in Allow users to Sign In using their username or password.

Tell Devise to use :login in the reset_password_keys

  1. Modify config/initializers/devise.rb to have:
     config.reset_password_keys = [ :login ]

Overwrite Devise’s finder methods in Users

  • For ActiveRecord:
     protected
    
     # Attempt to find a user by it's email. If a record is found, send new
     # password instructions to it. If not user is found, returns a new user
     # with an email not found error.
     def self.send_reset_password_instructions(attributes={})
       recoverable = find_recoverable_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
       recoverable.send_reset_password_instructions if recoverable.persisted?
       recoverable
     end
    
     def self.find_recoverable_or_initialize_with_errors(required_attributes, attributes, error=:invalid)
       (case_insensitive_keys || []).each { |k| attributes[k].try(:downcase!) }
    
       ###the has some error in my issue, my you should comment two line bellow
       attributes = attributes.slice(*required_attributes)
       attributes.delete_if { |key, value| value.blank? }
    
       if attributes.size == required_attributes.size
         if attributes.has_key?(:login)
            login = attributes.delete(:login)
            record = find_record(login)
         else
           record = where(attributes).first
         end
       end
    
       unless record
         record = new
    
         required_attributes.each do |key|
           value = attributes[key]
           record.send("#{key}=", value)
           record.errors.add(key, value.present? ? error : :blank)
         end
       end
       record
     end
    
     def self.find_record(login)
       where(["username = :value OR email = :value", { :value => login }]).first
     end
  • For Mongoid:
def self.find_record(login)
  found = where(:username => login).to_a
  found = where(:email => login).to_a if found.empty?
  found
end

For Mongoid this can be optimized using a custom javascript function

def self.find_record(login)
  where("function() {return this.username == '#{login}' || this.email == '#{login}'}")
end
  • For MongoMapper:
def self.find_record(login)
  (self.where(:email => login[:login]).first || self.where(:username => login[:login]).first) rescue nil
end

Update your views

  1. Modify the views
    • passwords/new.html.erb:
      -  <p><%= f.label :email %><br />
      -  <%= f.email_field :email %></p>
      +  <p><%= f.label :login %><br />
      +  <%= f.text_field :login %></p>

Gmail or me.com Style

Another way to do this is me.com and gmail style. You allow an email or the username of the email. For public facing accounts, this has more security. Rather than allow some hacker to enter a username and then just guess the password, they would have no clue what the user’s email is. Just to make it easier on the user for logging in, allow a short form of their email to be used e.g “someone@domain.com” or just “someone” for short.

before_create :create_login

  def create_login
    email = self.email.split(/@/)
    login_taken = User.where( :login => email[0]).first
    unless login_taken
      self.login = email[0]
    else
      self.login = self.email
    end
  end

  def self.find_for_database_authentication(conditions)
    self.where(:login => conditions[:email]).first || self.where(:email => conditions[:email]).first
  end

For the Rails 2 version (1.0 tree): There is no find_for_database_authentication method, so use self.find_for_authentication as the finding method.

def self.find_for_authentication(conditions)
  conditions = ["username = ? or email = ?", conditions[authentication_keys.first], conditions[authentication_keys.first]]
  super
end
Posted in Uncategorized

How use the collection type model column怎样使用集合类型的模型字段

For example you have bellow code in migrate folder

# 0: <20, 1: 20< <=25 , 2: 25< <=30, 3: 30< <=35, 4: 35< <=40, 5: 40<
add_column :profiles, :agerange, :integer

and then how to use it:

for model file:

# 0: <20, 1: 20< <=25 , 2: 25< <=30, 3: 30< <=35, 4: 35< <=40, 5: 40<
A20 = 0
A20_25 = 1
A25_30 = 2
A30_35 = 3
A35_40 = 4
A40 = 5

AGERANGE = {
A20 => "#{I18n.t("activerecord.attributes.profiles.agerange.A20")}",
A20_25 => "#{I18n.t("activerecord.attributes.profiles.agerange.A20_25")}",
A25_30 => "#{I18n.t("activerecord.attributes.profiles.agerange.A25_30")}",
A30_35 => "#{I18n.t("activerecord.attributes.profiles.agerange.A30_35")}",
A35_40 => "#{I18n.t("activerecord.attributes.profiles.agerange.A35_40")}",
A40 => "#{I18n.t("activerecord.attributes.profiles.agerange.A40")}",
}

validates_inclusion_of :agerange, :in => AGERANGE.keys,
:message => "{{value}} must be in #{AGERANGE.values.join ','}"

# just a helper method for the view
def age_range
AGERANGE[agerange]
end

and then how use them in ‘form‘ and ’show‘ page
in form.html.erb


<%= f.label :agerange, t("activerecord.attributes.profiles.agerange_label") %>
<%= select_tag(:agerange, options_for_select(Profile::AGERANGE.invert)) %>

in show.html.erb
<%= s.attribute :age_range %>
Posted in Uncategorized

5 个常见的 Rails 开发误区

本文作者是一名Rails开发者,他总结了在Rails开发过程中的一些常见误区。文章内容如下:

我使用Rails已经有一段时间了,在这期间我看了大量的Rails项目,下面的这五个常见的误区,我几乎在每一个Rails代码中都看到过。

1.  没有 schema 规范的迁移

数据模型是应用程序的核心。没有schema的约束,你的数据会因为项目代码上的bugs而慢慢变得糟糕,直到你无法相信库中的任何字段。这里有一个 Concact Schema:

create_table "contacts" do |t|
    t.integer  "user_id"
    t.string   "name"
    t.string   "phone"
    t.string   "email"
end
上面哪些需要更改呢?通常一个Contact必须依附于User,并且会有一个name 属性,这可以使用数据库约束来确保。可以添加“:null => false”,这样即使验证代码存在bugs,我们依然可以确保模型一致性,因为如果违反了null约束,数据库并不会允许模型保存这些数据。
create_table "contacts" do |t|
    t.integer  "user_id", :null => false
    t.string   "name", :null => false
    t.string   "phone"
    t.string   "email"
end
TIPS:使用“:limit => N”规范你的string类型字段的大小。Strings 默认255个字符,而phone字段应该不需要这么长吧!
2.  面向对象编程 

大多数Rails开发人员并不写面向对象的代码。他们通常会在项目中写面向MVC的Ruby代码(把模型和控制器分开写在合适的位置)。通常是在lib目录下添加带有类方法的工具模块,仅此而已。但开发人员往往需要花费2-3年才能认识到“Rails就是Ruby。我完全可以创建一些简单的对象,并且不一定按照Rails建议的方式去封装它们。” 

TIPS:对你调用的第三方服务使用facade(外观模式)。通过在测试中提供mock facade,你就不用在你的测试集中真的去调用这些第三方服务了。
3.  在 helpers中连接HTML 

如果你正在创建helper,恭喜,至少说明你正在试图让你的视图层更整洁。但是开发人员经常不知道一些使用helpers创建标签的常见方式,这就导致了槽糕的字符串连接或者糟糕的插值形式。
str = "<li class='vehicle_list'> "
str += link_to("#{vehicle.title.upcase} Sale", show_all_styles_path(vehicle.id, vehicle.url_title))
str += " </li>"
str.html_safe
看吧,相当糟糕,而且容易导致XSS安全漏洞!让 content_tag 来拯救这些代码吧。
content_tag :li, :class => 'vehicle_list' do
  link_to("#{vehicle.title.upcase} Sale", show_all_styles_path(vehicle.id, vehicle.url_title))
end
TIPS:现在就开始在helper中使用blocks(代码块)吧。当产生内嵌的HTML时,嵌入的blocks更自然、更贴切。 

4.  Giant Queries(大查询,比如载入整张表的查询)会把一切都加载到内存 

如果你需要修正数据,你只需要遍历并且修正它,对吗?
User.has_purchased(true).each do |customer|
  customer.grant_role(:customer)
end
假设你有个百万级别客户的电商网站,假设每个用户对象需要500字节,上面的代码会在运行的时候消耗500M内存。 

下面是更好的方式:
User.has_purchased(true).find_each do |customer|
  customer.grant_role(:customer)
end
find_each使用 find_in_batches 每次取出1000条记录,非常有效的降低了对内存的需求。 

TIPS:使用 update_all 或者原始 SQL 语句执行大的更新操作。学习SQL可能需要花费点时间,不过带来的好处是明显的:你会看到100x的性能改善。 

5.  代码审查 

我猜你会使用GitHub,并且我进一步猜测你不会去pull requests(GitHub上的申请代码合并操作)。如果你需要花费一到两天去构建一个新特性,那么到一个分支上去做吧,然后发送一个 pull request。团队会审查你的代码,并且给出一些你没有考虑到的改进或者最新特性的建议。我保证这样会提高你的代码质量。我们在TheClymb项目中90%的改动都是通过这种方式完成的,并且这是100%值得去做的一个经验。 

TIPS:不要没有经过任何测试就合并你的pull request。测试对保证应用的稳定性非常有价值,并且可以让你踏实地睡一个好觉。
Posted in Uncategorized

RVM 下载 加速 -by liuhui998

今天晚上有点时间,我就折腾了一下 rails。

按照这个教程,我一步步的进行安装。

正如我之前听说的 rvm 下载 ruby 的速度只有不到5KB/s 速度。

在 google 了二圈后,我发现国内外好像没有人解决这个问题。

于是我发扬geek精神,开始打起了 rvm 源代码的主意:

1) rvm 是从 ruby-lang.org 这个站点下载 ruby 的源代码
rvm 慢的主要是因为 ruby-lang.org 这个网站下载速度慢

2) 如果找到 ruby-lang.org 的更快的镜像网站,并修改 rvm 里面的配置
这个问题也就解决了

于是找到一个叫 UK Mirror Service 的网站,它提供了 ruby-lang.org 镜像服务:

http://www.mirrorservice.org/sites/ftp.ruby-lang.org/

我测试了一下,平均速度最慢也超过 30KB/s

好的镜像找到了,那么下一步就是在哪里修改 ruby 下载地址。

 

<code>cd $rvm_path grep -nR "ruby-lang.org" ./</code>

 

 

发现地址是写在 $rvm_path/config/db 文件里

找到这一段:

ruby_1.0_url=http://ftp.ruby-lang.org/pub/ruby/1.0
ruby_1.2_url=http://ftp.ruby-lang.org/pub/ruby/1.2
ruby_1.3_url=http://ftp.ruby-lang.org/pub/ruby/1.3
ruby_1.4_url=http://ftp.ruby-lang.org/pub/ruby/1.4
ruby_1.5_url=http://ftp.ruby-lang.org/pub/ruby/1.5
ruby_1.6_url=http://ftp.ruby-lang.org/pub/ruby/1.6
ruby_1.7_url=http://ftp.ruby-lang.org/pub/ruby/1.7
ruby_1.8_url=http://ftp.ruby-lang.org/pub/ruby/1.8
ruby_1.9_url=http://ftp.ruby-lang.org/pub/ruby/1.9
ruby_2.0_url=http://ftp.ruby-lang.org/pub/ruby/2.0

改成

ruby_1.0_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.0
ruby_1.2_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.2
ruby_1.3_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.3
ruby_1.4_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.4
ruby_1.5_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.5
ruby_1.6_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.6
ruby_1.7_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.7
ruby_1.8_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.8
ruby_1.9_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.9
ruby_2.0_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/2.0

我已把这个修攺提交到我们仓库里 http://github.com/liuhui998/rvm
可以直接点击下载我改好后的 文件

大家改好 $rvm_path/config/db 文件后,最好能重启终端程序后再执行 rvm install 命令
这样新的 mirror 就会起效。

经过测试,改进后的 rvm, 在家中4M 以太网的速度可以达到200KB/s.

其本上解决了 rvm 下载 ruby 慢的问题。

Posted in Uncategorized