from __future__ import print_function, unicode_literals from datetime import date from django.conf import settings from django.core.management.base import BaseCommand from django.utils.six.moves.urllib_parse import urljoin from django.utils.text import slugify import requests from candidates.models import ( AreaExtra, OrganizationExtra, PartySet, PostExtra ) from elections.models import AreaType, Election from elections.uk import mapit from popolo.models import Area, Organization, Post clast Command(BaseCommand): help = 'Create posts and elections for the 2016 PCC elections' def handle(self, **options): mapit_url = settings.MAPIT_BASE_URL self.gb_parties, _ = PartySet.objects.get_or_create( slug='gb', defaults={'name': 'Great Britain'} ) self.organizations = {} self.base_election_info = { 'name': 'Police and Crime Commissioner Elections 2016', 'for_post_role': 'Police and Crime Commissioner', 'label_format': 'Police and Crime Commissioner for {area_name}', 'area_generation': 1, 'election_date': date(2016, 5, 5), 'party_lists_in_use': False, 'mapit_code': 'PDG', 'electon_id_prefix': 'pcc', # 'area_type_description': 'Police Force', } url_path = '/areas/' + self.base_election_info['mapit_code'] url = urljoin(mapit_url, url_path) r = requests.get(url) mapit_results = r.json().items() # First make all the organisations for mapit_area_id, mapit_area_data in mapit_results: if mapit_area_data['codes']['police_id'] == "metropolitan": continue self.add_police_force_orgs(mapit_area_id, mapit_area_data) # Create a single election self.create_pcc_election() # Add all the areas for that election for mapit_area_id, mapit_area_data in mapit_results: if mapit_area_data['codes']['police_id'] == "metropolitan": # The Met doesn't have a PCCge continue self.add_pcc_areas(mapit_area_id, mapit_area_data) def add_police_force_orgs(self, mapit_area_id, mapit_area_data): org_name = mapit_area_data['name'] org_slug = self.format_org_slug(org_name) try: organization_extra = OrganizationExtra.objects.get(slug=org_slug) organization = organization_extra.base except OrganizationExtra.DoesNotExist: organization = Organization.objects.create(name=org_name) organization_extra = OrganizationExtra.objects.create( base=organization, slug=org_slug ) self.organizations[org_name] = organization def format_org_slug(self, org_name): name = org_name.lower()\ .replace('police', '')\ .replace('constabulary', '')\ .strip() return slugify(name) def format_election_slug(self, election_info): return ".".join([ election_info['electon_id_prefix'], election_info['election_date'].strftime('%Y-%m-%d')]) def create_pcc_election(self): election_defaults = { k: self.base_election_info[k] for k in [ 'name', 'for_post_role', 'area_generation', 'election_date', 'party_lists_in_use'] } election_defaults['current'] = True election_defaults['candidate_membership_role'] = 'Candidate' # election_defaults['organization'] = self.organizations[org_name] election_defaults['name'] election_slug = self.format_election_slug( self.base_election_info, ) print('Creating:', election_defaults['name'], '...',) self.election, created = Election.objects.update_or_create( slug=election_slug, defaults=election_defaults ) if created: print('[created]') else: print('[already existed]') def add_pcc_areas(self, mapit_area_id, mapit_area_data): org_name = mapit_area_data['name'] area_type, _ = AreaType.objects.update_or_create( name=self.base_election_info['mapit_code'], defaults={'source': 'MapIt'} ) if not self.election.area_types.filter(name=area_type.name).exists(): self.election.area_types.add(area_type) area, _ = Area.objects.update_or_create( identifier=mapit.format_code_from_area(mapit_area_data), defaults={'name': mapit_area_data['name']} ) # Now make sure that the MapIt codes are present as identifiers: for scheme, identifier in mapit_area_data['codes'].items(): area.other_identifiers.update_or_create( scheme=scheme, defaults={'identifier': identifier}, ) AreaExtra.objects.get_or_create(base=area, type=area_type) post, _ = Post.objects.update_or_create( organization=self.organizations[org_name], area=area, role='Police and Crime Commissioner for {area_name}'.format( area_name=org_name ), defaults={ 'label': self.base_election_info['label_format'].format( area_name=area.name ) }) post_extra, _ = PostExtra.objects.update_or_create( base=post, defaults={ 'slug': mapit.format_code_from_area(mapit_area_data), 'party_set': self.gb_parties, }, ) PostExtra.objects.update_or_create( postextra=post_extra, election=self.election, )