#!/usr/bin/perl
Hide Show 4 lines of Pod
our
$root_path
;
use
lib
$root_path
.
'../../lib'
;
$Data::Dumper::Sortkeys
= 1;
our
%config
;
use
lib
$root_path
.
'./pslib'
;
psmisc::config( 0, 0, 0, 1 );
$config
{
'log_trace'
} =
$config
{
'log_dmpbef'
} = 0;
$config
{
'log_dmp'
} = 0;
$config
{
'hit_to_ask'
} ||= 2;
$config
{
'queue_recalc_every'
} ||= 30;
$config
{
'ask_retry'
} ||= 3600;
$config
{
'limit_max'
} ||= 100;
$config
{
'row_all'
} = {
'not null'
=> 1, };
$config
{
'periods'
} = {
'h'
=> 3600,
'd'
=> 86400,
'w'
=> 7 * 86400,
};
$config
{
'sql'
} = {
'driver'
=>
'mysql'
,
'dbname'
=>
'dcstat'
,
'auto_connect'
=> 1,
'log'
=>
sub
{
shift
; psmisc::printlog(
@_
) },
'cp_in'
=>
'cp1251'
,
'table'
=> {
'queries'
=> {
'time'
=> pssql::row(
'time'
,
'index'
=> 1 ),
'hub'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 64,
'index'
=> 1 ),
'nick'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 32,
'index'
=> 1 ),
'ip'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 15,
'Zindex'
=> 1 ),
'port'
=> pssql::row(
undef
,
'type'
=>
'SMALLINT'
,
'Zindex'
=> 1 ),
'tth'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 40,
'default'
=>
''
,
'index'
=> 1 ),
'string'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 255,
'default'
=>
''
,
'index'
=> 1 ),
},
'results'
=> {
'time'
=> pssql::row(
'time'
,
'index'
=> 1 ),
'string'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 255,
'index'
=> 1 ),
'hub'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 64,
'index'
=> 1 ),
'nick'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 32,
'index'
=> 1 ),
'ip'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 15,
'Zindex'
=> 1 ),
'port'
=> pssql::row(
undef
,
'type'
=>
'SMALLINT'
,
'Zindex'
=> 1 ),
'tth'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 40,
'index'
=> 1 ),
'file'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 255,
'Zindex'
=> 1 ),
'filename'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 255,
'index'
=> 1 ),
'ext'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 32,
'index'
=> 1 ),
'size'
=> pssql::row(
undef
,
'type'
=>
'BIGINT'
,
'index'
=> 1 ),
},
'chat'
=> {
'time'
=> pssql::row(
'time'
,
'index'
=> 1 ),
'hub'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 64,
'index'
=> 1 ),
'nick'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 32,
'index'
=> 1 ),
'string'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 3090,
'Zindex'
=> 1 ),
},
}
};
$config
{
'sql'
}{
'table'
}{
'queries'
.
$_
} = {
'tth'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 40,
'default'
=>
''
,
'index'
=> 1,
'Zprimary'
=> 1, ),
'string'
=> pssql::row(
undef
,
'type'
=>
'VARCHAR'
,
'length'
=> 255,
'default'
=>
''
,
'index'
=> 1,
'Zprimary'
=> 1, ),
'cnt'
=> pssql::row(
undef
,
'type'
=>
'INT'
,
'index'
=> 1 ),
}
for
keys
%{
$config
{
'periods'
} };
$config
{
'sql'
}{
'table'
}{
'resultsf'
} =
{ %{
$config
{
'sql'
}{
'table'
}{
'results'
} },
'cnt'
=> pssql::row(
undef
,
'type'
=>
'INT'
,
'index'
=> 1 ), };
delete
$config
{
'sql'
}{
'table'
}{
'resultsf'
}{
$_
}
for
qw(time nick ip port file)
;
Hide Show 10 lines of Pod
our
$db
= pssql->new( %{
$config
{
'sql'
} or {} }, );
my
%every
;
sub
every {
my
(
$sec
,
$func
) = (
shift
,
shift
);
$func
->(
@_
),
$every
{
$func
} =
time
if
$every
{
$func
} +
$sec
<
time
and
ref
$func
eq
'CODE'
;
}
unless
(
caller
) {
print
(
"usage: stat.pl [--configParam=configValue] [dchub:// ]host[:port] [more params and hubs]\n"
),
exit
if
!
$ARGV
[0];
if
(
$ARGV
[0] eq
'calc'
) {
$db
->
do
(
'CREATE TABLE IF NOT EXISTS resultsftmp LIKE resultsf'
,
'REPLACE LOW_PRIORITY resultsftmp (string,hub,tth,filename,ext,size, cnt) SELECT string,hub,tth,filename,ext,size, COUNT(*) as cnt FROM results WHERE tth != "" GROUP BY tth HAVING cnt > 1 ORDER BY cnt DESC LIMIT '
.
$config
{
'limit_max'
} .
''
,
'DROP TABLE resultsf'
,
'RENAME TABLE resultsftmp TO resultsf'
,
);
$db
->
do
(
'CREATE TABLE IF NOT EXISTS queries'
.
$_
.
'tmp LIKE queries'
.
$_
,
'REPLACE LOW_PRIORITY queries'
.
$_
.
'tmp (string, cnt) SELECT string, COUNT(*) as cnt FROM queries WHERE string != "" AND time >= '
. (
int
(
time
-
$config
{
'periods'
}{
$_
} ) )
.
' GROUP BY string HAVING cnt > 1 ORDER BY cnt DESC LIMIT '
.
$config
{
'limit_max'
} .
''
,
'REPLACE LOW_PRIORITY queries'
.
$_
.
'tmp (tth, cnt) SELECT tth, COUNT(*) as cnt FROM queries WHERE tth != "" AND time >= '
. (
int
(
time
-
$config
{
'periods'
}{
$_
} ) )
.
' GROUP BY tth HAVING cnt > 1 ORDER BY cnt DESC LIMIT '
.
$config
{
'limit_max'
} .
''
,
'DROP TABLE queries'
.
$_
,
'RENAME TABLE queries'
.
$_
.
'tmp TO queries'
.
$_
,
)
for
$ARGV
[1]
or
sort
{
$config
{
'periods'
}{
$a
} <=>
$config
{
'periods'
}{
$b
} }
keys
%{
$config
{
'periods'
} };
exit
;
}
our
%work
;
our
@dc
;
sub
close_all {
flush_all();
$db
->disconnect();
$_
->destroy()
for
@dc
;
exit
;
}
sub
flush_all {
$db
->flush_insert();
}
$SIG
{INT} =
$SIG
{__DIE__} = \
&close_all
;
$SIG
{HUP} = $^O =~ /win/i ? \
&close_all
: \
&flush_all
;
for
(
@ARGV
) {
local
@_
;
if
( /^-/ and
@_
=
split
'='
,
$_
) {
$config
{config_file} =
$_
[1], psmisc::config()
if
$_
[0] eq
'--config'
;
psmisc::program_one(
'params_pre_config'
,
@_
[ 1, 0 ] );
}
else
{
my
$hub
=
$_
;
my
$dc
= Net::DirectConnect::clihub->new(
'Nick'
=>
'dcstat'
,
'sharesize'
=> 40_000_000_000 +
int
(
rand
10_000_000_000 ),
'log'
=>
sub
{
shift
; psmisc::printlog(
@_
) },
'myport'
=> 41111,
'auto_connect'
=> 0,
'reconnects'
=> 500,
'handler'
=> {
'Search_parse_aft'
=>
sub
{
my
$dc
=
shift
;
my
$search
=
shift
;
my
%s
= ( %{
$_
[0] }, );
return
if
$s
{
'nick'
} eq
$dc
->{
'Nick'
};
$db
->insert_hash(
'queries'
, \
%s
);
my
$q
=
$s
{
'tth'
} ||
$s
{
'string'
} ||
return
;
++
$work
{
'ask'
}{
$q
};
every(
$config
{
'queue_recalc_every'
},
our
$queuerecalc
||=
sub
{
my
$time
=
int
time
;
$work
{
'toask'
} = [ (
sort
{
$work
{
'ask'
}{
$b
} <=>
$work
{
'ask'
}{
$a
} }
grep
{
$work
{
'ask'
}{
$_
} >=
$config
{
'hit_to_ask'
} and !
exists
$work
{
'asked'
}{
$_
} }
keys
%{
$work
{
'ask'
} }
), (
sort
{
$work
{
'ask'
}{
$b
} <=>
$work
{
'ask'
}{
$a
} }
grep
{
$work
{
'ask'
}{
$_
} >=
$config
{
'hit_to_ask'
}
and
$work
{
'asked'
}{
$_
}
and
$work
{
'asked'
}{
$_
} +
$config
{
'ask_retry'
} <
$time
}
keys
%{
$work
{
'ask'
} }
)
];
printlog(
'info'
,
"queue len="
,
scalar
@{
$work
{
'toask'
} },
" first hits="
,
$work
{
'ask'
}{
$work
{
'toask'
}[0] } );
}
);
$q
=
shift
@{
$work
{
'toask'
} } or
return
;
if
(
!
$dc
->{
'search_todo'
}
)
{
$work
{
'asked'
}{
$q
} =
int
time
;
$dc
->search(
$q
);
}
},
'SR_parse_aft'
=>
sub
{
my
$dc
=
shift
;
my
%s
= %{
$_
[1] ||
return
};
$db
->insert_hash(
'results'
, \
%s
);
},
'chatline'
=>
sub
{
my
$dc
=
shift
;
my
%s
;
(
$s
{nick},
$s
{string} ) =
$_
[0] =~ /^<([^>]+)> (.+)$/;
$db
->insert_hash(
'chat'
, {
%s
,
'time'
=>
int
(
time
),
'hub'
=>
$dc
->{
'hub'
}, } );
},
'welcome'
=>
sub
{
my
$dc
=
shift
;
printlog(
'welcome'
,
@_
);
},
},
%config
,
);
$dc
->
connect
(
$hub
);
push
@dc
,
$dc
;
$_
->work()
for
@dc
;
}
}
while
(
grep
{
$_
->active() }
@dc
) {
$_
->work()
for
@dc
;
}
$_
->destroy()
for
@dc
;
}