@@ -0,0 +1,1457 @@
+from collections import defaultdict%0A%0Afrom proposal.models import Change, Proposal%0Afrom proposal.views import proposal_json%0Afrom proposal.query import build_proposal_query%0A%0A%0Adef find_updates(subscriptions, since):%0A    change_summary = defaultdict(dict)%0A%0A    for subscription in subscriptions:%0A        query_dict = subscription.query_dict%0A        if not query_dict:%0A            return None%0A%0A        query = build_proposal_query(query_dict)%0A        proposals = Proposal.objects.filter(query, updated__gt=since)%0A%0A        if not proposals:%0A            continue%0A%0A        ids = %5Bproposal.pk for proposal in proposals%5D%0A%0A        changes = Change.objects.filter(created_at__gt=since,%0A                                        proposal__in=ids)%5C%0A                                .order_by(%22created_at%22)%0A        for change in changes:%0A            if change.description:%0A                desc = change.description%0A            else:%0A                desc = %22%22%0A%0A            change_summary%5Bchange.proposal_id%5D%5Bchange.prop_path%5D = %7B%0A                %22description%22: desc%0A            %7D%0A%0A    summary = %5B%5D%0A    for proposal in proposals:%0A        if proposal.pk in change_summary:%0A            summary.append(%7B%22proposal%22: proposal_json(proposal,%0A                                                      include_images=1,%0A                                                      include_documents=False),%0A                            %22changes%22: change_summary%5Bproposal.pk%5D%7D)%0A%0A    return summary%0A

Change summary map for generating notification emails