]> git.proxmox.com Git - pmg-api.git/commitdiff
implement receiver statistics, cleanups
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 5 Sep 2017 12:02:54 +0000 (14:02 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 5 Sep 2017 12:02:54 +0000 (14:02 +0200)
PMG/API2/Statistics.pm
PMG/Statistic.pm

index 82b45d8e81d30619f54a5d18a69cab61a48c8dde..18250f2492c5be9a905f6ec0e56c082f471eaf68 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use warnings;
 use Data::Dumper;
 use JSON;
+use URI::Escape;
 
 use PVE::Tools;
 use PVE::SafeSyslog;
@@ -47,6 +48,7 @@ __PACKAGE__->register_method ({
            { name => "maildistribution" },
            { name => "spamscores" },
            { name => "sender" },
+           { name => "receiver" },
            { name => "virus" },
        ];
     }});
@@ -210,7 +212,7 @@ __PACKAGE__->register_method ({
                    description => "Spam score.",
                    type => 'number',
                },
-               virusname => {
+               virusinfo => {
                    description => "Virus name.",
                    type => 'string',
                    optional => 1,
@@ -230,14 +232,172 @@ __PACKAGE__->register_method ({
        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 ({
index 74f14ae82896aed44317e97f0c22bdfdd6f5dc0c..0c2098697c6011672710560ef89450f9801f53cf 100755 (executable)
@@ -536,6 +536,26 @@ sub sort_dir {
     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();
@@ -608,25 +628,12 @@ sub user_stat_sender_details {
     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 " .
@@ -654,19 +661,7 @@ sub user_stat_sender {
     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);
 
@@ -691,21 +686,24 @@ sub user_stat_sender {
 }
 
 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;
     }
@@ -716,41 +714,43 @@ sub user_stat_receiver_details {
 }
 
 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;
     }