Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / project-show.py @ 362dadaa

History | View | Annotate | Download (7.6 kB)

1
# Copyright 2012-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
from optparse import make_option
35
from django.core.management.base import CommandError
36

    
37
from synnefo.lib.ordereddict import OrderedDict
38
from snf_django.management.commands import SynnefoCommand
39
from snf_django.management import utils
40
from astakos.im.models import ProjectApplication, Project
41
from ._common import show_resource_value, style_options, check_style
42
from synnefo.util import units
43

    
44

    
45
class Command(SynnefoCommand):
46
    args = "<id>"
47
    help = "Show details for project <id>"
48

    
49
    option_list = SynnefoCommand.option_list + (
50
        make_option('--pending',
51
                    action='store_true',
52
                    dest='pending',
53
                    default=False,
54
                    help=("For a given project, show also pending "
55
                          "modification, if any")
56
                    ),
57
        make_option('--members',
58
                    action='store_true',
59
                    dest='members',
60
                    default=False,
61
                    help=("Show a list of project memberships")
62
                    ),
63
        make_option('--unit-style',
64
                    default='mb',
65
                    help=("Specify display unit for resource values "
66
                          "(one of %s); defaults to mb") % style_options),
67
    )
68

    
69
    def handle(self, *args, **options):
70
        if len(args) != 1:
71
            raise CommandError("Please provide project ID or name")
72

    
73
        self.unit_style = options['unit_style']
74
        check_style(self.unit_style)
75

    
76
        show_pending = bool(options['pending'])
77
        show_members = bool(options['members'])
78
        show_quota = bool(options['list_quotas'])
79
        self.output_format = options['output_format']
80

    
81
        id_ = args[0]
82
        if True:
83
            project = get_chain_state(id_)
84
            self.print_project(project)
85
            if show_members and project is not None:
86
                self.stdout.write("\n")
87
                fields, labels = members_fields(project)
88
                self.pprint_table(fields, labels, title="Members")
89
            if show_pending:
90
                app = project.last_application
91
                if app and app.state == ProjectApplication.PENDING:
92
                    self.stdout.write("\n")
93
                    self.print_app(app)
94

    
95
    def pprint_dict(self, d, vertical=True):
96
        utils.pprint_table(self.stdout, [d.values()], d.keys(),
97
                           self.output_format, vertical=vertical)
98

    
99
    def pprint_table(self, tbl, labels, title=None):
100
        utils.pprint_table(self.stdout, tbl, labels,
101
                           self.output_format, title=title)
102

    
103
    def print_app(self, app):
104
        app_info = app_fields(app)
105
        self.pprint_dict(app_info)
106
        self.print_app_resources(app)
107

    
108
    def print_project(self, project):
109
        self.pprint_dict(project_fields(project))
110
        self.print_resources(project)
111

    
112
    def print_resources(self, project):
113
        policies = project.projectresourcequota_set.all()
114
        fields, labels = resource_fields(policies, self.unit_style)
115
        if fields:
116
            self.stdout.write("\n")
117
            self.pprint_table(fields, labels, title="Resource limits")
118

    
119
    def print_app_resources(self, app):
120
        policies = app.projectresourcegrant_set.all()
121
        fields, labels = resource_fields(policies, None, self.unit_style)
122
        if fields:
123
            self.stdout.write("\n")
124
            self.pprint_table(fields, labels, title="Resource limits")
125

    
126

    
127
def get_chain_state(project_id):
128
    try:
129
        return Project.objects.get(uuid=project_id)
130
    except Project.DoesNotExist:
131
        raise CommandError("Project with id %s not found." % project_id)
132

    
133

    
134
def resource_fields(policies, style):
135
    labels = ('name', 'description', 'max per member')
136
    collect = []
137
    for policy in policies:
138
        name = policy.resource.name
139
        desc = policy.resource.desc
140
        capacity = policy.member_capacity
141
        collect.append((name, desc,
142
                        show_resource_value(capacity, name, style)))
143
    return collect, labels
144

    
145

    
146
def app_fields(app):
147
    d = OrderedDict([
148
        ('project id', app.chain.uuid),
149
        ('application id', app.id),
150
        ('status', app.state_display()),
151
        ('applicant', app.applicant),
152
        ('comments for review', app.comments),
153
        ('request issue date', app.issue_date),
154
        ])
155
    if app.name:
156
        d['name'] = app.name
157
    if app.owner:
158
        d['owner'] = app.owner
159
    if app.homepage:
160
        d['homepage'] = app.homepage
161
    if app.description:
162
        d['description'] = app.description
163
    if app.start_date:
164
        d['request start date'] = app.start_date
165
    if app.end_date:
166
        d['request end date'] = app.end_date
167
    if app.member_join_policy:
168
        d['join policy'] = app.member_join_policy_display
169
    if app.member_leave_policy:
170
        d['leave policy'] = app.member_leave_policy_display
171
    if app.limit_on_members_number:
172
        d['max members'] = units.show(app.limit_on_members_number, None)
173

    
174
    return d
175

    
176

    
177
def project_fields(project):
178
    app = project.last_application
179

    
180
    d = OrderedDict([
181
        ('project id', project.uuid),
182
        ('name', project.realname),
183
        ('status', project.state_display()),
184
        ('owner', project.owner),
185
        ('homepage', project.homepage),
186
        ('description', project.description),
187
        ('creation date', project.creation_date),
188
        ('request end date', project.end_date),
189
        ])
190

    
191
    deact = project.last_deactivation()
192
    if deact is not None:
193
        d['deactivation date'] = deact.date
194

    
195
    d.update([
196
            ('join policy', project.member_join_policy_display),
197
            ('leave policy', project.member_leave_policy_display),
198
            ('max members', units.show(project.limit_on_members_number, None)),
199
            ('total members', project.members_count()),
200
    ])
201

    
202
    return d
203

    
204

    
205
def members_fields(project):
206
    labels = ('member uuid', 'email', 'status')
207
    objs = project.projectmembership_set.select_related('person')
208
    memberships = objs.all().order_by('state', 'person__email')
209
    collect = []
210
    for m in memberships:
211
        user = m.person
212
        collect.append((user.uuid,
213
                       user.email,
214
                       m.state_display()))
215

    
216
    return collect, labels