2 # (c) 2013 Hendrik 'henk' Jaeger <weechat@henk.geekmail.org> 
   3 # (c) 2015 arza <arza@arza.us> 
   5 # This program is free software; you can redistribute it and/or modify 
   6 # it under the terms of the GNU General Public License as published by 
   7 # the Free Software Foundation; either version 3 of the License, or 
   8 # (at your option) any later version. 
  10 # This program is distributed in the hope that it will be useful, 
  11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  13 # GNU General Public License for more details. 
  15 # You should have received a copy of the GNU General Public License 
  16 # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  20 # 2013-10-19 0.0.1 henk: 
  22 # 2015-09-24 0.1 arza: 
  23 #  - option -m/--minimum for minimum count of mutual channels 
  32     "Lists multiple occurences of the same nick(s) in a set of channels.", 
  39     "Lists multiple occurences of the same nick(s) in a set of channels.", 
  40     "[-s/--servers servername[,...]] [-c/--channels channelname[,...]] [-n/--nicks nickname[,...]] [-m/--minimum minimum]", 
  41     "--servers servername[,servername],...] 
  42 --channels channelname[@servername][,channelname[@servername],...] 
  43 --nicks nickname[,nickname,...] 
  44 --minimum minimum (default: 2) 
  46 Options used to set filters. All given names are treated as regular expressions. If no names are given, no filters are set. 
  48 NOTE: Only nicknames from channels the client is joined to are available for comparison! 
  52     /samechannel 
-m 
5 -s freenode
,IRCnet
 
  53     Lists nicks found on at least five channels 
in freenode 
and IRCnet combined
. 
  55     /samechannel 
--channels foo
 
  56     Lists nicks found on at least two channels that 
include 'foo' on all servers
. 
  58     /samechannel 
--nicks barbaz
,hons 
--servers example
,foobarbaz
 
  59     Lists channels from the servers example 
and foobarbaz 
for each given nick
. 
  61     /samechannel 
--nicks foo 
--channels ^
#example.*@.*free.*$ 
  62     Lists channels you share with nick foo that 
begin with 
'example' from every server with 
'free' in their names
.", 
  64     "|| --servers %(irc_servers) --minimum 
--channels 
%(irc_channels)" + 
  65     "|| --channels %(irc_channels) --servers 
%(irc_servers)" + 
  66     "|| --nicks %(irc_server_nicks) --servers 
%(irc_servers)", 
  74   $hdata_ircserver = Weechat.hdata_get('irc_server') 
  75   $hdata_ircchannel = Weechat.hdata_get('irc_channel') 
  76   $hdata_ircnick = Weechat.hdata_get('irc_nick') 
  78   return Weechat::WEECHAT_RC_OK 
  81 def samechannel_cb( data, buffer, args ) 
  82   options = get_options( args.shellsplit ) 
  84   serverchannelptrs = Hash.new 
  87   serverptrs = find_servers(options[:serverfilter]) 
  89   serverptrs.each do |serverptr| 
  90     serverchannelptrs[serverptr] = find_channels(options[:channelfilter], serverptr) 
  93   serverchannelptrs.each_pair do |serverptr, channelptrs| 
  94     servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name') 
  95     own_nick = Weechat.hdata_string($hdata_ircserver, serverptr, 'nick') 
  97     channelptrs.each do |channelptr| 
  98       channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name') 
 100       find_nicks(options[:nickfilter], channelptr).each do |nickptr| 
 101         nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name') 
 102         next if nickname == own_nick 
 103         (nickcount[nickname] ||= Array.new) << [channelname, servername].join('@') 
 108   minimum = options[:minimumfilter].to_i 
 109   minimum = 2 if minimum==0 
 111   duplicate_nicks = nickcount.delete_if do |nickname, nickpaths| 
 112     nickpaths.length < minimum 
 114   duplicate_nicks_sorted = duplicate_nicks.sort do |a, b| 
 115     a[1].length <=> b[1].length 
 117   duplicate_nicks_sorted.each do |nickname, nickpaths| 
 118     Weechat.print("", "#{Weechat.color('yellow')}#{nickname}#{Weechat.color('chat')} appeared 
#{nickpaths.length} times
: #{nickpaths.join(', ')}") 
 121   return Weechat::WEECHAT_RC_OK 
 124 def find_nicks( names, channelptr ) 
 125   all_nicks = hhh_get_ptrarray($hdata_ircnick, Weechat.hdata_pointer($hdata_ircchannel, channelptr, 'nicks')) 
 127     all_nicks.find_all do |nickptr| 
 128       nickname = Weechat.hdata_string($hdata_ircnick, nickptr, 'name') 
 129       foundnames = names.any? do |name| 
 130         Regexp.new(name).match(nickname) 
 138 def find_channels( names, serverptr ) 
 139   servername = Weechat.hdata_string($hdata_ircserver, serverptr, 'name') 
 140   all_channels = hhh_get_ptrarray($hdata_ircchannel, Weechat.hdata_pointer($hdata_ircserver, serverptr, 'channels')) 
 142     all_channels.find_all do |channelptr| 
 143       channelname = Weechat.hdata_string($hdata_ircchannel, channelptr, 'name') 
 144       foundnames = names.any? do |name| 
 145         name_re = Regexp.new(name) 
 146         if /.*@.*/.match(name) 
 147           name_re.match(channelname + '@' + servername
) 
 149           name_re
.match(channelname
) 
 158 def find_servers( names 
) 
 159   serverptrlist 
= Weechat
.hdata_get_list($hdata_ircserver, 'irc_servers') 
 161     matching_servers 
= names
.map 
do |name
| 
 162       foundserverptr 
= Weechat
.hdata_search($hdata_ircserver, serverptrlist
, '${irc_server.name} =~ ' + name
, 1) 
 165     return hhh_get_ptrarray($hdata_ircserver, serverptrlist
) 
 169 def hhh_get_ptrarray( hdata
, pointer 
) 
 172     pointers 
<< pointer 
unless pointer
.empty
? 
 173   end until (pointer 
= Weechat
.hdata_move(hdata
, pointer
, 1)).empty
? 
 177 def get_options( args 
) 
 180   opt_parser 
= OptionParser
.new 
do |opts
| 
 182     opts
.on("-c", "--channels channelname[,channelname,...]", 
 183             "Only channels matching the given (partial) channelname(s) will be considered.)") do |channels
| 
 184       options
[:channelfilter] = channels
.split(',') 
 187     opts
.on("-n", "--nicks nickname[,nickname,...]", 
 188             "Only nicks matching the given (partial) nickname(s) will be considered.)") do |nicks
| 
 189       options
[:nickfilter] = nicks
.split(',') 
 192     opts
.on("-s", "--servers servername[,servername,...]", 
 193             "Only servers matching the given (partial) servername(s) will be considered.)") do |servers
| 
 194       options
[:serverfilter] = servers
.split(',') 
 197     opts
.on("-m", "--minimum minimum", 
 198             "Only nicks with at least this many matches will be considered.") do |minimum
| 
 199       options
[:minimumfilter] = minimum
 
 204   opt_parser
.parse(args
)