Class: OPDS::Feed Abstract

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/opds/feed.rb

Overview

This class is abstract.

Not really abstract as it’s full fledged, but it should not be used directly

Feed class is used as an ancestor to NavigationFeed and AcquisitionFeed it handles all the parsing

Direct Known Subclasses

AcquisitionFeed, NavigationFeed

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

#log, log

Constructor Details

#initialize(browser = nil) ⇒ Feed



17
18
19
20
# File 'lib/opds/feed.rb', line 17

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

Instance Attribute Details

#entriesArray<Entry> (readonly)

Entry list

See Also:



14
15
16
# File 'lib/opds/feed.rb', line 14

def entries
  @entries
end

#raw_docNokogiri::XML::Document (readonly)

“Raw” Nokogiri document used while parsing. It might useful to access atom foreign markup



10
11
12
# File 'lib/opds/feed.rb', line 10

def raw_doc
  @raw_doc
end

Class Method Details

.from_nokogiri(content, browser = nil) ⇒ Feed

Create a feed from a nokogiri document



88
89
90
91
92
93
# File 'lib/opds/feed.rb', line 88

def self.from_nokogiri(content,browser=nil)
  z=self.new browser
  z.instance_variable_set('@raw_doc',content)
  z.serialize!
  z
end

.parse_raw(txt, opts = {}, browser = nil) ⇒ AcquisitionFeed, NavigationFeed

Will parse a text stream as an OPDS Catalog, internaly used by #parse_url



75
76
77
78
79
80
81
# File 'lib/opds/feed.rb', line 75

def self.parse_raw(txt,opts={},browser=nil)
  parser=OPDSParser.new(opts)
  pfeed=parser.parse(txt,browser)
  type=parser.sniffed_type
  return pfeed unless type.nil?
  nil
end

.parse_url(url, browser = OPDS::Support::Browser.new, parser_opts = {}) ⇒ AcquisitionFeed, ...

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.

See Also:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/opds/feed.rb', line 46

def self.parse_url(url,browser=OPDS::Support::Browser.new,parser_opts={})
  @browser=browser
  @browser.go_to(url)
  if @browser.ok?
    parsed = self.parse_raw(@browser.body,parser_opts,browser) 
    if parsed.nil?
      disco=@browser.discover(@browser.current_location)
      if disco.size > 0
        d=disco[nil]
        d||=disco['related']
        d||=disco
        Logging.log("Discovered : #{d.first.url}")
        return d.first.navigate
      end
      return false
    else
      return  parsed
    end
  else
    return false
  end
end

Instance Method Details

#authorHash



154
155
156
157
158
159
160
# File 'lib/opds/feed.rb', line 154

def author
  {
    :name => text(raw_doc.at('/xmlns:feed/xmlns:author/xmlns:name',raw_doc.root.namespaces)),
    :uri => text(raw_doc.at('/xmlns:feed/xmlns:author/xmlns:uri',raw_doc.root.namespaces)),
    :email => text(raw_doc.at('/xmlns:feed/xmlns:author/xmlns:email',raw_doc.root.namespaces))
  }
end

#first_page?Boolean

Is it the first page ?



180
181
182
# File 'lib/opds/feed.rb', line 180

def first_page?
  !prev_page_url if paginated?
end

#iconString



111
112
113
# File 'lib/opds/feed.rb', line 111

def icon
  text(raw_doc.at('/xmlns:feed/xmlns:icon',raw_doc.root.namespaces))
end

#idString



149
150
151
# File 'lib/opds/feed.rb', line 149

def id
  text(raw_doc.at('/xmlns:feed/xmlns:id',raw_doc.root.namespaces))
end

#inspectObject



202
203
204
# File 'lib/opds/feed.rb', line 202

def inspect
  "#<#{self.class}:0x#{self.object_id.abs.to_s(16)} entries(count):#{@entries.size} #{instance_variables.reject{|e| e=='@raw_doc'||e=='@entries' }.collect{|e| "#{e}=#{instance_variable_get(e).inspect}"}.join(' ')} >"
end

#last_page?Boolean

Is it the last page ?



186
187
188
# File 'lib/opds/feed.rb', line 186

def last_page?
  !next_page_url if paginated?
end


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/opds/feed.rb', line 116

def links
  if !@links || @links.size ==0
    @links=OPDS::Support::LinkSet.new @browser
    raw_doc.xpath('/xmlns:feed/xmlns:link',raw_doc.root.namespaces).each do |n|
      text=nil
      text=n.attributes['title'].value unless n.attributes['title'].nil?
      type=n.attributes['type'].value unless n.attributes['type'].nil?
      link=n.attributes['href'].value
      unless n.attributes['rel'].nil?
        n.attributes['rel'].value.split.each do |rel|
          if rel=='http://opds-spec.org/facet'
            group=n.attribute_with_ns('facetGroup','http://opds-spec.org/2010/catalog')
            group=group.value unless group.nil?
            active=n.attribute_with_ns('activeFacet','http://opds-spec.org/2010/catalog')
            active=active.value unless active.nil?
            count=n.attribute_with_ns('count','http://purl.org/syndication/thread/1.0')
            count=count.value unless count.nil?

          @links.push_facet(link,text,type,group,active,count)
          else
          @links.push(rel,link,text,type)
          end
        end
      else
        @links.push(nil,link,text,type)
      end
    end

  end
  @links
end

#next_pageAcquisitionFeed, ...

Get next page feed



192
193
194
# File 'lib/opds/feed.rb', line 192

def next_page
  Feed.parse_url(next_page_url,@browser)
end

#next_page_urlString



163
164
165
# File 'lib/opds/feed.rb', line 163

def next_page_url
  links.link_url(:rel => 'next')
end

#paginated?Boolean

Is the feed paginated ?



174
175
176
# File 'lib/opds/feed.rb', line 174

def paginated?
  !next_page_url.nil?||!prev_page_url.nil?
end

#prev_pageAcquisitionFeed, ...

Get previous page feed



198
199
200
# File 'lib/opds/feed.rb', line 198

def prev_page
  Feed.parse_url(prev_page_url,@browser)
end

#prev_page_urlString



168
169
170
# File 'lib/opds/feed.rb', line 168

def prev_page_url
  links.link_url(:rel => 'prev')
end

#serialize!Object

TODO:

really make private

read xml entries into the entry list struct



98
99
100
101
102
# File 'lib/opds/feed.rb', line 98

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

#titleString



106
107
108
# File 'lib/opds/feed.rb', line 106

def title
  text(raw_doc.at('/xmlns:feed/xmlns:title',raw_doc.root.namespaces))
end