use warnings;
use Data::Dumper;
use JSON;
+use URI::Escape;
use PVE::Tools;
use PVE::SafeSyslog;
{ name => "maildistribution" },
{ name => "spamscores" },
{ name => "sender" },
+ { name => "receiver" },
{ name => "virus" },
];
}});
description => "Spam score.",
type => 'number',
},
- virusname => {
+ virusinfo => {
description => "Virus name.",
type => 'string',
optional => 1,
my $stat = PMG::Statistic->new($start, $end);
my $rdb = PMG::RuleDB->new();
+ my $sender = uri_unescape($param->{sender});
+
my $sorters = [];
if ($param->{orderby}) {
- my $props = ['time', 'receiver', 'bytes', 'blocked', 'spamlevel', 'viruscount'];
+ my $props = ['time', 'receiver', 'bytes', 'blocked', 'spamlevel', 'virusinfo'];
$sorters = $decode_orderby->($param->{orderby}, $props);
}
return $stat->user_stat_sender_details(
- $rdb, $param->{sender}, $userstat_limit, $sorters, $param->{filter});
+ $rdb, $sender, $userstat_limit, $sorters, $param->{filter});
+ }});
+
+__PACKAGE__->register_method ({
+ name => 'receiver',
+ path => 'receiver',
+ method => 'GET',
+ description => "Receiver Address Statistics.",
+ permissions => { check => [ 'admin', 'qmanager', 'audit'] },
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ starttime => get_standard_option('pmg-starttime'),
+ endtime => get_standard_option('pmg-endtime'),
+ filter => {
+ description => "Receiver address filter.",
+ type => 'string',
+ maxLength => 512,
+ optional => 1,
+ },
+ orderby => $orderby_param_desc,
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ receiver => {
+ description => "Sender email.",
+ type => 'string',
+ },
+ count => {
+ description => "Mail count.",
+ type => 'number',
+ optional => 1,
+ },
+ bytes => {
+ description => "Mail traffic (Bytes).",
+ type => 'number',
+ },
+ spamcount => {
+ description => "Number of sent spam mails.",
+ type => 'number',
+ optional => 1,
+ },
+ viruscount => {
+ description => "Number of sent virus mails.",
+ type => 'number',
+ optional => 1,
+ },
+ },
+ },
+ links => [ { rel => 'child', href => "{receiver}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $restenv = PMG::RESTEnvironment->get();
+ my $cinfo = $restenv->{cinfo};
+
+ my $start = $param->{starttime} // (time - 86400);
+ my $end = $param->{endtime} // ($start + 86400);
+
+ # fixme: advanced stat setting
+ my $stat = PMG::Statistic->new($start, $end);
+ my $rdb = PMG::RuleDB->new();
+
+ my $sorters = [];
+ if ($param->{orderby}) {
+ my $props = ['receiver', 'count', 'bytes', 'spamcount', 'viruscount'];
+ $sorters = $decode_orderby->($param->{orderby}, $props);
+ }
+
+ my $res = $stat->user_stat_receiver($rdb, $userstat_limit, $sorters, $param->{filter});
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method ({
+ name => 'receiverdetails',
+ path => 'receiver/{receiver}',
+ method => 'GET',
+ description => "Detailed Receiver Statistics.",
+ permissions => { check => [ 'admin', 'qmanager', 'audit'] },
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ starttime => get_standard_option('pmg-starttime'),
+ endtime => get_standard_option('pmg-endtime'),
+ receiver => get_standard_option('pmg-email-address', {
+ description => "Receiver email address.",
+ }),
+ filter => {
+ description => "Sender address filter.",
+ type => 'string',
+ maxLength => 512,
+ optional => 1,
+ },
+ orderby => $orderby_param_desc,
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ time => {
+ description => "Receive time stamp",
+ type => 'integer',
+ },
+ sender => {
+ description => "Sender email.",
+ type => 'string',
+ },
+ bytes => {
+ description => "Mail traffic (Bytes).",
+ type => 'number',
+ },
+ blocked => {
+ description => "Mail was blocked.",
+ type => 'boolean',
+ },
+ spamlevel => {
+ description => "Spam score.",
+ type => 'number',
+ },
+ virusinfo => {
+ description => "Virus name.",
+ type => 'string',
+ optional => 1,
+ },
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $restenv = PMG::RESTEnvironment->get();
+ my $cinfo = $restenv->{cinfo};
+
+ my $start = $param->{starttime} // (time - 86400);
+ my $end = $param->{endtime} // ($start + 86400);
+
+ my $stat = PMG::Statistic->new($start, $end);
+ my $rdb = PMG::RuleDB->new();
+
+ my $receiver = uri_unescape($param->{receiver});
+
+ my $sorters = [];
+ if ($param->{orderby}) {
+ my $props = ['time', 'sender', 'bytes', 'blocked', 'spamlevel', 'virusinfo'];
+ $sorters = $decode_orderby->($param->{orderby}, $props);
+ }
+
+ return $stat->user_stat_receiver_details(
+ $rdb, $receiver, $userstat_limit, $sorters, $param->{filter});
}});
__PACKAGE__->register_method ({
return $sortdir;
}
+my $compute_sql_orderby = sub {
+ my ($sorters, $sort_default, $sort_always_prop) = @_;
+
+ my $has_default_sort;
+
+ my $orderby = '';
+
+ foreach my $obj (@$sorters) {
+ $has_default_sort = 1 if $obj->{property} eq $sort_always_prop;
+ $orderby .= ', ' if $orderby;
+ $orderby .= "$obj->{property} $obj->{direction}"
+ }
+
+ $orderby .= $sort_default if !$orderby;
+
+ $orderby .= ", $sort_always_prop" if !$has_default_sort;
+
+ return $orderby;
+};
+
sub user_stat_contact_details {
my ($self, $rdb, $receiver, $limit, $orderby) = @_;
my ($from, $to) = $self->timespan();
my ($self, $rdb, $sender, $limit, $sorters, $filter) = @_;
my ($from, $to) = $self->timespan();
- my $sth;
-
- my $orderby = '';
- my $receiver_sort;
+ my $orderby = $compute_sql_orderby->($sorters, 'time ASC', 'receiver');
- foreach my $obj (@$sorters) {
- $receiver_sort = 1 if $obj->{property} eq 'receiver';
- $orderby .= ', ' if $orderby;
- $orderby .= "$obj->{property} $obj->{direction}"
- }
-
- $orderby .= 'time DESC' if !$orderby;
-
- $orderby .= ", receiver" if !$receiver_sort;
-
- my $cond_good_mail = $self->query_cond_good_mail ($from, $to);
+ my $cond_good_mail = $self->query_cond_good_mail($from, $to);
- $sth = $rdb->{dbh}->prepare(
+ my $sth = $rdb->{dbh}->prepare(
"SELECT " .
"blocked, bytes, ptime, sender, receiver, spamlevel, time, virusinfo " .
"FROM CStatistic, CReceivers " .
my $sth;
my $query;
- my $orderby = '';
-
- my $sender_sort;
-
- foreach my $obj (@$sorters) {
- $sender_sort = 1 if $obj->{property} eq 'sender';
- $orderby .= ', ' if $orderby;
- $orderby .= "$obj->{property} $obj->{direction}"
- }
-
- $orderby .= 'count DESC' if !$orderby;
-
- $orderby .= ", sender" if !$sender_sort;
+ my $orderby = $compute_sql_orderby->($sorters, 'count DESC', 'sender');
my $cond_good_mail = $self->query_cond_good_mail ($from, $to);
}
sub user_stat_receiver_details {
- my ($self, $rdb, $receiver, $limit, $orderby) = @_;
+ my ($self, $rdb, $receiver, $limit, $sorters, $filter) = @_;
+
my ($from, $to) = $self->timespan();
- my $sth;
- my $res;
- $orderby || ($orderby = 'time');
- my $sortdir = sort_dir ($orderby);
+ my $orderby = $compute_sql_orderby->($sorters, 'time ASC', 'sender');
- my $cond_good_mail = $self->query_cond_good_mail ($from, $to);
+ my $cond_good_mail = $self->query_cond_good_mail($from, $to);
+
+ my $sth = $rdb->{dbh}->prepare(
+ "SELECT blocked, bytes, ptime, sender, receiver, spamlevel, time, virusinfo " .
+ "FROM CStatistic, CReceivers " .
+ "WHERE cid = cstatistic_cid AND rid = cstatistic_rid AND $cond_good_mail AND receiver = ? " .
+ ($filter ? "AND sender like " . $rdb->{dbh}->quote("%${filter}%") . ' ' : '') .
+ "ORDER BY $orderby limit $limit");
- $sth = $rdb->{dbh}->prepare("SELECT * FROM CStatistic, CReceivers " .
- "WHERE cid = cstatistic_cid AND rid = cstatistic_rid AND $cond_good_mail AND receiver = ? " .
- "ORDER BY $orderby $sortdir, sender limit $limit");
$sth->execute($receiver);
+ my $res = [];
while (my $ref = $sth->fetchrow_hashref()) {
push @$res, $ref;
}
}
sub user_stat_receiver {
- my ($self, $rdb, $limit, $orderby) = @_;
+ my ($self, $rdb, $limit, $sorters, $filter) = @_;
+
my ($from, $to) = $self->timespan();
my $sth;
- my $res;
- my $query;
- $orderby || ($orderby = 'count');
- my $sortdir = sort_dir ($orderby);
+ my $orderby = $compute_sql_orderby->($sorters, 'count DESC', 'receiver');
my $cond_good_mail = $self->query_cond_good_mail ($from, $to) . " AND " .
"receiver IS NOT NULL AND receiver != ''";
+ my $query = "SELECT receiver, " .
+ "count(*) AS count, " .
+ "sum (bytes) AS bytes, " .
+ "count (virusinfo) as viruscount, " .
+ "count (CASE WHEN spamlevel >= 3 THEN 1 ELSE NULL END) as spamcount ";
+
if ($self->{adv}) {
my $active_workers = $self->query_active_workers ();
- $query = "SELECT receiver, count(*) AS count, sum (bytes) AS bytes, " .
- "count (virusinfo) as viruscount, " .
- "count (CASE WHEN spamlevel >= 3 THEN 1 ELSE NULL END) as spamcount " .
- "FROM CStatistic, CReceivers, ($active_workers) as workers " .
- "WHERE cid = cstatistic_cid AND rid = cstatistic_rid AND $cond_good_mail AND direction AND worker=receiver " .
- "GROUP BY receiver " .
- "ORDER BY $orderby $sortdir, receiver LIMIT $limit";
+ $query .= "FROM CStatistic, CReceivers, ($active_workers) as workers ";
+
+ $query .= "WHERE cid = cstatistic_cid AND rid = cstatistic_rid AND worker=receiver ";
+
} else {
- $query = "SELECT receiver, count(*) AS count, sum (bytes) AS bytes, " .
- "count (virusinfo) as viruscount, " .
- "count (CASE WHEN spamlevel >= 3 THEN 1 ELSE NULL END) as spamcount " .
- "FROM CStatistic, CReceivers " .
- "WHERE cid = cstatistic_cid AND rid = cstatistic_rid AND $cond_good_mail and direction " .
- "GROUP BY receiver " .
- "ORDER BY $orderby $sortdir, receiver LIMIT $limit";
+ $query .= "FROM CStatistic, CReceivers ";
+
+ $query .= "WHERE cid = cstatistic_cid AND rid = cstatistic_rid ";
}
+ $query .= "AND $cond_good_mail and direction " .
+ ($filter ? "AND receiver like " . $rdb->{dbh}->quote("%${filter}%") . ' ' : '') .
+ "GROUP BY receiver ORDER BY $orderby LIMIT $limit";
+
$sth = $rdb->{dbh}->prepare($query);
$sth->execute();
+ my $res = [];
while (my $ref = $sth->fetchrow_hashref()) {
push @$res, $ref;
}