Permalink
Browse files

Network, Search, Updates APIs

  • Loading branch information...
1 parent e743c1f commit ea547f7586d49065b0679a6bc0cd2128c6ff76fb Wynn Netherland committed Nov 26, 2009
View
@@ -15,6 +15,7 @@ begin
gem.add_dependency('oauth', '~> 0.3.5')
gem.add_dependency('roxml', '~> 3.1.3')
+ gem.add_dependency('crack', '~> 0.1.4')
gem.add_development_dependency('thoughtbot-shoulda', '>= 2.10.1')
gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
View
@@ -1,6 +1,16 @@
## Changelog
+
+### 0.1.0 - November 25, 2009
+
+* Network updates API support
+* Search API support
+* Updates API support
+
### 0.0.2 - November 25, 2009
+
* Swapped out Crack for ROXML for prettier object access
* Added more tests for Profile API
+
### 0.0.1 - November 24, 2009
+
* Initial release
View
@@ -51,6 +51,20 @@ def get(path, options={})
response.body
end
+ def put(path, options={})
+ path = "/v1#{path}"
+ response = access_token.put(path, options)
+ raise_errors(response)
+ response
+ end
+
+ def delete(path, options={})
+ path = "/v1#{path}"
+ response = access_token.delete(path, options)
+ raise_errors(response)
+ response
+ end
+
def profile(options={})
@@ -81,6 +95,42 @@ def connections(options={})
Connections.from_xml(get(path)).profiles
end
+ def search(options={})
+ path = "/people"
+ options = {:keywords => options} if options.is_a?(String)
+ options = format_options_for_query(options)
+
+ People.from_xml(get(to_uri(path, options)))
+ end
+
+ def current_status
+ path = "/people/~/current-status"
+ Crack::XML.parse(get(path))['current_status']
+ end
+
+ def update_status(text)
+ path = "/people/~/current-status"
+ put(path, status_to_xml(text))
+ end
+
+ def clear_status
+ path = "/people/~/current-status"
+ delete(path).code
+ end
+
+ def network_statuses(options={})
+ options[:type] = 'STAT'
+ network_updates(options)
+ end
+
+ def network_updates(options={})
+ path = "/people/~/network"
+ Network.from_xml(get(to_uri(path, options)))
+ end
+
+
+
+
# helpful in making authenticated calls and writing the
# raw xml to a fixture file
def write_fixture(path, filename)
@@ -100,15 +150,37 @@ def raise_errors(response)
raise Unavailable, "(#{response.code}): #{response.message}"
end
- if response.body.include?("<error>")
+ if response.body && response.body.include?("<error>")
error = LinkedIn::Error.from_xml(response.body)
- case error.status
- when 404
- Raise LinkedInError, "(#{error.status}): #{error.code} - #{error.message}"
- end
+ Raise LinkedInError, "(#{error.status}): #{error.code} - #{error.message}"
+ end
+ end
+
+ def format_options_for_query(opts)
+ opts.keys.each do |key|
+ value = opts.delete(key)
+ value = value.join("+") if value.is_a?(Array)
+ value = value.gsub(" ", "+") if value.is_a?(String)
+ opts[key.to_s.gsub("_","-")] = value
end
+ opts
+ end
+
+ def to_query(options)
+ options.inject([]) do |collection, opt|
+ collection << "#{opt[0]}=#{opt[1]}"
+ collection
+ end * '&'
end
+
+ def to_uri(path, options)
+ uri = URI.parse(path)
+ if options && options != {}
+ uri.query = to_query(options)
+ end
+ uri.to_s
+ end
def person_path(options)
path = "/people/"
@@ -123,6 +195,10 @@ def person_path(options)
end
end
+ def status_to_xml(status)
+ %Q{<?xml version="1.0" encoding="UTF-8"?>
+ <current-status>#{status}</current-status>}
+ end
end
View
@@ -0,0 +1,7 @@
+module LinkedIn
+ class Network
+ include ROXML
+ xml_convention {|val| val.gsub("_","-") }
+ xml_reader :updates, :as => [Update]
+ end
+end
View
@@ -0,0 +1,10 @@
+module LinkedIn
+ class People
+ include ROXML
+ xml_convention {|val| val.gsub("_","-") }
+ xml_reader :total, :as => Integer, :from => "@total"
+ xml_reader :start, :as => Integer, :from => "@start"
+ xml_reader :count, :as => Integer, :from => "@count"
+ xml_reader :profiles, :as => [Profile], :from => 'person'
+ end
+end
View
@@ -0,0 +1,11 @@
+module LinkedIn
+ class Update
+ include ROXML
+ xml_convention {|val| val.gsub("_","-") }
+ xml_reader :timestamp, :as => Integer
+ xml_reader :update_key
+ xml_reader :update_type
+ xml_reader :profile, :as => Profile, :from => 'update-content/person'
+ xml_reader :is_commentable?
+ end
+end
View
@@ -7,6 +7,9 @@
gem 'roxml', '~> 3.1.3'
require 'roxml'
+gem 'crack', '~> 0.1.4'
+require 'crack'
+
require 'cgi'
module LinkedIn
@@ -38,5 +41,8 @@ class NotFound < StandardError; end
require File.join(directory, 'linked_in', 'location')
require File.join(directory, 'linked_in', 'position')
require File.join(directory, 'linked_in', 'profile')
+require File.join(directory, 'linked_in', 'update')
+require File.join(directory, 'linked_in', 'network')
+require File.join(directory, 'linked_in', 'people')
require File.join(directory, 'linked_in', 'connections')
require File.join(directory, 'linked_in', 'client')
View
@@ -44,6 +44,61 @@ class ClientTest < Test::Unit::TestCase
cons.size.should == 146
cons.last.last_name.should == 'Yuchnewicz'
end
+
+ should "perform a search by keyword" do
+ stub_get("/v1/people?keywords=github", "search.xml")
+ results = @linkedin.search(:keywords => 'github')
+ results.start == 0
+ results.count == 10
+ results.profiles.first.first_name.should == 'Zach'
+ results.profiles.first.last_name.should == 'Inglis'
+ end
+
+ should "perform a search by multiple keywords" do
+ stub_get("/v1/people?keywords=ruby+rails", "search.xml")
+ results = @linkedin.search(:keywords => ["ruby", "rails"])
+ results.start == 0
+ results.count == 10
+ results.profiles.first.first_name.should == 'Zach'
+ results.profiles.first.last_name.should == 'Inglis'
+ end
+
+ should "perform a search by name" do
+ stub_get("/v1/people?name=Zach+Inglis", "search.xml")
+ results = @linkedin.search(:name => "Zach Inglis")
+ results.start == 0
+ results.count == 10
+ results.profiles.first.first_name.should == 'Zach'
+ results.profiles.first.last_name.should == 'Inglis'
+ end
+
+ should "update a user's current status" do
+ stub_put("/v1/people/~/current-status", "blank.xml")
+ @linkedin.update_status("Testing out the LinkedIn API")
+ end
+
+ should "clear a user's current status" do
+ stub_delete("/v1/people/~/current-status", "blank.xml")
+ @linkedin.clear_status
+ end
+
+ should "retrieve the authenticated user's current status" do
+ stub_get("/v1/people/~/current-status", "status.xml")
+ @linkedin.current_status.should == "New blog post: What makes a good API wrapper? http://wynnnetherland.com/2009/11/what-makes-a-good-api-wrapper/"
+ end
+
+ should "retrieve status updates for the authenticated user's network" do
+ stub_get("/v1/people/~/network?type=STAT", "network_statuses.xml")
+ stats = @linkedin.network_statuses
+ stats.updates.first.profile.first_name.should == 'Vahid'
+ end
+
+ should "retrieve network updates" do
+ stub_get("/v1/people/~/network?type=PICT", "picture_updates.xml")
+ stats = @linkedin.network_updates(:type => "PICT")
+ stats.updates.size.should == 4
+ stats.updates.last.profile.headline.should == "Creative Director for Intridea"
+ end
end
View
No changes.
Oops, something went wrong.

0 comments on commit ea547f7

Please sign in to comment.