twibot 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.1.5 / 2009-04-12
2
+
3
+ * Added support for regular expression routes
4
+ * Make timeline_for option configurable, ie in config: timeline_for: :public
5
+ * Fixed bug: Users where unlawfully rejected when their screen name started with
6
+ a capital letter (Wilco)
7
+ * Fixed bug: Twibot crashed if there were no handlers registered
8
+
1
9
  == 0.1.4 / 2009-03-24
2
10
 
3
11
  * Removed some warnings
data/Readme.rdoc CHANGED
@@ -1,6 +1,7 @@
1
1
  = Twibot
2
2
  Official URL: http://github.com/cjohansen/twibot/tree/master
3
3
  Christian Johansen (http://www.cjohansen.no)
4
+ Twitter: @cjno
4
5
 
5
6
  == Description
6
7
 
@@ -87,6 +88,16 @@ to match incoming tweets and messages:
87
88
  You can have several "tweet" blocks (or "message" or "reply"). The first one to
88
89
  match an incoming tweet/message will handle it.
89
90
 
91
+ As of the upcoming 0.1.5/0.2.0, Twibot also supports regular expressions as routes:
92
+
93
+ require 'twibot'
94
+
95
+ tweet /^time ([^\s]*) ([^\s]*)/ do |message, params|
96
+ # params is an array of matches when using regexp routes
97
+ time = MyTimeService.lookup(params[0], params[1])
98
+ client.message :post, "Time is #{time} in #{params[:city]}, #{params[:country]}"
99
+ end
100
+
90
101
  === Working with the Twitter API
91
102
 
92
103
  The DSL gives you access to your Twitter client instance through "client" (or "twitter"):
@@ -121,10 +132,10 @@ make 20.000 reqs/hour, and shouldn't be a problem so long as your intentions are
121
132
  (I think).
122
133
 
123
134
  Twibot polls like this:
124
- * Poll messages if any message handlers exist
125
- * Poll tweets if any tweet or reply handlers exist
126
- * Sleep for +interval+ seconds
127
- * Go over again
135
+ * Poll messages if any message handlers exist
136
+ * Poll tweets if any tweet or reply handlers exist
137
+ * Sleep for +interval+ seconds
138
+ * Go over again
128
139
 
129
140
  As long as Twibot finds any messages and/or tweets, the interval stays the same
130
141
  (min_interval configuration switch). If nothing was found however, the interval to
@@ -133,9 +144,10 @@ reaches max_interval, where it will stay until Twibot finds anything.
133
144
 
134
145
  == Contributors
135
146
 
136
- * Dan Van Derveer (bug fixes) - http://dan.van.derveer.com/
137
- * Ben Vandgrift (Twitter downtime error handling) - http://neovore.com/
138
- * Jens Ohlig (warnings)
147
+ * Dan Van Derveer (bug fixes) - http://dan.van.derveer.com/
148
+ * Ben Vandgrift (Twitter downtime error handling) - http://neovore.com/
149
+ * Jens Ohlig (warnings)
150
+ * Wilco van Duinkerken (bug fixes) - http://www.sparkboxx.com/
139
151
 
140
152
  == License
141
153
 
data/lib/twibot.rb CHANGED
@@ -7,7 +7,7 @@ require File.join(File.dirname(__FILE__), 'hash')
7
7
  module Twibot
8
8
 
9
9
  # :stopdoc:
10
- VERSION = '0.1.4'
10
+ VERSION = '0.1.5'
11
11
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
12
12
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
13
13
  # :startdoc:
data/lib/twibot/bot.rb CHANGED
@@ -47,14 +47,16 @@ module Twibot
47
47
  messages = @twitter.messages(:received, { :count => 1 })
48
48
  @processed[:message] = messages.first.id if messages.length > 0
49
49
 
50
- handle_tweets = @handlers[:tweet].length + @handlers[:reply].length > 0
50
+ handle_tweets = !@handlers.nil? && @handlers[:tweet].length + @handlers[:reply].length > 0
51
51
  tweets = []
52
+
52
53
  begin
53
- tweets = handle_tweets ? @twitter.timeline_for(:me, { :count => 1 }) : []
54
+ tweets = handle_tweets ? @twitter.timeline_for(@config.to_hash[:timeline_for], { :count => 1 }) : []
54
55
  rescue Twitter::RESTError => e
55
56
  log.error("Failed to connect to Twitter. It's likely down for a bit:")
56
- log.error(e.to_s)
57
+ log.error(e.to_s)
57
58
  end
59
+
58
60
  @processed[:tweet] = tweets.first.id if tweets.length > 0
59
61
  @processed[:reply] = tweets.first.id if tweets.length > 0
60
62
 
@@ -94,8 +96,8 @@ module Twibot
94
96
  dispatch_messages(type, @twitter.messages(:received, options), %w{message messages})
95
97
  rescue Twitter::RESTError => e
96
98
  log.error("Failed to connect to Twitter. It's likely down for a bit:")
97
- log.error(e.to_s)
98
- 0
99
+ log.error(e.to_s)
100
+ 0
99
101
  end
100
102
  end
101
103
 
@@ -108,13 +110,11 @@ module Twibot
108
110
  options = {}
109
111
  options[:since_id] = @processed[type] if @processed[type]
110
112
  begin
111
- dispatch_messages(type,
112
- @twitter.timeline_for(config[:include_friends] ? :friends : :me,
113
- options), %w{tweet tweets})
113
+ dispatch_messages(type, @twitter.timeline_for(@config.to_hash[:timeline_for], options), %w{tweet tweets})
114
114
  rescue Twitter::RESTError => e
115
115
  log.error("Failed to connect to Twitter. It's likely down for a bit:")
116
- log.error(e.to_s)
117
- 0
116
+ log.error(e.to_s)
117
+ 0
118
118
  end
119
119
  end
120
120
 
@@ -130,10 +130,10 @@ module Twibot
130
130
  dispatch_messages(type, @twitter.status(:replies, options), %w{reply replies})
131
131
  rescue Twitter::RESTError => e
132
132
  log.error("Failed to connect to Twitter. It's likely down for a bit:")
133
- log.error(e.to_s)
134
- 0
133
+ log.error(e.to_s)
134
+ 0
135
135
  end
136
-
136
+
137
137
  end
138
138
 
139
139
  #
data/lib/twibot/config.rb CHANGED
@@ -29,7 +29,8 @@ module Twibot
29
29
  :password => nil,
30
30
  :prompt => false,
31
31
  :daemonize => false,
32
- :include_friends => false
32
+ :include_friends => false,
33
+ :timeline_for => :public
33
34
  }
34
35
 
35
36
  def initialize(settings = {})
@@ -50,6 +50,11 @@ module Twibot
50
50
  def pattern=(pattern)
51
51
  return if pattern.nil? || pattern == ""
52
52
 
53
+ if pattern.is_a?(Regexp)
54
+ @options[:pattern] = pattern
55
+ return
56
+ end
57
+
53
58
  words = pattern.split.collect { |s| s.strip } # Get all words in pattern
54
59
  @options[:tokens] = words.inject([]) do |sum, token| # Find all tokens, ie :symbol :like :names
55
60
  next sum unless token =~ /^:.*/ # Don't process regular words
@@ -70,7 +75,7 @@ module Twibot
70
75
 
71
76
  users = @options[:from] ? @options[:from] : nil
72
77
  sender = message.respond_to?(:sender) ? message.sender : message.user
73
- return false if users && !users.include?(sender.screen_name) # Check allowed senders
78
+ return false if users && !users.include?(sender.screen_name.downcase) # Check allowed senders
74
79
  true
75
80
  end
76
81
 
@@ -82,10 +87,12 @@ module Twibot
82
87
  return unless recognize?(message)
83
88
  @params = {}
84
89
 
85
- if @options[:pattern]
90
+ if @options[:pattern] && @options[:tokens]
86
91
  matches = message.text.match(@options[:pattern])
87
92
  @options[:tokens].each_with_index { |token, i| @params[token] = matches[i+1] }
88
93
  @params[:text] = (matches[@options[:tokens].length+1] || "").strip
94
+ elsif @options[:pattern] && !@options[:tokens]
95
+ @params = message.text.match(@options[:pattern]).to_a[1..-1] || []
89
96
  else
90
97
  @params[:text] = message.text
91
98
  end
data/test/test_bot.rb CHANGED
@@ -116,6 +116,11 @@ class TestBot < Test::Unit::TestCase
116
116
  Twitter::Client.any_instance.expects(:status).with(:replies, { :since_id => 1 }).returns([])
117
117
  assert_equal 0, bot.receive_replies
118
118
  end
119
+
120
+ should "use public as default timeline method for tweet 'verb'" do
121
+ bot = Twibot::Bot.new(Twibot::Config.default)
122
+ assert_equal :public, bot.instance_eval { @config.to_hash[:timeline_for] }
123
+ end
119
124
  end
120
125
 
121
126
  class TestBotMacros < Test::Unit::TestCase
data/test/test_handler.rb CHANGED
@@ -126,6 +126,12 @@ class TestHandler < Test::Unit::TestCase
126
126
  message = tweet "cjno", "time oslo norway"
127
127
  assert handler.recognize?(message)
128
128
  end
129
+
130
+ should "recognize tweets from allowed users with capital screen names" do
131
+ handler = Twibot::Handler.new :from => [:cjno, :irbno]
132
+ message = tweet "Cjno", "time oslo norway"
133
+ assert handler.recognize?(message)
134
+ end
129
135
 
130
136
  should "accept options as only argument" do
131
137
  handler = Twibot::Handler.new :from => :cjno
@@ -144,7 +150,7 @@ class TestHandler < Test::Unit::TestCase
144
150
  handler.dispatch(message)
145
151
  end
146
152
 
147
- should "should call constructor block from handle" do
153
+ should "call constructor block from handle" do
148
154
  handler = Twibot::Handler.new("time :city :country", :from => ["cjno", "irbno"]) do |message, params|
149
155
  raise "Boom!"
150
156
  end
@@ -153,4 +159,33 @@ class TestHandler < Test::Unit::TestCase
153
159
  handler.handle(nil, nil)
154
160
  end
155
161
  end
162
+
163
+ should "recognize regular expressions" do
164
+ handler = Twibot::Handler.new /(?:what|where) is (.*)/i
165
+ message = twitter_message "dude", "Where is this shit?"
166
+ assert handler.recognize?(message)
167
+
168
+ message = twitter_message "dude", "How is this shit?"
169
+ assert !handler.recognize?(message)
170
+ end
171
+
172
+ should "recognize regular expressions from specific users" do
173
+ handler = Twibot::Handler.new /(?:what|where) is (.*)/i, :from => "cjno"
174
+ message = twitter_message "dude", "Where is this shit?"
175
+ assert !handler.recognize?(message)
176
+
177
+ message = twitter_message "cjno", "Where is this shit?"
178
+ assert handler.recognize?(message)
179
+ end
180
+
181
+ should "provide parameters as arrays when matching regular expressions" do
182
+ handler = Twibot::Handler.new(/time ([^\s]*) ([^\s]*)/) do |message, params|
183
+ assert_equal "oslo", params[0]
184
+ assert_equal "norway", params[1]
185
+ end
186
+
187
+ message = twitter_message "cjno", "time oslo norway"
188
+ assert handler.recognize?(message)
189
+ handler.dispatch(message)
190
+ end
156
191
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twibot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Johansen
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-24 00:00:00 +01:00
12
+ date: 2009-04-12 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency