Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

A Shoes hypermedia client for ALPS microblogging

View http.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
require 'net/http'
require 'open-uri'
 
require 'hpricot'
 
# A simple get request should not require this much boilerplate.
def fetch_data(uri)
uri = URI(uri)
req = Net::HTTP::Get.new(uri.request_uri)
req['Accept'] = "application/xhtml+xml"
 
res = Net::HTTP.start(uri.host, uri.port) {|http|
http.request(req)
}
 
Hpricot(res.body)
end
 
# I also like to wrap post requests, too. This is basically taken straight
# from the Net::HTTP docs: http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html
def post_data_with_auth(uri, username, password, data)
uri = URI(uri)
req = Net::HTTP::Post.new(uri.path)
req.basic_auth username, password
req.set_form_data(data)
 
res = Net::HTTP.start(uri.host, uri.port) do |http|
http.request(req)
end
 
case res
when Net::HTTPSuccess then
res
when Net::HTTPRedirection then
# We expect a redirect most of the time, and we'll want to
# follow the redirect.
res['location']
else
res.value
end
end
View http.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
# An ALPS microblogging client.
#
# http://amundsen.com/hypermedia/profiles/
 
require 'ostruct'
require './http'
 
# We're going to want to save some configuration options
Config = OpenStruct.new
 
# The only URI we hard-code. Bonus points for making this configuration, too.
Config.root_uri = "http://alps-microblog.herokuapp.com/"
Config.current_uri = Config.root_uri
 
class MicroblogClient < Shoes
 
# We have two basic screens: the preferences setup screen, and our index,
# where all the action happens
url '/', :index
url '/preferences', :preferences
 
def index
current_data = fetch_data(Config.current_uri)
 
# We want to make sure that this gets set. We can't post stuff without it!
unless Config.username and Config.password
visit "/preferences"
end
 
if form = current_data.search("//form[@class='message-post']")
para "What's happening?", :size => "large"
 
flow do
message_text = edit_line
 
button "Post" do
uri = form.first['action']
 
Config.current_uri = post_data_with_auth(uri, Config.username, Config.password, :message => message_text.text)
 
visit "/"
end
end
end
 
if messages = current_data.search("//div[@id='messages']/ul[@class='all']")
stack do
para "All messages", :size => "large"
 
messages.search("li").each do |message|
text = message.search("//span[@class='message-text']").inner_html.strip
user = message.search("//span[@class='user-text']").inner_html
para "'#{text}' - @#{user}"
end
end
end
 
button "refresh", :right => 10, :top => 5, :align => "right" do
visit "/"
end
end
 
# This preferences screen will allow us to set our username and password
# so that we don't have to re-authenticate per request
def preferences
para "Account Information", :size => "large"
 
stack do
user_edit = nil
pass_edit = nil
root_edit = nil
 
flow do
para "Username:"
user_edit = edit_line
end
 
flow do
para "Password:"
pass_edit = edit_line :secret => true
end
 
flow do
para "Root URI:"
root_edit = edit_line :width => 300
root_edit.text = Config.root_uri
end
 
button "Save" do
Config.username = user_edit.text
Config.password = pass_edit.text
Config.root_uri = root_edit.text
visit "/"
end
end
end
end
 
Shoes.app :title => "ALPS Microblogging Client"

zomg 80 chars!!!11!!1!11 :heart:

Owner

inorite

Good to see this here!

Just a note. The ALPS spec doesn't mean that only certain class names will appear on an element (link, form, etc.). You proly need to use contains() in your XPath queries when checking for a class name on a div, span, form, etc..

Owner

I'm guessing you got @clnclarinet's emails, then. :) I will have to update my code.

sorry about that, @steveklabnik ;)

Owner

No need to be sorry!

The rel attribute should also be treated the same way; it could contain multiple white-space separated values.

I decided to make a repo so I can describe the changes I'm making: https://github.com/clnclarinet/shoes-alps-client

mamund commented
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.