kag-gather 1.3.4 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,126 @@
1
+ module Cinch
2
+ module Commands
3
+ #
4
+ # @api semipublic
5
+ #
6
+ class Command
7
+
8
+ # Argument formats
9
+ ARG_FORMATS = {
10
+ string: /\S+/,
11
+ integer: /\d+/,
12
+ float: /\d*\.\d+/,
13
+ text: /.+/
14
+ }
15
+
16
+ # Name of the command
17
+ attr_reader :name
18
+
19
+ # Argument names/formats
20
+ attr_reader :arguments
21
+
22
+ # Short summary of the command
23
+ attr_reader :summary
24
+
25
+ # Long description of the command
26
+ attr_reader :description
27
+
28
+ # if admin-only
29
+ attr_reader :admin
30
+
31
+ #
32
+ # Creates a new command.
33
+ #
34
+ # @param [Symbol] name
35
+ # Name of the command.
36
+ #
37
+ # @param [Hash{Symbol => Symbol,Regexp,String,Array}] arguments
38
+ # Arguments names and their formats or possible values.
39
+ #
40
+ # @param [Hash] options
41
+ # Additional options.
42
+ #
43
+ # @option options [Array] :aliases
44
+ # Additiona aliases for the command.
45
+ #
46
+ # @option options [String] :summary
47
+ # Short summary of the command.
48
+ #
49
+ # @option options [String] :description
50
+ # Long description of the command.
51
+ #
52
+ def initialize(name,arguments,options={})
53
+ @name = name.to_s
54
+ @arguments = arguments
55
+ @aliases = options.fetch(:aliases,[]).map(&:to_s)
56
+
57
+ @summary = options[:summary]
58
+ @description = options[:description]
59
+ @admin = options[:admin]
60
+ end
61
+
62
+ #
63
+ # The names for the command.
64
+ #
65
+ # @return [Array<String>]
66
+ # Command names.
67
+ #
68
+ def names
69
+ [@name] + @aliases
70
+ end
71
+
72
+ #
73
+ # Creates a Regular Expression that matches invocations of the command.
74
+ #
75
+ # @return [Regexp]
76
+ # A Regular Expression that matches the command and captures it's
77
+ # arguments.
78
+ #
79
+ def regexp
80
+ pattern = '(?:' + Regexp.union([@name] + @aliases).source + ')'
81
+
82
+ @arguments.each_value do |format|
83
+ arg_regexp = case format
84
+ when Symbol
85
+ ARG_FORMATS.fetch(format)
86
+ when Regexp
87
+ format
88
+ else
89
+ Regexp.union(format)
90
+ end
91
+
92
+ pattern << ' (' << arg_regexp.source << ')'
93
+ end
94
+
95
+ # match the full message
96
+ pattern << '$'
97
+
98
+ Regexp.new(pattern)
99
+ end
100
+
101
+ #
102
+ # The usage string for the command.
103
+ #
104
+ # @return [String]
105
+ # The usage string for the command and it's arguments.
106
+ #
107
+ def usage
108
+ usage = "#{@name}"
109
+
110
+ @arguments.each do |arg,format|
111
+ usage << ' ' << case format
112
+ when Array
113
+ '[' + format.join('|') + ']'
114
+ when String
115
+ format.to_s
116
+ else
117
+ arg.to_s.upcase
118
+ end
119
+ end
120
+
121
+ usage
122
+ end
123
+
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,64 @@
1
+ require 'commands/command'
2
+ require 'kag/common'
3
+
4
+ module Cinch
5
+ module Commands
6
+
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ #
13
+ # All registered commands.
14
+ #
15
+ # @return [Array<Command>]
16
+ # The registered commands.
17
+ #
18
+ # @api semipublic
19
+ #
20
+ def commands
21
+ @commands ||= []
22
+ end
23
+
24
+ protected
25
+
26
+ #
27
+ # Registers a command.
28
+ #
29
+ # @param [Symbol] name
30
+ #
31
+ # @param [Hash{Symbol => Symbol,Regexp}] arguments
32
+ #
33
+ # @param [Hash] options
34
+ # Additional options.
35
+ #
36
+ # @option options [String] :summary
37
+ # The short summary for the command.
38
+ #
39
+ # @option options [String] :description
40
+ # The long description for the command.
41
+ #
42
+ # @return [Command]
43
+ # The new command.
44
+ #
45
+ # @example
46
+ # command :grant, {name: :string, :level: :integer},
47
+ # summary: "Grants access",
48
+ # description: %{
49
+ # Grants a certain level of access to the user
50
+ # }
51
+ #
52
+ def command(name,arguments={},options={})
53
+ new_command = Command.new(name,arguments,options)
54
+
55
+ m = options.key?(:method) ? options[:method] : name
56
+ match(new_command.regexp, method: m)
57
+
58
+ commands << new_command
59
+ new_command
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,101 @@
1
+ require 'commands/commands'
2
+ require 'cinch/plugin'
3
+ require 'kag/common'
4
+
5
+ module Cinch
6
+ module Commands
7
+ #
8
+ # Generic `!help` command that lists all commands.
9
+ #
10
+ class Help
11
+ include Cinch::Plugin
12
+ include Cinch::Commands
13
+ include KAG::Common
14
+
15
+ command :help, {command: :string},
16
+ summary: %{Displays help information for the COMMAND},
17
+ description: %{Finds the COMMAND and prints the usage and description for the COMMAND.}
18
+
19
+ command :help, {},
20
+ summary: "Lists available commands",
21
+ description: %{If no COMMAND argument is given, then all commands will be listed.}
22
+
23
+ #
24
+ # Displays a list of commands or the help information for a specific
25
+ # command.
26
+ #
27
+ # @param [Cinch::Message]
28
+ # The message that invoked `!help`.
29
+ #
30
+ # @param [String] command
31
+ # The specific command to list help information for.
32
+ #
33
+ def help(m,command=nil)
34
+ if command
35
+ found = commands_named(command)
36
+
37
+ if found.empty?
38
+ m.reply "help: Unknown command #{command.dump}"
39
+ else
40
+ return if found.first.admin and !is_admin(m.user)
41
+
42
+ msg = []
43
+ # print all usages
44
+ found.each do |cmd|
45
+ msg << cmd.usage
46
+ end
47
+ # print the description of the first command
48
+ desc = found.first.description.to_s
49
+ msg = "\x0302#{msg.join(", ")}\x0314"+(desc != "" ? " - #{desc}" : " - #{found.first.summary.to_s}")
50
+ User(m.user.nick).send(msg)
51
+ end
52
+ else
53
+ msg = []
54
+ each_command do |cmd|
55
+ #msg << "\x0302#{cmd.usage}\x0314: #{cmd.summary}" unless (cmd.admin and !is_admin(m.user))
56
+ msg << "!"+cmd.usage
57
+ end
58
+ User(m.user.nick).send(msg.join ", ")
59
+ end
60
+ end
61
+
62
+ protected
63
+
64
+ #
65
+ # Enumerates over every command.
66
+ #
67
+ # @yield [command]
68
+ # The given block will be passed every command.
69
+ #
70
+ # @yieldparam [Command] command
71
+ # A command.
72
+ #
73
+ # @return [Enumerator]
74
+ # If no block is given, an Enumerator will be returned.
75
+ #
76
+ def each_command(&block)
77
+ return enum_for(__method__) unless block_given?
78
+
79
+ bot.config.plugins.plugins.each do |plugin|
80
+ if plugin < Cinch::Commands
81
+ plugin.commands.each(&block)
82
+ end
83
+ end
84
+ end
85
+
86
+ #
87
+ # Finds all commands with a similar name.
88
+ #
89
+ # @param [String] name
90
+ # The name to search for.
91
+ #
92
+ # @return [Array<Command>]
93
+ # The commands with the matching name.
94
+ #
95
+ def commands_named(name)
96
+ each_command.select { |command| command.name == name }
97
+ end
98
+
99
+ end
100
+ end
101
+ end
data/lib/gather.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'patches'
2
- require 'kag/gather'
1
+ require 'kag/bot/bot'
3
2
 
4
- KAG::Bot.new
3
+ KAG::Bot::Bot.new
@@ -0,0 +1,93 @@
1
+ require 'cinch'
2
+ require 'kag/common'
3
+ require 'commands/help'
4
+
5
+ module KAG
6
+ module Bans
7
+ class Plugin
8
+ include Cinch::Plugin
9
+ include Cinch::Commands
10
+ include KAG::Common
11
+
12
+ command :report,{nick: :string},
13
+ summary: "Report a user the bot"
14
+ def report(m,nick)
15
+ unless is_banned?(m.user)
16
+ u = User(nick)
17
+ if u and !u.unknown
18
+ KAG::Bans::Report.new(self,m,u)
19
+ else
20
+ reply m,"User #{nick} not found!"
21
+ end
22
+ end
23
+ end
24
+
25
+ command :reports,{nick: :string},
26
+ summary: "Show the number of reports for a given user"
27
+ def reports(m,nick)
28
+ user = User(nick)
29
+ if user and !user.unknown
30
+ count = KAG::Bans::Report.reports(user)
31
+ if count
32
+ reply m,"User has been reported #{count.to_s} times."
33
+ else
34
+ reply m,"User has not been reported."
35
+ end
36
+ else
37
+ reply m,"Could not find user #{nick}"
38
+ end
39
+ end
40
+
41
+ command :reported,{},
42
+ summary: "Show a list of reported users"
43
+ def reported(m)
44
+ unless is_banned?(m.user)
45
+ KAG::Bans::Report.list
46
+ end
47
+ end
48
+
49
+ command :unreport,{nick: :string},
50
+ summary: "Clear all reports for a given user",
51
+ admin: true
52
+ def unreport(m,nick)
53
+ if is_admin(m.user)
54
+ user = User(nick)
55
+ if user and !user.unknown
56
+ KAG::Bans::Report.remove(self,m,user)
57
+ else
58
+ reply m,"Could not find user #{nick}"
59
+ end
60
+ end
61
+ end
62
+
63
+ command :ignore,{nick: :string},
64
+ summary: "Ignore (Ban) a user",
65
+ admin: true
66
+ def ignore(m,nick)
67
+ if is_admin(m.user)
68
+ user = User(nick)
69
+ if user and !user.unknown
70
+ KAG::Bans::Report.ignore(self,m,user)
71
+ else
72
+ reply m,"Could not find user #{nick}"
73
+ end
74
+ end
75
+ end
76
+
77
+ command :unignore,{nick: :string},
78
+ summary: "Unignore (Unban) a user",
79
+ admin: true
80
+ def unignore(m,nick)
81
+ if is_admin(m.user)
82
+ user = User(nick)
83
+ if user and !user.unknown
84
+ KAG::Bans::Report.unignore(self,m,user)
85
+ else
86
+ reply m,"Could not find user #{nick}"
87
+ end
88
+ end
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,172 @@
1
+ require 'symboltable'
2
+ require 'kag/data'
3
+ require 'kag/config'
4
+
5
+ module KAG
6
+ module Bans
7
+ class Report < SymbolTable
8
+ def initialize(gather,m,user)
9
+ hash = {
10
+ :nick => user.nick,
11
+ :authname => user.authname,
12
+ :host => user.host,
13
+ :realname => user.realname,
14
+ :gather => gather,
15
+ :message => m,
16
+ :count => 1
17
+ }
18
+ super(hash)
19
+ _ensure_data
20
+ if reported?
21
+ if can_report?
22
+ if past_threshold?
23
+ ignore
24
+ else
25
+ up_report_count
26
+ end
27
+ else
28
+ self.gather.reply self.message,"You have already reported #{self[:nick]}. You can only report a user once."
29
+ end
30
+ else
31
+ report
32
+ end
33
+ end
34
+
35
+ def can_report?
36
+ r = _report
37
+ if r and r[:reporters]
38
+ !r[:reporters].include?(self.message.user.authname)
39
+ else
40
+ true
41
+ end
42
+ end
43
+
44
+ def _ensure_data
45
+ data[:reported] = {} unless data[:reported]
46
+ data[:ignored] = {} unless data[:ignored]
47
+ end
48
+
49
+ def reported?
50
+ data[:reported].key?(self[:authname].to_sym)
51
+ end
52
+
53
+ def report
54
+ puts self.message.inspect
55
+ c = self.dup
56
+ c.delete(:gather)
57
+ c.delete(:message)
58
+ c[:reporters] = [self.message.user.authname]
59
+ data[:reported][self[:authname].to_sym] = c
60
+ data.save
61
+
62
+ self.gather.reply self.message,"User #{self[:nick]} reported." if self.gather.class == KAG::Gather
63
+ end
64
+
65
+ def ignore
66
+ c = self.clone
67
+ c.delete(:gather)
68
+ c.delete(:message)
69
+ data[:ignored][self[:authname].to_sym] = c
70
+ data.save
71
+ self.gather.reply self.message,"User #{self[:nick]} ignored." if self.gather.class == KAG::Gather
72
+ end
73
+
74
+ def past_threshold?
75
+ _report[:count].to_i > KAG::Config.instance[:report_threshold].to_i
76
+ end
77
+
78
+ def up_report_count
79
+ _report[:count] = _report[:count].to_i + 1
80
+ _report[:reporters] = [] unless _report[:reporters]
81
+ _report[:reporters] << self.message.user.authname
82
+ data.save
83
+
84
+ self.gather.reply message,"User #{self[:nick]} reported. #{self[:nick]} has now been reported #{data[:reported][self[:authname].to_sym][:count]} times." if self.gather.class == KAG::Gather
85
+ end
86
+
87
+ def self.ignore(gather,message,user)
88
+ KAG::Config.data[:ignored] = {} unless KAG::Config.data[:ignored]
89
+ if KAG::Config.data[:ignored] and !KAG::Config.data[:ignored].key?(user.authname.to_sym)
90
+ c = SymbolTable.new({
91
+ :nick => user.nick,
92
+ :authname => user.authname,
93
+ :host => user.host,
94
+ :realname => user.realname,
95
+ :gather => gather,
96
+ :message => message,
97
+ :reporters => [message.user.authname]
98
+ })
99
+ KAG::Config.data[:ignored][user.authname.to_sym] = c
100
+ KAG::Config.data.save
101
+
102
+ gather.reply message,"User #{user.nick} added to ignore list." if gather.class == KAG::Gather
103
+ true
104
+ else
105
+ gather.reply message,"User #{user.nick} already in ignore list!" if gather.class == KAG::Gather
106
+ false
107
+ end
108
+ end
109
+
110
+ def self.remove(gather,message,user)
111
+ if KAG::Config.data[:reported] and KAG::Config.data[:reported].key?(user.authname.to_sym)
112
+ KAG::Config.data[:reported].delete(user.authname.to_sym)
113
+ KAG::Config.data.save
114
+
115
+ gather.reply message,"User #{user.nick} removed from report list." if gather.class == KAG::Gather
116
+ true
117
+ else
118
+ gather.reply message,"User #{user.nick} not in report list!" if gather.class == KAG::Gather
119
+ false
120
+ end
121
+ end
122
+
123
+ def self.unignore(gather,message,user)
124
+ if KAG::Config.data[:ignored] and KAG::Config.data[:ignored].key?(user.authname.to_sym)
125
+ KAG::Config.data[:ignored].delete(user.authname.to_sym)
126
+ KAG::Config.data.save
127
+
128
+ gather.reply message,"User #{user.nick} removed from ignore list." if gather.class == KAG::Gather
129
+ true
130
+ else
131
+ gather.reply message,"User #{user.nick} not in ignore list!" if gather.class == KAG::Gather
132
+ false
133
+ end
134
+ end
135
+
136
+ def self.reports(user)
137
+ if KAG::Config.data[:reported] and KAG::Config.data[:reported].key?(user.authname.to_sym)
138
+ KAG::Config.data[:reported][user.authname.to_sym][:count]
139
+ else
140
+ false
141
+ end
142
+ end
143
+
144
+ def self.is_banned?(user)
145
+ KAG::Config.data[:ignored] = {} unless KAG::Config.data[:ignored]
146
+ begin
147
+ KAG::Config.data[:ignored].key?(user.authname.to_sym)
148
+ rescue Exception => e
149
+ puts e.message
150
+ end
151
+ end
152
+
153
+ def self.list
154
+ if KAG::Config.data[:ignored]
155
+ KAG::Config.data[:ignored].keys
156
+ else
157
+ []
158
+ end
159
+ end
160
+
161
+ protected
162
+
163
+ def data
164
+ KAG::Config.data
165
+ end
166
+
167
+ def _report
168
+ data[:reported][self[:authname].to_sym]
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,42 @@
1
+ require 'patches'
2
+ require 'cinch'
3
+ require 'kag/config'
4
+ require 'kag/data'
5
+ require 'kag/gather/plugin'
6
+ require 'kag/bans/plugin'
7
+ require 'kag/irc/plugin'
8
+ require 'kag/bot/plugin'
9
+ require 'commands/help'
10
+
11
+ module KAG
12
+ module Bot
13
+ class Bot
14
+ def initialize
15
+ config = self.config
16
+ bot = Cinch::Bot.new do
17
+ configure do |c|
18
+ c.server = config[:server]
19
+ c.channels = config[:channels]
20
+ c.port = config[:port].to_i > 0 ? config[:port] : 6667
21
+ #c.ssl = config[:ssl]
22
+ c.nick = config[:nick].to_s != "" ? config[:nick] : "KAGatherer"
23
+ c.realname = config[:realname].to_s != "" ? config[:realname] : "KAG Gatherer"
24
+ c.messages_per_second = 1
25
+ c.server_queue_size = 1
26
+ c.plugins.plugins = [Cinch::Commands::Help,KAG::Bot::Plugin,KAG::Gather::Plugin,KAG::Bans::Plugin,KAG::IRC::Plugin]
27
+ if config[:sasl]
28
+ c.sasl.username = config[:sasl][:username]
29
+ c.sasl.password = config[:sasl][:password]
30
+ end
31
+ end
32
+ end
33
+
34
+ bot.start
35
+ end
36
+
37
+ def config
38
+ KAG::Config.instance
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,56 @@
1
+ require 'cinch'
2
+ require 'kag/common'
3
+ require 'commands/help'
4
+
5
+ module KAG
6
+ module Bot
7
+ class Plugin
8
+ include Cinch::Plugin
9
+ include Cinch::Commands
10
+ include KAG::Common
11
+
12
+ command :quit,{},
13
+ summary: "Quit the bot",
14
+ admin: true
15
+ def quit(m)
16
+ if is_admin(m.user)
17
+ m.bot.quit("Shutting down...")
18
+ end
19
+ end
20
+
21
+ command :restart,{},
22
+ summary: "Restart the bot",
23
+ admin: true
24
+ def restart(m)
25
+ if is_admin(m.user)
26
+ cmd = (KAG::Config.instance[:restart_method] or "nohup sh gather.sh &")
27
+ debug cmd
28
+ pid = spawn cmd
29
+ debug "Restarting bot, new process ID is #{pid.to_s} ..."
30
+ exit
31
+ end
32
+ end
33
+
34
+ command :is_an_admin,{nick: :string},
35
+ summary: "See if the specified user is an Admin"
36
+ def is_an_admin(m,nick)
37
+ u = User(nick)
38
+ if is_admin(u)
39
+ reply m,"Yes, #{nick} is an admin!"
40
+ else
41
+ reply m,"No, #{nick} is not an admin."
42
+ end
43
+ end
44
+
45
+ command :reload_config,{},
46
+ summary: "Reload the configuration file",
47
+ admin: true
48
+ def reload_config(m)
49
+ if is_admin(m.user)
50
+ KAG::Config.instance.reload
51
+ m.reply "Configuration reloaded."
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
data/lib/kag/common.rb ADDED
@@ -0,0 +1,34 @@
1
+
2
+ module KAG
3
+ module Common
4
+ include Cinch::Plugin
5
+
6
+ def reply(message,text,colorize = true)
7
+ text = Format(:grey,text) if colorize
8
+ message.reply text
9
+ end
10
+
11
+ def send_channels_msg(msg,colorize = true)
12
+ KAG::Config.instance[:channels].each do |c|
13
+ msg = Format(:grey,msg) if colorize
14
+ Channel(c).send(msg)
15
+ end
16
+ end
17
+
18
+ def is_banned?(user)
19
+ KAG::Bans::Report.is_banned?(user)
20
+ end
21
+
22
+ def debug(msg)
23
+ if KAG::Config.instance[:debug]
24
+ puts msg
25
+ end
26
+ end
27
+
28
+ def is_admin(user)
29
+ user.refresh
30
+ o = (KAG::Config.instance[:owners] or [])
31
+ o.include?(user.authname)
32
+ end
33
+ end
34
+ end