#!/usr/local/bin/ruby -w # # $Id: offertop.rb,v 1.13 2010/07/17 16:13:43 cvs Exp $ # (c) 2005, Dirk Meyer, Im Grund 4, 34317 Habichtswald # based on wirk from:; # (C) 2002 by dpunkt.de, Armin Roehrl, Stefan Schmiedl, Clemens Wyss 2002-01-20 # # Updates on: # http://anime.dinoex.net/xdcc/tools/ # class LogHash < Hash attr_reader :re attr_reader :title attr_reader :art attr_reader :klammer # Hash mit Standardwert 0 def initialize( re, title, artm, klammer = 1 ) super(0) @re = re @title = title @art = art @klammer = klammer end # absteigend sortieren nach Werten # und abschneiden def populaerste(n) pop = sort { |a, b| b[1] <=> a[1] } pop[1...n] end def sum total = 0 each { |b, a| total += a } total end def printtop(n) $output.print sum, " #{@art}\n" $output.print size, " verschiedene #{@title}s\n" pop = populaerste(n) if not pop.nil? $output.print "Die beliebtesten #{@title}s: Zahl der #{@art}, #{@title}\n" pop.each { |b, a| $output.printf "%7d\t%s\n", a, b } end $output.print "\n" end end class LogHashPack < LogHash def printtop(n) $output.print sum, " #{@art}\n" $output.print size, " verschiedene #{@title}s\n" pop = populaerste(n) if not pop.nil? $output.print "Die beliebtesten #{@title}s: Zahl der #{@art}, #{@title}\n" pop.each { |b, a| $output.printf "%7d\t#%s\t%s\n", a, b, $packs[ b.to_i ] } end $output.print "\n" end end # ** 2006-02-10-06:17:25: XDCC SEND #29 requested: ihs (euirc-13824fe7.bpool.celox.de) # ** 2006-02-10-17:48:48: XDCC SEND 15 Queued (slot): Spaghetti (euirc-6ab9fef9.adsl.alicedsl.de) # $request_pack = / XDCC SEND #*([0-9]*) (requested|Queued .slot.): [^ ]* / # $request_nick = / XDCC SEND #*[0-9]* (requested|Queued .slot.): ([^ )]*)/ # ** 2010-07-16-22:34:21: XDCC SEND 1039: requested (katharsis KATHARSIS!~KATHARSIS@EUIRC-B122E697.DIP0.T-IPCONNECT.DE on euirc) # ** 2010-07-16-22:34:23: XDCC SEND 1044: Queued (slot) (katharsis KATHARSIS!~KATHARSIS@EUIRC-B122E697.DIP0.T-IPCONNECT.DE on euirc) # ** 2010-07-16-22:34:30: XDCC SEND 1057: Queued (idle slot) (katharsis KATHARSIS!~KATHARSIS@EUIRC-B122E697.DIP0.T-IPCONNECT.DE on euirc) $request_pack = / XDCC SEND #*([0-9]*)[:] (requested|Queued .*slot.) [(][^ ]* / $request_nick = / XDCC SEND #*[0-9]*[:] (requested|Queued .*slot.) [(]([^ )]*)/ # ** 2006-02-10-06:17:26: XDCC [515:ihs]: Connection established (84.245.180.163:1027 -> 213.239.196.229:53686) $connected_nick = / XDCC [\[][0-9]*[:]([^\]]*)[\]]: Connection established / # ** 2006-02-10-06:39:30: XDCC [515:ihs]: Transfer Completed (383302 KB, 22 min 3.865 sec, 289.5 KB/sec) $completed_nick = / XDCC [\[][0-9]*[:]([^\]]*)[\]]: Transfer Completed / #completed_speed = / XDCC [\[][0-9]*[:][^\]]*[\]]: Transfer Completed .[0-9]* KB, [^,]*, ([0-9]*[.][0-9]) / # ** 2006-02-10-06:18:02: Stat: 1/20 Sls, 0/20 Q, 2464.8K/s Rcd, 0 SrQ (Bdw: 8100K, 67.5K/s, 2473.1K/s Rcd) $packs = Array.new(0) # Die Gruppierungen im regulären Ausdruck # werden in den LogHashtabellen gezählt def log_search( input, *hash ) # String-Objekt aus der Schleife ziehen split = "\n" # hash-Indizes an MatchData angleichen hash.unshift nil loop { # nächster Block und der Rest der Zeile data = input.read(4095) or break data += (input.gets || "") for line in data.split(split) for i in 1...hash.length if md = hash[i].re.match(line) key = md[ hash[i].klammer ] hash[i][ key ] += 1 end end end } # Karteileichen beseitigen hash.each { |h| h.delete(nil) if h } hash[1..-1] end def get_long(string) return string.unpack('N')[ 0 ] end def get_text(string) l = string.unpack('C')[ 0 ] l -= 1 return string[1, l] end def parse_buffer(buffer, bsize) fsize = bsize - 16 ipos = 8 packnr = 0 while ipos < fsize tag = get_long( buffer[ipos, 4] ) len = get_long( buffer[ipos + 4, 4] ) if ( len <= 8 ) printf( ":tag=%d
\n", tag ) printf( ":len=%d
\n", len ) printf( "Warning: parsing statfile aborted\n" ) ipos = fsize break end case tag when 3072 # XDCCS packnr += 1 chunkdata = buffer[ipos, len] jpos = 8 while jpos < len jtag = get_long( chunkdata[jpos, 4] ) jlen = get_long( chunkdata[jpos + 4, 4] ) if ( len <= 8 ) printf( ":xtag=%d
\n", jtag ) printf( ":xlen=%d
\n", jlen ) printf( "Warning: parsing statfile aborted\n" ) jpos = len break end case jtag when 0 jpos = len when 3073 # FILE text = chunkdata[jpos + 7, jlen - 8] xf = get_text( text ) $packs[ packnr ] = xf.gsub( /^.*\//, '' ) when 3074 # DESC text = chunkdata[jpos + 7, jlen - 8] desc = get_text( text ) $packs[ packnr ] = desc end jpos += jlen r = jlen % 4 if ( r > 0 ) jpos += 4 - r end end end ipos += len; r = len % 4; if ( r > 0 ) ipos += 4 - r; end end end def parse_state( filename ) File.stat(filename).file? or next bsize = File.size(filename) begin buffer = File.open(filename, 'r').read parse_buffer( buffer, bsize ) rescue $stderr.print "Failure at #{filename}: #{$!} => Skipping!\n" end end def make_statistik( input ) return log_search( input, LogHashPack.new( $request_pack, 'Pack', 'Anfragen' ), LogHash.new( $request_nick, 'Nick', 'Anfragen', 2 ), LogHash.new( $connected_nick, 'Nick', 'Verbindungen' ), LogHash.new( $completed_nick, 'Nick', 'Downloads' ) ) end input = 0 $output = STDOUT if ARGV.size > 0 then ARGV.each { |filename| if /[.]state/.match( filename ) parse_state( filename ) next end if FileTest.exist?( filename ) if ( $packs.size == 0 ) state = filename.sub( /[.].*$/, '' ) parse_state( "#{state}.state" ) end input += 1 if input == 1 $list = make_statistik( File.open(filename, 'r') ) next end STDERR.print "Only 1 Logfile supported!\n" exit 1 else $output = File.open(filename, 'w') end } else STDERR.print "Usage: offertop []\n" exit 64 end if input == 0 $list = make_statistik( STDIN ) end $list.each { |top| top.printtop( 10 ) } if $output != STDOUT $output.close end exit 0 # eof