beerbot 0.1.5 → 0.2.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-