def handle(self, **options): all_people = [] for person_dict in popit_unwrap_pagination( self.api.persons, embed="membership.organization", per_page=100, ): if person_dict.get('standing_in') \ and person_dict['standing_in'].get(options['year']): person = PopItPerson.create_from_dict(person_dict) all_people.append(person.as_dict(year=options['year'])) csv = list_to_csv(all_people) # Write to stdout if no output filename is specified, or if it # is '-' if options['output_filename'] in (None, '-'): with sys.stdout as f: f.write(csv) else: # Otherwise write to a temporary file and atomically # rename into place: ntf = NamedTemporaryFile( delete=False, dir=dirname(options['output_filename']) ) ntf.write(csv) chmod(ntf.name, 0o644) rename(ntf.name, options['output_filename'])
def safely_write(output_filename, people, group_by_post): csv = list_to_csv(people, group_by_post) # Write to a temporary file and atomically rename into place: ntf = NamedTemporaryFile( delete=False, dir=dirname(output_filename) ) ntf.write(csv.encode('utf-8')) chmod(ntf.name, 0o644) rename(ntf.name, output_filename)
def get(self, request, *args, **kwargs): pee = self.get_object() memberships_dict, elected = memberships_dicts_for_csv( election_slug=pee.election.slug, post_slug=pee.post.slug) filename = "{ballot_paper_id}.csv".format( ballot_paper_id=pee.ballot_paper_id) response = HttpResponse(content_type="text/csv") response[ "Content-Disposition"] = 'attachment; filename="%s"' % filename response.write(list_to_csv(memberships_dict[pee.election.slug])) return response
def safely_write(output_filename, people, group_by_post): """ Use Django's storage backend to write the CSV file to the MEDIA_ROOT. If using S3 (via Django Storages) the file is atomically written when the file is closed (when the context manager closes). That is, the file can be opened and written to but nothing changes at the public S3 URL until the object is closed. Meaning it's not possible to have a half written file. If not using S3, there will be a short time where the file is empty during write. """ csv = list_to_csv(people, group_by_post) file_store = DefaultStorage() with file_store.open(output_filename, "w") as out_file: out_file.write(csv.encode("utf-8"))
def handle(self, *args, **options): if len(args) != 1: msg = "You must supply the prefix for output filenames" raise CommandError(msg) output_prefix = args[0] all_people = [] election_to_people = defaultdict(list) for person_dict in popit_unwrap_pagination( self.api.persons, embed="membership.organization", per_page=100, ): standing_in = person_dict.get('standing_in') if not standing_in: continue for election in standing_in.keys(): if not standing_in[election]: continue person = PopItPerson.create_from_dict(person_dict) person_as_csv_dict = person.as_dict(election=election) all_people.append(person_as_csv_dict) election_to_people[election].append(person_as_csv_dict) elections = election_to_people.keys() + [None] for election in elections: if election is None: output_filename = output_prefix + '-all.csv' people_data = all_people else: output_filename = output_prefix + '-' + election + '.csv' people_data = election_to_people[election] csv = list_to_csv(people_data) # Otherwise write to a temporary file and atomically # rename into place: ntf = NamedTemporaryFile( delete=False, dir=dirname(output_filename) ) ntf.write(csv) chmod(ntf.name, 0o644) rename(ntf.name, output_filename)
def handle(self, **options): if options['election']: try: all_elections = [Election.objects.get(slug=options['election'])] except Election.DoesNotExist: message = "Couldn't find an election with slug {election_slug}" raise CommandError(message.format(election_slug=options['election'])) else: all_elections = list(Election.objects.all()) + [None] people_by_election = defaultdict(list) for election in all_elections: if election is None: # Get information for every candidate in every # election. Unfortunately this may not be well # defined when mapping to CSV, since it's conceivable # that someone is standing in two different current # elections taking place on the same date. This file # is only generated so that the same files are # generated by YourNextMP - we probably shouldn't # generate it in the future. for person_extra in PersonExtra.objects.all(): elections = list(Election.objects.filter( candidacies__base__person=person_extra.base.id, candidacies__base__role=F('candidate_membership_role') ).order_by('current', 'election_date')) if not elections: continue election = elections[-1] people_by_election[None].append( person_extra.as_dict( election, base_url=options['site_base_url'] ) ) else: # This is the well-defined case - get all the # candidates for a particular election. for person_extra in PersonExtra.objects.filter( base__memberships__extra__election=election, base__memberships__role=election.candidate_membership_role ).select_related('base'): people_by_election[election.slug].append( person_extra.as_dict( election, base_url=options['site_base_url'] ) ) for election in all_elections: if election is None: output_filename = \ options['OUTPUT-PREFIX'] + '-all.csv' election_slug = None else: output_filename = \ options['OUTPUT-PREFIX'] + '-' + election.slug + '.csv' election_slug = election.slug people_data = people_by_election[election_slug] csv = list_to_csv(people_data) # Write to a temporary file and atomically rename into place: ntf = NamedTemporaryFile( delete=False, dir=dirname(output_filename) ) ntf.write(csv) chmod(ntf.name, 0o644) rename(ntf.name, output_filename)
def handle(self, **options): if options['election']: try: all_elections = [ Election.objects.get(slug=options['election']) ] except Election.DoesNotExist: message = "Couldn't find an election with slug {election_slug}" raise CommandError( message.format(election_slug=options['election'])) else: all_elections = list(Election.objects.all()) + [None] people_by_election = defaultdict(list) for election in all_elections: if election is None: # Get information for every candidate in every # election. Unfortunately this may not be well # defined when mapping to CSV, since it's conceivable # that someone is standing in two different current # elections taking place on the same date. This file # is only generated so that the same files are # generated by YourNextMP - we probably shouldn't # generate it in the future. for person_extra in PersonExtra.objects.all(): elections = list( Election.objects.filter( candidacies__base__person=person_extra.base.id, candidacies__base__role=F( 'candidate_membership_role')).order_by( 'current', 'election_date')) if not elections: continue election = elections[-1] people_by_election[None].append( person_extra.as_dict( election, base_url=options['site_base_url'])) else: # This is the well-defined case - get all the # candidates for a particular election. for person_extra in PersonExtra.objects.filter( base__memberships__extra__election=election, base__memberships__role=election. candidate_membership_role).select_related('base'): people_by_election[election.slug].append( person_extra.as_dict( election, base_url=options['site_base_url'])) for election in all_elections: if election is None: output_filename = \ options['OUTPUT-PREFIX'] + '-all.csv' election_slug = None else: output_filename = \ options['OUTPUT-PREFIX'] + '-' + election.slug + '.csv' election_slug = election.slug people_data = people_by_election[election_slug] csv = list_to_csv(people_data) # Write to a temporary file and atomically rename into place: ntf = NamedTemporaryFile(delete=False, dir=dirname(output_filename)) ntf.write(csv) chmod(ntf.name, 0o644) rename(ntf.name, output_filename)