]> git.rmz.io Git - dotfiles.git/blob - weechat/ruby/samechannel.rb
bin: add script to output curses colors
[dotfiles.git] / weechat / ruby / samechannel.rb
1 #
2 # (c) 2013 Hendrik 'henk' Jaeger <weechat@henk.geekmail.org>
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17
18 def weechat_init
19 Weechat.register(
20 "samechannel",
21 "henk",
22 "0.0.1",
23 "GPL3",
24 "Lists multiple occurences of the same nick(s) in a set of channels.",
25 "",
26 ""
27 )
28
29 Weechat.hook_command(
30 "samechannel",
31 "Lists multiple occurences of the same nick(s) in a set of channels.",
32 "[[-s|--servers] servername[,...]] [[-c|--channels] channelname[,...]] [[-n|--nicks] nickname[,...]]",
33 "--servers servername[,servername],...]
34 --channels channelname[@servername][,channelname[@servername],...]
35 --nicks nickname[,nickname,...]
36 Options used to set filters. All given names are treated as regular expressions. If no names are given, no filters are set.
37
38 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!
39
40 NOTE: Only nicknames from channels the client is joined to are available for comparison!
41
42 EXAMPLES:
43 /samechannel --channels foo
44 Lists nicks found in more than two channels on all servers.
45
46 /samechannel --nicks barbaz,hons --servers example,foobarbaz
47 Lists channels from the servers example and foobarbaz for each given nick.
48
49 /samechannel --nicks foo --channels ^#example.*@.*free.*$
50 Lists channels you share with nick foo that begin with 'example' from every server with 'free' in their names.",
51 "-servers %(irc_servers)
52 || -servers %(irc_servers) -channels %(irc_channels)
53 || -servers %(irc_servers) -nicks %(irc_server_nicks)
54 || -channels %(irc_channels)
55 || -channels %(irc_channels) -servers %(irc_servers)
56 || -channels %(irc_channels) -nicks %(irc_server_nicks)
57 || -nicks %(irc_server_nicks)
58 || -nicks %(irc_server_nicks) -servers %(irc_servers)
59 || -nicks %(irc_server_nicks) -channels %(irc_channels)",
60 "samechannel_cb",
61 ""
62 )
63
64 require 'shellwords'
65 require 'optparse'
66
67 $hdata_ircserver = Weechat.hdata_get('irc_server')
68 $hdata_ircchannel = Weechat.hdata_get('irc_channel')
69 $hdata_ircnick = Weechat.hdata_get('irc_nick')
70
71 return Weechat::WEECHAT_RC_OK
72 end
73
74 def samechannel_cb( data, buffer, args )
75 options = get_options( args.shellsplit )
76
77 serverchannelptrs = Hash.new
78 nickcount = Hash.new
79
80 serverptrs = find_servers(options[:serverfilter])
81
82 serverptrs.each do |serverptr|
83 serverchannelptrs[serverptr] = find_channels(options[:channelfilter], serverptr)
84 end
85
86 serverchannelptrs.each_pair do |serverptr, channelptrs|
87 servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name')
88 own_nick = Weechat.hdata_string($hdata_ircserver, serverptr, 'nick')
89
90 channelptrs.each do |channelptr|
91 channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name')
92
93 find_nicks(options[:nickfilter], channelptr).each do |nickptr|
94 nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name')
95 next if nickname == own_nick
96 (nickcount[nickname] ||= Array.new) << [channelname, servername].join('@')
97 end
98 end
99 end
100
101 duplicate_nicks = nickcount.delete_if do |nickname, nickpaths|
102 nickpaths.length <= 1
103 end
104 duplicate_nicks_sorted = duplicate_nicks.sort do |a, b|
105 a[1].length <=> b[1].length
106 end
107 duplicate_nicks_sorted.each do |nickname, nickpaths|
108 Weechat.print("", "#{Weechat.color('yellow')}#{nickname}#{Weechat.color('chat')} appeared #{nickpaths.length} times: #{nickpaths.join(', ')}")
109 end
110
111 return Weechat::WEECHAT_RC_OK
112 end
113
114 def find_nicks( names, channelptr )
115 all_nicks = hhh_get_ptrarray($hdata_ircnick, Weechat.hdata_pointer($hdata_ircchannel, channelptr, 'nicks'))
116 if names
117 all_nicks.find_all do |nickptr|
118 nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name')
119 foundnames = names.any? do |name|
120 Regexp.new(name).match(nickname)
121 end
122 end
123 else
124 return all_nicks
125 end
126 end
127
128 def find_channels( names, serverptr )
129 servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name')
130 all_channels = hhh_get_ptrarray($hdata_ircchannel, Weechat.hdata_pointer($hdata_ircserver, serverptr, 'channels'))
131 if names
132 all_channels.find_all do |channelptr|
133 channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name')
134 foundnames = names.any? do |name|
135 name_re = Regexp.new(name)
136 if /.*@.*/.match(name)
137 name_re.match(channelname + '@' + servername)
138 else
139 name_re.match(channelname)
140 end
141 end
142 end
143 else
144 return all_channels
145 end
146 end
147
148 def find_servers( names )
149 serverptrlist = Weechat.hdata_get_list($hdata_ircserver, 'irc_servers')
150 if names
151 matching_servers = names.map do |name|
152 foundserverptr = Weechat.hdata_search($hdata_ircserver, serverptrlist, '${irc_server.name} =~ ' + name, 1)
153 end
154 else
155 return hhh_get_ptrarray($hdata_ircserver, serverptrlist)
156 end
157 end
158
159 def hhh_get_ptrarray( hdata, pointer )
160 pointers = Array.new
161 begin
162 pointers << pointer unless pointer.empty?
163 end until (pointer = Weechat.hdata_move(hdata, pointer, 1)).empty?
164 return pointers
165 end
166
167 def get_options( args )
168 options = Hash.new
169
170 opt_parser = OptionParser.new do |opts|
171 opts.on("-c", "--channels channelname[,channelname,...]",
172 "Only channels matching the given (partial) channelname(s) will be considered.)") do |channels|
173 options[:channelfilter] = channels.split(',')
174 end
175
176 opts.on("-n", "--nicks nickname[,nickname,...]",
177 "Only nicks matching the given (partial) nickname(s) will be considered.)") do |nicks|
178 options[:nickfilter] = nicks.split(',')
179 end
180
181 opts.on("-s", "--servers servername[,servername,...]",
182 "Only servers matching the given (partial) servername(s) will be considered.)") do |servers|
183 options[:serverfilter] = servers.split(',')
184 end
185 end
186
187 opt_parser.parse(args)
188
189 return options
190 end