linkedin2 0.0.16 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +2 -0
  4. data/.rspec +2 -2
  5. data/.travis.yml +1 -1
  6. data/README.md +3 -3
  7. data/Rakefile +1 -1
  8. data/lib/linkedin/api.rb +16 -0
  9. data/lib/linkedin/api/authentication.rb +5 -7
  10. data/lib/linkedin/api/companies.rb +16 -10
  11. data/lib/linkedin/api/invitation.rb +39 -0
  12. data/lib/linkedin/api/messaging.rb +24 -0
  13. data/lib/linkedin/api/network_updates.rb +5 -9
  14. data/lib/linkedin/api/people.rb +18 -0
  15. data/lib/linkedin/client.rb +34 -72
  16. data/lib/linkedin/configuration.rb +26 -11
  17. data/lib/linkedin/credentials.rb +27 -0
  18. data/lib/linkedin/errors.rb +45 -0
  19. data/lib/linkedin/faraday_middleware.rb +6 -4
  20. data/lib/linkedin/faraday_middleware/credentials_request.rb +31 -0
  21. data/lib/linkedin/faraday_middleware/{linkedin_error_response.rb → error_response.rb} +2 -10
  22. data/lib/linkedin/faraday_middleware/format_request.rb +17 -0
  23. data/lib/linkedin/faraday_middleware/user_agent_request.rb +10 -0
  24. data/lib/linkedin/fields.rb +58 -0
  25. data/lib/linkedin/industries.rb +199 -0
  26. data/lib/linkedin/response.rb +19 -0
  27. data/lib/linkedin/version.rb +1 -1
  28. data/lib/linkedin2.rb +11 -19
  29. data/linkedin.gemspec +16 -7
  30. data/spec/api/companies_spec.rb +8 -9
  31. data/spec/api/groups_spec.rb +3 -4
  32. data/spec/api/jobs_spec.rb +2 -3
  33. data/spec/api/network_updates_spec.rb +9 -15
  34. data/spec/api/{profiles_spec.rb → people_spec.rb} +11 -13
  35. data/spec/faraday_middleware/{linkedin_error_response_spec.rb → error_response_spec.rb} +8 -21
  36. data/spec/fixtures/requests/companies.yml +25 -15
  37. data/spec/fixtures/requests/invalid.yml +7 -7
  38. data/spec/fixtures/requests/network_updates.yml +12 -12
  39. data/spec/fixtures/requests/people.yml +380 -0
  40. data/spec/spec_helper.rb +18 -19
  41. data/spec/support/coverage.rb +14 -0
  42. data/spec/support/vcr.rb +9 -0
  43. data/spec/test_app.yml +3 -2
  44. metadata +119 -38
  45. data/lib/linkedin/api/industries.rb +0 -171
  46. data/lib/linkedin/api/permissions.rb +0 -42
  47. data/lib/linkedin/api/profiles.rb +0 -71
  48. data/lib/linkedin/error.rb +0 -29
  49. data/lib/linkedin/faraday_middleware/linkedin_format_request.rb +0 -26
  50. data/lib/linkedin/industry.rb +0 -33
  51. data/spec/fixtures/requests/profiles.yml +0 -201
@@ -0,0 +1,27 @@
1
+ module LinkedIn
2
+ class Credentials
3
+ extend Forwardable
4
+
5
+ def_delegators :client, :auth_code
6
+
7
+ def initialize(configuration)
8
+ @configuration = configuration
9
+ end
10
+
11
+ def type
12
+ :oauth2
13
+ end
14
+
15
+ def client
16
+ @client ||= OAuth2::Client.new @configuration.key, @configuration.secret, oauth2_options
17
+ end
18
+
19
+ private
20
+
21
+ def oauth2_options
22
+ { site: 'https://api.linkedin.com',
23
+ authorize_url: 'https://www.linkedin.com/uas/oauth2/authorization',
24
+ token_url: 'https://www.linkedin.com/uas/oauth2/accessToken' }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,45 @@
1
+ module LinkedIn
2
+ class Error < StandardError; end
3
+
4
+ class ServiceError < Error
5
+ attr_reader :source
6
+
7
+ def initialize(response = {})
8
+ @source = Hashie::Mash.new response
9
+ end
10
+
11
+ def message
12
+ return self.class.name if body.message.empty?
13
+ body.message
14
+ end
15
+
16
+ def status
17
+ response.status
18
+ end
19
+
20
+ def body
21
+ response.body
22
+ end
23
+
24
+ def request
25
+ @request ||= Hashie::Mash.new url: source.url, headers: source.request_headers, params: source.params
26
+ end
27
+
28
+ def response
29
+ @response ||= Hashie::Mash.new status: source.status, body: source.body, headers: source.response_headers
30
+ end
31
+ end
32
+
33
+ class BadRequest < ServiceError; end
34
+ class Unauthorized < ServiceError; end
35
+ class Forbidden < ServiceError; end
36
+ class NotFound < ServiceError; end
37
+ class InternalServerError < ServiceError; end
38
+
39
+ class CSRF < Error
40
+ def initialize(expected = nil, received = nil)
41
+ additional = "Excepted '#{expected}' but received '#{received}'" if expected
42
+ super "Response state did not match sent state. #{additional}."
43
+ end
44
+ end
45
+ end
@@ -1,11 +1,13 @@
1
1
  module LinkedIn
2
2
  module FaradayMiddleware
3
- require 'linkedin/faraday_middleware/linkedin_format_request'
4
- require 'linkedin/faraday_middleware/linkedin_error_response'
3
+ Dir[ File.expand_path('../faraday_middleware/**/*.rb', __FILE__) ].each { |f| require f }
5
4
 
6
5
  if Faraday::Middleware.respond_to? :register_middleware
7
- Faraday::Request.register_middleware linkedin_format: lambda { LinkedinFormatRequest }
8
- Faraday::Response.register_middleware linkedin_errors: lambda { LinkedinErrorResponse }
6
+ Faraday::Request.register_middleware linkedin_credentials: lambda { CredentialsRequest }
7
+ Faraday::Request.register_middleware linkedin_format: lambda { FormatRequest }
8
+ Faraday::Request.register_middleware linkedin_user_agent: lambda { UserAgentRequest }
9
+
10
+ Faraday::Response.register_middleware linkedin_errors: lambda { ErrorResponse }
9
11
  end
10
12
  end
11
13
  end
@@ -0,0 +1,31 @@
1
+ module LinkedIn
2
+ module FaradayMiddleware
3
+ class CredentialsRequest < Faraday::Middleware
4
+ PARAM_NAME = 'oauth2_access_token'.freeze
5
+
6
+ extend Forwardable
7
+ def_delegators :'Faraday::Utils', :parse_query, :build_query
8
+
9
+ def initialize(app, credentials)
10
+ super app
11
+ @credentials = credentials
12
+ end
13
+
14
+ def call(env)
15
+ params = query_params(env[:url]).reverse_merge PARAM_NAME => @credentials.access_token
16
+ token = params[PARAM_NAME]
17
+
18
+ env[:url].query = build_query params unless token.blank?
19
+
20
+ @app.call env
21
+ end
22
+
23
+ private
24
+
25
+ def query_params(url)
26
+ return {} if url.query.blank?
27
+ parse_query url.query
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,6 +1,6 @@
1
1
  module LinkedIn
2
2
  module FaradayMiddleware
3
- class LinkedinErrorResponse < Faraday::Response::Middleware
3
+ class ErrorResponse < Faraday::Response::Middleware
4
4
  ERRORS = {
5
5
  400 => BadRequest,
6
6
  401 => Unauthorized,
@@ -13,16 +13,8 @@ module LinkedIn
13
13
  status = env[:status].to_i
14
14
  error = ERRORS[status] || Error
15
15
 
16
- raise error.new response_values(env) if status >= 400
17
- end
18
-
19
- def response_values(env)
20
- {
21
- request: OpenStruct.new(headers: env[:request_headers], uri: env[:url]),
22
- response: env[:response]
23
- }
16
+ raise error.new Hashie::Mash.new(env) if status >= 400
24
17
  end
25
18
  end
26
19
  end
27
20
  end
28
-
@@ -0,0 +1,17 @@
1
+ module LinkedIn
2
+ module FaradayMiddleware
3
+ class FormatRequest < Faraday::Middleware
4
+ HEADER_NAME = 'X-Li-Format'.freeze
5
+
6
+ def initialize(app = nil, format = :json)
7
+ super app
8
+ @format = format
9
+ end
10
+
11
+ def call(env)
12
+ env[:request_headers].reverse_merge! HEADER_NAME => @format.to_s unless @format.blank?
13
+ @app.call env
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ module LinkedIn
2
+ module FaradayMiddleware
3
+ class UserAgentRequest < Faraday::Middleware
4
+ def call(env)
5
+ env[:request_headers].reverse_merge! 'User-Agent' => "LinkedIn2 Gem v#{ LinkedIn::VERSION }"
6
+ @app.call env
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,58 @@
1
+ module LinkedIn
2
+ module Fields
3
+ COMPANY_CONTACT_INFO = { 'contact-info' => [ 'phone1', 'phone2', 'fax' ]}
4
+ COMPANY_ADDRESS = { 'address' => [ 'street1', 'street2', 'city', 'state', 'postal-code', 'country-code', 'region-code' ]}
5
+ COMPANY_LOCATIONS = { 'locations' => ['description', 'is-headquarters', 'is-active', COMPANY_ADDRESS, COMPANY_CONTACT_INFO ] }
6
+ COMPANY = ['id', 'name', 'universal-name', 'email-domains', 'company-type', 'ticker', 'website-url',
7
+ 'industries', 'status', 'logo-url', 'square-logo-url', 'blog-rss-url', 'twitter-id',
8
+ 'employee-count-range', 'specialties', 'description', 'stock-exchange', 'founded-year', 'end-year', 'num-followers', COMPANY_LOCATIONS ]
9
+
10
+
11
+ PROFILE_COMPANY = { 'company' => [ 'id', 'name', 'type', 'size', 'industry', 'ticker' ] }
12
+ PROFILE_LOCATION = { 'location' => ['name', { 'country' => 'code' } ] }
13
+ PROFILE_POSITIONS = { 'positions' => [ 'id', 'title', 'summary', 'start-date', 'end-date', 'is-current', COMPANY ] }
14
+ PROFILE_API_STD_PROFILE_REQ = { 'api-standard-profile-request' => ['url', 'headers'] }
15
+
16
+ BASE_BASIC_PROFILE = [ 'id', 'first-name', 'last-name','maiden-name', 'formatted-name', 'phonetic-first-name',
17
+ 'phonetic-last-name', 'formatted-phonetic-name', 'headline', 'industry', 'distance',
18
+ 'current-share', 'num-connections', 'num-connections-capped', 'summary', 'specialties',
19
+ 'picture-url', 'site-standard-profile-request', 'public-profile-url',
20
+ PROFILE_LOCATION, PROFILE_POSITIONS, PROFILE_API_STD_PROFILE_REQ ]
21
+
22
+ PROFILE_RELATION_TO_VIEWER = { 'relation-to-viewer' => [ 'num-related-connections', 'related-connections' => BASE_BASIC_PROFILE ] }
23
+
24
+ PROFILE_MEMBER_URL_RESOURCES = { 'member-url-resources' => [ 'url', 'name' ] }
25
+ BASE_FULL_PROFILE = [ 'last-modified-timestamp', 'proposal-comments', 'associations', 'interests', 'publications',
26
+ 'patents', 'languages', 'skills', 'certifications', 'educations', 'courses', 'volunteer',
27
+ 'three-current-positions', 'three-past-positions', 'num-recommenders', 'recommendations-received',
28
+ 'mfeed-rss-url', 'following', 'job-bookmarks', 'suggestions', 'date-of-birth',
29
+ 'related-profile-views', 'honors-awards' ]
30
+
31
+ R_BASICPROFILE = BASE_BASIC_PROFILE + [ PROFILE_RELATION_TO_VIEWER ]
32
+ R_EMAILADDRESS = [ 'email-address' ]
33
+ R_FULLPROFILE = R_BASICPROFILE + BASE_FULL_PROFILE + [ PROFILE_MEMBER_URL_RESOURCES ]
34
+ R_CONTACTINFO = [ 'phone-numbers', 'bound-account-types', 'im-accounts', 'main-address', 'twitter-accounts', 'primary-twitter-account']
35
+ R_NETWORK = [ 'connections' ]
36
+ RW_GROUPS = [ 'group-memberships' ]
37
+ RW_NUS = [ 'network' ]
38
+ W_MESSAGES = []
39
+
40
+ def self.render(*fields)
41
+ fields.compact!
42
+ return '' if fields.blank?
43
+
44
+ srender nil => fields
45
+ end
46
+
47
+ private
48
+
49
+ def self.srender(*fields)
50
+ fields = fields.first if fields.size == 1
51
+
52
+ return srender(fields.map { |key, value| "#{key}:(#{srender value})" }) if fields.respond_to? :keys
53
+ return fields.map { |value| srender value }.join ',' if fields.respond_to? :each
54
+
55
+ fields.to_s
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,199 @@
1
+ module LinkedIn
2
+ module Industries
3
+ def self.all
4
+ LinkedIn::INDUSTRIES
5
+ end
6
+
7
+ def self.[](code)
8
+ find_by_code code
9
+ end
10
+
11
+ def self.find_by_code(code)
12
+ all.detect { |indust| indust[:code] == code }
13
+ end
14
+
15
+ def self.find_by_group(*groups)
16
+ all.reject { |indust| (groups & indust[:group]) != groups }
17
+ end
18
+
19
+ def self.find_by_description(description)
20
+ all.detect { |indust| normalize_description(indust[:description]) == normalize_description(description) }
21
+ end
22
+
23
+ def self.find_group_names(*groups)
24
+ Array[groups].flatten.map { |group| LinkedIn::GROUPS[group.to_sym] }
25
+ end
26
+
27
+ private
28
+
29
+ def self.normalize_description(description)
30
+ description.to_s.downcase.strip.gsub(' ','_').gsub(/[^\w]/, '').to_sym
31
+ end
32
+ end
33
+
34
+ INDUSTRIES = [ { code: 1, group: [:gov, :tech], description: 'Defense & Space' },
35
+ { code: 3, group: [:tech], description: 'Computer Hardware' },
36
+ { code: 4, group: [:tech], description: 'Computer Software' },
37
+ { code: 5, group: [:tech], description: 'Computer Networking' },
38
+ { code: 6, group: [:tech], description: 'Internet' },
39
+ { code: 7, group: [:tech], description: 'Semiconductors' },
40
+ { code: 8, group: [:gov, :tech], description: 'Telecommunications' },
41
+ { code: 9, group: [:leg], description: 'Law Practice' },
42
+ { code: 10, group: [:leg], description: 'Legal Services' },
43
+ { code: 11, group: [:corp], description: 'Management Consulting' },
44
+ { code: 12, group: [:gov, :hlth, :tech], description: 'Biotechnology' },
45
+ { code: 13, group: [:hlth], description: 'Medical Practice' },
46
+ { code: 14, group: [:hlth], description: 'Hospital & Health Care' },
47
+ { code: 15, group: [:hlth, :tech], description: 'Pharmaceuticals' },
48
+ { code: 16, group: [:hlth], description: 'Veterinary' },
49
+ { code: 17, group: [:hlth], description: 'Medical Devices' },
50
+ { code: 18, group: [:good], description: 'Cosmetics' },
51
+ { code: 19, group: [:good], description: 'Apparel & Fashion' },
52
+ { code: 20, group: [:good, :rec], description: 'Sporting Goods' },
53
+ { code: 21, group: [:good], description: 'Tobacco' },
54
+ { code: 22, group: [:good], description: 'Supermarkets' },
55
+ { code: 23, group: [:good, :man, :serv], description: 'Food Production' },
56
+ { code: 24, group: [:good, :man], description: 'Consumer Electronics' },
57
+ { code: 25, group: [:good, :man], description: 'Consumer Goods' },
58
+ { code: 26, group: [:good, :man], description: 'Furniture' },
59
+ { code: 27, group: [:good, :man], description: 'Retail' },
60
+ { code: 28, group: [:med, :rec], description: 'Entertainment' },
61
+ { code: 29, group: [:rec], description: 'Gambling & Casinos' },
62
+ { code: 30, group: [:rec, :serv, :tran], description: 'Leisure, Travel & Tourism' },
63
+ { code: 31, group: [:rec, :serv, :tran], description: 'Hospitality' },
64
+ { code: 32, group: [:rec, :serv], description: 'Restaurants' },
65
+ { code: 33, group: [:rec], description: 'Sports' },
66
+ { code: 34, group: [:rec, :serv], description: 'Food & Beverages' },
67
+ { code: 35, group: [:art, :med, :rec], description: 'Motion Pictures and Film' },
68
+ { code: 36, group: [:med, :rec], description: 'Broadcast Media' },
69
+ { code: 37, group: [:art, :med, :rec], description: 'Museums and Institutions' },
70
+ { code: 38, group: [:art, :med, :rec], description: 'Fine Art' },
71
+ { code: 39, group: [:art, :med, :rec], description: 'Performing Arts' },
72
+ { code: 40, group: [:rec, :serv], description: 'Recreational Facilities and Services' },
73
+ { code: 41, group: [:fin], description: 'Banking' },
74
+ { code: 42, group: [:fin], description: 'Insurance' },
75
+ { code: 43, group: [:fin], description: 'Financial Services' },
76
+ { code: 44, group: [:cons, :fin, :good], description: 'Real Estate' },
77
+ { code: 45, group: [:fin], description: 'Investment Banking' },
78
+ { code: 46, group: [:fin], description: 'Investment Management' },
79
+ { code: 47, group: [:corp, :fin], description: 'Accounting' },
80
+ { code: 48, group: [:cons], description: 'Construction' },
81
+ { code: 49, group: [:cons], description: 'Building Materials' },
82
+ { code: 50, group: [:cons], description: 'Architecture & Planning' },
83
+ { code: 51, group: [:cons, :gov], description: 'Civil Engineering' },
84
+ { code: 52, group: [:gov, :man], description: 'Aviation & Aerospace' },
85
+ { code: 53, group: [:man], description: 'Automotive' },
86
+ { code: 54, group: [:man], description: 'Chemicals' },
87
+ { code: 55, group: [:man], description: 'Machinery' },
88
+ { code: 56, group: [:man], description: 'Mining & Metals' },
89
+ { code: 57, group: [:man], description: 'Oil & Energy' },
90
+ { code: 58, group: [:man], description: 'Shipbuilding' },
91
+ { code: 59, group: [:man], description: 'Utilities' },
92
+ { code: 60, group: [:man], description: 'Textiles' },
93
+ { code: 61, group: [:man], description: 'Paper & Forest Products' },
94
+ { code: 62, group: [:man], description: 'Railroad Manufacture' },
95
+ { code: 63, group: [:agr], description: 'Farming' },
96
+ { code: 64, group: [:agr], description: 'Ranching' },
97
+ { code: 65, group: [:agr], description: 'Dairy' },
98
+ { code: 66, group: [:agr], description: 'Fishery' },
99
+ { code: 67, group: [:edu], description: 'Primary/Secondary Education' },
100
+ { code: 68, group: [:edu], description: 'Higher Education' },
101
+ { code: 69, group: [:edu], description: 'Education Management' },
102
+ { code: 70, group: [:edu, :gov], description: 'Research' },
103
+ { code: 71, group: [:gov], description: 'Military' },
104
+ { code: 72, group: [:gov, :leg], description: 'Legislative Office' },
105
+ { code: 73, group: [:gov, :leg], description: 'Judiciary' },
106
+ { code: 74, group: [:gov], description: 'International Affairs' },
107
+ { code: 75, group: [:gov], description: 'Government Administration' },
108
+ { code: 76, group: [:gov], description: 'Executive Office' },
109
+ { code: 77, group: [:gov, :leg], description: 'Law Enforcement' },
110
+ { code: 78, group: [:gov], description: 'Public Safety' },
111
+ { code: 79, group: [:gov], description: 'Public Policy' },
112
+ { code: 80, group: [:corp, :med], description: 'Marketing and Advertising' },
113
+ { code: 81, group: [:med, :rec], description: 'Newspapers' },
114
+ { code: 82, group: [:med, :rec], description: 'Publishing' },
115
+ { code: 83, group: [:med, :rec], description: 'Printing' },
116
+ { code: 84, group: [:med, :serv], description: 'Information Services' },
117
+ { code: 85, group: [:med, :rec, :serv], description: 'Libraries' },
118
+ { code: 86, group: [:org, :serv], description: 'Environmental Services' },
119
+ { code: 87, group: [:serv, :tran], description: 'Package/Freight Delivery' },
120
+ { code: 88, group: [:org, :serv], description: 'Individual & Family Services' },
121
+ { code: 89, group: [:org, :serv], description: 'Religious Institutions' },
122
+ { code: 90, group: [:org, :serv], description: 'Civic & Social Organization' },
123
+ { code: 91, group: [:org, :serv], description: 'Consumer Services' },
124
+ { code: 92, group: [:tran], description: 'Transportation/Trucking/Railroad' },
125
+ { code: 93, group: [:tran], description: 'Warehousing' },
126
+ { code: 94, group: [:man, :tech, :tran], description: 'Airlines/Aviation' },
127
+ { code: 95, group: [:tran], description: 'Maritime' },
128
+ { code: 96, group: [:tech], description: 'Information Technology and Services' },
129
+ { code: 97, group: [:corp], description: 'Market Research' },
130
+ { code: 98, group: [:corp], description: 'Public Relations and Communications' },
131
+ { code: 99, group: [:art, :med], description: 'Design' },
132
+ { code: 100, group: [:org], description: 'Nonprofit Organization Management' },
133
+ { code: 101, group: [:org], description: 'Fund-Raising' },
134
+ { code: 102, group: [:corp, :org], description: 'Program Development' },
135
+ { code: 103, group: [:art, :med, :rec], description: 'Writing and Editing' },
136
+ { code: 104, group: [:corp], description: 'Staffing and Recruiting' },
137
+ { code: 105, group: [:corp], description: 'Professional Training & Coaching' },
138
+ { code: 106, group: [:fin, :tech], description: 'Venture Capital & Private Equity' },
139
+ { code: 107, group: [:gov, :org], description: 'Political Organization' },
140
+ { code: 108, group: [:corp, :gov, :serv], description: 'Translation and Localization' },
141
+ { code: 109, group: [:med, :rec], description: 'Computer Games' },
142
+ { code: 110, group: [:corp, :rec, :serv], description: 'Events Services' },
143
+ { code: 111, group: [:art, :med, :rec], description: 'Arts and Crafts' },
144
+ { code: 112, group: [:good, :man], description: 'Electrical/Electronic Manufacturing' },
145
+ { code: 113, group: [:med], description: 'Online Media' },
146
+ { code: 114, group: [:gov, :man, :tech], description: 'Nanotechnology' },
147
+ { code: 115, group: [:art, :rec], description: 'Music' },
148
+ { code: 116, group: [:corp, :tran], description: 'Logistics and Supply Chain' },
149
+ { code: 117, group: [:man], description: 'Plastics' },
150
+ { code: 118, group: [:tech], description: 'Computer & Network Security' },
151
+ { code: 119, group: [:tech], description: 'Wireless' },
152
+ { code: 120, group: [:leg, :org], description: 'Alternative Dispute Resolution' },
153
+ { code: 121, group: [:corp, :org, :serv], description: 'Security and Investigations' },
154
+ { code: 122, group: [:corp, :serv], description: 'Facilities Services' },
155
+ { code: 123, group: [:corp], description: 'Outsourcing/Offshoring' },
156
+ { code: 124, group: [:hlth, :rec], description: 'Health, Wellness and Fitness' },
157
+ { code: 125, group: [:hlth], description: 'Alternative Medicine' },
158
+ { code: 126, group: [:med, :rec], description: 'Media Production' },
159
+ { code: 127, group: [:art, :med], description: 'Animation' },
160
+ { code: 128, group: [:cons, :corp, :fin], description: 'Commercial Real Estate' },
161
+ { code: 129, group: [:fin], description: 'Capital Markets' },
162
+ { code: 130, group: [:gov, :org], description: 'Think Tanks' },
163
+ { code: 131, group: [:org], description: 'Philanthropy' },
164
+ { code: 132, group: [:edu, :org], description: 'E-Learning' },
165
+ { code: 133, group: [:good], description: 'Wholesale' },
166
+ { code: 134, group: [:corp, :good, :tran], description: 'Import and Export' },
167
+ { code: 135, group: [:cons, :gov, :man], description: 'Mechanical or Industrial Engineering' },
168
+ { code: 136, group: [:art, :med, :rec], description: 'Photography' },
169
+ { code: 137, group: [:corp], description: 'Human Resources' },
170
+ { code: 138, group: [:corp, :man], description: 'Business Supplies and Equipment' },
171
+ { code: 139, group: [:hlth], description: 'Mental Health Care' },
172
+ { code: 140, group: [:art, :med], description: 'Graphic Design' },
173
+ { code: 141, group: [:gov, :org, :tran], description: 'International Trade and Development' },
174
+ { code: 142, group: [:good, :man, :rec], description: 'Wine and Spirits' },
175
+ { code: 143, group: [:good], description: 'Luxury Goods & Jewelry' },
176
+ { code: 144, group: [:gov, :man, :org], description: 'Renewables & Environment' },
177
+ { code: 145, group: [:cons, :man], description: 'Glass, Ceramics & Concrete' },
178
+ { code: 146, group: [:good, :man], description: 'Packaging and Containers' },
179
+ { code: 147, group: [:cons, :man], description: 'Industrial Automation' },
180
+ { code: 148, group: [:gov], description: 'Government Relations' } ]
181
+
182
+ GROUPS = { agr: 'Agriculture',
183
+ art: 'Art & Design',
184
+ cons: 'Real Estate & Construction',
185
+ corp: 'Business & Operations',
186
+ edu: 'Education',
187
+ fin: 'Financial Services',
188
+ good: 'Consumer Goods',
189
+ gov: 'Government',
190
+ hlth: 'Health Care',
191
+ leg: 'Legal',
192
+ man: 'Basic Industries',
193
+ med: 'Media & Entertainment',
194
+ org: 'Charitable & Civic Organizations',
195
+ rec: 'Leisure & Recreation',
196
+ serv: 'Business Services',
197
+ tech: 'Technology',
198
+ tran: 'Transportation & Logistics' }
199
+ end
@@ -0,0 +1,19 @@
1
+ module LinkedIn
2
+ class Response < Hashie::Mash
3
+ attr_reader :_response
4
+
5
+ def initialize(response)
6
+ super response.body
7
+ @_response = response
8
+ end
9
+
10
+ def method_missing(method, *args, &block)
11
+ case method.to_s
12
+ when /^_(.+)/
13
+ _response.send $1.to_sym, *args, &block
14
+ else
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end