]> git.netwichtig.de Git - user/henk/code/ruby/weechat-samechannel.git/blob - samechannel.rb
On branch master
[user/henk/code/ruby/weechat-samechannel.git] / samechannel.rb
1 #
2 # (c) Hendrik 'henk' Jaeger <weechat@henk.geekmail.org>
3 #
4
5 def weechat_init
6   Weechat.register(
7     "samechannel",
8     "henk",
9     "0.0.1",
10     "GPL3",
11     "Lists multiple occurences of the same nick(s) in a set of channels.",
12     "",
13     ""
14   )
15
16   Weechat.hook_command(
17     "samechannel",
18     "Lists multiple occurences of the same nick(s) in a set of channels.",
19     "[[-s|--servers] servername[,...]] [[-c|--channels] channelname[,...]] [[-n|--nicks] nickname[,...]]",
20     "--servers servername[,servername],...]
21 --channels channelname[@servername][,channelname[@servername],...]
22 --nicks nickname[,nickname,...]
23 Options used to set filters. All given names are treated as regular expressions. If no names are given, no filters are set.
24
25 WARNING: If you are joined to MANY or even just a few very crowded channels, this script may have to do a lot of comparisons!
26
27 NOTE: Only nicknames from channels the client is joined to are available for comparison!
28     
29 EXAMPLES:
30     /samechannel --channels foo
31     Lists nicks found in more than two channels on all servers.
32     
33     /samechannel --nicks barbaz,hons --servers example,foobarbaz
34     Lists channels from the servers example and foobarbaz for each given nick.
35     
36     /samechannel --nicks foo --channels ^#example.*@.*free.*$
37     Lists channels you share with nick foo that begin with 'example' from every server with 'free' in their names.",
38     "-servers %(irc_servers)
39     || -servers %(irc_servers) -channels %(irc_channels)
40     || -servers %(irc_servers) -nicks %(irc_server_nicks)
41     || -channels %(irc_channels)
42     || -channels %(irc_channels) -servers %(irc_servers)
43     || -channels %(irc_channels) -nicks %(irc_server_nicks)
44     || -nicks %(irc_server_nicks)
45     || -nicks %(irc_server_nicks) -servers %(irc_servers)
46     || -nicks %(irc_server_nicks) -channels %(irc_channels)",
47     "samechannel_cb",
48     ""
49   )
50
51   require 'shellwords'
52   require 'optparse'
53
54   $hdata_ircserver = Weechat.hdata_get('irc_server')
55   $hdata_ircchannel = Weechat.hdata_get('irc_channel')
56   $hdata_ircnick = Weechat.hdata_get('irc_nick')
57
58   return Weechat::WEECHAT_RC_OK
59 end
60
61 def samechannel_cb( data, buffer, args )
62   options = get_options( args.shellsplit )
63
64   serverchannelptrs = Hash.new
65   nickcount = Hash.new
66
67   serverptrs = find_servers(options[:serverfilter])
68
69   serverptrs.each do |serverptr|
70     serverchannelptrs[serverptr] = find_channels(options[:channelfilter], serverptr)
71   end
72
73   serverchannelptrs.each_pair do |serverptr, channelptrs|
74     servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name')
75     own_nick = Weechat.hdata_string($hdata_ircserver, serverptr, 'nick')
76
77     channelptrs.each do |channelptr|
78       channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name')
79
80       find_nicks(options[:nickfilter], channelptr).each do |nickptr|
81         nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name')
82         next if nickname == own_nick
83         (nickcount[nickname] ||= Array.new) << [channelname, servername].join('@')
84       end
85     end
86   end
87
88   duplicate_nicks = nickcount.delete_if do |nickname, nickpaths|
89     nickpaths.length <= 1
90   end
91   duplicate_nicks_sorted = duplicate_nicks.sort do |a, b|
92     a[1].length <=> b[1].length
93   end
94   duplicate_nicks_sorted.each do |nickname, nickpaths|
95     Weechat.print("", "#{Weechat.color('yellow')}#{nickname}#{Weechat.color('chat')} appeared #{nickpaths.length} times: #{nickpaths.join(', ')}")
96   end
97
98   return Weechat::WEECHAT_RC_OK
99 end
100
101 def find_nicks( names, channelptr )
102   all_nicks = hhh_get_ptrarray($hdata_ircnick, Weechat.hdata_pointer($hdata_ircchannel, channelptr, 'nicks'))
103   if names
104     all_nicks.find_all do |nickptr|
105       nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name')
106       foundnames = names.any? do |name|
107         Regexp.new(name).match(nickname)
108       end
109     end
110   else
111     return all_nicks
112   end
113 end
114
115 def find_channels( names, serverptr )
116   servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name')
117   all_channels = hhh_get_ptrarray($hdata_ircchannel, Weechat.hdata_pointer($hdata_ircserver, serverptr, 'channels'))
118   if names
119     all_channels.find_all do |channelptr|
120       channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name')
121       foundnames = names.any? do |name|
122         name_re = Regexp.new(name)
123         if /.*@.*/.match(name)
124           name_re.match(channelname + '@' + servername)
125         else
126           name_re.match(channelname)
127         end
128       end
129     end
130   else
131     return all_channels
132   end
133 end
134
135 def find_servers( names )
136   serverptrlist = Weechat.hdata_get_list($hdata_ircserver, 'irc_servers')
137   if names
138     matching_servers = names.map do |name|
139       foundserverptr = Weechat.hdata_search($hdata_ircserver, serverptrlist, '${irc_server.name} =~ ' + name, 1)
140     end
141   else
142     return hhh_get_ptrarray($hdata_ircserver, serverptrlist)
143   end
144 end
145
146 def hhh_get_ptrarray( hdata, pointer )
147   pointers = Array.new
148   begin
149     pointers << pointer unless pointer.empty?
150   end until (pointer = Weechat.hdata_move(hdata, pointer, 1)).empty?
151   return pointers
152 end
153
154 def get_options( args )
155   options = Hash.new
156
157   opt_parser = OptionParser.new do |opts|
158     opts.on("-c", "--channels channelname[,channelname,...]",
159             "Only channels matching the given (partial) channelname(s) will be considered.)") do |channels|
160       options[:channelfilter] = channels.split(',')
161     end
162
163     opts.on("-n", "--nicks nickname[,nickname,...]",
164             "Only nicks matching the given (partial) nickname(s) will be considered.)") do |nicks|
165       options[:nickfilter] = nicks.split(',')
166     end
167
168     opts.on("-s", "--servers servername[,servername,...]",
169             "Only servers matching the given (partial) servername(s) will be considered.)") do |servers|
170       options[:serverfilter] = servers.split(',')
171     end
172   end
173
174   opt_parser.parse(args)
175
176   return options
177 end
178
179
180
181
182
183
184
185
186
187
188
189 #  buffer_plugin = Weechat.buffer_get_string(buffer, "localvar_plugin")
190 #  buffer_type = Weechat.buffer_get_string(buffer, "localvar_type")
191 #  buffer_server = Weechat.buffer_get_string(buffer, "localvar_server")
192
193 #  args_string
194 #  optionargs = args_string.scan(/-#{optionname} ([^[:space:],]+,?)+/)
195 #end
196
197 #def get_all_servers
198 #  return hhh_get_ptrarray($hdata_ircserver, Weechat.hdata_get_list($hdata_ircserver, 'irc_servers'))
199 #end
200