Revision bfe23b13

b/snf-astakos-app/astakos/im/api/backends/lib/django/__init__.py
319 319
        g.policies = policies
320 320
#        g.members = members
321 321
        g.owners = owners
322
        return self._details(g)
323
    
324
    
325
    @safe
326
    def submit_application(self, **kwargs):
327
        app = self._create_object(ProjectApplication, **kwargs)
328
        notification = build_notification(
329
            settings.SERVER_EMAIL,
330
            [settings.ADMINS],
331
            _(GROUP_CREATION_SUBJECT) % {'group':app.definition.name},
332
            _('An new project application identified by %(serial)s has been submitted.') % app.serial
333
        )
334
        notification.send()
335
    
336
    @safe
337
    def list_applications(self):
338
        return self._list(ProjectAppication)
339
    
340
    @safe
341
    def approve_application(self, serial):
342
        app = self._lookup_object(ProjectAppication, serial=serial)
343
        notify = False
344
        if not app.precursor_application:
345
            kwargs = {
346
                'application':app,
347
                'creation_date':datetime.now(),
348
                'last_approval_date':datetime.now(),
349
            }
350
            project = self._create_object(Project, **kwargs)
351
        else:
352
            project = app.precursor_application.project
353
            last_approval_date = project.last_approval_date
354
            if project.is_valid:
355
                project.application = app
356
                project.last_approval_date = datetime.now()
357
                project.save()
358
            else:
359
                raise Exception(_(astakos_messages.INVALID_PROJECT) % project.__dict__)
360
        
361
        r = _synchonize_project(project.serial)
362
        if not r.is_success:
363
            # revert to precursor
364
            project.appication = app.precursor_application
365
            if project.application:
366
                project.last_approval_date = last_approval_date
367
            project.save()
368
            r = synchonize_project(project.serial)
369
            if not r.is_success:
370
                raise Exception(_(astakos_messages.QH_SYNC_ERROR))
371
        else:
372
            project.last_application_synced = app
373
            project.save()
374
            sender, recipients, subject, message
375
            notification = build_notification(
376
                settings.SERVER_EMAIL,
377
                [project.owner.email],
378
                _('Project application has been approved on %s alpha2 testing' % SITENAME),
379
                _('Your application request %(serial)s has been apporved.')
380
            )
381
            notification.send()
382
    
383
    
384
    @safe
385
    def list_projects(self, filter_property=None):
386
        if filter_property:
387
            q = filter_queryset_by_property(
388
                Project.objects.all(),
389
                filter_property
390
            )
391
            return map(lambda o: self._details(o), q)
392
        return self._list(Project)
393
        
394

  
395
    
396
    @safe
397
    def add_project_member(self, serial, user_id, request_user):
398
        project = self._lookup_object(Project, serial=serial)
399
        user = self.lookup_user(user_id)
400
        if not project.owner == request_user:
401
            raise Exception(_(astakos_messages.NOT_PROJECT_OWNER))
402
        
403
        if not project.is_alive:
404
            raise Exception(_(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
405
        if len(project.members) + 1 > project.limit_on_members_number:
406
            raise Exception(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
407
        m = self._lookup_object(ProjectMembership, person=user, project=project)
408
        if m.is_accepted:
409
            return
410
        m.is_accepted = True
411
        m.decision_date = datetime.now()
412
        m.save()
413
        notification = build_notification(
414
            settings.SERVER_EMAIL,
415
            [user.email],
416
            _('Your membership on project %(name)s has been accepted.') % project.definition.__dict__, 
417
            _('Your membership on project %(name)s has been accepted.') % project.definition.__dict__,
418
        )
419
        notification.send()
420
    
421
    @safe
422
    def remove_project_member(self, serial, user_id, request_user):
423
        project = self._lookup_object(Project, serial=serial)
424
        if not project.is_alive:
425
            raise Exception(_(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
426
        if not project.owner == request_user:
427
            raise Exception(_(astakos_messages.NOT_PROJECT_OWNER))
428
        user = self.lookup_user(user_id)
429
        m = self._lookup_object(ProjectMembership, person=user, project=project)
430
        if not m.is_accepted:
431
            return
432
        m.is_accepted = False
433
        m.decision_date = datetime.now()
434
        m.save()
435
        notification = build_notification(
436
            settings.SERVER_EMAIL,
437
            [user.email],
438
            _('Your membership on project %(name)s has been removed.') % project.definition.__dict__, 
439
            _('Your membership on project %(name)s has been removed.') % project.definition.__dict__,
440
        )
441
        notification.send()    
442
    
443
    @safe
444
    def suspend_project(self, serial):
445
        project = self._lookup_object(Project, serial=serial)
446
        project.suspend()
447
        notification = build_notification(
448
            settings.SERVER_EMAIL,
449
            [project.owner.email],
450
            _('Project %(name)s has been suspended on %s alpha2 testing' % SITENAME),
451
            _('Project %(name)s has been suspended on %s alpha2 testing' % SITENAME)
452
        )
453
        notification.send()
454
    
455
    @safe
456
    def terminate_project(self, serial):
457
        project = self._lookup_object(Project, serial=serial)
458
        project.termination()
459
        notification = build_notification(
460
            settings.SERVER_EMAIL,
461
            [project.owner.email],
462
            _('Project %(name)s has been terminated on %s alpha2 testing' % SITENAME),
463
            _('Project %(name)s has been terminated on %s alpha2 testing' % SITENAME)
464
        )
465
        notification.send()
466
    
467
    @safe
468
    def synchonize_project(self, serial):
469
        project = self._lookup_object(Project, serial=serial)
470
        project.sync()
322
        return self._details(g)
b/snf-astakos-app/astakos/im/fixtures/member_join_policies.json
1 1
[
2 2
    {
3
        "model": "im.memberleavepolicy",
3
        "model": "im.memberjoinpolicy",
4 4
        "pk": 1,
5 5
        "fields": {
6 6
            "policy": "auto_accept",
7
            "description": "remove requests are automatically accepted by the system"
7
            "description": "leave requests are automatically accepted by the system"
8 8
        }
9 9
    },
10 10
    {
11
        "model": "im.memberleavepolicy",
11
        "model": "im.memberjoinpolicy",
12 12
        "pk": 2,
13 13
        "fields": {
14 14
            "policy": "owner_accepts",
15
            "description": "remove requests must be accepted by the owner of the project"
15
            "description": "leave requests must be accepted by the owner of the project"
16 16
        }
17 17
    },
18 18
    {
19
        "model": "im.memberleavepolicy",
19
        "model": "im.memberjoinpolicy",
20 20
        "pk": 3,
21 21
        "fields": {
22 22
            "policy": "closed",
23
            "description": "members can not leave the project"
23
            "description": "no member can leave the project"
24 24
        }
25 25
    }
26
]
26
]
b/snf-astakos-app/astakos/im/fixtures/member_leave_policies.json
1 1
[
2 2
    {
3
        "model": "im.memberjoinpolicy",
3
        "model": "im.memberleavepolicy",
4 4
        "pk": 1,
5 5
        "fields": {
6 6
            "policy": "auto_accept",
7
            "description": "leave requests are automatically accepted by the system"
7
            "description": "remove requests are automatically accepted by the system"
8 8
        }
9 9
    },
10 10
    {
11
        "model": "im.memberjoinpolicy",
11
        "model": "im.memberleavepolicy",
12 12
        "pk": 2,
13 13
        "fields": {
14 14
            "policy": "owner_accepts",
15
            "description": "leave requests must be accepted by the owner of the project"
15
            "description": "remove requests must be accepted by the owner of the project"
16 16
        }
17 17
    },
18 18
    {
19
        "model": "im.memberjoinpolicy",
19
        "model": "im.memberleavepolicy",
20 20
        "pk": 3,
21 21
        "fields": {
22 22
            "policy": "closed",
23
            "description": "no member can leave the project"
23
            "description": "members can not leave the project"
24 24
        }
25 25
    }
26 26
]
b/snf-astakos-app/astakos/im/forms.py
1019 1019
        try:
1020 1020
            return self.valid_users
1021 1021
        except:
1022
            return ()
1022
            return ()
1023

  
1024
class ProjectMembersSortForm(forms.Form):
1025
    sorting = forms.ChoiceField(
1026
        label='Sort by',
1027
        choices=(('person__email', 'User Id'),
1028
                 ('person__first_name', 'Name'),
1029
                 ('acceptance_date', 'Acceptance date')
1030
        ),
1031
        required=True
1032
    )
1033

  
1034
class ProjectGroupSearchForm(forms.Form):
1035
    q = forms.CharField(max_length=200, label='Search project')
b/snf-astakos-app/astakos/im/management/commands/project-application-approve.py
1
# Copyright 2012 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 django.core.management.base import BaseCommand, CommandError
37
from django.db import transaction
38
from django.views.generic.create_update import lookup_object
39
from django.http import Http404
40

  
41
from astakos.im.models import ProjectApplication
42

  
43
@transaction.commit_on_success
44
class Command(BaseCommand):
45
    args = "<project application id>"
46
    help = "Update project state"
47

  
48
    def handle(self, *args, **options):
49
        if len(args) < 1:
50
            raise CommandError("Please provide a group identifier")
51
        
52
        try:
53
            id = int(args[0])
54
        except ValueError:
55
            raise CommandError('Invalid id')
56
        else:
57
            try:
58
                # Is it a project application id?
59
                app = lookup_object(ProjectApplication, id, None, None)
60
            except Http404:
61
                raise CommandError('Invalid id')
62
            try:
63
                app.approve()
64
            except BaseException, e:
65
                raise CommandError(e)
b/snf-astakos-app/astakos/im/management/commands/project-list.py
52 52
    def handle_noargs(self, **options):
53 53
        apps = ProjectApplication.objects.select_related().all()
54 54

  
55
        labels = ('id', 'name', 'status')
55
        labels = ('id', 'name', 'state')
56 56
        columns = (3, 40, 10)
57 57

  
58 58
        if not options['csv']:
......
65 65
            fields = (
66 66
                str(app.id),
67 67
                app.definition.name,
68
                app.status
68
                app.state
69 69
            )
70 70

  
71 71
            if options['csv']:
b/snf-astakos-app/astakos/im/management/commands/project-update.py
35 35

  
36 36
from django.core.management.base import BaseCommand, CommandError
37 37
from django.db import transaction
38
from django.views.generic.create_update import lookup_object
39
from django.http import Http404
38 40

  
39
from astakos.im.models import _lookup_object, ProjectApplication, Project
41
from astakos.im.models import (
42
    ProjectApplication, Project, PENDING
43
)
40 44

  
41 45
@transaction.commit_on_success
42 46
class Command(BaseCommand):
43
    args = "<project application id>"
47
    args = "<project id>"
44 48
    help = "Update project state"
45 49

  
46 50
    option_list = BaseCommand.option_list + (
47
        make_option('--approve',
48
                    action='store_true',
49
                    dest='approve',
50
                    default=False,
51
                    help="Approve group"),
52 51
        make_option('--terminate',
53 52
                    action='store_true',
54 53
                    dest='terminate',
......
65 64
        if len(args) < 1:
66 65
            raise CommandError("Please provide a group identifier")
67 66
        
68
        app = None
69
        p = None
70 67
        try:
71 68
            id = int(args[0])
72 69
        except ValueError:
73 70
            raise CommandError('Invalid id')
74 71
        else:
75 72
            try:
76
                # Is it a project application id?
77
                app = _lookup_object(ProjectApplication, id=id)
78
            except ProjectApplication.DoesNotExist:
79
                try:
80
                    # Is it a project id?
81
                    p = _lookup_object(Project, id=id)
82
                except Project.DoesNotExist:
83
                    raise CommandError('Invalid id')
84
            try:
85
                if options['approve']:
86
                    if not app:
87
                        raise CommandError('Project application id is required.')
88
                    app.approve()
89

  
90
                if app and app.status != 'Pending':
91
                    p = app.project
92

  
73
                # Is it a project id?
74
                p = lookup_object(Project, id, None, None)
75
            except Http404:
76
                raise CommandError('Invalid id')
77
            else:
93 78
                if options['terminate']:
94 79
                    p.terminate()
95
                if options['suspend']:
80
                elif options['suspend']:
96 81
                    p.suspend()
97 82
            except BaseException, e:
98
                import traceback
99
                traceback.print_exc()
100 83
                raise CommandError(e)
b/snf-astakos-app/astakos/im/messages.py
47 47
                                               You are going to receive a verification email in the new address.'
48 48

  
49 49
OBJECT_CREATED                          =   'The %(verbose_name)s was created successfully.'
50
MEMBER_JOINED_GROUP                     =   '%(realname)s has been successfully joined the group.'
50
USER_JOINED_GROUP                       =   '%(realname)s has been successfully joined the group.'
51
USER_LEFT_GROUP                         =   '%(realname)s has been successfully left the group.'
52
USER_MEMBERSHIP_REJECTED                =   '%(realname)s\'s request to join the group has been rejected.'
51 53
MEMBER_REMOVED                          =   '%(realname)s has been successfully removed from the group.'
52 54
BILLING_ERROR                           =   'Service response status: %(status)d' 
53 55
LOGOUT_SUCCESS                          =   'You have successfully logged out.'
......
57 59

  
58 60
MAX_INVITATION_NUMBER_REACHED   =           'There are no invitations left.'
59 61
GROUP_MAX_PARTICIPANT_NUMBER_REACHED    =   'Group maximum participant number has been reached.'
62
PROJECT_MAX_PARTICIPANT_NUMBER_REACHED  =   'Project maximum participant number has been reached.'
60 63
NO_APPROVAL_TERMS                       =   'There are no approval terms.'
61 64
PENDING_EMAIL_CHANGE_REQUEST            =   'There is already a pending change email request.'
62 65
OBJECT_CREATED_FAILED                   =   'The %(verbose_name)s creation failed: %(reason)s.'
63 66
GROUP_JOIN_FAILURE                      =   'Failed to join group.'
67
PROJECT_JOIN_FAILURE                    =   'Failed to join project.'
64 68
GROUPKIND_UNKNOWN                       =   'There is no such a group kind'
65 69
NOT_MEMBER                              =   'User is not member of the group.'
66 70
NOT_OWNER                               =   'User is not a group owner.'
......
136 140
MEMBER_JOIN_POLICY_CLOSED               =   'The project member join policy is cloesd.'
137 141
MEMBER_LEAVE_POLICY_CLOSED              =   'The project member leave policy is cloesd.'
138 142
NOT_MEMBERSHIP_REQUEST                  =   'There is no such a membership request.'
143
MEMBERSHIP_REQUEST_EXISTS               =   'There is alreary such a membership request.'
139 144
NO_APPLICANT                            =   'Project application requires an applicant. None found.'
140
ADD_PROJECT_MEMBERS_Q_HELP              =   'Add comma separated user emails, eg. user1@user.com, user2@user.com'
145
ADD_PROJECT_MEMBERS_Q_HELP              =   'Add comma separated user emails, eg. user1@user.com, user2@user.com'
146
MISSING_IDENTIFIER                      =   'Missing identifier.'
147
UNKNOWN_IDENTIFIER                      =   'Unknown identidier.'
148
PENDING_MEMBERSHIP_LEAVE                =   'Your request is pending acceptio.'
b/snf-astakos-app/astakos/im/migrations/0035_auto__add_memberjoinpolicy__add_projectmembershiphistory__add_projecta.py
1
# encoding: utf-8
2
import datetime
3
from south.db import db
4
from south.v2 import SchemaMigration
5
from django.db import models
6

  
7
class Migration(SchemaMigration):
8

  
9
    def forwards(self, orm):
10
        
11
        # Adding model 'MemberJoinPolicy'
12
        db.create_table('im_memberjoinpolicy', (
13
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14
            ('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
15
            ('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
16
        ))
17
        db.send_create_signal('im', ['MemberJoinPolicy'])
18

  
19
        # Adding model 'ProjectMembershipHistory'
20
        db.create_table('im_projectmembershiphistory', (
21
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
22
            ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.AstakosUser'])),
23
            ('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Project'])),
24
            ('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 10, 13, 48, 24, 819868))),
25
            ('removal_date', self.gf('django.db.models.fields.DateField')(null=True)),
26
            ('rejection_date', self.gf('django.db.models.fields.DateField')(null=True)),
27
        ))
28
        db.send_create_signal('im', ['ProjectMembershipHistory'])
29

  
30
        # Adding model 'ProjectApplication'
31
        db.create_table('im_projectapplication', (
32
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
33
            ('applicant', self.gf('django.db.models.fields.related.ForeignKey')(related_name='my_project_applications', to=orm['im.AstakosUser'])),
34
            ('owner', self.gf('django.db.models.fields.related.ForeignKey')(related_name='own_project_applications', to=orm['im.AstakosUser'])),
35
            ('comments', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
36
            ('definition', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['im.ProjectDefinition'], unique=True)),
37
            ('issue_date', self.gf('django.db.models.fields.DateTimeField')()),
38
            ('precursor_application', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['im.ProjectApplication'], unique=True, null=True, blank=True)),
39
            ('state', self.gf('django.db.models.fields.CharField')(default='Unknown', max_length=80)),
40
        ))
41
        db.send_create_signal('im', ['ProjectApplication'])
42

  
43
        # Adding model 'Project'
44
        db.create_table('im_project', (
45
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
46
            ('application', self.gf('django.db.models.fields.related.OneToOneField')(related_name='project', unique=True, to=orm['im.ProjectApplication'])),
47
            ('creation_date', self.gf('django.db.models.fields.DateTimeField')()),
48
            ('last_approval_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
49
            ('termination_start_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
50
            ('termination_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
51
            ('membership_dirty', self.gf('django.db.models.fields.BooleanField')(default=False)),
52
            ('last_application_synced', self.gf('django.db.models.fields.related.OneToOneField')(blank=True, related_name='last_project', unique=True, null=True, to=orm['im.ProjectApplication'])),
53
        ))
54
        db.send_create_signal('im', ['Project'])
55

  
56
        # Adding model 'ProjectMembership'
57
        db.create_table('im_projectmembership', (
58
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
59
            ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.AstakosUser'])),
60
            ('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Project'])),
61
            ('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 10, 13, 48, 24, 819045))),
62
            ('acceptance_date', self.gf('django.db.models.fields.DateField')(null=True, db_index=True)),
63
            ('leave_request_date', self.gf('django.db.models.fields.DateField')(null=True)),
64
        ))
65
        db.send_create_signal('im', ['ProjectMembership'])
66

  
67
        # Adding unique constraint on 'ProjectMembership', fields ['person', 'project']
68
        db.create_unique('im_projectmembership', ['person_id', 'project_id'])
69

  
70
        # Adding model 'ProjectDefinition'
71
        db.create_table('im_projectdefinition', (
72
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
73
            ('name', self.gf('django.db.models.fields.CharField')(max_length=80)),
74
            ('homepage', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True)),
75
            ('description', self.gf('django.db.models.fields.TextField')(null=True)),
76
            ('start_date', self.gf('django.db.models.fields.DateTimeField')()),
77
            ('end_date', self.gf('django.db.models.fields.DateTimeField')()),
78
            ('member_join_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberJoinPolicy'])),
79
            ('member_leave_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberLeavePolicy'])),
80
            ('limit_on_members_number', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
81
        ))
82
        db.send_create_signal('im', ['ProjectDefinition'])
83

  
84
        # Adding model 'MemberLeavePolicy'
85
        db.create_table('im_memberleavepolicy', (
86
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
87
            ('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
88
            ('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
89
        ))
90
        db.send_create_signal('im', ['MemberLeavePolicy'])
91

  
92
        # Adding model 'ProjectResourceGrant'
93
        db.create_table('im_projectresourcegrant', (
94
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
95
            ('member_limit', self.gf('django.db.models.fields.BigIntegerField')(null=True)),
96
            ('project_limit', self.gf('django.db.models.fields.BigIntegerField')(null=True)),
97
            ('resource', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Resource'])),
98
            ('project_definition', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.ProjectDefinition'], blank=True)),
99
        ))
100
        db.send_create_signal('im', ['ProjectResourceGrant'])
101

  
102
        # Adding unique constraint on 'ProjectResourceGrant', fields ['resource', 'project_definition']
103
        db.create_unique('im_projectresourcegrant', ['resource_id', 'project_definition_id'])
104

  
105

  
106
    def backwards(self, orm):
107
        
108
        # Removing unique constraint on 'ProjectResourceGrant', fields ['resource', 'project_definition']
109
        db.delete_unique('im_projectresourcegrant', ['resource_id', 'project_definition_id'])
110

  
111
        # Removing unique constraint on 'ProjectMembership', fields ['person', 'project']
112
        db.delete_unique('im_projectmembership', ['person_id', 'project_id'])
113

  
114
        # Deleting model 'MemberJoinPolicy'
115
        db.delete_table('im_memberjoinpolicy')
116

  
117
        # Deleting model 'ProjectMembershipHistory'
118
        db.delete_table('im_projectmembershiphistory')
119

  
120
        # Deleting model 'ProjectApplication'
121
        db.delete_table('im_projectapplication')
122

  
123
        # Deleting model 'Project'
124
        db.delete_table('im_project')
125

  
126
        # Deleting model 'ProjectMembership'
127
        db.delete_table('im_projectmembership')
128

  
129
        # Deleting model 'ProjectDefinition'
130
        db.delete_table('im_projectdefinition')
131

  
132
        # Deleting model 'MemberLeavePolicy'
133
        db.delete_table('im_memberleavepolicy')
134

  
135
        # Deleting model 'ProjectResourceGrant'
136
        db.delete_table('im_projectresourcegrant')
137

  
138

  
139
    models = {
140
        'auth.group': {
141
            'Meta': {'object_name': 'Group'},
142
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
143
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
144
            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
145
        },
146
        'auth.permission': {
147
            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
148
            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
149
            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
150
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
151
            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
152
        },
153
        'auth.user': {
154
            'Meta': {'object_name': 'User'},
155
            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
156
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
157
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
158
            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
159
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
160
            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
161
            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
162
            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
163
            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
164
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
165
            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
166
            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
167
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
168
        },
169
        'contenttypes.contenttype': {
170
            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
171
            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
172
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
173
            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
174
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
175
        },
176
        'im.additionalmail': {
177
            'Meta': {'object_name': 'AdditionalMail'},
178
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
179
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
180
            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
181
        },
182
        'im.approvalterms': {
183
            'Meta': {'object_name': 'ApprovalTerms'},
184
            'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 10, 13, 48, 24, 808772)', 'db_index': 'True'}),
185
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
186
            'location': ('django.db.models.fields.CharField', [], {'max_length': '255'})
187
        },
188
        'im.astakosgroup': {
189
            'Meta': {'object_name': 'AstakosGroup', '_ormbases': ['auth.Group']},
190
            'approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
191
            'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 10, 13, 48, 24, 801104)'}),
192
            'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}),
193
            'estimated_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
194
            'expiration_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
195
            'group_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}),
196
            'homepage': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
197
            'issue_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
198
            'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.GroupKind']"}),
199
            'max_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
200
            'moderation_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
201
            'policy': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosGroupQuota']", 'blank': 'True'})
202
        },
203
        'im.astakosgroupquota': {
204
            'Meta': {'unique_together': "(('resource', 'group'),)", 'object_name': 'AstakosGroupQuota'},
205
            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']", 'blank': 'True'}),
206
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
207
            'limit': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
208
            'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}),
209
            'uplimit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'})
210
        },
211
        'im.astakosuser': {
212
            'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'AstakosUser', '_ormbases': ['auth.User']},
213
            'activation_sent': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
214
            'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
215
            'astakos_groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosGroup']", 'symmetrical': 'False', 'through': "orm['im.Membership']", 'blank': 'True'}),
216
            'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
217
            'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
218
            'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
219
            'date_signed_terms': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
220
            'disturbed_quota': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
221
            'email_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
222
            'has_credits': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
223
            'has_signed_terms': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
224
            'invitations': ('django.db.models.fields.IntegerField', [], {'default': '100'}),
225
            'is_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
226
            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
227
            'owner': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'owner'", 'null': 'True', 'to': "orm['im.AstakosGroup']"}),
228
            'policy': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosUserQuota']", 'symmetrical': 'False'}),
229
            'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
230
            'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
231
            'updated': ('django.db.models.fields.DateTimeField', [], {}),
232
            'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
233
        },
234
        'im.astakosuserauthprovider': {
235
            'Meta': {'unique_together': "(('identifier', 'module', 'user'),)", 'object_name': 'AstakosUserAuthProvider'},
236
            'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
237
            'affiliation': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
238
            'auth_backend': ('django.db.models.fields.CharField', [], {'default': "'astakos'", 'max_length': '255'}),
239
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
240
            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
241
            'module': ('django.db.models.fields.CharField', [], {'default': "'local'", 'max_length': '255'}),
242
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_providers'", 'to': "orm['im.AstakosUser']"})
243
        },
244
        'im.astakosuserquota': {
245
            'Meta': {'unique_together': "(('resource', 'user'),)", 'object_name': 'AstakosUserQuota'},
246
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
247
            'limit': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
248
            'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}),
249
            'uplimit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
250
            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
251
        },
252
        'im.emailchange': {
253
            'Meta': {'object_name': 'EmailChange'},
254
            'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
255
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
256
            'new_email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
257
            'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 10, 13, 48, 24, 810599)'}),
258
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emailchange_user'", 'unique': 'True', 'to': "orm['im.AstakosUser']"})
259
        },
260
        'im.groupkind': {
261
            'Meta': {'object_name': 'GroupKind'},
262
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
263
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
264
        },
265
        'im.invitation': {
266
            'Meta': {'object_name': 'Invitation'},
267
            'code': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True'}),
268
            'consumed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
269
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
270
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
271
            'inviter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invitations_sent'", 'null': 'True', 'to': "orm['im.AstakosUser']"}),
272
            'is_consumed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
273
            'realname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
274
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
275
        },
276
        'im.memberjoinpolicy': {
277
            'Meta': {'object_name': 'MemberJoinPolicy'},
278
            'description': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
279
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
280
            'policy': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
281
        },
282
        'im.memberleavepolicy': {
283
            'Meta': {'object_name': 'MemberLeavePolicy'},
284
            'description': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
285
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
286
            'policy': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
287
        },
288
        'im.membership': {
289
            'Meta': {'unique_together': "(('person', 'group'),)", 'object_name': 'Membership'},
290
            'date_joined': ('django.db.models.fields.DateField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
291
            'date_requested': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 10, 13, 48, 24, 806557)', 'blank': 'True'}),
292
            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']"}),
293
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
294
            'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
295
        },
296
        'im.pendingthirdpartyuser': {
297
            'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'PendingThirdPartyUser'},
298
            'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
299
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
300
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
301
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
302
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
303
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
304
            'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
305
            'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
306
            'token': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
307
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
308
        },
309
        'im.project': {
310
            'Meta': {'object_name': 'Project'},
311
            'application': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'project'", 'unique': 'True', 'to': "orm['im.ProjectApplication']"}),
312
            'creation_date': ('django.db.models.fields.DateTimeField', [], {}),
313
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
314
            'last_application_synced': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'last_project'", 'unique': 'True', 'null': 'True', 'to': "orm['im.ProjectApplication']"}),
315
            'last_approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
316
            'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosUser']", 'through': "orm['im.ProjectMembership']", 'symmetrical': 'False'}),
317
            'membership_dirty': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
318
            'termination_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
319
            'termination_start_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'})
320
        },
321
        'im.projectapplication': {
322
            'Meta': {'object_name': 'ProjectApplication'},
323
            'applicant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'my_project_applications'", 'to': "orm['im.AstakosUser']"}),
324
            'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
325
            'definition': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectDefinition']", 'unique': 'True'}),
326
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
327
            'issue_date': ('django.db.models.fields.DateTimeField', [], {}),
328
            'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'own_project_applications'", 'to': "orm['im.AstakosUser']"}),
329
            'precursor_application': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectApplication']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
330
            'state': ('django.db.models.fields.CharField', [], {'default': "'Unknown'", 'max_length': '80'})
331
        },
332
        'im.projectdefinition': {
333
            'Meta': {'object_name': 'ProjectDefinition'},
334
            'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
335
            'end_date': ('django.db.models.fields.DateTimeField', [], {}),
336
            'homepage': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
337
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
338
            'limit_on_members_number': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
339
            'member_join_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberJoinPolicy']"}),
340
            'member_leave_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberLeavePolicy']"}),
341
            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
342
            'resource_grants': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.ProjectResourceGrant']", 'blank': 'True'}),
343
            'start_date': ('django.db.models.fields.DateTimeField', [], {})
344
        },
345
        'im.projectmembership': {
346
            'Meta': {'unique_together': "(('person', 'project'),)", 'object_name': 'ProjectMembership'},
347
            'acceptance_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'db_index': 'True'}),
348
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
349
            'leave_request_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
350
            'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}),
351
            'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Project']"}),
352
            'request_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 10, 13, 48, 24, 819045)'})
353
        },
354
        'im.projectmembershiphistory': {
355
            'Meta': {'object_name': 'ProjectMembershipHistory'},
356
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
357
            'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}),
358
            'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Project']"}),
359
            'rejection_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
360
            'removal_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
361
            'request_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 10, 13, 48, 24, 819868)'})
362
        },
363
        'im.projectresourcegrant': {
364
            'Meta': {'unique_together': "(('resource', 'project_definition'),)", 'object_name': 'ProjectResourceGrant'},
365
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
366
            'member_limit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
367
            'project_definition': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.ProjectDefinition']", 'blank': 'True'}),
368
            'project_limit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
369
            'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"})
370
        },
371
        'im.resource': {
372
            'Meta': {'object_name': 'Resource'},
373
            'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}),
374
            'group': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
375
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
376
            'meta': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.ResourceMetadata']", 'symmetrical': 'False'}),
377
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
378
            'service': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Service']"}),
379
            'unit': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'})
380
        },
381
        'im.resourcemetadata': {
382
            'Meta': {'object_name': 'ResourceMetadata'},
383
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
384
            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
385
            'value': ('django.db.models.fields.CharField', [], {'max_length': '255'})
386
        },
387
        'im.service': {
388
            'Meta': {'object_name': 'Service'},
389
            'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
390
            'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
391
            'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
392
            'icon': ('django.db.models.fields.FilePathField', [], {'max_length': '100', 'blank': 'True'}),
393
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
394
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
395
            'url': ('django.db.models.fields.FilePathField', [], {'max_length': '100'})
396
        },
397
        'im.sessioncatalog': {
398
            'Meta': {'object_name': 'SessionCatalog'},
399
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
400
            'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
401
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sessions'", 'null': 'True', 'to': "orm['im.AstakosUser']"})
402
        }
403
    }
404

  
405
    complete_apps = ['im']
/dev/null
1
# encoding: utf-8
2
import datetime
3
from south.db import db
4
from south.v2 import SchemaMigration
5
from django.db import models
6

  
7
class Migration(SchemaMigration):
8

  
9
    def forwards(self, orm):
10
        
11
        # Adding model 'MemberJoinPolicy'
12
        db.create_table('im_memberjoinpolicy', (
13
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14
            ('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
15
            ('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
16
        ))
17
        db.send_create_signal('im', ['MemberJoinPolicy'])
18

  
19
        # Adding model 'ProjectMembershipHistory'
20
        db.create_table('im_projectmembershiphistory', (
21
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
22
            ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.AstakosUser'])),
23
            ('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Project'])),
24
            ('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 9, 11, 4, 41, 210148))),
25
            ('removal_date', self.gf('django.db.models.fields.DateField')(null=True)),
26
            ('rejection_date', self.gf('django.db.models.fields.DateField')(null=True)),
27
        ))
28
        db.send_create_signal('im', ['ProjectMembershipHistory'])
29

  
30
        # Adding unique constraint on 'ProjectMembershipHistory', fields ['person', 'project']
31
        db.create_unique('im_projectmembershiphistory', ['person_id', 'project_id'])
32

  
33
        # Adding model 'ProjectApplication'
34
        db.create_table('im_projectapplication', (
35
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
36
            ('applicant', self.gf('django.db.models.fields.related.ForeignKey')(related_name='my_project_applications', to=orm['im.AstakosUser'])),
37
            ('owner', self.gf('django.db.models.fields.related.ForeignKey')(related_name='own_project_applications', to=orm['im.AstakosUser'])),
38
            ('comments', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
39
            ('definition', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['im.ProjectDefinition'], unique=True)),
40
            ('issue_date', self.gf('django.db.models.fields.DateTimeField')()),
41
            ('precursor_application', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['im.ProjectApplication'], unique=True, null=True, blank=True)),
42
        ))
43
        db.send_create_signal('im', ['ProjectApplication'])
44

  
45
        # Adding model 'Project'
46
        db.create_table('im_project', (
47
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
48
            ('application', self.gf('django.db.models.fields.related.OneToOneField')(related_name='project', unique=True, to=orm['im.ProjectApplication'])),
49
            ('creation_date', self.gf('django.db.models.fields.DateTimeField')()),
50
            ('last_approval_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
51
            ('termination_start_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
52
            ('termination_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
53
            ('membership_dirty', self.gf('django.db.models.fields.BooleanField')(default=False)),
54
            ('last_application_synced', self.gf('django.db.models.fields.related.OneToOneField')(blank=True, related_name='last_project', unique=True, null=True, to=orm['im.ProjectApplication'])),
55
        ))
56
        db.send_create_signal('im', ['Project'])
57

  
58
        # Adding model 'ProjectMembership'
59
        db.create_table('im_projectmembership', (
60
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
61
            ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.AstakosUser'])),
62
            ('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Project'])),
63
            ('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 9, 11, 4, 41, 209391))),
64
            ('acceptance_date', self.gf('django.db.models.fields.DateField')(null=True, db_index=True)),
65
        ))
66
        db.send_create_signal('im', ['ProjectMembership'])
67

  
68
        # Adding unique constraint on 'ProjectMembership', fields ['person', 'project']
69
        db.create_unique('im_projectmembership', ['person_id', 'project_id'])
70

  
71
        # Adding model 'ProjectDefinition'
72
        db.create_table('im_projectdefinition', (
73
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
74
            ('name', self.gf('django.db.models.fields.CharField')(max_length=80)),
75
            ('homepage', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True)),
76
            ('description', self.gf('django.db.models.fields.TextField')(null=True)),
77
            ('start_date', self.gf('django.db.models.fields.DateTimeField')()),
78
            ('end_date', self.gf('django.db.models.fields.DateTimeField')()),
79
            ('member_join_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberJoinPolicy'])),
80
            ('member_leave_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberLeavePolicy'])),
81
            ('limit_on_members_number', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
82
        ))
83
        db.send_create_signal('im', ['ProjectDefinition'])
84

  
85
        # Adding model 'MemberLeavePolicy'
86
        db.create_table('im_memberleavepolicy', (
87
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
88
            ('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
89
            ('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
90
        ))
91
        db.send_create_signal('im', ['MemberLeavePolicy'])
92

  
93
        # Adding model 'ProjectResourceGrant'
94
        db.create_table('im_projectresourcegrant', (
95
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
96
            ('member_limit', self.gf('django.db.models.fields.BigIntegerField')(null=True)),
97
            ('project_limit', self.gf('django.db.models.fields.BigIntegerField')(null=True)),
98
            ('resource', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Resource'])),
99
            ('project_definition', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.ProjectDefinition'], blank=True)),
100
        ))
101
        db.send_create_signal('im', ['ProjectResourceGrant'])
102

  
103
        # Adding unique constraint on 'ProjectResourceGrant', fields ['resource', 'project_definition']
104
        db.create_unique('im_projectresourcegrant', ['resource_id', 'project_definition_id'])
105

  
106

  
107
    def backwards(self, orm):
108
        
109
        # Removing unique constraint on 'ProjectResourceGrant', fields ['resource', 'project_definition']
110
        db.delete_unique('im_projectresourcegrant', ['resource_id', 'project_definition_id'])
111

  
112
        # Removing unique constraint on 'ProjectMembership', fields ['person', 'project']
113
        db.delete_unique('im_projectmembership', ['person_id', 'project_id'])
114

  
115
        # Removing unique constraint on 'ProjectMembershipHistory', fields ['person', 'project']
116
        db.delete_unique('im_projectmembershiphistory', ['person_id', 'project_id'])
117

  
118
        # Deleting model 'MemberJoinPolicy'
119
        db.delete_table('im_memberjoinpolicy')
120

  
121
        # Deleting model 'ProjectMembershipHistory'
122
        db.delete_table('im_projectmembershiphistory')
123

  
124
        # Deleting model 'ProjectApplication'
125
        db.delete_table('im_projectapplication')
126

  
127
        # Deleting model 'Project'
128
        db.delete_table('im_project')
129

  
130
        # Deleting model 'ProjectMembership'
131
        db.delete_table('im_projectmembership')
132

  
133
        # Deleting model 'ProjectDefinition'
134
        db.delete_table('im_projectdefinition')
135

  
136
        # Deleting model 'MemberLeavePolicy'
137
        db.delete_table('im_memberleavepolicy')
138

  
139
        # Deleting model 'ProjectResourceGrant'
140
        db.delete_table('im_projectresourcegrant')
141

  
142

  
143
    models = {
144
        'auth.group': {
145
            'Meta': {'object_name': 'Group'},
146
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
147
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
148
            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
149
        },
150
        'auth.permission': {
151
            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
152
            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
153
            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
154
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
155
            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
156
        },
157
        'auth.user': {
158
            'Meta': {'object_name': 'User'},
159
            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
160
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
161
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
162
            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
163
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
164
            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
165
            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
166
            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
167
            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
168
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
169
            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
170
            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
171
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
172
        },
173
        'contenttypes.contenttype': {
174
            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
175
            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
176
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
177
            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
178
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
179
        },
180
        'im.additionalmail': {
181
            'Meta': {'object_name': 'AdditionalMail'},
182
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
183
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
184
            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
185
        },
186
        'im.approvalterms': {
187
            'Meta': {'object_name': 'ApprovalTerms'},
188
            'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 198398)', 'db_index': 'True'}),
189
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
190
            'location': ('django.db.models.fields.CharField', [], {'max_length': '255'})
191
        },
192
        'im.astakosgroup': {
193
            'Meta': {'object_name': 'AstakosGroup', '_ormbases': ['auth.Group']},
194
            'approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
195
            'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 189261)'}),
196
            'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}),
197
            'estimated_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
198
            'expiration_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
199
            'group_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}),
200
            'homepage': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
201
            'issue_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
202
            'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.GroupKind']"}),
203
            'max_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
204
            'moderation_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
205
            'policy': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosGroupQuota']", 'blank': 'True'})
206
        },
207
        'im.astakosgroupquota': {
208
            'Meta': {'unique_together': "(('resource', 'group'),)", 'object_name': 'AstakosGroupQuota'},
209
            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']", 'blank': 'True'}),
210
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
211
            'limit': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
212
            'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}),
213
            'uplimit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'})
214
        },
215
        'im.astakosuser': {
216
            'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'AstakosUser', '_ormbases': ['auth.User']},
217
            'activation_sent': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
218
            'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
219
            'astakos_groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosGroup']", 'symmetrical': 'False', 'through': "orm['im.Membership']", 'blank': 'True'}),
220
            'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
221
            'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
222
            'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
223
            'date_signed_terms': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
224
            'disturbed_quota': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
225
            'email_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
226
            'has_credits': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
227
            'has_signed_terms': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
228
            'invitations': ('django.db.models.fields.IntegerField', [], {'default': '100'}),
229
            'is_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
230
            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
231
            'owner': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'owner'", 'null': 'True', 'to': "orm['im.AstakosGroup']"}),
232
            'policy': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosUserQuota']", 'symmetrical': 'False'}),
233
            'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
234
            'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
235
            'updated': ('django.db.models.fields.DateTimeField', [], {}),
236
            'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
237
        },
238
        'im.astakosuserauthprovider': {
239
            'Meta': {'unique_together': "(('identifier', 'module', 'user'),)", 'object_name': 'AstakosUserAuthProvider'},
240
            'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
241
            'affiliation': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
242
            'auth_backend': ('django.db.models.fields.CharField', [], {'default': "'astakos'", 'max_length': '255'}),
243
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
244
            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
245
            'module': ('django.db.models.fields.CharField', [], {'default': "'local'", 'max_length': '255'}),
246
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_providers'", 'to': "orm['im.AstakosUser']"})
247
        },
248
        'im.astakosuserquota': {
249
            'Meta': {'unique_together': "(('resource', 'user'),)", 'object_name': 'AstakosUserQuota'},
250
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
251
            'limit': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
252
            'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}),
253
            'uplimit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
254
            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
255
        },
256
        'im.emailchange': {
257
            'Meta': {'object_name': 'EmailChange'},
258
            'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
259
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
260
            'new_email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
261
            'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 200303)'}),
262
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emailchange_user'", 'unique': 'True', 'to': "orm['im.AstakosUser']"})
263
        },
264
        'im.groupkind': {
265
            'Meta': {'object_name': 'GroupKind'},
266
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
267
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
268
        },
269
        'im.invitation': {
270
            'Meta': {'object_name': 'Invitation'},
271
            'code': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True'}),
272
            'consumed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
273
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
274
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
275
            'inviter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invitations_sent'", 'null': 'True', 'to': "orm['im.AstakosUser']"}),
276
            'is_consumed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
277
            'realname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
278
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
279
        },
280
        'im.memberjoinpolicy': {
281
            'Meta': {'object_name': 'MemberJoinPolicy'},
282
            'description': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
283
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
284
            'policy': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
285
        },
286
        'im.memberleavepolicy': {
287
            'Meta': {'object_name': 'MemberLeavePolicy'},
288
            'description': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
289
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
290
            'policy': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
291
        },
292
        'im.membership': {
293
            'Meta': {'unique_together': "(('person', 'group'),)", 'object_name': 'Membership'},
294
            'date_joined': ('django.db.models.fields.DateField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
295
            'date_requested': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 196071)', 'blank': 'True'}),
296
            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']"}),
297
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
298
            'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
299
        },
300
        'im.pendingthirdpartyuser': {
301
            'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'PendingThirdPartyUser'},
302
            'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
303
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
304
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
305
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
306
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
307
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
308
            'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
309
            'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
310
            'token': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
311
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
312
        },
313
        'im.project': {
314
            'Meta': {'object_name': 'Project'},
315
            'application': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'project'", 'unique': 'True', 'to': "orm['im.ProjectApplication']"}),
316
            'creation_date': ('django.db.models.fields.DateTimeField', [], {}),
317
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
318
            'last_application_synced': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'last_project'", 'unique': 'True', 'null': 'True', 'to': "orm['im.ProjectApplication']"}),
319
            'last_approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
320
            'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosUser']", 'through': "orm['im.ProjectMembership']", 'symmetrical': 'False'}),
321
            'membership_dirty': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
322
            'termination_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
323
            'termination_start_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'})
324
        },
325
        'im.projectapplication': {
326
            'Meta': {'object_name': 'ProjectApplication'},
327
            'applicant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'my_project_applications'", 'to': "orm['im.AstakosUser']"}),
328
            'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
329
            'definition': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectDefinition']", 'unique': 'True'}),
330
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
331
            'issue_date': ('django.db.models.fields.DateTimeField', [], {}),
332
            'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'own_project_applications'", 'to': "orm['im.AstakosUser']"}),
333
            'precursor_application': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectApplication']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
334
        },
335
        'im.projectdefinition': {
336
            'Meta': {'object_name': 'ProjectDefinition'},
337
            'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
338
            'end_date': ('django.db.models.fields.DateTimeField', [], {}),
339
            'homepage': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
340
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
341
            'limit_on_members_number': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
342
            'member_join_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberJoinPolicy']"}),
343
            'member_leave_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberLeavePolicy']"}),
344
            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
345
            'resource_grants': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.ProjectResourceGrant']", 'blank': 'True'}),
346
            'start_date': ('django.db.models.fields.DateTimeField', [], {})
347
        },
348
        'im.projectmembership': {
349
            'Meta': {'unique_together': "(('person', 'project'),)", 'object_name': 'ProjectMembership'},
350
            'acceptance_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'db_index': 'True'}),
351
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
352
            'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}),
353
            'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Project']"}),
354
            'request_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 209391)'})
355
        },
356
        'im.projectmembershiphistory': {
357
            'Meta': {'unique_together': "(('person', 'project'),)", 'object_name': 'ProjectMembershipHistory'},
358
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
359
            'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}),
360
            'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Project']"}),
361
            'rejection_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
362
            'removal_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
363
            'request_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 210148)'})
364
        },
365
        'im.projectresourcegrant': {
366
            'Meta': {'unique_together': "(('resource', 'project_definition'),)", 'object_name': 'ProjectResourceGrant'},
367
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
368
            'member_limit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
369
            'project_definition': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.ProjectDefinition']", 'blank': 'True'}),
370
            'project_limit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
371
            'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"})
372
        },
373
        'im.resource': {
374
            'Meta': {'object_name': 'Resource'},
375
            'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}),
376
            'group': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
377
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
378
            'meta': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.ResourceMetadata']", 'symmetrical': 'False'}),
379
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
380
            'service': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Service']"}),
381
            'unit': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'})
382
        },
383
        'im.resourcemetadata': {
384
            'Meta': {'object_name': 'ResourceMetadata'},
385
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
386
            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
387
            'value': ('django.db.models.fields.CharField', [], {'max_length': '255'})
388
        },
389
        'im.service': {
390
            'Meta': {'object_name': 'Service'},
391
            'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
392
            'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
393
            'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
394
            'icon': ('django.db.models.fields.FilePathField', [], {'max_length': '100', 'blank': 'True'}),
395
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
396
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
397
            'url': ('django.db.models.fields.FilePathField', [], {'max_length': '100'})
398
        },
399
        'im.sessioncatalog': {
400
            'Meta': {'object_name': 'SessionCatalog'},
401
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
402
            'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
403
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sessions'", 'null': 'True', 'to': "orm['im.AstakosUser']"})
404
        }
405
    }
406

  
407
    complete_apps = ['im']
b/snf-astakos-app/astakos/im/models.py
61 61
from django.conf import settings
62 62
from django.utils.importlib import import_module
63 63
from django.core.validators import email_re
64
from django.core.exceptions import PermissionDenied
65
from django.views.generic.create_update import lookup_object
66
from django.core.exceptions import ObjectDoesNotExist
64 67

  
65 68
from astakos.im.settings import (
66 69
    DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL,
......
85 88
DEFAULT_CONTENT_TYPE = None
86 89
_content_type = None
87 90

  
91
PENDING, APPROVED, REPLACED, UNKNOWN = 'Pending', 'Approved', 'Replaced', 'Unknown'
92

  
88 93
def get_content_type():
89 94
    global _content_type
90 95
    if _content_type is not None:
......
1030 1035

  
1031 1036
_auto_accept_join = False
1032 1037
def get_auto_accept_join():
1033
    global _auto_accept
1034
    if _auto_accept is not False:
1035
        return _auto_accept
1038
    global _auto_accept_join
1039
    if _auto_accept_join is not False:
1040
        return _auto_accept_join
1036 1041
    try:
1037 1042
        auto_accept = MemberJoinPolicy.objects.get(policy='auto_accept')
1038 1043
    except:
1039 1044
        auto_accept = None
1040
    _auto_accept = auto_accept
1045
    _auto_accept_join = auto_accept
1041 1046
    return auto_accept
1042 1047

  
1048
_closed_join = False
1049
def get_closed_join():
1050
    global _closed_join
1051
    if _closed_join is not False:
1052
        return _closed_join
1053
    try:
1054
        closed = MemberJoinPolicy.objects.get(policy='closed')
1055
    except:
1056
        closed = None
1057
    _closed_join = closed
1058
    return closed
1059

  
1043 1060
_auto_accept_leave = False
1044 1061
def get_auto_accept_leave():
1045
    global _auto_accept
1046
    if _auto_accept is not False:
1047
        return _auto_accept
1062
    global _auto_accept_leave
1063
    if _auto_accept_leave is not False:
1064
        return _auto_accept_leave
1048 1065
    try:
1049 1066
        auto_accept = MemberLeavePolicy.objects.get(policy='auto_accept')
1050 1067
    except:
1051 1068
        auto_accept = None
1052
    _auto_accept = auto_accept
1069
    _auto_accept_leave = auto_accept
1053 1070
    return auto_accept
1054 1071

  
1072
_closed_leave = False
1073
def get_closed_leave():
1074
    global _closed_leave
1075
    if _closed_leave is not False:
1076
        return _closed_leave
1077
    try:
1078
        closed = MemberLeavePolicy.objects.get(policy='closed')
1079
    except:
1080
        closed = None
1081
    _closed_leave = closed
1082
    return closeds
1083

  
1055 1084
class ProjectDefinition(models.Model):
1056 1085
    name = models.CharField(max_length=80)
1057 1086
    homepage = models.URLField(max_length=255, null=True, blank=True)
......
1128 1157
    class Meta:
1129 1158
        unique_together = ("resource", "project_definition")
1130 1159

  
1160

  
1131 1161
class ProjectApplication(models.Model):
1132
    PENDING, APPROVED, REPLACED = range(3)
1133
    states_list = ['Pending', 'Approved', 'Replaced']
1162
    states_list = [PENDING, APPROVED, REPLACED, UNKNOWN]
1134 1163
    states = dict((k, v) for k, v in enumerate(states_list))
1135 1164

  
1136 1165
    applicant = models.ForeignKey(
......
1150 1179
        blank=True,
1151 1180
        db_index=True
1152 1181
    )
1182
    state = models.CharField(max_length=80, default=UNKNOWN)
1153 1183
    
1154 1184
    @property
1155 1185
    def follower(self):
......
1163 1193
        self.definition = self.definition
1164 1194
        super(ProjectApplication, self).save()
1165 1195

  
1166
    @property
1167
    def status(self):
1168
        if self.follower:
1169
            try:
1170
                self.follower.project
1171
            except:
1172
                pass
1173
            else:
1174
                if self.follower.project.last_approval_date:
1175
                    return self.states[self.REPLACED]
1176
        try:
1177
            self.project
1178
        except Project.DoesNotExist:
1179
            return self.states[self.PENDING]
1180
        if self.project.is_alive:
1181
            return self.states[self.APPROVED]
1182
        
1196

  
1183 1197
    @staticmethod
1184 1198
    def submit(definition, resource_policies, applicant, comments, precursor_application=None, commit=True):
1185 1199
        application = None
1186 1200
        if precursor_application:
1187
            try:
1188
                precursor_application.project
1189
            except:
1190
                pass
1191
            else:
1192
                if precursor_application.status != 'Pending':
1193
                    application = precursor_application
1194
                    application.precursor_application = precursor_application
1195
                    application.id = None
1196
                    print '>>>', application.precursor_application.id
1197
        if not application:
1201
            precursor_application_id = precursor_application.id
1202
            application = precursor_application
1203
            application.id = None
1204
        else:
1198 1205
            application = ProjectApplication(owner=applicant)
1199 1206
        application.definition = definition
1207
        application.definition.id = None
1200 1208
        application.applicant = applicant
1201 1209
        application.comments = comments
1202 1210
        application.issue_date = datetime.now()
1203
        application.definition.id = None
1204
        application.id = None
1211
        application.state = PENDING
1205 1212
        if commit:
1206 1213
            application.save()
1207 1214
            application.definition.resource_policies = resource_policies
1208
        if applicant.is_superuser:
1209
            self.approve_application()
1210
#         else:
1211
#             notification = build_notification(
1212
#                 settings.SERVER_EMAIL,
1213
#                 [i[1] for i in settings.ADMINS],
1214
#                 _(GROUP_CREATION_SUBJECT) % {'group':application.definition.name},
1215
#                 _('An new project application identified by %(id)s has been submitted.') % application.__dict__
1216
#             )
1217
#             notification.send()
1215
            # better implementation ???
1216
            if precursor_application:
1217
                try:
1218
                    precursor = ProjectApplication.objects.get(id=precursor_application_id)
1219
                except:
1220
                    pass
1221
                precursor.state = REPLACED
1222
                precursor.save()
1223
                application.precursor_application_id = precursor
1224
                application.save()
1225
        else:
1226
            notification = build_notification(
1227
                settings.SERVER_EMAIL,
1228
                [i[1] for i in settings.ADMINS],
1229
                _(GROUP_CREATION_SUBJECT) % {'group':application.definition.name},
1230
                _('An new project application identified by %(id)s has been submitted.') % application.__dict__
1231
            )
1232
            notification.send()
1218 1233
        return application
1219 1234
        
1220 1235
    def approve(self, approval_user=None):
......
1222 1237
        If approval_user then during owner membership acceptance
1223 1238
        it is checked whether the request_user is eligible.
1224 1239
        """
1225
        if self.status != self.states[self.PENDING]:
1240
        if self.state != PENDING:
1226 1241
            return
1227
        if not self.precursor_application:
1242
        create = False
1243
        try:
1244
            self.precursor_application.project
1245
        except:
1246
            create = True
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff