Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / project-list.py @ 88f5242e

History | View | Annotate | Download (5.8 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 = """List projects and project status.
46

47
    Project status can be one of:
48
      Pending              an uninitialized project, pending review
49

50
      Active               an active project
51

52
      Denied               an uninitialized project, denied by the admin
53

54
      Dismissed            a denied project, dismissed by the applicant
55

56
      Cancelled            an uninitialized project, cancelled by the applicant
57

58
      Suspended            a project suspended by the admin;
59
                           it can later be resumed
60

61
      Terminated           a terminated project; its name can be claimed
62
                           by a new project"""
63

    
64
    option_list = SynnefoCommand.option_list + (
65
        make_option('--all',
66
                    action='store_true',
67
                    dest='all',
68
                    default=False,
69
                    help="List all projects (default)"),
70
        make_option('--new',
71
                    action='store_true',
72
                    dest='new',
73
                    default=False,
74
                    help="List only new pending uninitialized projects"),
75
        make_option('--modified',
76
                    action='store_true',
77
                    dest='modified',
78
                    default=False,
79
                    help="List only projects with pending modification"),
80
        make_option('--pending',
81
                    action='store_true',
82
                    dest='pending',
83
                    default=False,
84
                    help=("Show only projects with a pending application "
85
                          "(equiv. --modified --new)")),
86
        make_option('--skip',
87
                    action='store_true',
88
                    dest='skip',
89
                    default=False,
90
                    help="Skip cancelled and terminated projects"),
91
        make_option('--name',
92
                    dest='name',
93
                    help='Filter projects by name'),
94
        make_option('--owner',
95
                    dest='owner',
96
                    help='Filter projects by owner\'s email or uuid'),
97
    )
98

    
99
    def handle(self, *args, **options):
100

    
101
        flt = Q()
102
        owner = options['owner']
103
        if owner:
104
            flt &= filter_by_owner(owner)
105

    
106
        name = options['name']
107
        if name:
108
            flt &= filter_by_name(name)
109

    
110
        chains = Project.objects.all_with_pending(flt)
111

    
112
        if not options['all']:
113
            if options['skip']:
114
                pred = lambda c: (
115
                    c[0].overall_state() not in Project.SKIP_STATES
116
                    or c[1] is not None)
117
                chains = filter_preds([pred], chains)
118

    
119
            preds = []
120
            if options['new'] or options['pending']:
121
                preds.append(
122
                    lambda c: c[0].overall_state() == Project.O_PENDING)
123
            if options['modified'] or options['pending']:
124
                preds.append(
125
                    lambda c: c[0].overall_state() != Project.O_PENDING
126
                    and c[1] is not None)
127

    
128
            if preds:
129
                chains = filter_preds(preds, chains)
130

    
131
        labels = ('ProjID', 'Name', 'Owner', 'Status', 'Pending AppID')
132

    
133
        info = chain_info(chains)
134
        utils.pprint_table(self.stdout, info, labels,
135
                           options["output_format"])
136

    
137

    
138
def filter_preds(preds, chains):
139
    return [c for c in chains
140
            if any(map(lambda f: f(c), preds))]
141

    
142

    
143
def filter_by_name(name):
144
    return Q(application__name=name)
145

    
146

    
147
def filter_by_owner(s):
148
    if is_email(s):
149
        return Q(application__owner__email=s)
150
    if is_uuid(s):
151
        return Q(application__owner__uuid=s)
152
    raise CommandError("Expecting either email or uuid.")
153

    
154

    
155
def chain_info(chains):
156
    l = []
157
    for project, pending_app in chains:
158
        status = project.state_display()
159
        pending_appid = pending_app.id if pending_app is not None else ""
160
        application = project.application
161

    
162
        t = (project.uuid,
163
             application.name,
164
             application.owner.email,
165
             status,
166
             pending_appid,
167
             )
168
        l.append(t)
169
    return l