diff --git a/Rakefile b/Rakefile index 5acfe49..1d9e6e1 100644 --- a/Rakefile +++ b/Rakefile @@ -4,6 +4,9 @@ task :migrate => :environment do ActiveRecord::Migrator.migrate 'migrations', (ENV['version'] ? ENV['version'].to_i : nil) end +def all_models + [User, Account, Day] +end namespace :fixtures do @@ -26,18 +29,11 @@ task :environment do require 'ohnomymoney' end -def all_models - [User, Account, Day] -end - -def fixture_dir - "fixtures" -end def restore_fixture(model) model.delete_all - YAML::load_file("#{fixture_dir}/#{model.table_name}.yml").each do |row| + YAML::load_file("fixtures/#{model.table_name}.yml").each do |row| record = model.new row.keys.each do |field| record[field] = row[field] if row[field] @@ -57,8 +53,8 @@ def dump_fixture(model) records << element end - FileUtils.mkdir_p fixture_dir - File.open("#{fixture_dir}/#{model.table_name}.yml", "w") do |file| + FileUtils.mkdir_p "fixtures" + File.open("fixtures/#{model.table_name}.yml", "w") do |file| YAML.dump data, file end diff --git a/charting.rb b/charting.rb new file mode 100644 index 0000000..1937ebc --- /dev/null +++ b/charting.rb @@ -0,0 +1,78 @@ +require 'google_chart' + +helpers do + + def chart_for(days) + oldest = days.first + newest = days[days.size-1] + balances = days.map {|day| day.balance} + + min = balances.min + max = balances.max + disparity = max - min + y = (disparity * 1.66).to_i + buffer = (y - disparity) / 2 + + y_min = round(min - buffer) + y_max = round(max + buffer) + y = y_max - y_min + y_step = round(y / 10.0, 2) + + x_step = days.size / 7 + x_step = 1 if x_step < 1 + x_days = [] + days.each_with_index {|b, i| x_days << b if i % x_step == 0} + x_days[0] = days[0] + x_days[-1] = days[-1] + + y_labels = (0..10).map {|i| format_balance(y_min + (y_step * i))} + x_labels = x_days.map {|day| format_date day.date_of} + + label = newest.balance > 0 ? 'Money' : 'Debt' + data = balances.map {|balance| (balance - y_min).to_f} + color = newest.balance > 0 ? '008800' : 'cc0000' + + chart = GoogleChart::LineChart.new '857x350' + chart.data_encoding = :text + chart.max_value y + chart.data label, data, color + chart.axis :x, :labels => x_labels + chart.axis :y, :labels => y_labels + chart.axis :right, :labels => y_labels + + p chart.to_url(:chdlp => 'b') + chart.to_url :chdlp => 'b' + end + + def round(n, level = 3) + (n - (n % (10**level))).to_i + end + + def double_encode(text) + text.gsub("&", "&") + end + + def format_balance(balance) + number = balance.to_f / 100 + parts = ("%01.2f" % number).split('.') + answer = '$' + number_with_delimiter(parts[0]) + '.' + parts[1].to_s + if number > 0 + answer = '+' + answer + elsif number < 0 + answer = '-' + answer + end + answer + end + + def number_with_delimiter(number) + number = number.to_i.abs + parts = number.to_s.split('.') + parts[0].gsub! /(\d)(?=(\d\d\d)+(?!\d))/, "\\1," + parts.join '.' + end + + def format_date(date) + date.strftime("%B ") + date.strftime("%d").gsub(/^0/, "") + end + +end \ No newline at end of file diff --git a/fixtures/accounts.yml b/fixtures/accounts.yml index 1800eed..c253052 100644 --- a/fixtures/accounts.yml +++ b/fixtures/accounts.yml @@ -20,12 +20,12 @@ - name: Credit Card created_at: 2010-02-15 01:55:20 -05:00 updated_at: 2010-02-15 02:23:49 -05:00 - account_type: debt + account_type: debts id: 4 user_id: 1 - name: Student Loans created_at: 2010-02-15 01:57:24 -05:00 updated_at: 2010-02-15 02:23:55 -05:00 - account_type: debt + account_type: debts id: 5 user_id: 1 diff --git a/models.rb b/models.rb index 2396389..50f7229 100644 --- a/models.rb +++ b/models.rb @@ -6,7 +6,7 @@ class Day < ActiveRecord::Base end class Account < ActiveRecord::Base - TYPES = %w( worth assets debt ) + TYPES = %w( worth assets debts ) belongs_to :user has_many :days @@ -15,10 +15,17 @@ class Account < ActiveRecord::Base validates_presence_of :user_id validates_inclusion_of :account_type, :in => TYPES + named_scope :worth, :conditions => {:account_type => 'worth'} + named_scope :assets, :conditions => {:account_type => 'assets'} + named_scope :debts, :conditions => {:account_type => 'debts'} def needs_name account_type != 'worth' end + + def balance + days.count > 0 ? days.first(:order => "created_at DESC").balance : 0 + end end class User < ActiveRecord::Base diff --git a/ohnomymoney.rb b/ohnomymoney.rb index 27ff3e1..5eb902e 100755 --- a/ohnomymoney.rb +++ b/ohnomymoney.rb @@ -4,6 +4,9 @@ require 'sinatra' require 'environment' +require 'erb' +require 'charting' + # For now, have the root URL act as if we visited the userpage of the first user before do request.path_info = "/#{User.first.handle}" if request.path_info == '/' @@ -12,5 +15,10 @@ get "/:handle" do halt 404 unless user = User.find_by_handle(params[:handle]) - user.accounts.all.map(&:name).join("
\n") + erb :index, :locals => { + :user => user, + :worth => user.accounts.worth.first, + :assets => user.accounts.assets.all, + :debts => user.accounts.debts.all + } end \ No newline at end of file diff --git a/views/index.erb b/views/index.erb new file mode 100644 index 0000000..ab65374 --- /dev/null +++ b/views/index.erb @@ -0,0 +1,29 @@ + + + + <%= user.name %>'s Money + + + +

<%= user.name %>'s Money

+ + + +
+ +
+ + + \ No newline at end of file