Revision aa27f246

b/snf-astakos-app/astakos/im/functions.py
70 70
from astakos.im.models import (
71 71
    AstakosUser, Invitation, ProjectMembership, ProjectApplication, Project,
72 72
    UserSetting,
73
    get_resource_names, new_chain, users_quotas)
73
    get_resource_names, new_chain)
74
from astakos.im.quotas import users_quotas
74 75
from astakos.im.project_notif import (
75 76
    membership_change_notify, membership_enroll_notify,
76 77
    membership_request_notify, membership_leave_request_notify,
b/snf-astakos-app/astakos/im/management/commands/astakos-quota.py
34 34
from optparse import make_option
35 35
from django.core.management.base import BaseCommand, CommandError
36 36

  
37
from astakos.im.models import sync_all_users, sync_users, AstakosUser
37
from astakos.im.models import AstakosUser
38
from astakos.im.quotas import sync_all_users, sync_users
38 39
from astakos.im.functions import get_user_by_uuid
39 40
from astakos.im.management.commands._common import is_uuid, is_email
40 41
from synnefo.lib.db.transaction import commit_on_success_strict
b/snf-astakos-app/astakos/im/management/commands/user-show.py
34 34
from django.core.management.base import BaseCommand, CommandError
35 35

  
36 36
from astakos.im.models import AstakosUser, get_latest_terms
37
from astakos.im.quotas import user_quotas
37 38
from astakos.im.util import model_to_dict
38 39
from synnefo.lib.ordereddict import OrderedDict
39 40

  
......
66 67
            raise CommandError(msg)
67 68

  
68 69
        for user in users:
69
            quotas = user.all_quotas()
70
            quotas = user_quotas(user)
70 71

  
71 72
            settings_dict = {}
72 73
            settings = user.settings()
b/snf-astakos-app/astakos/im/models.py
84 84
from synnefo.lib.db.intdecimalfield import intDecimalField
85 85
from synnefo.util.text import uenc, udec
86 86

  
87
from astakos.im.quotas import get_users_quotas_and_limits, set_user_quota
88

  
89 87
logger = logging.getLogger(__name__)
90 88

  
91 89
DEFAULT_CONTENT_TYPE = None
......
257 255

  
258 256
    register_resources(rs)
259 257

  
260

  
261
def get_default_quota():
262
    _DEFAULT_QUOTA = {}
263
    resources = Resource.objects.select_related('service').all()
264
    for resource in resources:
265
        capacity = resource.uplimit
266
        _DEFAULT_QUOTA[resource.full_name()] = capacity
267

  
268
    return _DEFAULT_QUOTA
269

  
270 258
def get_resource_names():
271 259
    _RESOURCE_NAMES = []
272 260
    resources = Resource.objects.select_related('service').all()
......
768 756
    def settings(self):
769 757
        return UserSetting.objects.filter(user=self)
770 758

  
771
    def all_quotas(self):
772
        quotas = users_quotas([self])
773
        try:
774
            return quotas[self.uuid]
775
        except:
776
            raise ValueError("could not compute quotas")
777

  
778

  
779
SYSTEM = 'system'
780

  
781
def initial_quotas(users):
782
    initial = {}
783
    default_quotas = get_default_quota()
784

  
785
    for user in users:
786
        uuid = user.uuid
787
        source_quota = {SYSTEM: dict(default_quotas)}
788
        initial[uuid] = source_quota
789

  
790
    objs = AstakosUserQuota.objects.select_related()
791
    orig_quotas = objs.filter(user__in=users)
792
    for user_quota in orig_quotas:
793
        uuid = user_quota.user.uuid
794
        user_init = initial.get(uuid, {})
795
        resource = user_quota.resource.full_name()
796
        user_init[resource] = user_quota.capacity
797
        initial[uuid] = user_init
798

  
799
    return initial
800

  
801

  
802
def get_grant_source(grant):
803
    return SYSTEM
804

  
805

  
806
def users_quotas(users, initial=None):
807
    if initial is None:
808
        quotas = initial_quotas(users)
809
    else:
810
        quotas = copy.deepcopy(initial)
811

  
812
    ACTUALLY_ACCEPTED = ProjectMembership.ACTUALLY_ACCEPTED
813
    objs = ProjectMembership.objects.select_related('project', 'person')
814
    memberships = objs.filter(person__in=users,
815
                              state__in=ACTUALLY_ACCEPTED,
816
                              project__state=Project.APPROVED)
817

  
818
    project_ids = set(m.project_id for m in memberships)
819
    objs = ProjectApplication.objects.select_related('project')
820
    apps = objs.filter(project__in=project_ids)
821

  
822
    project_dict = {}
823
    for app in apps:
824
        project_dict[app.project] = app
825

  
826
    objs = ProjectResourceGrant.objects.select_related()
827
    grants = objs.filter(project_application__in=apps)
828

  
829
    for membership in memberships:
830
        uuid = membership.person.uuid
831
        userquotas = quotas.get(uuid, {})
832

  
833
        application = project_dict[membership.project]
834

  
835
        for grant in grants:
836
            if grant.project_application_id != application.id:
837
                continue
838

  
839
            source = get_grant_source(grant)
840
            source_quotas = userquotas.get(source, {})
841

  
842
            resource = grant.resource.full_name()
843
            prev = source_quotas.get(resource, 0)
844
            new = prev + grant.member_capacity
845
            source_quotas[resource] = new
846
            userquotas[source] = source_quotas
847
        quotas[uuid] = userquotas
848

  
849
    return quotas
850

  
851 759

  
852 760
class AstakosUserAuthProviderManager(models.Manager):
853 761

  
......
2320 2228
    serial  =   models.AutoField(primary_key=True)
2321 2229

  
2322 2230

  
2323
def sync_users(users, sync=True):
2324
    def _sync_users(users, sync):
2325

  
2326
        info = {}
2327
        for user in users:
2328
            info[user.uuid] = user.email
2329

  
2330
        qh_quotas, qh_limits = get_users_quotas_and_limits(users)
2331
        astakos_initial = initial_quotas(users)
2332
        astakos_quotas = users_quotas(users)
2333

  
2334
        diff_quotas = {}
2335
        for holder, local in astakos_quotas.iteritems():
2336
            registered = qh_limits.get(holder, None)
2337
            if local != registered:
2338
                diff_quotas[holder] = dict(local)
2339

  
2340
        if sync:
2341
            r = set_user_quota(diff_quotas)
2342

  
2343
        return (qh_limits, qh_quotas,
2344
                astakos_initial, diff_quotas, info)
2345

  
2346
    return _sync_users(users, sync)
2347

  
2348

  
2349
def sync_all_users(sync=True):
2350
    users = AstakosUser.objects.verified()
2351
    return sync_users(users, sync)
2352

  
2353 2231
class ProjectMembershipHistory(models.Model):
2354 2232
    reasons_list    =   ['ACCEPT', 'REJECT', 'REMOVE']
2355 2233
    reasons         =   dict((k, v) for v, k in enumerate(reasons_list))
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