module Gnip class Publisher def Publisher.list(options = {}) options = Gnip.optify!(options) scope = options.getopt(:scope, Gnip.scope) resource = options.getopt(:resource, Gnip.default.resource) endpoint = resource.endpoint "#{ scope }/publishers.xml" response = endpoint.get xml = response.to_s Publisher.list_from_xml(xml, :scope => scope) end def Publisher.list_from_xml(xml, options = {}, &block) list = [] parse_xml(xml, options) do |publisher| block ? block.call(publisher) : list.push(publisher) end block ? nil : list end def Publisher.from_xml(xml, options = {}, &block) parse_xml(xml, options){|publisher| return publisher} end def Publisher.parse_xml(xml, options = {}, &block) doc = Nokogiri::XML.parse(xml) list = [] selectors = '*/publishers', 'publisher' selectors.each do |selector| search = doc.search(selector) next unless search.size > 0 search.each do |node| publisher = Publisher.from_node(node, options) block ? block.call(publisher) : list.push(publisher) end end block ? nil : list end def Publisher.from_node(node, options = {}) name = node['name'] rules = node.search('supportedRuleTypes/type').map{|type| type.content} Publisher.new(name, options.update(:rules => rules)) end def Publisher.for name, options = {} options = Gnip.optify!(options) scope = options.getopt(:scope, Gnip.scope) resource = options.getopt(:resource, Gnip.default.resource) endpoint = resource["#{ scope }/publishers/#{ name }.xml"] response = endpoint.get xml = response.to_s publisher = Publisher.from_xml(xml) publisher.scope = scope publisher end def Publisher.exists?(*args, &block) Publisher.for(*args, &block) rescue false end def Publisher.resource @resource ||= Gnip.default.resource end def Publisher.create(*args, &block) publisher = new(*args, &block) resource = Publisher.resource["#{ publisher.scope }/publishers.xml"] resource.post(publisher.to_xml(:declaration => true)) Publisher.for(publisher.name, :scope => publisher.scope) end def Publisher.delete(name, options = {}) if publisher = Publisher.exists?(name, options) publisher.delete end 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 << 'rules' def rules @rules ||= List.of(String) end def rules= value rules.replace(value) end attr_accessor :scope def initialize(*args) args, options = Gnip.args_for(args) self.name = args.shift if args.first @scope = options.getopt(:scope, Gnip.scope).to_s @resource = options.getopt(:resource, Gnip.default.resource) rules = options.getopt(:rules, []).flatten.compact @rules = rules.map{|rule| Rule.for(rule)} end def resource @resource["#{ scope }/publishers/#{ name }"] end class Rule < ::String List = [] %w[ actor tag to regarding source keyword ].each do |name| module_eval <<-code def Rule.#{ name } @#{ name } ||= Rule.new('#{ name }').freeze end code List << Rule.send(name) end List.freeze def Rule.list List end def Rule.for(name) send(name.to_s.downcase.strip) rescue raise ArgumentError, "bad rule type #{ name.inspect }" end def Rule.[] name Rule.for(name) end end def Publisher.rule Rule end include Tagz def to_xml(*args) args, options = Gnip.args_for(args) doc = args.first tagz(doc) { publisher_(:name => name){ supportedRuleTypes_{ rules.each{|rule| type_{ rule }} } } } end =begin def Publisher.template @template ||= Template.new do " > % rules.each do |rule| <%= rule %> % end " end end def to_xml(options = {}) Publisher.template.expand(self) end =end def delete Publisher.resource["#{ scope }/publishers/#{ name }"].delete self end def activity_stream options = {} Activity.stream(options.update(:publisher => self, :scope => scope)) end def activity options = {}, &block Gnip.optify!(options) style = options.getopt(:style, 'activity').to_s raise ArgumentError unless %w( activity notification ).include?(style) bucket = options.getopt(:bucket) ago = options.getopt(:ago) thru = options.getopt(:thru, options.getopt(:through)) if Range === ago ago, thru = [ago.begin, ago.end].sort.reverse end unless bucket bucket = ago ? bucket_for_minutes_ago(ago) : 'current' end filter = options.getopt(:filter) filter = filter.value if(filter and filter.respond_to?(:value)) filter = filter.name if(filter and filter.respond_to?(:name)) buckets = if thru thru = 0 if thru =~ /current|now/i a, b = [ago, Integer(thru)].sort (a..b).to_a.reverse.map{|i| bucket_for_minutes_ago(i)} else if bucket =~ /all/i stream = send("#{ style }_stream") stream.buckets.map{|bucket| File.basename(bucket, '.xml')} else [bucket] end end buckets.map! do |bucket| bucket.is_a?(Time) ? bucket.strftime('%Y%m%d%H%M') : bucket end activities = [] msg = buckets.size > 1 ? 'threadify' : 'each' buckets.send(msg) do |bucket| path = "#{ style }/#{ bucket }.xml" path = "filters/#{ filter }/#{ path }" if filter xml = resource[path].get Activity.list_from_xml(xml) do |activity| activity.gnip_resource_uri = resource[path].uri block ? block.call(activity) : activities.push(activity) end end activities unless block end def bucket_for_minutes_ago ago bucket = Gnip.time - (Integer(ago) * 60) bucket.strftime('%Y%m%d%H%M') end def notification_stream options = {} Activity.stream(options.update(:publisher => self, :scope => scope, :style => 'notification')) end def notifications options = {} Gnip.optify!(options) options.setopt!(:style, 'notification') unless options.hasopt?(:style) activity(options) end def publish *activities activities.flatten! activities.compact! #xml = "#{ activities.map{|activity| activity.to_xml} }" xml = tagz { activities_{ activities.map{|activity| activity.to_xml(tagz.doc)} } } resource['activity.xml'].post(xml) activities end def filter @filter ||= FilterResource.new(self) end class FilterResource attr_accessor :publisher def initialize publisher @publisher = publisher end def resource publisher.resource end def list xml = resource['filters.xml'].get Filter.list_from_xml(xml).each{|filter| filter.publisher = publisher} end def for name xml = resource["filters/#{ name }.xml"].get filter = Filter.from_xml(xml) ensure filter.publisher = publisher if filter end alias_method '[]', 'for' def create(name, rules, options) Gnip.optify!(options) filter = Filter.new(name, rules, options) resource['filters.xml'].post(filter.to_xml(:declaration => true)) filter = self.for(name) ensure filter.publisher = publisher if filter end end end end