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
Example #4
0
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)
Example #7
0
    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)