@@ -0,0 +1,2897 @@
+import csv%0Aimport sys%0A%0Afrom django.core.management.base import BaseCommand, CommandError%0A%0Afrom pombola.core.models import Organisation, OrganisationRelationship%0A%0AMAPS_URL_TEMPLATE = 'https://www.google.com/maps/place/%7Blat%7D+%7Blon%7D/@%7Blat%7D,%7Blon%7D,17z'%0A%0Adef encode_row_values_to_utf8(row):%0A    return %7B%0A        k: unicode(v).encode('utf-8')%0A        for k, v in row.items()%0A    %7D%0A%0Aclass Command(BaseCommand):%0A%0A    def handle(self, *args, **options):%0A%0A        fields = %5B%0A            'OfficeID',%0A            'OfficeName',%0A            'MapURL',%0A            'PhysicalAddress',%0A            'Latitude',%0A            'Longitude',%0A            'PartyName',%0A            'PartyID'%0A        %5D%0A%0A        writer = csv.DictWriter(sys.stdout, fieldnames=fields)%0A%0A        writer.writeheader()%0A%0A        for o in Organisation.objects. %5C%0A            filter(kind__slug='constituency-office'). %5C%0A            order_by('slug'):%0A            places = o.place_set.filter(%0A                kind__slug='constituency-office',%0A                name__startswith='Approximate position of ',%0A            )%0A            place_count = places.count()%0A            if place_count %3E 1:%0A                msg = %22Multiple places (%7Bplace_count%7D) found for %7Borganisation_id%7D%22%0A                raise CommandError(msg.format(%0A                    place_count=place_count,%0A                    organisation_id=o.id%0A                ))%0A            row = %7B'OfficeID': o.id, 'OfficeName': o.name%7D%0A            if place_count:%0A                location = places%5B0%5D.location%0A                row%5B'Latitude'%5D = location.y%0A                row%5B'Longitude'%5D = location.x%0A                row%5B'MapURL'%5D = MAPS_URL_TEMPLATE.format(%0A                    lat=location.y,%0A                    lon=location.x,%0A                )%0A            # Try to find the party whose office this is:%0A            try:%0A                party = OrganisationRelationship.objects.get(%0A                    organisation_b=o,%0A                    kind__name='has_office'%0A                ).organisation_a%0A                row%5B'PartyID'%5D = party.id%0A                row%5B'PartyName'%5D = party.name%0A            except OrganisationRelationship.DoesNotExist:%0A                message = %22No party found for office with ID %7Boffice_id%7D%5Cn%22%0A                self.stderr.write(message.format(office_id=o.id))%0A            # Now try to find the address from the office%0A            # organisation's contacts:%0A            addresses = o.contacts.filter(kind__slug='address')%0A            address_count = addresses.count()%0A            if address_count %3E 1:%0A                msg = %22Multiple address found for %7Borganisation_id%7D%22%0A                raise CommandError(msg.format(%0A                    address_count=address_count,%0A                    organisation_id=o.id%0A                ))%0A            if address_count:%0A                row%5B'PhysicalAddress'%5D = addresses%5B0%5D.value%0A            writer.writerow(encode_row_values_to_utf8(row))%0A

Add a command to output a CSV file of constituency offices