feed_cache 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in feed_cache.gemspec
4
+ gemspec
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "feed_cache/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "feed_cache"
7
+ s.version = FeedCache::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Brendon Murphy"]
10
+ s.email = ["xternal1+github@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{A thin wrapper over Feedzirra with injected caching}
13
+ s.description = s.summary
14
+
15
+ s.add_dependency "feedzirra", "~> 0.0.23"
16
+
17
+ s.add_development_dependency "rspec"
18
+ s.add_development_dependency "activesupport", "~> 2.3.5"
19
+
20
+ s.rubyforge_project = "feed_cache"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,40 @@
1
+ require 'forwardable'
2
+ require 'feedzirra'
3
+
4
+ module FeedCache
5
+ class Fetcher
6
+ extend Forwardable
7
+
8
+ attr_reader :url, :options
9
+
10
+ def_delegators :@fz_feed, :title, :last_modified, :entries
11
+
12
+ def cache
13
+ FeedCache.cache
14
+ end
15
+
16
+ def initialize(url, options = {})
17
+ raise "cache must be set with FeedCache.cache=" unless cache
18
+ @url = url
19
+ @options = { :expires_in => FeedCache.default_expires_in }.merge options
20
+ end
21
+
22
+ def fetch
23
+ @fz_feed = cache.fetch(cache_key, options) do
24
+ Feedzirra::Feed.fetch_and_parse(url)
25
+ end
26
+ end
27
+
28
+ def valid_feed?
29
+ # Feedzirra returns fixnums in error conditions, so we
30
+ # need to type check.
31
+ @fz_feed && ! @fz_feed.is_a?(Fixnum)
32
+ end
33
+
34
+ private
35
+
36
+ def cache_key
37
+ url
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module FeedCache
2
+ VERSION = "0.0.1"
3
+ end
data/lib/feed_cache.rb ADDED
@@ -0,0 +1,37 @@
1
+ module FeedCache
2
+ DEFAULT_ENTRIES_LIMIT = 10
3
+ DEFAULT_EXPIRES_IN = 900
4
+
5
+ class << self
6
+ attr_accessor :cache
7
+ attr_writer :default_entries_limit, :default_expires_in
8
+
9
+ def default_entries_limit
10
+ @default_entries_limit || DEFAULT_ENTRIES_LIMIT
11
+ end
12
+
13
+ def default_expires_in
14
+ @default_expires_in || DEFAULT_EXPIRES_IN
15
+ end
16
+
17
+ def configure(&block)
18
+ yield self
19
+ end
20
+ alias_method :config, :configure
21
+ end
22
+
23
+ def self.fetch(url, options = {})
24
+ feed = FeedCache::Fetcher.new(url, options)
25
+ feed.fetch
26
+ feed.valid_feed? ? feed : nil
27
+ end
28
+
29
+ def self.entries_for(url, options = {})
30
+ limit = options.delete(:limit) || default_entries_limit
31
+ feed = fetch(url, options)
32
+ (feed ? feed.entries : []).take(limit)
33
+ end
34
+ end
35
+
36
+ require File.expand_path("feed_cache/fetcher", File.dirname(__FILE__))
37
+ require File.expand_path("feed_cache/version", File.dirname(__FILE__))
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'active_support'
3
+
4
+ # Examples are unforunately coupled to FeedZirra for now because it uses curb which is tough
5
+ # to mock, and the state of other feed parsers isn't compliant with our gemset
6
+
7
+ describe FeedCache do
8
+ let(:blog_url) { "http://blog.kajabi.com/rss.xml" }
9
+ let(:blog_feed) { YAML.load_file(File.join File.dirname(__FILE__), "./fixtures/blog_feed.yaml") }
10
+ let(:cache) { ActiveSupport::Cache::MemoryStore.new }
11
+
12
+ before do
13
+ Feedzirra::Feed.stub(:fetch_and_parse).with(blog_url).and_return(blog_feed)
14
+ FeedCache.configure do |fc|
15
+ fc.cache = cache
16
+ end
17
+ end
18
+
19
+ describe "fetching a feed" do
20
+ context "for a valid feed grab" do
21
+ it "returns the feed with entries" do
22
+ feed = FeedCache.fetch(blog_url)
23
+ feed.entries.length.should == 20
24
+ end
25
+
26
+ it "stores the feed lookup in the cache" do
27
+ cache.exist?(blog_url).should be_false
28
+ FeedCache.fetch(blog_url)
29
+ cache.exist?(blog_url).should be_true
30
+ end
31
+ end
32
+
33
+ context "for an invalid feed grab" do
34
+ it "returns nil" do
35
+ Feedzirra::Feed.stub(:fetch_and_parse).with(blog_url).and_return(404)
36
+ FeedCache.fetch(blog_url).should be_nil
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "getting just the entries for a feed" do
42
+ context "for a valid feed grab" do
43
+ it "returns the entries array" do
44
+ FeedCache.entries_for(blog_url).length.should == 10
45
+ end
46
+
47
+ it "takes a limit option to trucate entries" do
48
+ FeedCache.entries_for(blog_url, :limit => 3).length.should == 3
49
+ end
50
+
51
+ it "respects the default entries limit setting" do
52
+ FeedCache.default_entries_limit = 7
53
+ FeedCache.entries_for(blog_url).length.should == 7
54
+ end
55
+ end
56
+
57
+ context "for an invalid feed grab" do
58
+ it "returns an empty array" do
59
+ Feedzirra::Feed.stub(:fetch_and_parse).with(blog_url).and_return(404)
60
+ FeedCache.entries_for(blog_url).should == []
61
+ end
62
+ end
63
+ end
64
+ end