atomPub, ruby y la api de 11870 - Presentation Transcript
Atom Publishing
Protocol, ruby y la
api de 11870.com
David Calavera
antecedentes
11870.com
๏ recuerda y comparte negocios ...
David Calavera Conferencia Rails 2007
11870.com
• recuerda y comparte negocios ...
๏ no solo de comentarios vive el hombre
David Calavera Conferencia Rails 2007
11870.com
• recuerda y comparte negocios ...
• no solo de comentarios vive el hombre
๏ ¿por qué tengo que atarme a la web?
David Calavera Conferencia Rails 2007
11870.com
• recuerda y comparte negocios ...
• no solo de comentarios vive el hombre
• ¿por qué tengo que atarme a la web?
๏ ¿quien tiene que adaptarse?
David Calavera Conferencia Rails 2007
atomPub
“the atom publishing protocol is an
application-level protocol for
publishing and editing web resources”
David Calavera Conferencia Rails 2007
๏ ¿sabes qué es HTTP y como usarlo?
David Calavera Conferencia Rails 2007
• ¿sabes qué es HTTP y como usarlo?
๏ ¿sabes qué es XML y como usarlo?
David Calavera Conferencia Rails 2007
• ¿sabes qué es HTTP y como usarlo?
• ¿sabes qué es XML y como usarlo?
๏ ¿sabes qué es un feed y como crearlo?
David Calavera Conferencia Rails 2007
atomPub
características
estándar
http://ietfreport.isoc.org/idref/rfc5023
David Calavera Conferencia Rails 2007
más...
• paginación
๏ caché
David Calavera Conferencia Rails 2007
POST /wp-app.php/posts
HTTP/1.1 201 Created
Content-Type: application/atom+xml;type=entry;charset=\"utf-8\"
ETag: \"c180de84f991g8\"
David Calavera Conferencia Rails 2007
POST /wp-app.php/posts
HTTP/1.1 201 Created
Content-Type: application/atom+xml;type=entry;charset=\"utf-8\"
ETag: \"c180de84f991g8\"
GET /wp-app.php/post/3
HTTP/1.1 304 Not Modified
If-None-Match: \"c180de84f991g8\"
David Calavera Conferencia Rails 2007
POST /wp-app.php/posts
HTTP/1.1 201 Created
Content-Type: application/atom+xml;type=entry;charset=\"utf-8\"
ETag: \"c180de84f991g8\"
GET /wp-app.php/post/3
HTTP/1.1 304 Not Modified
If-None-Match: \"c180de84f991g8\"
PUT /wp-app.php/post/3
HTTP/1.1 412 Precondition Failed
If-Match: \"c180de84f991g8\"
David Calavera Conferencia Rails 2007
más...
• paginación
• caché
๏ control de estado
David Calavera Conferencia Rails 2007
atomPub:collection
POST 'http://www.verbosemode.com/wp-app.php/posts'
HTTP/1.1 201 Created
Content-Type: */*
Location: 'http://www.verbosemode.com/wp-app.php/post/3'
Content-Location: 'http://www.verbosemode.com/wp-app.php/post/3'
GET 'http://www.verbosemode.com/wp-app.php/posts'
HTTP/1.1 200 OK
David Calavera Conferencia Rails 2007
atomPub:entry
PUT 'http://www.verbosemode.com/wp-app.php/post/3'
HTTP/1.1 204 No Content
Content-Type: application/atom+xml;type=entry
DELETE 'http://www.verbosemode.com/wp-app.php/post/3'
HTTP/1.1 200 OK
GET 'http://www.verbosemode.com/wp-app.php/post/3'
HTTP/1.1 200 OK
David Calavera Conferencia Rails 2007
atomPub:entry
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<entry xmlns=\"http://www.w3.org/2005/Atom\"
xmlns:app=\"http://www.w3.org/2007/app\" xml:lang=\"en\">
<id>http://www.verbosemode.com/?p=3</id>
<title type=\"text\">Spanish Rails Conf 07</title>
<updated>2007-11-04T15:43:49Z</updated>
<published>2007-11-04T11:38:28Z</published>
<app:edited>2007-11-04T15:43:49Z</app:edited>
<app:control><app:draft>no</app:draft></app:control>
<author><name>david</name></author>
<content type=\"xhtml\"><div xmlns='http://www.w3.org/1999/xhtml'>
Next November 22 and 23 I'm going to attend to ...</div></content>
<link rel=\"edit\" href=\"http://www.verbosemode.com/wp-app.php/post/3\" />
<category scheme=\"http://www.verbosemode.com\" term=\"atomPub\" />
<category scheme=\"http://www.verbosemode.com\" term=\"rails\" />
<summary type=\"text\">Next November 22 and 23 I’m ...</summary>
</entry>
David Calavera Conferencia Rails 2007
atomPub:entry
¿y... qué pasa con los otros tipos de recursos?
<entry xmlns=\"http://www.w3.org/2005/Atom\"
xmlns:app=\"http://www.w3.org/2007/app\" xml:lang=\"en\">
<id>http://www.verbosemode.com/wp-content/uploads/2007/11/avatar.png</id>
<title type=\"text\">avatar poster</title>
<updated>2007-11-13T21:59:55Z</updated>
<published>2007-11-13T21:59:55Z</published>
<app:edited>2007-11-13T21:59:55Z</app:edited>
<app:control><app:draft>no</app:draft></app:control>
<author><name>david</name></author>
<link rel=\"edit-media\"
href=\"http://www.verbosemode.com/wp-app.php/attachment/file/4\" />
<link rel=\"edit\" href=\"http://www.verbosemode.com/wp-app.php/post/4\" />
<content type=\"image/png\"
src=\"http://www.verbosemode.com/wp-content/uploads/2007/11/avatar.png\"/>
</entry>
David Calavera Conferencia Rails 2007
atomPub:entry
¿y... qué pasa con los otros tipos de recursos?
PUT 'http://www.verbosemode.com/wp-app.php/attachment/file/4'
HTTP/1.1 204 No Content
Content-Type: */*
DELETE 'http://www.verbosemode.com/wp-app.php/attachment/file/4'
HTTP/1.1 200 OK
GET 'http://www.verbosemode.com/wp-app.php/attachment/file/4'
HTTP/1.1 200 OK
David Calavera Conferencia Rails 2007
atomPub
¿pero... hay gente que usa esto?
๏ google: gdata, youtube, openSocial
David Calavera Conferencia Rails 2007
• google: gdata, youtube, openSocial
๏ microsoft: windows live writer
David Calavera Conferencia Rails 2007
• google: gdata, youtube, openSocial
• microsoft: windows live writer
๏ ibm: lotus connections
David Calavera Conferencia Rails 2007
• google: gdata, youtube, openSocial
• microsoft: windows live writer
• ibm: lotus connections
๏ wordpress
David Calavera Conferencia Rails 2007
• google: gdata, youtube, openSocial
• microsoft: windows live writer
• ibm: lotus connections
• wordpress
๏ nokia: liveblog
David Calavera Conferencia Rails 2007
• google: gdata, youtube, openSocial
• microsoft: windows live writer
• ibm: lotus connections
• wordpress
• nokia: liveblog
๏ six apart: typepad, movable type
David Calavera Conferencia Rails 2007
• google: gdata, youtube, openSocial
• microsoft: windows live writer
• ibm: lotus connections
• wordpress
• nokia: liveblog
• six apart: typepad, movable type
๏ 11870.com
ruby
sin más
Net::HTTP
David Calavera Conferencia Rails 2007
Net::HTTP
๏ fácil de mantener
David Calavera Conferencia Rails 2007
Net::HTTP
• fácil de mantener
๏ respuesta condicionada al estado
David Calavera Conferencia Rails 2007
los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
end
David Calavera Conferencia Rails 2007
los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
end
David Calavera Conferencia Rails 2007
los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
#GET
http.request Net::HTTP::Get.new(@uri.path)
end
David Calavera Conferencia Rails 2007
los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
#GET
http.request Net::HTTP::Get.new(@uri.path)
#PUT
http.request Net::HTTP::Put.new(@uri.path), data
end
David Calavera Conferencia Rails 2007
los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
#GET
http.request Net::HTTP::Get.new(@uri.path)
#PUT
http.request Net::HTTP::Put.new(@uri.path), data
#DELETE
http.request Net::HTTP::Delete.new(@uri.path)
end
David Calavera Conferencia Rails 2007
REXML
๏ parser completo
David Calavera Conferencia Rails 2007
REXML
• parser completo
๏ escrito completamente en ruby
David Calavera Conferencia Rails 2007
REXML
• parser completo
• escrito completamente en ruby
๏ pasa los test de aceptación de Oasis
David Calavera Conferencia Rails 2007
REXML
• parser completo
• escrito completamente en ruby
• pasa los test de aceptación de Oasis
๏ soporta XPath
David Calavera Conferencia Rails 2007
REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
Builder
๏ crea xml fácilmente
David Calavera Conferencia Rails 2007
require 'builder'
builder = Builder::XmlMarkup.new
xml = builder.feed( 'xmlns' => 'http://www.w3.org/2005/Atom' ) do |feed|
feed.id 'http://conferenciarails.org/atomPub'
feed.updated Time.now
feed.author do |author| author.name 'David Calavera' end
feed.entry do |entry|
entry.title 'entrada para la conferencia rails'
end
end
David Calavera Conferencia Rails 2007
Builder
• crea xml fácilmente
๏ no solo se usa con rails
David Calavera Conferencia Rails 2007
๏ in the beginning... was the command line
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
David Calavera Conferencia Rails 2007
• in the beginning... was the command line
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
๏ vamos de camping
Camping.goes :Atom
module Atom::Views
def index
html do
head do
title 'Atom Publishing Protocol @ conferecia rails'
end
body do ... end
end
end
David Calavera Conferencia Rails 2007
ruby
extras
atom-tools
http://code.necronomicorp.com/atom-tools
๏ parsea y manipula feeds
David Calavera Conferencia Rails 2007
atom-tools
http://code.necronomicorp.com/atom-tools
• parsea y manipula feeds
๏ adaptado al rfc 5023
David Calavera Conferencia Rails 2007
atom-tools
http://code.necronomicorp.com/atom-tools
• parsea y manipula feeds
• adaptado al rfc 5023
๏ abstracción de http y xml
David Calavera Conferencia Rails 2007
require 'atom-tools'
http = Atom::HTTP.new
http.user = 'david'
http.pass = 'my password'
http.always_auth :basic
service = Atom::Service.new
'http://verbosemode.com/wp-app.php/service', http
service.collections.each do |collection|
puts collection.accepts
end
David Calavera Conferencia Rails 2007
require 'atom-tools'
http = Atom::HTTP.new
http.user = 'david'
http.pass = 'my password'
http.always_auth :basic
service = Atom::Service.new
'http://verbosemode.com/wp-app.php/service', http
service.collections.each do |collection|
puts collection.accepts
end
David Calavera Conferencia Rails 2007
require 'atom-tools'
http = Atom::HTTP.new
http.user = 'david'
http.pass = 'my password'
http.always_auth :basic
service = Atom::Service.new
'http://verbosemode.com/wp-app.php/service', http
service.collections.each do |collection|
puts collection.accepts
end
David Calavera Conferencia Rails 2007
atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
๏ rails es REST
David Calavera Conferencia Rails 2007
atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
• rails es REST
๏ mejor soporte para atom y atomPub
David Calavera Conferencia Rails 2007
atom_feed do |feed|
feed.title(\"My great blog!\")
feed.updated((@posts.first.created_at))
for post in @posts
feed.entry(post) do |entry|
entry.tag!('georss:where',
'xmlns:georss' => 'http://www.georss.org/georss/10') do |where|
where.tag!('gml:Poing',
'xmlns:gml' => 'http://www.opengis.net/gml') do |point|
point.tag!('gml:pos', nil, '40.419967 -3.698965')
end
end
David Calavera Conferencia Rails 2007
atom_feed({'xmlns:georss' => 'http://www.georss.org/georss/10',
'xmlns:gml' => 'http://www.opengis.net/gml'}) do |feed|
feed.title(\"My great blog!\")
feed.updated((@posts.first.created_at))
for post in @posts
feed.entry(post) do |entry|
entry.georss:where do |where|
where.gml:Point do |point|
point.tag!('gml:pos', '40.419967 -3.698965')
end
end
David Calavera Conferencia Rails 2007
atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
• rails es REST
• mejor soporte para atom y atomPub
๏ acts_as_collection
David Calavera Conferencia Rails 2007
atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
• rails es REST
• mejor soporte para atom y atomPub
• acts_as_collection
๏ acts_as_service_document
David Calavera Conferencia Rails 2007
class ServicesController < ApplicationController
acts_as_service_document
def index
render :xml => service_document
end
end
David Calavera Conferencia Rails 2007
the ape
http://www.tbray.org/ape
๏ the atom publishing exerciser
the ape
http://www.tbray.org/ape
• the atom publishing exerciser
๏ introspección!!!
David Calavera Conferencia Rails 2007
David Calavera Conferencia Rails 2007
the ape
http://www.tbray.org/ape
• the atom publishing exerciser
• introspección!!!
๏ varios sistemas de autenticación
David Calavera Conferencia Rails 2007
David Calavera Conferencia Rails 2007
the ape
http://www.tbray.org/ape
• the atom publishing exerciser
• introspección!!!
• varios sistemas de autenticación
๏ no es muy fácil de instalar (de momento)
David Calavera Conferencia Rails 2007
the ape
http://www.tbray.org/ape
• the atom publishing exerciser
• introspección!!!
• varios sistemas de autenticación
• no es muy fácil de instalar (de momento)
๏ no es muy fácil de configurar (de momento)
David Calavera Conferencia Rails 2007
la api de 11870.com
http://11870.com/api
por partes
๏ api de búsqueda
➡ formato openSearch (http://opensearch.org)
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
๏ autenticación
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
๏ autenticación
➡ identificar aplicaciones
David Calavera Conferencia Rails 2007
Net::HTTP.start( '11870.com' ) do |http|
req = Net::HTTP::Get.new('/api/v1')
req['appToken'] = 'el app token que 11870 te ha asignado'
digest = Digest::MD5.hexdigest(\"#{req['appToken']}#{la clave secreta}\")
req['authSign'] = digest
http.request req
end
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
๏ autenticación
➡ identificar aplicaciones
➡ autenticar usuarios
David Calavera Conferencia Rails 2007
request['Authorization'] = 'WSSE profile=\"UsernameToken\"'
request['X-WSSE'] = wsse!
def wsse!
nonce = Array.new(10){ rand(0x1000000) }.pack('I*')
nonce_b64 = [nonce].pack(\"m\").chomp
now = Time.now.gmtime.strftime(\"%FT%TZ\")
digest = [Digest::SHA1.digest(nonce_b64 + now + @password)].pack(\"m\").chomp
%Q<UsernameToken Username=\"#{@username}\",
PasswordDigest=\"#{digest}\", Nonce=\"#{nonce_b64}\", Created=\"#{now}\">
end
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
๏ autenticación
➡ identificar aplicaciones
➡ autenticar usuarios
➡ evolucionará a OAuth (http://oauth.net)
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
• autenticación
๏ múltiples representaciones
David Calavera Conferencia Rails 2007
{
\"id\":\"/api/v1/sites/calavera\",
\"title\":\"Sites\",
\"updated\":\"2007-09-28T07:53:46.000Z\",
\"authors\":[{
\"name\":\"calavera\"
}
],
\"links\":[{
\"href\":\"http://11870.com/api/v1/sites/calavera\",
\"rel\":\"self\"
},{
\"href\":\"http://11870.com/api/v1/sites/calavera?page=2\",
\"rel\":\"next\"
}
],
\"entries\":[{
\"lang\":\"es\",
\"id\":\"http://11870.com/pro/23474/calavera\",
\"title\":\"Apple Store Fifth Avenue\",
\"summary\":\"en directo\",
\"content\":\"estoy ahora mismo en esta...
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
• autenticación
• múltiples representaciones
๏ control de versiones
David Calavera Conferencia Rails 2007
๏ ahora
Net::HTTP.start( '11870.com' ) do |http|
http.request Net::HTTP::Get.new('/api/v1')
end
David Calavera Conferencia Rails 2007
• ahora
Net::HTTP.start( '11870.com' ) do |http|
http.request Net::HTTP::Get.new('/api/v1')
end
๏ en un futuro
Net::HTTP.start( '11870.com' ) do |http|
http.request Net::HTTP::Get.new('/api/v1.5')
end
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
• autenticación
• múltiples representaciones
• control de versiones
๏ soporte de librerías
David Calavera Conferencia Rails 2007
http://code.google.com/p/api-11870/
David Calavera Conferencia Rails 2007
más allá de atomPub
• sintaxis
• autenticación
• múltiples representaciones
• control de versiones
• soporte de librerías
๏ ¡documentación!
David Calavera Conferencia Rails 2007
http://groups.google.com/group/api-11870
David Calavera Conferencia Rails 2007
la api de 11870.com
oos4ruby
búsqueda
require 'oos4ruby'
oos = Oos.new
oos.auth_app 'appToken', 'secretKey'
oos.search q => 'apple store in new york'
oos.search bbox => ['SOUTH', 'WEST', 'NORTH', 'EAST']
oos.search lat => 'LATITUDE', lon => 'LONGITUDE', radius => '3000 METRES'
oos.search tags => ['restaurant', 'cheap', 'clean']
David Calavera Conferencia Rails 2007
búsqueda
require 'oos4ruby'
oos = Oos.new
oos.auth_app 'appToken', 'secretKey'
oos.search q => 'apple store in new york'
oos.search bbox => ['SOUTH', 'WEST', 'NORTH', 'EAST']
oos.search lat => 'LATITUDE', lon => 'LONGITUDE', radius => '3000 METRES'
oos.search tags => ['restaurant', 'cheap', 'clean']
David Calavera Conferencia Rails 2007
búsqueda
require 'oos4ruby'
oos = Oos.new
oos.auth_app 'appToken', 'secretKey'
oos.search q => 'apple store in new york'
oos.search bbox => ['SOUTH', 'WEST', 'NORTH', 'EAST']
oos.search lat => 'LATITUDE', lon => 'LONGITUDE', radius => '3000 METRES'
oos.search tags => ['restaurant', 'cheap', 'clean']
David Calavera Conferencia Rails 2007
búsqueda
require 'oos4ruby'
oos = Oos.new
oos.auth_app 'appToken', 'secretKey'
oos.search q => 'apple store in new york'
oos.search bbox => ['SOUTH', 'WEST', 'NORTH', 'EAST']
oos.search lat => 'LATITUDE', lon => 'LONGITUDE', radius => '3000 METRES'
oos.search tags => ['restaurant', 'cheap', 'clean']
David Calavera Conferencia Rails 2007
búsqueda
require 'oos4ruby'
oos = Oos.new
oos.auth_app 'appToken', 'secretKey'
oos.search q => 'apple store in new york'
oos.search bbox => ['SOUTH', 'WEST', 'NORTH', 'EAST']
oos.search lat => 'LATITUDE', lon => 'LONGITUDE', radius => '3000 METRES'
oos.search tags => ['restaurant', 'cheap', 'clean']
David Calavera Conferencia Rails 2007
gestión
require 'oos4ruby'
oos = Oos.new
oos.auth_user 'user email', 'auth token'
user = oos.user
user.sites.each do |pro|
unless pro.multimedia.empty?
pro.multimedia.each do |media|
puts media.type
puts media.src
end
end
end
user.contacts.create! :slug => 'calavera', :trusted => 'true'
user.update_avatar! '/Users/david/skull.png'
David Calavera Conferencia Rails 2007
gestión
require 'oos4ruby'
oos = Oos.new
oos.auth_user 'user email', 'auth token'
user = oos.user
user.sites.each do |pro|
unless pro.multimedia.empty?
pro.multimedia.each do |media|
puts media.type
puts media.src
end
end
end
user.contacts.create! :slug => 'calavera', :trusted => 'true'
user.update_avatar! '/Users/david/skull.png'
David Calavera Conferencia Rails 2007
gestión
require 'oos4ruby'
oos = Oos.new
oos.auth_user 'user email', 'auth token'
user = oos.user
user.sites.each do |pro|
unless pro.multimedia.empty?
pro.multimedia.each do |media|
puts media.type
puts media.src
end
end
end
user.contacts.create! :slug => 'calavera', :trusted => 'true'
user.update_avatar! '/Users/david/skull.png'
David Calavera Conferencia Rails 2007
gestión
require 'oos4ruby'
oos = Oos.new
oos.auth_user 'user email', 'auth token'
user = oos.user
user.sites.each do |pro|
unless pro.multimedia.empty?
pro.multimedia.each do |media|
puts media.type
puts media.src
end
end
end
user.contacts.create! :slug => 'calavera', :trusted => 'true'
user.update_avatar! '/Users/david/skull.png'
David Calavera Conferencia Rails 2007
0 comments
Post a comment