ruben 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 09c93b25e4f051e816791d7c6d1f56132c8e916e
4
+ data.tar.gz: a0e138d4f441de54b04d4a35b3be5f866e76498f
5
+ SHA512:
6
+ metadata.gz: c385cdcbc386cd357aa000a7f75b84a8fbd8bf6d107e5a98f3511cc6a72e605031f1abf7ab11ec505a7c94e15ecf626318963ab2fc80a6957492a49e8ee054cd
7
+ data.tar.gz: 41131b1132fe46909a129bb2d1495aa0c5a07760f2206d8c46710343a393a4ad66ea63f2bebb38103c2e8779ee19e56c619cd169d189b1b7c57ac65121bc40d7
data/LICENSE CHANGED
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  THE SOFTWARE.
22
-
data/README.md CHANGED
@@ -4,32 +4,28 @@ Ruben
4
4
  [![Build Status](https://travis-ci.org/ericqweinstein/ruben.png)](https://travis-ci.org/ericqweinstein/ruben)
5
5
 
6
6
  ###Description
7
-
8
7
  Ruben is an IRC chat bot written in Ruby. He is inspired, in part, by [Hubot](http://hubot.github.com/), his CoffeeScript brother from another mother.
9
8
 
10
9
  ###Dependencies
11
-
12
- * Ruby 1.9.3 (not tested in Ruby 2.0)
13
- * Rake 10.0.3 (for running tests)
14
- * RSpec 2.12.2 (for running tests)
10
+ * Ruby 1.9.3+
11
+ * Rake 10.0.4 (for running tests, if that's your jam)
12
+ * RSpec 2.13.0 (see above)
15
13
 
16
14
  ###Installation
17
-
18
- Version 1.0.2 is available from RubyGems; you can get your version of Ruben by typing
15
+ Version 1.1.0 is available from RubyGems; you can get your version of Ruben by typing
19
16
 
20
17
  ```bash
21
18
  $ gem install ruben
22
19
  ```
23
20
 
24
21
  ###Getting Started
25
-
26
22
  Ruben comes with a `bin/ruben` executable, so you can run him with
27
23
 
28
24
  ```bash
29
25
  $ ruben <server> <port> <channel> <nick>
30
26
  ```
31
27
 
32
- Ruben takes a server name, port number, channel name, and nick as command line arguments. For example, if you type:
28
+ Ruben takes a server name, port number, channel name, and nick as command line arguments. For example, if you type:
33
29
 
34
30
  ```bash
35
31
  $ ruben irc.freenode.net 6667 test_chan ruben_
@@ -48,7 +44,6 @@ $ >> JOIN #test_chan
48
44
  You can get Ruben's usage information by typing `ruben -h` or `ruben --help`.
49
45
 
50
46
  ###Adding Scripts
51
-
52
47
  You can extend Ruben's functionality by adding scripts to `/scripts`. Each script should be a `.rb` file that instantiates a new `Listener` object, like so:
53
48
 
54
49
  ```ruby
@@ -60,4 +55,3 @@ Listener.new(/Regexp/, thing_to_do)
60
55
  ```
61
56
 
62
57
  Ruben's listeners hear every incoming IRC message. If a listener's Regexp matches the inbound message, Ruben will call the associated lambda.
63
-
data/Rakefile CHANGED
@@ -1,6 +1,41 @@
1
- require 'rake'
1
+ #!/usr/bin/env rake
2
+ # encoding: UTF-8
2
3
 
3
- task :default do
4
- sh "rspec"
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+ require 'yard'
7
+
8
+ task default: :help
9
+
10
+ desc 'Display help menu'
11
+ task :help do
12
+ puts <<-eos
13
+ Available Rake tasks:
14
+
15
+ rake help # Display help menu
16
+ rake rubocop # Lint
17
+ rake spec # Run tests
18
+ rake yard # Generate documentation
19
+ eos
20
+ end
21
+
22
+ desc 'Lint'
23
+ RuboCop::RakeTask.new(:rubocop) do |t|
24
+ t.patterns = %w(bin/**/* lib/**/*.rb)
25
+ end
26
+
27
+ desc 'Run tests'
28
+ task :spec do
29
+ RSpec::Core::RakeTask.new(:spec) do |task|
30
+ task.rspec_opts = ['--color --format d']
31
+ task.pattern = './spec/**/*_spec.rb'
32
+ end
5
33
  end
6
34
 
35
+ desc 'Generate documentation'
36
+ task :yard do
37
+ YARD::Rake::YardocTask.new do |t|
38
+ t.files = %w(bin/* lib/**/*.rb)
39
+ t.options = ['--protected', '--private']
40
+ end
41
+ end
data/bin/ruben CHANGED
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
2
4
 
3
- require "optparse"
4
- require_relative "../lib/robot"
5
-
6
- options = {}
5
+ require 'optparse'
6
+ require_relative '../lib/robot'
7
7
 
8
8
  opt_parser = OptionParser.new do |opts|
9
- opts.banner = "Usage: ruben SERVER PORT CHANNEL NICK"
10
- opts.separator ""
11
- opts.separator "Running Ruben:"
12
- opts.separator " SERVER is an IRC server (e.g. irc.freenode.net)."
13
- opts.separator " PORT is the IRC port (e.g. 6667)."
14
- opts.separator " CHANNEL is the IRC channel you want to join."
15
- opts.separator " NICK is the nickname you want Ruben to use."
16
- opts.separator ""
17
-
18
- opts.on("-h", "--help", "Display this screen") do
9
+ opts.banner = 'Usage: ruben SERVER PORT CHANNEL NICK'
10
+ opts.separator ''
11
+ opts.separator 'Running Ruben:'
12
+ opts.separator ' SERVER is an IRC server (e.g. irc.freenode.net).'
13
+ opts.separator ' PORT is the IRC port (e.g. 6667).'
14
+ opts.separator ' CHANNEL is the IRC channel you want to join.'
15
+ opts.separator ' NICK is the nickname you want Ruben to use.'
16
+ opts.separator ''
17
+
18
+ opts.on('-h', '--help', 'Display this screen') do
19
19
  puts opt_parser
20
20
  exit
21
21
  end
@@ -37,7 +37,6 @@ rescue SocketError => e
37
37
  end
38
38
 
39
39
  # Ensure Ruben leaves politely when ^C-ed
40
- trap("INT") { ruben.quit }
40
+ trap('INT') { ruben.quit }
41
41
 
42
42
  ruben.run
43
-
@@ -1,8 +1,20 @@
1
- require "socket"
2
- require "singleton"
3
- require_relative "robot/channel"
4
- require_relative "robot/listener"
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
3
+ require 'socket'
4
+ require 'singleton'
5
+ require_relative 'robot/channel'
6
+ require_relative 'robot/listener'
5
7
 
8
+ # Handles connection to the TCP socket and
9
+ # sending credentials as per the IRC protocol.
10
+ # @see http://tools.ietf.org/html/rfc2812
11
+ # @attr_reader [TCPSocket] socket A TCP socket.
12
+ # @attr [String] server An IRC server.
13
+ # @attr [Integer] port The port to connect to.
14
+ # @attr [String] channel The IRC channel to join.
15
+ # @attr [String] nick The robot's nickname.
16
+ # @attr [Array<Listener>] listeners A list
17
+ # of all registered listeners.
6
18
  class Robot
7
19
  include Singleton
8
20
  include Channel
@@ -11,24 +23,22 @@ class Robot
11
23
  attr_accessor :server, :port, :channel, :nick, :listeners
12
24
 
13
25
  def initialize
14
- @listeners = Listener.all_listeners
26
+ @listeners = Listener.listeners
15
27
  end
16
28
 
29
+ # The main event loop.
17
30
  def run
18
31
  begin
19
32
  @socket = TCPSocket.open(server, port)
20
- rescue
21
- puts "An error occurred. Make sure to call Ruben with a valid server and port name."
22
- exit
33
+ rescue => e
34
+ puts "An error occurred: #{e.message}"
35
+ exit 1
23
36
  end
24
37
 
25
- send "USER ruben 0 * :Ruben"
38
+ send 'USER ruben 0 * :Ruben'
26
39
  send "NICK #{@nick}"
27
40
  send "JOIN ##{@channel}"
28
41
 
29
- until @socket.eof? do
30
- listen
31
- end
42
+ listen until @socket.eof?
32
43
  end
33
44
  end
34
-
@@ -1,43 +1,51 @@
1
- require_relative "listener"
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
3
+ require_relative 'listener'
2
4
 
3
- # Load scripts
4
- Dir[File.dirname(__FILE__) + "/scripts/*.rb"].each { |script| require script }
5
+ # Load all our 'bot's scripts.
6
+ Dir[File.dirname(__FILE__) + '/scripts/*.rb'].each { |script| require script }
5
7
 
8
+ # Handles communcation with IRC.
6
9
  module Channel
10
+ # Things the robot might say when disconnecting.
11
+ PARTING_MESSAGES = ['bye', 'peace!', 'later', 'I\'m out']
7
12
 
8
- PARTING_MESSAGES = ["bye", "peace!", "later", "I'm out"]
9
-
13
+ # Sends a message to IRC.
14
+ # @param [String] msg The message to send.
10
15
  def send(msg)
11
16
  @socket.puts msg
12
- puts "<< " << msg
17
+ puts '<< ' << msg
13
18
  end
14
19
 
20
+ # Sends a message to users in the channel.
21
+ # @param [String] msg The message to say.
15
22
  def say(msg)
16
23
  send "PRIVMSG ##{@channel} :#{msg}"
17
24
  end
18
25
 
26
+ # Continuously listens to the socket
27
+ # for messages coming from either IRC
28
+ # or users in the channel.
19
29
  def listen
20
30
  @inbound = @socket.gets
21
- puts ">> " << @inbound
31
+ puts '>> ' << @inbound
22
32
 
23
- # Stay connected to the server
24
- if @inbound.match(/^PING (.*)$/)
25
- pong = $1
33
+ # Stay connected to the server.
34
+ if @inbound.match(/^PING (?<msg>.*)$/)
35
+ pong = Regexp.last_match[:msg]
26
36
  send "PONG #{pong}"
27
37
  end
28
38
 
29
- # Respond to messages in the channel
39
+ # Respond to messages in the channel.
30
40
  @listeners.each do |listener|
31
- if @inbound.match(listener.pattern)
32
- listener.response.call
33
- end
41
+ listener.response.call if @inbound.match listener.pattern
34
42
  end
35
43
  end
36
44
 
45
+ # Terminates the IRC connection.
37
46
  def quit
38
47
  say "#{PARTING_MESSAGES.sample}"
39
48
  send "PART ##{@channel} :mic drop"
40
- send "QUIT"
49
+ send 'QUIT'
41
50
  end
42
51
  end
43
-
@@ -1,16 +1,31 @@
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
3
+
4
+ # Collects and initalizes
5
+ # listeners from all our scripts.
6
+ # @attr [RegExp] pattern A pattern against
7
+ # which to match incoming messages.
8
+ # @attr [String] response The response to
9
+ # provide if the RegExp matches.
1
10
  class Listener
2
11
  attr_accessor :pattern, :response
3
12
 
4
- @@listeners = []
5
-
13
+ @listeners = []
14
+
6
15
  def initialize(pattern, response)
7
- @@listeners << self
8
- @pattern = pattern
16
+ self.class.add_listener(self)
17
+ @pattern = pattern
9
18
  @response = response
10
19
  end
11
20
 
12
- def self.all_listeners
13
- @@listeners
21
+ class << self
22
+ attr_reader :listeners
23
+
24
+ # Adds a listener object to the class'
25
+ # list of listeners.
26
+ # @param [Listener] listener A listener to add.
27
+ def add_listener(listener)
28
+ @listeners << listener
29
+ end
14
30
  end
15
31
  end
16
-
@@ -1,8 +1,10 @@
1
- # MAXIMUM WARP
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
2
3
 
4
+ # Provides a random warp factor whenever
5
+ # the robot hears the word 'engage'.
3
6
  warp_factor = lambda do
4
7
  Robot.instance.say "WARP FACTOR #{rand(9) + 1}"
5
8
  end
6
9
 
7
10
  Listener.new(/ :\bengage\b/i, warp_factor)
8
-
@@ -1,11 +1,13 @@
1
- # Heads I win, tails you lose
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
2
3
 
4
+ # The robot flips a coin when
5
+ # it hears 'flip a coin'.
3
6
  flip_coin = lambda do
4
7
  coin_flip = rand(2)
5
- result = coin_flip == 1 ? "heads" : "tails"
8
+ result = coin_flip == 1 ? 'heads' : 'tails'
6
9
 
7
10
  Robot.instance.say "#{result}!"
8
11
  end
9
12
 
10
13
  Listener.new(/ :(?:(?:ruben)?,?\s*flip\s*(?:a)?\s*coin)/i, flip_coin)
11
-
@@ -1,9 +1,11 @@
1
- # Friendly robots are good robots
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
2
3
 
4
+ # The robot says hello when greeted
5
+ # with any of the greetings.
3
6
  say_hello = lambda do
4
- greetings = ["sup", "hey", "what up", "sup g"]
7
+ greetings = ['sup', 'hey', 'what up', 'sup g']
5
8
  Robot.instance.say "#{greetings.sample}"
6
9
  end
7
10
 
8
11
  Listener.new(/ :(?:hi|hello|hey)\s*,?\s*(?:ruben)/i, say_hello)
9
-
@@ -1,9 +1,11 @@
1
- # Polite robots are good robots
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
2
3
 
4
+ # The robot tells you you're welcome
5
+ # when it hears 'thanks', 'ty', &c.
3
6
  youre_welcome = lambda do
4
- responses = ["no prob", "sure thing", "np boss"]
7
+ responses = ['no prob', 'sure thing', 'np boss']
5
8
  Robot.instance.say "#{responses.sample}"
6
9
  end
7
-
8
- Listener.new(/ :(?:thanks|ty|thank\s*you),?\s*(?:ruben)/i, youre_welcome)
9
10
 
11
+ Listener.new(/ :(?:thanks|ty|thank\s*you),?\s*(?:ruben)/i, youre_welcome)
@@ -1,5 +1,8 @@
1
- # Ruben's a gamblin' man
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
2
3
 
4
+ # The robot rolls a D6 whenever
5
+ # it hears 'roll the dice'.
3
6
  roll_dice = lambda do
4
7
  lucky_number = rand(5) + 1
5
8
 
@@ -7,4 +10,3 @@ roll_dice = lambda do
7
10
  end
8
11
 
9
12
  Listener.new(/ :(?:(?:ruben)?,?\s*roll\s*(?:the)?\s*dice)/i, roll_dice)
10
-
@@ -1,11 +1,14 @@
1
- # Teaching Ruben to tell time
1
+ # encoding: UTF-8
2
+ # @author Eric Weinstein <eric.q.weinstein@gmail.com>
2
3
 
4
+ # The robot tells you what time it
5
+ # is when it hears 'what time'.
3
6
  what_time = lambda do
4
- current_hour = Time.now.localtime.strftime("%H").to_i
7
+ current_hour = Time.now.localtime.strftime('%H').to_i
5
8
  current_hour = current_hour > 12 ? current_hour - 12 : current_hour
6
9
 
7
- Robot.instance.say "I dunno, around #{Time.now.localtime.strftime("#{current_hour}:%M %p")}"
10
+ Robot.instance.say "I dunno, around #{Time
11
+ .now.localtime.strftime("#{current_hour}:%M %p")}"
8
12
  end
9
13
 
10
14
  Listener.new(/ :(?:what\s*time)/i, what_time)
11
-
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruben
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
5
- prerelease:
4
+ version: 1.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Eric Weinstein
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-11 00:00:00.000000000 Z
11
+ date: 2014-06-23 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: Ruben is an IRC chat bot written in Ruby. He is inspired, in part, by
15
14
  Hubot, his CoffeeScript brother from another mother.
@@ -35,27 +34,26 @@ files:
35
34
  - Rakefile
36
35
  homepage: http://github.com/ericqweinstein/ruben
37
36
  licenses: []
37
+ metadata: {}
38
38
  post_install_message:
39
39
  rdoc_options: []
40
40
  require_paths:
41
41
  - lib
42
42
  required_ruby_version: !ruby/object:Gem::Requirement
43
- none: false
44
43
  requirements:
45
- - - ! '>='
44
+ - - '>='
46
45
  - !ruby/object:Gem::Version
47
46
  version: '0'
48
47
  required_rubygems_version: !ruby/object:Gem::Requirement
49
- none: false
50
48
  requirements:
51
- - - ! '>='
49
+ - - '>='
52
50
  - !ruby/object:Gem::Version
53
51
  version: '0'
54
52
  requirements: []
55
53
  rubyforge_project:
56
- rubygems_version: 1.8.25
54
+ rubygems_version: 2.0.14
57
55
  signing_key:
58
- specification_version: 3
56
+ specification_version: 4
59
57
  summary: An extensible IRC chat bot.
60
58
  test_files: []
61
59
  has_rdoc: