diff --git a/README.md b/README.md new file mode 100644 index 0000000..7860804 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +realtime charts of amazon ec2 spot prices. \ No newline at end of file diff --git a/app/exchange.rb b/app/exchange.rb index ff00eea..67f5c40 100644 --- a/app/exchange.rb +++ b/app/exchange.rb @@ -1,3 +1,7 @@ +require 'time' +require 'rubygems' +require 'twitter' + class Exchange def regular_price(which) @@ -7,9 +11,92 @@ def regular_price(which) def spot_price(which) spot_price_map[which] end + + def update_prices + current = {} + ['us-east-1', 'us-west-1', 'eu-west-1'].each do |region| + fetch_region(region) + data = parse_region(region) + store_region(region, data) + + data.keys.each do |type| + which = "#{region}.#{type}" + price = data[type].last[1] + current[which] = price + end + end + store_prices(current) + end private + def fetch_region(region) + puts "#{Time.now} - fetching #{region}" + last = Time.parse(`tail -1 #{history_file(region)}`.split[2]) + open(history_file(region), 'a') do |file| + url = "https://#{region}.ec2.amazonaws.com" + start = last.strftime('%Y-%m-%dT%H:%M:%S') + `ec2-describe-spot-price-history --url #{url} --start-time #{start}`.each do |line| + if Time.parse(line.split[2]) > last + file.puts line + puts line + end + end + end + end + + def parse_region(region) + data = {} + open(history_file(region), 'r').each do |line| + col = line.split + price = col[1].to_f + stamp = Time.parse(col[2]).utc + inst = col[3] + os = col[4].split('/')[0].downcase + type = "#{os}.#{inst}" + values = data[type] ||= [] + values << [stamp - 1, values.last[1]] unless values.empty? + values << [stamp, price] + end + data.each do |type, values| + values << [Time.now.utc, values.last[1]] + end + data + end + + def store_region(region, data) + data.keys.each do |type| + which = "#{region}.#{type}" + atomic_write("#{data_dir}/#{which}.csv") do |file| + data[type].each do |stamp, price| + file.puts "#{stamp.strftime('%Y-%m-%d %H:%M:%S')},#{price}" + end + end + price = data[type].last[1] + percent = (price / regular_price(which) * 100).round + old_price = spot_price(which) + tweet(which, price, percent) if old_price and old_price.to_s != price.to_s + end + end + + def tweet(which, price, percent) + password = open(File.join(File.dirname(__FILE__), '..', '.twitter')).read.chomp + client = Twitter::Base.new(Twitter::HTTPAuth.new('cx_ticker', password)) + url = "http://cloudexchange.org/charts/#{which}.html" + message = "#{which} — $#{'%.3f' % price} — #{percent}% — #{url}" + puts message + client.update message + rescue Crack::ParseError => ignored + end + + def store_prices(data) + atomic_write("#{data_dir}/spot.csv") do |file| + data.each do |type, price| + file.puts "#{type},#{price}" + end + end + end + def regular_price_map @regular_price_map ||= price_map('regular') end @@ -26,9 +113,21 @@ def price_map(name) end result end + + def history_file(region) + "#{data_dir}/history.#{region}.txt" + end def data_dir "#{File.dirname(__FILE__)}/public/data" end + def atomic_write(path) + tmpfile = "/tmp/ruby.#{rand}" + open(tmpfile, 'w') do |file| + yield file + end + `mv #{tmpfile} #{path}` + end + end \ No newline at end of file diff --git a/app/updater.rb b/app/updater.rb new file mode 100755 index 0000000..a37bfca --- /dev/null +++ b/app/updater.rb @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby + +require File.join(File.dirname(__FILE__), 'exchange') + +exchange = Exchange.new +exchange.update_prices diff --git a/config/buildout.sh b/config/buildout.sh index 6111c26..abea068 100644 --- a/config/buildout.sh +++ b/config/buildout.sh @@ -55,13 +55,4 @@ vi .profile export PATH=$EC2_HOME/bin:$PATH #cronjob -crontab -e - - JAVA_HOME=/usr/lib/jvm/java-6-openjdk - EC2_URL=https://eu-west-1.ec2.amazonaws.com - EC2_PRIVATE_KEY=/home/ubuntu/.ec2/pk-TM374PQ4KXOLLOWN5DUYXYB3M3EX3IQP.pem - EC2_CERT=/home/ubuntu/.ec2/cert-TM374PQ4KXOLLOWN5DUYXYB3M3EX3IQP.pem - EC2_HOME=/home/ubuntu/ec2-api-tools-1.3-46266 - PATH=/home/ubuntu/ec2-api-tools-1.3-46266/bin:/opt/ruby/bin:/usr/local/bin:/usr/bin:/bin - - */5 * * * * /home/ubuntu/cloudexchange.org/fetch_history.rb >> /home/ubuntu/cloudexchange.org/cron.log 2>&1 \ No newline at end of file +crontab -e \ No newline at end of file