Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (7.4 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 BaseCommand, CommandError
36

    
37
from synnefo.lib.ordereddict import OrderedDict
38
from astakos.im.models import Chain, ProjectApplication
39

    
40
from ._common import format
41

    
42

    
43
class Command(BaseCommand):
44
    args = "<id or name>"
45
    help = """
46
    Show project details.
47

48
    Command comes in two forms:
49
        project-show <id>    Look up project by id
50

51
        project-show <name>  Look up all projects whose name
52
                             contains the given string
53
"""
54

    
55
    option_list = BaseCommand.option_list + (
56
        make_option('--app',
57
                    action='store_true',
58
                    dest='app',
59
                    default=False,
60
                    help="Show details of applications instead of projects"
61
                    ),
62
        make_option('--pending',
63
                    action='store_true',
64
                    dest='pending',
65
                    default=False,
66
                    help=("For a given project, show also pending modifications "
67
                          "(applications), if any")
68
                    ),
69
        )
70

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

    
75
        show_pending = bool(options['pending'])
76
        search_apps  = options['app']
77

    
78
        name_or_id = args[0]
79
        is_id = name_or_id.isdigit()
80
        if is_id:
81
            name_or_id = int(name_or_id)
82

    
83
        if search_apps:
84
            infolist = app_info(name_or_id, is_id)
85
        else:
86
            chains = get_chains(name_or_id, is_id)
87
            infolist = collect_info(chains, show_pending)
88

    
89
        if not infolist:
90
            kind = 'project application' if search_apps else 'project'
91
            field = 'id' if is_id else 'name'
92
            msg = "Unknown %s with %s '%s'" % (kind, field, name_or_id)
93
            raise CommandError(msg)
94

    
95
        for info in infolist:
96
            self.show_info(info)
97

    
98
    def show_info(self, info):
99
        for key, val in info.items():
100
            line = '%s: %s\n' % (key.rjust(22), format(val))
101
            self.stdout.write(line)
102
        self.stdout.write('\n')
103

    
104

    
105
def app_info(name_or_id, is_id):
106
    try:
107
        apps = ([ProjectApplication.objects.get(id=name_or_id)]
108
                if is_id
109
                else ProjectApplication.objects.search_by_name(name_or_id))
110
        return [app_fields(app) for app in apps]
111
    except ProjectApplication.DoesNotExist:
112
            return []
113

    
114
def get_chains(name_or_id, is_id):
115
    if is_id:
116
        try:
117
            return [Chain.objects.get(chain=name_or_id)]
118
        except Chain.DoesNotExist:
119
            return []
120
    else:
121
        return Chain.objects.search_by_name(name_or_id)
122

    
123
def collect_info(chains, pending):
124
    states = [chain.full_state() for chain in chains]
125

    
126
    infolist = []
127
    for state in states:
128
        infolist += (chain_fields(state, pending))
129
    return infolist
130

    
131
def chain_fields((s, project, app), request=False):
132
    l = []
133
    if project:
134
        l = [project_fields(s, project, app)]
135
        if request and s in Chain.PENDING_STATES:
136
            l.append(app_fields(app))
137
    else:
138
        l = [app_fields(app)]
139
    return l
140

    
141
def app_fields(app):
142
    mem_limit = app.limit_on_members_number
143
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"
144

    
145
    d = OrderedDict([
146
            ('project id', app.chain),
147
            ('application id', app.id),
148
            ('name', app.name),
149
            ('status', app.state_display()),
150
            ('owner', app.owner),
151
            ('applicant', app.applicant),
152
            ('homepage', app.homepage),
153
            ('description', app.description),
154
            ('comments for review', app.comments),
155
            ('request issue date', app.issue_date),
156
            ('request start date', app.start_date),
157
            ('request end date', app.end_date),
158
            ('resources', app.resource_policies),
159
            ('join policy', app.member_join_policy_display),
160
            ('leave policy', app.member_leave_policy_display),
161
            ('max members', mem_limit_show),
162
            ])
163

    
164
    return d
165

    
166

    
167
def project_fields(s, project, last_app):
168
    app = project.application
169

    
170
    d = OrderedDict([
171
            ('project id', project.id),
172
            ('application id', app.id),
173
            ('name', app.name),
174
            ('status', Chain.state_display(s)),
175
            ])
176
    if s in Chain.PENDING_STATES:
177
        d.update([('pending application', last_app.id)])
178

    
179
    d.update([('owner', app.owner),
180
              ('applicant', app.applicant),
181
              ('homepage', app.homepage),
182
              ('description', app.description),
183
              ('comments for review', app.comments),
184
              ('request issue date', app.issue_date),
185
              ('request start date', app.start_date),
186
              ('creation date', project.creation_date),
187
              ('request end date', app.end_date),
188
              ])
189

    
190
    deact_date = project.deactivation_date
191
    if deact_date is not None:
192
        d['deactivation date'] = deact_date
193

    
194
    mem_limit = app.limit_on_members_number
195
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"
196

    
197
    d.update([
198
            ('resources', app.resource_policies),
199
            ('join policy', app.member_join_policy_display),
200
            ('leave policy', app.member_leave_policy_display),
201
            ('max members', mem_limit_show),
202
            ('total members', project.members_count()),
203
            ])
204

    
205
    memberships = project.projectmembership_set
206
    accepted  = [str(m.person) for m in memberships.any_accepted()]
207
    requested = [str(m.person) for m in memberships.requested()]
208
    suspended = [str(m.person) for m in memberships.suspended()]
209

    
210
    if accepted:
211
        d['accepted members'] = ', '.join(accepted)
212

    
213
    if suspended:
214
        d['suspended members'] = ', '.join(suspended)
215

    
216
    if requested:
217
        d['membership requests'] = ', '.join(requested)
218

    
219
    return d