]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/topic.rb
script echo needs a to_s
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / topic.rb
1 # Author: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
2 # Add a bunch of topic manipulation features
3
4 class TopicPlugin < Plugin
5   def initialize
6     super
7     @separator = "|" # default separator
8   end
9
10   def help(plugin, topic="")
11     case plugin
12     when "topic"
13       case topic
14       when "add"
15         return "topic add <text> => add <text> at the end the topic"
16       when "prepend"
17         return "topic prepend <text> => add <text> at the beginning of the topic"
18       when "addat"
19         return "topic addat <num> <text> => add <text> at position <num> of the topic"
20       when "del", "delete"
21         return "topic del <num> => remove section <num> from the topic"
22       when "replace"
23         return "topic replace <num> <text> => Replaces section <num> with <text>"
24       when "sep", "separator"
25         return "topic sep(arator) [<text>] => get or set the topic section separator"
26       when "learn"
27         return "topic learn => remembers the topic for later"
28       when "restore"
29         return "topic restore => resets the topic to the latest remembered one"
30       when "clear"
31         return "topic clear => clears the topic"
32       when "set"
33         return "topic set <text> => sets the topic to <text>"
34       else
35         return "topic add(at)|prepend|del(ete)|replace|sep(arator)|learn|restore|clear|set: " + \
36                "manipulate the topic of the current channel; use topic <#channel> <command> " + \
37                "for private addressing"
38       end
39     end
40   end
41
42   def handletopic(m, param)
43     return unless m.kind_of?(PrivMessage)
44     if m.public?
45       ch = m.channel
46     else
47       ch = m.server.get_channel(param[:channel])
48       unless ch
49         m.reply("I am not in channel #{param[:channel]}")
50         return
51       end
52     end
53     cmd = param[:command]
54     txt = param[:text].to_s
55
56     case cmd
57     when /^a(dd|ppend)$/
58       topicappend(m, ch, txt)
59     when 'prepend'
60       topicprepend(m, ch, txt)
61     when 'addat'
62       if txt =~ /\s*(-?\d+)\s+(.*)\s*/
63         num = $1.to_i - 1
64         num += 1 if num < 0
65         txt = $2
66         topicaddat(m, ch, num, txt)
67       end
68     when /^del(ete)?$/
69       if txt =~ /\s*(-?\d+)\s*/
70         num=$1.to_i - 1
71         num += 1 if num < 0
72         topicdel(m, ch, num)
73       end
74     when 'set'
75       topicset(m, ch, txt)
76     when 'clear'
77       topicset(m, ch, '')
78     when /^sep(arator)?$/
79       topicsep(m, ch, txt)
80     when 'learn'
81       learntopic(m, ch)
82     when 'replace'
83       if txt =~ /\s*(-?\d+)\s+(.*)\s*/
84         num = $1.to_i - 1
85         num += 1 if num < 0
86         txt = $2
87         replacetopic(m, ch, num, txt)
88       end
89     when 'restore'
90       restoretopic(m, ch)
91     else
92       m.reply 'unknown command'
93     end
94   end
95
96   def topicsep(m, ch, txt)
97     return if !@bot.auth.allow?("topic::edit::separator", m.source, m.replyto)
98     if txt
99       sep = txt.strip
100       if sep != ""
101         setsep(ch, sep)
102       end
103     end
104     m.reply "Topic separator set to #{getsep(ch)}"
105   end
106
107   def setsep(ch, sep)
108     raise unless ch.class <= Irc::Channel
109     # TODO multiserver
110     k = ch.downcase
111
112     if @registry.has_key?(k)
113       data = @registry[k]
114     else
115       data = Hash.new
116     end
117
118     oldsep = getsep(ch)
119     topic = ch.topic.text
120     topicarray = topic.split(/\s+#{Regexp.escape(oldsep)}\s*/)
121
122     if sep != oldsep and topicarray.length > 0
123       newtopic = topicarray.join(" #{sep} ")
124       @bot.topic ch, newtopic
125     end
126
127     data[:separator] = sep
128     @registry[k] = data
129   end
130
131   def getsep(ch)
132     raise unless ch.class <= Irc::Channel
133     # TODO multiserver
134     k = ch.downcase
135
136     if @registry.has_key?(k)
137       if @registry[k].has_key?(:separator)
138         return @registry[k][:separator]
139       end
140     end
141     return @separator
142   end
143
144   def topicaddat(m, channel, num, txt)
145     return if !@bot.auth.allow?("topic::edit::add", m.source, m.replyto)
146     sep = getsep(channel)
147     topic = channel.topic.to_s
148     topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
149     topicarray.insert(num, txt)
150     newtopic = topicarray.join(" #{sep} ")
151     @bot.topic channel, newtopic
152   end
153
154   def topicappend(m, ch, txt)
155     topicaddat(m, ch, -1, txt)
156   end
157
158   def topicprepend(m, ch, txt)
159     topicaddat(m, ch, 0, txt)
160   end
161
162   def topicdel(m, channel, num)
163     return if !@bot.auth.allow?("topic::edit::del", m.source, m.replyto)
164     sep = getsep(channel)
165     topic = channel.topic.to_s
166     topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
167     topicarray.delete_at(num)
168     newtopic = topicarray.join(" #{sep} ")
169     @bot.topic channel, newtopic
170   end
171
172   def learntopic(m, channel)
173     return if !@bot.auth.allow?("topic::store::store", m.source, m.replyto)
174     topic = channel.topic.to_s
175     k = channel.downcase
176     if @registry.has_key?(k)
177       data = @registry[k]
178     else
179       data = Hash.new
180     end
181     data[:topic] = topic
182     @registry[k] = data
183     m.okay
184   end
185
186   def replacetopic(m, channel, num, txt)
187     return if !@bot.auth.allow?("topic::edit::replace", m.source, m.replyto)
188     sep = getsep(channel)
189     topic = channel.topic.to_s
190     topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
191     topicarray[num] = txt
192     newtopic = topicarray.join(" #{sep} ")
193     @bot.topic channel, newtopic
194   end
195
196   def restoretopic(m, channel)
197     return if !@bot.auth.allow?("topic::store::restore", m.source, m.replyto)
198     return if !@bot.auth.allow?("restoretopic", m.source, m.replyto)
199     k = channel.downcase
200     if @registry.has_key?(k) && @registry[k].has_key?(:topic)
201       topic = @registry[k][:topic]
202       topicset(m, channel, topicl
203     else
204       m.reply "I don't remember any topic for this channel"
205     end
206   end
207
208   def topicset(m, channel, text)
209     return if !@bot.auth.allow?("topic::edit::replace", m.source, m.replyto)
210     @bot.topic channel, text
211   end
212
213 end
214 plugin = TopicPlugin.new
215
216 plugin.map 'topic :command *text', :action => 'handletopic', :public => true, :private => false
217 plugin.map 'topic :channel :command *text', :action => 'handletopic', :public => false, :private => true
218
219 plugin.default_auth('*', false)
220
221