Revision 82d7e9ef

b/snf-astakos-app/astakos/im/models.py
1618 1618
    ACCEPTED    =   1
1619 1619
    REMOVED     =   2
1620 1620
    REJECTED    =   3   # never seen, because .delete()
1621
    REPLACED    =   4   # when the project definition is replaced
1622
                        # spontaneously goes back to ACCEPTED when synced
1621 1623

  
1622 1624
    class Meta:
1623 1625
        unique_together = ("person", "project")
......
1697 1699
        self.delete()
1698 1700

  
1699 1701
    def get_quotas(self, limits_list=None, factor=1):
1700
        holder = self.person.username
1701 1702
        if limits_list is None:
1702 1703
            limits_list = []
1703 1704
        append = limits_list.append
1705
        holder = self.person.username
1704 1706
        all_grants = self.project.application.resource_grants.all()
1705 1707
        for grant in all_grants:
1706 1708
            append(QuotaLimits(holder       = holder,
......
1710 1712
                               export_limit = factor * grant.member_export_limit))
1711 1713
        return limits_list
1712 1714

  
1715
    def get_diff_quotas(self, limits_list=None, factor=1):
1716
        if limits_list is None:
1717
            limits_list = []
1718

  
1719
        append = limits_list.append
1720
        holder = self.person.username
1721

  
1722
        # first, inverse all current limits, and index them by resource name
1723
        cur_grants = self.project.application.resource_grants.all()
1724
        f = factor * -1
1725
        tmp_grants = {}
1726
        for grant in cur_grants:
1727
            name = grant.resource.name
1728
            tmp_grants[name] = QuotaLimits(
1729
                            holder       = holder,
1730
                            resource     = name,
1731
                            capacity     = f * grant.member_capacity,
1732
                            import_limit = f * grant.member_import_limit,
1733
                            export_limit = f * grant.member_export_limit))
1734

  
1735
        # second, add each new limit to its inversed current
1736
        for new_grant in new_grants:
1737
            name = grant.resource.name
1738
            cur_grant = tmp_grants.pop(name, None)
1739
            if cur_grant is None:
1740
                # if limits on a new resource, set 0 current values
1741
                capacity = 0
1742
                import_limit = 0
1743
                export_limit = 0
1744
            else:
1745
                capacity = cur_grant.capacity
1746
                import_limit = cur_grant.import_limit
1747
                export_limit = cur_grant.export_limit
1748

  
1749
            capacity += new_grant.member_capacity
1750
            import_limit += new_grant.member_import_limit
1751
            export_limit += new_grant.member_export_limit
1752

  
1753
            append(QuotaLimits(holder       = holder,
1754
                               resource     = name,
1755
                               capacity     = capacity,
1756
                               import_limit = import_limit,
1757
                               export_limit = export_limit))
1758

  
1759
        # third, append all the inversed current limits for removed resources
1760
        limits_list.extend(tmp_grants.itervalues())
1761
        return limits_list
1762

  
1713 1763
    def do_sync(self):
1714 1764
        state = self.sync_get_synced_state()
1715 1765
        new_state = self.sync_get_new_state()
1716 1766

  
1717 1767
        if state == self.REQUESTED and new_state == self.ACCEPTED:
1718
            factor = 1
1768
            quotas = self.get_quotas(factor=1)
1719 1769
        elif state == self.ACCEPTED and new_state == self.REMOVED:
1720
            factor = -1
1770
            quotas = self.get_quotas(factor=-1)
1771
        elif state == self.ACCEPTED and new_state == self.REPLACED:
1772
            quotas = self.get_diff_quotas(factor=1)
1721 1773
        else:
1722 1774
            m = _("%s: sync: called on invalid state ('%s' -> '%s')") % (
1723 1775
                    self, state, new_state)
1724 1776
            raise AssertionError(m)
1725 1777

  
1726
        quotas = self.get_quotas(factor=factor)
1727 1778
        try:
1728 1779
            failure = add_quotas(quotas)
1729 1780
            if failure:
......
1734 1785
        else:
1735 1786
            self.sync_set_synced()
1736 1787

  
1788
        # some states have instant side-effects/transitions
1737 1789
        if new_state == self.REMOVED:
1738 1790
            self.delete()
1791
        elif new_state == self.REPLACED:
1792
            self.sync_init_state(self.ACCEPTED)
1739 1793

  
1740 1794
    def sync(self):
1741 1795
        with exclusive_or_raise:

Also available in: Unified diff