Skip to content

Commit

Permalink
defining parser inheritance chain
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Cetrulo committed May 18, 2012
1 parent 4830db6 commit a8b3c28
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
4 changes: 3 additions & 1 deletion lib/planet/blog.rb
Expand Up @@ -16,10 +16,12 @@ def initialize(attributes = {})
self.twitter = attributes[:twitter]
self.posts = attributes.fetch(:posts, [])
self.planet = attributes[:planet]

@parsers = Parsers.new
end

def fetch
parser = self.type ? Parsers.get_parser(self.type) : Parsers.get_parser_for(self.feed)
parser = self.type ? @parsers.get_parser(self.type) : @parsers.get_parser_for(self.feed)

feed = parser.fetch_and_parse(self.feed)

Expand Down
43 changes: 35 additions & 8 deletions lib/planet/parsers.rb
@@ -1,25 +1,52 @@
require 'feedzirra'
require 'set'

class Planet
class Parsers
@@parsers = []
@@parsers = Set.new

def self.add_parser(parser)
@@parsers << parser
end

def initialize
@types, @domains = {}, {}

def self.get_parser(type)
@@parsers.each do |parser|
return parser if parser.type == type
new_type, new_domains = parser.type, parser.domains

fail("duplicate type") if new_type and @types.has_key? new_type
fail("overlapping domains") unless (@domains.keys & new_domains).empty?

@types[new_type] = parser if new_type
new_domains.each do |new_domain|
@domains[new_domain] = parser
end
end
end

raise ArgumentError, "no parser for type '#{ type }'", caller
def get_parser(type)
begin
return @types.fetch(type)
rescue KeyError => e
raise(ArgumentError, "No parser for type '#{ type }'", caller)
end
end

def self.get_parser_for(feed)
def get_parser_for(feed)
feed_domain = URI(feed).host

@@parsers.each do |parser|
return parser if parser.domains.any? { |domain| feed_domain.end_with? domain }
@domains.each do |domain, parser|
return parser if feed_domain.end_with? domain
end

return Feedzirra::Feed
return Feedzirra::Feed # default generic parser
end
end
end

# load parsers
dirname = File.join([File.dirname(__FILE__), 'parsers'])
Dir.open(dirname).each do |filename|
require "#{dirname}/#{filename}" if filename.end_with? '.rb'
end
21 changes: 21 additions & 0 deletions lib/planet/parsers/base_parser.rb
@@ -0,0 +1,21 @@
class Planet
class Parsers
class BaseParser
def self.type
@type
end

def self.domains
@domains || []
end

def self.inherited(parser)
Parsers.add_parser parser
end

def self.fetch_and_parse(feed)
raise(Exception, "Not implemented", caller)
end
end
end
end

0 comments on commit a8b3c28

Please sign in to comment.