474 |
474 |
p = m.project
|
475 |
475 |
if not p.is_active:
|
476 |
476 |
continue
|
477 |
|
grants = p.application.definition.projectresourcegrant_set.all()
|
|
477 |
grants = p.current_application.definition.projectresourcegrant_set.all()
|
478 |
478 |
for g in grants:
|
479 |
479 |
d[str(g.resource)] += g.member_limit or inf
|
480 |
480 |
# TODO set default for remaining
|
... | ... | |
1153 |
1153 |
"""
|
1154 |
1154 |
q = list(get_alive_projects())
|
1155 |
1155 |
q = filter(lambda p: p.definition.name == self.name , q)
|
1156 |
|
q = filter(lambda p: p.application.id != self.projectapplication.id, q)
|
|
1156 |
q = filter(lambda p: p.current_application.id != self.projectapplication.id, q)
|
1157 |
1157 |
if self.projectapplication.precursor_application:
|
1158 |
|
q = filter(lambda p: p.application.id != \
|
|
1158 |
q = filter(lambda p: p.current_application.id != \
|
1159 |
1159 |
self.projectapplication.precursor_application.id, q)
|
1160 |
1160 |
if q:
|
1161 |
1161 |
raise ValidationError(
|
... | ... | |
1229 |
1229 |
application.state = PENDING
|
1230 |
1230 |
application.save()
|
1231 |
1231 |
application.definition.resource_policies = resource_policies
|
|
1232 |
|
|
1233 |
try:
|
|
1234 |
notification = build_notification(
|
|
1235 |
settings.SERVER_EMAIL,
|
|
1236 |
[i[1] for i in settings.ADMINS],
|
|
1237 |
_(PROJECT_CREATION_SUBJECT) % application.definition.__dict__,
|
|
1238 |
template='im/projects/project_creation_notification.txt',
|
|
1239 |
dictionary={'object':application}
|
|
1240 |
).send()
|
|
1241 |
except NotificationError, e:
|
|
1242 |
logger.error(e.messages)
|
1232 |
1243 |
|
1233 |
|
notification = build_notification(
|
1234 |
|
settings.SERVER_EMAIL,
|
1235 |
|
[i[1] for i in settings.ADMINS],
|
1236 |
|
_(PROJECT_CREATION_SUBJECT) % application.definition.__dict__,
|
1237 |
|
template='im/projects/project_creation_notification.txt',
|
1238 |
|
dictionary={'object':application}
|
1239 |
|
)
|
1240 |
|
notification.send()
|
1241 |
1244 |
return application
|
1242 |
1245 |
|
1243 |
1246 |
def approve(self, approval_user=None):
|
... | ... | |
1246 |
1249 |
it is checked whether the request_user is eligible.
|
1247 |
1250 |
|
1248 |
1251 |
Raises:
|
1249 |
|
ValidationError: if there is other alive project with the same name
|
1250 |
|
|
|
1252 |
PermissionDenied
|
1251 |
1253 |
"""
|
1252 |
1254 |
try:
|
1253 |
1255 |
self.definition.validate_name()
|
... | ... | |
1263 |
1265 |
except:
|
1264 |
1266 |
project = Project()
|
1265 |
1267 |
project.creation_date = now
|
1266 |
|
project.accept_member(self.owner, approval_user)
|
1267 |
1268 |
|
1268 |
1269 |
project.last_application_approved = self
|
1269 |
1270 |
project.last_approval_date = now
|
1270 |
1271 |
project.save()
|
|
1272 |
project.accept_member(self.owner, approval_user)
|
1271 |
1273 |
|
1272 |
1274 |
p = precursor
|
1273 |
1275 |
while p:
|
... | ... | |
1278 |
1280 |
self.state = APPROVED
|
1279 |
1281 |
self.save()
|
1280 |
1282 |
|
1281 |
|
transaction.commit()
|
1282 |
|
|
1283 |
|
notification = build_notification(
|
1284 |
|
settings.SERVER_EMAIL,
|
1285 |
|
[self.owner.email],
|
1286 |
|
_(PROJECT_APPROVED_SUBJECT) % self.definition.__dict__,
|
1287 |
|
template='im/projects/project_approval_notification.txt',
|
1288 |
|
dictionary={'object':self}
|
1289 |
|
)
|
1290 |
|
notification.send()
|
|
1283 |
if transaction.is_managed():
|
|
1284 |
transaction.commit()
|
1291 |
1285 |
|
1292 |
1286 |
rejected = self.project.sync()
|
1293 |
|
if not rejected:
|
1294 |
|
project.application = self
|
1295 |
|
project.save()
|
|
1287 |
|
|
1288 |
try:
|
|
1289 |
notification = build_notification(
|
|
1290 |
settings.SERVER_EMAIL,
|
|
1291 |
[self.owner.email],
|
|
1292 |
_(PROJECT_APPROVED_SUBJECT) % self.definition.__dict__,
|
|
1293 |
template='im/projects/project_approval_notification.txt',
|
|
1294 |
dictionary={'object':self}
|
|
1295 |
).send()
|
|
1296 |
except NotificationError, e:
|
|
1297 |
logger.error(e.messages)
|
1296 |
1298 |
|
1297 |
1299 |
|
1298 |
1300 |
class Project(models.Model):
|
1299 |
1301 |
application = models.OneToOneField(
|
1300 |
|
ProjectApplication, related_name='project', null=True, blank=True)
|
|
1302 |
ProjectApplication, related_name='project', null=True)
|
1301 |
1303 |
creation_date = models.DateTimeField()
|
1302 |
1304 |
last_approval_date = models.DateTimeField(null=True)
|
1303 |
1305 |
termination_start_date = models.DateTimeField(null=True)
|
... | ... | |
1307 |
1309 |
last_application_approved = models.OneToOneField(
|
1308 |
1310 |
ProjectApplication, related_name='last_project')
|
1309 |
1311 |
|
|
1312 |
@property
|
|
1313 |
def current_application(self):
|
|
1314 |
return self.application or self.last_application_approved
|
1310 |
1315 |
|
1311 |
1316 |
@property
|
1312 |
1317 |
def definition(self):
|
1313 |
|
return self.application.definition
|
|
1318 |
return self.current_application.definition
|
1314 |
1319 |
|
1315 |
1320 |
@property
|
1316 |
1321 |
def violated_members_number_limit(self):
|
... | ... | |
1375 |
1380 |
return
|
1376 |
1381 |
members = specific_members or self.approved_members
|
1377 |
1382 |
c, rejected = send_quota(self.approved_members)
|
|
1383 |
if not rejected:
|
|
1384 |
self.application = self.last_application_approved
|
|
1385 |
self.save()
|
1378 |
1386 |
return rejected
|
1379 |
1387 |
|
1380 |
1388 |
def accept_member(self, user, request_user=None):
|
... | ... | |
1436 |
1444 |
self.termination_date = datetime.now()
|
1437 |
1445 |
self.save()
|
1438 |
1446 |
|
1439 |
|
notification = build_notification(
|
1440 |
|
settings.SERVER_EMAIL,
|
1441 |
|
[self.application.owner.email],
|
1442 |
|
_(PROJECT_TERMINATION_SUBJECT) % self.definition.__dict__,
|
1443 |
|
template='im/projects/project_termination_notification.txt',
|
1444 |
|
dictionary={'object':self.application}
|
1445 |
|
)
|
1446 |
|
notification.send()
|
|
1447 |
try:
|
|
1448 |
notification = build_notification(
|
|
1449 |
settings.SERVER_EMAIL,
|
|
1450 |
[self.current_application.owner.email],
|
|
1451 |
_(PROJECT_TERMINATION_SUBJECT) % self.definition.__dict__,
|
|
1452 |
template='im/projects/project_termination_notification.txt',
|
|
1453 |
dictionary={'object':self.current_application}
|
|
1454 |
).send()
|
|
1455 |
except NotificationError, e:
|
|
1456 |
logger.error(e.messages)
|
1447 |
1457 |
|
1448 |
1458 |
def suspend(self):
|
1449 |
1459 |
self.last_approval_date = None
|
1450 |
1460 |
self.save()
|
1451 |
1461 |
self.sync()
|
1452 |
|
notification = build_notification(
|
1453 |
|
settings.SERVER_EMAIL,
|
1454 |
|
[self.application.owner.email],
|
1455 |
|
_(PROJECT_SUSPENSION_SUBJECT) % self.definition.__dict__,
|
1456 |
|
template='im/projects/project_suspension_notification.txt',
|
1457 |
|
dictionary={'object':self.application}
|
1458 |
|
)
|
1459 |
|
notification.send()
|
|
1462 |
|
|
1463 |
try:
|
|
1464 |
notification = build_notification(
|
|
1465 |
settings.SERVER_EMAIL,
|
|
1466 |
[self.current_application.owner.email],
|
|
1467 |
_(PROJECT_SUSPENSION_SUBJECT) % self.definition.__dict__,
|
|
1468 |
template='im/projects/project_suspension_notification.txt',
|
|
1469 |
dictionary={'object':self.current_application}
|
|
1470 |
).send()
|
|
1471 |
except NotificationError, e:
|
|
1472 |
logger.error(e.messages)
|
1460 |
1473 |
|
1461 |
1474 |
class ProjectMembership(models.Model):
|
1462 |
1475 |
person = models.ForeignKey(AstakosUser)
|
... | ... | |
1472 |
1485 |
"""
|
1473 |
1486 |
Raises:
|
1474 |
1487 |
django.exception.PermissionDenied
|
1475 |
|
astakos.im.notifications.NotificationError
|
1476 |
1488 |
"""
|
1477 |
1489 |
try:
|
1478 |
1490 |
if request_user and \
|
1479 |
|
(not self.project.application.owner == request_user and \
|
|
1491 |
(not self.project.current_application.owner == request_user and \
|
1480 |
1492 |
not request_user.is_superuser):
|
1481 |
1493 |
raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
|
1482 |
1494 |
if not self.project.is_alive:
|
... | ... | |
1491 |
1503 |
return
|
1492 |
1504 |
self.acceptance_date = datetime.now()
|
1493 |
1505 |
self.save()
|
1494 |
|
notification = build_notification(
|
1495 |
|
settings.SERVER_EMAIL,
|
1496 |
|
[self.person.email],
|
1497 |
|
_(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % self.project.definition.__dict__,
|
1498 |
|
template='im/projects/project_membership_change_notification.txt',
|
1499 |
|
dictionary={'object':self.project.application, 'action':'accepted'}
|
1500 |
|
).send()
|
1501 |
1506 |
self.sync()
|
|
1507 |
|
|
1508 |
try:
|
|
1509 |
notification = build_notification(
|
|
1510 |
settings.SERVER_EMAIL,
|
|
1511 |
[self.person.email],
|
|
1512 |
_(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % self.project.definition.__dict__,
|
|
1513 |
template='im/projects/project_membership_change_notification.txt',
|
|
1514 |
dictionary={'object':self.project.current_application, 'action':'accepted'}
|
|
1515 |
).send()
|
|
1516 |
except NotificationError, e:
|
|
1517 |
logger.error(e.messages)
|
1502 |
1518 |
|
1503 |
1519 |
def reject(self, request_user=None):
|
1504 |
1520 |
"""
|
1505 |
1521 |
Raises:
|
1506 |
|
django.exception.PermissionDenied,
|
1507 |
|
astakos.im.notifications.NotificationError
|
|
1522 |
django.exception.PermissionDenied
|
1508 |
1523 |
"""
|
1509 |
1524 |
if request_user and \
|
1510 |
|
(not self.project.application.owner == request_user and \
|
|
1525 |
(not self.project.current_application.owner == request_user and \
|
1511 |
1526 |
not request_user.is_superuser):
|
1512 |
1527 |
raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
|
1513 |
1528 |
if not self.project.is_alive:
|
... | ... | |
1520 |
1535 |
)
|
1521 |
1536 |
self.delete()
|
1522 |
1537 |
history_item.save()
|
1523 |
|
notification = build_notification(
|
1524 |
|
settings.SERVER_EMAIL,
|
1525 |
|
[self.person.email],
|
1526 |
|
_(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % self.project.definition.__dict__,
|
1527 |
|
template='im/projects/project_membership_change_notification.txt',
|
1528 |
|
dictionary={'object':self.project.application, 'action':'rejected'}
|
1529 |
|
).send()
|
1530 |
|
|
|
1538 |
|
|
1539 |
try:
|
|
1540 |
notification = build_notification(
|
|
1541 |
settings.SERVER_EMAIL,
|
|
1542 |
[self.person.email],
|
|
1543 |
_(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % self.project.definition.__dict__,
|
|
1544 |
template='im/projects/project_membership_change_notification.txt',
|
|
1545 |
dictionary={'object':self.project.current_application, 'action':'rejected'}
|
|
1546 |
).send()
|
|
1547 |
except NotificationError, e:
|
|
1548 |
logger.error(e.messages)
|
|
1549 |
|
1531 |
1550 |
def remove(self, request_user=None):
|
1532 |
1551 |
"""
|
1533 |
1552 |
Raises:
|
1534 |
1553 |
django.exception.PermissionDenied
|
1535 |
|
astakos.im.notifications.NotificationError
|
1536 |
1554 |
"""
|
1537 |
1555 |
if request_user and \
|
1538 |
|
(not self.project.application.owner == request_user and \
|
|
1556 |
(not self.project.current_application.owner == request_user and \
|
1539 |
1557 |
not request_user.is_superuser):
|
1540 |
1558 |
raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
|
1541 |
1559 |
if not self.project.is_alive:
|
... | ... | |
1549 |
1567 |
)
|
1550 |
1568 |
self.delete()
|
1551 |
1569 |
history_item.save()
|
1552 |
|
notification = build_notification(
|
1553 |
|
settings.SERVER_EMAIL,
|
1554 |
|
[self.person.email],
|
1555 |
|
_(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % self.project.definition.__dict__,
|
1556 |
|
template='im/projects/project_membership_change_notification.txt',
|
1557 |
|
dictionary={'object':self.project.application, 'action':'removed'}
|
1558 |
|
).send()
|
1559 |
1570 |
self.sync()
|
|
1571 |
|
|
1572 |
try:
|
|
1573 |
notification = build_notification(
|
|
1574 |
settings.SERVER_EMAIL,
|
|
1575 |
[self.person.email],
|
|
1576 |
_(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % self.project.definition.__dict__,
|
|
1577 |
template='im/projects/project_membership_change_notification.txt',
|
|
1578 |
dictionary={'object':self.project.current_application, 'action':'removed'}
|
|
1579 |
).send()
|
|
1580 |
except NotificationError, e:
|
|
1581 |
logger.error(e.messages)
|
1560 |
1582 |
|
1561 |
1583 |
def leave(self):
|
1562 |
|
leave_policy = self.project.application.definition.member_leave_policy
|
|
1584 |
leave_policy = self.project.current_application.definition.member_leave_policy
|
1563 |
1585 |
if leave_policy == get_auto_accept_leave():
|
1564 |
1586 |
self.remove()
|
1565 |
1587 |
else:
|
... | ... | |
1727 |
1749 |
def check_closed_join_membership_policy(sender, instance, **kwargs):
|
1728 |
1750 |
if instance.id:
|
1729 |
1751 |
return
|
1730 |
|
if instance.person == instance.project.application.owner:
|
|
1752 |
if instance.person == instance.project.current_application.owner:
|
1731 |
1753 |
return
|
1732 |
|
join_policy = instance.project.application.definition.member_join_policy
|
|
1754 |
join_policy = instance.project.current_application.definition.member_join_policy
|
1733 |
1755 |
if join_policy == get_closed_join():
|
1734 |
1756 |
raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
|
1735 |
1757 |
pre_save.connect(check_closed_join_membership_policy, sender=ProjectMembership)
|
... | ... | |
1738 |
1760 |
def check_auto_accept_join_membership_policy(sender, instance, created, **kwargs):
|
1739 |
1761 |
if not created:
|
1740 |
1762 |
return
|
1741 |
|
join_policy = instance.project.application.definition.member_join_policy
|
|
1763 |
join_policy = instance.project.current_application.definition.member_join_policy
|
1742 |
1764 |
if join_policy == get_auto_accept_join() and not instance.acceptance_date:
|
1743 |
1765 |
instance.accept()
|
1744 |
1766 |
post_save.connect(check_auto_accept_join_membership_policy, sender=ProjectMembership)
|