beerbot 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5711f62c9ce4965a324d3578b5555761d8c493ef
4
+ data.tar.gz: 61bdaff04c5ae69702858f623316671d305b5474
5
+ SHA512:
6
+ metadata.gz: 5551c5b99e88f48ed52bbc6d3ee3581d8842c9e841551919cdeb2fc37034206239543be1228f47b509d83fe6c7a04a09134b06ff09bbb90d8540a95c96b18497
7
+ data.tar.gz: 4e189c7c8ac1ba58f3874a8e78cebaf7fdb01b29bc3702830fa43aeec1fd0fbce1afc0495eccc0a26c515be398b27b43e70251245f08d1c0cd146ae1912d6385
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # The files in this directory are part of BeerBot, a a ruby irc bot library.
4
+ # Copyright (C) 2013,2014 Daniel Bush
5
+ # This program is distributed under the terms of the GNU
6
+ # General Public License. A copy of the license should be
7
+ # enclosed with this project in the file LICENSE. If not
8
+ # see <http://www.gnu.org/licenses/>.
9
+
10
+ raise "Needs ruby 2" if /^1/===RUBY_VERSION
11
+ require_relative '../lib/RunIRC'
12
+
13
+ if ARGV.size == 0 then
14
+ puts "Usage: ruby beerbot.rb path/to/ircconf.json"
15
+ puts "See conf/irc.json"
16
+ exit 1
17
+ end
18
+
19
+ conffile = ARGV[0]
20
+ BeerBot::Config.load JSON.load(File.read(conffile))
21
+ BeerBot::Config.validate!
22
+
23
+ $runirc = BeerBot::RunIRC.new BeerBot::Config
24
+ $runirc.start
@@ -0,0 +1,20 @@
1
+ require 'CronR' # For scheduler
2
+
3
+ require_relative 'BeerBot/00.utils/utils'
4
+ require_relative 'BeerBot/00.utils/paramExpand'
5
+ require_relative 'BeerBot/00.utils/DataFile'
6
+ require_relative 'BeerBot/00.utils/InOut'
7
+ require_relative 'BeerBot/00.utils/world/IRCWorld'
8
+ require_relative 'BeerBot/01.connect/IRCConnection'
9
+ require_relative 'BeerBot/01.protocols/botmsg'
10
+ require_relative 'BeerBot/01.protocols/irc'
11
+ require_relative 'BeerBot/02.bot/bot'
12
+ require_relative 'BeerBot/03.more/BotMsgMore'
13
+ require_relative 'BeerBot/06.dispatchers/irc'
14
+ require_relative 'BeerBot/70.scheduler/scheduler'
15
+ require_relative 'BeerBot/Config'
16
+
17
+ module BeerBot
18
+ module Modules
19
+ end
20
+ end
@@ -0,0 +1,56 @@
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 'json'
9
+ module BeerBot
10
+ module Utils
11
+ # A class that loads data from a file and allows you to access it
12
+ # using the #data method.
13
+ #
14
+ # If the file is updated (after >=1 sec), #data will reload.
15
+ class DataFile
16
+ attr_reader :reloaded # true if last call to #data reloaded file
17
+ def initialize filepath
18
+ @filepath = filepath
19
+ @data = File.read(filepath)
20
+ @mtime = File.stat(filepath).mtime
21
+ @reloaded = false
22
+ end
23
+ def data
24
+ @reloaded = false
25
+ return @data unless File.exists?(@filepath)
26
+ mtime = File.stat(@filepath).mtime
27
+ return @data if mtime == @mtime
28
+ puts "Reloading data file #{@filepath}"
29
+ @mtime = mtime
30
+ @data = File.read(@filepath)
31
+ @reloaded = true
32
+ @data
33
+ end
34
+ end
35
+ # Specialised DataFile that parses json.
36
+ class JsonDataFile < DataFile
37
+ attr_reader :json
38
+ def initialize filepath
39
+ super
40
+ @json = JSON.parse(@data)
41
+ end
42
+ def data
43
+ super
44
+ begin
45
+ if @reloaded then
46
+ json = JSON.parse(@data)
47
+ @json = json
48
+ end
49
+ rescue => e
50
+ return @json
51
+ end
52
+ @json
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,46 @@
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
+ module Utils
10
+
11
+ # Represents a thread that waits on an in-queue, processes any
12
+ # things received and puts them on an out-queue.
13
+
14
+ class InOut
15
+
16
+ attr_reader :inq,:outq,:run,:thread
17
+
18
+ def initialize inq:nil,outq:nil,&block
19
+ @inq = inq
20
+ @outq = outq
21
+ @run = block
22
+ raise "No block given" unless block_given?
23
+ end
24
+
25
+ def start!
26
+ @thread = Thread.new {
27
+ loop {
28
+ begin
29
+ thing = @inq.deq
30
+ response = @run.call(thing)
31
+ if response then
32
+ @outq.enq(response)
33
+ else
34
+ # TODO
35
+ end
36
+ rescue => e
37
+ puts e
38
+ puts e.backtrace
39
+ end
40
+ }
41
+ }
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,68 @@
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
@@ -0,0 +1,77 @@
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 ParamExpand
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
@@ -0,0 +1,149 @@
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
+ # Look for parameters in a string.
14
+ #
15
+ # Numeric parameters => "... ::1 ... ::2 "
16
+ # Key parameters => "... ::foo ... ::bar "
17
+ # Multi => "... ::foo|::1 ... ::bar|::foo|::1 "
18
+ #
19
+ # (?: ) is a non-capturing group.
20
+
21
+ def self.scan_param msg
22
+ matches = msg.scan(/(?:::[^\W\s:|]*(?:\|::[^\W\s:|]*)*)/)
23
+ matches.map{|m|
24
+ a = m.split('|').map{|m2|
25
+ m2 = m2.sub('::','')
26
+ case m2
27
+ when /\d+/
28
+ m2.to_i
29
+ else
30
+ m2
31
+ end
32
+ }
33
+ [m,a]
34
+ }
35
+ end
36
+
37
+ # Return a parser that takes string msg and extracts a specified
38
+ # prefix at beginning.
39
+ #
40
+ # The prefix might be a nick or a command prefix.
41
+ #
42
+ # Use this to get commands issued to the bot through a channel.
43
+ #
44
+ # TODO: make sure this returns msg without the prefix, or nil
45
+ # otherwise.
46
+
47
+ def self.make_prefix_parser prefix
48
+ rx = Regexp.new("^#{prefix}\\W?(.*)",'i')
49
+ lambda {|msg|
50
+ if m = rx.match(msg) then
51
+ m[1].strip
52
+ end
53
+ }
54
+ end
55
+
56
+ # Expand a string with numeric and key parameters using data
57
+ # provided.
58
+ #
59
+ # Parameters should be preceded with a double-colon in the msg.
60
+ # Numeric parameters are matched to 'args'.
61
+ # So ::1 => args[0] etc
62
+ #
63
+ # 'expand' will return the expanded string as best it can and an
64
+ # error object.
65
+ # The error object will tell you if there weren't enough
66
+ # parameters in args to satisfy the numeric parameters in the
67
+ # string.
68
+ #
69
+ # ("::1 ::foo ::bar|::1",'a',foo:'b') => "a b a"
70
+
71
+ def self.expand msg,*args,**kargs
72
+ errargs = []
73
+ params = self.scan_param(msg)
74
+ # Do the big ones first.
75
+ params = params.sort{|a,b|b[1].size<=>a[1].size}
76
+ params.each {|i|
77
+ # pattern: "::1|::foo"
78
+ # parts: [1,'foo']
79
+ pattern,parts = i
80
+ found = false
81
+ _errargs = []
82
+ _errkargs = []
83
+ parts.each {|part|
84
+ v = nil
85
+ case part
86
+ when Fixnum
87
+ v = args[part-1]
88
+ _errargs.push(part) unless v
89
+ else
90
+ if part == '' then # pattern is or contains '::' which has part ''.
91
+ v = ''
92
+ else
93
+ v = kargs[part.to_sym]
94
+ _errkargs.push(part) unless v
95
+ end
96
+ end
97
+ if v then
98
+ if v == '' then
99
+ #byebug
100
+ # Squeeze spaces. Not perfect, but it'll do.
101
+ msg = msg.gsub(/ ?#{pattern.gsub('|','\|')} ?/,' ')
102
+ else
103
+ msg = msg.gsub(pattern,v.to_s)
104
+ end
105
+ found = true
106
+ end
107
+ }
108
+ unless found then
109
+ errargs += _errargs
110
+ end
111
+ }
112
+ [msg,errargs]
113
+ end
114
+
115
+ # Regex that looks for a sed command eg
116
+ # "s/pattern/replacement/flags" in a string.
117
+ #
118
+ # This regex doesn't handle backslash escapes, so if pattern or
119
+ # replacement contain '/' use another delimiter eg s#...#...# etc.
120
+ #
121
+ # Non alphanumeric delimiters are allowed.
122
+ #
123
+ # Returns: nil or a MatchData instance with symbol keys:
124
+ # :sed (the whole sed command), :sep (the separator), :pattern,
125
+ # :replacement, :flags
126
+ #
127
+ # If you want to combine this regex, call
128
+ # sed_regex.source => <string>
129
+
130
+ def self.sed_regex
131
+ %r{
132
+ ^(?<before>.*)
133
+ \b
134
+ (?<sed>
135
+ s
136
+ (?<sep>[^A-z0-9\s])
137
+ (?<pattern>(?!\g<sep>)*.*)
138
+ \k<sep>
139
+ (?<replacement>(?!\g<sep>)*.*)
140
+ \k<sep>
141
+ (?<flags>[A-z]*)
142
+ )
143
+ (?<after>.*)$
144
+ }x
145
+ end
146
+
147
+ end
148
+
149
+ end