Skip to content

Commit

Permalink
Documentation
Browse files Browse the repository at this point in the history
using yardoc
  • Loading branch information
zetaben committed Sep 18, 2010
1 parent 7ccdf14 commit fff9610
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 20 deletions.
2 changes: 2 additions & 0 deletions lib/opds/acquisition_feed.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
module OPDS
# Represents an acquisition feed
# @see http://opds-spec.org/specs/opds-catalog-1-0-20100830/#Acquisition_Feeds
class AcquisitionFeed < Feed
end
end
48 changes: 40 additions & 8 deletions lib/opds/entry.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,50 @@
module OPDS
# Represents a catalog entry
class Entry
include Logging

# "Raw" Nokogiri document used while parsing.
# It might useful to access atom foreign markup
# @return [Nokogiri::XML::Document] Parsed document
attr_reader :raw_doc
# @return [String] entry title
attr_reader :title
# @return [String] entry id
attr_reader :id
# @return [Date] entry updated date
attr_reader :updated
# @return [Date] entry published date
attr_reader :published
# @return [String] entry summary
attr_reader :summary
# @return [Array] entry parsed authors
attr_reader :authors
# @return [Array] entry parsed contributors
attr_reader :contributors
# @return [OPDS::Support::LinkSet] Set of links found in the entry
attr_reader :links
# @return [Hash] Hash of found dublin core metadata found in the entry
# @see http://dublincore.org/documents/dcmi-terms/
attr_reader :dcmetas
# @return [Array] Categories found
attr_reader :categories
# @return [String] content found
attr_reader :content
# @return [String] entry right
attr_reader :rights
# @return [String] entry subtitle
attr_reader :subtitle

def initialize(browser=nil)
# @param browser (see Feed.parse_url)
def initialize(browser=OPDS::Support::Browser.new)
@browser=browser
@browser||=OPDS::Support::Browser.new
end


# Create an entry from a nokogiri fragment
# @param content [Nokogiri::XML::Element] Nokogiri fragment (should be <entry>)
# @param namespaces Associated document namespaces
# @param browser (see Feed.parse_url)
# @return [Entry]
def self.from_nokogiri(content,namespaces=nil, browser=nil)
z=self.new browser
z.instance_variable_set('@raw_doc',content)
Expand All @@ -29,7 +53,9 @@ def self.from_nokogiri(content,namespaces=nil, browser=nil)
z
end


# Read the provided document into the entry struct
# @private
# @todo really make private
def serialize!
@namespaces=raw_doc.root.namespaces if @namespaces.nil?
@authors=[]
Expand Down Expand Up @@ -101,23 +127,29 @@ def serialize!

end


#First Author
# @return [Hash]
def author
authors.first
end


# Is it a partial atom entry ?
# @return [boolean]
def partial?
links.by(:rel)['alternate'].any? do |l|
l[3]=='application/atom+xml'||l[3]=='application/atom+xml;type=entry'
end
end


# @return [String] URL to the complete entry
# @todo accessor to the complete entry
def complete_url
links.by(:rel)['alternate'].find do |l|
l[3]=='application/atom+xml;type=entry'||l[3]=='application/atom+xml'
end unless !partial?
end


# @return [Array] acquisition link subset
def acquisition_links
rel_start='http://opds-spec.org/acquisition'
[*links.by(:rel).reject do |k,_|
Expand Down
65 changes: 59 additions & 6 deletions lib/opds/feed.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
module OPDS
# Feed class is used as an ancestor to NavigationFeed and AcquisitionFeed it handles
# all the parsing
# @abstract Not really abstract as it's full fledged, but it should not be used directly
class Feed
include Logging
# "Raw" Nokogiri document used while parsing.
# It might useful to access atom foreign markup
# @return [Nokogiri::XML::Document] Parsed document
attr_reader :raw_doc
# Entry list
# @see Entry
# @return [Array<Entry>] list of parsed entries
attr_reader :entries


def initialize(browser=nil)
@browser=browser
@browser||=OPDS::Support::Browser.new
end

=begin
# access root catalog
def root
return @root unless root?
Expand All @@ -19,10 +28,23 @@ def root
# root catalog predicate
def root?
end

def self.parse_url(url,browser=nil,parser_opts={})
=end


# Parse the given url.
#
# If the resource at the give url is not an OPDS Catalog, this method will
# try to find a linked catalog.
# If many are available it will take the first one with a priority given to
# nil rel or rel="related" catalogs.
#
# @param url [String] url to parse
# @param browser (see Feed.parse_raw)
# @param parser_opts parser options (unused at the moment)
# @see OPDS::Support::Browser
# @return [AcquisitionFeed,NavigationFeed, Entry, nil] an instance of a parsed feed, entry or nil
def self.parse_url(url,browser=OPDS::Support::Browser.new,parser_opts={})
@browser=browser
@browser||=OPDS::Support::Browser.new
@browser.go_to(url)
if @browser.ok?
parsed = self.parse_raw(@browser.body,parser_opts,browser)
Expand All @@ -44,6 +66,12 @@ def self.parse_url(url,browser=nil,parser_opts={})
end
end

# Will parse a text stream as an OPDS Catalog, internaly used by #parse_url
#
# @param txt [String] text to parse
# @param opts [Hash] options to pass to the parser
# @param browser [OPDS::Support::Browser] an optional compatible browser to use
# @return [AcquisitionFeed,NavigationFeed] an instance of a parsed feed or nil
def self.parse_raw(txt,opts={},browser=nil)
parser=OPDSParser.new(opts)
pfeed=parser.parse(txt,browser)
Expand All @@ -52,28 +80,39 @@ def self.parse_raw(txt,opts={},browser=nil)
nil
end


# Create a feed from a nokogiri document
# @param content [Nokogiri::XML::Document] nokogiri document
# @param browser (see Feed.parse_url)
# @return [Feed] new feed
def self.from_nokogiri(content,browser=nil)
z=self.new browser
z.instance_variable_set('@raw_doc',content)
z.serialize!
z
end

#read xml entries into entry struct
# @private
# read xml entries into the entry list struct
# @todo really make private
def serialize!
@entries=raw_doc.xpath('/xmlns:feed/xmlns:entry',raw_doc.root.namespaces).map do |el|
OPDS::Entry.from_nokogiri(el,raw_doc.root.namespaces,@browser)
end
end


# @return [String] Feed title
def title
text(raw_doc.at('/xmlns:feed/xmlns:title',raw_doc.root.namespaces))
end

# @return [String] Feed icon definition
def icon
text(raw_doc.at('/xmlns:feed/xmlns:icon',raw_doc.root.namespaces))
end

# @return [OPDS::Support::LinkSet] Set with atom feed level links
def links
if !@links || @links.size ==0
@links=OPDS::Support::LinkSet.new @browser
Expand All @@ -95,10 +134,12 @@ def links
@links
end

# @return [String] Feed id
def id
text(raw_doc.at('/xmlns:feed/xmlns:id',raw_doc.root.namespaces))
end

# @return [Hash] Feed author (keys : name,uri,email)
def author
{
:name => text(raw_doc.at('/xmlns:feed/xmlns:author/xmlns:name',raw_doc.root.namespaces)),
Expand All @@ -107,31 +148,42 @@ def author
}
end


# @return [String] Next page url
def next_page_url
links.link_url(:rel => 'next')
end

# @return [String] Previous page url
def prev_page_url
links.link_url(:rel => 'prev')
end

# Is the feed paginated ?
# @return Boolean
def paginated?
!next_page_url.nil?||!prev_page_url.nil?
end

# Is it the first page ?
# @return Boolean
def first_page?
!prev_page_url if paginated?
end

# Is it the last page ?
# @return Boolean
def last_page?
!next_page_url if paginated?
end

# Get next page feed
# @return (see Feed.parse_url)
def next_page
Feed.parse_url(next_page_url,@browser)
end

# Get previous page feed
# @return (see Feed.parse_url)
def prev_page
Feed.parse_url(prev_page_url,@browser)
end
Expand All @@ -141,6 +193,7 @@ def inspect
end

protected
# Convert a nokogiri node to String value if not nil
def text(t)
return t.text unless t.nil?
t
Expand Down
4 changes: 4 additions & 0 deletions lib/opds/navigation_feed.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
module OPDS
# Represents a navigation feed
# @see http://opds-spec.org/specs/opds-catalog-1-0-20100830/#Navigation_Feeds
class NavigationFeed < Feed
# Collection of all Navigation feeds found in this feed
# @return [OPDS::Support::LinkSet] found links
def navigation_links
nav_links=Support::LinkSet.new @browser
self.links.each do |l|
Expand Down
3 changes: 3 additions & 0 deletions lib/opds/opds.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
module OPDS
# Convinience call to Feed.parse_url
# @see Feed.parse_url
# @return (see Feed.parse_url)
def self.access(feed)
Feed.parse_url(feed)
end
Expand Down
14 changes: 14 additions & 0 deletions lib/opds/parser.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
require "nokogiri"
module OPDS
# Class in charge of discovering the type of the given text stream.
# It will dispatch the pre-parsed atom content to the desired class
# @see OPDS::AcquisitionFeed
# @see OPDS::NavigationFeed
# @see OPDS::Entry
class OPDSParser
include Logging
# @return [Hash] parsing options
attr_accessor :options
# @return [Symbol] last parsed stream sniffed type (:acquisition,:navigation,:entry)
attr_reader :sniffed_type
def initialize(opts={})
@sniffed_type=nil
self.options=opts.merge({})
end

# Parse a text stream
# @param content [String] text stream
# @param browser (see Feed.parse_url)
# @return [NavigationFeed, AcquisitionFeed, Entry] the parsed structure
def parse(content,browser=nil)
@ret=Nokogiri::XML(content)
@sniffed_type=sniff(@ret)
Expand All @@ -20,6 +31,9 @@ def parse(content,browser=nil)
end

protected
# Sniff a provided nokogiri document to detect it's type
# @param doc [Nokogiri::XML::Document] Document to sniff
# @return [:acquisition, :navigation, :entry, nil] sniffed type
def sniff(doc)
return :entry if doc.root.name=='entry'
entries = doc.xpath('/xmlns:feed/xmlns:entry',doc.root.namespaces)
Expand Down
16 changes: 15 additions & 1 deletion lib/opds/support/browser.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
require "open-uri"
module OPDS
# Supporting classes
module Support
# Browser class, it will be used to access the Internet.
# Currently based on open-uri only
class Browser
include Logging
# Navigate to the provided uri
# @param uri [String] uri to go to
def go_to(uri)
log("Accessing #{uri}")
url=URI.parse(uri)
Expand All @@ -21,27 +26,35 @@ def go_to(uri)
end
end

# Last page load was ok ?
# @return [boolean]
def ok?
status==200
end


# @return [integer] Last page load return code
def status
@last_response.code.to_i if @last_response
end

# @return [Hash] Last page HTTP headers
def headers
@last_response.to_hash if @last_response
end

# @return [String] Last page body
def body
@last_response.body if @last_response
end

# @return [String] current uri
def current_location
@current_location
end

# Try to discover catalog links at the given url
# @params [String] url to search
# @return [OPDS::Support::LinkSet, false] discovered links
def discover(url)
go_to(url)
if ok?
Expand All @@ -59,6 +72,7 @@ def discover(url)
end

private
# extracts linkset from doc + xpath expression
def extract_links(tab,doc, expr)
doc.xpath(expr).each do |n|
text=nil
Expand Down
Loading

0 comments on commit fff9610

Please sign in to comment.