hulse 0.5 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 904848309e824d9e0c4ded85597ba3f0e7409d46
4
- data.tar.gz: 9dc85ec003bf1b9c1c5cd3b8602150413109b283
3
+ metadata.gz: 24805bee84bd7c6a90544f7d70c98c0eb32661c2
4
+ data.tar.gz: f8e91bcffaca717a42d71e1f5bd1903fa52da684
5
5
  SHA512:
6
- metadata.gz: 8277fdc3417493c205504d907a17b68aa4d5d9dcb5cd8a7898e4f21db786912450814749218468ee997e1dffde0d3f97eed145ffba2edf89dff804dd22862f0c
7
- data.tar.gz: 97c18eccfd0850e1b116223e132ee5b066881b1b472e250489baa59d48b80ca30df3d6ebef679685a19adff93babfebdb9b4ec973941a8427adf5f791827137d
6
+ metadata.gz: 3171a1108d9677464ff0ddd67f3780ae37128dd0118f68efba14215f1033647ebd92fd19d6da0fbf7d7e14a14dce7649ddd17a48f702638f6770a393e06465eb
7
+ data.tar.gz: c7739d66a725f05131c0d4e696a6647bd0c2b535eb453a9ef06b52a53e26459516673e1a420b097936aed8da074bbdfaa5acdcad1187151b8074255d7c6e9e34
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Hulse
2
2
 
3
- Hulse is a Ruby gem for accessing House and Senate roll call votes from the official sources on [house.gov](http://clerk.house.gov/evs/2013/index.asp) and [senate.gov](http://www.senate.gov/pagelayout/legislative/a_three_sections_with_teasers/votes.htm). It works using Ruby 1.9.3 and 2.x.
3
+ Hulse is a Ruby gem for accessing raw data and information published by and about the U.S. Congress. It works using Ruby 1.9.3, 2.0, 2.1 and 2.2. It is not a wrapper for existing non-governmental APIs of congressional information. Instead, it loads, parses and scrapes official sources.
4
+
5
+ Hulse can be used to get House and Senate roll call votes from the official sources on [house.gov](http://clerk.house.gov/evs/2013/index.asp) and [senate.gov](http://www.senate.gov/pagelayout/legislative/a_three_sections_with_teasers/votes.htm).
4
6
 
5
7
  Hulse has two vote classes, `HouseVote` and `SenateVote`, which create Ruby objects using the XML attributes available from roll call vote data (voice votes are not covered by Hulse or available as data from official sources). Hulse makes a few changes, renaming some attributes for clarity and consistency, and collapsing each House vote's date and time into a single datetime attribute. Otherwise it does not alter the original data.
6
8
 
@@ -8,6 +10,8 @@ Hulse has two vote classes, `HouseVote` and `SenateVote`, which create Ruby obje
8
10
 
9
11
  Hulse also has two member classes, `HouseMember` and `SenateMember`, which create Ruby objects using the XML made available by the Clerk of the House and the Secretary of the Senate. House members have some basic information, including the unique `bioguide_id`, along with office details and committee and subcommittee assignment data. For vacant seats, information on the seat's previous occupant is available. Senate members have less information, but their data includes the Senate class and the URLs of their websites and email forms.
10
12
 
13
+ Hulse has two other classes, `HouseFloor` and `Record`. The former provides a wrapper to [XML data on floor activity](http://clerk.house.gov/floorsummary/floor.aspx?day=20150729) published by the Clerk of the House, including timestamps and descriptions. The `Record` class provides a basic wrapper to the [Congressional Record](https://www.congress.gov/congressional-record), the daily listing of activities by the House and Senate, as well as some methods for accessing specific portions of it, particularly the titles and permalinks of articles.
14
+
11
15
  Hulse is named for [Carl Hulse](https://www.nytimes.com/learning/students/ask_reporters/Carl_Hulse.html), a longtime congressional correspondent for The New York Times.
12
16
 
13
17
  ## Installation
@@ -47,6 +51,18 @@ For Senate votes, you can grab a year's SenateVote objects (with a limited set o
47
51
  2.0.0p353 :007 > senate_2013.first
48
52
  => <Hulse::SenateVote:0x000001017f0d58 @congress=113, @session=1, @year=2013, @vote_number="00291", @vote_date=<Date: 2013-12-20 ((2456647j,0s,0n),+0s,2299161j)>, @issue="PN921", @question="On the Cloture Motion", @vote_result="Agreed to", @vote_count={:yeas=>"59", :nays=>"34"}, @vote_title="Motion to Invoke Cloture on the Nomination of Janet L. Yellen to be Chairman of the Board of Governors of the Federal Reserve System">
49
53
  ```
54
+ House and Senate members have a `current` class method that retrieves the latest XML data from the House and Senate websites and creates Ruby objects. The House file has more data, including vacancies, than the Senate file does.
55
+
56
+ ```ruby
57
+ irb(main):003:> require 'hulse'
58
+ irb(main):003:0> members = Hulse::HouseMember.current
59
+ irb(main):004:0> members.first
60
+ => <Hulse::HouseMember:0x007fc6cb37f020 @bioguide_id="Y000033", @sort_name="YOUNG,DON", @last_name="Young", @first_name="Don", @middle_name=nil, @suffix=nil, @courtesy="Mr.", @official_name="Don Young", @formal_name="Mr. Young of Alaska", @party="R", @caucus_party="R", @state_postal="AK", @state_name="Alaska", @district="At Large", @district_code="AK00", @hometown="Fort Yukon", @office_building="RHOB", @office_room="2314", @office_zip="20515-0200", @phone="(202) 225-5765", @last_elected_date=#<Date: 2014-11-04 ((2456966j,0s,0n),+0s,2299161j)>, @sworn_date=#<Date: 2015-01-12 ((2457035j,0s,0n),+0s,2299161j)>, @committees=[{"comcode"=>"II00", "rank"=>"2"}, {"comcode"=>"PW00", "rank"=>"2"}], @subcommittees=[{"subcomcode"=>"II10", "rank"=>"2"}, {"subcomcode"=>"II13", "rank"=>"2"}, {"subcomcode"=>"II24", "rank"=>"1", "leadership"=>"Chairman"}, {"subcomcode"=>"PW05", "rank"=>"2"}, {"subcomcode"=>"PW07", "rank"=>"2"}, {"subcomcode"=>"PW12", "rank"=>"2"}], @is_vacant=false, @footnote=nil, @predecessor=nil, @vacancy_date=nil>
61
+ ```
62
+
63
+ ## Tests
64
+
65
+ Hulse uses `MiniTest` for development. To run the tests, do `rake test`.
50
66
 
51
67
  ## Authors
52
68
 
data/hulse.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "minitest"
24
24
  spec.add_dependency "httparty"
25
+ spec.add_dependency "nokogiri"
25
26
  spec.add_dependency "oj"
26
27
  spec.add_dependency "american_date"
27
28
  end
@@ -0,0 +1,40 @@
1
+ module Hulse
2
+ class HouseFloor
3
+
4
+ attr_reader :legislative_day, :finished, :actions, :congress, :session, :url, :next_session
5
+
6
+ def initialize(params={})
7
+ params.each_pair do |k,v|
8
+ instance_variable_set("@#{k}", v)
9
+ end
10
+ end
11
+
12
+ def self.latest_dates
13
+ url = "http://clerk.house.gov/floorsummary/floor-rss.ashx"
14
+ response = HTTParty.get(url)
15
+ xml = response.parsed_response
16
+ xml['rss']['channel']['item'].map{|i| Date.parse(i['pubDate']).to_s}.uniq
17
+ end
18
+
19
+ def self.date(date)
20
+ url = "http://clerk.house.gov/floorsummary/Download.aspx?file=#{date.to_s.gsub('-','')}.xml"
21
+ response = HTTParty.get(url)
22
+ xml = HTTParty::Parser.call(response.parsed_response, :xml)
23
+ self.create_from_xml(xml)
24
+ end
25
+
26
+ def self.create_from_xml(xml)
27
+ actions = []
28
+ xml['legislative_activity']['floor_actions']['floor_action'].each do |action|
29
+ actions << action.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
30
+ end
31
+ results = self.new(congress: xml['legislative_activity']['legislative_congress']['congress'].to_i,
32
+ session: xml['legislative_activity']['legislative_congress']['session'].to_i,
33
+ legislative_day: xml['legislative_activity']['legislative_day']['__content__'].strip,
34
+ finished: xml['legislative_activity']['floor_actions']['legislative_day_finished']['__content__'],
35
+ url: "http://clerk.house.gov/floorsummary/floor.aspx?day=#{xml['legislative_activity']['legislative_day']['date']}",
36
+ next_session: DateTime.parse(xml['legislative_activity']['floor_actions']['legislative_day_finished']['next_legislative_day_convenes']),
37
+ actions: actions)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,104 @@
1
+ module Hulse
2
+ class Record
3
+
4
+ attr_reader :date, :section, :topics, :html
5
+
6
+ def initialize(params={})
7
+ params.each_pair do |k,v|
8
+ instance_variable_set("@#{k}", v)
9
+ end
10
+ end
11
+
12
+ def to_s
13
+ section
14
+ end
15
+
16
+ def self.base_url(date=nil)
17
+ if date
18
+ year, month, day = date.year, date.month, date.day
19
+ else
20
+ date = Date.today-1
21
+ year, month, day = date.year, date.month, date.day
22
+ end
23
+ "https://www.congress.gov/congressional-record/#{year}/#{month}/#{day}/"
24
+ end
25
+
26
+ def self.daily_digest(date=nil)
27
+ doc = HTTParty.get(base_url(date)+'daily-digest')
28
+ html = Nokogiri::HTML(doc.parsed_response)
29
+ (html/:pre).text
30
+ end
31
+
32
+ def self.senate(date=nil)
33
+ doc = HTTParty.get(base_url(date)+'senate-section')
34
+ create_from_html(Nokogiri::HTML(doc.parsed_response), date, 'senate')
35
+ end
36
+
37
+ def self.house(date=nil)
38
+ doc = HTTParty.get(base_url(date)+'house-section')
39
+ create_from_html(Nokogiri::HTML(doc.parsed_response), date, 'house')
40
+ end
41
+
42
+ def self.extension_of_remarks(date=nil)
43
+ doc = HTTParty.get(base_url(date)+'extensions-of-remarks-section')
44
+ create_from_html(Nokogiri::HTML(doc.parsed_response), date, 'extension')
45
+ end
46
+
47
+ def self.create_from_html(html, date, section)
48
+ section_topics = topics(html)
49
+ self.new(date: date,
50
+ section: section,
51
+ topics: section_topics,
52
+ html: html
53
+ )
54
+ end
55
+
56
+ def self.topics(html)
57
+ (html/:td).map{|d| d.children[1]}.compact.map{|l| {url: l['href'], title: l.text.strip}}
58
+ end
59
+
60
+ def has_senate_explanations?
61
+ topics.select{|l| l[:title].include?("VOTE EXPLANATION")}.empty? ? false : true
62
+ end
63
+
64
+ def senate_explanations
65
+ topics.select{|l| l[:title].include?("VOTE EXPLANATION")}
66
+ end
67
+
68
+ def has_personal_explanations?
69
+ topics.select{|l| l[:title].include?("PERSONAL EXPLANATION")}.empty? ? false : true
70
+ end
71
+
72
+ def personal_explanations
73
+ topics.select{|l| l[:title].include?("PERSONAL EXPLANATION")}
74
+ end
75
+
76
+ def has_committee_elections?
77
+ topics.select{|l| l[:title].include?("COMMITTEE ELECTION")}.empty? ? false : true
78
+ end
79
+
80
+ def committee_elections
81
+ topics.select{|l| l[:title].include?("COMMITTEE ELECTION")}
82
+ end
83
+
84
+ def has_committee_resignations?
85
+ topics.select{|l| l[:title].include?("COMMITTEE RESIGNATION")}.empty? ? false : true
86
+ end
87
+
88
+ def chairman_designations
89
+ topics.select{|l| l[:title].include?("DESIGNATING THE CHAIRMAN")}
90
+ end
91
+
92
+ def ranking_designations
93
+ topics.select{|l| l[:title].include?("DESIGNATING THE RANKING")}
94
+ end
95
+
96
+ def leaves_of_absence
97
+ topics.select{|l| l[:title].include?("LEAVE OF ABSENCE")}
98
+ end
99
+
100
+ def committee_leaves_of_absence
101
+ topics.select{|l| l[:title].include?("COMMITTEE LEAVE OF ABSENCE")}
102
+ end
103
+ end
104
+ end
data/lib/hulse/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Hulse
2
- VERSION = "0.5"
2
+ VERSION = "0.6"
3
3
  end
data/lib/hulse.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'httparty'
2
2
  require 'oj'
3
+ require 'nokogiri'
3
4
  require "hulse/version"
5
+ require "hulse/record"
4
6
  require "hulse/house_vote"
5
7
  require "hulse/house_member"
8
+ require "hulse/house_floor"
6
9
  require "hulse/senate_vote"
7
10
  require "hulse/senate_member"
8
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hulse
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.5'
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Willis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-23 00:00:00.000000000 Z
11
+ date: 2015-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: oj
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -109,8 +123,10 @@ files:
109
123
  - Rakefile
110
124
  - hulse.gemspec
111
125
  - lib/hulse.rb
126
+ - lib/hulse/house_floor.rb
112
127
  - lib/hulse/house_member.rb
113
128
  - lib/hulse/house_vote.rb
129
+ - lib/hulse/record.rb
114
130
  - lib/hulse/senate_member.rb
115
131
  - lib/hulse/senate_vote.rb
116
132
  - lib/hulse/version.rb
@@ -136,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
152
  version: '0'
137
153
  requirements: []
138
154
  rubyforge_project:
139
- rubygems_version: 2.2.2
155
+ rubygems_version: 2.4.5
140
156
  signing_key:
141
157
  specification_version: 4
142
158
  summary: Hulse is a Ruby gem for accessing House and Senate roll call votes and member