luigi-sunlight 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.textile +8 -0
- data/README.textile +37 -11
- data/lib/sunlight.rb +22 -19
- data/lib/sunlight/district.rb +24 -24
- data/lib/sunlight/legislator.rb +107 -23
- data/sunlight.gemspec +2 -2
- metadata +4 -2
data/CHANGES.textile
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
h3. 0.2.0 / 2009-03-01
|
2
|
+
|
3
|
+
* Add support for twitter_id and youtube_url on Legislator
|
4
|
+
* Add Legislator#search_by_name for fuzzy name searching
|
5
|
+
* Add Legislator#all_in_zipcode for better lookups on a five-digit zip code
|
6
|
+
* Raise exception when API Key isn't set
|
7
|
+
* Credit for various fixes goes to GitHub users pengwynn, hoverbird, and wilson
|
8
|
+
|
1
9
|
h3. 0.1.0 / 2008-08-20
|
2
10
|
|
3
11
|
* Initial version
|
data/README.textile
CHANGED
@@ -38,18 +38,22 @@ First, register for an API key "here":http://services.sunlightlabs.com/api/regis
|
|
38
38
|
|
39
39
|
Then, you'll want to stick the following lines somewhere in your Ruby environment.
|
40
40
|
|
41
|
-
<code>
|
41
|
+
<pre><code>
|
42
42
|
require 'rubygems'
|
43
43
|
require 'sunlight'
|
44
44
|
include Sunlight
|
45
45
|
Sunlight.api_key = 'yourapikeyfromtheurlabove'
|
46
|
-
</code>
|
46
|
+
</code></pre>
|
47
47
|
|
48
|
-
If you're testing this out in IRB, you'll run them one at a time.
|
48
|
+
If you're testing this out in IRB, you'll run them one at a time. If you're using Rails 2.1, stick them in a file called @sunlight.rb@ in @RAILS_ROOT/config/initializers@. They'll load on app startup.
|
49
49
|
|
50
50
|
h2. Usage
|
51
51
|
|
52
|
-
|
52
|
+
The Sunlight gem currently supports the Legislator and District objects. The Lobbyist object is coming soon.
|
53
|
+
|
54
|
+
h3. Legislator
|
55
|
+
|
56
|
+
Time to get to the good stuff. The most useful method is @Legislator#all_for@:
|
53
57
|
|
54
58
|
<pre><code>
|
55
59
|
congresspeople = Legislator.all_for(:address => "123 Fifth Ave New York, NY 10003")
|
@@ -63,17 +67,28 @@ Now, it's time to get to the good stuff. The most useful method is @Legislator#a
|
|
63
67
|
junior_senator.phone # returns "202-224-4451"
|
64
68
|
</code></pre>
|
65
69
|
|
66
|
-
Note that you should make the best attempt to get a full street address
|
70
|
+
Note that you should make the best attempt to get a full street address, as that is geocoded behind the scenes into a lat/long pair. If all you have is a five-digit zip code, you should not use @Legislator#all_for@, instead opting for @Legislator#all_in_zipcode@ (see below). If you pass in a zip+4, then go ahead and use @Legislator#all_for@.
|
67
71
|
|
68
|
-
So @Legislator#all_for@ returns a hash of @Legislator@ objects, and the keys are @:senior_senator@, @:junior_senator@, and @:representative@. You can also pass in a lat/long pair:
|
72
|
+
So @Legislator#all_for@ returns a hash of @Legislator@ objects, and the keys are @:senior_senator@, @:junior_senator@, and @:representative@. Make sure to review all the available fields from the "Sunlight Labs API":http://services.sunlightlabs.com/api/docs/legislators/. You can also pass in a lat/long pair:
|
69
73
|
|
70
74
|
<pre><code>
|
71
75
|
congresspeople = Legislator.all_for(:latitude => 33.876145, :longitude => -84.453789)
|
72
76
|
</code></pre>
|
73
77
|
|
74
|
-
This bypasses the geocoding necessary by the Google Maps API. For social networks and other applications with a User object, it makes sense to geocode the address up front and save the lat/long data in the local database. Then, use the lat/long pair instead of address, which cuts a substantial bit time from the @Legislator#all_for@ request since the Google Maps API Geocoding function doesn't have to be called.
|
78
|
+
This bypasses the geocoding necessary by the Google Maps API. For social networks and other applications with a User object, it makes sense to geocode the user's address up front and save the lat/long data in the local database. Then, use the lat/long pair instead of address, which cuts a substantial bit of time from the @Legislator#all_for@ request since the Google Maps API Geocoding function doesn't have to be called.
|
79
|
+
|
80
|
+
Have a five-digit zip code only? You can use the @Legislator#all_in_zipcode@ method, but keep in mind that a single zip may have multiple U.S. Representatives, as congressional district lines frequently divide populous zip codes. Unlike @Legislator#all_for@, this method returns an array of legislators, and it'll be up to you to parse through them (there will be a senior senator, a junior senator, and one or more representatives).
|
81
|
+
|
82
|
+
<pre><code>
|
83
|
+
members_of_congress = Legislator.all_in_zipcode(90210)
|
84
|
+
|
85
|
+
members_of_congress.each do |member|
|
86
|
+
# do stuff
|
87
|
+
end
|
88
|
+
|
89
|
+
</code></pre>
|
75
90
|
|
76
|
-
You can also use the @Legislator#all_where@ method for searching based on available fields.
|
91
|
+
You can also use the @Legislator#all_where@ method for searching based on available fields. Again, you'll get back an array of @Legislator@ objects:
|
77
92
|
|
78
93
|
<pre><code>
|
79
94
|
johns = Legislator.all_where(:firstname => "John")
|
@@ -85,7 +100,18 @@ You can also use the @Legislator#all_where@ method for searching based on availa
|
|
85
100
|
end
|
86
101
|
</code></pre>
|
87
102
|
|
88
|
-
|
103
|
+
Lastly, to provide your users with a name search functionality, use @Legislator#search_by_name@, which uses fuzzy matching to compensate for nicknames and misspellings. So "Teddy Kennedey" (real name Edward Kennedy) and "Jack Murtha" (real name John Murtha) will return the correct matches. You can specify a higher confidence threshold (default set to 0.80) if you feel that the matches being returned aren't accurate enough. This also returns an array of @Legislator@ objects:
|
104
|
+
|
105
|
+
<pre><code>
|
106
|
+
legislators = Legislator.search_by_name("Teddy Kennedey")
|
107
|
+
legislators = Legislator.search_by_name("Johnny Boy Kerry", 0.91)
|
108
|
+
</code></pre>
|
109
|
+
|
110
|
+
|
111
|
+
h3. District
|
112
|
+
|
113
|
+
|
114
|
+
There's also the @District@ object. @District#get@ takes in either lat/long or an address and does it's best to return the correct Congressional District:
|
89
115
|
|
90
116
|
<pre><code>
|
91
117
|
district = District.get(:latitude => 33.876145, :longitude => -84.453789)
|
@@ -95,7 +121,7 @@ There's also the @District@ object. @District#get@ takes in either lat/long or a
|
|
95
121
|
district = District.get(:address => "123 Fifth Ave New York, NY")
|
96
122
|
</code></pre>
|
97
123
|
|
98
|
-
Finally, two more methods, @District.all_from_zipcode@ and @District.zipcodes_in@, help you out when
|
124
|
+
Finally, two more methods, @District.all_from_zipcode@ and @District.zipcodes_in@, help you out when you want to get all districts in a given zip code, or if you want to get back all zip codes in a given district.
|
99
125
|
|
100
126
|
<pre><code>
|
101
127
|
districts = District.all_from_zipcode(90210) # returns array of District objects
|
@@ -107,7 +133,7 @@ h2. License
|
|
107
133
|
|
108
134
|
See the terms of usage for the "Sunlight Labs API":http://services.sunlightlabs.com/api/ and the "Google Maps API":http://code.google.com/apis/maps/terms.html.
|
109
135
|
|
110
|
-
Copyright ©
|
136
|
+
Copyright © 2009 by Luigi Montanez under the MIT License.
|
111
137
|
|
112
138
|
Permission is hereby granted, free of charge, to any person
|
113
139
|
obtaining a copy of this software and associated documentation
|
data/lib/sunlight.rb
CHANGED
@@ -2,58 +2,61 @@ require 'rubygems'
|
|
2
2
|
require 'json'
|
3
3
|
require 'cgi'
|
4
4
|
require 'ym4r/google_maps/geocoding'
|
5
|
+
require 'net/http'
|
5
6
|
include Ym4r::GoogleMaps
|
6
7
|
|
7
8
|
module Sunlight
|
8
|
-
|
9
|
+
|
9
10
|
API_URL = "http://services.sunlightlabs.com/api/"
|
10
11
|
API_FORMAT = "json"
|
11
12
|
attr_accessor :api_key
|
12
|
-
|
13
|
+
|
13
14
|
# Houses general methods to work with the Sunlight and Google Maps APIs
|
14
15
|
class SunlightObject
|
15
|
-
|
16
|
-
|
16
|
+
|
17
|
+
|
17
18
|
# Constructs a Sunlight API-friendly URL
|
18
19
|
def self.construct_url(api_method, params)
|
19
|
-
|
20
|
+
if Sunlight.api_key == nil or Sunlight.api_key == ''
|
21
|
+
raise "Failed to provide Sunlight API Key"
|
22
|
+
else
|
23
|
+
"#{API_URL}#{api_method}.#{API_FORMAT}?apikey=#{Sunlight.api_key}#{hash2get(params)}"
|
24
|
+
end
|
20
25
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
|
27
|
+
|
24
28
|
# Converts a hash to a GET string
|
25
29
|
def self.hash2get(h)
|
26
|
-
|
30
|
+
|
27
31
|
get_string = ""
|
28
|
-
|
32
|
+
|
29
33
|
h.each_pair do |key, value|
|
30
34
|
get_string += "&#{key.to_s}=#{CGI::escape(value.to_s)}"
|
31
35
|
end
|
32
|
-
|
36
|
+
|
33
37
|
get_string
|
34
|
-
|
38
|
+
|
35
39
|
end # def hash2get
|
36
40
|
|
37
|
-
|
41
|
+
|
38
42
|
# Use the Net::HTTP and JSON libraries to make the API call
|
39
43
|
#
|
40
44
|
# Usage:
|
41
45
|
# District.get_json_data("http://someurl.com") # returns Hash of data or nil
|
42
46
|
def self.get_json_data(url)
|
43
|
-
|
47
|
+
|
44
48
|
response = Net::HTTP.get_response(URI.parse(url))
|
45
49
|
if response.class == Net::HTTPOK
|
46
50
|
result = JSON.parse(response.body)
|
47
51
|
else
|
48
52
|
nil
|
49
53
|
end
|
50
|
-
|
54
|
+
|
51
55
|
end # self.get_json_data
|
52
|
-
|
53
|
-
|
54
|
-
|
56
|
+
|
57
|
+
|
55
58
|
end # class SunlightObject
|
56
|
-
|
59
|
+
|
57
60
|
end # module Sunlight
|
58
61
|
|
59
62
|
Dir["#{File.dirname(__FILE__)}/sunlight/*.rb"].each { |source_file| require source_file }
|
data/lib/sunlight/district.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Sunlight
|
2
2
|
|
3
3
|
class District < SunlightObject
|
4
|
-
|
4
|
+
|
5
5
|
attr_accessor :state, :number
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(state, number)
|
8
8
|
@state = state
|
9
9
|
@number = number
|
@@ -17,14 +17,14 @@ module Sunlight
|
|
17
17
|
def self.get(params)
|
18
18
|
|
19
19
|
if (params[:latitude] and params[:longitude])
|
20
|
-
|
20
|
+
|
21
21
|
get_from_lat_long(params[:latitude], params[:longitude])
|
22
|
-
|
22
|
+
|
23
23
|
elsif (params[:address])
|
24
24
|
|
25
25
|
# get the lat/long from Google
|
26
26
|
placemarks = Geocoding::get(params[:address])
|
27
|
-
|
27
|
+
|
28
28
|
unless placemarks.empty?
|
29
29
|
placemark = placemarks[0]
|
30
30
|
get_from_lat_long(placemark.latitude, placemark.longitude)
|
@@ -33,7 +33,7 @@ module Sunlight
|
|
33
33
|
else
|
34
34
|
nil # appropriate params not found
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
end
|
38
38
|
|
39
39
|
|
@@ -42,46 +42,46 @@ module Sunlight
|
|
42
42
|
# District.get_from_lat_long(-123, 123) # returns District object or nil
|
43
43
|
#
|
44
44
|
def self.get_from_lat_long(latitude, longitude)
|
45
|
-
|
45
|
+
|
46
46
|
url = construct_url("districts.getDistrictFromLatLong", {:latitude => latitude, :longitude => longitude})
|
47
|
-
|
47
|
+
|
48
48
|
if (result = get_json_data(url))
|
49
|
-
|
49
|
+
|
50
50
|
districts = []
|
51
51
|
result["response"]["districts"].each do |district|
|
52
52
|
districts << District.new(district["district"]["state"], district["district"]["number"])
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
districts.first
|
56
|
-
|
56
|
+
|
57
57
|
else
|
58
58
|
nil
|
59
59
|
end # if response.class
|
60
|
-
|
60
|
+
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
|
64
64
|
|
65
65
|
# Usage:
|
66
66
|
# District.all_from_zipcode(90210) # returns array of District objects
|
67
67
|
#
|
68
68
|
def self.all_from_zipcode(zipcode)
|
69
|
-
|
69
|
+
|
70
70
|
url = construct_url("districts.getDistrictsFromZip", {:zip => zipcode})
|
71
|
-
|
71
|
+
|
72
72
|
if (result = get_json_data(url))
|
73
|
-
|
73
|
+
|
74
74
|
districts = []
|
75
75
|
result["response"]["districts"].each do |district|
|
76
76
|
districts << District.new(district["district"]["state"], district["district"]["number"])
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
districts
|
80
|
-
|
80
|
+
|
81
81
|
else
|
82
82
|
nil
|
83
83
|
end # if response.class
|
84
|
-
|
84
|
+
|
85
85
|
end
|
86
86
|
|
87
87
|
|
@@ -90,9 +90,9 @@ module Sunlight
|
|
90
90
|
# District.zipcodes_in("NY", 29) # returns ["14009", "14024", "14029", ...]
|
91
91
|
#
|
92
92
|
def self.zipcodes_in(state, number)
|
93
|
-
|
93
|
+
|
94
94
|
url = construct_url("districts.getZipsFromDistrict", {:state => state, :district => number})
|
95
|
-
|
95
|
+
|
96
96
|
if (result = get_json_data(url))
|
97
97
|
result["response"]["zips"]
|
98
98
|
else
|
@@ -100,9 +100,9 @@ module Sunlight
|
|
100
100
|
end # if response.class
|
101
101
|
|
102
102
|
end
|
103
|
-
|
104
|
-
|
103
|
+
|
104
|
+
|
105
105
|
|
106
106
|
end # class District
|
107
107
|
|
108
|
-
end # module Sunlight
|
108
|
+
end # module Sunlight
|
data/lib/sunlight/legislator.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
module Sunlight
|
2
2
|
|
3
3
|
class Legislator < SunlightObject
|
4
|
-
|
4
|
+
|
5
5
|
|
6
6
|
attr_accessor :title, :firstname, :middlename, :lastname, :name_suffix, :nickname,
|
7
7
|
:party, :state, :district, :gender, :phone, :fax, :website, :webform,
|
8
8
|
:email, :congress_office, :bioguide_id, :votesmart_id, :fec_id,
|
9
|
-
:govtrack_id, :crp_id, :event_id, :congresspedia_url
|
10
|
-
|
9
|
+
:govtrack_id, :crp_id, :event_id, :congresspedia_url, :youtube_url,
|
10
|
+
:twitter_id, :fuzzy_score
|
11
|
+
|
11
12
|
# Takes in a hash where the keys are strings (the format passed in by the JSON parser)
|
12
13
|
#
|
13
14
|
def initialize(params)
|
@@ -15,9 +16,9 @@ module Sunlight
|
|
15
16
|
instance_variable_set("@#{key}", value) if Legislator.instance_methods.include? key
|
16
17
|
end
|
17
18
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
|
20
|
+
|
21
|
+
|
21
22
|
#
|
22
23
|
# Useful for getting the exact Legislators for a given district.
|
23
24
|
#
|
@@ -35,10 +36,10 @@ module Sunlight
|
|
35
36
|
# rep = officials[:representative]
|
36
37
|
#
|
37
38
|
# Legislator.all_for(:address => "123 Fifth Ave New York, NY 10003")
|
38
|
-
# Legislator.all_for(:address => "90210") #
|
39
|
+
# Legislator.all_for(:address => "90210") # it'll work, but use all_in_zip instead
|
39
40
|
#
|
40
41
|
def self.all_for(params)
|
41
|
-
|
42
|
+
|
42
43
|
if (params[:latitude] and params[:longitude])
|
43
44
|
Legislator.all_in_district(District.get(:latitude => params[:latitude], :longitude => params[:longitude]))
|
44
45
|
elsif (params[:address])
|
@@ -46,10 +47,10 @@ module Sunlight
|
|
46
47
|
else
|
47
48
|
nil # appropriate params not found
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
end
|
51
|
-
|
52
|
-
|
52
|
+
|
53
|
+
|
53
54
|
#
|
54
55
|
# A helper method for all_for. Use that instead, unless you
|
55
56
|
# already have the district object, then use this.
|
@@ -59,16 +60,16 @@ module Sunlight
|
|
59
60
|
# officials = Legislator.all_in_district(District.new("NJ", "7"))
|
60
61
|
#
|
61
62
|
def self.all_in_district(district)
|
62
|
-
|
63
|
+
|
63
64
|
senior_senator = Legislator.all_where(:state => district.state, :district => "Senior Seat").first
|
64
65
|
junior_senator = Legislator.all_where(:state => district.state, :district => "Junior Seat").first
|
65
66
|
representative = Legislator.all_where(:state => district.state, :district => district.number).first
|
66
|
-
|
67
|
+
|
67
68
|
{:senior_senator => senior_senator, :junior_senator => junior_senator, :representative => representative}
|
68
|
-
|
69
|
+
|
69
70
|
end
|
70
|
-
|
71
|
-
|
71
|
+
|
72
|
+
|
72
73
|
#
|
73
74
|
# A more general, open-ended search on Legislators than #all_for.
|
74
75
|
# See the Sunlight API for list of conditions and values:
|
@@ -86,26 +87,109 @@ module Sunlight
|
|
86
87
|
# dudes = Legislator.all_where(:gender => "M")
|
87
88
|
#
|
88
89
|
def self.all_where(params)
|
89
|
-
|
90
|
+
|
90
91
|
url = construct_url("legislators.getList", params)
|
91
|
-
|
92
|
+
|
92
93
|
if (result = get_json_data(url))
|
93
|
-
|
94
|
+
|
94
95
|
legislators = []
|
95
96
|
result["response"]["legislators"].each do |legislator|
|
96
97
|
legislators << Legislator.new(legislator["legislator"])
|
97
98
|
end
|
98
|
-
|
99
|
+
|
99
100
|
legislators
|
100
|
-
|
101
|
+
|
101
102
|
else
|
102
103
|
nil
|
103
104
|
end # if response.class
|
104
|
-
|
105
|
+
|
105
106
|
end
|
106
107
|
|
108
|
+
#
|
109
|
+
# When you only have a zipcode (and could not get address from the user), use this.
|
110
|
+
# It specifically accounts for the case where more than one Representative's district
|
111
|
+
# is in a zip code.
|
112
|
+
#
|
113
|
+
# If possible, ask for full address for proper geocoding via Legislator#all_for, which
|
114
|
+
# gives you a nice hash.
|
115
|
+
#
|
116
|
+
# Returns:
|
117
|
+
#
|
118
|
+
# An array of Legislator objects
|
119
|
+
#
|
120
|
+
# Usage:
|
121
|
+
#
|
122
|
+
# legislators = Legislator.all_in_zipcode(90210)
|
123
|
+
#
|
124
|
+
def self.all_in_zipcode(zipcode)
|
125
|
+
|
126
|
+
url = construct_url("legislators.allForZip", {:zip => zipcode})
|
127
|
+
|
128
|
+
if (result = get_json_data(url))
|
129
|
+
|
130
|
+
legislators = []
|
131
|
+
result["response"]["legislators"].each do |legislator|
|
132
|
+
legislators << Legislator.new(legislator["legislator"])
|
133
|
+
end
|
134
|
+
|
135
|
+
legislators
|
136
|
+
|
137
|
+
else
|
138
|
+
nil
|
139
|
+
end # if response.class
|
140
|
+
|
141
|
+
end # def self.all_in_zipcode
|
142
|
+
|
107
143
|
|
144
|
+
#
|
145
|
+
# Fuzzy name searching. Returns possible matching Legislators
|
146
|
+
# along with a confidence score. Confidence scores below 0.8
|
147
|
+
# mean the Legislator should not be used.
|
148
|
+
#
|
149
|
+
# The API documentation explains it best:
|
150
|
+
#
|
151
|
+
# http://wiki.sunlightlabs.com/index.php/Legislators.search
|
152
|
+
#
|
153
|
+
# Returns:
|
154
|
+
#
|
155
|
+
# An array of Legislators, with the fuzzy_score set as an attribute
|
156
|
+
#
|
157
|
+
# Usage:
|
158
|
+
#
|
159
|
+
# legislators = Legislator.search_by_name("Teddy Kennedey")
|
160
|
+
# legislators = Legislator.search_by_name("Johnny Kerry", 0.9)
|
161
|
+
#
|
162
|
+
def self.search_by_name(name, threshold='0.8')
|
163
|
+
|
164
|
+
url = construct_url("legislators.search", {:name => name, :threshold => threshold})
|
165
|
+
|
166
|
+
if (response = get_json_data(url))
|
167
|
+
|
168
|
+
legislators = []
|
169
|
+
response["response"]["results"].each do |result|
|
170
|
+
if result
|
171
|
+
legislator = Legislator.new(result["result"]["legislator"])
|
172
|
+
fuzzy_score = result["result"]["score"]
|
173
|
+
|
174
|
+
if threshold.to_f < fuzzy_score.to_f
|
175
|
+
legislator.fuzzy_score = fuzzy_score.to_f
|
176
|
+
legislators << legislator
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
if legislators.empty?
|
182
|
+
nil
|
183
|
+
else
|
184
|
+
legislators
|
185
|
+
end
|
186
|
+
|
187
|
+
else
|
188
|
+
nil
|
189
|
+
end
|
190
|
+
|
191
|
+
end # def self.search_by_name
|
108
192
|
|
109
193
|
end # class Legislator
|
110
194
|
|
111
|
-
end # module Sunlight
|
195
|
+
end # module Sunlight
|
data/sunlight.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "sunlight"
|
3
|
-
s.version = "0.
|
4
|
-
s.date = "
|
3
|
+
s.version = "0.2.0"
|
4
|
+
s.date = "2009-03-01"
|
5
5
|
s.summary = "Library for accessing the Sunlight Labs API."
|
6
6
|
s.email = "luigi.montanez@gmail.com"
|
7
7
|
s.homepage = "http://github.com/luigi/sunlight"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: luigi-sunlight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luigi Montanez
|
@@ -9,11 +9,12 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-03-01 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
@@ -23,6 +24,7 @@ dependencies:
|
|
23
24
|
version:
|
24
25
|
- !ruby/object:Gem::Dependency
|
25
26
|
name: ym4r
|
27
|
+
type: :runtime
|
26
28
|
version_requirement:
|
27
29
|
version_requirements: !ruby/object:Gem::Requirement
|
28
30
|
requirements:
|