Class: SimpleRSS
Overview
rubocop:disable Metrics/ClassLength
Constant Summary collapse
- VERSION =
@rbs! include Enumerable[Hash[Symbol, untyped]]
"2.2.0".freeze
- DATE_TAGS =
i[pubDate lastBuildDate published updated expirationDate modified dc:date].freeze
- STRIP_HTML_TAGS =
i[ contributor skipHours skipDays].freeze
i[ id title subtitle link description webMaster managingEditor contributor pubDate lastBuildDate updated dc:date generator language docs cloud ttl skipHours skipDays image logo icon rights copyright textInput feedburner:browserFriendly itunes: itunes:category ]
i[ id title link link+alternate link+self link+edit link+replies contributor description summary content content:encoded comments pubDate published updated expirationDate modified dc:date category guid trackback:ping trackback:about dc:creator dc:title dc:subject dc:rights dc:publisher feedburner:origLink media:content#url media:content#type media:content#height media:content#width media:content#duration media:title media:thumbnail#url media:thumbnail#height media:thumbnail#width media:credit media:credit#role media:category media:category#scheme media:description enclosure#url enclosure#type enclosure#length itunes:duration itunes:image#href ]
Instance Attribute Summary collapse
-
#etag ⇒ Object
readonly
: String?.
-
#items ⇒ Object
(also: #entries)
readonly
Returns the value of attribute items.
-
#last_modified ⇒ Object
readonly
: String?.
-
#source ⇒ Object
readonly
: String.
Class Method Summary collapse
- .feed_tags ⇒ Object
- .feed_tags=(ft) ⇒ Object
-
.fetch(url, options = {}) ⇒ Object
Fetch and parse a feed from a URL Returns nil if conditional GET returns 304 Not Modified.
- .item_tags ⇒ Object
- .item_tags=(it) ⇒ Object
- .merge(*feeds) ⇒ Object
-
.parse(source, options = {}) ⇒ Object
The strict attribute is for compatibility with Ruby's standard RSS parser.
- .valid?(source, options = {}) ⇒ Boolean
Instance Method Summary collapse
-
#[](index) ⇒ Object
Access an item by index.
- #as_json(_options = {}) ⇒ Object (also: #to_hash)
- #channel ⇒ Object (also: #feed)
- #dedupe ⇒ Object
- #diff(other) ⇒ Object
-
#each(&block) ⇒ Object
Iterate over all items in the feed.
- #enclosures ⇒ Object
- #feed_type ⇒ Object
- #images ⇒ Object
-
#initialize(source, options = {}) ⇒ SimpleRSS
constructor
A new instance of SimpleRSS.
- #items_by_category(name) ⇒ Object
- #items_since(time) ⇒ Object
-
#latest(count = 10) ⇒ Object
Get the n most recent items, sorted by date.
- #merge(*feeds) ⇒ Object
- #search(query) ⇒ Object
- #to_json ⇒ Object
- #to_xml(format: :rss2) ⇒ Object
- #valid? ⇒ Boolean
Constructor Details
#initialize(source, options = {}) ⇒ SimpleRSS
Returns a new instance of SimpleRSS.
61 62 63 64 65 66 67 68 |
# File 'lib/simple-rss.rb', line 61 def initialize(source, = {}) @source = source.respond_to?(:read) ? source.read.to_s : source.to_s @items = [] #: Array[Hash[Symbol, untyped]] = {} #: Hash[Symbol, untyped] .update() parse end |
Instance Attribute Details
#etag ⇒ Object (readonly)
: String?
23 24 25 |
# File 'lib/simple-rss.rb', line 23 def etag @etag end |
#items ⇒ Object (readonly) Also known as: entries
Returns the value of attribute items.
21 22 23 |
# File 'lib/simple-rss.rb', line 21 def items @items end |
#last_modified ⇒ Object (readonly)
: String?
24 25 26 |
# File 'lib/simple-rss.rb', line 24 def last_modified @last_modified end |
#source ⇒ Object (readonly)
: String
22 23 24 |
# File 'lib/simple-rss.rb', line 22 def source @source end |
Class Method Details
.feed_tags ⇒ Object
231 232 233 |
# File 'lib/simple-rss.rb', line 231 def end |
.feed_tags=(ft) ⇒ Object
236 237 238 |
# File 'lib/simple-rss.rb', line 236 def (ft) = ft end |
.fetch(url, options = {}) ⇒ Object
Fetch and parse a feed from a URL Returns nil if conditional GET returns 304 Not Modified
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/simple-rss.rb', line 277 def fetch(url, = {}) require "net/http" require "uri" uri = URI.parse(url) response = perform_fetch(uri, ) return nil if response.is_a?(Net::HTTPNotModified) raise SimpleRSSError, "HTTP #{response.code}: #{response.message}" unless response.is_a?(Net::HTTPSuccess) body = response.body.force_encoding(Encoding::UTF_8) feed = parse(body, ) feed.instance_variable_set(:@etag, response["ETag"]) feed.instance_variable_set(:@last_modified, response["Last-Modified"]) feed end |
.item_tags ⇒ Object
241 242 243 |
# File 'lib/simple-rss.rb', line 241 def end |
.item_tags=(it) ⇒ Object
246 247 248 |
# File 'lib/simple-rss.rb', line 246 def (it) = it end |
.merge(*feeds) ⇒ Object
266 267 268 269 270 271 |
# File 'lib/simple-rss.rb', line 266 def merge(*feeds) first_feed = feeds.first return [] if first_feed.nil? first_feed.merge(*feeds.drop(1)) end |
.parse(source, options = {}) ⇒ Object
The strict attribute is for compatibility with Ruby's standard RSS parser
253 254 255 |
# File 'lib/simple-rss.rb', line 253 def parse(source, = {}) new source, end |
.valid?(source, options = {}) ⇒ Boolean
258 259 260 261 262 263 |
# File 'lib/simple-rss.rb', line 258 def valid?(source, = {}) parse(source, ) true rescue StandardError false end |
Instance Method Details
#[](index) ⇒ Object
Access an item by index
90 91 92 |
# File 'lib/simple-rss.rb', line 90 def [](index) items[index] end |
#as_json(_options = {}) ⇒ Object Also known as: to_hash
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/simple-rss.rb', line 196 def as_json( = {}) hash = {} #: Hash[Symbol, untyped] .each do |tag| tag_cleaned = clean_tag(tag) value = instance_variable_get("@#{tag_cleaned}") hash[tag_cleaned] = serialize_value(value) if value end hash[:items] = items.map do |item| item.transform_values { |v| serialize_value(v) } end hash end |
#channel ⇒ Object Also known as: feed
71 72 73 |
# File 'lib/simple-rss.rb', line 71 def channel self end |
#dedupe ⇒ Object
170 171 172 173 |
# File 'lib/simple-rss.rb', line 170 def dedupe @items = dedupe_items(items) self end |
#diff(other) ⇒ Object
159 160 161 162 163 164 165 166 167 |
# File 'lib/simple-rss.rb', line 159 def diff(other) other_keys = keyed_item_set(other.items) current_keys = keyed_item_set(items) { added: select_new_keyed_items(other.items, current_keys), removed: select_new_keyed_items(items, other_keys) } end |
#each(&block) ⇒ Object
Iterate over all items in the feed
80 81 82 83 84 85 |
# File 'lib/simple-rss.rb', line 80 def each(&block) return enum_for(:each) unless block items.each(&block) self end |
#enclosures ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/simple-rss.rb', line 176 def enclosures items.filter_map do |item| enclosure_url = item[:enclosure_url] next if blank_value?(enclosure_url) { url: enclosure_url, type: item[:enclosure_type], length: item[:enclosure_length], item: item } end end |
#feed_type ⇒ Object
102 103 104 105 106 107 108 109 110 |
# File 'lib/simple-rss.rb', line 102 def feed_type atom_namespaced_feed = source.match?(/<(atom:)?feed\b[^>]*xmlns(:\w+)?=['"][^'"]*atom/i) return :atom if atom_namespaced_feed return :rss2 if source.match?(/<rss[^>]*version=['"]2/i) return :rss1 if source.match?(/<rdf:RDF/i) return :rss09 if source.match?(/<rss[^>]*version=['"]0\.9/i) :unknown end |
#images ⇒ Object
191 192 193 |
# File 'lib/simple-rss.rb', line 191 def images items.flat_map { |item| item_image_urls(item) }.uniq end |
#items_by_category(name) ⇒ Object
132 133 134 135 136 137 138 139 140 141 |
# File 'lib/simple-rss.rb', line 132 def items_by_category(name) query = name.to_s.downcase items.select do |item| category = item[:category] next false if category.nil? category_matches_query?(category, query) end end |
#items_since(time) ⇒ Object
124 125 126 127 128 129 |
# File 'lib/simple-rss.rb', line 124 def items_since(time) items.select do |item| item_date = item[:pubDate] || item[:updated] || item[:published] item_date.is_a?(Time) && item_date > time end end |
#latest(count = 10) ⇒ Object
Get the n most recent items, sorted by date
97 98 99 |
# File 'lib/simple-rss.rb', line 97 def latest(count = 10) items.sort_by { |item| item[:pubDate] || item[:updated] || Time.at(0) }.reverse.first(count) end |
#merge(*feeds) ⇒ Object
153 154 155 156 |
# File 'lib/simple-rss.rb', line 153 def merge(*feeds) all_items = [items, *feeds.map(&:items)].flatten dedupe_items(sorted_items_by_date(all_items)) end |
#search(query) ⇒ Object
144 145 146 147 148 149 150 |
# File 'lib/simple-rss.rb', line 144 def search(query) pattern = Regexp.new(Regexp.escape(query.to_s), Regexp::IGNORECASE) items.select do |item| searchable_fields(item).any? { |field| field.to_s.match?(pattern) } end end |
#to_json ⇒ Object
213 214 215 216 |
# File 'lib/simple-rss.rb', line 213 def to_json(*) require "json" JSON.generate(as_json) end |
#to_xml(format: :rss2) ⇒ Object
221 222 223 224 225 226 227 |
# File 'lib/simple-rss.rb', line 221 def to_xml(format: :rss2) case format when :rss2 then to_rss2_xml when :atom then to_atom_xml else raise ArgumentError, "Unknown format: #{format}. Supported: :rss2, :atom" end end |
#valid? ⇒ Boolean
113 114 115 116 117 118 119 120 121 |
# File 'lib/simple-rss.rb', line 113 def valid? return false if items.empty? title_value = instance_variable_get(:@title) link_value = instance_variable_get(:@link) return true if title_value || link_value false end |