]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/topic.rb
0b266851a2faca929d1ced357b6ca340e90c6ede
[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       return m.reply "I am not in channel #{ch}" unless ch
49     end
50     cmd = param[:command]
51     txt = param[:text].join(" ")
52
53     case cmd
54     when /^a(dd|ppend)$/
55       topicappend(m, ch, txt)
56     when 'prepend'
57       topicprepend(m, ch, txt)
58     when 'addat'
59       if txt =~ /\s*(-?\d+)\s+(.*)\s*/
60         num = $1.to_i - 1
61         num += 1 if num < 0
62         txt = $2
63         topicaddat(m, ch, num, txt)
64       end
65     when /^del(ete)?$/
66       if txt =~ /\s*(-?\d+)\s*/
67         num=$1.to_i - 1
68         num += 1 if num < 0
69         topicdel(m, ch, num)
70       end
71     when 'set'
72       topicset(m, ch, txt)
73     when 'clear'
74       topicset(m, ch, '')
75     when /^sep(arator)?$/
76       topicsep(m, ch, txt)
77     when 'learn'
78       learntopic(m, ch)
79     when 'replace'
80       if txt =~ /\s*(-?\d+)\s+(.*)\s*/
81         num = $1.to_i - 1
82         num += 1 if num < 0
83         txt = $2
84         replacetopic(m, ch, num, txt)
85       end
86     when 'restore'
87       restoretopic(m, ch)
88     else
89       m.reply 'unknown command'
90     end
91   end
92
93   def topicsep(m, ch, txt)
94     if txt
95       sep = txt.strip
96       if sep != ""
97         setsep(ch, sep)
98       end
99     end
100     m.reply "Topic separator set to #{getsep(ch)}"
101   end
102
103   def setsep(ch, sep)
104     raise unless ch.class <= Irc::Channel
105     # TODO multiserver
106     k = ch.downcase
107
108     if @registry.has_key?(k)
109       data = @registry[k]
110     else
111       data = Hash.new
112     end
113
114     oldsep = getsep(ch)
115     topic = ch.topic.text
116     topicarray = topic.split(/\s+#{Regexp.escape(oldsep)}\s*/)
117
118     if sep != oldsep and topicarray.length > 0
119       newtopic = topicarray.join(" #{sep} ")
120       @bot.topic ch, newtopic
121     end
122
123     data[:separator] = sep
124     @registry[k] = data
125   end
126
127   def getsep(ch)
128     raise unless ch.class <= Irc::Channel
129     # TODO multiserver
130     k = ch.downcase
131
132     if @registry.has_key?(k)
133       if @registry[k].has_key?(:separator)
134         return @registry[k][:separator]
135       end
136     end
137     return @separator
138   end
139
140   def topicaddat(m, channel, num, txt)
141     sep = getsep(channel)
142     topic = channel.topic.to_s
143     topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
144     topicarray.insert(num, txt)
145     newtopic = topicarray.join(" #{sep} ")
146     @bot.topic channel, newtopic
147   end
148
149   def topicappend(m, ch, txt)
150     topicaddat(m, ch, -1, txt)
151   end
152
153   def topicprepend(m, ch, txt)
154     topicaddat(m, ch, 0, txt)
155   end
156
157   def topicdel(m, channel, num)
158     sep = getsep(channel)
159     topic = channel.topic.to_s
160     topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
161     topicarray.delete_at(num)
162     newtopic = topicarray.join(" #{sep} ")
163     @bot.topic channel, newtopic
164   end
165
166   def learntopic(m, channel)
167     return if !@bot.auth.allow?("learntopic", m.source, m.replyto)
168     topic = channel.topic.to_s
169     k = channel.downcase
170     if @registry.has_key?(k)
171       data = @registry[k]
172     else
173       data = Hash.new
174     end
175     data[:topic] = topic
176     @registry[k] = data
177     m.okay
178   end
179
180   def replacetopic(m, channel, num, txt)
181     return if !@bot.auth.allow?("topic", m.source, m.replyto)
182     sep = getsep(channel)
183     topic = @bot.channels[channel].topic.to_s
184     topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
185     topicarray[num] = txt
186     newtopic = topicarray.join(" #{sep} ")
187     @bot.topic channel, newtopic
188   end
189
190   def restoretopic(m, channel)
191     return if !@bot.auth.allow?("restoretopic", m.source, m.replyto)
192     k = channel.downcase
193     if @registry.has_key?(k) && @registry[k].has_key?(:topic)
194       topic = @registry[k][:topic]
195       @bot.topic channel, topic
196     else
197       m.reply "I don't remember any topic for this channel"
198     end
199   end
200
201   def topicset(m, channel, text)
202     return if !@bot.auth.allow?("topic", m.source, m.replyto)
203     @bot.topic channel, text
204   end
205
206 end
207 plugin = TopicPlugin.new
208 plugin.map 'topic :command *text', :action => 'handletopic', :public => true, :private => false
209 plugin.map 'topic :channel :command *text', :action => 'handletopic', :public => false, :private => true
210