Revision aa27f246 snf-astakos-app/astakos/im/quotas.py

b/snf-astakos-app/astakos/im/quotas.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from astakos.im.models import (
35
    Resource, AstakosUserQuota, AstakosUser,
36
    Project, ProjectMembership, ProjectResourceGrant, ProjectApplication)
34 37
from astakos.quotaholder.callpoint import QuotaholderDjangoDBCallpoint
35 38

  
36 39
qh = QuotaholderDjangoDBCallpoint()
......
94 97

  
95 98
def set_user_quota(quotas):
96 99
    qh.set_holder_quota(quotas)
100

  
101

  
102
def get_default_quota():
103
    _DEFAULT_QUOTA = {}
104
    resources = Resource.objects.select_related('service').all()
105
    for resource in resources:
106
        capacity = resource.uplimit
107
        _DEFAULT_QUOTA[resource.full_name()] = capacity
108

  
109
    return _DEFAULT_QUOTA
110

  
111

  
112
SYSTEM = 'system'
113

  
114

  
115
def initial_quotas(users):
116
    initial = {}
117
    default_quotas = get_default_quota()
118

  
119
    for user in users:
120
        uuid = user.uuid
121
        source_quota = {SYSTEM: dict(default_quotas)}
122
        initial[uuid] = source_quota
123

  
124
    objs = AstakosUserQuota.objects.select_related()
125
    orig_quotas = objs.filter(user__in=users)
126
    for user_quota in orig_quotas:
127
        uuid = user_quota.user.uuid
128
        user_init = initial.get(uuid, {})
129
        resource = user_quota.resource.full_name()
130
        user_init[resource] = user_quota.capacity
131
        initial[uuid] = user_init
132

  
133
    return initial
134

  
135

  
136
def get_grant_source(grant):
137
    return SYSTEM
138

  
139

  
140
def users_quotas(users, initial=None):
141
    if initial is None:
142
        quotas = initial_quotas(users)
143
    else:
144
        quotas = copy.deepcopy(initial)
145

  
146
    ACTUALLY_ACCEPTED = ProjectMembership.ACTUALLY_ACCEPTED
147
    objs = ProjectMembership.objects.select_related('project', 'person')
148
    memberships = objs.filter(person__in=users,
149
                              state__in=ACTUALLY_ACCEPTED,
150
                              project__state=Project.APPROVED)
151

  
152
    project_ids = set(m.project_id for m in memberships)
153
    objs = ProjectApplication.objects.select_related('project')
154
    apps = objs.filter(project__in=project_ids)
155

  
156
    project_dict = {}
157
    for app in apps:
158
        project_dict[app.project] = app
159

  
160
    objs = ProjectResourceGrant.objects.select_related()
161
    grants = objs.filter(project_application__in=apps)
162

  
163
    for membership in memberships:
164
        uuid = membership.person.uuid
165
        userquotas = quotas.get(uuid, {})
166

  
167
        application = project_dict[membership.project]
168

  
169
        for grant in grants:
170
            if grant.project_application_id != application.id:
171
                continue
172

  
173
            source = get_grant_source(grant)
174
            source_quotas = userquotas.get(source, {})
175

  
176
            resource = grant.resource.full_name()
177
            prev = source_quotas.get(resource, 0)
178
            new = prev + grant.member_capacity
179
            source_quotas[resource] = new
180
            userquotas[source] = source_quotas
181
        quotas[uuid] = userquotas
182

  
183
    return quotas
184

  
185

  
186
def user_quotas(user):
187
    quotas = users_quotas([user])
188
    try:
189
        return quotas[user.uuid]
190
    except KeyError:
191
        raise ValueError("could not compute quotas")
192

  
193

  
194
def sync_users(users, sync=True):
195
    def _sync_users(users, sync):
196

  
197
        info = {}
198
        for user in users:
199
            info[user.uuid] = user.email
200

  
201
        qh_quotas, qh_limits = get_users_quotas_and_limits(users)
202
        astakos_initial = initial_quotas(users)
203
        astakos_quotas = users_quotas(users)
204

  
205
        diff_quotas = {}
206
        for holder, local in astakos_quotas.iteritems():
207
            registered = qh_limits.get(holder, None)
208
            if local != registered:
209
                diff_quotas[holder] = dict(local)
210

  
211
        if sync:
212
            r = set_user_quota(diff_quotas)
213

  
214
        return (qh_limits, qh_quotas,
215
                astakos_initial, diff_quotas, info)
216

  
217
    return _sync_users(users, sync)
218

  
219

  
220
def sync_all_users(sync=True):
221
    users = AstakosUser.objects.verified()
222
    return sync_users(users, sync)

Also available in: Unified diff