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

Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
34
from optparse import make_option
35
from django.core.management.base import CommandError
36

Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
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
43


44
class Command(SynnefoCommand):
45
46
    args = "<id>"
    help = "Show details for project (or application) <id>"
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
47

48
    option_list = SynnefoCommand.option_list + (
49
50
51
52
        make_option('--app',
                    action='store_true',
                    dest='app',
                    default=False,
53
54
                    help="Show details of applications instead of projects"
                    ),
55
        make_option('--pending',
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
56
                    action='store_true',
57
                    dest='pending',
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
58
                    default=False,
59
60
61
62
63
64
65
66
                    help=("For a given project, show also pending "
                          "modifications (applications), if any")
                    ),
        make_option('--members',
                    action='store_true',
                    dest='members',
                    default=False,
                    help=("Show a list of project memberships")
67
                    ),
68
69
70
71
        make_option('--unit-style',
                    default='mb',
                    help=("Specify display unit for resource values "
                          "(one of %s); defaults to mb") % style_options),
72
    )
73
74
75

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

78
79
80
        self.unit_style = options['unit_style']
        check_style(self.unit_style)

81
        show_pending = bool(options['pending'])
82
        show_members = bool(options['members'])
83
        search_apps = options['app']
84
        self.output_format = options['output_format']
85

86
87
88
89
90
        id_ = args[0]
        try:
            id_ = int(id_)
        except ValueError:
            raise CommandError("id should be an integer value.")
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
91

92
        if search_apps:
93
94
            app = get_app(id_)
            self.print_app(app)
95
        else:
96
97
            project, pending_app = get_chain_state(id_)
            self.print_project(project, pending_app)
98
            if show_members and project is not None:
99
                self.stdout.write("\n")
100
                fields, labels = members_fields(project)
101
                self.pprint_table(fields, labels, title="Members")
102
            if show_pending and pending_app is not None:
103
                self.stdout.write("\n")
104
                self.print_app(pending_app)
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
105

106
107
108
    def pprint_dict(self, d, vertical=True):
        utils.pprint_table(self.stdout, [d.values()], d.keys(),
                           self.output_format, vertical=vertical)
109

110
    def pprint_table(self, tbl, labels, title=None):
111
        utils.pprint_table(self.stdout, tbl, labels,
112
113
114
115
116
117
118
                           self.output_format, title=title)

    def print_app(self, app):
        app_info = app_fields(app)
        self.pprint_dict(app_info)
        self.print_resources(app)

119
    def print_project(self, project, app):
120
121
122
        if project is None:
            self.print_app(app)
        else:
123
            self.pprint_dict(project_fields(project, app))
124
125
126
127
128
129
130
            self.print_resources(project.application)

    def print_resources(self, app):
        fields, labels = resource_fields(app, self.unit_style)
        if fields:
            self.stdout.write("\n")
            self.pprint_table(fields, labels, title="Resource limits")
131

132

133
def get_app(app_id):
134
    try:
135
        return ProjectApplication.objects.get(id=app_id)
136
137
    except ProjectApplication.DoesNotExist:
        raise CommandError("Application with id %s not found." % app_id)
138

139

140
141
def get_chain_state(project_id):
    try:
142
143
144
        chain = Project.objects.get(id=project_id)
        return chain, chain.last_pending_application()
    except Project.DoesNotExist:
145
        raise CommandError("Project with id %s not found." % project_id)
146

147

148
149
150
151
152
153
154
155
156
157
158
159
160
def resource_fields(app, style):
    labels = ('name', 'description', 'max per member')
    policies = app.projectresourcegrant_set.all()
    collect = []
    for policy in policies:
        name = policy.resource.name
        desc = policy.resource.desc
        capacity = policy.member_capacity
        collect.append((name, desc,
                        show_resource_value(capacity, name, style)))
    return collect, labels


Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
161
def app_fields(app):
162
163
164
    mem_limit = app.limit_on_members_number
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"

Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
165
    d = OrderedDict([
166
        ('project id', app.chain_id),
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
        ('application id', app.id),
        ('name', app.name),
        ('status', app.state_display()),
        ('owner', app.owner),
        ('applicant', app.applicant),
        ('homepage', app.homepage),
        ('description', app.description),
        ('comments for review', app.comments),
        ('request issue date', app.issue_date),
        ('request start date', app.start_date),
        ('request end date', app.end_date),
        ('join policy', app.member_join_policy_display),
        ('leave policy', app.member_leave_policy_display),
        ('max members', mem_limit_show),
    ])
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
182
183
184
185

    return d


186
def project_fields(project, pending_app):
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
187
    app = project.application
188

Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
189
    d = OrderedDict([
190
191
192
        ('project id', project.id),
        ('application id', app.id),
        ('name', app.name),
193
        ('status', project.state_display()),
194
    ])
195
196
    if pending_app is not None:
        d.update([('pending application', pending_app.id)])
197
198

    d.update([('owner', app.owner),
199
              ('applicant', app.applicant),
200
201
202
              ('homepage', app.homepage),
              ('description', app.description),
              ('comments for review', app.comments),
203
204
205
206
              ('request issue date', app.issue_date),
              ('request start date', app.start_date),
              ('creation date', project.creation_date),
              ('request end date', app.end_date),
207
208
              ])

Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
209
210
    deact_date = project.deactivation_date
    if deact_date is not None:
211
        d['deactivation date'] = deact_date
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
212

213
214
215
    mem_limit = app.limit_on_members_number
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"

Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
216
217
218
    d.update([
            ('join policy', app.member_join_policy_display),
            ('leave policy', app.member_leave_policy_display),
219
            ('max members', mem_limit_show),
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
220
            ('total members', project.members_count()),
221
    ])
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
222

223
    return d
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
224
225


226
227
228
229
230
231
232
233
234
235
def members_fields(project):
    labels = ('member uuid', 'email', 'status')
    objs = project.projectmembership_set.select_related('person')
    memberships = objs.all().order_by('state', 'person__email')
    collect = []
    for m in memberships:
        user = m.person
        collect.append((user.uuid,
                       user.email,
                       m.state_display()))
Giorgos Korfiatis's avatar
Giorgos Korfiatis committed
236

237
    return collect, labels