Statistics
| Branch: | Tag: | Revision:

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

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 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 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 = SynnefoCommand.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
        first = True
96
        for info in infolist:
97
            if not first:
98
                self.stdout.write("\n")
99
            else:
100
                first = False
101
            utils.pprint_table(self.stdout, [info.values()], info.keys(),
102
                               options["output_format"], vertical=True)
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

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

    
124

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

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

    
133

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

    
144

    
145
def app_fields(app):
146
    mem_limit = app.limit_on_members_number
147
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"
148

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

    
168
    return d
169

    
170

    
171
def project_fields(s, project, last_app):
172
    app = project.application
173

    
174
    d = OrderedDict([
175
        ('project id', project.id),
176
        ('application id', app.id),
177
        ('name', app.name),
178
        ('status', Chain.state_display(s)),
179
    ])
180
    if s in Chain.PENDING_STATES:
181
        d.update([('pending application', last_app.id)])
182

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

    
194
    deact_date = project.deactivation_date
195
    if deact_date is not None:
196
        d['deactivation date'] = deact_date
197

    
198
    mem_limit = app.limit_on_members_number
199
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"
200

    
201
    d.update([
202
            ('resources', app.resource_policies),
203
            ('join policy', app.member_join_policy_display),
204
            ('leave policy', app.member_leave_policy_display),
205
            ('max members', mem_limit_show),
206
            ('total members', project.members_count()),
207
    ])
208

    
209
    memberships = project.projectmembership_set
210
    accepted = [str(m.person) for m in memberships.any_accepted()]
211
    requested = [str(m.person) for m in memberships.requested()]
212
    suspended = [str(m.person) for m in memberships.suspended()]
213

    
214
    if accepted:
215
        d['accepted members'] = ', '.join(accepted)
216

    
217
    if suspended:
218
        d['suspended members'] = ', '.join(suspended)
219

    
220
    if requested:
221
        d['membership requests'] = ', '.join(requested)
222

    
223
    return d