erasmus 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar
5
+ 14 rue de Plaisance, 75014 Paris, France
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ = erasmus
2
+
3
+ A simple, modular irc bot/framework.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but
13
+ bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2009 xiongchiamiov. See LICENSE for details.
data/lib/bots.rb ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'erasmus'
4
+ require 'utils'
5
+
6
+ Erasmus::Bot.new("irc.freenode.net").join([
7
+ Erasmus::Channel.new('erasmus-testing') \
8
+ .extend(Utils::Foo) \
9
+ .extend(Utils::Changelog) \
10
+ .extend(Utils::FlagFloodProtection), \
11
+ Erasmus::Channel.new('erasmus-testing2'),
12
+ ]).run
data/lib/erasmus.rb ADDED
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'socket'
4
+
5
+ module Erasmus
6
+ class Bot
7
+ attr_reader :nick
8
+
9
+ def initialize(server, port=6667)
10
+ @nick = 'mpu_test'
11
+ @channels = {}
12
+ @socket = TCPSocket.open(server, port)
13
+ say "NICK #{@nick}"
14
+ say "USER #{@nick} 0 * #{@nick}"
15
+ end
16
+
17
+ def join(channels)
18
+ channels.each do |channel|
19
+ channel.server = self
20
+ channel.join
21
+ @channels[channel.name] = channel
22
+ end
23
+
24
+ #return self so we can chain methods
25
+ self
26
+ end
27
+
28
+ def say(msg)
29
+ puts msg
30
+ @socket.puts msg
31
+ end
32
+
33
+ def say_to_channel(channel, message)
34
+ say "PRIVMSG ##{channel} :#{message}"
35
+ end
36
+
37
+ def pm_user(user, message)
38
+ say "PRIVMSG #{user} :#{message}"
39
+ end
40
+
41
+ def notice_user(user, message)
42
+ say "NOTICE #{user} :#{message}"
43
+ end
44
+
45
+ def notice_channel(channel, message)
46
+ say "NOTICE ##{channel} :#{message}"
47
+ end
48
+
49
+ def run
50
+ until @socket.eof? do
51
+ msg = @socket.gets
52
+ puts msg
53
+
54
+ case msg
55
+ when /^PING :(.*)$/
56
+ say "PONG #{$1}"
57
+ # channel messages
58
+ when /^:(.*)!(.*) PRIVMSG #(\S+) :(.*)$/
59
+ user = $1
60
+ host = $2
61
+ channel = $3
62
+ content = $4
63
+ @channels[channel].handle_public_message(user, host, content)
64
+ # actual private messages
65
+ when /^:(.*)!(.*) PRIVMSG \S+ :(.*)$/
66
+ user = $1
67
+ host = $2
68
+ content = $3
69
+ handle_private_message(user, host, content)
70
+ end
71
+ end
72
+ end
73
+
74
+ def handle_private_message(user, host, message)
75
+ pm_user(user, 'hey!')
76
+ end
77
+
78
+ def quit
79
+ @channels.each do |name, channel|
80
+ channel.part
81
+ end
82
+ say 'QUIT'
83
+ end
84
+ end
85
+
86
+ class Channel
87
+ attr_accessor :server
88
+ attr_reader :name
89
+
90
+ def initialize(channel, flag='!')
91
+ @name = channel
92
+ @flag = flag
93
+
94
+ @flags = {}
95
+ @blacklists = []
96
+ end
97
+
98
+ def join
99
+ @server.say "JOIN ##{@name}"
100
+ end
101
+
102
+ def part(message='Bai~')
103
+ @server.say "PART ##{@name} :#{message}"
104
+ end
105
+
106
+ def say(message)
107
+ @server.say_to_channel(@name, message)
108
+ end
109
+
110
+ def hilight_user(user, message)
111
+ @server.say_to_channel(@name, "#{user}: #{message}")
112
+ end
113
+
114
+ def notice_user(user, message)
115
+ @server.notice_user(user, message)
116
+ end
117
+
118
+ def notice_channel(message)
119
+ @server.notice_channel(@name, message)
120
+ end
121
+
122
+ def handle_public_message(user, host, message)
123
+ if message =~ /^#{@server.nick}: (.*)$/
124
+ handle_hilight(user, host, $1)
125
+ elsif message =~ /^#{@flag}(\S+)\s(.*)$/
126
+ command = $1
127
+ arguments = $2.split(/\s/)
128
+ handle_flag(user, host, command, arguments)
129
+ end
130
+ end
131
+
132
+ def handle_hilight(user, host, message)
133
+ end
134
+ def handle_flag(user, host, flag, arguments)
135
+ if allowed? user
136
+ begin
137
+ @flags[flag].call(user, host, arguments)
138
+ rescue NoMethodError
139
+ #say("Sorry, there's no action associated with the flag #{flag}.")
140
+ end
141
+ end
142
+ end
143
+
144
+ def allowed?(user)
145
+ begin
146
+ @blacklists.each do |blacklist|
147
+ blacklist.call(user)
148
+ end
149
+ rescue NotAllowedException
150
+ return false
151
+ rescue => detail
152
+ say("Uh oh: #{detail}")
153
+ return false
154
+ else
155
+ return true
156
+ end
157
+ end
158
+ end
159
+
160
+ class NotAllowedException < StandardError
161
+ end
162
+ end
data/lib/utils.rb ADDED
@@ -0,0 +1,69 @@
1
+ module Utils
2
+ module Foo
3
+ def handle_hilight(user, host, message)
4
+ hilight_user(user, 'whatcha want?')
5
+ end
6
+
7
+ def self.extended(obj)
8
+ obj.instance_eval {
9
+ @flags['foo'] = lambda { |user, host, arguments|
10
+ say('bar')
11
+ }
12
+ @flags['bar'] = lambda { |user, host, arguments|
13
+ notice_user(user, 'baz')
14
+ }
15
+ @flags['baz'] = lambda { |user, host, arguments|
16
+ notice_channel('not baz!')
17
+ }
18
+ }
19
+ end
20
+
21
+ def join
22
+ @server.say "JOIN ##{@name}"
23
+ say "#{1.chr}ACTION is here to help#{1.chr}"
24
+ end
25
+ end
26
+
27
+ module Changelog
28
+ def self.extended(obj)
29
+ obj.instance_eval {
30
+ @flags['changelog'] = lambda { |user, host, arguments|
31
+ if arguments[0] and arguments[0] =~ /^[\w\d "]+$/
32
+ output = `git --no-pager log --pretty=format:%s --since=#{arguments[0]}`
33
+ else
34
+ output = `git --no-pager log --pretty=format:%s -1`
35
+ end
36
+ if output.empty?
37
+ say "No changes found for specified period of time."
38
+ else
39
+ for summary in output.split("\n")
40
+ say summary
41
+ end
42
+ end
43
+ }
44
+ }
45
+ end
46
+ end
47
+
48
+ module FlagFloodProtection
49
+ require 'erasmus'
50
+ require 'thread' # for Queue
51
+
52
+ def self.extended(obj)
53
+ obj.instance_eval {
54
+ @userMessages = Hash.new(Queue.new)
55
+ @blacklists << lambda { |user|
56
+ @userMessages[user] << Time.now
57
+
58
+ # don't allow messages from users who have sent
59
+ # 5 messages in 15 seconds
60
+ if @userMessages[user].length > 4 \
61
+ and Time.now - @userMessages[user].pop < 15
62
+ say("#{user} is flooding!")
63
+ raise Erasmus::NotAllowedException
64
+ end
65
+ }
66
+ }
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class ErasmusTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'erasmus'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erasmus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - xiongchiamiov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-15 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: "TODO: longer description of your gem"
26
+ email: xiong.chiamiov@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - lib/bots.rb
36
+ - lib/erasmus.rb
37
+ - lib/utils.rb
38
+ - LICENSE
39
+ - README.rdoc
40
+ has_rdoc: true
41
+ homepage: http://github.com/xiongchiamiov/erasmus
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.1
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: A simple, modular irc bot/framework
66
+ test_files:
67
+ - test/erasmus_test.rb
68
+ - test/test_helper.rb