Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / project-show.py @ 398a9604

History | View | Annotate | Download (7.2 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 synnefo.webproject.management.commands import SynnefoCommand
39
from synnefo.webproject.management import utils
40
from astakos.im.models import Chain, ProjectApplication
41

    
42

    
43
class Command(SynnefoCommand):
44
    args = "<id>"
45
    help = "Show details for project (or application) <id>"
46

    
47
    option_list = SynnefoCommand.option_list + (
48
        make_option('--app',
49
                    action='store_true',
50
                    dest='app',
51
                    default=False,
52
                    help="Show details of applications instead of projects"
53
                    ),
54
        make_option('--pending',
55
                    action='store_true',
56
                    dest='pending',
57
                    default=False,
58
                    help=("For a given project, show also pending "
59
                          "modifications (applications), if any")
60
                    ),
61
        make_option('--members',
62
                    action='store_true',
63
                    dest='members',
64
                    default=False,
65
                    help=("Show a list of project memberships")
66
                    ),
67
    )
68

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

    
73
        show_pending = bool(options['pending'])
74
        show_members = bool(options['members'])
75
        search_apps = options['app']
76
        self.output_format = options['output_format']
77

    
78
        id_ = args[0]
79
        try:
80
            id_ = int(id_)
81
        except ValueError:
82
            raise CommandError("id should be an integer value.")
83

    
84
        if search_apps:
85
            self.pprint_dict(app_info(id_))
86
        else:
87
            state, project, app = get_chain_state(id_)
88
            self.pprint_dict(chain_fields(state, project, app))
89
            if show_members and project is not None:
90
                self.stdout.write("\n")
91
                fields, labels = members_fields(project)
92
                self.pprint_table(fields, labels)
93
            if show_pending and state in Chain.PENDING_STATES:
94
                self.stdout.write("\n")
95
                self.pprint_dict(app_fields(app))
96

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

    
101
    def pprint_table(self, tbl, labels):
102
        utils.pprint_table(self.stdout, tbl, labels,
103
                           self.output_format)
104

    
105

    
106
def app_info(app_id):
107
    try:
108
        app = ProjectApplication.objects.get(id=app_id)
109
        return app_fields(app)
110
    except ProjectApplication.DoesNotExist:
111
        raise CommandError("Application with id %s not found." % app_id)
112

    
113

    
114
def get_chain_state(project_id):
115
    try:
116
        chain = Chain.objects.get(chain=project_id)
117
        return chain.full_state()
118
    except Chain.DoesNotExist:
119
        raise CommandError("Project with id %s not found." % project_id)
120

    
121

    
122
def chain_fields(state, project, app):
123
    if project is not None:
124
        return project_fields(state, project, app)
125
    else:
126
        return app_fields(app)
127

    
128

    
129
def app_fields(app):
130
    mem_limit = app.limit_on_members_number
131
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"
132

    
133
    d = OrderedDict([
134
        ('project id', app.chain),
135
        ('application id', app.id),
136
        ('name', app.name),
137
        ('status', app.state_display()),
138
        ('owner', app.owner),
139
        ('applicant', app.applicant),
140
        ('homepage', app.homepage),
141
        ('description', app.description),
142
        ('comments for review', app.comments),
143
        ('request issue date', app.issue_date),
144
        ('request start date', app.start_date),
145
        ('request end date', app.end_date),
146
        ('resources', app.resource_policies),
147
        ('join policy', app.member_join_policy_display),
148
        ('leave policy', app.member_leave_policy_display),
149
        ('max members', mem_limit_show),
150
    ])
151

    
152
    return d
153

    
154

    
155
def project_fields(s, project, last_app):
156
    app = project.application
157

    
158
    d = OrderedDict([
159
        ('project id', project.id),
160
        ('application id', app.id),
161
        ('name', app.name),
162
        ('status', Chain.state_display(s)),
163
    ])
164
    if s in Chain.PENDING_STATES:
165
        d.update([('pending application', last_app.id)])
166

    
167
    d.update([('owner', app.owner),
168
              ('applicant', app.applicant),
169
              ('homepage', app.homepage),
170
              ('description', app.description),
171
              ('comments for review', app.comments),
172
              ('request issue date', app.issue_date),
173
              ('request start date', app.start_date),
174
              ('creation date', project.creation_date),
175
              ('request end date', app.end_date),
176
              ])
177

    
178
    deact_date = project.deactivation_date
179
    if deact_date is not None:
180
        d['deactivation date'] = deact_date
181

    
182
    mem_limit = app.limit_on_members_number
183
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"
184

    
185
    d.update([
186
            ('resources', app.resource_policies),
187
            ('join policy', app.member_join_policy_display),
188
            ('leave policy', app.member_leave_policy_display),
189
            ('max members', mem_limit_show),
190
            ('total members', project.members_count()),
191
    ])
192

    
193
    return d
194

    
195

    
196
def members_fields(project):
197
    labels = ('member uuid', 'email', 'status')
198
    objs = project.projectmembership_set.select_related('person')
199
    memberships = objs.all().order_by('state', 'person__email')
200
    collect = []
201
    for m in memberships:
202
        user = m.person
203
        collect.append((user.uuid,
204
                       user.email,
205
                       m.state_display()))
206

    
207
    return collect, labels