Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (7 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 = "Show project details"
46

    
47
    option_list = BaseCommand.option_list + (
48
        make_option('--app',
49
                    action='store_true',
50
                    dest='app',
51
                    default=False,
52
                    help="Show application details instead"),
53
        make_option('--pending',
54
                    action='store_true',
55
                    dest='pending',
56
                    default=False,
57
                    help="Show pending modification too"),
58
    )
59

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

    
64
        show_pending = bool(options['pending'])
65
        search_apps  = options['app']
66

    
67
        name_or_id = args[0]
68
        is_id = name_or_id.isdigit()
69
        if is_id:
70
            name_or_id = int(name_or_id)
71

    
72
        if search_apps:
73
            infolist = app_info(name_or_id, is_id)
74
        else:
75
            chains = get_chains(name_or_id, is_id)
76
            infolist = collect_info(chains, show_pending)
77

    
78
        if not infolist:
79
            kind = 'project application' if search_apps else 'project'
80
            field = 'id' if is_id else 'name'
81
            msg = "Unknown %s with %s '%s'" % (kind, field, name_or_id)
82
            raise CommandError(msg)
83

    
84
        for info in infolist:
85
            self.show_info(info)
86

    
87
    def show_info(self, info):
88
        for key, val in info.items():
89
            line = '%s: %s\n' % (key.rjust(22), format(val))
90
            self.stdout.write(line)
91
        self.stdout.write('\n')
92

    
93

    
94
def app_info(name_or_id, is_id):
95
    try:
96
        apps = ([ProjectApplication.objects.get(id=name_or_id)]
97
                if is_id
98
                else ProjectApplication.objects.search_by_name(name_or_id))
99
        return [app_fields(app) for app in apps]
100
    except ProjectApplication.DoesNotExist:
101
            return []
102

    
103
def get_chains(name_or_id, is_id):
104
    if is_id:
105
        try:
106
            return [Chain.objects.get(chain=name_or_id)]
107
        except Chain.DoesNotExist:
108
            return []
109
    else:
110
        return Chain.objects.search_by_name(name_or_id)
111

    
112
def collect_info(chains, pending):
113
    states = [chain.full_state() for chain in chains]
114

    
115
    infolist = []
116
    for state in states:
117
        infolist += (chain_fields(state, pending))
118
    return infolist
119

    
120
def chain_fields((s, project, app), request=False):
121
    l = []
122
    if project:
123
        l = [project_fields(s, project, app)]
124
        if request and s in Chain.PENDING_STATES:
125
            l.append(app_fields(app))
126
    else:
127
        l = [app_fields(app)]
128
    return l
129

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

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

    
153
    return d
154

    
155

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

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

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

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

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

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

    
194
    memberships = project.projectmembership_set
195
    accepted  = [str(m.person) for m in memberships.any_accepted()]
196
    requested = [str(m.person) for m in memberships.requested()]
197
    suspended = [str(m.person) for m in memberships.suspended()]
198

    
199
    if accepted:
200
        d['accepted members'] = ', '.join(accepted)
201

    
202
    if suspended:
203
        d['suspended members'] = ', '.join(suspended)
204

    
205
    if requested:
206
        d['membership requests'] = ', '.join(requested)
207

    
208
    return d