Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

more generic rss plugin #1

Merged
merged 9 commits into from

2 participants

@cz8s

Hi, took you code and added a Plugin to parse generic rss/atom feeds.
it handles rss and atom, and can speak https. So now one can include the feeds generated by github in a jekyll site :)

Christoph added some commits
Christoph add statusnet-plugin e352801
Christoph fix typo 6ce19ef
Christoph fix typo a76ec17
Christoph another typo. I hate wiki-tables :) 51414e3
Christoph use function from rails to make the item.day relative.
and actually use the count variable to determine how many
posts to show
7464244
Christoph generic rss-feed cc0156a
Christoph don't need statusnet plugin.
its a generic rssfeed-plugin now
cc7d212
Christoph rssfeed.rb ready for usage now
* handles atom and rss
* handles https
c0eea04
Christoph fix documentation 528faf6
@christianhellsten christianhellsten merged commit 603591f into christianhellsten:master
@christianhellsten

Thanks Christoph.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 31, 2011
  1. add statusnet-plugin

    Christoph authored
  2. fix typo

    Christoph authored
  3. fix typo

    Christoph authored
  4. another typo. I hate wiki-tables :)

    Christoph authored
Commits on Sep 4, 2011
  1. use function from rails to make the item.day relative.

    Christoph authored
    and actually use the count variable to determine how many
    posts to show
Commits on Sep 9, 2011
  1. generic rss-feed

    Christoph authored
Commits on Sep 14, 2011
  1. don't need statusnet plugin.

    Christoph authored
    its a generic rssfeed-plugin now
Commits on Sep 22, 2011
  1. rssfeed.rb ready for usage now

    Christoph authored
    * handles atom and rss
    * handles https
  2. fix documentation

    Christoph authored
This page is out of date. Refresh to see the latest.
Showing with 176 additions and 0 deletions.
  1. +27 −0 README.textile
  2. +149 −0 rssfeed.rb
View
27 README.textile
@@ -29,3 +29,30 @@ h4. Parameters
h2. Author
"Christian Hellsten":http://christianhellsten.com ("Aktagon Ltd.":http://aktagon.com)
+
+h2. rssfeed
+
+This Jekyll plugin is used for fetching and rendering rss and atom feeds
+
+h3. Usage
+
+This will fetch the last 15 dents and cache them for 3600 seconds:
+
+<pre><code>
+ {% rssfeed url:https://github.com/cz8s.atom count:15 ttl:3600 %}
+ {{ item.link }}
+ {{ item.day }}
+ {{ item.description }}
+ {% endstatusnet %}
+</code></pre>
+
+h4. Parameters
+
+|Name|Description|Example|
+|url|where the feed is |https://github.com/cz8s.atom|
+|count|Number of Posts to show |15|
+|ttl|The number of seconds the feed is cached 3600 caches the feed for one hour. Leave empty to always fetch feed.|3600|
+
+h2. Author
+
+"Christoph":http://www.kluenter.de
View
149 rssfeed.rb
@@ -0,0 +1,149 @@
+require 'open-uri'
+require 'pp'
+require 'ostruct'
+require 'yaml'
+require 'jekyll'
+require 'date'
+require 'digest/md5'
+require 'action_view'
+require 'net/http'
+require 'net/https'
+require 'feedparser'
+require 'uri'
+
+include ActionView::Helpers::DateHelper
+
+# From http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html
+class Hash
+ def stringify_keys!
+ keys.each do |key|
+ self[key.to_s] = delete(key)
+ end
+ self
+ end
+end
+
+
+
+
+#
+# Parses a rss/atom feed and returns items as an array.
+#
+class RSSFeed
+ DEFAULT_TTL = 600
+ class << self
+ def tag(url, count = 15, ttl=DEFAULT_TTL)
+ links = []
+ url = "#{url}"
+ uri=URI.parse(url)
+ http = Net::HTTP.new(uri.host, uri.port)
+ if uri.scheme == "https"
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
+ request = Net::HTTP::Get.new(uri.request_uri)
+ response = http.request(request)
+ f = FeedParser::Feed::new(response.body)
+ f.items.take(count.to_i).each do |i|
+ item = OpenStruct.new
+ item.title = i.title
+ item.link = i.link
+ item.date = i.date
+ item.day = time_ago_in_words(i.date)
+ item.description = i.content
+ links << item
+ end
+ links
+ end
+ end
+end
+
+#
+# Cached version of the RSSFeed Jekyll tag.
+#
+class CachedRSSFeed < RSSFeed
+ DEFAULT_TTL = 600
+ CACHE_DIR = '_rssfeed_cache'
+ class << self
+ def tag(url, count = 15, ttl = DEFAULT_TTL)
+ ttl = DEFAULT_TTL if ttl.nil?
+ cache_key = "#{url}_#{count}"
+ cache_file = File.join(CACHE_DIR, Digest::MD5.hexdigest(cache_key) + '.yml')
+ FileUtils.mkdir_p(CACHE_DIR) if !File.directory?(CACHE_DIR)
+ age_in_seconds = Time.now - File.stat(cache_file).mtime if File.exist?(cache_file)
+ if age_in_seconds.nil? || age_in_seconds > ttl
+ result = super(url, count)
+ File.open(cache_file, 'w') { |out| YAML.dump(result, out) }
+ else
+ result = YAML::load_file(cache_file)
+ end
+ result
+ end
+ end
+end
+
+module Jekyll
+ class RSSFeedTag < Liquid::Block
+
+ include Liquid::StandardFilters
+ Syntax = /(#{Liquid::QuotedFragment}+)?/
+
+ def initialize(tag_name, markup, tokens)
+ @variable_name = 'item'
+ @attributes = {}
+
+ # Parse parameters
+ if markup =~ Syntax
+ markup.scan(Liquid::TagAttributes) do |key, value|
+ #p key + ":" + value
+ @attributes[key] = value
+ end
+ else
+ raise SyntaxError.new("Syntax Error in 'rssfeed' - Valid syntax: rssfeed uid:x count:x]")
+ end
+
+ @ttl = @attributes.has_key?('ttl') ? @attributes['ttl'].to_i : nil
+ @url = @attributes['url']
+ @count = @attributes['count']
+ @name = 'item'
+
+ super
+ end
+
+ def render(context)
+ context.registers[:rssfeed] ||= Hash.new(0)
+
+ if @ttl
+ collection = CachedRSSFeed.tag(@url, @count, @ttl)
+ else
+ collection = RSSFeed.tag(@url, @count)
+ end
+
+ length = collection.length
+ result = []
+
+ # loop through found items and render results
+ context.stack do
+ collection.each_with_index do |item, index|
+ attrs = item.send('table')
+ context[@variable_name] = attrs.stringify_keys! if attrs.size > 0
+ context['forloop'] = {
+ 'name' => @name,
+ 'length' => length,
+ 'index' => index + 1,
+ 'index0' => index,
+ 'rindex' => length - index,
+ 'rindex0' => length - index -1,
+ 'first' => (index == 0),
+ 'last' => (index == length - 1) }
+
+ result << render_all(@nodelist, context)
+ end
+ end
+ result
+ end
+ end
+end
+
+Liquid::Template.register_tag('rssfeed', Jekyll::RSSFeedTag)
+
Something went wrong with that request. Please try again.