linkedin2 0.0.16 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
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