diff options
-rw-r--r-- | samechannel.rb | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/samechannel.rb b/samechannel.rb new file mode 100644 index 0000000..30a24ac --- /dev/null +++ b/samechannel.rb @@ -0,0 +1,200 @@ +# +# (c) Hendrik 'henk' Jaeger <weechat@henk.geekmail.org> +# + +def weechat_init + Weechat.register( + "samechannel", + "henk", + "0.0.1", + "GPL3", + "Lists multiple occurences of the same nick(s) in a set of channels.", + "", + "" + ) + + Weechat.hook_command( + "samechannel", + "Lists multiple occurences of the same nick(s) in a set of channels.", + "[[-s|--servers] servername[,...]] [[-c|--channels] channelname[,...]] [[-n|--nicks] nickname[,...]]", + "--servers servername[,servername],...] +--channels channelname[@servername][,channelname[@servername],...] +--nicks nickname[,nickname,...] +Options used to set filters. All given names are treated as regular expressions. If no names are given, no filters are set. + +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! + +NOTE: Only nicknames from channels the client is joined to are available for comparison! + +EXAMPLES: + /samechannel --channels foo + Lists nicks found in more than two channels on all servers. + + /samechannel --nicks barbaz,hons --servers example,foobarbaz + Lists channels from the servers example and foobarbaz for each given nick. + + /samechannel --nicks foo --channels ^#example.*@.*free.*$ + Lists channels you share with nick foo that begin with 'example' from every server with 'free' in their names.", + "-servers %(irc_servers) + || -servers %(irc_servers) -channels %(irc_channels) + || -servers %(irc_servers) -nicks %(irc_server_nicks) + || -channels %(irc_channels) + || -channels %(irc_channels) -servers %(irc_servers) + || -channels %(irc_channels) -nicks %(irc_server_nicks) + || -nicks %(irc_server_nicks) + || -nicks %(irc_server_nicks) -servers %(irc_servers) + || -nicks %(irc_server_nicks) -channels %(irc_channels)", + "samechannel_cb", + "" + ) + + require 'shellwords' + require 'optparse' + + $hdata_ircserver = Weechat.hdata_get('irc_server') + $hdata_ircchannel = Weechat.hdata_get('irc_channel') + $hdata_ircnick = Weechat.hdata_get('irc_nick') + + return Weechat::WEECHAT_RC_OK +end + +def samechannel_cb( data, buffer, args ) + options = get_options( args.shellsplit ) + + serverchannelptrs = Hash.new + nickcount = Hash.new + + serverptrs = find_servers(options[:serverfilter]) + + serverptrs.each do |serverptr| + serverchannelptrs[serverptr] = find_channels(options[:channelfilter], serverptr) + end + + serverchannelptrs.each_pair do |serverptr, channelptrs| + servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name') + own_nick = Weechat.hdata_string($hdata_ircserver, serverptr, 'nick') + + channelptrs.each do |channelptr| + channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name') + + find_nicks(options[:nickfilter], channelptr).each do |nickptr| + nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name') + next if nickname == own_nick + (nickcount[nickname] ||= Array.new) << [channelname, servername].join('@') + end + end + end + + duplicate_nicks = nickcount.delete_if do |nickname, nickpaths| + nickpaths.length <= 1 + end + duplicate_nicks_sorted = duplicate_nicks.sort do |a, b| + a[1].length <=> b[1].length + end + duplicate_nicks_sorted.each do |nickname, nickpaths| + Weechat.print("", "#{Weechat.color('yellow')}#{nickname}#{Weechat.color('chat')} appeared #{nickpaths.length} times: #{nickpaths.join(', ')}") + end + + return Weechat::WEECHAT_RC_OK +end + +def find_nicks( names, channelptr ) + all_nicks = hhh_get_ptrarray($hdata_ircnick, Weechat.hdata_pointer($hdata_ircchannel, channelptr, 'nicks')) + if names + all_nicks.find_all do |nickptr| + nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name') + foundnames = names.any? do |name| + Regexp.new(name).match(nickname) + end + end + else + return all_nicks + end +end + +def find_channels( names, serverptr ) + servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name') + all_channels = hhh_get_ptrarray($hdata_ircchannel, Weechat.hdata_pointer($hdata_ircserver, serverptr, 'channels')) + if names + all_channels.find_all do |channelptr| + channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name') + foundnames = names.any? do |name| + name_re = Regexp.new(name) + if /.*@.*/.match(name) + name_re.match(channelname + '@' + servername) + else + name_re.match(channelname) + end + end + end + else + return all_channels + end +end + +def find_servers( names ) + serverptrlist = Weechat.hdata_get_list($hdata_ircserver, 'irc_servers') + if names + matching_servers = names.map do |name| + foundserverptr = Weechat.hdata_search($hdata_ircserver, serverptrlist, '${irc_server.name} =~ ' + name, 1) + end + else + return hhh_get_ptrarray($hdata_ircserver, serverptrlist) + end +end + +def hhh_get_ptrarray( hdata, pointer ) + pointers = Array.new + begin + pointers << pointer unless pointer.empty? + end until (pointer = Weechat.hdata_move(hdata, pointer, 1)).empty? + return pointers +end + +def get_options( args ) + options = Hash.new + + opt_parser = OptionParser.new do |opts| + opts.on("-c", "--channels channelname[,channelname,...]", + "Only channels matching the given (partial) channelname(s) will be considered.)") do |channels| + options[:channelfilter] = channels.split(',') + end + + opts.on("-n", "--nicks nickname[,nickname,...]", + "Only nicks matching the given (partial) nickname(s) will be considered.)") do |nicks| + options[:nickfilter] = nicks.split(',') + end + + opts.on("-s", "--servers servername[,servername,...]", + "Only servers matching the given (partial) servername(s) will be considered.)") do |servers| + options[:serverfilter] = servers.split(',') + end + end + + opt_parser.parse(args) + + return options +end + + + + + + + + + + + +# buffer_plugin = Weechat.buffer_get_string(buffer, "localvar_plugin") +# buffer_type = Weechat.buffer_get_string(buffer, "localvar_type") +# buffer_server = Weechat.buffer_get_string(buffer, "localvar_server") + +# args_string +# optionargs = args_string.scan(/-#{optionname} ([^[:space:],]+,?)+/) +#end + +#def get_all_servers +# return hhh_get_ptrarray($hdata_ircserver, Weechat.hdata_get_list($hdata_ircserver, 'irc_servers')) +#end + |