Class: Currency::Exchange::Rate::Source::Xe
- Defined in:
- lib/currency/exchange/rate/source/xe.rb
Overview
Connects to xe.com and parses “XE.com Quick Cross Rates” from home page HTML.
Constant Summary collapse
- PIVOT_CURRENCY =
Defines the pivot currency for xe.com/.
:USD
Instance Attribute Summary
Attributes inherited from Provider
Attributes inherited from Base
#pivot_currency, #time_quantitizer, #verbose
Instance Method Summary collapse
- #clear_rates ⇒ Object
- #eat_lines_until(rx) ⇒ Object
-
#initialize(*opt) ⇒ Xe
constructor
A new instance of Xe.
-
#load_rates(time = nil) ⇒ Object
Return a list of known base rates.
-
#name ⇒ Object
Returns ‘xe.com’.
-
#parse_page_rates(data = nil) ⇒ Object
Parses xe.com homepage HTML for quick rates of 10 currencies.
-
#raw_rates ⇒ Object
Returns a cached Hash of rates:.
Methods inherited from Provider
#available?, #date_DD, #date_MM, #date_YYYY, #get_page_content, #get_rate, #get_uri, #rates
Methods inherited from Base
#__subclass_responsibility, #clear_rate, #convert, #currencies, #get_rate, #get_rate_base, #get_rates, #new_rate, #normalize_time, #rate, #rates, #to_s
Constructor Details
#initialize(*opt) ⇒ Xe
Returns a new instance of Xe.
20 21 22 23 24 25 |
# File 'lib/currency/exchange/rate/source/xe.rb', line 20 def initialize(*opt) self.uri = 'http://xe.com/' self.pivot_currency = PIVOT_CURRENCY @raw_rates = nil super(*opt) end |
Instance Method Details
#clear_rates ⇒ Object
34 35 36 37 |
# File 'lib/currency/exchange/rate/source/xe.rb', line 34 def clear_rates @raw_rates = nil super end |
#eat_lines_until(rx) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/currency/exchange/rate/source/xe.rb', line 117 def eat_lines_until(rx) until @lines.empty? @line = @lines.shift if md = rx.match(@line) $stderr.puts "\nMATCHED #{@line.inspect} WITH #{rx.inspect} AT LINES:\n#{@lines[0..4].inspect}" if @verbose return md end yield @line if block_given? end raise ParserError, [ 'eat_lines_until failed', :rx, rx ] false end |
#load_rates(time = nil) ⇒ Object
Return a list of known base rates.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/currency/exchange/rate/source/xe.rb', line 134 def load_rates(time = nil) if time $stderr.puts "#{self}: WARNING CANNOT SUPPLY HISTORICAL RATES" unless @time_warning @time_warning = true end rates = raw_rates # Load rates rates_pivot = rates[PIVOT_CURRENCY] raise ::Currency::Exception::UnknownRate, [ "Cannot get base rate #{PIVOT_CURRENCY.inspect}", :pivot_currency, PIVOT_CURRENCY, ] unless rates_pivot result = rates_pivot.keys.collect do | c2 | new_rate(PIVOT_CURRENCY, c2, rates_pivot[c2], ) end result end |
#name ⇒ Object
Returns ‘xe.com’.
29 30 31 |
# File 'lib/currency/exchange/rate/source/xe.rb', line 29 def name 'xe.com' end |
#parse_page_rates(data = nil) ⇒ Object
Parses xe.com homepage HTML for quick rates of 10 currencies.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/currency/exchange/rate/source/xe.rb', line 53 def parse_page_rates(data = nil) data = get_page_content unless data doc = Hpricot(data) # xe.com no longer gives date/time. # Remove usecs. time = Time.at(Time.new.to_i).getutc = time # parse out the currency names in the table currency = [ ] doc.search("table.currency tr:first-child .c1").each do |td| currency.push(td.inner_text.strip.upcase.intern) end $stderr.puts "Found currencies: #{currency.inspect}" if @verbose raise ParserError, "Currencies header not found" if currency.empty? # Parse out the actual rates, dealing with the explanation gunk about which currency is worth more parsed_rates = doc.search(".currency tr:nth-child(2) td.c2.cA, .currency tr:nth-child(2) td.cLast").map do |e| if (inner = e.search('div.aboveLayer')).size > 0 inner.inner_text.strip else e.inner_text.strip end end rate = { } parsed_rates.each_with_index do |parsed_rate, i| usd_to_cur = parsed_rate.to_f cur = currency[i] raise ParserError, "Currency not found at column #{i}" unless cur next if cur.to_s == PIVOT_CURRENCY.to_s (rate[PIVOT_CURRENCY] ||= {})[cur] = usd_to_cur (rate[cur] ||= { })[PIVOT_CURRENCY] ||= 1.0 / usd_to_cur $stderr.puts "#{cur.inspect} => #{usd_to_cur}" if @verbose end raise ::Currency::Exception::UnavailableRates, "No rates found in #{get_uri.inspect}" if rate.keys.empty? raise ParserError, [ "Not all currencies found", :expected_currences, currency, :found_currencies, rate.keys, :missing_currencies, currency - rate.keys, ] if rate.keys.size != currency.size @lines = @line = nil raise ParserError, "Rate date not found" unless rate end |
#raw_rates ⇒ Object
Returns a cached Hash of rates:
xe.raw_rates[:USD][:CAD] => 1.0134
44 45 46 47 |
# File 'lib/currency/exchange/rate/source/xe.rb', line 44 def raw_rates # Force load of rates @raw_rates ||= parse_page_rates end |