Revision 79f67df6

b/snf-astakos-app/astakos/im/management/commands/stats-astakos.py
1
# Copyright 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34

  
35
import datetime
36
import json
37
import string
38

  
39
#from optparse import make_option
40

  
41
from django.conf import settings
42
from snf_django.management.utils import pprint_table
43

  
44
from snf_django.management.commands import SynnefoCommand, CommandError
45
from astakos.im.models import AstakosUser, Resource
46
from astakos.quotaholder_app.models import Holding
47
from django.db.models import Sum
48

  
49

  
50
class Command(SynnefoCommand):
51
    help = "Get available statistics of Astakos service"
52
    can_import_settings = True
53

  
54
    option_list = SynnefoCommand.option_list + (
55
    )
56

  
57
    def handle(self, *args, **options):
58
        stats = get_astakos_stats()
59

  
60
        output_format = options["output_format"]
61
        if output_format == "json":
62
            self.stdout.write(json.dumps(stats, indent=4) + "\n")
63
        elif output_format == "pretty":
64
            pretty_print_stats(stats, self.stdout)
65
        else:
66
            raise CommandError("Output format '%s' not supported." %
67
                               output_format)
68

  
69

  
70
def get_astakos_stats():
71
    stats = {"datetime": datetime.datetime.now().strftime("%c")}
72

  
73
    resources = Resource.objects.values_list("name", flat=True)
74

  
75
    users = AstakosUser.objects.all()
76
    verified = users.filter(email_verified=True)
77
    active = users.filter(is_active=True)
78

  
79
    user_stats = {}
80
    user_stats["total"] = {"total": users.count(),
81
                           "verified": verified.count(),
82
                           "active": active.count(),
83
                           "usage": {}}
84

  
85
    for resource in resources:
86
        usage = Holding.objects.filter(resource=resource)\
87
                               .aggregate(summ=Sum("usage_max"))
88
        user_stats["total"]["usage"][resource] = int(usage["summ"])
89

  
90
    for provider in settings.ASTAKOS_IM_MODULES:
91

  
92
        users = AstakosUser.objects.filter(auth_providers__module=provider)
93
        verified = users.filter(email_verified=True)
94
        active = users.filter(is_active=True)
95

  
96
        user_stats[provider] = {"total": users.count(),
97
                                "verified": verified.count(),
98
                                "active": active.count(),
99
                                "usage": {}}
100

  
101
        users_uuids = users.values_list("uuid", flat=True)
102
        for resource in resources:
103
            usage = Holding.objects\
104
                           .filter(holder__in=users_uuids, resource=resource)\
105
                           .aggregate(summ=Sum("usage_max"))
106
            user_stats[provider]["usage"][resource] = int(usage["summ"])
107

  
108
    stats["users"] = user_stats
109

  
110
    return stats
111

  
112

  
113
def columns_from_fields(fields, values):
114
    return zip(map(string.lower, fields), [values.get(f, 0) for f in fields])
115

  
116

  
117
def pretty_print_stats(stats, stdout):
118
    newline = lambda: stdout.write("\n")
119

  
120
    datetime = stats.get("datetime")
121
    stdout.write("datetime: %s\n" % datetime)
122
    newline()
123

  
124
    users = stats.get("users", {})
125

  
126
    all_providers = users.pop("total")
127
    if all_providers is not None:
128
        fields = ["total", "verified", "active"]
129
        table = columns_from_fields(fields, all_providers)
130
        usage = all_providers.get("usage", {})
131
        for name, val in sorted(usage.items()):
132
            table.append((name, val))
133
        pprint_table(stdout, table, None,
134
                     title="Statistics for All Providers")
135
        newline()
136

  
137
    for provider_name, provider_info in sorted(users.items()):
138
        fields = ["total", "verified", "active"]
139
        table = columns_from_fields(fields, provider_info)
140
        usage = provider_info.get("usage", {})
141
        for name, val in sorted(usage.items()):
142
            table.append((name, val))
143
        pprint_table(stdout, table, None,
144
                     title="Statistics for Provider '%s'" % provider_name)
145
        newline()

Also available in: Unified diff