<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,5 @@
+v0.8.3. Added support for broadcasting Twitter (Summize) search results and other RSS feed results to Campfire. 
+
 v0.8.2. Attempt automatic Twitter reconnects. 
 
 v0.8.1. Use standard logger.  Bot class restructured.  Better error handling.  Better Campfire spam protection.</diff>
      <filename>CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -6,9 +6,11 @@ require 'echoe'
 
 Echoe.new('camptweet') do |p|
   p.author = &quot;Brian Dainton&quot;
-  p.summary = &quot;A simple daemon that polls for updated Twitter statuses and posts them to a Campfire room.&quot;
+  p.summary = &quot;A simple daemon that polls for updated Twitter statuses, 
+    Twitter search results, and RSS/Atom feed content and posts 
+    them to a Campfire room.&quot;
   p.url = &quot;http://github.com/bdainton/camptweet&quot;
-  p.dependencies = [&quot;twitter4r &gt;=0.3.0&quot;, &quot;tinder &gt;=0.1.6&quot;]
+  p.dependencies = [&quot;twitter4r &gt;=0.3.0&quot;, &quot;tinder &gt;=0.1.6&quot;, &quot;simple-rss&quot;]
 end
 
 </diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -4,8 +4,10 @@ require 'camptweet'
 
 Camptweet::Bot.new do |camptweet|
   camptweet.twitter_users = ['bdainton']
+  camptweet.twitter_search_terms = ['fiveruns']
+  camptweet.feed_urls = ['http://github.com/repositories.atom']
   camptweet.campfire_subdomain = 'mycompany'
-  camptweet.campfire_use_ssl = true  
+  camptweet.campfire_use_ssl = true
   camptweet.campfire_room = 'Room Name'  
   camptweet.campfire_email = 'foo@mycompany.com'
   camptweet.campfire_password = 'foo_password'</diff>
      <filename>bin/camptweetd_base</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,8 @@ require 'active_support'
 require 'time'
 require 'twitter'
 require 'tinder'
+require 'simple-rss'
+require 'open-uri'
 
 Dir[File.join(File.dirname(__FILE__), 'camptweet/**/*.rb')].sort.each { |lib| require lib }
 </diff>
      <filename>lib/camptweet.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,8 @@ module Camptweet
   class Bot
     
     attr_accessor :twitter_users
+    attr_accessor :twitter_search_terms
+    attr_accessor :feed_urls
     attr_accessor :campfire_subdomain
     attr_accessor :campfire_use_ssl    
     attr_accessor :campfire_room
@@ -13,7 +15,8 @@ module Camptweet
   
     def initialize(&amp;block)
       yield self if block_given?
-      init_log      
+      init_log
+      add_twitter_search_urls_to_feed_urls
       connect_to_twitter
       connect_to_campfire
       login_to_campfire
@@ -21,35 +24,46 @@ module Camptweet
     end
   
     def run
-      last_statuses = initial_statuses
+      last_statuses = {}
+      last_feed_items = {}
       
       loop do
         begin
           new_statuses = []
+          new_feed_items = []
+          
+          # check for updated tweets
           checking_twitter_timelines do |user, status|
             if last_statuses[user].nil?
-              # Only broadcast this tweet if we have an initial status against
-              # which we can compare it.
               last_statuses[user] = status
             elsif status.created_at &gt; last_statuses[user].created_at
-              # Only consider the most recent tweet.
               new_statuses &lt;&lt; status
               last_statuses[user] = status
             end
           end
-              
+          
+          # post any updated tweets to campfire
           new_statuses.sort_by(&amp;:created_at).each do |status|
             begin
-              message = &quot;[#{status.user.name}] #{status.text}&quot;
-              log.info message
-              room.speak message
-              log.debug &quot;(Campfire updated)&quot;
+              send_message_to_campfire &quot;[#{status.user.name}] #{status.text}&quot;
             rescue Timeout::Error =&gt; e
               log.info &quot;Campfire timeout: (#{e.message})&quot;
             ensure
               sleep 2
             end
           end
+          
+          # check for updated rss feed items and post them to campfire
+          checking_feeds do |feed_url, feed, item|
+            log.debug &quot;...checking last_feed_item for this feed: #{last_feed_items[feed_url].blank? ? 'no item' : last_feed_items[feed_url].title}&quot;
+            if last_feed_items[feed_url].blank?
+              last_feed_items[feed_url] = item
+            elsif timestamp_for(item) &gt; timestamp_for(last_feed_items[feed_url])
+              last_feed_items[feed_url] = item
+              send_message_to_campfire feed_item_message_for(feed, item)
+            end          
+          end
+              
         rescue =&gt; e
           log.error e.message
           log.error e.backtrace
@@ -61,6 +75,18 @@ module Camptweet
       end
     end
     
+    def twitter_users
+      @twitter_users ||= []
+    end
+    
+    def twitter_search_terms
+      @twitter_search_terms ||= []
+    end
+    
+    def feed_urls
+      @feed_urls ||= []
+    end
+    
     private
     
     def connect_to_twitter
@@ -109,14 +135,6 @@ module Camptweet
       verbose
     end
     
-    def initial_statuses
-      returning statuses = {} do
-        checking_twitter_timelines do |user, status|
-          statuses[user] = status
-        end
-      end
-    end
-    
     def checking_twitter_timelines
       twitter_users.each do |user|
         begin
@@ -137,6 +155,56 @@ module Camptweet
         end
       end
     end
+    
+    def checking_feeds
+      feed_urls.each do |feed_url|
+        begin
+          log.debug &quot;Checking '#{feed_url}'...&quot;
+          rss = SimpleRSS.parse(open(feed_url))
+          if rss.items.blank?
+            log.debug &quot;No items in this RSS feed.&quot;
+            next
+          end
+          item = rss.items.first
+          log.debug &quot;First item has title #{item.title} with timestamp #{timestamp_for(item)}&quot;
+          yield feed_url, rss, item
+        rescue =&gt; e
+          log.error &quot;Error in parsing feed: (#{e.message})&quot;
+          log.error e.backtrace
+        ensure
+          log.debug &quot;   ...done.&quot;
+          sleep 2
+        end
+      end
+    end
+    
+    def timestamp_for(feed_item)
+      return feed_item.published if feed_item.published
+      return feed_item.pubDate if feed_item.pubDate
+      return feed_item.updated if feed_item.updated
+      return feed_item.dc_date if feed_item.dc_date        
+      log.debug &quot;Couldn't find a date for feed item #{feed_item.inspect}&quot;      
+    end
+    
+    def send_message_to_campfire(message)
+      begin
+        log.info message
+        room.speak message
+        log.debug &quot;(Campfire updated)&quot;
+      rescue Timeout::Error =&gt; e
+        log.info &quot;Campfire timeout: (#{e.message})&quot;
+      end
+    end
+    
+    def feed_item_message_for(feed, item)
+      &quot;[#{feed.title}] #{item.title} (#{item.author}): #{item.link}&quot;
+    end
+      
+    def add_twitter_search_urls_to_feed_urls
+      twitter_search_terms.each do |search_term|
+        feed_urls &lt;&lt; &quot;http://summize.com/search.atom?q=#{search_term}&quot;
+      end
+    end
 
   end
 end
\ No newline at end of file</diff>
      <filename>lib/camptweet/bot.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>f490e0bdc8fd47e8581dea369f6b28709311395d</id>
    </parent>
  </parents>
  <author>
    <name>Brian Dainton</name>
    <email>brian.dainton@gmail.com</email>
  </author>
  <url>http://github.com/bdainton/camptweet/commit/fe5a83623bf8d5443cf7cd00ecf3daa4301b3fcd</url>
  <id>fe5a83623bf8d5443cf7cd00ecf3daa4301b3fcd</id>
  <committed-date>2008-06-29T21:34:31-07:00</committed-date>
  <authored-date>2008-06-29T21:34:31-07:00</authored-date>
  <message>Added capability to broadcast updated RSS/Atom feed items to Campfire.  Baked in (Summize-based) Twitter search on top of this.</message>
  <tree>76a9ab16fa4903e5ef1abc590c1dc351a525fc62</tree>
  <committer>
    <name>Brian Dainton</name>
    <email>brian.dainton@gmail.com</email>
  </committer>
</commit>
