Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / project-list.py @ 6d583e07

History | View | Annotate | Download (6.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

    
36
from snf_django.management.commands import SynnefoCommand, CommandError
37

    
38
from astakos.im.models import Project
39
from django.db.models import Q
40
from snf_django.management import utils
41
from ._common import is_uuid, is_email
42

    
43

    
44
class Command(SynnefoCommand):
45
    help = """
46
    List projects and project status.
47

48
    Project status can be one of:
49
      Pending              an application <AppId> for a new project
50

51
      Active               an active project
52

53
      Active - Pending     an active project with
54
                           a pending modification <AppId>
55

56
      Denied               an application for a new project,
57
                           denied by the admin
58

59
      Dismissed            a denied project, dismissed by the applicant
60

61
      Cancelled            an application for a new project,
62
                           cancelled by the applicant
63

64
      Suspended            a project suspended by the admin;
65
                           it can later be resumed
66

67
      Suspended - Pending  a suspended project with
68
                           a pending modification <AppId>
69

70
      Terminated           a terminated project; its name can be claimed
71
                           by a new project
72
"""
73

    
74
    option_list = SynnefoCommand.option_list + (
75
        make_option('--all',
76
                    action='store_true',
77
                    dest='all',
78
                    default=False,
79
                    help="List all projects (default)"),
80
        make_option('--new',
81
                    action='store_true',
82
                    dest='new',
83
                    default=False,
84
                    help="List only new project applications"),
85
        make_option('--modified',
86
                    action='store_true',
87
                    dest='modified',
88
                    default=False,
89
                    help="List only projects with pending modification"),
90
        make_option('--pending',
91
                    action='store_true',
92
                    dest='pending',
93
                    default=False,
94
                    help=("Show only projects with a pending application "
95
                          "(equiv. --modified --new)")),
96
        make_option('--skip',
97
                    action='store_true',
98
                    dest='skip',
99
                    default=False,
100
                    help="Skip cancelled and terminated projects"),
101
        make_option('--name',
102
                    dest='name',
103
                    help='Filter projects by name'),
104
        make_option('--owner',
105
                    dest='owner',
106
                    help='Filter projects by owner\'s email or uuid'),
107
    )
108

    
109
    def handle(self, *args, **options):
110

    
111
        flt = Q()
112
        owner = options['owner']
113
        if owner:
114
            flt &= filter_by_owner(owner)
115

    
116
        name = options['name']
117
        if name:
118
            flt &= filter_by_name(name)
119

    
120
        chains = Project.objects.all_with_pending(flt)
121

    
122
        if not options['all']:
123
            if options['skip']:
124
                pred = lambda c: (
125
                    c[0].overall_state() not in Project.SKIP_STATES
126
                    or c[1] is not None)
127
                chains = filter_preds([pred], chains)
128

    
129
            preds = []
130
            if options['new'] or options['pending']:
131
                preds.append(
132
                    lambda c: c[0].overall_state() == Project.O_PENDING)
133
            if options['modified'] or options['pending']:
134
                preds.append(
135
                    lambda c: c[0].overall_state() != Project.O_PENDING
136
                    and c[1] is not None)
137

    
138
            if preds:
139
                chains = filter_preds(preds, chains)
140

    
141
        labels = ('ProjID', 'Name', 'Owner', 'Email', 'Status',
142
                  'Pending AppID')
143

    
144
        info = chain_info(chains)
145
        utils.pprint_table(self.stdout, info, labels,
146
                           options["output_format"])
147

    
148

    
149
def filter_preds(preds, chains):
150
    return [c for c in chains
151
            if any(map(lambda f: f(c), preds))]
152

    
153

    
154
def filter_by_name(name):
155
    return Q(application__name=name)
156

    
157

    
158
def filter_by_owner(s):
159
    if is_email(s):
160
        return Q(application__owner__email=s)
161
    if is_uuid(s):
162
        return Q(application__owner__uuid=s)
163
    raise CommandError("Expecting either email or uuid.")
164

    
165

    
166
def chain_info(chains):
167
    l = []
168
    for project, pending_app in chains:
169
        status = project.state_display()
170
        pending_appid = pending_app.id if pending_app is not None else ""
171
        application = project.application
172

    
173
        t = (project.pk,
174
             application.name,
175
             application.owner.realname,
176
             application.owner.email,
177
             status,
178
             pending_appid,
179
             )
180
        l.append(t)
181
    return l