Revision b22de10a
/dev/null | ||
---|---|---|
1 |
[ |
|
2 |
{ |
|
3 |
"model": "im.memberacceptpolicy", |
|
4 |
"pk": 1, |
|
5 |
"fields": { |
|
6 |
"policy": "auto_accept", |
|
7 |
"description": "new join requests are automatically accepted by the system" |
|
8 |
} |
|
9 |
}, |
|
10 |
{ |
|
11 |
"model": "im.memberacceptpolicy", |
|
12 |
"pk": 2, |
|
13 |
"fields": { |
|
14 |
"policy": "owner_accepts", |
|
15 |
"description": "new join requests must be accepted by the owner of the project" |
|
16 |
} |
|
17 |
}, |
|
18 |
{ |
|
19 |
"model": "im.memberacceptpolicy", |
|
20 |
"pk": 3, |
|
21 |
"fields": { |
|
22 |
"policy": "closed", |
|
23 |
"description": "no new members can join the project, even if old ones leave" |
|
24 |
} |
|
25 |
} |
|
26 |
] |
b/snf-astakos-app/astakos/im/fixtures/member_accept_policies.json | ||
---|---|---|
1 |
[ |
|
2 |
{ |
|
3 |
"model": "im.memberrejectpolicy", |
|
4 |
"pk": 1, |
|
5 |
"fields": { |
|
6 |
"policy": "auto_accept", |
|
7 |
"description": "remove requests are automatically accepted by the system" |
|
8 |
} |
|
9 |
}, |
|
10 |
{ |
|
11 |
"model": "im.memberrejectpolicy", |
|
12 |
"pk": 2, |
|
13 |
"fields": { |
|
14 |
"policy": "owner_accepts", |
|
15 |
"description": "remove requests must be accepted by the owner of the project" |
|
16 |
} |
|
17 |
}, |
|
18 |
{ |
|
19 |
"model": "im.memberrejectpolicy", |
|
20 |
"pk": 3, |
|
21 |
"fields": { |
|
22 |
"policy": "closed", |
|
23 |
"description": "members can not leave the project" |
|
24 |
} |
|
25 |
} |
|
26 |
] |
b/snf-astakos-app/astakos/im/fixtures/member_reject_policies.json | ||
---|---|---|
1 |
[ |
|
2 |
{ |
|
3 |
"model": "im.memberacceptpolicy", |
|
4 |
"pk": 1, |
|
5 |
"fields": { |
|
6 |
"policy": "auto_accept", |
|
7 |
"description": "leave requests are automatically accepted by the system" |
|
8 |
} |
|
9 |
}, |
|
10 |
{ |
|
11 |
"model": "im.memberacceptpolicy", |
|
12 |
"pk": 2, |
|
13 |
"fields": { |
|
14 |
"policy": "owner_accepts", |
|
15 |
"description": "leave requests must be accepted by the owner of the project" |
|
16 |
} |
|
17 |
}, |
|
18 |
{ |
|
19 |
"model": "im.memberacceptpolicy", |
|
20 |
"pk": 3, |
|
21 |
"fields": { |
|
22 |
"policy": "closed", |
|
23 |
"description": "no member can leave the project" |
|
24 |
} |
|
25 |
} |
|
26 |
] |
b/snf-astakos-app/astakos/im/migrations/0036_auto__chg_field_project_termination_date__chg_field_project_last_appro.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 |
# Changing field 'Project.termination_date' |
|
12 |
db.alter_column('im_project', 'termination_date', self.gf('django.db.models.fields.DateTimeField')(null=True)) |
|
13 |
|
|
14 |
# Changing field 'Project.last_approval_date' |
|
15 |
db.alter_column('im_project', 'last_approval_date', self.gf('django.db.models.fields.DateTimeField')(null=True)) |
|
16 |
|
|
17 |
# Adding field 'ProjectDefinition.homepage' |
|
18 |
db.add_column('im_projectdefinition', 'homepage', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True), keep_default=False) |
|
19 |
|
|
20 |
|
|
21 |
def backwards(self, orm): |
|
22 |
|
|
23 |
# User chose to not deal with backwards NULL issues for 'Project.termination_date' |
|
24 |
raise RuntimeError("Cannot reverse this migration. 'Project.termination_date' and its values cannot be restored.") |
|
25 |
|
|
26 |
# User chose to not deal with backwards NULL issues for 'Project.last_approval_date' |
|
27 |
raise RuntimeError("Cannot reverse this migration. 'Project.last_approval_date' and its values cannot be restored.") |
|
28 |
|
|
29 |
# Deleting field 'ProjectDefinition.homepage' |
|
30 |
db.delete_column('im_projectdefinition', 'homepage') |
|
31 |
|
|
32 |
|
|
33 |
models = { |
|
34 |
'auth.group': { |
|
35 |
'Meta': {'object_name': 'Group'}, |
|
36 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
37 |
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), |
|
38 |
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) |
|
39 |
}, |
|
40 |
'auth.permission': { |
|
41 |
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, |
|
42 |
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
43 |
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), |
|
44 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
45 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) |
|
46 |
}, |
|
47 |
'auth.user': { |
|
48 |
'Meta': {'object_name': 'User'}, |
|
49 |
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
|
50 |
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), |
|
51 |
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), |
|
52 |
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), |
|
53 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
54 |
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), |
|
55 |
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
56 |
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
57 |
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
|
58 |
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), |
|
59 |
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), |
|
60 |
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), |
|
61 |
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) |
|
62 |
}, |
|
63 |
'contenttypes.contenttype': { |
|
64 |
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, |
|
65 |
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
66 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
67 |
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
68 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
|
69 |
}, |
|
70 |
'im.additionalmail': { |
|
71 |
'Meta': {'object_name': 'AdditionalMail'}, |
|
72 |
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), |
|
73 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
74 |
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}) |
|
75 |
}, |
|
76 |
'im.approvalterms': { |
|
77 |
'Meta': {'object_name': 'ApprovalTerms'}, |
|
78 |
'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 6, 23, 16, 19, 367473)', 'db_index': 'True'}), |
|
79 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
80 |
'location': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
81 |
}, |
|
82 |
'im.astakosgroup': { |
|
83 |
'Meta': {'object_name': 'AstakosGroup', '_ormbases': ['auth.Group']}, |
|
84 |
'approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), |
|
85 |
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 6, 23, 16, 19, 359649)'}), |
|
86 |
'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
87 |
'estimated_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
88 |
'expiration_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
89 |
'group_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}), |
|
90 |
'homepage': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
91 |
'issue_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
92 |
'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.GroupKind']"}), |
|
93 |
'max_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
94 |
'moderation_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), |
|
95 |
'policy': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosGroupQuota']", 'blank': 'True'}) |
|
96 |
}, |
|
97 |
'im.astakosgroupquota': { |
|
98 |
'Meta': {'unique_together': "(('resource', 'group'),)", 'object_name': 'AstakosGroupQuota'}, |
|
99 |
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']", 'blank': 'True'}), |
|
100 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
101 |
'limit': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
102 |
'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}), |
|
103 |
'uplimit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}) |
|
104 |
}, |
|
105 |
'im.astakosuser': { |
|
106 |
'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'AstakosUser', '_ormbases': ['auth.User']}, |
|
107 |
'activation_sent': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), |
|
108 |
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
109 |
'astakos_groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosGroup']", 'symmetrical': 'False', 'through': "orm['im.Membership']", 'blank': 'True'}), |
|
110 |
'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), |
|
111 |
'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
112 |
'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
113 |
'date_signed_terms': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), |
|
114 |
'disturbed_quota': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), |
|
115 |
'email_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
116 |
'has_credits': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
117 |
'has_signed_terms': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
118 |
'invitations': ('django.db.models.fields.IntegerField', [], {'default': '100'}), |
|
119 |
'is_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
120 |
'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
121 |
'owner': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'owner'", 'null': 'True', 'to': "orm['im.AstakosGroup']"}), |
|
122 |
'policy': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.AstakosUserQuota']", 'symmetrical': 'False'}), |
|
123 |
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
124 |
'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
125 |
'updated': ('django.db.models.fields.DateTimeField', [], {}), |
|
126 |
'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) |
|
127 |
}, |
|
128 |
'im.astakosuserauthprovider': { |
|
129 |
'Meta': {'unique_together': "(('identifier', 'module', 'user'),)", 'object_name': 'AstakosUserAuthProvider'}, |
|
130 |
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), |
|
131 |
'affiliation': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
132 |
'auth_backend': ('django.db.models.fields.CharField', [], {'default': "'astakos'", 'max_length': '255'}), |
|
133 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
134 |
'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
135 |
'module': ('django.db.models.fields.CharField', [], {'default': "'local'", 'max_length': '255'}), |
|
136 |
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_providers'", 'to': "orm['im.AstakosUser']"}) |
|
137 |
}, |
|
138 |
'im.astakosuserquota': { |
|
139 |
'Meta': {'unique_together': "(('resource', 'user'),)", 'object_name': 'AstakosUserQuota'}, |
|
140 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
141 |
'limit': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), |
|
142 |
'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}), |
|
143 |
'uplimit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}), |
|
144 |
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}) |
|
145 |
}, |
|
146 |
'im.emailchange': { |
|
147 |
'Meta': {'object_name': 'EmailChange'}, |
|
148 |
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), |
|
149 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
150 |
'new_email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), |
|
151 |
'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 6, 23, 16, 19, 369393)'}), |
|
152 |
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emailchange_user'", 'unique': 'True', 'to': "orm['im.AstakosUser']"}) |
|
153 |
}, |
|
154 |
'im.groupkind': { |
|
155 |
'Meta': {'object_name': 'GroupKind'}, |
|
156 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
157 |
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) |
|
158 |
}, |
|
159 |
'im.invitation': { |
|
160 |
'Meta': {'object_name': 'Invitation'}, |
|
161 |
'code': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True'}), |
|
162 |
'consumed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), |
|
163 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
|
164 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
165 |
'inviter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invitations_sent'", 'null': 'True', 'to': "orm['im.AstakosUser']"}), |
|
166 |
'is_consumed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
167 |
'realname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
168 |
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) |
|
169 |
}, |
|
170 |
'im.memberacceptpolicy': { |
|
171 |
'Meta': {'object_name': 'MemberAcceptPolicy'}, |
|
172 |
'description': ('django.db.models.fields.CharField', [], {'max_length': '80'}), |
|
173 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
174 |
'policy': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) |
|
175 |
}, |
|
176 |
'im.membership': { |
|
177 |
'Meta': {'unique_together': "(('person', 'group'),)", 'object_name': 'Membership'}, |
|
178 |
'date_joined': ('django.db.models.fields.DateField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), |
|
179 |
'date_requested': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 6, 23, 16, 19, 365072)', 'blank': 'True'}), |
|
180 |
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']"}), |
|
181 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
182 |
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}) |
|
183 |
}, |
|
184 |
'im.pendingthirdpartyuser': { |
|
185 |
'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'PendingThirdPartyUser'}, |
|
186 |
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
187 |
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), |
|
188 |
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), |
|
189 |
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), |
|
190 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
191 |
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), |
|
192 |
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
193 |
'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
194 |
'token': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
195 |
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) |
|
196 |
}, |
|
197 |
'im.project': { |
|
198 |
'Meta': {'object_name': 'Project'}, |
|
199 |
'application': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'project'", 'unique': 'True', 'to': "orm['im.ProjectApplication']"}), |
|
200 |
'creation_date': ('django.db.models.fields.DateTimeField', [], {}), |
|
201 |
'last_approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
202 |
'last_synced_application': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'last_project'", 'unique': 'True', 'null': 'True', 'to': "orm['im.ProjectApplication']"}), |
|
203 |
'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosUser']", 'through': "orm['im.ProjectMembership']", 'symmetrical': 'False'}), |
|
204 |
'serial': ('django.db.models.fields.CharField', [], {'default': "'9dacd97c1c1446649791deaaae0414'", 'unique': 'True', 'max_length': '30', 'primary_key': 'True'}), |
|
205 |
'termination_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}) |
|
206 |
}, |
|
207 |
'im.projectapplication': { |
|
208 |
'Meta': {'object_name': 'ProjectApplication'}, |
|
209 |
'applicant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'my_project_applications'", 'to': "orm['im.AstakosUser']"}), |
|
210 |
'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), |
|
211 |
'definition': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectDefinition']", 'unique': 'True'}), |
|
212 |
'issue_date': ('django.db.models.fields.DateTimeField', [], {}), |
|
213 |
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'own_project_applications'", 'to': "orm['im.AstakosUser']"}), |
|
214 |
'precursor_application': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectApplication']", 'unique': 'True', 'null': 'True', 'blank': 'True'}), |
|
215 |
'serial': ('django.db.models.fields.CharField', [], {'default': "'d23622e32e0a48e9b8f15ee063776f'", 'unique': 'True', 'max_length': '30', 'primary_key': 'True'}) |
|
216 |
}, |
|
217 |
'im.projectdefinition': { |
|
218 |
'Meta': {'object_name': 'ProjectDefinition'}, |
|
219 |
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
220 |
'end_date': ('django.db.models.fields.DateTimeField', [], {}), |
|
221 |
'homepage': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
222 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
223 |
'limit_on_members_number': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
224 |
'member_accept_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberAcceptPolicy']"}), |
|
225 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}), |
|
226 |
'resource_grants': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['im.Resource']", 'null': 'True', 'through': "orm['im.ProjectResourceGrant']", 'blank': 'True'}), |
|
227 |
'start_date': ('django.db.models.fields.DateTimeField', [], {}) |
|
228 |
}, |
|
229 |
'im.projectmembership': { |
|
230 |
'Meta': {'unique_together': "(('person', 'project'),)", 'object_name': 'ProjectMembership'}, |
|
231 |
'decision_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'db_index': 'True'}), |
|
232 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
233 |
'is_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
|
234 |
'issue_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 6, 23, 16, 19, 378504)'}), |
|
235 |
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"}), |
|
236 |
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Project']"}) |
|
237 |
}, |
|
238 |
'im.projectresourcegrant': { |
|
239 |
'Meta': {'unique_together': "(('resource', 'project_definition'),)", 'object_name': 'ProjectResourceGrant'}, |
|
240 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
241 |
'member_limit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}), |
|
242 |
'project_definition': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.ProjectDefinition']", 'blank': 'True'}), |
|
243 |
'project_limit': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}), |
|
244 |
'resource': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Resource']"}) |
|
245 |
}, |
|
246 |
'im.resource': { |
|
247 |
'Meta': {'object_name': 'Resource'}, |
|
248 |
'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}), |
|
249 |
'group': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), |
|
250 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
251 |
'meta': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.ResourceMetadata']", 'symmetrical': 'False'}), |
|
252 |
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}), |
|
253 |
'service': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.Service']"}), |
|
254 |
'unit': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) |
|
255 |
}, |
|
256 |
'im.resourcemetadata': { |
|
257 |
'Meta': {'object_name': 'ResourceMetadata'}, |
|
258 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
259 |
'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}), |
|
260 |
'value': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
261 |
}, |
|
262 |
'im.service': { |
|
263 |
'Meta': {'object_name': 'Service'}, |
|
264 |
'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), |
|
265 |
'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
266 |
'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
267 |
'icon': ('django.db.models.fields.FilePathField', [], {'max_length': '100', 'blank': 'True'}), |
|
268 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
269 |
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}), |
|
270 |
'url': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}) |
|
271 |
}, |
|
272 |
'im.sessioncatalog': { |
|
273 |
'Meta': {'object_name': 'SessionCatalog'}, |
|
274 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
275 |
'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}), |
|
276 |
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sessions'", 'null': 'True', 'to': "orm['im.AstakosUser']"}) |
|
277 |
} |
|
278 |
} |
|
279 |
|
|
280 |
complete_apps = ['im'] |
b/snf-astakos-app/astakos/im/models.py | ||
---|---|---|
1017 | 1017 |
def __str__(self): |
1018 | 1018 |
return self.policy |
1019 | 1019 |
|
1020 |
class MemberRejectPolicy(models.Model): |
|
1021 |
policy = models.CharField(_('Policy'), max_length=255, unique=True, db_index=True) |
|
1022 |
description = models.CharField(_('Description'), max_length=80) |
|
1023 |
|
|
1024 |
def __str__(self): |
|
1025 |
return self.policy |
|
1026 |
|
|
1020 | 1027 |
_auto_accept = False |
1021 | 1028 |
def get_auto_accept(): |
1022 | 1029 |
global _auto_accept |
... | ... | |
1047 | 1054 |
def save(self): |
1048 | 1055 |
self.validate_name() |
1049 | 1056 |
super(ProjectDefinition, self).save() |
1050 |
|
|
1051 |
def validate_name(self): |
|
1052 |
""" |
|
1053 |
Validate name uniqueness among all active projects. |
|
1054 |
""" |
|
1055 |
alive_projects = list(get_alive_projects()) |
|
1056 |
q = filter(lambda p: p.definition.name==self.name, alive_projects) |
|
1057 |
if q: |
|
1058 |
raise ValidationError({'name': [_(astakos_messages.UNIQUE_PROJECT_NAME_CONSTRAIN_ERR)]}) |
|
1059 |
|
|
1057 |
|
|
1060 | 1058 |
@property |
1061 | 1059 |
def violated_resource_grants(self): |
1062 | 1060 |
return False |
... | ... | |
1086 | 1084 |
uplimit = p.get('uplimit', 0) |
1087 | 1085 |
update = p.get('update', True) |
1088 | 1086 |
self.add_resource_policy(service, resource, uplimit, update) |
1089 |
|
|
1090 |
def get_absolute_url(self): |
|
1091 |
return reverse('project_application_detail', args=(self.serial,)) |
|
1092 |
|
|
1093 | 1087 |
|
1094 | 1088 |
class ProjectResourceGrant(models.Model): |
1095 | 1089 |
objects = ExtendedManager() |
... | ... | |
1108 | 1102 |
unique=True, |
1109 | 1103 |
default=uuid.uuid4().hex[:30] |
1110 | 1104 |
) |
1111 |
applicant = models.ForeignKey(AstakosUser, related_name='my_project_applications') |
|
1112 |
owner = models.ForeignKey(AstakosUser, related_name='own_project_applications') |
|
1105 |
applicant = models.ForeignKey( |
|
1106 |
AstakosUser, |
|
1107 |
related_name='my_project_applications', |
|
1108 |
db_index=True) |
|
1109 |
owner = models.ForeignKey( |
|
1110 |
AstakosUser, |
|
1111 |
related_name='own_project_applications', |
|
1112 |
db_index=True |
|
1113 |
) |
|
1113 | 1114 |
comments = models.TextField(null=True, blank=True) |
1114 | 1115 |
definition = models.OneToOneField(ProjectDefinition) |
1115 | 1116 |
issue_date = models.DateTimeField() |
... | ... | |
1129 | 1130 |
application = models.OneToOneField(ProjectApplication, related_name='project') |
1130 | 1131 |
creation_date = models.DateTimeField() |
1131 | 1132 |
last_approval_date = models.DateTimeField(null=True) |
1133 |
termination_start_date = models.DateTimeField(null=True) |
|
1132 | 1134 |
termination_date = models.DateTimeField(null=True) |
1133 | 1135 |
members = models.ManyToManyField(AstakosUser, through='ProjectMembership') |
1134 |
last_synced_application = models.OneToOneField( |
|
1136 |
membership_dirty = models.BooleanField(default=False) |
|
1137 |
last_application_synced = models.OneToOneField( |
|
1135 | 1138 |
ProjectApplication, related_name='last_project', null=True, blank=True |
1136 | 1139 |
) |
1137 | 1140 |
|
1138 | 1141 |
@property |
1139 | 1142 |
def definition(self): |
1140 | 1143 |
return self.application.definition |
1141 |
|
|
1144 |
|
|
1145 |
@property |
|
1146 |
def violated_members_number_limit(self): |
|
1147 |
return len(self.approved_members) <= self.definition.limit_on_members_number |
|
1148 |
|
|
1142 | 1149 |
@property |
1143 | 1150 |
def is_valid(self): |
1144 | 1151 |
try: |
... | ... | |
1147 | 1154 |
return False |
1148 | 1155 |
else: |
1149 | 1156 |
return True |
1150 |
|
|
1157 |
|
|
1151 | 1158 |
@property |
1152 | 1159 |
def is_active(self): |
1153 | 1160 |
if not self.is_valid: |
... | ... | |
1158 | 1165 |
return False |
1159 | 1166 |
if self.definition.violated_resource_grants: |
1160 | 1167 |
return False |
1168 |
# if self.violated_members_number_limit: |
|
1169 |
# return False |
|
1161 | 1170 |
return True |
1162 | 1171 |
|
1163 | 1172 |
@property |
... | ... | |
1177 | 1186 |
if not self.last_approval_date: |
1178 | 1187 |
if not self.definition.violated_resource_grants: |
1179 | 1188 |
return False |
1189 |
# if not self.violated_members_number_limit: |
|
1190 |
# return False |
|
1180 | 1191 |
return True |
1181 | 1192 |
|
1182 | 1193 |
@property |
... | ... | |
1195 | 1206 |
return False |
1196 | 1207 |
|
1197 | 1208 |
@property |
1198 |
def approved_members(self): |
|
1199 |
return [m.person for m in self.members.filter(is_accepted=True)] |
|
1200 |
|
|
1201 |
def suspend(self): |
|
1202 |
self.last_approval_date = None |
|
1203 |
self.save() |
|
1209 |
def is_synchronized(self): |
|
1210 |
return self.last_application_synced == self.application and \ |
|
1211 |
not self.membership_dirty and \ |
|
1212 |
(not self.termination_start_date or termination_date) |
|
1204 | 1213 |
|
1205 |
def terminate(self): |
|
1206 |
self.terminaton_date = datetime.now() |
|
1207 |
self.save() |
|
1208 |
|
|
1209 |
def sync(self): |
|
1210 |
c, rejected = send_quota(self.approved_members) |
|
1214 |
@property |
|
1215 |
def approved_members(self): |
|
1216 |
return [m.person for m in self.projectmembership_set.filter(is_accepted=True)] |
|
1217 |
|
|
1218 |
def sync(self, specific_members=()): |
|
1219 |
if self.is_synchornized(): |
|
1220 |
return |
|
1221 |
members = specific_members or self.approved_members |
|
1222 |
c, rejected = send_quota(members) |
|
1211 | 1223 |
return rejected |
1212 | 1224 |
|
1213 | 1225 |
def add_member(self, user, request_user=None): |
... | ... | |
1229 | 1241 |
return |
1230 | 1242 |
if created: |
1231 | 1243 |
m.issue_date = datetime.now() |
1244 |
|
|
1232 | 1245 |
m.is_accepted = True |
1233 | 1246 |
m.decision_date = datetime.now() |
1234 | 1247 |
m.save() |
1248 |
|
|
1249 |
# set membership_dirty flag |
|
1250 |
self.membership_dirty = True |
|
1251 |
self.save() |
|
1252 |
|
|
1253 |
rejected = self.sync([user]) |
|
1254 |
if not rejected: |
|
1255 |
# if syncing was successful unset membership_dirty flag |
|
1256 |
self.membership_dirty = False |
|
1257 |
self.save() |
|
1258 |
|
|
1235 | 1259 |
notification = build_notification( |
1236 | 1260 |
settings.SERVER_EMAIL, |
1237 | 1261 |
[user.email], |
1238 | 1262 |
_('Your membership on project %(name)s has been accepted.') % project.definition.__dict__, |
1239 | 1263 |
_('Your membership on project %(name)s has been accepted.') % project.definition.__dict__ |
1240 | 1264 |
) |
1241 |
notification.send() |
|
1242 |
|
|
1265 |
|
|
1243 | 1266 |
def remove_member(self, user, request_user=None): |
1244 | 1267 |
if user.is_digit(): |
1245 | 1268 |
user = _lookup_object(AstakosUser, id=user) |
... | ... | |
1254 | 1277 |
m.is_accepted = False |
1255 | 1278 |
m.decision_date = datetime.now() |
1256 | 1279 |
m.save() |
1280 |
|
|
1281 |
# set membership_dirty flag |
|
1282 |
self.membership_dirty = True |
|
1283 |
self.save() |
|
1284 |
|
|
1285 |
rejected = self.sync([user]) |
|
1286 |
if not rejected: |
|
1287 |
# if syncing was successful unset membership_dirty flag |
|
1288 |
self.membership_dirty = False |
|
1289 |
self.save() |
|
1290 |
|
|
1257 | 1291 |
notification = build_notification( |
1258 | 1292 |
settings.SERVER_EMAIL, |
1259 | 1293 |
[user.email], |
... | ... | |
1261 | 1295 |
_('Your membership on project %(name)s has been removed.') % project.definition.__dict__ |
1262 | 1296 |
) |
1263 | 1297 |
notification.send() |
1298 |
|
|
1299 |
|
|
1300 |
def validate_name(self): |
|
1301 |
""" |
|
1302 |
Validate name uniqueness among all active projects. |
|
1303 |
""" |
|
1304 |
alive_projects = list(get_alive_projects()) |
|
1305 |
q = filter( |
|
1306 |
lambda p: p.definition.name == self.definition.name and \ |
|
1307 |
p.application.serial != self.application.serial, |
|
1308 |
alive_projects |
|
1309 |
) |
|
1310 |
if q: |
|
1311 |
raise ValidationError( |
|
1312 |
{'name': [_(astakos_messages.UNIQUE_PROJECT_NAME_CONSTRAIN_ERR)]} |
|
1313 |
) |
|
1314 |
|
|
1315 |
@classmethod |
|
1316 |
def submit(definition, applicant, comments, precursor_application=None, commit=True): |
|
1317 |
if precursor_application and precursor_application.project.is_valid: |
|
1318 |
application = precursor_application.copy() |
|
1319 |
application.precursor_application = precursor_application |
|
1320 |
else: |
|
1321 |
application = ProjectApplication(owner=applicant) |
|
1322 |
application.definition = definition |
|
1323 |
application.applicant = applicant |
|
1324 |
application.comments = comments |
|
1325 |
application.issue_date = datetime.now() |
|
1326 |
if commit: |
|
1327 |
definition.save() |
|
1328 |
application.save() |
|
1329 |
if applicant.is_superuser(): |
|
1330 |
self.approve_application() |
|
1331 |
notification = build_notification( |
|
1332 |
settings.SERVER_EMAIL, |
|
1333 |
[i[1] for i in settings.ADMINS], |
|
1334 |
_(GROUP_CREATION_SUBJECT) % {'group':application.definition.name}, |
|
1335 |
_('An new project application identified by %(serial)s has been submitted.') % application.__dict__ |
|
1336 |
) |
|
1337 |
notification.send() |
|
1338 |
return application |
|
1339 |
|
|
1340 |
def approve(self, approval_user=None): |
|
1341 |
""" |
|
1342 |
If approval_user then during owner membership acceptance |
|
1343 |
it is checked whether the request_user is eligible. |
|
1344 |
""" |
|
1345 |
if not self.precursor_application: |
|
1346 |
kwargs = { |
|
1347 |
'application':self, |
|
1348 |
'creation_date':datetime.now(), |
|
1349 |
'last_approval_date':datetime.now(), |
|
1350 |
} |
|
1351 |
project = _create_object(Project, **kwargs) |
|
1352 |
project.add_member(self.owner, approval_user) |
|
1353 |
else: |
|
1354 |
project = self.precursor_application.project |
|
1355 |
last_approval_date = project.last_approval_date |
|
1356 |
if project.is_valid: |
|
1357 |
project.application = app |
|
1358 |
project.last_approval_date = datetime.now() |
|
1359 |
project.save() |
|
1360 |
else: |
|
1361 |
raise Exception(_(astakos_messages.INVALID_PROJECT) % project.__dict__) |
|
1362 |
|
|
1363 |
rejected = self.sync() |
|
1364 |
if rejected: |
|
1365 |
# revert to precursor |
|
1366 |
project.appication = app.precursor_application |
|
1367 |
if project.application: |
|
1368 |
project.last_approval_date = last_approval_date |
|
1369 |
project.save() |
|
1370 |
rejected = synchonize_project(project.serial) |
|
1371 |
if rejected: |
|
1372 |
raise Exception(_(astakos_messages.QH_SYNC_ERROR)) |
|
1373 |
else: |
|
1374 |
project.last_application_synced = app |
|
1375 |
project.save() |
|
1376 |
sender, recipients, subject, message |
|
1377 |
notification = build_notification( |
|
1378 |
settings.SERVER_EMAIL, |
|
1379 |
[project.owner.email], |
|
1380 |
_('Project application has been approved on %s alpha2 testing' % SITENAME), |
|
1381 |
_('Your application request %(serial)s has been apporved.') |
|
1382 |
) |
|
1383 |
notification.send() |
|
1384 |
|
|
1385 |
def terminate(self): |
|
1386 |
self.termination_start_date = datetime.now() |
|
1387 |
self.terminaton_date = None |
|
1388 |
self.save() |
|
1389 |
|
|
1390 |
rejected = self.sync() |
|
1391 |
if not rejected: |
|
1392 |
self.termination_start_date = None |
|
1393 |
self.terminaton_date = datetime.now() |
|
1394 |
self.save() |
|
1395 |
|
|
1396 |
notification = build_notification( |
|
1397 |
settings.SERVER_EMAIL, |
|
1398 |
[self.application.owner.email], |
|
1399 |
_('Project %(name)s has been terminated.') % self.definition.__dict__, |
|
1400 |
_('Project %(name)s has been terminated.') % self.definition.__dict__ |
|
1401 |
) |
|
1402 |
notification.send() |
|
1403 |
|
|
1404 |
def suspend(self): |
|
1405 |
self.last_approval_date = None |
|
1406 |
self.save() |
|
1407 |
notification = build_notification( |
|
1408 |
settings.SERVER_EMAIL, |
|
1409 |
[self.application.owner.email], |
|
1410 |
_('Project %(name)s has been suspended.') % self.definition.__dict__, |
|
1411 |
_('Project %(name)s has been suspended.') % self.definition.__dict__ |
|
1412 |
) |
|
1413 |
notification.send() |
|
1414 |
|
|
1264 | 1415 |
|
1265 | 1416 |
|
1266 | 1417 |
class ProjectMembership(models.Model): |
... | ... | |
1322 | 1473 |
def list_applications(): |
1323 | 1474 |
return ProjectApplication.objects.all() |
1324 | 1475 |
|
1325 |
def submit_application(definition, applicant, comments, precursor_application=None, commit=True): |
|
1326 |
if precursor_application: |
|
1327 |
application = precursor_application.copy() |
|
1328 |
application.precursor_application = precursor_application |
|
1329 |
else: |
|
1330 |
application = ProjectApplication(owner=applicant) |
|
1331 |
application.definition = definition |
|
1332 |
application.applicant = applicant |
|
1333 |
application.comments = comments |
|
1334 |
application.issue_date = datetime.now() |
|
1335 |
if commit: |
|
1336 |
definition.save() |
|
1337 |
application.save() |
|
1338 |
notification = build_notification( |
|
1339 |
settings.SERVER_EMAIL, |
|
1340 |
[i[1] for i in settings.ADMINS], |
|
1341 |
_(GROUP_CREATION_SUBJECT) % {'group':application.definition.name}, |
|
1342 |
_('An new project application identified by %(serial)s has been submitted.') % application.__dict__ |
|
1343 |
) |
|
1344 |
notification.send() |
|
1345 |
return application |
|
1346 |
|
|
1347 |
def approve_application(serial, request_user=None): |
|
1348 |
app = _lookup_object(ProjectApplication, serial=serial) |
|
1349 |
if not app.precursor_application: |
|
1350 |
kwargs = { |
|
1351 |
'application':app, |
|
1352 |
'creation_date':datetime.now(), |
|
1353 |
'last_approval_date':datetime.now(), |
|
1354 |
} |
|
1355 |
project = _create_object(Project, **kwargs) |
|
1356 |
project.add_member(app.owner, request_user) |
|
1357 |
else: |
|
1358 |
project = app.precursor_application.project |
|
1359 |
last_approval_date = project.last_approval_date |
|
1360 |
if project.is_valid: |
|
1361 |
project.application = app |
|
1362 |
project.last_approval_date = datetime.now() |
|
1363 |
project.save() |
|
1364 |
else: |
|
1365 |
raise Exception(_(astakos_messages.INVALID_PROJECT) % project.__dict__) |
|
1366 |
|
|
1367 |
rejected = synchonize_project(project.serial) |
|
1368 |
if rejected: |
|
1369 |
# revert to precursor |
|
1370 |
project.appication = app.precursor_application |
|
1371 |
if project.application: |
|
1372 |
project.last_approval_date = last_approval_date |
|
1373 |
project.save() |
|
1374 |
rejected = synchonize_project(project.serial) |
|
1375 |
if rejected: |
|
1376 |
raise Exception(_(astakos_messages.QH_SYNC_ERROR)) |
|
1377 |
else: |
|
1378 |
project.last_application_synced = app |
|
1379 |
project.save() |
|
1380 |
sender, recipients, subject, message |
|
1381 |
notification = build_notification( |
|
1382 |
settings.SERVER_EMAIL, |
|
1383 |
[project.owner.email], |
|
1384 |
_('Project application has been approved on %s alpha2 testing' % SITENAME), |
|
1385 |
_('Your application request %(serial)s has been apporved.') |
|
1386 |
) |
|
1387 |
notification.send() |
|
1388 |
|
|
1389 | 1476 |
|
1390 | 1477 |
def list_projects(filter_property=None): |
1391 | 1478 |
if filter_property: |
... | ... | |
1395 | 1482 |
) |
1396 | 1483 |
return Project.objects.all() |
1397 | 1484 |
|
1398 |
def suspend_project(serial): |
|
1399 |
project = _lookup_object(Project, serial=serial) |
|
1400 |
project.suspend() |
|
1401 |
notification = build_notification( |
|
1402 |
settings.SERVER_EMAIL, |
|
1403 |
[project.owner.email], |
|
1404 |
_('Project %(name)s has been suspended.') % project.definition.__dict__, |
|
1405 |
_('Project %(name)s has been suspended.') % project.definition.__dict__ |
|
1406 |
) |
|
1407 |
notification.send() |
|
1408 |
|
|
1409 |
def terminate_project(serial): |
|
1410 |
project = _lookup_object(Project, serial=serial) |
|
1411 |
project.termination() |
|
1412 |
notification = build_notification( |
|
1413 |
settings.SERVER_EMAIL, |
|
1414 |
[project.owner.email], |
|
1415 |
_('Project %(name)s has been terminated.') % project.definition.__dict__, |
|
1416 |
_('Project %(name)s has been terminated.') % project.definition.__dict__ |
|
1417 |
) |
|
1418 |
notification.send() |
|
1419 | 1485 |
|
1420 | 1486 |
def synchonize_project(serial): |
1421 | 1487 |
project = _lookup_object(Project, serial=serial) |
1422 |
if project.app != project.last_application_synced:
|
|
1423 |
return project.sync() |
|
1424 |
|
|
1488 |
return project.sync()
|
|
1489 |
|
|
1490 |
|
|
1425 | 1491 |
def create_astakos_user(u): |
1426 | 1492 |
try: |
1427 | 1493 |
AstakosUser.objects.get(user_ptr=u.pk) |
b/snf-astakos-app/docs/projects_specs.rst | ||
---|---|---|
164 | 164 |
``members`` |
165 | 165 |
*the set of members for this project* |
166 | 166 |
|
167 |
``membership_updated``
|
|
167 |
``membership_dirty``
|
|
168 | 168 |
*boolean attribute declaring that the project |
169 | 169 |
needs membership synchronization. |
170 | 170 |
It must be atomically set and committed before |
... | ... | |
234 | 234 |
|
235 | 235 |
An alive project is delcared synchronized by setting |
236 | 236 |
``last_application_synced`` to be equal to the ``application``, |
237 |
and setting ``membership_updated`` to false,
|
|
237 |
and setting ``membership_dirty`` to false,
|
|
238 | 238 |
|
239 | 239 |
Semantically, the project becomes synchronized when its application |
240 | 240 |
definition has been fully implemented and committed to quotaholder, |
... | ... | |
248 | 248 |
a project is declared synchronized if and only if: |
249 | 249 |
|
250 | 250 |
- ``last_application_synced`` equals ``application`` |
251 |
- ``membership_updated`` is false
|
|
251 |
- ``membership_dirty`` is false
|
|
252 | 252 |
- ``termination_start_date`` is null or ``termination_date`` is set |
253 | 253 |
|
254 | 254 |
Depending on which of the previous three clauses fail, |
Also available in: Unified diff