Major changes since the first release 0.1.0 :
- the support of OAuth is fixed (see below, an example with LinkedIn API)
- a new middleware handles the Amazon Web Service authentication
The homepage is at http://fperrad.github.com/lua-Spore,
and the sources are hosted at http://github.com/fperrad/lua-Spore.
All feedback welcome. Thanks.
François.
=====8<===============8<=====
local url = require 'socket.url'
local Spore = require 'Spore'
--Spore.debug = io.stdout -- show URL & Headers
local function get_linkedin_keys (keys)
    local oauth = require 'Spore'.new_from_spec
'https://raw.github.com/SPORE/api-description/master/services/linkedin/oauth.json'
    oauth:enable('Auth.OAuth', keys)
    local r1 = oauth:get_request_token()
    print("request", r1.body)
    for k, v in r1.body:gmatch'([^&=]+)=([^&=]*)&?' do keys[k] =
url.unescape(v) end
    local r2 = oauth:authorize_token{ oauth_token = keys.oauth_token }
    print("authorize", r2.status, r2.headers.location)
    os.execute("x-www-browser " .. r2.headers.location) -- on linux
--    os.execute("start " .. r2.headers.location) -- on Windows
    print "enter oauth_verifier (security code):"
    local input = io.stdin:read('*l')
    print("oauth_verifier=]" .. input .. "[")
    keys.oauth_verifier = input
    local r3 = oauth:get_access_token()
    print("access", r3.body)
    for k, v in r3.body:gmatch'([^&=]+)=([^&=]*)&?' do keys[k] =
url.unescape(v) end
    keys.oauth_callback_confirmed = nil
    keys.oauth_verifier = nil
    keys.oauth_expires_in = nil
    keys.oauth_authorization_expires_in = nil
    keys.xoauth_request_auth_url = nil
    return keys, oauth
end
local client = Spore.new_from_spec
'https://raw.github.com/SPORE/api-description/master/services/linkedin/people.json'
client:enable 'Format.JSON'
client:enable('Parameter.Default', {
    selector = '',
    format = 'json',
})
local keys, oauth = get_linkedin_keys{
    oauth_consumer_key    = 'YOUR_API_KEY',
    oauth_consumer_secret = 'YOUR_SECRET_KEY',
}
client:enable('Auth.OAuth', keys)
-- People
local res = client:my_profile{ selector = ':(id)' }
print(res.status)               --> 200
print(res.body.id)
local res = client:profile_by_id{ id = res.body.id, selector =
':(first-name,last-name)', lang = 'fr-FR' }
print(res.status)               --> 200
print(res.body.firstName)
print(res.body.lastName)
local res = client:profile_by_id{ id = 'unknown' }
print(res.status)               --> 404
local res = client:my_connections()
print(res.status)               --> 200
print(res.body._total)
for _, v in ipairs(res.body.values) do
    print(v.id, v.lastName, v.firstName, v.siteStandardProfileRequest.url)
end
local res = client:search_people{ keywords = 'ReST' }
print(res.status)               --> 200
print(res.body.numResults)
for _, v in ipairs(res.body.people.values) do
    print(v.id, v.lastName, v.firstName)
end
local r4 = oauth:invalidate_token()
print(r4.status)               --> 200
local base = 'https://raw.github.com/SPORE/api-description/master/services/linkedin/'
local client = Spore.new_from_spec(base .. 'jobs.json', base .. 'network.json')
client:enable 'Format.XML'
client:enable('Auth.OAuth', get_linkedin_keys{
    oauth_consumer_key    = 'YOUR_API_KEY',
    oauth_consumer_secret = 'YOUR_SECRET_KEY',
})
-- Jobs
local res = client:bookmark_job{ payload = { ['job-bookmark'] = { job
= { id = { 1725262 } } } } }  -- POST
print(res.status)               --> 201
local res = client:my_bookmarked_jobs{ selector = '' }  -- GET
print(res.status)               --> 200
print(res.body['job-bookmarks'].total)
local res = client:unbookmark_job{ id = 1725262 }  -- DELETE
print(res.status)               --> 204
print(res.body)
-- Network
local payload = {
    activity = {
        locale = 'en_US',
        ['content-type'] = { 'linkedin-html' },
        body = { [[sent with <a
href="http://fperrad.github.com/lua-Spore/">lua-Spore (v0.1.2)</a>]]
},
    }
}
local res = client:post_update{ payload = payload }  -- POST
print(res.status)               --> 201
> Major changes since the first release 0.1.0 :
> - the support of OAuth is fixed (see below, an example with LinkedIn 
> API)
> - a new middleware handles the Amazon Web Service authentication
Hello François and the rest of the group.
I've been wanting to write a SPORE specification for Moodstocks API for 
a while, but it would be currently useless since we use HTTP Digest 
authentication. Do you think there is a clean way to implement it in 
lua-Spore?
I know vanilla luasocket doesn't support it, but maybe cURL could be 
used instead?
The difficulty with Digest Auth is that it is a two requests process 
(the server MUST answer 401 to the first request). Also, efficient 
implementations of Digest Auth are stateful (they keep the server nonce 
and a counter per connection). I have no idea how a stateful middleware 
could be implemented in lua-Spore, is there an example of such a 
middleware?
Thanks for this great library anyway,
-- 
Pierre 'catwell' Chapuis
I write the both versions (stateless & statefull). see
https://gist.github.com/1063624
In fact, with Spore, things become simple.
(note: the statefull needs a fix that I just pushed in master)
François
> I write the both versions (stateless & statefull). see
> https://gist.github.com/1063624
> In fact, with Spore, things become simple.
>
> (note: the statefull needs a fix that I just pushed in master)
Wow, this is cool. Thanks for the responsiveness!
I will try it with the other services and write a full Spore
spec ASAP.
-- 
Pierre 'catwell' Chapuis
lua-Spore 0.1.3 is released (with Auth.Digest).
François
> --
> Pierre 'catwell' Chapuis
>
>