module Gnip
class Filter
def Filter.list_from_xml(xml, options = {}, &block)
list = []
parse_xml(xml, options) do |filter|
block ? block.call(filter) : list.push(filter)
end
block ? nil : list
end
def Filter.parse_xml(xml, options = {}, &block)
doc = Nokogiri::XML.parse(xml)
list = []
selectors = 'filter'
selectors.each do |selector|
search = doc.search(selector)
next unless search.size > 0
search.each do |node|
filter = Filter.from_node(node, options)
block ? block.call(filter) : list.push(filter)
end
end
block ? nil : list
end
def Filter.from_node(node, options = {})
full_data = node['fullData'] =~ /true/ ? true : false
name = node['name']
post_url = nil
rules = []
node.search('rule').each do |rule_node|
type = rule_node['type']
value = rule_node.content
rules << {:type => type, :value => value}
end
if post_url_node = node.at('postURL')
post_url = post_url_node.content
end
new(name, rules, :full_data => full_data, :post_url => post_url)
end
def Filter.from_xml(xml, options = {})
parse_xml(xml, options){|filter| return filter}
end
Attributes = []
Attributes << 'name'
def name
@name ||= nil
end
def name= value
@name = String(value)
ensure
raise ArgumentError, @name unless @name =~ %r/^[a-zA-Z0-9.+-]+$/
end
Attributes << 'post_url'
def post_url
@post_url ||= nil
end
def post_url= value
@post_url = String(value)
end
Attributes << 'rules'
def rules
@rules ||= List.of(Rule)
end
def rules= value
rules.replace(value)
end
Attributes << 'full_data'
def full_data
@full_data ||= nil
end
def full_data= value
@full_data = !!value
end
attr_accessor :publisher
def initialize(*args)
args, options = Gnip.args_for(args)
self.name = args.shift unless args.empty?
self.rules = args unless args.empty?
options.each{|key, value| send("#{ key }=", value)}
end
class Rule
def Rule.from_xml(xml, options = {})
parse_xml(xml, options){|rule| return rule}
end
def Rule.parse_xml(xml, options = {}, &block)
doc = Nokogiri::XML.parse(xml)
list = []
selectors = 'rule'
selectors.each do |selector|
search = doc.search(selector)
next unless search.size > 0
search.each do |node|
rule = Rule.from_node(node, options)
block ? block.call(rule) : list.push(rule)
end
end
block ? nil : list
end
def Rule.from_node(node, options = {})
type = node['type']
value = node.content
new(:type => type, :value => value)
end
def Rule.for(*args)
arg = args.first if args.size == 1
if Rule === arg
arg
elsif Hash === arg
new(arg)
else
new(*args)
end
end
attr_accessor :type
attr_accessor :value
def initialize(*args)
args, options = Gnip.args_for(args)
type = value = nil
case args.size
when 1
type, value = args.first.to_s.split(%r/:/, 2)
when 2
type, value = args
end
self.type = Publisher.rule.for options.getopt(:type, type)
self.value = options.getopt(:value, value)
end
def inspect
"#{ type }:#{ value }"
end
def to_s
inspect
end
def to_yaml(*a, &b)
to_s.to_yaml(*a, &b)
end
=begin
def Rule.template
@template ||=
Template.new do
"
>
<%= value %>
"
end
end
def to_xml(options = {})
Rule.template.expand(self)
end
=end
include Tagz
def to_xml(*args)
args, options = Gnip.args_for(args)
doc = args.shift
tagz(doc) {
rule_(:type => type){ value }
}
end
attr_accessor :filter
def resource
raise 'filter not set!' unless filter
rule = self
filter.publisher.filter.resource["filters/#{ filter.name }/rules?type=#{ rule.type }&value=#{ rule.value }"]
end
def delete(options = {})
Gnip.optify!(options)
filter = options.getopt(:filter, self.filter)
resource.delete
self
end
end
include Tagz
def to_xml(*args)
tagz {
filter_(:name => name, :fullData => !!full_data){
postURL_{ post_url } if post_url
rules.each do |rule|
rule_(:type => rule.type){ rule.value }
end
nil
}
}
end
=begin
def Filter.template
@template ||=
Template.new do
"
fullData=<%= (!!full_data).to_s.inspect %>>
% if post_url
<%= post_url %>
% end
% rules.each do |rule|
><%= rule.value %>
% end
"
end
end
def to_xml(options = {})
Filter.template.expand(self)
end
=end
def resource
raise 'publisher not set!' unless publisher
publisher.filter.resource["filters/#{ name }.xml"]
end
def get(*args, &block)
resource.get(*args, &block)
end
def delete(*args, &block)
resource.delete(*args, &block)
end
def put(*args, &block)
resource.put(*args, &block)
end
def post(*args, &block)
resource.post(*args, &block)
end
def replace(other)
put(other.to_xml)
publisher.filter.for(name)
end
def rule
@rule ||= RuleResource.new(self)
end
class RuleResource
attr_accessor :filter
def initialize filter
@filter = filter
end
def publisher
filter.publisher
end
def resource
publisher.resource
end
def list options = {}
Gnip.optify!(options)
type = options.getopt(:type) or raise 'no type'
value = options.getopt(:value) or raise 'no type'
xml = resource["filters/#{ filter.name }/rules?type=#{ type }&value=#{ value }"].get
rule = Rule.from_xml(xml)
rule.filter = filter
rule
end
def for(*args)
rule = Rule.for(*args)
list(:type => rule.type, :value => rule.value)
end
def delete options = {}
list(options).delete(:filter => filter)
end
def create(*rules)
rules = rules.map{|rule| Rule.for(rule)}
slices = [] and rules.each_slice(5000){|slice| slices << slice}
msg = slices.size > 1 ? 'threadify' : 'each'
slices.send(msg) do |slice|
xml = slice.map{|rule| rule.to_xml(:declaration => false)}.join
resource["filters/#{ filter.name }/rules"].post("#{ xml }")
end
rules.each{|rule| rule.filter = filter}
rules
end
end
end
end