Change soft-fail to use the config, rather than env
[rbx.git] / tools / rubuildius / matzbot / lib / commands.rb
blob10c0b6952b8ff7c0a8ad4c2e9a2cb85649eb2df9
1 require 'set'
2 require 'yaml'
4 module MatzBot
5   module Commands
6     extend self
8     def help(data)
9       config[:hidden_methods] ||= []
10       hidden = config[:hidden_methods].map { |m| m.to_s }
11       if is_admin?
12         commands = protected_instance_methods(false) - hidden
13         command  = :pm
14       else 
15         commands = public_instance_methods(false) - hidden
16         command  = :say
17       end
19       send(command, "Commands I know: \0037 #{commands.sort * ', '}")
20     end
22     def action(data)
23       data = [data].flatten
24       socket.puts "PRIVMSG #{config[:channel]} :\01ACTION #{data * ' '}\01"
25       sleep 1
26     end
28     def say(data, channel = config[:channel])
29       data = data.join(" ") if data.is_a?(Array)
30       data.split("\n").each do |message|
31         message = filters(:say).inject(message) do |string, filter|
32           filter.call(string)
33         end if filters(:say).size.nonzero?
34         while message 
35           fragment, message = message[0..450], message[450..-1]
36           socket.puts "PRIVMSG #{channel} :#{fragment}"          
37         end
38         sleep 1
39       end
40       nil
41     end
42     alias :puts :say
43     private :puts
45     def save!(data)
46       Session.save
47       puts "Saved session data. ;)"
48     end
50   protected
51     def quit(data)
52       socket.puts "QUIT :#{data.shift}"
53       exit
54     end
55     
56     def update_nick(data)
57       socket.puts "NICK :#{nick = data.shift}"
58       config[:nick] = nick
59     end
61  private
62     def session
63       Session.session
64     end
66     def reply(string)
67       say "#{Client.last_nick}: #{string}" if Client.last_nick
68     end
70     def pm(data, nick = Client.last_nick)
71       say(data, nick)
72     end
74     # filter :say => :drunk_say
75     # filter :listen => :google_translate
76     def filter(type_and_methods)
77       type = type_and_methods.keys.first
78       Array(type_and_methods[type]).each do |method|
79         filters(type) <<
80           case method
81           when Symbol, String then proc { |message| send(method, message) }     
82           when Proc then method
83           end
84       end
85     end
87     def filters(type)
88       $filters ||= {}
89       $filters[type.to_sym] ||= Set.new
90     end
92     def reload_filters!
93       $filters.clear if $filters
94     end
96     def help_method(options = {})
97       # help_method :svn => [ :add_repo, :clear_repos ]
98       options.each do |method, wraps|
99         define_method(method) do |*data|
100           wraps.map! { |m| m.to_s } 
101           command = :pm
102           unless is_admin?
103             wraps -= protected_instance_methods(false)
104             command = :say
105           end
106           send(command, "Commands for `#{method}': #{wraps.sort * ', '}")
107         end
108         config[:hidden_methods] ||= Set.new
109         config[:hidden_methods] += wraps.map { |m| m.to_s }
110       end
111     end
113     def socket
114       Client.socket
115     end
117     def config
118       Client.config ||= {}
119     end
121     def is_admin?
122       Client.authorized
123     end
125     def needs_gem(hash)
126       # needs_gem 'hpricot' => [ :method1, :method2 ]
127       config[:failed_methods] ||= Set.new
128       gem = ''
129       hash.keys.each { |gem| require gem }
130     rescue LoadError
131       config[:failed_methods] += Array(hash[gem])
132     end
134     def method_added(method)
135       config[:failed_methods] ||= Set.new
136       remove_method method if config[:failed_methods].include?(method)
137     end
138   end