diff --git a/.gitignore b/.gitignore index d8d4f6fce..bba165748 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ gems/gems/* gems/specifications/* merb_profile_results misfit_fixtures/* +config/database.yml diff --git a/app/controllers/graph_data.rb b/app/controllers/graph_data.rb index 0c6a573aa..e9d5eebce 100644 --- a/app/controllers/graph_data.rb +++ b/app/controllers/graph_data.rb @@ -72,7 +72,7 @@ def branch(id) start_date = @branch.centers.clients.loans.min(:scheduled_disbursal_date) end_date = Date.today # (@client.loans.map { |l| l.last_loan_history_date }).max loan_ids = @branch.centers.clients.loans.all(:fields => [:id]).map { |x| x.id } - common_aggregate_loan_graph(loan_ids, start_date, end_date) + weekly_aggregate_loan_graph(loan_ids, start_date, end_date) end def total @@ -125,6 +125,7 @@ def aggregate_loan_graph(loan_ids, start_date, end_date) end def common_aggregate_loan_graph(loan_ids, start_date, end_date) # __DEPRECATED__ + debugger days = (end_date - start_date).to_i step_size = 1; i = 0 # make a nice round step size, not more than 20 steps while days/step_size > 50 @@ -135,8 +136,8 @@ def common_aggregate_loan_graph(loan_ids, start_date, end_date) # __DEPRECATED__ steps.times { |i| dates << start_date + step_size * i } @labels, @stacks, max_amount = [], [], 0 - p dates dates.each_with_index do |date, index| + t0 =Time.now future = date > Date.today s = LoanHistory.sum_outstanding_for(date, loan_ids)[0] scheduled_outstanding = (s['scheduled_outstanding_total'].to_i or 0) # or *_principal @@ -155,12 +156,80 @@ def common_aggregate_loan_graph(loan_ids, start_date, end_date) # __DEPRECATED__ { :val => [-overpaid, 0].max, :colour => (future ? '#ff5588' : '#aa0000'), :tip => "#{tip_base} shortfall of #{-overpaid} (#{percentage})" } ] @labels << ((index % step_size == 0) ? date.strftime("%b%d'%y") : '') + puts "Did t#{index} in total #{Time.now - t0} secs" + end + render_loan_graph('aggregate loan graph', @stacks, @labels, step_size, max_amount) + end + + def weekly_aggregate_loan_graph(loan_ids, start_date, end_date) + t0 =Time.now + step_size = 12 + structs = repository.adapter.query(%Q{ + SELECT da_te as date, weeknum, + SUM(scheduled_outstanding_principal) AS scheduled_outstanding_principal, + SUM(scheduled_outstanding_total) AS scheduled_outstanding_total, + SUM(actual_outstanding_principal) AS actual_outstanding_principal, + SUM(actual_outstanding_total) AS actual_outstanding_total + FROM (SELECT da_te, weeknum, + scheduled_outstanding_principal, + scheduled_outstanding_total, + actual_outstanding_principal, + actual_outstanding_total + FROM (SELECT loan_id, + max(date) as da_te, + concat(year(date),'_',week(date)) AS weeknum + FROM loan_history + WHERE loan_id IN (#{loan_ids.join(",")}) + GROUP BY loan_id, weeknum) AS dt, + loan_history lh + WHERE lh.loan_id = dt.loan_id + AND lh.date = dt.da_te) AS dt1 GROUP BY weeknum ORDER BY date;}) + + puts "Finished query in #{Time.now - t0}" + @labels, @stacks, max_amount = [], [], 0 + @t = nil + structs.each_with_index do |s, index| + # there is a problem with the week that spans two years as it gets spilt into 2008_52 and 2009_0 or similar + puts index + if @t + s['scheduled_outstanding_total'] += @t['scheduled_outstanding_total'] + s['actual_outstanding_total'] += @t['actual_outstanding_total'] + @t = nil + end + if index < structs.size - 1 and structs[index + 1]['weeknum'].index("_0") + @t = s + next + end + date = s['date'] + future = date > Date.today +# s = LoanHistory.sum_outstanding_for(date, loan_ids)[0] + scheduled_outstanding = (s['scheduled_outstanding_total'].to_i or 0) # or *_principal + actual_outstanding = future ? scheduled_outstanding : (s['actual_outstanding_total'].to_i or 0) # or *_principal + max_amount = [max_amount, scheduled_outstanding, actual_outstanding].max + overpaid = scheduled_outstanding - actual_outstanding # negative means shortfall + tip_base = "##{index+1}, #{date.strftime("%a %b %d %Y")}#{(future ? ' (future)' : '')}
" + percentage = scheduled_outstanding == 0 ? '0' : (overpaid.abs.to_f/scheduled_outstanding*100).round.to_s + '%' + @stacks << [ + { :val => [scheduled_outstanding, actual_outstanding].min, :colour => (future ? '#55aaff' : '#003d4a'), + :tip => tip_base + (future ? + "#{scheduled_outstanding.round} scheduled outstanding" : + "#{actual_outstanding.round} outstanding (#{percentage} #{overpaid > 0 ? 'overpaid' : 'shortfall'})") }, + { :val => [overpaid, 0].max, :colour => (future ? '#55ff55' : '#00aa00'), + :tip => "#{tip_base} overpaid #{ overpaid} (#{percentage})" }, + { :val => [-overpaid, 0].max, :colour => (future ? '#ff5588' : '#aa0000'), + :tip => "#{tip_base} shortfall of #{-overpaid} (#{percentage})" } ] + @labels << ((index % step_size == 0) ? date.strftime("%b%d'%y") : '') + puts "Did t#{index} in total #{Time.now - t0} secs" end render_loan_graph('aggregate loan graph', @stacks, @labels, step_size, max_amount) end + + + + def render_loan_graph(description, stacks, labels, step_size, max_amount) <<-JSON { "elements": [ { diff --git a/app/controllers/search.rb b/app/controllers/search.rb new file mode 100644 index 000000000..386db969b --- /dev/null +++ b/app/controllers/search.rb @@ -0,0 +1,12 @@ +class Search < Application + + def index + debugger + model = Kernel.const_get(params[:model]) + parameter = params[:by].snake_case.to_sym + @object = model.all( parameter => params[:value])[0] + raise NotFound unless @object + redirect "/#{model.to_s.snake_case.pluralize}/#{@object.id}" + end + +end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb new file mode 100644 index 000000000..2562ab65f --- /dev/null +++ b/app/helpers/search_helper.rb @@ -0,0 +1,5 @@ +module Merb + module SearchHelper + + end +end # Merb \ No newline at end of file diff --git a/app/models/#client.rb# b/app/models/#client.rb# new file mode 100644 index 000000000..f43d4148e --- /dev/null +++ b/app/models/#client.rb# @@ -0,0 +1,36 @@ +93235-55017 sandeep +class Client + include DataMapper::Resource + include Paperclip::Resource + before :valid?, :parse_dates + + property :id, Serial + property :reference, String, :length => 100, :nullable => false + property :name, String, :length => 100, :nullable => false + property :spouse_name, String, :length => 100 + property :date_of_birth, Date + property :address, Text + property :active, Boolean, :default => true, :nullable => false + property :date_joined, Date + + has_attached_file :picture, + :styles => {:medium => "300x300>", :thumb => "60x60#"}, + :url => "/uploads/:class/:id/:attachment/:style/:basename.:extension", + :path => "#{Merb.root}/public/uploads/:class/:id/:attachment/:style/:basename.:extension" + + has_attached_file :application_form, + :styles => {:medium => "300x300>", :thumb => "60x60#"}, + :url => "/uploads/:class/:id/:attachment/:style/:basename.:extension", + :path => "#{Merb.root}/public/uploads/:class/:id/:attachment/:style/:basename.:extension" + + has n, :loans + belongs_to :center + + validates_length :name, :min => 3 + validates_present :center + validates_is_unique :reference + + + private + include DateParser # mixin for the hook "before :valid?, :parse_dates" +end diff --git a/app/views/branches/index.html.haml b/app/views/branches/index.html.haml index 7a7f77e8f..690808808 100644 --- a/app/views/branches/index.html.haml +++ b/app/views/branches/index.html.haml @@ -2,10 +2,6 @@ / .graph / = ofc2(430, 200, 'http://' + (request.env['HTTP_HOST'] or 'example.org') + url(:graph_data, :action => 'total', :scope_unit => 'months', :scope_size => 3) ) -%form#loan_search{:action => "javascript:document.location='/loans/' + document.forms[0].loan_id.value;"} - Search for loan by id: - %input{:name => "loan_id"} - %input{:type => "submit"} %h1 Overview of all branches diff --git a/app/views/layout/application.html.haml b/app/views/layout/application.html.haml index d0ff0dd9e..833609d63 100644 --- a/app/views/layout/application.html.haml +++ b/app/views/layout/application.html.haml @@ -37,8 +37,26 @@  |  %b= link_to 'staff members', url(:staff_members)  |  + %b= link_to 'search', '#', :onclick => "javascript:document.getElementById('search_div').style.display='block';" +  |  %b= link_to 'data entry', url(:data_entry) - + #search_div{:style => 'margin: 2px; background:lightyellow;padding: 4px;'} + %form{:action => '/search'} + Search for + %select{:name => 'model'} + - ['Branch','Client','Center','Loan'].each do |model| + %option{:value => model} + = model + with + %select{:name => 'by'} + - ['Id','Name','Reference'].each do |by| + %option{:value => by} + = by + %input{:name => 'value'} + %a{:href => '#', :onclick => "document.getElementById('search_div').style.display='none';"} + Hide search + %br + %input{:type => 'submit', :value=>'search'} #content #breadcrums= breadcrums diff --git a/app/views/payments/create.xml.haml b/app/views/payments/create.xml.haml new file mode 100644 index 000000000..f22727c93 --- /dev/null +++ b/app/views/payments/create.xml.haml @@ -0,0 +1,2 @@ +%status + = @payment.status diff --git a/app/views/reports/#index.html.haml# b/app/views/reports/#index.html.haml# new file mode 100644 index 000000000..85b675322 --- /dev/null +++ b/app/views/reports/#index.html.haml# @@ -0,0 +1,15 @@ +%h1 + Reports + +%table#mytable{:width => "100%"} + %tr + - @reports.each do |report| + %tr + %td + = report.name + %td + = link_to 'Show', url(:report, report) + %td + = link_to 'Edit', url(:edit_report, report) + += link_to 'New', url(:new_report) \ No newline at end of file diff --git a/app/views/reports/_default_report.html.haml.bak b/app/views/reports/_default_report.html.haml.bak new file mode 100644 index 000000000..3f1a50416 --- /dev/null +++ b/app/views/reports/_default_report.html.haml.bak @@ -0,0 +1,104 @@ +%h2 + = @report.name + +- @branch_loans = {} +- Branch.all.each do |branch| + - @branch_loans[branch.id] = Loan.all('client.center.branch_id' => branch.id) + +%table + %tr + %th + Parameter + %th + All Branches + - Branch.all.each do |branch| + %th + = branch.name + %tr + %th + No. of CM + %td + = Center.all.manager.uniq.count + - Branch.all.each do |branch| + %td + = Center.all(:branch_id => branch.id).manager.uniq.count + %tr + %th + No. of Centers + %td + = Center.all.count + - Branch.all.each do |branch| + %td + = Center.all(:branch_id => branch.id).count + %tr + %th + No. of Clients + %td + = Client.all.count + - Branch.all.each do |branch| + %td + = Client.all('center.branch_id' => branch.id).count + %tr + %th + No. of Clients + %td + = Client.all.count + - Branch.all.each do |branch| + %td + = Client.all('center.branch_id' => branch.id).count + %tr + %th + No. of Borowers + %td + = repository(:default).adapter.query("SELECT COUNT(DISTINCT(client_id)) FROM loans")[0] + - Branch.all.each do |branch| + %td + = repository.adapter.query("SELECT COUNT(DISTINCT(client_id)) FROM loans,clients,centers,branches WHERE loans.client_id = clients.id AND clients.center_id = centers.id AND centers.branch_id = branches.id AND branches.id = #{branch.id}")[0] + %tr + %th + Loans for next week (number) + %td + = Loan.all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => Date.today + 7).count + - Branch.all.each do |branch| + %td + = @branch_loans[branch.id].all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => (Date.today + 7)).count + %tr + %th + Loans for next week (amount) + %td + = Loan.all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => Date.today + 7).sum(:amount) || 0 + - Branch.all.each do |branch| + %td + = @branch_loans[branch.id].all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => (Date.today + 7)).sum(:amount) || 0 + %tr + %th + Waiting Clients (number) + %td + = Loan.all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil).count + - Branch.all.each do |branch| + %td + = @branch_loans[branch.id].all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil, 'client.center.branch_id' => branch.id).count + %tr + %th + Waiting Clients (amount) + %td + = Loan.all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil).sum(:amount) + - Branch.all.each do |branch| + %td + = @branch_loans[branch.id].all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil, 'client.center.branch_id' => branch.id).sum(:amount) + %tr + %th + Defaulted Loans (Count) + %td + = LoanHistory.all(:current => true, :amount_in_default.not => 0).count + - Branch.all.each do |branch| + %td + = LoanHistory.all(:current => true, :amount_in_default.not => 0, 'loan.client.center.branch_id' => branch.id).count + %tr + %th + Defaulted Loans (Amount) + %td + = LoanHistory.all(:current => true, :amount_in_default.not => 0).sum(:amount_in_default) + - Branch.all.each do |branch| + %td + = LoanHistory.all(:current => true, :amount_in_default.not => 0, 'loan.client.center.branch_id' => branch.id).sum(:amount_in_default) diff --git a/app/views/search/index.html.haml b/app/views/search/index.html.haml new file mode 100644 index 000000000..cc697b4e2 --- /dev/null +++ b/app/views/search/index.html.haml @@ -0,0 +1 @@ +You're in index of the Search controller. \ No newline at end of file diff --git a/app/views/staff_members/day_sheet.html.haml b/app/views/staff_members/day_sheet.html.haml new file mode 100644 index 000000000..fe9822af8 --- /dev/null +++ b/app/views/staff_members/day_sheet.html.haml @@ -0,0 +1,99 @@ +- @date = params[:date] || Date.today +%h1 + Day sheet for + = @staff_member.name + for + = @date + +- @centers.each do |center| + %h2 + = center.name + %table.narrow.form{ :width => '100%' } + %thead + %tr + %th + %th on name + %th id + %th amount + %th outstanding + %th.center status + %th disbursed on + %th funder + %th installment + %th principal due + %th interest due + %th total due + %tbody + - tot_amount, tot_outstanding, tot_installments, tot_principal, tot_interest, tot_total = 0, 0, 0, 0, 0, 0 + - center.clients.each do |client| + - loan_row_count = 0 + - Loan.all(:client_id => client.id).each do |loan| + - next if [nil, :repaid, :pending].include? loan.get_status + - loan_row_count += 1 + %tr{ :class => cycle('odd','') } + %td   + %td + %b= loan.client.name + %td + = loan.id + %td.numeric + - i = loan.amount + %b= i.to_currency + - tot_amount += i + %td.numeric + - i = loan.actual_outstanding_principal_on(@date) + %b= i.to_currency + - tot_outstanding += i + %td.center + = loan.get_status(@date).to_s + %td + = loan.disbursal_date.to_s + %td + = loan.funder_name + %td.numeric + - i = loan.number_of_installments_before(@date) + = i + - tot_installments += i + %td.numeric + - i = [-loan.principal_overpaid_on(@date), 0].max + = i.to_currency + - tot_principal += i + %td.numeric + - i = [-loan.interest_overpaid_on(@date), 0].max + = i.to_currency + - tot_interest += i + %td.numeric + - i = [-loan.total_overpaid_on(@date), 0].max + = i.to_currency + - tot_total += i + - if loan_row_count == 0 + %tr{ :class => cycle('odd','') } + %td + %td + %b= client.name + %td{ :colspan => 5 } + %i nothing outstanding + %tr{ :style => 'border-bottom: 2px solid;' } + %tr + %td + %td + %td + %td.numeric + %b= tot_amount.to_currency + %td.numeric + %b= tot_outstanding.to_currency + %td + %td + %td + %td.numeric + %b= tot_installments + %td.numeric + %b= tot_principal.to_currency + %td.numeric + %b= tot_interest.to_currency + %td.numeric + %b= tot_total.to_currency + + %tfoot + %tr + %td{ :colspan => 12 } diff --git a/bin/erubis b/bin/erubis new file mode 100755 index 000000000..a55f1f846 --- /dev/null +++ b/bin/erubis @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +# This was added by Merb's bundler + +require "rubygems" +require File.join(File.dirname(__FILE__), "common") + +gems_dir = File.join(File.dirname(__FILE__), '..', 'gems') + +if File.directory?(gems_dir) + $BUNDLE = true + Gem.clear_paths + Gem.path.replace([File.expand_path(gems_dir)]) + ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}" + + gem_file = File.join(gems_dir, "specifications", "erubis-*.gemspec") + + if local_gem = Dir[gem_file].last + version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1] + end +end + +version ||= ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'erubis', version +load 'erubis' \ No newline at end of file diff --git a/bin/htmldiff b/bin/htmldiff new file mode 100755 index 000000000..8771d917b --- /dev/null +++ b/bin/htmldiff @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +# This was added by Merb's bundler + +require "rubygems" +require File.join(File.dirname(__FILE__), "common") + +gems_dir = File.join(File.dirname(__FILE__), '..', 'gems') + +if File.directory?(gems_dir) + $BUNDLE = true + Gem.clear_paths + Gem.path.replace([File.expand_path(gems_dir)]) + ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}" + + gem_file = File.join(gems_dir, "specifications", "diff-lcs-*.gemspec") + + if local_gem = Dir[gem_file].last + version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1] + end +end + +version ||= ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'diff-lcs', version +load 'htmldiff' \ No newline at end of file diff --git a/bin/ldiff b/bin/ldiff new file mode 100755 index 000000000..a95ecaf90 --- /dev/null +++ b/bin/ldiff @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +# This was added by Merb's bundler + +require "rubygems" +require File.join(File.dirname(__FILE__), "common") + +gems_dir = File.join(File.dirname(__FILE__), '..', 'gems') + +if File.directory?(gems_dir) + $BUNDLE = true + Gem.clear_paths + Gem.path.replace([File.expand_path(gems_dir)]) + ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}" + + gem_file = File.join(gems_dir, "specifications", "diff-lcs-*.gemspec") + + if local_gem = Dir[gem_file].last + version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1] + end +end + +version ||= ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'diff-lcs', version +load 'ldiff' \ No newline at end of file diff --git a/bin/merb-gen b/bin/merb-gen new file mode 100755 index 000000000..fa76a75b1 --- /dev/null +++ b/bin/merb-gen @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +# This was added by Merb's bundler + +require "rubygems" +require File.join(File.dirname(__FILE__), "common") + +gems_dir = File.join(File.dirname(__FILE__), '..', 'gems') + +if File.directory?(gems_dir) + $BUNDLE = true + Gem.clear_paths + Gem.path.replace([File.expand_path(gems_dir)]) + ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}" + + gem_file = File.join(gems_dir, "specifications", "merb-gen-*.gemspec") + + if local_gem = Dir[gem_file].last + version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1] + end +end + +version ||= ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'merb-gen', version +load 'merb-gen' \ No newline at end of file diff --git a/bin/multigem b/bin/multigem new file mode 100755 index 000000000..766d2ed2e --- /dev/null +++ b/bin/multigem @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +# This was added by Merb's bundler + +require "rubygems" +require File.join(File.dirname(__FILE__), "common") + +gems_dir = File.join(File.dirname(__FILE__), '..', 'gems') + +if File.directory?(gems_dir) + $BUNDLE = true + Gem.clear_paths + Gem.path.replace([File.expand_path(gems_dir)]) + ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}" + + gem_file = File.join(gems_dir, "specifications", "ZenTest-*.gemspec") + + if local_gem = Dir[gem_file].last + version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1] + end +end + +version ||= ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'ZenTest', version +load 'multigem' \ No newline at end of file diff --git a/bin/prettify_json.rb b/bin/prettify_json.rb new file mode 100755 index 000000000..bb5214efc --- /dev/null +++ b/bin/prettify_json.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +# This was added by Merb's bundler + +require "rubygems" +require File.join(File.dirname(__FILE__), "common") + +gems_dir = File.join(File.dirname(__FILE__), '..', 'gems') + +if File.directory?(gems_dir) + $BUNDLE = true + Gem.clear_paths + Gem.path.replace([File.expand_path(gems_dir)]) + ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}" + + gem_file = File.join(gems_dir, "specifications", "json_pure-*.gemspec") + + if local_gem = Dir[gem_file].last + version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1] + end +end + +version ||= ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'json_pure', version +load 'prettify_json.rb' \ No newline at end of file diff --git a/config/database.example.yml b/config/database.example.yml new file mode 100644 index 000000000..952ef38bf --- /dev/null +++ b/config/database.example.yml @@ -0,0 +1,27 @@ +--- +# This is a sample database file for the DataMapper ORM +development: &defaults + # These are the settings for repository :default + + # WARNING: Do not use sqlite3. This is a FINANCIAL application, it needs a real database. + + adapter: mysql + database: mostfit_dev + username: root + password: hatstars + host: localhost + +test: + <<: *defaults + database: db/test.db + +production: + adapter: mysql + database: aaj + username: mostfit + password: 19te11eCAP + host: localhost + + +rake: + <<: *defaults diff --git a/config/database.yml b/config/database.yml index 321f2c432..952ef38bf 100644 --- a/config/database.yml +++ b/config/database.yml @@ -6,9 +6,9 @@ development: &defaults # WARNING: Do not use sqlite3. This is a FINANCIAL application, it needs a real database. adapter: mysql - database: mostfit_aaj__test + database: mostfit_dev username: root - password: priyam08 + password: hatstars host: localhost test: diff --git a/spec/requests/search_spec.rb b/spec/requests/search_spec.rb new file mode 100644 index 000000000..cda43c17e --- /dev/null +++ b/spec/requests/search_spec.rb @@ -0,0 +1,7 @@ +require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb') + +describe "/search" do + before(:each) do + @response = request("/search") + end +end \ No newline at end of file diff --git a/tasks/merb.thor/#gem_ext.rb# b/tasks/merb.thor/#gem_ext.rb# new file mode 100644 index 000000000..f58963617 --- /dev/null +++ b/tasks/merb.thor/#gem_ext.rb# @@ -0,0 +1,125 @@ +require "erb" + +Gem.pre_install_hooks.push(proc do |installer| + unless File.file?(installer.bin_dir / "common.rb") + FileUtils.mkdir_p(installer.bin_dir) + FileUtils.cp(File.dirname(__FILE__) / "common.rb", installer.bin_dir / "common.rb") + end + + include ColorfulMessages + name = installer.spec.name + if $GEMS && versions = ($GEMS.assoc(name) || [])[1] + dep = Gem::Dependency.new(name, versions) + unless dep.version_requirements.satisfied_by?(installer.spec.version) + error "Cannot install #{installer.spec.full_name} " \ + "for #{$INSTALLING}; " \ + "you required #{dep}" + ::Thor::Tasks::Merb::Gem.rollback_trans + exit! + end + end + success "Installing #{installer.spec.full_name}" +end) + +class ::Gem::Uninstaller + def self._with_silent_ui + + ui = Gem::DefaultUserInteraction.ui + def ui.say(str) + puts "- #{str}" + end + + yield + + class << Gem::DefaultUserInteraction.ui + remove_method :say + end + end + + def self._uninstall(source_index, name, op, version) + unless source_index.find_name(name, "#{op} #{version}").empty? + uninstaller = Gem::Uninstaller.new( + name, + :version => "#{op} #{version}", + :install_dir => Dir.pwd / "gems", + :all => true, + :ignore => true + ) + _with_silent_ui { uninstaller.uninstall } + end + end + + def self._uninstall_others(source_index, name, version) + _uninstall(source_index, name, "<", version) + _uninstall(source_index, name, ">", version) + end +end + +Gem.post_install_hooks.push(proc do |installer| + source_index = installer.instance_variable_get("@source_index") + ::Gem::Uninstaller._uninstall_others( + source_index, installer.spec.name, installer.spec.version + ) +end) + +class ::Gem::DependencyInstaller + alias old_fg find_gems_with_sources + + def find_gems_with_sources(dep) + if @source_index.any? { |_, installed_spec| + installed_spec.satisfies_requirement?(dep) + } + return [] + end + + old_fg(dep) + end +end + +class ::Gem::SpecFetcher + alias old_fetch fetch + def fetch(dependency, all = false, matching_platform = true, prerelease = false) + idx = Gem::SourceIndex.from_installed_gems + + reqs = dependency.version_requirements.requirements + + if reqs.size == 1 && reqs[0][0] == "=" + dep = idx.search(dependency).sort.last + end + + if dep + file = dep.loaded_from.dup + file.gsub!(/specifications/, "cache") + file.gsub!(/gemspec$/, "gem") + spec = ::Gem::Format.from_file_by_path(file).spec + [[spec, file]] + else + old_fetch(dependency, all, matching_platform, prerelease) + end + end +end + +class ::Gem::Installer + def app_script_text(bin_file_name) + template = File.read(File.dirname(__FILE__) / "app_script.rb") + erb = ERB.new(template) + erb.result(binding) + end +end + +class ::Gem::Specification + def recursive_dependencies(from, index = Gem.source_index) + specs = self.runtime_dependencies.map do |dep| + spec = index.search(dep).last + unless spec + from_name = from.is_a?(::Gem::Specification) ? from.full_name : from.to_s + wider_net = index.find_name(dep.name).last + ThorUI.error "Needed #{dep} for #{from_name}, but could not find it" + ThorUI.error "Found #{wider_net.full_name}" if wider_net + ::Thor::Tasks::Merb::Gem.rollback_trans + end + spec + end + specs + specs.map {|s| s.recursive_dependencies(self, index)}.flatten.uniq + end +end