beerbot 0.1.5 → 0.2.0.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/{run-irc.rb → beerbot-run-irc.rb} +9 -3
- data/lib/RunIRC.rb +46 -18
- data/lib/beerbot.rb +17 -0
- data/lib/{BeerBot → beerbot}/00.utils/InOut.rb +0 -0
- data/lib/beerbot/00.utils/utils.rb +34 -0
- data/lib/{BeerBot → beerbot}/01.bot/Bot.rb +49 -21
- data/lib/{BeerBot → beerbot}/01.bot/BotModule.rb +0 -0
- data/lib/{BeerBot → beerbot}/01.bot/botmsg.rb +51 -0
- data/lib/{BeerBot → beerbot}/01.connect/IRCConnection.rb +39 -19
- data/lib/{BeerBot → beerbot}/02.protocols/irc.rb +1 -1
- data/lib/{BeerBot → beerbot}/06.dispatchers/dispatcher.rb +32 -67
- data/lib/{BeerBot → beerbot}/70.scheduler/scheduler.rb +0 -0
- data/lib/{BeerBot → beerbot}/Config.rb +36 -3
- metadata +17 -24
- data/lib/BeerBot.rb +0 -22
- data/lib/BeerBot/00.utils/DataFile.rb +0 -103
- data/lib/BeerBot/00.utils/More.rb +0 -68
- data/lib/BeerBot/00.utils/param_expand.rb +0 -105
- data/lib/BeerBot/00.utils/sentence_expand.rb +0 -77
- data/lib/BeerBot/00.utils/utils.rb +0 -92
- data/lib/BeerBot/00.utils/world/IRCWorld.rb +0 -47
- data/lib/BeerBot/00.utils/world/World.rb +0 -74
- data/lib/BeerBot/01.bot/BotMsgMore.rb +0 -35
@@ -1,68 +0,0 @@
|
|
1
|
-
# The files in this directory are part of BeerBot, a a ruby irc bot library.
|
2
|
-
# Copyright (C) 2014 Daniel Bush
|
3
|
-
# This program is distributed under the terms of the GNU
|
4
|
-
# General Public License. A copy of the license should be
|
5
|
-
# enclosed with this project in the file LICENSE. If not
|
6
|
-
# see <http://www.gnu.org/licenses/>.
|
7
|
-
|
8
|
-
module BeerBot
|
9
|
-
|
10
|
-
module Utils
|
11
|
-
|
12
|
-
# A hash that buffers things by some key.
|
13
|
-
#
|
14
|
-
# If 'things' exceeds a set number, then these are stored in an
|
15
|
-
# array against the key.
|
16
|
-
#
|
17
|
-
# For irc and other messaging the key should probably
|
18
|
-
# be key :to of one or more botmsg's.
|
19
|
-
# @see BotMsgMore
|
20
|
-
|
21
|
-
class More < Hash
|
22
|
-
|
23
|
-
attr_accessor :size
|
24
|
-
|
25
|
-
def initialize
|
26
|
-
super
|
27
|
-
# Default value is empty array.
|
28
|
-
self.default_proc = lambda {|h,k|
|
29
|
-
h[k] = []
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
|
-
def size
|
34
|
-
@size ||= 5 # lines
|
35
|
-
end
|
36
|
-
|
37
|
-
# Fetch array of items from buffer for key 'key'.
|
38
|
-
#
|
39
|
-
# 'key' should probably be a person or channel you are messaging.
|
40
|
-
#
|
41
|
-
# Should return an array of items (eg of botmsg hashes).
|
42
|
-
|
43
|
-
def more key
|
44
|
-
arr = self[key]
|
45
|
-
self[key] = arr.slice(self.size,arr.size) || []
|
46
|
-
return arr.slice(0,self.size-1)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Filter an array of items allowing only
|
50
|
-
# the first 'n' of these.
|
51
|
-
#
|
52
|
-
# The remainder are stored in this hash and can
|
53
|
-
# be accessed via 'key' using 'self.more'.
|
54
|
-
|
55
|
-
def filter arr,key
|
56
|
-
if arr.size <= self.size then
|
57
|
-
self[key] = [] # reset buffer
|
58
|
-
return arr
|
59
|
-
end
|
60
|
-
self[key] = arr.slice(self.size,size)
|
61
|
-
return arr.slice(0,self.size)
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
@@ -1,105 +0,0 @@
|
|
1
|
-
# The files in this directory are part of BeerBot, a a ruby irc bot library.
|
2
|
-
# Copyright (C) 2014 Daniel Bush
|
3
|
-
# This program is distributed under the terms of the GNU
|
4
|
-
# General Public License. A copy of the license should be
|
5
|
-
# enclosed with this project in the file LICENSE. If not
|
6
|
-
# see <http://www.gnu.org/licenses/>.
|
7
|
-
|
8
|
-
|
9
|
-
module BeerBot
|
10
|
-
|
11
|
-
module Utils
|
12
|
-
|
13
|
-
module ParamExpand
|
14
|
-
|
15
|
-
# Look for parameters in a string.
|
16
|
-
#
|
17
|
-
# Numeric parameters => "... ::1 ... ::2 "
|
18
|
-
# Key parameters => "... ::foo ... ::bar "
|
19
|
-
# Multi => "... ::foo|::1 ... ::bar|::foo|::1 "
|
20
|
-
#
|
21
|
-
# (?: ) is a non-capturing group.
|
22
|
-
|
23
|
-
def self.scan_param msg
|
24
|
-
matches = msg.scan(/(?:::[^\W\s:|]*(?:\|::[^\W\s:|]*)*)/)
|
25
|
-
matches.map{|m|
|
26
|
-
a = m.split('|').map{|m2|
|
27
|
-
m2 = m2.sub('::','')
|
28
|
-
case m2
|
29
|
-
when /^\d+$/
|
30
|
-
m2.to_i
|
31
|
-
else
|
32
|
-
m2
|
33
|
-
end
|
34
|
-
}
|
35
|
-
[m,a]
|
36
|
-
}
|
37
|
-
end
|
38
|
-
|
39
|
-
# Expand a string with numeric and key parameters using data
|
40
|
-
# provided.
|
41
|
-
#
|
42
|
-
# Parameters should be preceded with a double-colon in the msg.
|
43
|
-
# Numeric parameters are matched to 'args'.
|
44
|
-
# So ::1 => args[0] etc
|
45
|
-
#
|
46
|
-
# 'expand' will return the expanded string as best it can and an
|
47
|
-
# error object.
|
48
|
-
# The error object will tell you if there weren't enough
|
49
|
-
# parameters in args to satisfy the numeric parameters in the
|
50
|
-
# string.
|
51
|
-
#
|
52
|
-
# Example:
|
53
|
-
#
|
54
|
-
# "::1 ::foo ::bar|::1" using ('a',foo:'b')
|
55
|
-
# => "a b a"
|
56
|
-
|
57
|
-
def self.expand msg,*args,**kargs
|
58
|
-
errargs = []
|
59
|
-
params = self.scan_param(msg)
|
60
|
-
# Do the big ones first.
|
61
|
-
params = params.sort{|a,b|b[1].size<=>a[1].size}
|
62
|
-
params.each {|i|
|
63
|
-
# pattern: "::1|::foo"
|
64
|
-
# parts: [1,'foo']
|
65
|
-
pattern,parts = i
|
66
|
-
found = false
|
67
|
-
_errargs = []
|
68
|
-
_errkargs = []
|
69
|
-
parts.each {|part|
|
70
|
-
v = nil
|
71
|
-
case part
|
72
|
-
when Fixnum
|
73
|
-
v = args[part-1]
|
74
|
-
_errargs.push(part) unless v
|
75
|
-
else
|
76
|
-
if part == '' then # pattern is or contains '::' which has part ''.
|
77
|
-
v = ''
|
78
|
-
else
|
79
|
-
v = kargs[part.to_sym]
|
80
|
-
_errkargs.push(part) unless v
|
81
|
-
end
|
82
|
-
end
|
83
|
-
if v then
|
84
|
-
if v == '' then
|
85
|
-
#byebug
|
86
|
-
# Squeeze spaces. Not perfect, but it'll do.
|
87
|
-
msg = msg.gsub(/ ?#{pattern.gsub('|','\|')} ?/,' ')
|
88
|
-
else
|
89
|
-
msg = msg.gsub(pattern,v.to_s)
|
90
|
-
end
|
91
|
-
found = true
|
92
|
-
end
|
93
|
-
}
|
94
|
-
unless found then
|
95
|
-
errargs += _errargs
|
96
|
-
end
|
97
|
-
}
|
98
|
-
[msg,errargs]
|
99
|
-
end
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
# The files in this directory are part of BeerBot, a a ruby irc bot library.
|
2
|
-
# Copyright (C) 2014 Daniel Bush
|
3
|
-
# This program is distributed under the terms of the GNU
|
4
|
-
# General Public License. A copy of the license should be
|
5
|
-
# enclosed with this project in the file LICENSE. If not
|
6
|
-
# see <http://www.gnu.org/licenses/>.
|
7
|
-
|
8
|
-
|
9
|
-
module BeerBot
|
10
|
-
|
11
|
-
module Utils
|
12
|
-
|
13
|
-
# Randomly generate sentences.
|
14
|
-
#
|
15
|
-
# See spec examples in spec/.
|
16
|
-
#
|
17
|
-
# Take a spec which is of form
|
18
|
-
# [<sentence>,<hash>]
|
19
|
-
# where <sentence> is a string and
|
20
|
-
# each entry in <hash>
|
21
|
-
# <key> => <value>
|
22
|
-
# where <key> is a symbol, and <value>
|
23
|
-
# is an array of <sentence>'s.
|
24
|
-
#
|
25
|
-
# <sentence> is a sentence or phrase.
|
26
|
-
# If a word starts with ':' it will be looked up
|
27
|
-
# in <hash>, an entry from <value> will be randomly
|
28
|
-
# selected.
|
29
|
-
# The entry from <value> will also undergo the
|
30
|
-
# same ':' substitution.
|
31
|
-
|
32
|
-
module SentenceExpand
|
33
|
-
|
34
|
-
# Recursively expand a sentence with parameters starting with
|
35
|
-
# ':' using values sampled from params.
|
36
|
-
#
|
37
|
-
# Split, map and rejoin a sentence (str).
|
38
|
-
#
|
39
|
-
# After splitting, apply expand on parameter words ":word".
|
40
|
-
#
|
41
|
-
# Watch out, throws error, be prepared.
|
42
|
-
|
43
|
-
def self.expand(str,params,raise_error=false)
|
44
|
-
words = str.split(/\s+/) # not great, we lose additional spaces
|
45
|
-
words.map {|word|
|
46
|
-
if word[0] == ':' then
|
47
|
-
if word[1] == ':' then
|
48
|
-
word # let the bot code gsub this; ::from , ::to
|
49
|
-
else
|
50
|
-
self.expand(
|
51
|
-
self.lookup(word[1..-1],params,raise_error),
|
52
|
-
params,raise_error
|
53
|
-
)
|
54
|
-
end
|
55
|
-
else
|
56
|
-
word
|
57
|
-
end
|
58
|
-
}.select{|word| word != nil && word != ""}.join(' ').strip
|
59
|
-
end
|
60
|
-
|
61
|
-
# Randomly select entry from params.
|
62
|
-
|
63
|
-
def self.lookup(str,params,raise_error=false)
|
64
|
-
if not params.has_key?(str) then
|
65
|
-
if raise_error then
|
66
|
-
raise "'#{str}' has no corresponding symbol in params #{params}"
|
67
|
-
else
|
68
|
-
return ""
|
69
|
-
end
|
70
|
-
end
|
71
|
-
result = params[str].sample
|
72
|
-
result ? result : ""
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,92 +0,0 @@
|
|
1
|
-
# The files in this directory are part of BeerBot, a a ruby irc bot library.
|
2
|
-
# Copyright (C) 2014 Daniel Bush
|
3
|
-
# This program is distributed under the terms of the GNU
|
4
|
-
# General Public License. A copy of the license should be
|
5
|
-
# enclosed with this project in the file LICENSE. If not
|
6
|
-
# see <http://www.gnu.org/licenses/>.
|
7
|
-
|
8
|
-
|
9
|
-
module BeerBot
|
10
|
-
|
11
|
-
module Utils
|
12
|
-
|
13
|
-
# Return a parser that takes string msg and extracts a specified
|
14
|
-
# prefix at beginning.
|
15
|
-
#
|
16
|
-
# The prefix might be a nick or a command prefix.
|
17
|
-
#
|
18
|
-
# Use this to get commands issued to the bot through a channel.
|
19
|
-
#
|
20
|
-
# TODO: make sure this returns msg without the prefix, or nil
|
21
|
-
# otherwise.
|
22
|
-
|
23
|
-
def self.make_prefix_parser prefix
|
24
|
-
rx = Regexp.new("^#{prefix}\\W?(.*)",'i')
|
25
|
-
lambda {|msg|
|
26
|
-
if m = rx.match(msg) then
|
27
|
-
m[1].strip
|
28
|
-
end
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
|
-
# Regex that looks for a sed command eg
|
33
|
-
# "s/pattern/replacement/flags" in a string.
|
34
|
-
#
|
35
|
-
# This regex doesn't handle backslash escapes, so if pattern or
|
36
|
-
# replacement contain '/' use another delimiter eg s#...#...# etc.
|
37
|
-
#
|
38
|
-
# Non alphanumeric delimiters are allowed.
|
39
|
-
#
|
40
|
-
# Returns: nil or a MatchData instance with symbol keys:
|
41
|
-
# :sed (the whole sed command), :sep (the separator), :pattern,
|
42
|
-
# :replacement, :flags
|
43
|
-
#
|
44
|
-
# If you want to combine this regex, call
|
45
|
-
# sed_regex.source => <string>
|
46
|
-
|
47
|
-
def self.sed_regex
|
48
|
-
%r{
|
49
|
-
^(?<before>.*)
|
50
|
-
\b
|
51
|
-
(?<sed>
|
52
|
-
s
|
53
|
-
(?<sep>[^A-z0-9\s])
|
54
|
-
(?<pattern>(?!\g<sep>)*.*)
|
55
|
-
\k<sep>
|
56
|
-
(?<replacement>(?!\g<sep>)*.*)
|
57
|
-
\k<sep>
|
58
|
-
(?<flags>[A-z]*)
|
59
|
-
)
|
60
|
-
(?<after>.*)$
|
61
|
-
}x
|
62
|
-
end
|
63
|
-
|
64
|
-
# Could use in a botmsg
|
65
|
-
#
|
66
|
-
# [to:to,msg:weighted_sample({90=>['yes','ok','fine'],10=>[...]})]
|
67
|
-
|
68
|
-
def weighted_sample thing
|
69
|
-
case thing
|
70
|
-
when Hash
|
71
|
-
keys = thing.keys
|
72
|
-
total = keys.reduce{|s,i|s+i}
|
73
|
-
i = Kernel.rand(total)
|
74
|
-
k = keys.reduce{|s,k|s+=k; if s>=i then break k; else s end}
|
75
|
-
case thing[k]
|
76
|
-
when Array
|
77
|
-
thing[k].sample
|
78
|
-
when String
|
79
|
-
thing[k]
|
80
|
-
when Hash
|
81
|
-
weight_sample(thing[k])
|
82
|
-
else
|
83
|
-
nil
|
84
|
-
end
|
85
|
-
else
|
86
|
-
nil
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# The files in this directory are part of BeerBot, a a ruby irc bot library.
|
2
|
-
# Copyright (C) 2014 Daniel Bush
|
3
|
-
# This program is distributed under the terms of the GNU
|
4
|
-
# General Public License. A copy of the license should be
|
5
|
-
# enclosed with this project in the file LICENSE. If not
|
6
|
-
# see <http://www.gnu.org/licenses/>.
|
7
|
-
|
8
|
-
require_relative 'World'
|
9
|
-
|
10
|
-
module BeerBot
|
11
|
-
|
12
|
-
module Utils
|
13
|
-
|
14
|
-
# The chief specialisation of IRCWorld is to handle user names which
|
15
|
-
# are sometimes prepended with characters like '@'.
|
16
|
-
#
|
17
|
-
# TODO: are there any more?
|
18
|
-
|
19
|
-
class IRCWorld < World
|
20
|
-
def remove_op nick
|
21
|
-
nick.sub(/^@/,'')
|
22
|
-
end
|
23
|
-
|
24
|
-
def nick oldnick,nick
|
25
|
-
oldnick = self.remove_op(oldnick)
|
26
|
-
nick = self.remove_op(nick)
|
27
|
-
super
|
28
|
-
end
|
29
|
-
|
30
|
-
def part nick,channel
|
31
|
-
nick = self.remove_op(nick)
|
32
|
-
super
|
33
|
-
end
|
34
|
-
|
35
|
-
def join nick,channel
|
36
|
-
nick = self.remove_op(nick)
|
37
|
-
super
|
38
|
-
end
|
39
|
-
|
40
|
-
def quit nick
|
41
|
-
nick = self.remove_op(nick)
|
42
|
-
super
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# The files in this directory are part of BeerBot, a a ruby irc bot library.
|
2
|
-
# Copyright (C) 2014 Daniel Bush
|
3
|
-
# This program is distributed under the terms of the GNU
|
4
|
-
# General Public License. A copy of the license should be
|
5
|
-
# enclosed with this project in the file LICENSE. If not
|
6
|
-
# see <http://www.gnu.org/licenses/>.
|
7
|
-
|
8
|
-
module BeerBot
|
9
|
-
|
10
|
-
module Utils
|
11
|
-
|
12
|
-
# There should be one world per connection instance tracking
|
13
|
-
# the channels joined and users on those channels.
|
14
|
-
|
15
|
-
class World < Hash
|
16
|
-
|
17
|
-
def initialize nick
|
18
|
-
self[:nick] = nick
|
19
|
-
|
20
|
-
# An index/lookup for channels we know about.
|
21
|
-
self[:channels] = Hash.new {|h,k| h[k] = {users:Set.new}}
|
22
|
-
|
23
|
-
# An index/lookup for users we know about.
|
24
|
-
self[:users] = Hash.new {|h,k| h[k] = {channels:Set.new}}
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
# Someone joins channel.
|
29
|
-
def join nick,channel
|
30
|
-
self[:channels][channel][:users].add(nick)
|
31
|
-
self[:users][nick][:channels].add(channel)
|
32
|
-
self[:users][nick][:quit] = false
|
33
|
-
self
|
34
|
-
end
|
35
|
-
|
36
|
-
# Someone leaves channel.
|
37
|
-
def part nick,channel
|
38
|
-
self[:channels][channel][:users].delete(nick)
|
39
|
-
self[:users][nick][:channels].delete(channel)
|
40
|
-
self
|
41
|
-
end
|
42
|
-
|
43
|
-
# Someone changes nick.
|
44
|
-
def nick oldnick,nick
|
45
|
-
self[:channels].each_pair{|name,chan|
|
46
|
-
if chan[:users].member?(oldnick) then
|
47
|
-
chan[:users].delete(oldnick)
|
48
|
-
chan[:users].add(nick)
|
49
|
-
end
|
50
|
-
}
|
51
|
-
self[:users][nick] = self[:users][oldnick]
|
52
|
-
self[:users].delete(oldnick)
|
53
|
-
# If it's us, update our nick:
|
54
|
-
if self[:nick] == oldnick then
|
55
|
-
self[:nick] = nick
|
56
|
-
end
|
57
|
-
self
|
58
|
-
end
|
59
|
-
|
60
|
-
def quit nick
|
61
|
-
self[:channels].each_pair{|name,chan|
|
62
|
-
chan[:users].delete(nick)
|
63
|
-
}
|
64
|
-
self[:users][nick][:channels] = Set.new
|
65
|
-
self[:users][nick][:quit] = true
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
|