Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / project-list.py @ 44aa52fd

History | View | Annotate | Download (5.9 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', 'Email', 'Status',
132
                  'Pending AppID')
133

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

    
138

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

    
143

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

    
147

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

    
155

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

    
163
        t = (project.pk,
164
             application.name,
165
             application.owner.realname,
166
             application.owner.email,
167
             status,
168
             pending_appid,
169
             )
170
        l.append(t)
171
    return l