Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge master into widgets

  • Loading branch information...
commit a9c7c41300adf95518549a2b5495e1a7d5a87921 1 parent c18106d
tashian authored
Showing with 3,105 additions and 238 deletions.
  1. 0  .gitmodules
  2. +24 −1 Gemfile
  3. +59 −33 Gemfile.lock
  4. +27 −2 app/controllers/account_controller.rb
  5. +7 −0 app/controllers/admin/contact_congress_controller.rb
  6. +62 −1 app/controllers/application_controller.rb
  7. +87 −0 app/controllers/battle_royale_controller.rb
  8. +125 −0 app/controllers/contact_congress_letters_controller.rb
  9. +1 −0  app/controllers/contact_controller.rb
  10. +11 −2 app/controllers/districts_controller.rb
  11. +7 −13 app/helpers/application_helper.rb
  12. +2 −0  app/helpers/contact_congress_letters_helper.rb
  13. +5 −0 app/helpers/contact_helper.rb
  14. +37 −0 app/models/bill.rb
  15. +2 −0  app/models/bill_text_node.rb
  16. +2 −2 app/models/bill_text_version.rb
  17. +14 −0 app/models/contact_congress_letter.rb
  18. +4 −0 app/models/contact_congress_letters_formageddon_thread.rb
  19. +21 −0 app/models/crp_interest_group.rb
  20. +1 −2  app/models/district.rb
  21. +35 −0 app/models/person.rb
  22. +8 −0 app/models/state.rb
  23. +10 −1 app/models/user.rb
  24. +1 −1  app/models/user_observer.rb
  25. +33 −0 app/views/account/facebook_complete.html.haml
  26. +0 −69 app/views/account/login.html.erb
  27. +40 −0 app/views/account/login.html.haml
  28. +16 −0 app/views/admin/contact_congress/index.html.haml
  29. +4 −4 app/views/bill/major.rxml
  30. +50 −0 app/views/bill/show.html.erb
  31. +13 −0 app/views/contact_congress_letters/_contact_congress_share.html.haml
  32. +10 −0 app/views/contact_congress_letters/_contact_congress_status_bar.html.haml
  33. +38 −0 app/views/contact_congress_letters/_contact_recipients.html.haml
  34. +7 −0 app/views/contact_congress_letters/_message_builder_commentary.html.haml
  35. +39 −0 app/views/contact_congress_letters/_message_builder_contribution_data.html.haml
  36. +5 −0 app/views/contact_congress_letters/_will_add_text_box.html.haml
  37. +65 −0 app/views/contact_congress_letters/create.html.haml
  38. +10 −0 app/views/contact_congress_letters/get_recipients.js.erb
  39. +173 −0 app/views/contact_congress_letters/new.html.haml
  40. +35 −0 app/views/contact_congress_letters/select_position.html.haml
  41. +48 −0 app/views/contact_congress_letters/show.html.haml
  42. +18 −0 app/views/contact_congress_letters/showthread.html.haml
  43. +0 −5 app/views/districts/index.html.erb
  44. +11 −1 app/views/districts/show.html.erb
  45. +11 −5 app/views/layouts/_header.html.erb
  46. +1 −1  app/views/layouts/frontpage.html.erb
  47. +18 −0 app/views/people/_person.html.haml
  48. +1 −1  app/views/person/_topic.html.erb
  49. +3 −4 app/views/shared/_comments.html.haml
  50. +4 −0 app/views/shared/_comments_list.html.haml
  51. +6 −0 app/views/shared/_error_messages.html.haml
  52. +12 −31 app/views/shared/_user_content.html.erb
  53. +6 −38 app/views/states/show.html.erb
  54. +256 −0 bin/build_formageddon_recipients.rb
  55. +16 −11 bin/get_sunlightlabs_data.rb
  56. +1 −1  config/assets.yml
  57. +1 −0  config/initializers/facebooker2.rb
  58. +19 −0 config/initializers/formageddon.rb
  59. +25 −0 config/routes.rb
  60. +10 −0 db/migrate/20110306192052_comments_trigger_modify.rb
  61. +19 −0 db/migrate/20110526181158_contact_congress_letters.rb
  62. +93 −0 db/migrate/20110526194928_create_formageddon_tables.rb
  63. +11 −0 db/migrate/20110610165044_user_facebook.rb
  64. BIN  public/images/comment.png
  65. BIN  public/images/facebook-bg.png
  66. BIN  public/images/letter-approve.png
  67. BIN  public/images/letter-oppose.png
  68. BIN  public/images/letter-tracking.png
  69. BIN  public/images/letters.png
  70. BIN  public/images/pencil.png
  71. BIN  public/images/people-arrow.png
  72. BIN  public/images/promo.gif
  73. BIN  public/images/tiny-arrow.png
  74. BIN  public/images/triangle.png
  75. BIN  public/images/widg-bg.jpg
  76. +19 −0 public/stylesheets/account.css
  77. +120 −7 public/stylesheets/bill.css
  78. +2 −1  public/stylesheets/contact.css
  79. +1,196 −0 public/stylesheets/contact_congress_letters.css
  80. +76 −0 public/stylesheets/master.css
  81. +12 −1 public/stylesheets/states.css
View
0  .gitmodules
No changes.
View
25 Gemfile
@@ -1,6 +1,7 @@
source 'http://rubygems.org'
gem 'rails', '3.0.7'
+gem 'rake', '0.8.7'
# database gems -- need both pg and mysql for app and wiki
gem 'pg'
@@ -12,6 +13,9 @@ gem "settingslogic"
# HAML support
gem "haml"
+# RABL for API / JSON
+gem 'rabl'
+
# RMagick
gem 'rmagick', '2.13.1'
gem 'simple_captcha', :git => 'git://github.com/galetahub/simple-captcha.git'
@@ -47,6 +51,7 @@ gem 'RedCloth'
gem 'bluecloth'
gem 'htmlentities'
gem "json"
+gem "nokogiri"
# Deployment
gem 'capistrano'
@@ -57,13 +62,31 @@ gem 'newrelic_rpm'
# oauth
gem 'oauth'
+gem 'facebooker2'
gem 'will_paginate', '~> 3.0.pre2'
gem "validates_captcha"
gem "okkez-open_id_authentication"
-gem "acts-as-taggable-on", :git => 'git://github.com/mbleigh/acts-as-taggable-on.git'
+gem "acts-as-taggable-on", :git => 'http://github.com/mbleigh/acts-as-taggable-on.git'
+
+### temp just for showing to drm
+gem 'mechanize'
+#gem 'formageddon', '0.0.0', :require => 'formageddon', :path => '/Users/aross/pcf-work/gitbranches/formageddon'
+gem 'formageddon', :git => 'git://github.com/opencongress/formageddon.git'
+
+gem 'rspec'
+gem 'rspec-rails', '~> 2.4'
+gem 'cucumber', '0.8.5'
+gem 'cucumber-rails'
+gem 'webrat'
+gem 'selenium-client'
+
+gem 'capybara'
+gem 'capybara-envjs'
+
+gem 'autotest'
# Testing
group :test, :development do
View
92 Gemfile.lock
@@ -5,7 +5,16 @@ GIT
simple_captcha (0.1.1)
GIT
- remote: git://github.com/mbleigh/acts-as-taggable-on.git
+ remote: git://github.com/opencongress/formageddon.git
+ revision: 887a36965fb1ec87c54c36128d6ae7fbff7380dd
+ specs:
+ formageddon (0.0.0)
+ delayed_job (~> 2.1)
+ haml
+ mechanize
+
+GIT
+ remote: http://github.com/mbleigh/acts-as-taggable-on.git
revision: 2752cfef4c66318d0925fbe880d5392ad188bb50
specs:
acts-as-taggable-on (2.0.6)
@@ -46,18 +55,18 @@ GEM
activemodel (= 3.0.7)
activesupport (= 3.0.7)
activesupport (3.0.7)
- addressable (2.2.5)
- arel (2.0.9)
+ addressable (2.2.6)
+ arel (2.0.10)
autotest (4.4.6)
ZenTest (>= 4.4.1)
bluecloth (2.1.0)
builder (2.1.2)
- capistrano (2.5.21)
+ capistrano (2.6.0)
highline
net-scp (>= 1.0.0)
net-sftp (>= 2.0.0)
net-ssh (>= 2.0.14)
- net-ssh-gateway (>= 1.0.0)
+ net-ssh-gateway (>= 1.1.0)
capistrano-ext (1.2.1)
capistrano (>= 1.0.0)
capybara (0.4.1.2)
@@ -72,10 +81,10 @@ GEM
capybara-envjs (0.4.0)
capybara (~> 0.4.0)
envjs (>= 0.3.7)
- carrierwave (0.5.3)
+ carrierwave (0.5.4)
activesupport (~> 3.0)
celerity (0.8.9)
- childprocess (0.1.8)
+ childprocess (0.1.9)
ffi (~> 1.0.6)
closure-compiler (1.1.1)
crack (0.1.8)
@@ -88,6 +97,10 @@ GEM
cucumber-rails (0.3.2)
cucumber (>= 0.8.0)
culerity (0.2.15)
+ daemons (1.1.3)
+ delayed_job (2.1.4)
+ activesupport (~> 3.0)
+ daemons
diff-lcs (1.1.2)
em-websocket (0.2.1)
addressable (>= 2.1.1)
@@ -98,10 +111,12 @@ GEM
abstract (>= 1.0.0)
eventmachine (0.12.10)
excon (0.6.3)
+ facebooker2 (0.0.11)
+ mogli (>= 0.0.12)
+ ruby-hmac
fastercsv (1.5.4)
- ffi (1.0.7)
- rake (>= 0.8.7)
- fog (0.8.1)
+ ffi (1.0.9)
+ fog (0.8.2)
builder
excon (~> 0.6.1)
formatador (>= 0.1.3)
@@ -110,7 +125,7 @@ GEM
net-ssh (>= 2.1.3)
nokogiri (>= 1.4.4)
ruby-hmac
- formatador (0.1.3)
+ formatador (0.1.4)
gherkin (2.1.5)
trollop (~> 1.16.2)
govkit (0.6.1)
@@ -118,25 +133,24 @@ GEM
httparty (>= 0.5.2)
json (>= 1.4.3)
nokogiri (>= 1.4.4)
- guard (0.3.4)
+ guard (0.4.1)
thor (~> 0.14.6)
- guard-livereload (0.1.10)
+ guard-livereload (0.1.11)
em-websocket (~> 0.2.0)
guard (>= 0.2.2)
json (~> 1.5.1)
- haml (3.1.1)
- highline (1.6.1)
- hoptoad_notifier (2.4.9)
+ haml (3.1.2)
+ highline (1.6.2)
+ hoptoad_notifier (2.4.11)
activesupport
builder
hpricot (0.8.4)
htmlentities (4.3.0)
- httparty (0.7.7)
+ httparty (0.7.8)
crack (= 0.1.8)
i18n (0.5.0)
- jammit (0.6.0)
- closure-compiler (>= 0.1.0)
- yui-compressor (>= 0.9.1)
+ jammit (0.6.3)
+ yui-compressor (>= 0.9.3)
johnson (2.0.0.pre3)
stackdeck (~> 0.2)
json (1.5.1)
@@ -146,19 +160,23 @@ GEM
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
+ mechanize (1.0.0)
+ nokogiri (>= 1.2.1)
mediacloth (0.0.3)
memcache (1.2.13)
memcache-client (1.8.5)
mime-types (1.16)
+ mogli (0.0.28)
+ httparty (>= 0.4.3)
mysql (2.8.1)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-sftp (2.0.5)
net-ssh (>= 2.0.9)
net-ssh (2.1.4)
- net-ssh-gateway (1.0.1)
+ net-ssh-gateway (1.1.0)
net-ssh (>= 1.99.1)
- newrelic_rpm (2.14.1)
+ newrelic_rpm (3.0.1)
nokogiri (1.4.4)
oauth (0.4.4)
okkez-open_id_authentication (1.0.1)
@@ -166,7 +184,8 @@ GEM
open4 (1.0.1)
pg (0.11.0)
polyglot (0.3.1)
- rack (1.2.2)
+ rabl (0.2.8)
+ rack (1.2.3)
rack-mount (0.6.14)
rack (>= 1.0.0)
rack-openid (1.3.1)
@@ -189,24 +208,24 @@ GEM
thor (~> 0.14.4)
rake (0.8.7)
rmagick (2.13.1)
- rspec (2.5.0)
- rspec-core (~> 2.5.0)
- rspec-expectations (~> 2.5.0)
- rspec-mocks (~> 2.5.0)
- rspec-core (2.5.1)
- rspec-expectations (2.5.0)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
- rspec-mocks (2.5.0)
- rspec-rails (2.5.0)
+ rspec-mocks (2.6.0)
+ rspec-rails (2.6.1)
actionpack (~> 3.0)
activesupport (~> 3.0)
railties (~> 3.0)
- rspec (~> 2.5.0)
+ rspec (~> 2.6.0)
ruby-hmac (0.4.0)
ruby-openid (2.1.8)
rubyzip (0.9.4)
selenium-client (1.2.18)
- selenium-webdriver (0.2.0)
+ selenium-webdriver (0.2.1)
childprocess (>= 0.1.7)
ffi (>= 1.0.7)
json_pure
@@ -253,7 +272,9 @@ DEPENDENCIES
closure-compiler
cucumber (= 0.8.5)
cucumber-rails
+ facebooker2
fog
+ formageddon!
govkit
guard
guard-livereload
@@ -263,17 +284,22 @@ DEPENDENCIES
htmlentities
jammit
json
+ mechanize
mediacloth
memcache
memcache-client
mysql
newrelic_rpm
+ nokogiri
oauth
okkez-open_id_authentication
pg
+ rabl
rack-openid
rails (= 3.0.7)
+ rake (= 0.8.7)
rmagick (= 2.13.1)
+ rspec
rspec-rails (~> 2.4)
ruby-openid
selenium-client
View
29 app/controllers/account_controller.rb
@@ -36,7 +36,7 @@ def get_user_full_name
end
end
- def login
+ def login
if params[:login_action]
session[:login_action] = {:url => session[:return_to], :action_result => params[:login_action]}
end
@@ -104,8 +104,32 @@ def accept_tos
end
end
+ def facebook_complete
+ @page_title = 'Facebook Connect'
+
+ @user = User.where(['facebook_uid=?', @facebook_user.id]).first
+ if @user.nil?
+ @user = User.new
+ end
+
+ if request.post?
+ @user.facebook_uid = @facebook_user.id
+ @user.email = @facebook_user.email
+ @user.update_attributes(params[:user])
+
+ if @user.save
+ @user.activate
+ self.current_user = @user
+ flash[:notice] = 'You have successfully signed up with your Facebook Account!'
+
+ redirect_to welcome_url
+ return
+ end
+ end
+ end
+
def signup
- @page_title = "Create a New Account"
+ @page_title = "Create a New Account"
logger.info session.inspect
@@ -178,6 +202,7 @@ def activate
end
def welcome
+ @page_title = 'Welcome to OpenCongress!'
@user = current_user
@show_tracked_list = true
View
7 app/controllers/admin/contact_congress_controller.rb
@@ -0,0 +1,7 @@
+class Admin::ContactCongressController < Admin::IndexController
+ before_filter :admin_login_required
+
+ def index
+ @people = Person.all_sitting
+ end
+end
View
63 app/controllers/application_controller.rb
@@ -5,14 +5,74 @@ class ApplicationController < ActionController::Base
include AuthenticatedSystem
include SimpleCaptcha::ControllerHelpers
+ include Facebooker2::Rails::Controller
include UrlHelper
+ before_filter :facebook_check
before_filter :store_location
before_filter :current_tab
before_filter :has_accepted_tos?
before_filter :get_site_text_page
before_filter :is_banned?
+ def facebook_check
+ # check to see if the user is logged into and has connected to OC
+ if current_facebook_user and current_facebook_client
+ begin
+ @facebook_user = Mogli::User.find(current_facebook_user.id, current_facebook_client)
+ rescue Mogli::Client::HTTPException
+ set_fb_cookie(nil,nil,nil,nil)
+ @facebook_user = nil
+ end
+ else
+ @facebook_user = nil
+ end
+
+ if @facebook_user
+ # the user isn't logged in, try to find the account based on email
+ if current_user == :false
+ oc_user = User.where(["email=?", @facebook_user.email]).first
+ else
+ # if the logged-in user's email matches the one from facebook, use that user
+ # otherwise, cancel the facebook connect attempt
+ if current_user.email == @facebook_user.email
+ return unless current_user.facebook_uid.blank?
+ oc_user = current_user
+ else
+ flash[:error] = "The email addresses in your Facebook and OpenCongress accounts do not match. Could not connect."
+ set_fb_cookie(nil,nil,nil,nil)
+ @facebook_user = nil
+ return
+ end
+ end
+
+ if oc_user
+ # if, for some reason, we don't have these fields, require them
+ if oc_user.login.blank? or oc_user.zipcode.blank? or !oc_user.accepted_tos
+ redirect_to :controller => 'account', :action => 'facebook_complete' unless params[:action] == 'facebook_complete'
+ return
+ end
+
+ # make sure we have facebook uid
+ if oc_user.facebook_uid.blank?
+ oc_user.facebook_uid = @facebook_user.id
+ oc_user.save
+
+ flash.now[:notice] = 'Your Facebook account has now been linked to this OpenCongress account!'
+ else
+ flash.now[:notice] = "Welcome, #{oc_user.login}."
+ end
+
+ # log the user in
+ self.current_user = oc_user
+ else
+ # new user. redirect to get essential info
+ redirect_to :controller => 'account', :action => 'facebook_complete' unless params[:action] == 'facebook_complete'
+ return
+ end
+ end
+ end
+
def is_valid_email?(e, with_headers = false)
if with_headers == false
email_check = Regexp.new('^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$')
@@ -136,5 +196,6 @@ def news_blog_count(count)
else
count
end
- end
+ end
+
end
View
87 app/controllers/battle_royale_controller.rb
@@ -10,10 +10,97 @@ def senators
def representatives
redirect_to :controller => 'people', :action => 'representatives'
+ return
+
+ @person = Person.find(params[:person]) if params[:person]
+
+ sort = params[:sort] ||= "bookmark_count_1"
+ order = params[:order] ||= "desc"
+ @p_title_class = "reps"
+ @p_title = "Representatives"
+ if order == "asc"
+ @p_subtitle = "Least "
+ else
+ @p_subtitle = "Most "
+ end
+ case sort
+ when "bookmark_count_1"
+ @p_subtitle << "Users Tracking"
+ when "p_approval_count"
+ @p_subtitle << "User Approval Votes"
+ when "p_approval_avg"
+ @p_subtitle << "Average User Approval"
+ when "total_comments"
+ @p_subtitle << "Comments"
+ end
+ page = params[:page] ||= 1
+# @cache_key = "br-reps-#{page}-#{sort}-#{order}-#{logged_in? ? current_user.login : nil}-#{@range}-#{params[:q].blank? ? nil : Digest::SHA1.hexdigest(params[:q])}"
+# unless read_fragment(@cache_key)
+ unless params[:q].blank?
+ @r_count = Person.count_all_by_most_tracked_for_range(@range, :search => prepare_tsearch_query(params[:q]), :order => sort + " " + order, :per_page => 20, :page => page, :person_type => "Rep.")
+ @results = Person.paginate_by_most_tracked_for_range(@range, :search => prepare_tsearch_query(params[:q]), :order => sort + " " + order, :per_page => 20, :page => page, :person_type => "Rep.", :total_entries => @r_count)
+ else
+ @r_count = Person.count_all_by_most_tracked_for_range(@range, :order => sort + " " + order, :per_page => 20, :page => page, :person_type => "Rep.")
+ @results = Person.paginate_by_most_tracked_for_range(@range, :order => sort + " " + order, :per_page => 20, :page => page, :person_type => "Rep.", :total_entries => @r_count)
+ end
+# end
+# get_counts
+
+ respond_to do |format|
+ format.html {
+ render :action => 'person_by_approval_rating'
+ }
+ format.xml {
+ render :xml => @results.to_xml(:except => [:bookmark_count_2,
+ :fti_names,:current_support_pb, :support_count_1, :rolls, :hot_bill_category_id,
+ :support_count_2, :vote_count_2])
+ }
+
+ end
+
end
def issues
redirect_to :controller => 'issues', :action => 'index'
+ return
+
+ @issue = Subject.find(params[:issue]) if params[:issue]
+
+ sort = params[:sort] ||= "bookmark_count_1"
+ order = params[:order] ||= "desc"
+ @p_title_class = "issues"
+ @p_title = "Issues"
+ if order == "asc"
+ @p_subtitle = "Least "
+ else
+ @p_subtitle = "Most "
+ end
+ case sort
+ when "bookmark_count_1"
+ @p_subtitle << "Users Tracking"
+ when "total_comments"
+ @p_subtitle << "Comments"
+ end
+ page = params[:page] ||= 1
+# @cache_key = "br-issues-#{page}-#{sort}-#{order}-#{logged_in? ? current_user.login : nil}-#{@range}-#{params[:q].blank? ? nil : Digest::SHA1.hexdigest(params[:q])}"
+# unless read_fragment(@cache_key)
+ unless params[:q].blank?
+ @r_count = Subject.count_all_by_most_tracked_for_range(@range, :search => prepare_tsearch_query(params[:q]), :order => sort + " " + order, :per_page => 20, :page => page)
+ @results = Subject.paginate_by_most_tracked_for_range(@range, :search => prepare_tsearch_query(params[:q]), :order => sort + " " + order, :per_page => 20, :page => page, :total_entries => @r_count)
+ else
+ @r_count = Subject.count_all_by_most_tracked_for_range(@range, :order => sort + " " + order, :per_page => 20, :page => page)
+ @results = Subject.paginate_by_most_tracked_for_range(@range, :order => sort + " " + order, :per_page => 20, :page => page, :total_entries => @r_count)
+ end
+# end
+ respond_to do |format|
+ format.html {
+ render :action => 'most_tracked_issues'
+ }
+ format.xml {
+ render :xml => @results.to_xml(:except => [:bookmark_count_2,:fti_names,:current_support_pb, :support_count_1, :rolls, :hot_bill_category_id, :support_count_2, :vote_count_2])
+ }
+
+ end
end
def show_bill_details
View
125 app/controllers/contact_congress_letters_controller.rb
@@ -0,0 +1,125 @@
+class ContactCongressLettersController < ApplicationController
+
+ def new
+ @page_title = "Contact Congress"
+ @bill = Bill.find_by_ident(params[:bill])
+
+
+ if logged_in?
+ @sens = current_user.my_sens
+ @reps = current_user.my_reps
+
+ if @sens.empty? && @reps.empty?
+ flash[:notice] = "In order to contact your representatives in Congress, you must configure your account. Please enter your zipcode and address in the form below."
+ redirect_to user_profile
+ end
+ else
+ @sens = @reps = []
+ end
+
+ if params[:position].nil?
+ render 'select_position'
+ return
+ end
+
+ formageddon_configured = false
+ ### loop through recipients and see if formageddon is configured
+
+
+ @position = params[:position]
+
+ case @position
+ when 'support'
+ message_start = "I support #{@bill.typenumber} - #{@bill.title_common}, and am tracking it using OpenCongress.org, the free public resource website for government transparency and accountability."
+ when 'oppose'
+ message_start = "I oppose #{@bill.typenumber} - #{@bill.title_common}, and am tracking it using OpenCongress.org, the free public resource website for government transparency and accountability."
+ else
+ message_start = "I'm tracking #{@bill.typenumber} - #{@bill.title_common} using OpenCongress.org, the free public resource website for government transparency and accountability."
+ end
+
+ @formageddon_thread = Formageddon::FormageddonThread.new
+ @formageddon_thread.prepare(:user => current_user, :subject => @bill.typenumber, :message => message_start)
+ end
+
+
+ def get_recipients
+ @bill = Bill.find_by_ident(params[:bill])
+
+ unless params[:zip4].blank?
+ @sens, @reps = Person.find_current_congresspeople_by_zipcode(params[:zip5], params[:zip4])
+ else
+ yg = YahooGeocoder.new("#{params[:address]}, #{params[:zip5]}")
+ unless yg.zip5.nil?
+ @sens, @reps = Person.find_current_congresspeople_by_zipcode(yg.zip5, yg.zip4)
+ @zip4 = yg.zip4
+ end
+
+
+ @sens, @reps = Person.find_current_congresspeople_by_address_and_zipcode(params[:address], params[:zip5])
+ end
+
+ @sens = [] unless @sens
+ @reps = [] unless @reps and @reps.size == 1
+
+ #render :partial => 'contact/contact_recipients', :locals => { :show_checkboxes => true }
+ end
+
+ def show
+ @contact_congress_letter = ContactCongressLetter.find(params[:id])
+ end
+
+ def create_from_formageddon
+ ## dont forget to check privacy settings
+ unless params[:letter_ids].blank?
+ letter_ids = params[:letter_ids].split(/,/)
+ @letters = Formageddon::FormageddonLetter.find(letter_ids)
+ end
+
+ bill = Bill.find_by_ident(params[:bill])
+
+ @letters.each do |l|
+ cclft = ContactCongressLettersFormageddonThread.find_by_formageddon_thread_id(l.formageddon_thread.id)
+ if cclft.nil?
+ if @contact_congress_letter.nil?
+ @contact_congress_letter = ContactCongressLetter.new
+ @contact_congress_letter.disposition = params[:disposition]
+ @contact_congress_letter.bill = bill unless bill.nil?
+ @contact_congress_letter.save
+ end
+
+ @contact_congress_letter.formageddon_threads << l.formageddon_thread
+ else
+ @contact_congress_letter = cclft.contact_congress_letter
+ break
+ end
+ end
+
+ if @contact_congress_letter.nil?
+ # something weird happened
+ redirect_to '/'
+ return
+ else
+ if @contact_congress_letter.user.nil?
+ if current_user == :false
+ user = create_new_user_from_formageddon_thread(@contact_congress_letter.formageddon_threads.first)
+ @contact_congress_letter.user = user
+ @new_user_notice = true
+ else
+ @contact_congress_letter.user = current_user
+ @new_user_notice = false
+ end
+ @contact_congress_letter.save
+ else
+ @new_user_notice = false
+ end
+ end
+
+ render :action => 'create'
+ end
+
+ private
+
+ def create_new_user_from_formageddon_thread(thread)
+ return nil
+ end
+end
View
1  app/controllers/contact_controller.rb
@@ -1,2 +1,3 @@
class ContactController < ApplicationController
+
end
View
13 app/controllers/districts_controller.rb
@@ -1,10 +1,19 @@
class DistrictsController < ApplicationController
before_filter :get_state
- # GET /districts/1
- # GET /districts/1.xml
+ # GET /states/:state_id/districts
+ def index
+ @districts = @state.districts
+ end
+
+ # GET /states/:state_id/districts/:id
def show
@district = @state.districts.find_by_district_number(params[:id])
+
+ @representative = Person.find_current_representative_by_state_and_district(@state.abbreviation, @district.district_number)
+
+ @senators = Person.find_current_senators_by_state(@state.abbreviation)
+
@page_title = "#{@state.name.titleize}'s #{@district.ordinalized_number} Congressional District"
@users = @district.users
@tracking_suggestions = @district.tracking_suggestions
View
20 app/helpers/application_helper.rb
@@ -554,21 +554,13 @@ def inline_determine_support(bill, support = 10)
end
end
- def user_bill_result(bill)
- vt = bill.bill_votes.count
- if vt == 0
- result = nil
- else
- bs = bill.bill_votes.count(:all, :conditions => "support = 0")
- bo = bill.bill_votes.count(:all, :conditions => "support = 1")
- result = (bs.to_f / vt) * 100
- result = result.round
- end
- color = percent_to_color(result)
+ def user_bill_result(bill)
+ color = percent_to_color(bill.users_percentage_at_position('support'))
%Q{<div id="users_result">
- <h3 class="clearfix" style="color:#{color};" id="support_#{bill.id.to_s}">#{result.nil? ? "-" : result}%</h3>
+ <h3 class="clearfix" style="color:#{color};" id="support_#{bill.id.to_s}">
+ #{bill.users_percentage_at_position('support').nil? ? "-" : bill.users_percentage_at_position('support')}%</h3>
<h4>Users Support Bill</h4>
- <font>#{bs} in favor / #{bo} opposed</font>
+ <font>#{bill.users_at_position('support')} in favor / #{bill.users_at_position('oppose')} opposed</font>
</div>}.html_safe
end
@@ -843,6 +835,8 @@ def bitly_url(object)
case object
when Article
url = url_for(:only_path => false, :controller => 'articles', :action => 'view', :id => object)
+ when ContactCongressLetter
+ url = url_for(:only_path => false, :controller => 'contact', :action => 'letter', :id => object)
end
begin
View
2  app/helpers/contact_congress_letters_helper.rb
@@ -0,0 +1,2 @@
+module ContactCongressLettersHelper
+end
View
5 app/helpers/contact_helper.rb
@@ -1,2 +1,7 @@
module ContactHelper
+ def twitter_share_for_letter(letter)
+ "http://twitter.com/home?status=" +
+ u("Wrote my members of #Congress on @opencongress to let them know I'm tracking #USbill #" +
+ letter.bill.typenumber)
+ end
end
View
37 app/models/bill.rb
@@ -896,6 +896,13 @@ def top_recipients_for_all_interest_groups(disposition = 'support', chamber = 'h
LIMIT ?", groups_ids, Settings.current_opensecrets_cycle, groups_ids, Settings.current_opensecrets_cycle, title, num])
end
+ def bill_position_organizations_support
+ bill_position_organizations.where("bill_position_organizations.disposition='support'")
+ end
+ def bill_position_organizations_oppose
+ bill_position_organizations.where("bill_position_organizations.disposition='oppose'")
+ end
+
class << self
def client_id_to_url(client_id)
client_id.slice!(/\d+_/)
@@ -1151,6 +1158,18 @@ def bill_status_hash
return status_hash
end
+ def vote_on_passage(person)
+ if (chamber == 'house' and person.title == 'Rep.') or (chamber == 'senate' and person.title = 'Sen.')
+ roll = originating_chamber_vote
+ else
+ roll = other_chamber_vote
+ end
+
+ return "Not Voted Yet" if roll.nil? or roll.roll_call.nil?
+
+ roll.roll_call.vote_for_person(person)
+ end
+
def self.full_text_search(q, options = {})
congresses = options[:congresses] || Settings.default_congress
@@ -1237,6 +1256,24 @@ def obj_title
typenumber
end
+
+ # methods about user interaction
+ def users_at_position(position = 'support')
+ bill_votes.count(:all, :conditions => ["support = ?", position == 'support' ? 0 : 1])
+ end
+
+ def users_percentage_at_position(position = 'support')
+ vt = bill_votes.count
+ if vt == 0
+ result = nil
+ else
+ bs = users_at_position('support')
+ bo = users_at_position('oppose')
+ result = ((position == 'support' ? bs.to_f : bo.to_f) / vt) * 100
+ result = result.round
+ end
+ end
+
def as_json(ops = {})
super(stylize_serialization(ops))
end
View
2  app/models/bill_text_node.rb
@@ -3,6 +3,8 @@ class BillTextNode < ActiveRecord::Base
has_many :comments, :as => :commentable
+ attr_accessor :bill_text_cache
+
def display_object_name
"Bill Text"
end
View
4 app/models/bill_text_version.rb
@@ -82,10 +82,10 @@ def pretty_version
end
def top_comment_nodes(limit = 3)
- BillTextNode.find_by_sql(["SELECT bill_text_nodes.id, bill_text_nodes.nid, count(comments.id) as comment_count
+ BillTextNode.find_by_sql(["SELECT bill_text_nodes.id, bill_text_nodes.nid, bill_text_nodes.bill_text_version_id, count(comments.id) as comment_count
FROM bill_text_nodes INNER JOIN comments ON bill_text_nodes.id=comments.commentable_id
WHERE bill_text_nodes.bill_text_version_id=? AND comments.commentable_type='BillTextNode'
- GROUP BY bill_text_nodes.id, bill_text_nodes.nid ORDER BY count(comments.id) DESC LIMIT ?;", self.id, limit])
+ GROUP BY bill_text_nodes.id, bill_text_nodes.nid, bill_text_nodes.bill_text_version_id ORDER BY count(comments.id) DESC LIMIT ?;", self.id, limit])
end
end
View
14 app/models/contact_congress_letter.rb
@@ -0,0 +1,14 @@
+class ContactCongressLetter < ActiveRecord::Base
+ has_many :formageddon_threads, :through => :contact_congress_letters_formageddon_threads, :class_name => 'Formageddon::FormageddonThread'
+ has_many :contact_congress_letters_formageddon_threads
+
+ belongs_to :bill
+ belongs_to :user
+
+ has_many :comments, :as => :commentable
+
+ def to_param
+ subject = formageddon_threads.first.formageddon_letters.first.subject
+ subject.blank? ? "#{id}" : "#{id}-#{subject.gsub(/[^a-z0-9]+/i, '-')}"
+ end
+end
View
4 app/models/contact_congress_letters_formageddon_thread.rb
@@ -0,0 +1,4 @@
+class ContactCongressLettersFormageddonThread < ActiveRecord::Base
+ belongs_to :formageddon_thread
+ belongs_to :contact_congress_letter
+end
View
21 app/models/crp_interest_group.rb
@@ -21,4 +21,25 @@ def top_recipients(chamber = 'house', num = 10, cycle = Settings.current_opensec
ORDER BY contrib_total DESC
LIMIT ?", osid, Settings.current_opensecrets_cycle, osid, Settings.current_opensecrets_cycle, title, num])
end
+
+ def contrib_for_person(person)
+ p = Person.find_by_sql(["SELECT people.*, top_recips_ind.ind_contrib_total, top_recips_pac.pac_contrib_total, (COALESCE(top_recips_ind.ind_contrib_total, 0) + COALESCE(top_recips_pac.pac_contrib_total, 0)) AS contrib_total FROM people
+ LEFT JOIN
+ (SELECT recipient_osid, SUM(crp_contrib_individual_to_candidate.amount) as ind_contrib_total
+ FROM crp_contrib_individual_to_candidate
+ WHERE crp_interest_group_osid=? AND cycle=? AND recipient_osid=? AND crp_contrib_individual_to_candidate.contrib_type IN ('10', '11', '15 ', '15', '15E', '15J', '22Y')
+ GROUP BY recipient_osid)
+ top_recips_ind ON people.osid=top_recips_ind.recipient_osid
+ LEFT JOIN
+ (SELECT recipient_osid, SUM(crp_contrib_pac_to_candidate.amount) as pac_contrib_total
+ FROM crp_contrib_pac_to_candidate
+ WHERE crp_contrib_pac_to_candidate.crp_interest_group_osid=? AND crp_contrib_pac_to_candidate.cycle=? AND crp_contrib_pac_to_candidate.recipient_osid=?
+ GROUP BY crp_contrib_pac_to_candidate.recipient_osid)
+ top_recips_pac ON people.osid=top_recips_pac.recipient_osid
+ WHERE people.id=?
+ ORDER BY contrib_total DESC
+ LIMIT 1", osid, Settings.current_opensecrets_cycle, person.osid, osid, Settings.current_opensecrets_cycle, person.osid, person.id])
+
+ return p.first.nil? ? 0 : p.first.attributes['contrib_total'].to_i
+ end
end
View
3  app/models/district.rb
@@ -127,7 +127,6 @@ def tracking_suggestions
end
end
-
def ordinalized_number
if self.district_number == 0
"At Large"
@@ -135,7 +134,7 @@ def ordinalized_number
district_number.ordinalize
end
end
-
+
def district_state_text
self.state.abbreviation + "-" + self.district_number.to_s
end
View
35 app/models/person.rb
@@ -52,6 +52,8 @@ class Person < ViewableObject
# acts_as_bookmarkable
+ acts_as_formageddon_recipient
+
has_one :person_stats, :dependent => :destroy
has_one :wiki_link, :as => "wikiable"
@@ -998,6 +1000,10 @@ def consecutive_years
end
end
+ def in_a_valid_district?
+ (representative? && district != '0')
+ end
+
def parse_facets(facets, primary_facet, selected_facets)
my_trackers = 0
facet_results_hsh = {}
@@ -1355,6 +1361,24 @@ def average_approval_state
average_approval_from_state(self.state)
end
+ def contrib_for_interest_group(num = 10, cycle = Settings.current_opensecrets_cycle)
+ igs = CrpInterestGroup.find_by_sql(["SELECT crp_interest_groups.*, top_ind_igs.ind_contrib_total, top_pac_igs.pac_contrib_total, (COALESCE(top_ind_igs.ind_contrib_total, 0) + COALESCE(top_pac_igs.pac_contrib_total, 0)) AS contrib_total FROM crp_interest_groups
+ LEFT JOIN
+ (SELECT crp_interest_group_osid, SUM(crp_contrib_individual_to_candidate.amount)::integer as ind_contrib_total
+ FROM crp_contrib_individual_to_candidate
+ WHERE cycle=? AND recipient_osid=? AND crp_contrib_individual_to_candidate.contrib_type IN ('10', '11', '15 ', '15', '15E', '15J', '22Y')
+ GROUP BY crp_interest_group_osid)
+ top_ind_igs ON crp_interest_groups.osid=top_ind_igs.crp_interest_group_osid
+ LEFT JOIN
+ (SELECT crp_interest_group_osid, SUM(crp_contrib_pac_to_candidate.amount)::integer as pac_contrib_total
+ FROM crp_contrib_pac_to_candidate
+ WHERE cycle=? AND recipient_osid=?
+ GROUP BY crp_interest_group_osid)
+ top_pac_igs ON crp_interest_groups.osid=top_pac_igs.crp_interest_group_osid
+ ORDER BY contrib_total DESC
+ LIMIT ?", cycle, osid, cycle, osid, num])
+ end
+
def top_interest_groups(num = 10, cycle = Settings.current_opensecrets_cycle)
igs = CrpInterestGroup.find_by_sql(["SELECT crp_interest_groups.*, top_ind_igs.ind_contrib_total, top_pac_igs.pac_contrib_total, (COALESCE(top_ind_igs.ind_contrib_total, 0) + COALESCE(top_pac_igs.pac_contrib_total, 0)) AS contrib_total FROM crp_interest_groups
LEFT JOIN
@@ -1441,6 +1465,10 @@ def contact_link
end
end
+ def office_zip
+ senator? ? "20510" : "20515"
+ end
+
# expiring the cache
def fragment_cache_key
"person_#{id}"
@@ -1501,6 +1529,13 @@ def cleanup_commentaries
end
deleted
end
+
+ def formageddon_display_address
+ addr = ""
+ addr += "#{title_long} #{firstname} #{lastname}\n"
+ addr += "#{congress_office}\n" unless congress_office.blank?
+ addr += "Washington, DC #{office_zip}\n"
+ end
SERIALIZATION_OPS = {:methods => [:oc_user_comments, :oc_users_tracking], :include => [:recent_news, :recent_blogs]}.freeze
View
8 app/models/state.rb
@@ -132,6 +132,14 @@ def self.make_download_script
end
end
+ def available_in_og?
+ ['CA','LA','MD','WI','MN','TX'].include?(abbreviation)
+ end
+
+ def og_link
+ 'http://' + abbreviation.downcase + '.opengovernment.org'
+ end
+
def m_thumb_path
"/images/states/thumbs_250/#{self.image_name}"
end
View
11 app/models/user.rb
@@ -166,6 +166,10 @@ def total_number_of_actions
self.comments.count + self.friends.count + self.bill_votes.count + self.person_approvals.count + self.bookmarks.count
end
+ def state
+ my_state.empty? ? nil : my_state.first
+ end
+
def my_state
ZipcodeDistrict.zip_lookup(self.zipcode, self.zip_four).collect {|p| p.state}.uniq
end
@@ -761,6 +765,10 @@ def self.fix_duplicate_users
end
+ def facebook_connect_user?
+ !facebook_uid.blank?
+ end
+
protected
def make_password_reset_code
@@ -788,12 +796,13 @@ def make_privacy_options
end
def password_required?
- !openid? && ( crypted_password.blank? || !password.blank? )
+ !openid? && !facebook_connect_user? && ( crypted_password.blank? || !password.blank? )
end
def openid?
!identity_url.blank?
end
+
private
def cache_district_and_state
View
2  app/models/user_observer.rb
@@ -1,6 +1,6 @@
class UserObserver < ActiveRecord::Observer
def after_create(user)
- UserNotifier.deliver_signup_notification(user)
+ UserNotifier.deliver_signup_notification(user) unless user.facebook_connect_user?
end
def after_save(user)
View
33 app/views/account/facebook_complete.html.haml
@@ -0,0 +1,33 @@
+#heading
+ %h2 Facebook Connect
+
+.padding
+ %h2 Almost Done!
+ %p.behave We just need a little more info to create and link your OpenCongress account.
+ %ul
+ %li
+ %strong Create a user name.
+ This is what will show up when you leave comments and track bills.
+ %li
+ %strong Enter your zipcode.
+ We'll use this to figure out who is representing you in Congress
+ %li
+ %strong Accept our Terms of Service
+
+ = form_for @user, :url => { :action => 'facebook_complete' } do |f|
+ = render "shared/error_messages", :target => @user
+
+ %p
+ = f.label :login, 'Username:'
+ = f.text_field :login
+
+ %p
+ = f.label :zipcode, 'Zipcode:'
+ = f.text_field :zipcode
+
+ %p
+ = f.check_box :accepted_tos
+ I agree to the <a href="/about/terms_of_service">Terms of Service</a> and <a href="/about/privacy_policy">Privacy Policy.</a>
+
+ %p
+ = f.submit 'Connect', :class => 'large button silver'
View
69 app/views/account/login.html.erb
@@ -1,69 +0,0 @@
-<% @page_title = "Login" -%>
-
-<div id="heading">
-<h2>Please Login or Register for a Free Account</h2>
-</div>
-
-<div class="padding">
-
-<div id="login-left" class="floatleft padding paddingtopnone">
-
-<h3>I have an account:</h3>
-
-<%= form_for :user do |f| %>
-
-<div title="Account login" id="loginform" class="floatleft form">
-
- <p><label for="user_login">Login:</label>
- <%= f.text_field :login, :size => 30 %>
- </p>
-
- <p>
- <label for="user_password">Password:</label>
- <%= f.password_field :password, :size => 30 %>
- </p>
-
- <input type="image" value="Login" class="floatright margintop behave" src="<%= image_path 'login2.png' %>" />
-
-
- <p class="margintop floatleft" style="margin-top: 10px;">
- <%= link_to "Forgot Password?", :action => 'forgot_password' %>
- </p>
-
-
-</div>
-<h3 style="text-align:left;">Login with OpenID</h3>
-<% end %>
-
-<%= form_for :user do |f| %>
-
-<div title="Account login" id="oid_loginform" class="form">
-
- <p class="openidform">
- <label for="identity_url">OpenID URL:</label>
- <%= text_field_tag :openid_url,nil, :size => 30 %>
- </p>
-<br />
-
- <input type="image" value="Login with OpenID" class="floatright margintop behave" src="<%= image_path 'login3.png' %>" />
-
-
-
-</div>
-
-<% end %>
-
-</div>
-
-<div id="login-right" class="floatright padding paddingtopnone">
- <h3 class="make_one">Make me one, right now!</h3>
-
-
- <%= render :partial => "signup_form" %>
- <div style="clear:both;margin-bottom:1em;"></div>
-
-
-
-</div>
-</div></div>
-
View
40 app/views/account/login.html.haml
@@ -0,0 +1,40 @@
+- @page_title = "Login"
+
+#heading
+ %h2 Please Login or Register for a Free Account
+
+.padding
+ #login-left.floatleft.padding.paddingtopnone
+ %div
+ %h3 Login With Your Facebook Account
+ = fb_connect_async_js
+ = fb_login_and_redirect(request.url, :perms => 'email')
+
+ #loginform.floatleft.form.clear{ :title => "Account login" }
+ %h3 I have an account:
+ = form_for :user do |f|
+ %p
+ %label{ :for => "user_login" } Login:
+ = f.text_field :login, :size => 30
+ %p
+ %label{ :for => "user_password" } Password:
+ = f.password_field :password, :size => 30
+ %input.floatright.margintop.behave{ :type => "image", :value => "Login", :src => image_path('login2.png') }
+
+ %p.margintop.floatleft.margin-top
+ = link_to "Forgot Password?", :action => 'forgot_password'
+
+ %h3 Login with OpenID
+ = form_for :user do |f|
+ #oid_loginform.form{ :title => "Account login" }
+ %p.openidform
+ %label{ :for => "identity_url" } OpenID URL:
+ = text_field_tag :openid_url,nil, :size => 30
+ %br
+ %input.floatright.margintop.behave{ :type => "image", :value => "Login with OpenID", :src => image_path('login3.png') }
+
+ #login-right.floatright.padding.paddingtopnone
+ %h3.make_one Create an OpenCongress Account
+ = render :partial => "signup_form"
+
+ %br{ :style => "clear:both" } &nbsp;
View
16 app/views/admin/contact_congress/index.html.haml
@@ -0,0 +1,16 @@
+.padding
+ %table.contact_steps_list
+ %tr
+ %th Recipient
+ %th Number of steps
+ %th Actions
+ - @people.each do |s|
+ %tr
+ %td= s.name
+ %td= s.formageddon_contact_steps.size
+ %td
+ = link_to 'View Steps', :controller => 'formageddon/contact_steps', :action => 'show', :recipient_id => s.id, :recipient_type => s.class
+ \|
+ = link_to 'Re-build Steps', :controller => 'formageddon/contact_steps', :action => 'new', :recipient_id => s.id, :recipient_type => s.class
+ \|
+ = link_to 'Clear Steps', { :controller => 'formageddon/contact_steps', :action => 'destroy', :recipient_id => s.id, :recipient_type => s.class }, :method => :delete
View
8 app/views/bill/major.rxml
@@ -2,12 +2,12 @@ xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
- xml.title "Open Congress : Major Bills"
- xml.link "rel" => "self", "href" => url_for(:controller => 'bill', :action => "major.rss", :only_path => false)
- xml.link "rel" => "alternate", "href" => url_for(:only_path => false, :controller => 'bill', :action => 'major')
+ xml.title "Open Congress : Hot Bills"
+ xml.link "rel" => "self", "href" => url_for(:controller => 'bill', :action => "hot.rss", :only_path => false)
+ xml.link "rel" => "alternate", "href" => url_for(:only_path => false, :controller => 'bill', :action => 'hot')
xml.updated @hot_bills.first.updated.strftime("%Y-%m-%dT%H:%M:%SZ") if @hot_bills.any?
xml.author { xml.name "opencongress.org" }
- xml.id "tag:opencongress.org,2010:/bill/major"
+ xml.id "tag:opencongress.org,2010:/bill/hot"
@hot_bills.each do |b|
bill_basic_atom_entry(xml, b, nil)
View
50 app/views/bill/show.html.erb
@@ -211,6 +211,56 @@
</div> <!-- // col2 -->
</div>
+ <br class="clear" />
+ <h3 class="margin-left push-left margin-top push-top">Most-Viewed Letters</h3>
+ <ul class='most_viewed_letters'>
+ <li class='support'>
+ <a href="#">
+ <span class='subject'>This Bill is Awesome!</span>
+ <span class='user'>aross</span>
+ <span class='date'>Jun 8, 2011</span>
+
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed porta tempus augue at ullamcorper. Maecenas malesuada, ante sit amet dignissim dictum, velit velit pharetra risus, sed dapibus odio lectus non nisi. Vestibulum nulla nulla, placerat tempus porttitor ut, luctus id neque. Donec fermentum enim quis lacus condimentum mattis. Vestibulum lobortis risus id ligula ornare fermentum. Etiam elit lacus, ullamcorper quis egestas rhoncus, pretium sed libero. Phasellus imperdiet quam sit amet metus pellentesque eget vehicula est mollis. In non augue diam, id porta purus. Donec ut diam purus. Duis mauris metus, ultrices a vulputate sed, consequat ac odio.</p>
+
+<p>Praesent blandit libero leo. Mauris in lorem lacus, quis facilisis erat. Pellentesque eget leo sit amet diam tristique congue. Donec non tellus laoreet urna pulvinar fringilla sit amet eget tellus. Morbi id libero elit. Morbi sapien ante, pharetra et placerat non, ornare non est. Aliquam suscipit elit velit. Vestibulum posuere, purus at commodo accumsan, erat est luctus metus, ac sagittis neque leo et ligula. Nullam laoreet mollis nibh vel vehicula. Donec tellus erat, venenatis in varius non, semper vitae mi. Sed vel molestie ligula. Pellentesque ac varius ligula. In ullamcorper, nibh a dictum rhoncus, diam felis ultricies dolor, auctor convallis turpis lectus et erat. Phasellus tempus vulputate urna, at dapibus massa vehicula ut. Mauris mi erat, sagittis ac porta sed, auctor quis urna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In facilisis tempor malesuada. Cras eu tristique urna. Suspendisse malesuada faucibus nunc vel ultrices. Proin laoreet sodales imperdiet.</p>
+
+<p>Suspendisse a mi odio, a aliquam nibh. Sed aliquet porttitor felis, eget mattis tortor ultricies a. In ullamcorper mollis ante eu auctor. Integer convallis euismod lectus non feugiat. Sed nec tincidunt felis. In viverra tincidunt velit, nec semper dui vestibulum in. Integer sit amet quam mauris, non elementum erat. Ut rutrum ligula nec mauris condimentum rutrum. Integer vitae odio at eros sollicitudin commodo. Vivamus interdum, lorem aliquam mattis dignissim, purus augue laoreet quam, nec iaculis felis lacus id nisi. Vivamus nec odio vitae nisl tincidunt iaculis a id quam. Vivamus tristique, turpis laoreet commodo sagittis, libero erat porta nulla, gravida ullamcorper ante nulla ut nibh. Cras venenatis iaculis molestie. Suspendisse posuere semper lectus ut ultricies. Mauris et enim non orci eleifend vulputate in eu justo. Nunc sollicitudin, lorem sit amet feugiat suscipit, tortor leo lacinia mi, vitae aliquam nisl nisi dictum urna. Morbi rutrum nunc at dui dictum aliquam. Proin luctus erat et turpis mollis interdum. Donec sollicitudin diam eu ipsum aliquam venenatis a ac mauris.</p>
+
+ </a>
+ </li>
+ <li class='oppose'>
+ <a href="#">
+ <span class='subject'>This Bill Sucks!</span>
+ <span class='user'>aross</span>
+ <span class='date'>Jun 8, 2011</span>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed porta tempus augue at ullamcorper. Maecenas malesuada, ante sit amet dignissim dictum, velit velit pharetra risus, sed dapibus odio lectus non nisi. Vestibulum nulla nulla, placerat tempus porttitor ut, luctus id neque. Donec fermentum enim quis lacus condimentum mattis. Vestibulum lobortis risus id ligula ornare fermentum. Etiam elit lacus, ullamcorper quis egestas rhoncus, pretium sed libero. Phasellus imperdiet quam sit amet metus pellentesque eget vehicula est mollis. In non augue diam, id porta purus. Donec ut diam purus. Duis mauris metus, ultrices a vulputate sed, consequat ac odio.</p>
+
+<p>Praesent blandit libero leo. Mauris in lorem lacus, quis facilisis erat. Pellentesque eget leo sit amet diam tristique congue. Donec non tellus laoreet urna pulvinar fringilla sit amet eget tellus. Morbi id libero elit. Morbi sapien ante, pharetra et placerat non, ornare non est. Aliquam suscipit elit velit. Vestibulum posuere, purus at commodo accumsan, erat est luctus metus, ac sagittis neque leo et ligula. Nullam laoreet mollis nibh vel vehicula. Donec tellus erat, venenatis in varius non, semper vitae mi. Sed vel molestie ligula. Pellentesque ac varius ligula. In ullamcorper, nibh a dictum rhoncus, diam felis ultricies dolor, auctor convallis turpis lectus et erat. Phasellus tempus vulputate urna, at dapibus massa vehicula ut. Mauris mi erat, sagittis ac porta sed, auctor quis urna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In facilisis tempor malesuada. Cras eu tristique urna. Suspendisse malesuada faucibus nunc vel ultrices. Proin laoreet sodales imperdiet.</p>
+
+<p>Suspendisse a mi odio, a aliquam nibh. Sed aliquet porttitor felis, eget mattis tortor ultricies a. In ullamcorper mollis ante eu auctor. Integer convallis euismod lectus non feugiat. Sed nec tincidunt felis. In viverra tincidunt velit, nec semper dui vestibulum in. Integer sit amet quam mauris, non elementum erat. Ut rutrum ligula nec mauris condimentum rutrum. Integer vitae odio at eros sollicitudin commodo. Vivamus interdum, lorem aliquam mattis dignissim, purus augue laoreet quam, nec iaculis felis lacus id nisi. Vivamus nec odio vitae nisl tincidunt iaculis a id quam. Vivamus tristique, turpis laoreet commodo sagittis, libero erat porta nulla, gravida ullamcorper ante nulla ut nibh. Cras venenatis iaculis molestie. Suspendisse posuere semper lectus ut ultricies. Mauris et enim non orci eleifend vulputate in eu justo. Nunc sollicitudin, lorem sit amet feugiat suscipit, tortor leo lacinia mi, vitae aliquam nisl nisi dictum urna. Morbi rutrum nunc at dui dictum aliquam. Proin luctus erat et turpis mollis interdum. Donec sollicitudin diam eu ipsum aliquam venenatis a ac mauris.</p>
+
+ </a>
+ </li>
+ <li>
+ <a href="#">
+ <span class='subject'>I'm Tracking this Bill!</span>
+ <span class='user'>aross</span>
+ <span class='date'>Jun 8, 2011</span>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed porta tempus augue at ullamcorper. Maecenas malesuada, ante sit amet dignissim dictum, velit velit pharetra risus, sed dapibus odio lectus non nisi. Vestibulum nulla nulla, placerat tempus porttitor ut, luctus id neque. Donec fermentum enim quis lacus condimentum mattis. Vestibulum lobortis risus id ligula ornare fermentum. Etiam elit lacus, ullamcorper quis egestas rhoncus, pretium sed libero. Phasellus imperdiet quam sit amet metus pellentesque eget vehicula est mollis. In non augue diam, id porta purus. Donec ut diam purus. Duis mauris metus, ultrices a vulputate sed, consequat ac odio.</p>
+
+<p>Praesent blandit libero leo. Mauris in lorem lacus, quis facilisis erat. Pellentesque eget leo sit amet diam tristique congue. Donec non tellus laoreet urna pulvinar fringilla sit amet eget tellus. Morbi id libero elit. Morbi sapien ante, pharetra et placerat non, ornare non est. Aliquam suscipit elit velit. Vestibulum posuere, purus at commodo accumsan, erat est luctus metus, ac sagittis neque leo et ligula. Nullam laoreet mollis nibh vel vehicula. Donec tellus erat, venenatis in varius non, semper vitae mi. Sed vel molestie ligula. Pellentesque ac varius ligula. In ullamcorper, nibh a dictum rhoncus, diam felis ultricies dolor, auctor convallis turpis lectus et erat. Phasellus tempus vulputate urna, at dapibus massa vehicula ut. Mauris mi erat, sagittis ac porta sed, auctor quis urna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In facilisis tempor malesuada. Cras eu tristique urna. Suspendisse malesuada faucibus nunc vel ultrices. Proin laoreet sodales imperdiet.</p>
+
+<p>Suspendisse a mi odio, a aliquam nibh. Sed aliquet porttitor felis, eget mattis tortor ultricies a. In ullamcorper mollis ante eu auctor. Integer convallis euismod lectus non feugiat. Sed nec tincidunt felis. In viverra tincidunt velit, nec semper dui vestibulum in. Integer sit amet quam mauris, non elementum erat. Ut rutrum ligula nec mauris condimentum rutrum. Integer vitae odio at eros sollicitudin commodo. Vivamus interdum, lorem aliquam mattis dignissim, purus augue laoreet quam, nec iaculis felis lacus id nisi. Vivamus nec odio vitae nisl tincidunt iaculis a id quam. Vivamus tristique, turpis laoreet commodo sagittis, libero erat porta nulla, gravida ullamcorper ante nulla ut nibh. Cras venenatis iaculis molestie. Suspendisse posuere semper lectus ut ultricies. Mauris et enim non orci eleifend vulputate in eu justo. Nunc sollicitudin, lorem sit amet feugiat suscipit, tortor leo lacinia mi, vitae aliquam nisl nisi dictum urna. Morbi rutrum nunc at dui dictum aliquam. Proin luctus erat et turpis mollis interdum. Donec sollicitudin diam eu ipsum aliquam venenatis a ac mauris.</p>
+
+ </a>
+ </li>
+ </ul>
+
+
+
+
+
+
<div class="users_also" id="users_tracking">
<br/>
<br/>
View
13 app/views/contact_congress_letters/_contact_congress_share.html.haml
@@ -0,0 +1,13 @@
+.contact_thread_share
+ %span Share this correspondence:
+ %ul.share
+ %li.email_friend
+ %a.e_trigger{ :href => url_for(:controller => 'resources', :action => 'email_friend_form', :object_class => nil, :object_id => nil)} Share via Email
+ %li.facebook
+ %a{ :target => "_blank", :href => "http://www.facebook.com/sharer.php?u=#{}&t=#{}" } Facebook
+ %li.twitter
+ %a{ :href => "http://twitter.com/home?status=#{}", :title => "Click to share your letter on Twitter" } Share on Twitter
+ :javascript
+ $j().ready(function() {
+ $j('#e_friend').jqm({ajax:'@href', trigger:'a.e_trigger'});
+ });
View
10 app/views/contact_congress_letters/_contact_congress_status_bar.html.haml
@@ -0,0 +1,10 @@
+.status_bar
+ .step{ :class => (step == 1) ? 'active' : 'inactive' }
+ %span 1.
+ Choose Your Position
+ .step{ :class => (step == 2) ? 'active' : 'inactive' }
+ %span 2.
+ Write Your Letter
+ .step.noborder{ :class => (step == 3) ? 'active' : 'inactive' }
+ %span 3.
+ Share Your Communication
View
38 app/views/contact_congress_letters/_contact_recipients.html.haml
@@ -0,0 +1,38 @@
+- show_checkboxes ||= false
+
+.contact_recipients
+ %span.sending You are sending this message to:
+ %ul.people
+ - @sens.each_with_index do |s, i|
+ %li.hide{ :id => "sen_#{i}" }
+ - if show_checkboxes
+ = check_box_tag "formageddon_multi_recipients[#{s.id}]", 'Person', true
+ = image_tag "photos/thumbs_50/#{s.id}-50px.jpeg", :class =>"photo", :alt => 'photo'
+ = link_to s.name, person_path(s)
+ - if @bill
+ %span
+ = "Vote on Passage of #{@bill.typenumber}: "
+ %strong= "#{@bill.vote_on_passage(s)}"
+ %hr#separator
+ - if @reps.size == 1
+ %li#rep.hide
+ - if show_checkboxes
+ = check_box_tag "formageddon_multi_recipients[#{@reps.first.id}]", 'Person', true
+ = image_tag "photos/thumbs_50/#{@reps.first.id}-50px.jpeg", :class =>"photo", :alt => 'photo'
+ = link_to @reps.first.name, person_path(@reps.first)
+ - if @bill
+ %span
+ = "Vote on Passage of #{@bill.typenumber}: "
+ %strong= "#{@bill.vote_on_passage(@reps.first)}"
+ - else
+ %li#rep.hide.none
+ Please enter your full address on the right
+ %br
+ so we can find your Representative.
+- unless @sens.empty? and @reps.empty?
+ :javascript
+ $j('#sen_0').css("top", "0px");
+ $j('#sen_1').css("top", "75px");
+ $j('#rep').css("top", "160px");
+ $j('.sending').css("opacity", "1.0");
+ $j('#separator').css("opacity", "1.0");
View
7 app/views/contact_congress_letters/_message_builder_commentary.html.haml
@@ -0,0 +1,7 @@
+%li.message_builder_clickable
+ = link_to a.title.html_safe, a.url
+ \-
+ = a.date.strftime("%B %d, %Y")
+ \-
+ = a.excerpt.html_safe
+ = render 'will_add_text_box', :text => "As noted in #{a.source} on #{a.date.strftime("%B %d, %Y")}, \"#{a.excerpt}\""
View
39 app/views/contact_congress_letters/_message_builder_contribution_data.html.haml
@@ -0,0 +1,39 @@
+- ['support', 'oppose'].each do |position|
+ .contribution_data
+ The following table shows contributions to each candidate by interest groups that
+ %strong= position
+ = @bill.typenumber
+
+ %table
+ %thead
+ %tr
+ %th.topleft
+ - (@sens + @reps).each do |p|
+ %th= p.lastname
+ %tbody
+ - @bill.bill_interest_groups.select{|g| g.disposition == position}.each do |big|
+ %tr
+ %th.group_column= big.crp_interest_group.name
+ - (@sens + @reps).each do |p|
+ - contribution_amount = big.crp_interest_group.contrib_for_person(p)
+ %td
+ %span.message_builder_clickable
+ = "$#{number_with_delimiter(contribution_amount)}"
+ = render 'will_add_text_box', :text => "#{p.title} #{p.lastname}, I know that you took $#{number_with_delimiter(contribution_amount)} from #{big.crp_interest_group.name.downcase} interest groups who #{position} #{@bill.typenumber}."
+
+:javascript
+ $j(".contribution_data .message_builder_clickable").hover(
+ function () {
+ $j(this).find("div.will_add_text_box:first").fadeIn(.3);
+ },
+ function () {
+ $j(this).find("div.will_add_text_box:first").fadeOut(.3);
+ }
+ );
+ $j(".contribution_data .message_builder_clickable").click(
+ function () {
+ txt = $j(this).find("div.message_builder_add_text:first").text();
+ msg = $j('div.formageddon_contact_form textarea:first')
+ msg.val(msg.val()+"\n\n"+unescape(txt));
+ }
+ );
View
5 app/views/contact_congress_letters/_will_add_text_box.html.haml
@@ -0,0 +1,5 @@
+%div.will_add_text_box
+ %span.arrow
+ %p Clicking this will add the following text:
+ %div.message_builder_add_text
+ = text
View
65 app/views/contact_congress_letters/create.html.haml
@@ -0,0 +1,65 @@
+#heading
+ %h2 Contact Congress
+
+.contact_congress
+ = render 'contact_congress_status_bar', :step => 3
+
+ .congrats
+ - if @new_user_notice
+ %p.new_user
+ %strong You must verify your email before we can send your letter.
+ %br
+ %br
+ We have created a new OpenCongress account for you and sent you a verification email. As soon as you verify your email address, we'll send your letter.
+ - else
+ %p
+ %strong Congratulations!
+ Your letter to your elected representatives has been sent! We will be tracking this correspondence and alert you to any replies immediately.
+ %br
+
+ .perm
+ Here is your letter's permalink:
+ = link_to url_for(:only_path => false, :controller => 'contact_congress_letters', :action => 'show', :id => @contact_congress_letter), url_for(:only_path => false, :controller => 'contact_congress_letters', :action => 'show', :id => @contact_congress_letter)
+
+ %p.center.bold Your communication can be more effective by following the steps below.
+
+
+ .after_steps
+ .step
+ %h2 Share
+ .desc
+ A
+ = link_to 'page with your letter', :controller => 'contact_congress_letters', :action => 'show', :id => @contact_congress_letter
+ has been set up. Share it with your friends and followers!
+
+ .share_buttons
+ <a class="med_button twitter" href="#{twitter_share_for_letter(@contact_congress_letter)}"><span>#{image_tag 'twitter_logo.png'}</span></a>
+ <a class="med_button facebook" href="http://www.facebook.com/OpenCongress"><span>#{image_tag 'facebook_badge.png', :alt=>'Find our Facebook'}</span></a>
+
+ /
+ .tweet
+ <a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
+ /
+ .face
+ <div id="fb-root"></div><script src="http://connect.facebook.net/en_US/all.js#appId=217834678241023&amp;xfbml=1"></script><fb:like href="#{url_for :only_path => false, :controller => 'contact', :action => 'letter', :id => @contact_congress_letter}" send="true" layout="button_count" width="450" show_faces="true" font="lucida grande"></fb:like>
+
+ .step
+ %h2 Mail
+ .desc
+ = link_to 'Print', '#'
+ this letter and send it through the mail. Here's the address:
+ %p
+ - @contact_congress_letter.formageddon_threads.each do |thread|
+ %p
+ = thread.formageddon_recipient.formageddon_display_address.gsub(/\n/, "<br />").html_safe
+ .step.noborder
+ %h2 Call
+ .desc
+ Call your representatives at the numbers below:
+
+ - @contact_congress_letter.formageddon_threads.each do |thread|
+ %p
+ = "#{thread.formageddon_recipient.title_long} #{thread.formageddon_recipient.firstname} #{thread.formageddon_recipient.lastname}"
+ %br
+ = thread.formageddon_recipient.phone
+
View
10 app/views/contact_congress_letters/get_recipients.js.erb
@@ -0,0 +1,10 @@
+<% if @sens.nil? && @reps.nil? %>
+ $j('#contact_recipients_container').html("<div class='none'>We could not find your representatives with the info you provided. Please try again.");
+<% else %>
+ $j('#contact_recipients_container').html("<%= escape_javascript(render :partial => 'contact_congress_letters/contact_recipients', :locals => { :show_checkboxes => true }) %>");
+ $j('#contribution_data_container').html("<%= escape_javascript(render :partial => 'contact_congress_letters/message_builder_contribution_data') %>");
+
+ <% if @zip4 %>
+ $j('#formageddon_formageddon_thread_sender_zip4').val('<%= @zip4 %>');
+ <% end %>
+<% end %>
View
173 app/views/contact_congress_letters/new.html.haml
@@ -0,0 +1,173 @@
+%span.regarding You are writing regarding
+%h1.regarding= truncate("#{@bill.typenumber} #{@bill.title_common}", :length => 170)
+
+#heading
+ %h2 Contact Congress
+
+.contact_congress
+ = render 'contact_congress_status_bar', :step => 2
+
+ %h3.large_heading OpenCongress Message Builder
+
+ .contact_message_builder
+ %h2 OpenCongress Message Builder
+
+ .instructions.margin-bottom
+ Use the tools in this column to help craft your letter. Any time your mouse highlights a section, you can click on it to add prepared text to your message.
+
+ .section
+ %h3 Latest Action
+ %ul
+ %li.message_builder_clickable
+ %strong= @bill.last_action.formatted_date
+ = @bill.last_action
+ = render 'will_add_text_box', :text => "I know the most recent action for this bill is as follows: \"#{@bill.last_action}\" on #{@bill.last_action.formatted_date}"
+
+ .section
+ %h3 Bill Statistics on OpenCongress
+ %ul
+ - unless @position == 'tracking' or @bill.users_percentage_at_position(@position).nil?
+ %li.users_position.message_builder_clickable
+ = "#{@bill.users_percentage_at_position(@position)}% of users #{@position} #{@bill.typenumber}"
+ = render 'will_add_text_box', :text => "#{@bill.users_percentage_at_position(@position)}% of users on OpenCongress.org, a free, non-partisan resource, #{@position} #{@bill.typenumber}."
+ %li.page_views.message_builder_clickable
+ = "#{@bill.typenumber} has been viewed #{number_with_delimiter(@bill.page_views_count)} times"
+ = render 'will_add_text_box', :text => "#{@bill.typenumber} has been viewed #{number_with_delimiter(@bill.page_views_count)} times on OpenCongress.org, a free, non-partisan resource."
+
+ .section
+ %h3 Contribution Data
+ #contribution_data_container
+ - unless @sens.empty? and @reps.empty?
+ = render :partial => 'message_builder_contribution_data'
+
+ - unless @bill.bill_position_organizations_support.empty?
+ .section
+ %h3 Supporting Organizations
+ = render 'message_builder_organizations', :disposition => 'support', :orgs => @bill.bill_position_organizations_support
+
+ - unless @bill.bill_position_organizations_oppose.empty?
+ .section
+ %h3 Opposing Organizations
+ = render 'message_builder_organizations', :disposition => 'oppose', :orgs => @bill.bill_position_organizations_oppose
+
+
+ .section
+ %h3 Most-commented sections of the bill text
+ %ul
+ - @bill.bill_text_versions.last.top_comment_nodes(5).each do |n|
+ %li.message_builder_clickable
+ = n.bill_text
+ = " (#{n.comments.count} comments, "
+ = link_to 'Link', bill_text_path(:id => n.bill_text_version.bill, :nid => n.nid, :version => n.bill_text_version.version)
+ = ")"
+
+ = render 'will_add_text_box', :text => "specifically, this section of the legislation: \"#{n.bill_text}\","
+
+
+
+
+ .section
+ %h3 Highest Rated User Comments
+ %ul
+ - @bill.comments.order("comments.plus_score_count - comments.minus_score_count DESC").limit(3).each do |c|
+ %li.message_builder_clickable
+ On
+ = "#{c.created_at.strftime("%B %d, %Y")},"
+ by
+ = link_to c.user.login, user_profile_path(c.user.login)
+ \-
+ = c.comment
+ = render 'will_add_text_box', :text => "As noted by #{c.user.login}, a user on OpenCongress.org, on #{c.created_at.strftime("%B %d, %Y")}, \"#{c.comment}\""
+
+ .section
+ %h3 Highly Rated Blog Articles
+ %ul
+ - @bill.blogs.order('commentaries.average_rating IS NOT NULL DESC').limit(3).each do |a|
+ = render 'message_builder_commentary', :a => a
+
+ .section
+ %h3 Highly Rated News Articles
+ %ul
+ - @bill.news.order('commentaries.average_rating IS NOT NULL DESC').limit(3).each do |a|
+ = render 'message_builder_commentary', :a => a
+
+
+
+
+ = form_for @formageddon_thread do |f|
+ .contact_letter
+ #contact_recipients_container
+ - if @sens.empty? and @reps.empty?
+ .contact_recipients
+ #none.none
+ Input your address on the right and we'll find your reps.
+ - else
+ = render 'contact_recipients', :show_checkboxes => true
+ .desk
+ %span.from From the Desk of Username
+ %span.the-user a user out of District something or other
+ .formageddon_contact_form
+ = render 'formageddon/threads/form', :f => f, :thread => @formageddon_thread
+
+ = hidden_field_tag :after_send_url, "/contact_congress_letters/create_from_formageddon?bill=#{@bill.ident}&disposition=#{@position}"
+
+ %ul.instruction
+ %li Click send, and we will automatically deliver your letter to the members of Congress you selected above.
+ %li On the next page, you may review your letter, share it with your community using social media, and track any official replies you may receive from members of Congress.
+
+ .value
+ %p OpenCongress is the only not-for-profit website that enables you to write all three of your members of Congress at once.
+ %p OpenCongress is the only website that gives this information back to the public commons, enabling you to find other constituents near you who are tracking the same bills and issues.
+
+:javascript
+ $j("#formageddon_formageddon_thread_sender_zip5").keyup(function() {
+ if ($j(this).val().length == 5) {
+ $j("#none").html("<img src='/images/spinner-ovals.gif' />");
+ $j.ajax({
+ url: '/contact_congress_letters/get_recipients?bill=#{@bill.ident}' + '&address=' + escape($j("#formageddon_formageddon_thread_sender_address1").val()) + '&zip5=' + $j(this).val()
+ });
+ }
+ });
+
+ $j("#formageddon_formageddon_thread_sender_zip4").keyup(function() {
+ if ($j(this).val().length == 4) {
+ $j("#rep").html("<img class='spin' src='/images/spinner-ovals.gif' />");
+
+ $j.ajax({
+ url: '/contact_congress_letters/get_recipients?bill=#{@bill.ident}' + '&rep_only=true&address=' + escape($j(this).val()) + '&zip5=' + $j("#formageddon_formageddon_thread_sender_zip5").val() + '&zip4=' + $j("#formageddon_formageddon_thread_sender_zip4").val()
+ });
+ }
+ });
+
+ $j("#formageddon_formageddon_thread_sender_address1").change(function() {
+ $j("#rep").html("<img class='spin' src='/images/spinner-ovals.gif' />");
+
+ $j.ajax({
+ url: '/contact_congress_letters/get_recipients?bill=#{@bill.ident}' + '&rep_only=true&address=' + escape($j(this).val()) + '&zip5=' + $j("#formageddon_formageddon_thread_sender_zip5").val() + '&zip4=' + $j("#formageddon_formageddon_thread_sender_zip4").val()
+ });
+ });
+
+ $j(".message_builder_clickable").hover(
+ function () {
+ $j(this).find("div.will_add_text_box:first").fadeIn(.3);
+ },
+ function () {
+ $j(this).find("div.will_add_text_box:first").fadeOut(.3);
+ }
+ );
+ $j(".message_builder_clickable").click(
+ function () {
+ txt = $j(this).find("div.message_builder_add_text:first").text();
+ msg = $j('div.formageddon_contact_form textarea:first')
+ msg.val(msg.val()+"\n\n"+unescape(txt));
+ }
+ );
+
+ $j(document).ready(function() {
+ $j('.formageddon_submit').addClass("button blue huge");
+ });
+
+
+<link href='http://fonts.googleapis.com/css?family=La+Belle+Aurore' rel='stylesheet' type='text/css'>
+
+
View
35 app/views/contact_congress_letters/select_position.html.haml
@@ -0,0 +1,35 @@
+%span.regarding You are writing regarding
+%h1.regarding= truncate("#{@bill.typenumber} #{@bill.title_common}", :length => 170)
+
+#heading
+ %h2 Contact Congress
+
+.contact_congress
+
+ = render 'contact_congress_status_bar', :step => 1
+
+ .selections.floatright
+ %p.margin-top
+ %h3.center What is your position on this bill?
+
+ .position_buttons.padding
+ %a.button.blue.huge.margin-right{ :href => url_for(:action => 'new', :bill => @bill.ident, :position => 'support') }
+ %span= "I Support #{@bill.typenumber}"
+ %a.button.yellow.huge.margin-right{ :href => url_for(:action => 'new', :bill => @bill.ident, :position => 'oppose') }
+ %span= "I Oppose #{@bill.typenumber}"
+ %a.button.silver.huge.margin-right{ :href => url_for(:action => 'new', :bill => @bill.ident, :position => 'tracking') }
+ %span= "I Am Tracking #{@bill.typenumber}"
+
+
+ .margin-left
+ - if @sens.empty? and @reps.empty?
+ .contact_recipients
+ .none
+ Select your position and we'll find your reps on the next page.
+
+ -else
+ = render :partial => 'contact_recipients'
+
+ %br
+ %br
+
View
48 app/views/contact_congress_letters/show.html.haml
@@ -0,0 +1,48 @@
+#heading
+ %h2 Contact Congress
+
+
+.contact_congress_letter
+ - if @contact_congress_letter.bill
+ #bill
+ This letter was sent regarding:
+ %strong= link_to truncate("#{@contact_congress_letter.bill.typenumber} #{@contact_congress_letter.bill.title_common}", :length => 170), bill_path(@contact_congress_letter.bill)
+ - if @contact_congress_letter.formageddon_threads.first.formageddon_sender
+ by
+ = link_to @contact_congress_letter.formageddon_threads.first.formageddon_sender.login, user_profile_path(@contact_congress_letter.formageddon_threads.first.formageddon_sender.login)
+ #recipients{ :class => "num#{@contact_congress_letter.formageddon_threads.size}" }
+ .to To:
+ %ul
+ - @contact_congress_letter.formageddon_threads.each do |t|
+ %li
+ = image_tag "photos/thumbs_50/#{t.formageddon_recipient.id}-50px.jpeg", :class =>"photo", :alt => 'photo'
+
+ .recipient_info
+ = link_to t.formageddon_recipient.name, person_path(t.formageddon_recipient)
+ - if @contact_congress_letter.bill
+ %span
+ = "Vote on Passage of #{@contact_congress_letter.bill.typenumber}: "
+ %strong= "#{@contact_congress_letter.bill.vote_on_passage(t.formageddon_recipient)}"
+
+
+
+ .comment-thing
+ .sharing
+ %p Share this letter with your friends and followers!
+
+ .tweet
+ <a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
+
+ .face
+ <div id="fb-root"></div><script src="http://connect.facebook.net/en_US/all.js#appId=217834678241023&amp;xfbml=1"></script><fb:like href="#{url_for :only_path => false, :controller => 'contact_congress_letters', :action => 'show', :id => @contact_congress_letter}" send="true" layout="button_count" width="450" show_faces="true" font="lucida grande"></fb:like>
+
+ %p Comment on this letter below
+
+
+
+ .formageddon_letter
+ .subject= @contact_congress_letter.formageddon_threads.first.formageddon_letters.first.subject
+ .body= @contact_congress_letter.formageddon_threads.first.formageddon_letters.first.message.gsub(/\n/, "<br />").html_safe
+
+ #letter_comments
+ = render :partial => 'shared/comments', :locals => { :object => @contact_congress_letter }
View
18 app/views/contact_congress_letters/showthread.html.haml
@@ -0,0 +1,18 @@
+#heading
+ %h2 Contact Congress
+
+.padding
+ -# FOR REFACTOR. should combine with share on blog
+ .permshare
+ = render :partial => 'contact_congress_share'
+
+
+ .contact_thread_header
+ %h4 Below is a thread of correspondence between
+ = link_to @thread.formageddon_sender.login, user_profile_path(@thread.formageddon_sender)
+ and
+ = link_to @thread.formageddon_recipient.name, person_path(@thread.formageddon_recipient)
+ \.
+
+
+ = render 'formageddon/threads/thread', :thread => @thread
View
5 app/views/districts/index.html.erb
@@ -10,13 +10,8 @@
<tr>
<td><%=h district.district_number %></td>
<td><%=h district.state_id %></td>
- <td><%= link_to 'Show', district %></td>
- <td><%= link_to 'Edit', edit_district_path(district) %></td>
- <td><%= link_to 'Destroy', district, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
-
-<%= link_to 'New district', new_district_path %>
View
12 app/views/districts/show.html.erb
@@ -12,11 +12,21 @@
<div class="padding">
<div class="col12">
- <h3><%= link_to "&larr; #{@state.name}", state_url(@state.abbreviation) %></h3>
+ <h3><%= link_to raw("&larr; #{@state.name}"), state_url(@state.abbreviation) %></h3>
<p><%= @district.freebase_description %>
<em>(More from <%= link_to "Freebase", @state.freebase_link %>)</em></p>
+ <div class='district-senators-box'>
+ <h2 class="dark">Senators</h2>
+ <%= render @senators %>
+ </div>
+
+ <div class='district-rep-box'>
+ <h2 class="dark">Representative</h2>
+ <%= render @representative %>
+ </div>
+
<div class="col1">
<% unless @tracking_suggestions.last[:my_bills_tracked_facet].first[:trackers] == 0 %>
View
16 app/views/layouts/_header.html.erb
@@ -6,7 +6,7 @@
</p>
<div id="user_account">
-
+ <%= fb_connect_async_js %>
<% if logged_in? %>
Welcome <b><%= link_to h(current_user.login), user_profile_url(current_user.login) %></b> |
@@ -16,16 +16,22 @@
<%= link_to 'Manage SEO/Site Text for this Page', {:controller => 'admin/site_text_pages', :action => 'edit', :pageparams => params, :page_text_editable_type => @user_object.class.name.capitalize, :page_text_editable_id => @user_object.id } %> |
<% else %>
- <%= link_to 'Manage SEO/Site Text for this Page', {:controller => 'admin/site_text_pages', :action => 'edit', :pageparams => params } %> |
+ <%= link_to 'Manage SEO/Site Text for this Page', {:controller => 'admin/site_text_pages', :action => 'edit', :pageparams => params } %> |
<% end %>
<% end %>
- <%= link_to "Logout", logout_path %>
-
+ <% if @facebook_user %>
+ <%= fb_logout_link("Logout", url_for(:controller => 'logout', :only_path => false)) %>
+ <% else %>
+ <%= link_to "Logout", logout_path %> |
+ <%= fb_login_and_redirect(request.url, {:text => 'Connect with Facebook', :perms => 'email'}) %>
+ <% end %>
<% else %>
<%= link_to_function "Search", "['login','login-link','search-toggle'].each(Element.toggle);", :id => "search-toggle", :style => "display:none;" %>
- <%= link_to_function "Login", "['login','login-link','search-toggle'].each(Element.toggle);", login_url, :id => "login-link" %> | <%= link_to "Register", :controller => 'account', :action => 'signup' %>
+ <%= link_to_function "Login with OC", "['login','login-link','search-toggle'].each(Element.toggle);", login_url, :id => "login-link" %> |
+ <%= link_to "Register", :controller => 'account', :action => 'signup' %> |
+ <%= fb_login_and_redirect(request.url, {:text => 'Login with Facebook', :perms => 'email'}) %>
<% end %>
</div>
</div>
View
2  app/views/layouts/frontpage.html.erb
@@ -22,7 +22,7 @@
<%= include_javascripts :frontpage %>
<%= csrf_meta_tag %>
<%= remote_forgery_protection %>
-
+
<%= include_stylesheets :frontpage, :media => 'all' %>
<!--[if lt IE 7]><style type="text/css">@import url("/stylesheets/ie6.css");</style><![endif]-->
View
18 app/views/people/_person.html.haml
@@ -0,0 +1,18 @@
+- bgcolor = "#FFFFFF"
+- bgcolor = "#FFEEEE" if person.party == "Republican"
+- bgcolor = "#EEEEFF" if person.party == "Democrat"
+%div{:class => "person_box_big", :style => "background-color:#{bgcolor};margin-bottom:3px;"}
+ = link_to image_tag("http://www.opencongress.org/images/photos/thumbs_50/#{person.id}-50px.jpeg", :class =>"photo", :alt => 'photo'), person_url(person.id)
+ %p
+ = link_to person.full_name, person_url(person.id), :class => 'full_name'
+ - if person.in_a_valid_district?
+ %span= link_to("#{person.district.to_i.ordinalize} District", state_district_path(person.state, person.district))
+ %span= person.party
+ - if person == @senators.first
+ %strong
+ = pluralize(person.consecutive_years, 'year')
+ in office
+ - else
+ = pluralize(person.consecutive_years, 'year')
+ in office
+ %div(style="clear:both;")
View
2  app/views/person/_topic.html.erb
@@ -3,7 +3,7 @@
<h3><em><%= @person.title_common %> <%= @person.full_name %></em></h3>
<h5>
<%= @person.party %> &nbsp;&bull;&nbsp;
- <%= "#{@person.district.to_i.ordinalize} District, " if (@person.representative? && @person.district != '0')%>
+ <%= link_to("#{@person.district.to_i.ordinalize} District", state_district_path(@person.state, @person.district)) + ', ' if @person.in_a_valid_district? %>
<%= "#{State.for_abbrev(@person.state)} &nbsp;&bull;&nbsp;".html_safe unless @person.state.blank? %>
<%= @person.is_sitting? ? "#{@person.consecutive_roles.size.ordinalize} Term" : "#{@person.consecutive_roles.size} Terms" %> &nbsp;&bull;&nbsp;
Sworn In <%= @person.consecutive_roles.last.startdate.strftime("%Y") %>
View
7 app/views/shared/_comments.html.haml
@@ -1,7 +1,8 @@
#comments-container
%a#comments{ :name => "comments" }
- = render :partial => 'shared/sort_comments'
+ - if object.comments.size > 1
+ = render :partial => 'shared/sort_comments'
%h2.comments_title
Comments
@@ -9,9 +10,7 @@
- link = @bill ? "/comments/atom/bill/#{@bill.id}" : "/comments/atom/person/#{@person.id}"
%a.feed{ :href => link} Feed
%a.feed.comment_feed{ :href => "/articles/all_comments_atom" }
- = dbox_trigger('about_comments')
-
- .dboxed= dbox_content("about_comments")
+
/
.rating_filter
View
4 app/views/shared/_comments_list.html.haml
@@ -18,6 +18,8 @@
= will_paginate comments, { :renderer => 'RemoteLinkRenderer', :param_name => 'comment_page', :params => { :controller => 'comments', :action => 'bill_text_comments', :version => object.bill_text_version.id, :nid => object.nid, :comment_sort => params[:comment_sort], :anchor => 'comments'}, :remote => {:update => "bill_text_comments_#{object.nid}" }}
- elsif object.kind_of? Article
= will_paginate comments, :param_name => 'comment_page', :params => { :controller => object.display_object_name.downcase, :action => 'view', :id => object.to_param, :comment_sort => params[:comment_sort], :anchor => 'comments'}
+ - elsif object.kind_of? ContactCongressLetter
+ = will_paginate comments, :param_name => 'comment_page', :params => { :controller => 'contact', :action => 'letter', :id => object.id, :comment_sort => params[:comment_sort], :anchor => 'comments'}
- else
= will_paginate comments, :param_name => 'comment_page', :params => { :controller => object.display_object_name.downcase, :action => 'comments', :id => ((object.display_object_name == 'Bill') ? object.ident : object.id), :navtab => 'comments', :comment_sort => params[:comment_sort], :anchor => 'comments'}
@@ -31,6 +33,8 @@
= will_paginate comments, { :renderer => 'RemoteLinkRenderer', :param_name => 'comment_page', :params => { :controller => 'comments', :action => 'bill_text_comments', :version => object.bill_text_version.id, :nid => object.nid, :comment_sort => params[:comment_sort], :anchor => 'comments'}, :remote => {:update => "bill_text_comments_#{object.nid}" }}
- elsif object.kind_of? Article
= will_paginate comments, :param_name => 'comment_page', :params => { :controller => object.display_object_name.downcase, :action => 'view', :id => object.id, :comment_sort => params[:comment_sort], :anchor => 'comments'}
+ - elsif object.kind_of? ContactCongressLetter
+ = will_paginate comments, :param_name => 'comment_page', :params => { :controller => 'contact', :action => 'letter', :id => object.id, :comment_sort => params[:comment_sort], :anchor => 'comments'}
- else
= will_paginate comments, :param_name => 'comment_page', :params => { :controller => object.display_object_name.downcase, :action => 'comments', :id => ((object.display_object_name == 'Bill') ? object.ident : object.id), :navtab => 'comments', :comment_sort => params[:comment_sort], :anchor => 'comments'}
View
6 app/views/shared/_error_messages.html.haml
@@ -0,0 +1,6 @@
+- if target.errors.any?
+ #errors
+ %h3 There was an error with your submission!
+ %ul
+ - target.errors.full_messages.each do |msg|
+ %li= msg