Skip to content

Commit

Permalink
Several improvements in Uri and HTML metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
atd committed Mar 22, 2010
1 parent d5bd31c commit 2819cb3
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 48 deletions.
83 changes: 39 additions & 44 deletions app/models/uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
# same source file name
URI

begin
require 'atom/service'
rescue MissingSourceFile
Rails.logger.info "Station Info: You need 'atom-tools' gem for AtomPub service document support"
end

begin
require 'mofo'
rescue MissingSourceFile
Rails.logger.info "Station Info: You need 'mofo' gem for Microformats support"
{ 'openid' => 'OpenID',
'atom/service' => 'AtomPub service document' }.each_pair do |gem, support|
begin
require gem
rescue MissingSourceFile
Rails.logger.info "Station Info: You need '#{ gem }' gem for #{ support } support"
end
end

# URI storage in the database
Expand All @@ -32,55 +29,53 @@ def to_uri

# Dereference URI and return HTML document
def html
@html ||= Station::Html.new(dereference(:accept => 'text/html').body)
# NOTE: Must read StringIO or Tmpfile
@html ||= Station::Html.new(dereference(:accept => 'text/html').try(:read))
end

def dereference(options = {})
# TODO?: non http(s) URIs
return nil unless to_uri.scheme =~ /^(http|https)$/

# Limit too many redirects
options[:redirect] ||= 0
return nil if options[:redirect] > 10

http = Net::HTTP.new(to_uri.host, to_uri.port)
http.use_ssl = to_uri.scheme == "https"
path = to_uri.path.present? && to_uri.path || '/'
path << "?#{ to_uri.query }" if to_uri.query.present?
headers = {}
headers['Accept'] = options[:accept] if options[:accept].present?
response = http.get(path, headers)
headers['Accept'] = options[:accept] if options.key?(:accept)

case response
when Net::HTTPSuccess
response
when Net::HTTPRedirection
options[:redirect] += 1
self.class.new(:uri => response['location']).dereference(options)
else
nil
end
to_uri.open(headers)
rescue
nil
end

# Returns the AtomPub Service Document associated with this URI.
def atompub_service_document
Atom::Service.discover self.uri
# Perform OpenID discover
#
# OpenID.discover returns [ claimed_id, openid_services ]
def openid_discover
@openid_discover ||= ::OpenID.discover self.uri
end

# Find hCard in this URI
#
# Needs the {mofo}[http://mofo.rubyforge.org/] gem
def hcard
hCard.find self.uri
# Is this URI an OpenID
def openid?
openid_discover.last.any?
rescue
nil
end

# Does this URI has a hCard attached?
def hcard?
hcard.present?
# Update self.uri with OpenID claimed ID
def to_openid
self.uri = openid_discover.first
end

# Update self.uri with OpenID claimed ID and save the record
def to_openid!
update_attribute :uri, openid_discover.first
end

# Returns the AtomPub Service Document associated with this URI.
def atompub_service_document
#FIXME: use html?
Atom::Service.discover self.uri
end

delegate :hcard, :hcard?,
:foaf, :foaf?,
:to => :html

private

# Extract service link from HTML head
Expand Down
73 changes: 69 additions & 4 deletions lib/station/html.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,85 @@
{ 'hpricot' => 'HTML introspection',
'mofo' => 'Microformats' }.each_pair do |gem, support|
begin
require gem
rescue MissingSourceFile
Rails.logger.info "Station Info: You need '#{ gem }' gem for #{ support } support"
end
end

module Station #:nodoc:
# Manage HTML documents
class Html
require 'hpricot'
attr_reader :text

def initialize(text = "")
@text = text
def initialize(text)
@text = text || ""
end

def doc
@doc ||= Hpricot(@text)
end

def head_links
doc.search('//link')
end

def feeds
doc.search('//link').select{ |l|
head_links.select{ |l|
l['rel'].match(/alternate/i)
}
end

def rdf_links
head_links.select{ |l|
l['rel'].match(/meta/i) && l['type'].match(/application\/rdf\+xml/)
}
end

def foaf_links
rdf_links.select{ |l|
l['title'].match(/^foaf$/i)
}
end

def atom_service_links
head_links.select{ |l|
l['rel'].match(/^service$/i)
}
end

def rsd_links
head_links.select{ |l|
l['rel'].match(/^EditURI$/i)
}
end

def foaf?
foaf_links.any?
end

def microformats
Microformat.find :text => text
rescue
Array.new
end

# Find hCard in this HTML
#
# Needs the {mofo}[http://mofo.rubyforge.org/] gem
def hcard
hCard.find :text => text
rescue
nil
end

# Does this URI has a hCard attached?
def hcard?
hcard.present?
end

def to_s
@text
end
end
end

0 comments on commit 2819cb3

Please sign in to comment.