An open source, stand-alone, customisable public spending data web app.
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

181 linhas
4.9 KiB

  1. require 'rubygems'
  2. require 'sinatra'
  3. require 'sinatra-helpers/haml/partials'
  4. require 'haml'
  5. require 'lib/models'
  6. PAYMENTS_FILTER_MIN = 1000
  7. helpers do
  8. def commify(amount)
  9. amount.to_s.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1,').reverse
  10. end
  11. def yesno(boolean)
  12. boolean == true ? 'Yes' : 'No'
  13. end
  14. end
  15. get '/' do
  16. @directorates = Directorate.all( :order => ['name'] )
  17. @payments_count = Payment.count
  18. @suppliers_count = Supplier.count
  19. @services_count = Service.count
  20. haml :home
  21. end
  22. get '/directorates/:slug' do
  23. @directorate = Directorate.first(:slug => params[:slug])
  24. haml :directorate
  25. end
  26. get '/suppliers/:slug.csv' do
  27. @supplier = Supplier.first(:slug => params[:slug])
  28. headers "Content-Disposition" => "attachment;filename=supplier-#{@supplier.slug}.csv",
  29. "Content-Type" => "application/octet-stream"
  30. result = "Date,Ref.,URL,Directorate,Service,Amount ex. VAT\n"
  31. for payment in @supplier.payments
  32. result += "#{payment.d.strftime("%d %b %Y")},#{payment.id},#{payment.url},\"#{payment.service.directorate.name}\",#{payment.service.name},#{sprintf("%0.2f", payment.amount)}\n"
  33. end
  34. result
  35. end
  36. get '/suppliers/:slug' do
  37. @supplier = Supplier.first(:slug => params[:slug])
  38. @total = @supplier.payments.sum(:amount)
  39. @count = @supplier.payments.size # Payment.count(:supplier_id => @supplier.id) ?
  40. @avg = @supplier.payments.avg(:amount)
  41. @max = @supplier.payments.max(:amount)
  42. @min = @supplier.payments.min(:amount)
  43. haml :supplier
  44. end
  45. get '/suppliers/?' do
  46. @suppliers = Supplier.all( :order => ['name'] )
  47. haml :suppliers
  48. end
  49. get '/services/:slug/payments.csv' do
  50. @service = Service.first(:slug => params[:slug])
  51. headers "Content-Disposition" => "attachment;filename=service-#{@service.slug}.csv",
  52. "Content-Type" => "application/octet-stream"
  53. result = "Date,Ref.,URL,Directorate,Supplier,Amount ex. VAT\n"
  54. for payment in @service.payments
  55. result += "#{payment.d.strftime("%d %b %Y")},#{payment.id},#{payment.url},\"#{payment.service.directorate.name}\",#{payment.supplier.name},#{sprintf("%0.2f", payment.amount)}\n"
  56. end
  57. result
  58. end
  59. get '/services/:slug.json' do
  60. @service = Service.first(:slug => params[:slug])
  61. headers "Content-Type" => "application/json"
  62. @service.to_json(:relationships => { :payments => { :include => :all }, :directorate => { :include => :all } })
  63. end
  64. get '/services/:slug' do
  65. @service = Service.first(:slug => params[:slug])
  66. @total = @service.payments.sum(:amount)
  67. @count = @service.payments.size
  68. @avg = @service.payments.avg(:amount)
  69. @max = @service.payments.max(:amount)
  70. @min = @service.payments.min(:amount)
  71. @results = repository(:default).adapter.query("
  72. SELECT s.name AS supplier_name, s.slug AS supplier_slug, SUM(p.amount) AS total
  73. FROM payments p, suppliers s
  74. WHERE p.supplier_id = s.id
  75. AND p.service_id = #{@service.id}
  76. GROUP BY s.name, s.slug
  77. ORDER BY total DESC")
  78. haml :service
  79. end
  80. get '/services/:slug/payments' do
  81. @FILTER_VALUES = %w[ 500 1000 2500 5000 10000 20000 ]
  82. @service = Service.first(:slug => params[:slug])
  83. # payments_filter_min cookie persists user selection of filter value
  84. unless @min = request.cookies["payments_filter_min"]
  85. @min = PAYMENTS_FILTER_MIN
  86. response.set_cookie(
  87. "payments_filter_min",
  88. { :value => @min, :expires => Time.now + (60 * 24 * 60 * 60) }
  89. ) # 60 days
  90. end
  91. @payments = Payment.all(:service_id => @service.id, :amount.gte => @min, :order => [ 'd' ])
  92. @total = @payments.sum(:amount)
  93. haml :servicepayments
  94. end
  95. get '/services/:slug/paymentsdetail' do
  96. @service = Service.first(:slug => params[:slug])
  97. min = PAYMENTS_FILTER_MIN
  98. if params[:min].to_i > 0
  99. min = params[:min].to_i
  100. end
  101. @payments = Payment.all(:service_id => @service.id, :amount.gte => min, :order => [ 'd' ])
  102. @total = @payments.sum(:amount)
  103. haml :servicepaymentsdetail, :layout => false
  104. end
  105. get '/services/?' do
  106. @services = Service.all( :order => ['name'] )
  107. haml :services
  108. end
  109. get '/payments/:id' do
  110. @payment = Payment.get(params[:id])
  111. haml :payment
  112. end
  113. get '/error' do
  114. haml :error
  115. end
  116. get '/about' do
  117. haml :about
  118. end
  119. get '/scoreboard.csv' do
  120. @councils = Council.all( :order => ['name'] )
  121. labels = %w[
  122. id
  123. created_at
  124. updated_at
  125. name
  126. slug
  127. url
  128. data_url
  129. open_licence
  130. machine_readable
  131. start_d
  132. end_d
  133. ]
  134. headers "Content-Disposition" => "attachment;filename=armchair-auditor-scoreboard.csv",
  135. "Content-Type" => "text/csv"
  136. output = ""
  137. for council in @councils
  138. output += "#{council.id},#{council.created_at.strftime("%d %b %Y")},#{council.updated_at.strftime("%d %b %Y")},#{council.name},#{council.slug},#{council.url},#{council.data_url},#{council.open_licence},#{council.machine_readable},#{council.start_d.strftime("%d %b %Y")},#{council.end_d.strftime("%d %b %Y")}\n"
  139. end
  140. labels.join(',') + "\n" + output
  141. end
  142. get '/scoreboard' do
  143. @councils = Council.all( :order => ['name'] )
  144. haml :scoreboard
  145. end
  146. not_found do
  147. haml :not_found
  148. end