├── VERSION ├── .gitignore ├── spec ├── spec_helper.rb ├── html │ └── bob.html └── lib │ └── person.rb ├── lib ├── xfn_stone.rb └── xfn_stone │ ├── person.rb │ └── document.rb ├── Manifest.txt ├── History.txt ├── Rakefile └── README.txt /VERSION: -------------------------------------------------------------------------------- 1 | 0.0.8 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## PROJECT::GENERAL 2 | coverage 3 | rdoc 4 | pkg 5 | *.gemspec 6 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | lib_path = File.expand_path("#{File.dirname(__FILE__)}/../../lib") 2 | $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path) 3 | require 'spec' 4 | -------------------------------------------------------------------------------- /lib/xfn_stone.rb: -------------------------------------------------------------------------------- 1 | require 'uri' 2 | require 'open-uri' 3 | 4 | require 'xfn_stone/document.rb' 5 | require 'xfn_stone/person.rb' 6 | 7 | module XfnStone 8 | VERSION = '0.0.8' 9 | end 10 | -------------------------------------------------------------------------------- /Manifest.txt: -------------------------------------------------------------------------------- 1 | History.txt 2 | Manifest.txt 3 | README.txt 4 | Rakefile 5 | lib/xfn_stone.rb 6 | lib/xfn_stone/document.rb 7 | lib/xfn_stone/person.rb 8 | spec/person.rb 9 | spec/spec_helper.rb 10 | -------------------------------------------------------------------------------- /History.txt: -------------------------------------------------------------------------------- 1 | === 0.0.2 / 2008-02-23 2 | 3 | * Moved from REXML to Hpricot 4 | * Hpricot can handle lots of pseudo-xml 5 | 6 | === 0.0.1 / 2008-02-19 7 | 8 | * 1 major enhancement 9 | * Birthday! 10 | 11 | -------------------------------------------------------------------------------- /spec/html/bob.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | my other home page 4 | my buddy dan 5 | my penpal jan 6 | coworker james 7 | coworker polly 8 | 9 | other rel uses 10 | 11 | 12 | -------------------------------------------------------------------------------- /lib/xfn_stone/person.rb: -------------------------------------------------------------------------------- 1 | module XfnStone 2 | class Person 3 | attr_reader :uri, :document 4 | 5 | def initialize(url, load_now = true) 6 | @uri = URI.parse(url) 7 | refresh if load_now 8 | end 9 | 10 | def refresh 11 | @document = Document.create_from_uri(@uri) 12 | end 13 | 14 | def contacts 15 | @document.elements("//a[@rel~=\"contact\"]") 16 | end 17 | 18 | def friends 19 | @document.elements("//a[@rel~=\"friend\"]") 20 | end 21 | 22 | def mine 23 | @document.elements("//a[@rel~=\"me\"]") 24 | end 25 | end 26 | end 27 | 28 | -------------------------------------------------------------------------------- /spec/lib/person.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__), *%w[../spec_helper]) 2 | require File.join(File.dirname(__FILE__), *%w[../../lib/xfn_stone.rb]) 3 | 4 | describe XfnStone::Person do 5 | 6 | before(:each) do 7 | html_page = open(File.dirname(__FILE__)+"/../html/bob.html") 8 | XfnStone::Document.should_receive(:open).and_return(html_page) 9 | @url = "http://localhost" 10 | @person = XfnStone::Person.new(@url) 11 | end 12 | 13 | it "should know its load URL" do 14 | @person.uri.to_s.should == @url 15 | end 16 | 17 | it "should return the 'me' links found in the document" do 18 | @person.mine.size.should == 1 19 | end 20 | 21 | it "should return the friend links found in the document" do 22 | @person.friends.size.should == 2 23 | end 24 | 25 | it "should return the contact links found in the document" do 26 | @person.contacts.size.should == 2 27 | end 28 | end 29 | 30 | -------------------------------------------------------------------------------- /lib/xfn_stone/document.rb: -------------------------------------------------------------------------------- 1 | #require 'rexml/document' 2 | #we're parsing HTML now 3 | require 'hpricot' 4 | 5 | module Hpricot 6 | class Elements 7 | def urls 8 | self.map do |fragment| 9 | fragment.attributes["href"] 10 | end 11 | end 12 | end 13 | end 14 | 15 | module XfnStone 16 | # This is an empty subclass of hpricot. Substuting a 17 | # different XML parser in the future will be easier this way. 18 | # Also a useful spot for future helpers. 19 | class Document 20 | def self.create_from_uri(uri) 21 | document = Document.new 22 | document.load_from_uri(uri) 23 | return document 24 | end 25 | 26 | def load_from_uri(uri) 27 | file = Document.open(uri.to_s) 28 | @document = Hpricot(file) 29 | end 30 | 31 | def elements(xpath) 32 | (@document/xpath) 33 | end 34 | 35 | # allow the open-uri call to be stubed 36 | def self.open(url) 37 | Kernel.open(url) 38 | end 39 | end 40 | 41 | class Element < Hpricot::Elem 42 | end 43 | 44 | end 45 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'rake' 3 | 4 | begin 5 | require 'jeweler' 6 | Jeweler::Tasks.new do |gem| 7 | gem.name = "xfn_stone" 8 | gem.summary = "XHTML Frinds Network helper library" 9 | gem.description = "Simplify development of loading and parsing HTML pages with XFN social network information." 10 | gem.email = "don@donpark.org" 11 | gem.homepage = "http://github.com/donpdonp/xfn_stone" 12 | gem.authors = ["Don Park"] 13 | gem.rubyforge_project = 'foafstone' 14 | gem.add_development_dependency "rspec", ">= 1.2.9" 15 | # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings 16 | end 17 | Jeweler::GemcutterTasks.new 18 | rescue LoadError 19 | puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" 20 | end 21 | 22 | require 'spec/rake/spectask' 23 | Spec::Rake::SpecTask.new(:spec) do |spec| 24 | spec.libs << 'lib' << 'spec' 25 | spec.spec_files = FileList['spec/lib/*.rb'] 26 | end 27 | 28 | Spec::Rake::SpecTask.new(:rcov) do |spec| 29 | spec.libs << 'lib' << 'spec' 30 | spec.pattern = 'spec/**/*_spec.rb' 31 | spec.rcov = true 32 | end 33 | 34 | task :spec => :check_dependencies 35 | 36 | task :default => :spec 37 | 38 | require 'rake/rdoctask' 39 | Rake::RDocTask.new do |rdoc| 40 | version = File.exist?('VERSION') ? File.read('VERSION') : "" 41 | 42 | rdoc.rdoc_dir = 'rdoc' 43 | rdoc.title = "example #{version}" 44 | rdoc.rdoc_files.include('README*') 45 | rdoc.rdoc_files.include('lib/**/*.rb') 46 | end 47 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | = xfn_stone 2 | 3 | * http://rubyforge.org/projects/foafstone/ 4 | 5 | == DESCRIPTION: 6 | 7 | XfnStone provides helper methods to make simple the processing 8 | of XML documents that contain HTML with XFN (XHTML Friends Network) 9 | attributes on its tags. 10 | 11 | 12 | == FEATURES/PROBLEMS: 13 | 14 | * XFN processing 15 | 16 | == SYNOPSIS: 17 | 18 | person = XfnStone::Person.new("http://example.com/myblog") 19 | person.friends => [ array of Person objects for friends listed on myblog ] 20 | 21 | == REQUIREMENTS: 22 | 23 | * REXML 24 | 25 | == INSTALL: 26 | 27 | * sudo gem install xfn_friends 28 | 29 | == LICENSE: 30 | 31 | (The MIT License) 32 | 33 | Copyright (c) 2008 34 | 35 | Permission is hereby granted, free of charge, to any person obtaining 36 | a copy of this software and associated documentation files (the 37 | 'Software'), to deal in the Software without restriction, including 38 | without limitation the rights to use, copy, modify, merge, publish, 39 | distribute, sublicense, and/or sell copies of the Software, and to 40 | permit persons to whom the Software is furnished to do so, subject to 41 | the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be 44 | included in all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 47 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 48 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 49 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 50 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 51 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 52 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 53 | --------------------------------------------------------------------------------