コード例 #1
0
def get_attention_needed_posts(max_results=None, random=False):
    from candidates.election_specific import shorten_post_label
    cursor = connection.cursor()
    # This is similar to the query in ConstituencyCountsView,
    # except it's not specific to a particular election and the
    # results are ordered with fewest candidates first:
    query = '''
SELECT pe.slug, p.label, ee.name, ee.slug, count(m.id) as count
  FROM popolo_post p
    INNER JOIN candidates_postextra pe ON pe.base_id = p.id
    INNER JOIN candidates_postextra_elections cppee ON cppee.postextra_id = pe.id
    INNER JOIN elections_election ee ON cppee.election_id = ee.id
    LEFT OUTER JOIN
      (popolo_membership m
        INNER JOIN candidates_membershipextra me
        ON me.base_id = m.id)
      ON m.role = ee.candidate_membership_role AND m.post_id = p.id AND
         me.election_id = ee.id
  GROUP BY pe.slug, p.label, ee.slug, ee.name
  ORDER BY'''
    if random:
        query += ' count, random()'
    else:
        query += ' count, ee.name, p.label'
    if max_results is not None:
        query += ' LIMIT {limit}'.format(limit=max_results)
    cursor.execute(query)
    return [{
        'post_slug': row[0],
        'post_label': row[1],
        'election_name': row[2],
        'election_slug': row[3],
        'count': row[4],
        'post_short_label': shorten_post_label(row[1]),
    } for row in cursor.fetchall()]
コード例 #2
0
    def get_context_data(self, **kwargs):
        from candidates.election_specific import shorten_post_label
        context = super(ConstituencyCountsView, self).get_context_data(**kwargs)
        cursor = connection.cursor()
        cursor.execute('''
SELECT pe.slug, p.label, count(m.id) as count
  FROM popolo_post p
    INNER JOIN candidates_postextra pe ON pe.base_id = p.id
    INNER JOIN candidates_postextraelection cppee ON cppee.postextra_id = pe.id
    INNER JOIN elections_election ee ON cppee.election_id = ee.id AND ee.id = %s
    LEFT OUTER JOIN
      (popolo_membership m
        INNER JOIN candidates_membershipextra me
        ON me.base_id = m.id)
      ON m.role = ee.candidate_membership_role AND m.post_id = p.id AND
         me.election_id = ee.id
  GROUP BY pe.slug, p.label
  ORDER BY count DESC;
        ''', [self.election_data.id])
        context['post_counts'] = [
            {
                'post_slug': row[0],
                'post_label': row[1],
                'count': row[2],
                'post_short_label': shorten_post_label(row[1]),
            }
            for row in cursor.fetchall()
        ]
        return context
コード例 #3
0
    def get_context_data(self, **kwargs):
        from candidates.election_specific import shorten_post_label
        context = super(ConstituencyCountsView, self).get_context_data(**kwargs)
        cursor = connection.cursor()
        cursor.execute('''
SELECT pe.slug, p.label, count(m.id) as count
  FROM popolo_post p
    INNER JOIN candidates_postextra pe ON pe.base_id = p.id
    INNER JOIN candidates_postextraelection cppee ON cppee.postextra_id = pe.id
    INNER JOIN elections_election ee ON cppee.election_id = ee.id AND ee.id = %s
    LEFT OUTER JOIN
      (popolo_membership m
        INNER JOIN candidates_membershipextra me
        ON me.base_id = m.id)
      ON m.role = ee.candidate_membership_role AND m.post_id = p.id AND
         me.election_id = ee.id
  GROUP BY pe.slug, p.label
  ORDER BY count DESC;
        ''', [self.election_data.id])
        context['post_counts'] = [
            {
                'post_slug': row[0],
                'post_label': row[1],
                'count': row[2],
                'post_short_label': shorten_post_label(row[1]),
            }
            for row in cursor.fetchall()
        ]
        return context
コード例 #4
0
def get_person_as_version_data(person):
    from candidates.election_specific import shorten_post_label
    result = {}
    person_extra = person.extra
    result['id'] = str(person.id)
    for field, null_value in form_simple_fields.items():
        result[field] = getattr(person, field) or null_value
    for field in form_complex_fields_locations:
        result[field] = getattr(person_extra, field)
    result['other_names'] = [
        {
            'name': on.name,
            'note': on.note,
            'start_date': on.start_date,
            'end_date': on.end_date,
        }
        for on in person.other_names.all()
    ]
    identifiers = list(person.identifiers.all())
    if identifiers:
        result['identifiers'] = [
            {
                'scheme': i.scheme,
                'identifier': i.identifier,
            }
            for i in identifiers
        ]
    result['image'] = person.image
    standing_in = {}
    party_memberships = {}
    for membership in person.memberships.filter(post__isnull=False):
        from candidates.models import MembershipExtra
        post = membership.post
        try:
            membership_extra = membership.extra
        except MembershipExtra.DoesNotExist:
            continue
        election = membership_extra.election
        standing_in[election.slug] = {
            'post_id': post.extra.slug,
            'name': shorten_post_label(post.label)
        }
        if membership_extra.elected is not None:
            standing_in[election.slug]['elected'] = membership_extra.elected
        if membership_extra.party_list_position is not None:
            standing_in[election.slug]['party_list_position'] = \
                membership_extra.party_list_position
        party = membership.on_behalf_of
        party_memberships[election.slug] = {
            'id': party.extra.slug,
            'name': party.name,
        }
    for not_standing_in_election in person_extra.not_standing.all():
        standing_in[not_standing_in_election.slug] = None
    result['standing_in'] = standing_in
    result['party_memberships'] = party_memberships
    return result
コード例 #5
0
    def add_election_fields(self, election_data):
        from candidates.election_specific import shorten_post_label

        election = election_data.slug
        self.fields["standing_" + election] = forms.ChoiceField(
            label=_("Standing in %s") % election_data.name,
            choices=BasePersonForm.STANDING_CHOICES,
            widget=forms.Select(attrs={"class": "standing-select"}),
        )
        self.fields["constituency_" + election] = forms.ChoiceField(
            label=_("Constituency in %s") % election_data.name,
            required=False,
            choices=[("", "")]
            + sorted(
                [
                    (post.slug, shorten_post_label(post.label))
                    for post in Post.objects.filter(elections__slug=election)
                ],
                key=lambda t: t[1],
            ),
            widget=forms.Select(attrs={"class": "post-select"}),
        )
        for party_set, party_choices in self.party_sets_and_party_choices:
            self.fields[
                "party_" + party_set.slug.upper() + "_" + election
            ] = forms.ChoiceField(
                label=_("Party in {election} ({party_set_name})").format(
                    election=election_data.name, party_set_name=party_set.name
                ),
                choices=party_choices,
                required=False,
                widget=forms.Select(
                    attrs={"class": "party-select party-select-" + election}
                ),
            )
            if election_data.party_lists_in_use:
                # Then add a field to enter the position on the party list
                # as an integer:
                field_name = (
                    "party_list_position_"
                    + party_set.slug.upper()
                    + "_"
                    + election
                )
                self.fields[field_name] = forms.IntegerField(
                    label=_(
                        "Position in party list ('1' for first, '2' for second, etc.)"
                    ),
                    min_value=1,
                    required=False,
                    widget=forms.NumberInput(
                        attrs={
                            "class": "party-position party-position-" + election
                        }
                    ),
                )
コード例 #6
0
def get_person_as_version_data(person):
    from candidates.election_specific import shorten_post_label
    result = {}
    person_extra = person.extra
    result['id'] = str(person.id)
    for field, null_value in form_simple_fields.items():
        result[field] = getattr(person, field) or null_value
    for field in form_complex_fields_locations:
        result[field] = getattr(person_extra, field)
    result['other_names'] = [{
        'name': on.name,
        'note': on.note,
        'start_date': on.start_date,
        'end_date': on.end_date,
    } for on in person.other_names.all()]
    identifiers = list(person.identifiers.all())
    if identifiers:
        result['identifiers'] = [{
            'scheme': i.scheme,
            'identifier': i.identifier,
        } for i in identifiers]
    result['image'] = person.image
    standing_in = {}
    party_memberships = {}
    for membership in person.memberships.filter(post__isnull=False):
        from candidates.models import MembershipExtra
        post = membership.post
        try:
            membership_extra = membership.extra
        except MembershipExtra.DoesNotExist:
            continue
        election = membership_extra.election
        standing_in[election.slug] = {
            'post_id': post.extra.slug,
            'name': shorten_post_label(post.label)
        }
        if membership_extra.elected is not None:
            standing_in[election.slug]['elected'] = membership_extra.elected
        if membership_extra.party_list_position is not None:
            standing_in[election.slug]['party_list_position'] = \
                membership_extra.party_list_position
        party = membership.on_behalf_of
        party_memberships[election.slug] = {
            'id': party.extra.slug,
            'name': party.name,
        }
    for not_standing_in_election in person_extra.not_standing.all():
        standing_in[not_standing_in_election.slug] = None
    result['standing_in'] = standing_in
    result['party_memberships'] = party_memberships
    return result
コード例 #7
0
def get_attention_needed_posts(max_results=None, random=False):
    from candidates.election_specific import shorten_post_label
    cursor = connection.cursor()
    # This is similar to the query in ConstituencyCountsView,
    # except it's not specific to a particular election and the
    # results are ordered with fewest candidates first:
    query = '''
SELECT pe.slug, p.label, ee.name, ee.slug, count(m.id) as count
  FROM popolo_post p
    INNER JOIN candidates_postextra pe ON pe.base_id = p.id
    INNER JOIN candidates_postextraelection cppee ON cppee.postextra_id = pe.id
    INNER JOIN elections_election ee ON cppee.election_id = ee.id
    LEFT OUTER JOIN
      (popolo_membership m
        INNER JOIN candidates_membershipextra me
        ON me.base_id = m.id)
      ON m.role = ee.candidate_membership_role AND m.post_id = p.id AND
         me.election_id = ee.id
    WHERE ee.current = TRUE
  GROUP BY pe.slug, p.label, ee.slug, ee.name
  ORDER BY'''
    if random:
        query += ' count, random()'
    else:
        query += ' count, ee.name, p.label'
    if max_results is not None:
        query += ' LIMIT {limit}'.format(limit=max_results)
    cursor.execute(query)
    return [
        {
            'post_slug': row[0],
            'post_label': row[1],
            'election_name': row[2],
            'election_slug': row[3],
            'count': row[4],
            'post_short_label': shorten_post_label(row[1]),
        }
        for row in cursor.fetchall()
    ]
コード例 #8
0
    def get_context_data(self, **kwargs):
        from candidates.election_specific import shorten_post_label

        context = super().get_context_data(**kwargs)

        context["post_election"] = get_object_or_404(
            PostExtraElection.objects.all().select_related("post", "election"),
            ballot_paper_id=context["election"],
        )

        mp_post = context["post_election"].post
        context["election"] = election = context["post_election"].election
        context["post_id"] = post_id = mp_post.slug
        context["post_obj"] = mp_post

        documents_by_type = {}
        # Make sure that every available document type has a key in
        # the dictionary, even if there are no such documents.
        doc_lookup = {
            t[0]: (t[1], t[2])
            for t in OfficialDocument.DOCUMENT_TYPES
        }
        for t in doc_lookup.values():
            documents_by_type[t] = []
        documents_for_post = OfficialDocument.objects.filter(
            post_election=context["post_election"])
        for od in documents_for_post:
            documents_by_type[doc_lookup[od.document_type]].append(od)
        context["official_documents"] = documents_by_type.items()
        context["some_official_documents"] = documents_for_post.count()

        context["post_label"] = mp_post.label
        context["post_label_shorter"] = shorten_post_label(
            context["post_label"])

        context["redirect_after_login"] = context[
            "post_election"].get_absolute_url()

        context["post_data"] = {"id": mp_post.slug, "label": mp_post.label}

        pee = context["post_election"]

        context["candidates_locked"] = pee.candidates_locked

        context["has_lock_suggestion"] = SuggestedPostLock.objects.filter(
            postextraelection=pee).exists()

        if self.request.user.is_authenticated:
            context[
                "current_user_suggested_lock"] = SuggestedPostLock.objects.filter(
                    user=self.request.user, postextraelection=pee).exists()

        context["suggest_lock_form"] = SuggestedPostLockForm(
            initial={"postextraelection": pee})

        if self.request.user.is_authenticated:
            context[
                "user_has_suggested_lock"] = SuggestedPostLock.objects.filter(
                    user=self.request.user, postextraelection=pee).exists()

        context["lock_form"] = ToggleLockForm(
            initial={
                "post_id": post_id,
                "lock": not context["candidates_locked"],
            })

        context["candidate_list_edits_allowed"] = get_edits_allowed(
            self.request.user, context["candidates_locked"])

        extra_qs = Membership.objects.select_related("post_election__election")
        current_candidacies, past_candidacies = split_candidacies(
            election,
            mp_post.memberships.select_related("person", "party").all(),
        )

        area_2015_map = {
            "WMC:E14000824": "65693",
            "WMC:E14000825": "65633",
            "WMC:E14000826": "65735",
            "WMC:E14000827": "65556",
            "WMC:E14000820": "65657",
            "WMC:E14000821": "65953",
            "WMC:E14000822": "66076",
            "WMC:E14000823": "66038",
            "WMC:E14000828": "65815",
            "WMC:E14000829": "65696",
            "WMC:E14000948": "65829",
            "WMC:E14000543": "66006",
            "WMC:E14000810": "65647",
            "WMC:E14000813": "65718",
            "WMC:E14000540": "65662",
            "WMC:E14000699": "65857",
            "WMC:E14000751": "66069",
            "WMC:E14000546": "65711",
            "WMC:S14000048": "14445",
            "WMC:S14000049": "14446",
            "WMC:E14000912": "65889",
            "WMC:E14000913": "65891",
            "WMC:E14000914": "66027",
            "WMC:E14000915": "65763",
            "WMC:E14000916": "65706",
            "WMC:E14000917": "65842",
            "WMC:S14000040": "14436",
            "WMC:S14000041": "14437",
            "WMC:S14000042": "14438",
            "WMC:S14000043": "14439",
            "WMC:S14000044": "14440",
            "WMC:S14000045": "14441",
            "WMC:S14000046": "14442",
            "WMC:S14000047": "14443",
            "WMC:E14000727": "65576",
            "WMC:E14000726": "65836",
            "WMC:E14000725": "65915",
            "WMC:E14000724": "65671",
            "WMC:E14000723": "65599",
            "WMC:E14000649": "65636",
            "WMC:E14000721": "65752",
            "WMC:E14000720": "65550",
            "WMC:E14000644": "65926",
            "WMC:E14000645": "65835",
            "WMC:E14000646": "65771",
            "WMC:E14000690": "65816",
            "WMC:E14000640": "65734",
            "WMC:W07000063": "66111",
            "WMC:E14000642": "66030",
            "WMC:E14000643": "66057",
            "WMC:E14001034": "65629",
            "WMC:E14001035": "65758",
            "WMC:E14001036": "65851",
            "WMC:E14001037": "65963",
            "WMC:E14001030": "66047",
            "WMC:E14001031": "65716",
            "WMC:E14001032": "66058",
            "WMC:E14001033": "65873",
            "WMC:E14000544": "65898",
            "WMC:E14001038": "65742",
            "WMC:E14001039": "65612",
            "WMC:E14000965": "66067",
            "WMC:E14000964": "65854",
            "WMC:E14000967": "65960",
            "WMC:E14000966": "65907",
            "WMC:S14000039": "14435",
            "WMC:S14000038": "14434",
            "WMC:E14000963": "65732",
            "WMC:E14000962": "66073",
            "WMC:S14000035": "14431",
            "WMC:S14000034": "14430",
            "WMC:S14000037": "14433",
            "WMC:S14000036": "14432",
            "WMC:E14000969": "65606",
            "WMC:E14000968": "65571",
            "WMC:S14000033": "14429",
            "WMC:S14000032": "14428",
            "WMC:E14000639": "65759",
            "WMC:E14000731": "65650",
            "WMC:W07000072": "66093",
            "WMC:E14000868": "65663",
            "WMC:E14000869": "65653",
            "WMC:W07000077": "66097",
            "WMC:W07000049": "66101",
            "WMC:E14000860": "65822",
            "WMC:E14000861": "66059",
            "WMC:E14000862": "65910",
            "WMC:E14000863": "65768",
            "WMC:E14000864": "65634",
            "WMC:E14000865": "65559",
            "WMC:E14000866": "65643",
            "WMC:E14000867": "65945",
            "WMC:W07000062": "66121",
            "WMC:E14000631": "65801",
            "WMC:N06000006": "66129",
            "WMC:N06000007": "66130",
            "WMC:W07000066": "66109",
            "WMC:N06000001": "66124",
            "WMC:N06000002": "66125",
            "WMC:N06000003": "66126",
            "WMC:W07000068": "66088",
            "WMC:W07000069": "66082",
            "WMC:N06000008": "66131",
            "WMC:N06000009": "66132",
            "WMC:E14000819": "65998",
            "WMC:E14000818": "65888",
            "WMC:E14000549": "65731",
            "WMC:E14000548": "65751",
            "WMC:E14000547": "65798",
            "WMC:E14000814": "66007",
            "WMC:E14000545": "65623",
            "WMC:E14000816": "65949",
            "WMC:E14000811": "65772",
            "WMC:E14000542": "66012",
            "WMC:E14000541": "65665",
            "WMC:E14000812": "65932",
            "WMC:E14000600": "66009",
            "WMC:E14000601": "66031",
            "WMC:E14000602": "65574",
            "WMC:E14000603": "65852",
            "WMC:E14000604": "65954",
            "WMC:E14000605": "65617",
            "WMC:E14000606": "65639",
            "WMC:E14000607": "65849",
            "WMC:E14000608": "65909",
            "WMC:E14000609": "65846",
            "WMC:E14000929": "65920",
            "WMC:E14000928": "65986",
            "WMC:E14000921": "65601",
            "WMC:E14000920": "65793",
            "WMC:E14000923": "65549",
            "WMC:E14000654": "65603",
            "WMC:E14000925": "65959",
            "WMC:E14000924": "65632",
            "WMC:E14000927": "65610",
            "WMC:E14000926": "65563",
            "WMC:E14000778": "65941",
            "WMC:E14000779": "65866",
            "WMC:E14000774": "66053",
            "WMC:E14000775": "65869",
            "WMC:E14000776": "65568",
            "WMC:E14000777": "65765",
            "WMC:E14000770": "65778",
            "WMC:E14000771": "65709",
            "WMC:E14000772": "65618",
            "WMC:E14000773": "65984",
            "WMC:E14000675": "65701",
            "WMC:E14000674": "65755",
            "WMC:E14000677": "65823",
            "WMC:E14000676": "65794",
            "WMC:E14000671": "65806",
            "WMC:E14000670": "65555",
            "WMC:E14000673": "65808",
            "WMC:E14000672": "66054",
            "WMC:E14000679": "65573",
            "WMC:E14000678": "65813",
            "WMC:E14001009": "65733",
            "WMC:E14001008": "65825",
            "WMC:E14001005": "65782",
            "WMC:E14001004": "65660",
            "WMC:E14001007": "65613",
            "WMC:E14001006": "65868",
            "WMC:E14001001": "65810",
            "WMC:E14001000": "65904",
            "WMC:E14001003": "65659",
            "WMC:E14001002": "66074",
            "WMC:E14000733": "65990",
            "WMC:E14000781": "65988",
            "WMC:E14000780": "66068",
            "WMC:E14000783": "65604",
            "WMC:E14000782": "65807",
            "WMC:E14000785": "65978",
            "WMC:E14000784": "65587",
            "WMC:E14000787": "65705",
            "WMC:E14000786": "66020",
            "WMC:E14000789": "66041",
            "WMC:E14000788": "65616",
            "WMC:E14000851": "65760",
            "WMC:E14000850": "65817",
            "WMC:E14000581": "65821",
            "WMC:E14000580": "65738",
            "WMC:E14000587": "65694",
            "WMC:E14000586": "65697",
            "WMC:E14000585": "65933",
            "WMC:E14000856": "65859",
            "WMC:E14000859": "65713",
            "WMC:E14000858": "65776",
            "WMC:E14000589": "66036",
            "WMC:E14000588": "65995",
            "WMC:S14000028": "14424",
            "WMC:S14000029": "14425",
            "WMC:S14000020": "14417",
            "WMC:S14000021": "14418",
            "WMC:E14000922": "65741",
            "WMC:E14000739": "65967",
            "WMC:E14000730": "65578",
            "WMC:E14000638": "65885",
            "WMC:E14000732": "65796",
            "WMC:E14000746": "65850",
            "WMC:E14000734": "65674",
            "WMC:E14000735": "65640",
            "WMC:E14000736": "65699",
            "WMC:E14000737": "65912",
            "WMC:E14000738": "65557",
            "WMC:E14000630": "65946",
            "WMC:E14000633": "65558",
            "WMC:E14000632": "65980",
            "WMC:E14000635": "65940",
            "WMC:E14000634": "65721",
            "WMC:E14000637": "65792",
            "WMC:E14000636": "65886",
            "WMC:E14001041": "65921",
            "WMC:E14001040": "65827",
            "WMC:E14001043": "65847",
            "WMC:E14001042": "65552",
            "WMC:E14001045": "65831",
            "WMC:E14001044": "65897",
            "WMC:E14001047": "66039",
            "WMC:E14001046": "65622",
            "WMC:E14001049": "65777",
            "WMC:E14001048": "65774",
            "WMC:E14000910": "65654",
            "WMC:E14000911": "65688",
            "WMC:E14000976": "65609",
            "WMC:E14000977": "65648",
            "WMC:E14000974": "65770",
            "WMC:E14000975": "65950",
            "WMC:E14000972": "65710",
            "WMC:E14000973": "65783",
            "WMC:E14000970": "65641",
            "WMC:E14000971": "65908",
            "WMC:S14000026": "14423",
            "WMC:S14000027": "14444",
            "WMC:S14000024": "14421",
            "WMC:S14000025": "14422",
            "WMC:S14000022": "14419",
            "WMC:S14000023": "14420",
            "WMC:E14000978": "66042",
            "WMC:E14000979": "65911",
            "WMC:E14000745": "65994",
            "WMC:E14000744": "66003",
            "WMC:E14000747": "65814",
            "WMC:E14000830": "65862",
            "WMC:E14000741": "65754",
            "WMC:E14000740": "66018",
            "WMC:E14000743": "65582",
            "WMC:E14000742": "65786",
            "WMC:E14000749": "65724",
            "WMC:E14000748": "66052",
            "WMC:E14000918": "65698",
            "WMC:E14000919": "65957",
            "WMC:E14000895": "65722",
            "WMC:E14000894": "65579",
            "WMC:E14000897": "65843",
            "WMC:E14000896": "65598",
            "WMC:E14000891": "66032",
            "WMC:E14000890": "65982",
            "WMC:E14000893": "66005",
            "WMC:E14000892": "65700",
            "WMC:W07000057": "66108",
            "WMC:W07000056": "66099",
            "WMC:W07000055": "66094",
            "WMC:W07000054": "66084",
            "WMC:E14000899": "65584",
            "WMC:E14000898": "66043",
            "WMC:W07000051": "66120",
            "WMC:W07000050": "66090",
            "WMC:E14000648": "65590",
            "WMC:E14000722": "65971",
            "WMC:E14000558": "65611",
            "WMC:E14000559": "65581",
            "WMC:E14000808": "65834",
            "WMC:E14000809": "65819",
            "WMC:E14000806": "65661",
            "WMC:E14000807": "66048",
            "WMC:E14000804": "65936",
            "WMC:E14000553": "65689",
            "WMC:E14000554": "65726",
            "WMC:E14000803": "65901",
            "WMC:E14000556": "65934",
            "WMC:E14000801": "66080",
            "WMC:E14000647": "65893",
            "WMC:W07000059": "66100",
            "WMC:W07000058": "66085",
            "WMC:E14000641": "66021",
            "WMC:E14000729": "65875",
            "WMC:E14000728": "65675",
            "WMC:E14000949": "65848",
            "WMC:W07000053": "66104",
            "WMC:W07000052": "66092",
            "WMC:E14000758": "65899",
            "WMC:E14000652": "65781",
            "WMC:E14000938": "65684",
            "WMC:E14000939": "66051",
            "WMC:E14000932": "65812",
            "WMC:E14000933": "65962",
            "WMC:E14000930": "65680",
            "WMC:E14000931": "65879",
            "WMC:E14000936": "65788",
            "WMC:E14000937": "65997",
            "WMC:E14000934": "65922",
            "WMC:E14000935": "65762",
            "WMC:E14000709": "65870",
            "WMC:E14000708": "65900",
            "WMC:E14000701": "65655",
            "WMC:E14000700": "65764",
            "WMC:E14000703": "65938",
            "WMC:E14000702": "65865",
            "WMC:E14000705": "66064",
            "WMC:E14000704": "65779",
            "WMC:E14000707": "65952",
            "WMC:E14000706": "65955",
            "WMC:E14000666": "65746",
            "WMC:E14000667": "65553",
            "WMC:E14000664": "65799",
            "WMC:E14000665": "65723",
            "WMC:E14000662": "66070",
            "WMC:E14000663": "65863",
            "WMC:E14000660": "66025",
            "WMC:E14000661": "65924",
            "WMC:E14000668": "65621",
            "WMC:E14000669": "65672",
            "WMC:E14001018": "65916",
            "WMC:E14001019": "65608",
            "WMC:E14001016": "66079",
            "WMC:E14001017": "65874",
            "WMC:E14001014": "65631",
            "WMC:E14001015": "65638",
            "WMC:E14001012": "65832",
            "WMC:E14001013": "65651",
            "WMC:E14001010": "65635",
            "WMC:E14001011": "65890",
            "WMC:W07000061": "66096",
            "WMC:E14000989": "65992",
            "WMC:E14000988": "65767",
            "WMC:E14000987": "65964",
            "WMC:E14000986": "65880",
            "WMC:E14000985": "65703",
            "WMC:E14000984": "66040",
            "WMC:E14000983": "65747",
            "WMC:E14000982": "65586",
            "WMC:E14000981": "65607",
            "WMC:E14000980": "65858",
            "WMC:E14000815": "66061",
            "WMC:E14000792": "65704",
            "WMC:E14000793": "66066",
            "WMC:E14000790": "66013",
            "WMC:E14000791": "66046",
            "WMC:E14000796": "65766",
            "WMC:E14000797": "65785",
            "WMC:E14000794": "65970",
            "WMC:E14000795": "65644",
            "WMC:E14000798": "65987",
            "WMC:E14000799": "65690",
            "WMC:E14000598": "65787",
            "WMC:E14000599": "65839",
            "WMC:E14000594": "65685",
            "WMC:E14000595": "65620",
            "WMC:E14000596": "66000",
            "WMC:E14000597": "65844",
            "WMC:E14000590": "65670",
            "WMC:E14000591": "66065",
            "WMC:E14000592": "65595",
            "WMC:E14000593": "65958",
            "WMC:E14000842": "66063",
            "WMC:E14000843": "65676",
            "WMC:E14000840": "65745",
            "WMC:E14000841": "65855",
            "WMC:E14000846": "65619",
            "WMC:E14000847": "65642",
            "WMC:E14000844": "65729",
            "WMC:E14000845": "65840",
            "WMC:E14000848": "65872",
            "WMC:E14000849": "66017",
            "WMC:E14000817": "65999",
            "WMC:E14000561": "65667",
            "WMC:E14000560": "65931",
            "WMC:E14000563": "66072",
            "WMC:E14000562": "65597",
            "WMC:E14000565": "65966",
            "WMC:E14000564": "65989",
            "WMC:E14000567": "65804",
            "WMC:E14000566": "66028",
            "WMC:E14000569": "65820",
            "WMC:E14000568": "65707",
            "WMC:E14000961": "65591",
            "WMC:E14000960": "65715",
            "WMC:E14000628": "65797",
            "WMC:E14000629": "65818",
            "WMC:E14000622": "65914",
            "WMC:E14000623": "65749",
            "WMC:E14000620": "65929",
            "WMC:E14000621": "65972",
            "WMC:E14000626": "66075",
            "WMC:E14000627": "65727",
            "WMC:E14000624": "65748",
            "WMC:E14000625": "65615",
            "WMC:S14000031": "14427",
            "WMC:S14000030": "14426",
            "WMC:E14001052": "65577",
            "WMC:E14001053": "65625",
            "WMC:E14001050": "65593",
            "WMC:E14001051": "65948",
            "WMC:E14001056": "66010",
            "WMC:E14001057": "65695",
            "WMC:E14001054": "65757",
            "WMC:E14001055": "65562",
            "WMC:E14001058": "66078",
            "WMC:E14001059": "65669",
            "WMC:E14000943": "65951",
            "WMC:E14000942": "65902",
            "WMC:E14000941": "65666",
            "WMC:E14000940": "66034",
            "WMC:E14000947": "65800",
            "WMC:E14000946": "65614",
            "WMC:E14000945": "65943",
            "WMC:E14000944": "65719",
            "WMC:S14000013": "14410",
            "WMC:S14000012": "14409",
            "WMC:S14000011": "14408",
            "WMC:S14000010": "14407",
            "WMC:S14000017": "14414",
            "WMC:S14000016": "14413",
            "WMC:S14000015": "14412",
            "WMC:S14000014": "14411",
            "WMC:E14000756": "65624",
            "WMC:E14000757": "65592",
            "WMC:E14000754": "65947",
            "WMC:E14000755": "65691",
            "WMC:E14000752": "65883",
            "WMC:E14000753": "65717",
            "WMC:E14000750": "65824",
            "WMC:E14000698": "66033",
            "WMC:E14000697": "66062",
            "WMC:E14000696": "66023",
            "WMC:E14000695": "65743",
            "WMC:E14000694": "65803",
            "WMC:E14000693": "66044",
            "WMC:E14000692": "65567",
            "WMC:E14000691": "66050",
            "WMC:E14000759": "65630",
            "WMC:E14000886": "65637",
            "WMC:E14000887": "66045",
            "WMC:E14000884": "66014",
            "WMC:E14000885": "65673",
            "WMC:E14000882": "65917",
            "WMC:E14000883": "65566",
            "WMC:E14000880": "65737",
            "WMC:E14000881": "65860",
            "WMC:W07000041": "66115",
            "WMC:W07000042": "66112",
            "WMC:W07000043": "66103",
            "WMC:W07000044": "66113",
            "WMC:W07000045": "66117",
            "WMC:E14000888": "65795",
            "WMC:E14000889": "65973",
            "WMC:E14000550": "65687",
            "WMC:E14000551": "65725",
            "WMC:E14000552": "65561",
            "WMC:E14000805": "65645",
            "WMC:E14000901": "65884",
            "WMC:E14000802": "65896",
            "WMC:E14000900": "66077",
            "WMC:E14000555": "65853",
            "WMC:E14000800": "65887",
            "WMC:E14000557": "65845",
            "WMC:E14000688": "65991",
            "WMC:E14000689": "65677",
            "WMC:E14000839": "65702",
            "WMC:E14000838": "65658",
            "WMC:S14000051": "14448",
            "WMC:E14000833": "65664",
            "WMC:E14000832": "65594",
            "WMC:E14000831": "66055",
            "WMC:E14000908": "65736",
            "WMC:E14000837": "65602",
            "WMC:E14000836": "65918",
            "WMC:E14000835": "65828",
            "WMC:E14000834": "65861",
            "WMC:E14000583": "66071",
            "WMC:E14000582": "65969",
            "WMC:E14000853": "65720",
            "WMC:E14000852": "65605",
            "WMC:E14000855": "65565",
            "WMC:W07000048": "66091",
            "WMC:E14000682": "65780",
            "WMC:E14000854": "66024",
            "WMC:E14000683": "65979",
            "WMC:E14000857": "65894",
            "WMC:E14000584": "65993",
            "WMC:E14000538": "65739",
            "WMC:E14000539": "66008",
            "WMC:E14000536": "65811",
            "WMC:E14000537": "66056",
            "WMC:E14000534": "65784",
            "WMC:E14000535": "65895",
            "WMC:E14000532": "65892",
            "WMC:E14000533": "65809",
            "WMC:E14000530": "65730",
            "WMC:E14000531": "65773",
            "WMC:E14000907": "65589",
            "WMC:E14000906": "65681",
            "WMC:E14000905": "65656",
            "WMC:E14000904": "66029",
            "WMC:E14000903": "65930",
            "WMC:E14000902": "66019",
            "WMC:S14000059": "14456",
            "WMC:S14000058": "14455",
            "WMC:S14000057": "14454",
            "WMC:S14000056": "14453",
            "WMC:S14000055": "14452",
            "WMC:S14000054": "14451",
            "WMC:S14000053": "14450",
            "WMC:S14000052": "14449",
            "WMC:E14000909": "65833",
            "WMC:S14000050": "14447",
            "WMC:E14000718": "65837",
            "WMC:E14000719": "65838",
            "WMC:E14000712": "65996",
            "WMC:E14000713": "65928",
            "WMC:E14000710": "65551",
            "WMC:E14000711": "65864",
            "WMC:E14000716": "65600",
            "WMC:E14000717": "65627",
            "WMC:E14000714": "65683",
            "WMC:E14000715": "65944",
            "WMC:E14000653": "65572",
            "WMC:N06000004": "66127",
            "WMC:E14000651": "65877",
            "WMC:E14000650": "65575",
            "WMC:E14000657": "65985",
            "WMC:E14000656": "65923",
            "WMC:E14000655": "65867",
            "WMC:N06000005": "66128",
            "WMC:E14000659": "66011",
            "WMC:E14000658": "65802",
            "WMC:W07000060": "66116",
            "WMC:E14001029": "65983",
            "WMC:E14001028": "65588",
            "WMC:E14001023": "65961",
            "WMC:E14001022": "66004",
            "WMC:E14001021": "65626",
            "WMC:E14001020": "66049",
            "WMC:E14001027": "65740",
            "WMC:E14001026": "65560",
            "WMC:E14001025": "65830",
            "WMC:W07000067": "66089",
            "WMC:W07000064": "66110",
            "WMC:W07000065": "66102",
            "WMC:E14000998": "65554",
            "WMC:E14000999": "65692",
            "WMC:E14000990": "65976",
            "WMC:E14000991": "65789",
            "WMC:E14000992": "65977",
            "WMC:E14000993": "65686",
            "WMC:E14000994": "65905",
            "WMC:E14000995": "65919",
            "WMC:E14000996": "65761",
            "WMC:E14000997": "65744",
            "WMC:E14000879": "65974",
            "WMC:E14000878": "65649",
            "WMC:E14000877": "66081",
            "WMC:E14000876": "66002",
            "WMC:E14000875": "65668",
            "WMC:E14000874": "65564",
            "WMC:E14000873": "66060",
            "WMC:E14000872": "65682",
            "WMC:E14000871": "66022",
            "WMC:E14000870": "65903",
            "WMC:W07000071": "66086",
            "WMC:W07000070": "66105",
            "WMC:W07000073": "66095",
            "WMC:N06000018": "66141",
            "WMC:W07000075": "66087",
            "WMC:W07000074": "66107",
            "WMC:W07000046": "66083",
            "WMC:W07000076": "66106",
            "WMC:N06000013": "66136",
            "WMC:N06000012": "66135",
            "WMC:N06000011": "66134",
            "WMC:N06000010": "66133",
            "WMC:N06000017": "66140",
            "WMC:N06000016": "66139",
            "WMC:N06000015": "66138",
            "WMC:N06000014": "66137",
            "WMC:W07000047": "66118",
            "WMC:E14001024": "65769",
            "WMC:W07000080": "66119",
            "WMC:E14000572": "65750",
            "WMC:E14000573": "65679",
            "WMC:E14000570": "65981",
            "WMC:E14000571": "65583",
            "WMC:E14000576": "65841",
            "WMC:E14000577": "65628",
            "WMC:E14000574": "65805",
            "WMC:E14000575": "65753",
            "WMC:E14000578": "65646",
            "WMC:E14000579": "65712",
            "WMC:W07000079": "66114",
            "WMC:E14000617": "65927",
            "WMC:E14000616": "65826",
            "WMC:E14000615": "65913",
            "WMC:E14000614": "65906",
            "WMC:E14000613": "66035",
            "WMC:E14000612": "65975",
            "WMC:E14000611": "66015",
            "WMC:E14000610": "65708",
            "WMC:E14000619": "65878",
            "WMC:E14000618": "65790",
            "WMC:W07000078": "66098",
            "WMC:E14001062": "66037",
            "WMC:E14001061": "65965",
            "WMC:E14001060": "65935",
            "WMC:E14000958": "65728",
            "WMC:E14000959": "65942",
            "WMC:E14000954": "65956",
            "WMC:E14000955": "66016",
            "WMC:E14000956": "65580",
            "WMC:E14000957": "65876",
            "WMC:E14000950": "65775",
            "WMC:E14000951": "65596",
            "WMC:E14000952": "65652",
            "WMC:E14000953": "65678",
            "WMC:S14000004": "14401",
            "WMC:S14000005": "14402",
            "WMC:S14000006": "14403",
            "WMC:S14000007": "14404",
            "WMC:S14000001": "14398",
            "WMC:S14000002": "14399",
            "WMC:S14000003": "14400",
            "WMC:S14000008": "14405",
            "WMC:S14000009": "14406",
            "WMC:E14000763": "65937",
            "WMC:E14000762": "65791",
            "WMC:E14000761": "65925",
            "WMC:E14000760": "65585",
            "WMC:E14000767": "65968",
            "WMC:E14000766": "65871",
            "WMC:E14000765": "66026",
            "WMC:E14000764": "65882",
            "WMC:E14000680": "65569",
            "WMC:E14000681": "65856",
            "WMC:E14000769": "66001",
            "WMC:E14000768": "65939",
            "WMC:E14000684": "65714",
            "WMC:E14000685": "65881",
            "WMC:E14000686": "65756",
            "WMC:E14000687": "65570",
            "WMC:S14000019": "14416",
            "WMC:S14000018": "14415",
        }
        # HACK
        slug = area_2015_map.get(mp_post.slug)
        current_candidacies_2015 = set()
        past_candidacies_2015 = set()
        if slug:
            other_post = Post.objects.get(slug=slug)
            current_candidacies_2015, past_candidacies_2015 = split_candidacies(
                election,
                other_post.memberships.select_related(
                    "person",
                    "party").filter(post_election__election__slug="2015"),
            )

        # HACK

        past_candidacies = past_candidacies.union(past_candidacies_2015)

        current_candidates = {c.person for c in current_candidacies}
        past_candidates = {c.person for c in past_candidacies}

        current_candidates = current_candidates.union(
            {c.person
             for c in current_candidacies_2015})
        past_candidates = past_candidates.union(
            {c.person
             for c in past_candidacies_2015})

        other_candidates = past_candidates - current_candidates

        elected, unelected = split_by_elected(election, current_candidacies)

        # Now split those candidates into those that we know aren't
        # standing again, and those that we just don't know about.
        not_standing_candidates = {
            p
            for p in other_candidates if election in p.not_standing.all()
        }
        might_stand_candidates = {
            p
            for p in other_candidates if election not in p.not_standing.all()
        }
        might_stand_candidates = {
            p
            for p in might_stand_candidates if p.death_date == ""
        }

        not_standing_candidacies = [
            c for c in past_candidacies if c.person in not_standing_candidates
        ]
        might_stand_candidacies = [
            c for c in past_candidacies if c.person in might_stand_candidates
        ]

        context["candidacies_not_standing_again"] = group_candidates_by_party(
            election, not_standing_candidacies)

        context["candidacies_might_stand_again"] = group_candidates_by_party(
            election, might_stand_candidacies)

        context["elected"] = group_candidates_by_party(election,
                                                       elected,
                                                       show_all=True)

        context["unelected"] = group_candidates_by_party(election, unelected)

        context["has_elected"] = (len(context["elected"]["parties_and_people"])
                                  > 0)

        context["show_retract_result"] = False
        number_of_winners = 0
        for c in current_candidacies:
            if c.elected:
                number_of_winners += 1
            if c.elected is not None:
                context["show_retract_result"] = True

        max_winners = get_max_winners(pee)
        context["show_confirm_result"] = bool(max_winners)

        context["add_candidate_form"] = NewPersonForm(
            election=election.slug,
            initial={
                ("constituency_" + election.slug): post_id,
                ("standing_" + election.slug): "standing",
            },
            hidden_post_widget=True,
        )

        context = get_person_form_fields(context,
                                         context["add_candidate_form"])
        context["identifiers_formset"] = PersonIdentifierFormsetFactory()

        return context
    def handle(self, username=None, **options):
        from slumber.exceptions import HttpClientError
        from candidates.popit import create_popit_api_object
        from candidates.election_specific import PARTY_DATA, shorten_post_label
        from candidates.models import PopItPerson

        if username is None:
            message = "You must supply the name of a user to be associated with the image uploads."
            raise CommandError(message)
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            message = "No user with the username '{0}' could be found"
            raise CommandError(message.format(username))

        api = create_popit_api_object()

        json_filename = join(
            dirname(__file__), '..', '..','data', 'candidates.json'
        )
        with open(json_filename) as f:
            all_data = json.load(f)

        # This map is needed to get getting YNR election data from
        # the election ID used in the JSON file.
        json_election_id_to_name = {
            e['pk']: e['fields']['name']
            for e in all_data if e['model'] == 'elections.election'
        }

        person_dict = {
            e['pk']: e['fields']
            for e in all_data if e['model'] == 'popolo.person'
        }

        candidate_list = [
            dict(person_id=e['pk'], election_id=e['fields']['election'])
            for e in all_data if e['model'] == 'elections.candidate'
        ]

        for candidate in candidate_list:
            vi_person_id = candidate['person_id']
            person_data = person_dict[vi_person_id]
            election_data, post_data = get_post_data(
                api, candidate['election_id'], json_election_id_to_name
            )
            birth_date = None
            if person_data['birth_date']:
                birth_date = str(dateutil.parser.parse(
                    person_data['birth_date'], dayfirst=True
                ).date())
            name = person_data['name']
            gender = person_data['gender']
            image_url = person_data['image']

            person = get_existing_popit_person(vi_person_id)
            if person:
                print("Found an existing person:", person.get_absolute_url())
            else:
                print("No existing person, creating a new one:", name)
                person = PopItPerson()

            # Now update fields from the imported data:
            person.name = name
            person.gender = gender
            if birth_date:
                person.birth_date = str(birth_date)
            else:
                person.birth_date = None
            standing_in_election = {
                'post_id': post_data['id'],
                'name': shorten_post_label(post_data['label']),
            }
            if 'area' in post_data:
                standing_in_election['mapit_url'] = post_data['area']['identifier']
            person.standing_in = {
                election_data.slug: standing_in_election
            }
            person.party_memberships = {
                election_data.slug: {
                    'id': UNKNOWN_PARTY_ID,
                    'name': PARTY_DATA.party_id_to_name[UNKNOWN_PARTY_ID],
                }
            }
            person.set_identifier('import-id', vi_person_id)
            change_metadata = get_change_metadata(
                None,
                'Imported candidate from JSON',
            )

            person.record_version(change_metadata)
            try:
                person.save_to_popit(api)
                if image_url:
                    enqueue_image(person, user, image_url)
            except HttpClientError as hce:
                print("Got an HttpClientError:", hce.content)
                raise
コード例 #10
0
def get_person_as_version_data(person, new_person=False):
    """
    If new_person is True then skip some DB checks that we know will be
    empty. This should reduce the number of queries needed.
    """

    # Prefetch to reduce the number of queries
    prefetch_related_objects([person], "tmp_person_identifiers")

    from candidates.election_specific import shorten_post_label

    result = {}
    result["id"] = str(person.id)

    # Add PersonIdentifier fields in to the global version namespace
    # TODO: move these to dict to make it easier to merge/split/revert
    existing_identifiers = {
        identifier.value_type: identifier.value
        for identifier in person.tmp_person_identifiers.all()
    }
    for field in PersonIdentifierFields:
        result[field.name] = existing_identifiers.get(field.name, "")

    for field in settings.SIMPLE_POPOLO_FIELDS:
        result[field.name] = getattr(person, field.name) or ""

    # Add legacy identifiers
    # TODO: these should use the PersonIdenfitiers model and value types,
    # but this code emulates the legacy way of adding IDs.
    if person.get_single_identifier_of_type("theyworkforyou"):
        result["identifiers"] = []
        new_id = person.get_single_identifier_of_type(
            "theyworkforyou").internal_identifier
        if not "publicwhip" in new_id:
            new_id = "uk.org.publicwhip/person/{}".format(new_id)

        result["identifiers"].append({
            "identifier": new_id,
            "scheme": "uk.org.publicwhip"
        })
    if person.get_single_identifier_of_type("twitter_username"):
        result["identifiers"] = result.get("identifiers", [])
        result["identifiers"].append({
            "identifier":
            person.get_single_identifier_of_type(
                "twitter_username").internal_identifier,
            "scheme":
            "twitter",
        })

    extra_values = {}
    result["other_names"] = []
    standing_in = {}
    party_memberships = {}

    if not new_person:
        result["other_names"] = [{
            "name": on.name,
            "note": on.note,
            "start_date": on.start_date,
            "end_date": on.end_date,
        }
                                 for on in person.other_names.order_by(
                                     "name", "start_date", "end_date")]

        for membership in person.memberships.filter(post__isnull=False):
            post = membership.post
            post_election = membership.post_election
            election = post_election.election
            standing_in[post_election.election.slug] = {
                "post_id": post.slug,
                "name": shorten_post_label(post.label),
            }
            if membership.elected is not None:
                standing_in[election.slug]["elected"] = membership.elected
            if membership.party_list_position is not None:
                standing_in[election.slug][
                    "party_list_position"] = membership.party_list_position
            party = membership.party
            party_memberships[post_election.election.slug] = {
                "id": party.legacy_slug,
                "name": party.name,
            }
        for not_standing_in_election in person.not_standing.all():
            standing_in[not_standing_in_election.slug] = None
            # Delete party memberships if not standing in this election
            party_memberships.pop(not_standing_in_election.slug, None)

    # Add `favourite_biscuits` to an `extra_fields` key
    # to re-produce the previous ExtraField model.
    # This is done like this to save changing the version diff
    # for exery edit to move to key to the parent object.
    # In the future we will have to run a script to move all the
    # keys to wherever we want them.
    extra_fields = {"favourite_biscuits": person.favourite_biscuit or ""}

    result["extra_fields"] = extra_fields

    result["standing_in"] = standing_in
    result["party_memberships"] = party_memberships
    return result
コード例 #11
0
def get_person_as_version_data(person):
    from candidates.election_specific import shorten_post_label
    result = {}
    person_extra = person.extra
    result['id'] = str(person.id)
    for field in SimplePopoloField.objects.all():
        result[field.name] = getattr(person, field.name) or ''
    for field in ComplexPopoloField.objects.all():
        result[field.name] = getattr(person_extra, field.name)
    extra_values = {
        extra_value.field.key: extra_value.value
        for extra_value in person.extra_field_values.select_related('field')
    }
    extra_fields = {
        extra_field.key: extra_values.get(extra_field.key, '')
        for extra_field in ExtraField.objects.all()
    }
    if extra_fields:
        result['extra_fields'] = extra_fields
    result['other_names'] = [
        {
            'name': on.name,
            'note': on.note,
            'start_date': on.start_date,
            'end_date': on.end_date,
        }
        for on in person.other_names.order_by('name', 'start_date', 'end_date')
    ]
    identifiers = list(person.identifiers.all())
    if identifiers:
        result['identifiers'] = [
            {
                'scheme': i.scheme,
                'identifier': i.identifier,
            }
            for i in identifiers
        ]
    result['image'] = person.image
    standing_in = {}
    party_memberships = {}
    for membership in person.memberships.filter(post__isnull=False):
        from candidates.models import MembershipExtra
        post = membership.post
        try:
            membership_extra = membership.extra
        except MembershipExtra.DoesNotExist:
            continue
        election = membership_extra.election
        standing_in[election.slug] = {
            'post_id': post.extra.slug,
            'name': shorten_post_label(post.label)
        }
        if membership_extra.elected is not None:
            standing_in[election.slug]['elected'] = membership_extra.elected
        if membership_extra.party_list_position is not None:
            standing_in[election.slug]['party_list_position'] = \
                membership_extra.party_list_position
        party = membership.on_behalf_of
        party_memberships[election.slug] = {
            'id': party.extra.slug,
            'name': party.name,
        }
    for not_standing_in_election in person_extra.not_standing.all():
        standing_in[not_standing_in_election.slug] = None
    result['standing_in'] = standing_in
    result['party_memberships'] = party_memberships
    return result
コード例 #12
0
    def __init__(self, *args, **kwargs):
        from candidates.election_specific import shorten_post_label

        election = kwargs.pop("election", None)
        hidden_post_widget = kwargs.pop("hidden_post_widget", None)
        super().__init__(*args, **kwargs)

        election_data = Election.objects.get_by_slug(election)

        standing_field_kwargs = {
            "label": _("Standing in %s") % election_data.name,
            "choices": self.STANDING_CHOICES,
        }
        if hidden_post_widget:
            standing_field_kwargs["widget"] = forms.HiddenInput()
        else:
            standing_field_kwargs["widget"] = forms.Select(
                attrs={"class": "standing-select"})
        self.fields["standing_" +
                    election] = forms.ChoiceField(**standing_field_kwargs)

        self.elections_with_fields = [election_data]

        post_field_kwargs = {
            "label":
            _("Post in the {election}").format(election=election_data.name),
            "max_length":
            256,
        }
        if hidden_post_widget:
            post_field_kwargs["widget"] = forms.HiddenInput()
            post_field = StrippedCharField(**post_field_kwargs)
        else:
            post_field = forms.ChoiceField(
                label=_("Post in the {election}").format(
                    election=election_data.name),
                required=False,
                choices=[("", "")] + sorted(
                    [(post.slug, shorten_post_label(post.label))
                     for post in Post.objects.filter(elections__slug=election)
                     ],
                    key=lambda t: t[1],
                ),
                widget=forms.Select(attrs={"class": "post-select"}),
            )

        self.fields["constituency_" + election] = post_field

        # It seems to be common in elections around the world for
        # there to be different sets of parties that candidates can
        # stand for depending on, for example, where in the country
        # they're standing. (For example, in the UK General Election,
        # there is a different register of parties for Northern
        # Ireland and Great Britain constituencies.) We create a party
        # choice field for each such "party set" and make sure only
        # the appropriate one is shown, depending on the election and
        # selected constituency, using Javascript.
        specific_party_set = None
        if hidden_post_widget:
            # Then the post can't be changed, so only add the
            # particular party set relevant for that post:
            post_id = kwargs["initial"]["constituency_" + election]
            specific_party_set = PartySet.objects.get(post__slug=post_id)

        party_registers_for_election = set(
            election_data.postextraelection_set.annotate(
                Count("post__party_set__slug")).values_list(
                    "post__party_set__slug", flat=True))
        for register in party_registers_for_election:
            register = register.upper()
            if specific_party_set and (register !=
                                       specific_party_set.slug.upper()):
                continue

            self.fields[
                "party_" + register + "_" + election] = forms.ChoiceField(
                    label=_("Party in {election} ({register})").format(
                        election=election_data.name, register=register),
                    choices=Party.objects.register(register).party_choices(),
                    required=False,
                    widget=forms.Select(
                        attrs={
                            "class": "party-select party-select-" + election
                        }),
                )

            if election_data.party_lists_in_use:
                # Then add a field to enter the position on the party list
                # as an integer:
                field_name = "party_list_position_" + register + "_" + election
                self.fields[field_name] = forms.IntegerField(
                    label=
                    _("Position in party list ('1' for first, '2' for second, etc.)"
                      ),
                    min_value=1,
                    required=False,
                    widget=forms.NumberInput(
                        attrs={
                            "class": "party-position party-position-" +
                            election
                        }),
                )
コード例 #13
0
def get_person_as_version_data(person, new_person=False):
    """
    If new_person is True then skip some DB checks that we know will be
    empty. This should reduce the number of queries needed.
    """
    from candidates.election_specific import shorten_post_label

    result = {}
    result["id"] = str(person.id)

    for field in settings.SIMPLE_POPOLO_FIELDS:
        result[field.name] = getattr(person, field.name) or ""
    for field in ComplexPopoloField.objects.all():
        if new_person:
            # Just set the attrs, as these will all be empty
            result[field.name] = ""
        else:
            result[field.name] = getattr(person, field.name)

    extra_values = {}
    result["other_names"] = []
    standing_in = {}
    party_memberships = {}

    if not new_person:
        result["other_names"] = [
            {
                "name": on.name,
                "note": on.note,
                "start_date": on.start_date,
                "end_date": on.end_date,
            }
            for on in person.other_names.order_by(
                "name", "start_date", "end_date"
            )
        ]

        identifiers = list(person.identifiers.all())
        if identifiers:
            result["identifiers"] = [
                {"scheme": i.scheme, "identifier": i.identifier}
                for i in identifiers
            ]

        for membership in person.memberships.filter(post__isnull=False):
            post = membership.post
            post_election = membership.post_election
            election = post_election.election
            standing_in[post_election.election.slug] = {
                "post_id": post.slug,
                "name": shorten_post_label(post.label),
            }
            if membership.elected is not None:
                standing_in[election.slug]["elected"] = membership.elected
            if membership.party_list_position is not None:
                standing_in[election.slug][
                    "party_list_position"
                ] = membership.party_list_position
            party = membership.party
            party_memberships[post_election.election.slug] = {
                "id": party.legacy_slug,
                "name": party.name,
            }
        for not_standing_in_election in person.not_standing.all():
            standing_in[not_standing_in_election.slug] = None

        extra_values = {
            extra_value.field.key: extra_value.value
            for extra_value in person.extra_field_values.select_related("field")
        }

    extra_fields = {
        extra_field.key: extra_values.get(extra_field.key, "")
        for extra_field in ExtraField.objects.all()
    }
    if extra_fields:
        result["extra_fields"] = extra_fields

    result["standing_in"] = standing_in
    result["party_memberships"] = party_memberships
    return result
    def handle(self, username=None, **options):
        from slumber.exceptions import HttpClientError
        from candidates.election_specific import PARTY_DATA, shorten_post_label
        from candidates.models import PopItPerson
        from candidates.popit import create_popit_api_object

        election_data = {
            'prv-2015': 'listedescandidatsauxelectionslegislativeslisteprovincialeanptic.csv',
            'nat-2015': 'listedescandidatsauxelectionslegislativesanptic.csv'
            }

        field_map = {
            'prv-2015': {
                'region': 1,
                'party': 4,
                'list_order': 5,
                'first_name': 7,
                'last_name': 6,
                'gender': 8,
                'birth_date': 9,
                'party_short': 3
            },
            'nat-2015': {
                'region': 0,
                'party': 2,
                'list_order': 3,
                'first_name': 5,
                'last_name': 4,
                'gender': 6,
                'birth_date': 7,
                'party_short': 2
            }
        }

        api = create_popit_api_object()

        party_id_missing = {}
        party_name_to_id = {}
        for party_id, party_name in PARTY_DATA.party_id_to_name.items():
            party_name_to_id[party_name] = party_id

        for election_id, filename in election_data.items():
            csv_filename = join(
                dirname(__file__), '..', '..', 'data', filename
            )

            fields = field_map[election_id]

            with codecs.open(csv_filename, 'r', encoding='windows-1252') as f:

                initial = True
                for candidate in unicode_csv_reader(f):
                    # skip header line
                    if initial:
                        initial = False
                        continue

                    region = candidate[fields['region']]
                    party = candidate[fields['party']]
                    party_list_order = candidate[fields['list_order']]
                    first_name = string.capwords(candidate[fields['first_name']])
                    last_name = string.capwords(candidate[fields['last_name']])
                    gender = candidate[fields['gender']]
                    birth_date = None

                    if candidate[fields['birth_date']] is not None:
                        birth_date = str(dateutil.parser.parse(
                            candidate[fields['birth_date']], dayfirst=True
                        ).date())

                    name = first_name + ' ' + last_name

                    id = '-'.join([
                        re.sub('[^\w]*', '', re.sub(r' ', '-', strip_accents(name.lower()))),
                        re.sub('[^\w]*', '', candidate[fields['party_short']].lower()),
                        birth_date
                    ])

                    # national candidate
                    if region == 'PAYS':
                        region = 'Burkina Faso'
                    election_data, post_data = get_post_data(
                        api, election_id, region
                    )

                    # debug
                    # tmp = '%s %s %s (%s) - %s (%s)' % ( id, first_name, last_name, party, region, post_data['label'] )
                    # print(tmp)

                    person = get_existing_popit_person(id)
                    if person:
                        # print("Found an existing person:", person.get_absolute_url())
                        pass
                    else:
                        print("No existing person, creating a new one:", name)
                        person = PopItPerson()

                    person.set_identifier('import-id', id)
                    person.family_name = last_name
                    person.given_name = first_name
                    person.name = name
                    person.gender = gender
                    if birth_date:
                        person.birth_date = str(birth_date)
                    else:
                        person.birth_date = None

                    standing_in_election = {
                        'post_id': post_data['id'],
                        'name': shorten_post_label(post_data['label']),
                        'party_list_position': party_list_order,
                    }

                    if 'area' in post_data:
                        standing_in_election['mapit_url'] = post_data['area']['identifier']

                    person.standing_in = {
                        election_data.slug: standing_in_election
                    }

                    change_metadata = get_change_metadata(
                        None,
                        'Imported candidate from CSV',
                    )

                    party_comp = re.sub(' +', ' ', party)
                    party_id = UNKNOWN_PARTY_ID
                    if party_comp in party_name_to_id.keys():
                        party_id = party_name_to_id[party_comp]
                        party = party_comp
                    else:
                        party_id = party_name_to_id['Unknown Party']
                        party = 'Unknown Party'

                    if party_id == UNKNOWN_PARTY_ID and party_comp not in party_id_missing.keys():
                        party_id_missing[party_comp] = 1

                    person.party_memberships = {
                        election_data.slug: {
                            'id': party_id,
                            'name': party,
                            'imported_name': party_comp
                        }
                    }

                    person.record_version(change_metadata)
                    try:
                        person.save_to_popit(api)
                    except HttpClientError as hce:
                        print("Got an HttpClientError:", hce.content)
                        raise

        if len(party_id_missing) > 0:
            print("Unmatched party names:")
            for name in party_id_missing.keys():
                print(name)
コード例 #15
0
    def handle(self, **options):
        from slumber.exceptions import HttpClientError, HttpServerError
        from candidates.election_specific import PARTY_DATA, shorten_post_label
        from candidates.models import PopItPerson
        from candidates.popit import create_popit_api_object

        api = create_popit_api_object()

        csv_filename = join(dirname(__file__), '..', '..', 'data',
                            'candidates.csv')
        with open(csv_filename) as f:
            all_data = csv.DictReader(f)

            for candidate in all_data:
                vi_person_id = candidate['Distrito'] + candidate[
                    'Numero Lista'] + candidate['Posicion'] + candidate[
                        'Cargo'] + candidate['Nombre Lista']

                election_data, post_data = get_post_data(
                    api, candidate['Cargo'], candidate['Distrito'])
                if (election_data == False):
                    print("Skipping: " + candidate['Cargo'] + ", " +
                          candidate['Distrito'] + ", " + candidate['Nombre'])
                    continue

                name = candidate['Nombre']
                birth_date = None
                gender = None
                image_url = None

                person = get_existing_popit_person(vi_person_id)
                if person:
                    print("Found an existing person:",
                          person.get_absolute_url())
                else:
                    print("No existing person, creating a new one:", name)
                    person = PopItPerson()

                # Now update fields from the imported data:
                person.name = name.split(",")[1] + " " + name.split(",")[0]
                person.gender = gender
                if birth_date:
                    person.birth_date = str(birth_date)
                else:
                    person.birth_date = None
                standing_in_election = {
                    'post_id': post_data['id'],
                    'name': shorten_post_label(post_data['label']),
                    'party_list_position': candidate['Posicion'],
                }
                if 'area' in post_data:
                    standing_in_election['mapit_url'] = post_data['area'][
                        'identifier']

                person.standing_in = {election_data.slug: standing_in_election}

                party_id = get_party_id(candidate["Partido"])

                person.party_memberships = {
                    election_data.slug: {
                        'id': party_id,
                        'name': PARTY_DATA.party_id_to_name[party_id],
                    }
                }
                person.set_identifier('import-id', vi_person_id)
                change_metadata = get_change_metadata(
                    None,
                    'Imported candidate from CSV',
                )

                person.record_version(change_metadata)
                try:
                    person.save_to_popit(api)
                except HttpClientError as hce:
                    print("Got an HttpClientError:", hce.content)
                    raise
                except HttpServerError as hse:
                    print("The server error content was:", hse.content)
                    raise
コード例 #16
0
    def short_label(self):
        from candidates.election_specific import shorten_post_label

        return shorten_post_label(self.base.label)
コード例 #17
0
    def handle(self, username=None, **options):
        from slumber.exceptions import HttpClientError
        from candidates.popit import create_popit_api_object
        from candidates.election_specific import PARTY_DATA, shorten_post_label
        from candidates.models import PopItPerson

        if username is None:
            message = "You must supply the name of a user to be associated with the image uploads."
            raise CommandError(message)
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            message = "No user with the username '{0}' could be found"
            raise CommandError(message.format(username))

        api = create_popit_api_object()

        json_filename = join(dirname(__file__), '..', '..', 'data',
                             'candidates.json')
        with open(json_filename) as f:
            all_data = json.load(f)

        # This map is needed to get getting YNR election data from
        # the election ID used in the JSON file.
        json_election_id_to_name = {
            e['pk']: e['fields']['name']
            for e in all_data if e['model'] == 'elections.election'
        }

        person_dict = {
            e['pk']: e['fields']
            for e in all_data if e['model'] == 'popolo.person'
        }

        candidate_list = [
            dict(person_id=e['pk'], election_id=e['fields']['election'])
            for e in all_data if e['model'] == 'elections.candidate'
        ]

        for candidate in candidate_list:
            vi_person_id = candidate['person_id']
            person_data = person_dict[vi_person_id]
            election_data, post_data = get_post_data(api,
                                                     candidate['election_id'],
                                                     json_election_id_to_name)
            birth_date = None
            if person_data['birth_date']:
                birth_date = str(
                    dateutil.parser.parse(person_data['birth_date'],
                                          dayfirst=True).date())
            name = person_data['name']
            gender = person_data['gender']
            image_url = person_data['image']

            person = get_existing_popit_person(vi_person_id)
            if person:
                print("Found an existing person:", person.get_absolute_url())
            else:
                print("No existing person, creating a new one:", name)
                person = PopItPerson()

            # Now update fields from the imported data:
            person.name = name
            person.gender = gender
            if birth_date:
                person.birth_date = str(birth_date)
            else:
                person.birth_date = None
            standing_in_election = {
                'post_id': post_data['id'],
                'name': shorten_post_label(post_data['label']),
            }
            if 'area' in post_data:
                standing_in_election['mapit_url'] = post_data['area'][
                    'identifier']
            person.standing_in = {election_data.slug: standing_in_election}
            person.party_memberships = {
                election_data.slug: {
                    'id': UNKNOWN_PARTY_ID,
                    'name': PARTY_DATA.party_id_to_name[UNKNOWN_PARTY_ID],
                }
            }
            person.set_identifier('import-id', vi_person_id)
            change_metadata = get_change_metadata(
                None,
                'Imported candidate from JSON',
            )

            person.record_version(change_metadata)
            try:
                person.save_to_popit(api)
                if image_url:
                    enqueue_image(person, user, image_url)
            except HttpClientError as hce:
                print("Got an HttpClientError:", hce.content)
                raise
コード例 #18
0
def get_person_as_version_data(person, new_person=False):
    """
    If new_person is True then skip some DB checks that we know will be
    empty. This should reduce the number of queries needed.
    """
    from candidates.election_specific import shorten_post_label
    result = {}
    person_extra = person.extra
    result['id'] = str(person.id)

    for field in settings.SIMPLE_POPOLO_FIELDS:
        result[field.name] = getattr(person, field.name) or ''
    for field in ComplexPopoloField.objects.all():
        if new_person:
            # Just set the attrs, as these will all be empty
            result[field.name] = ''
        else:
            result[field.name] = getattr(person_extra, field.name)

    extra_values = {}
    result['other_names'] = []
    standing_in = {}
    party_memberships = {}
    result['image'] = ''

    if not new_person:
        result['other_names'] = [{
            'name': on.name,
            'note': on.note,
            'start_date': on.start_date,
            'end_date': on.end_date,
        }
                                 for on in person.other_names.order_by(
                                     'name', 'start_date', 'end_date')]

        identifiers = list(person.identifiers.all())
        if identifiers:
            result['identifiers'] = [{
                'scheme': i.scheme,
                'identifier': i.identifier,
            } for i in identifiers]
        result['image'] = person.image

        for membership in person.memberships.filter(post__isnull=False):
            post = membership.post
            post_election = membership.post_election
            election = post_election.election
            standing_in[post_election.election.slug] = {
                'post_id': post.extra.slug,
                'name': shorten_post_label(post.label)
            }
            if membership.elected is not None:
                standing_in[election.slug]['elected'] = \
                    membership.elected
            if membership.party_list_position is not None:
                standing_in[election.slug]['party_list_position'] = \
                    membership.party_list_position
            party = membership.on_behalf_of
            party_memberships[post_election.election.slug] = {
                'id': party.extra.slug,
                'name': party.name,
            }
        for not_standing_in_election in person_extra.not_standing.all():
            standing_in[not_standing_in_election.slug] = None

        extra_values = {
            extra_value.field.key: extra_value.value
            for extra_value in person.extra_field_values.select_related(
                'field')
        }

    extra_fields = {
        extra_field.key: extra_values.get(extra_field.key, '')
        for extra_field in ExtraField.objects.all()
    }
    if extra_fields:
        result['extra_fields'] = extra_fields

    result['standing_in'] = standing_in
    result['party_memberships'] = party_memberships
    return result
    def handle(self, **options):
        from slumber.exceptions import HttpClientError, HttpServerError
        from candidates.election_specific import PARTY_DATA, shorten_post_label
        from candidates.models import PopItPerson
        from candidates.popit import create_popit_api_object

        api = create_popit_api_object()

        csv_filename = join(
            dirname(__file__), '..', '..','data', 'candidates.csv'
        )
        with open(csv_filename) as f:
            all_data = csv.DictReader(f)

            for candidate in all_data:
                vi_person_id = candidate['Distrito']+candidate['Numero Lista']+candidate['Posicion']+candidate['Cargo']+candidate['Nombre Lista']

                election_data, post_data = get_post_data(
                    api, candidate['Cargo'], candidate['Distrito']
                )
                if (election_data == False):
                    print("Skipping: "+ candidate['Cargo'] +", " + candidate['Distrito']+", " + candidate['Nombre'])
                    continue;

                name = candidate['Nombre']
                birth_date = None
                gender = None
                image_url = None

                person = get_existing_popit_person(vi_person_id)
                if person:
                    print("Found an existing person:", person.get_absolute_url())
                else:
                    print("No existing person, creating a new one:", name)
                    person = PopItPerson()

                # Now update fields from the imported data:
                person.name = name.split(",")[1] + " "  + name.split(",")[0]
                person.gender = gender
                if birth_date:
                    person.birth_date = str(birth_date)
                else:
                    person.birth_date = None
                standing_in_election = {
                    'post_id': post_data['id'],
                    'name': shorten_post_label(post_data['label']),
                    'party_list_position': candidate['Posicion'],
                }
                if 'area' in post_data:
                    standing_in_election['mapit_url'] = post_data['area']['identifier']

                person.standing_in = {
                    election_data.slug: standing_in_election
                }

                party_id = get_party_id(candidate["Partido"]);

                person.party_memberships = {
                    election_data.slug: {
                        'id': party_id,
                        'name': PARTY_DATA.party_id_to_name[party_id],
                    }
                }
                person.set_identifier('import-id', vi_person_id)
                change_metadata = get_change_metadata(
                    None,
                    'Imported candidate from CSV',
                )

                person.record_version(change_metadata)
                try:
                    person.save_to_popit(api)
                except HttpClientError as hce:
                    print("Got an HttpClientError:", hce.content)
                    raise
                except HttpServerError as hse:
                    print("The server error content was:", hse.content)
                    raise
コード例 #20
0
def get_person_as_version_data(person):
    from candidates.election_specific import shorten_post_label
    result = {}
    person_extra = person.extra
    result['id'] = str(person.id)
    for field in SimplePopoloField.objects.all():
        result[field.name] = getattr(person, field.name) or ''
    for field in ComplexPopoloField.objects.all():
        result[field.name] = getattr(person_extra, field.name)
    extra_values = {
        extra_value.field.key: extra_value.value
        for extra_value in person.extra_field_values.select_related('field')
    }
    extra_fields = {
        extra_field.key: extra_values.get(extra_field.key, '')
        for extra_field in ExtraField.objects.all()
    }
    if extra_fields:
        result['extra_fields'] = extra_fields
    result['other_names'] = [{
        'name': on.name,
        'note': on.note,
        'start_date': on.start_date,
        'end_date': on.end_date,
    } for on in person.other_names.order_by('name', 'start_date', 'end_date')]
    identifiers = list(person.identifiers.all())
    if identifiers:
        result['identifiers'] = [{
            'scheme': i.scheme,
            'identifier': i.identifier,
        } for i in identifiers]
    result['image'] = person.image
    standing_in = {}
    party_memberships = {}
    for membership in person.memberships.filter(post__isnull=False):
        from candidates.models import MembershipExtra
        post = membership.post
        try:
            membership_extra = membership.extra
        except MembershipExtra.DoesNotExist:
            continue
        election = membership_extra.election
        standing_in[election.slug] = {
            'post_id': post.extra.slug,
            'name': shorten_post_label(post.label)
        }
        if membership_extra.elected is not None:
            standing_in[election.slug]['elected'] = membership_extra.elected
        if membership_extra.party_list_position is not None:
            standing_in[election.slug]['party_list_position'] = \
                membership_extra.party_list_position
        party = membership.on_behalf_of
        party_memberships[election.slug] = {
            'id': party.extra.slug,
            'name': party.name,
        }
    for not_standing_in_election in person_extra.not_standing.all():
        standing_in[not_standing_in_election.slug] = None
    result['standing_in'] = standing_in
    result['party_memberships'] = party_memberships
    return result
コード例 #21
0
    def handle(self, username=None, **options):
        from slumber.exceptions import HttpClientError
        from candidates.election_specific import PARTY_DATA, shorten_post_label
        from candidates.models import PopItPerson
        from candidates.popit import create_popit_api_object

        election_data = {
            'prv-2015':
            'listedescandidatsauxelectionslegislativeslisteprovincialeanptic.csv',
            'nat-2015': 'listedescandidatsauxelectionslegislativesanptic.csv'
        }

        field_map = {
            'prv-2015': {
                'region': 1,
                'party': 4,
                'list_order': 5,
                'first_name': 7,
                'last_name': 6,
                'gender': 8,
                'birth_date': 9,
                'party_short': 3
            },
            'nat-2015': {
                'region': 0,
                'party': 2,
                'list_order': 3,
                'first_name': 5,
                'last_name': 4,
                'gender': 6,
                'birth_date': 7,
                'party_short': 2
            }
        }

        api = create_popit_api_object()

        party_id_missing = {}
        party_name_to_id = {}
        for party_id, party_name in PARTY_DATA.party_id_to_name.items():
            party_name_to_id[party_name] = party_id

        for election_id, filename in election_data.items():
            csv_filename = join(dirname(__file__), '..', '..', 'data',
                                filename)

            fields = field_map[election_id]

            with codecs.open(csv_filename, 'r', encoding='windows-1252') as f:

                initial = True
                for candidate in unicode_csv_reader(f):
                    # skip header line
                    if initial:
                        initial = False
                        continue

                    region = candidate[fields['region']]
                    party = candidate[fields['party']]
                    party_list_order = candidate[fields['list_order']]
                    first_name = string.capwords(
                        candidate[fields['first_name']])
                    last_name = string.capwords(candidate[fields['last_name']])
                    gender = candidate[fields['gender']]
                    birth_date = None

                    if candidate[fields['birth_date']] is not None:
                        birth_date = str(
                            dateutil.parser.parse(
                                candidate[fields['birth_date']],
                                dayfirst=True).date())

                    name = first_name + ' ' + last_name

                    id = '-'.join([
                        re.sub('[^\w]*', '',
                               re.sub(r' ', '-', strip_accents(name.lower()))),
                        re.sub('[^\w]*', '',
                               candidate[fields['party_short']].lower()),
                        birth_date
                    ])

                    # national candidate
                    if region == 'PAYS':
                        region = 'Burkina Faso'
                    election_data, post_data = get_post_data(
                        api, election_id, region)

                    # debug
                    # tmp = '%s %s %s (%s) - %s (%s)' % ( id, first_name, last_name, party, region, post_data['label'] )
                    # print(tmp)

                    person = get_existing_popit_person(id)
                    if person:
                        # print("Found an existing person:", person.get_absolute_url())
                        pass
                    else:
                        print("No existing person, creating a new one:", name)
                        person = PopItPerson()

                    person.set_identifier('import-id', id)
                    person.family_name = last_name
                    person.given_name = first_name
                    person.name = name
                    person.gender = gender
                    if birth_date:
                        person.birth_date = str(birth_date)
                    else:
                        person.birth_date = None

                    standing_in_election = {
                        'post_id': post_data['id'],
                        'name': shorten_post_label(post_data['label']),
                        'party_list_position': party_list_order,
                    }

                    if 'area' in post_data:
                        standing_in_election['mapit_url'] = post_data['area'][
                            'identifier']

                    person.standing_in = {
                        election_data.slug: standing_in_election
                    }

                    change_metadata = get_change_metadata(
                        None,
                        'Imported candidate from CSV',
                    )

                    party_comp = re.sub(' +', ' ', party)
                    party_id = UNKNOWN_PARTY_ID
                    if party_comp in party_name_to_id.keys():
                        party_id = party_name_to_id[party_comp]
                        party = party_comp
                    else:
                        party_id = party_name_to_id['Unknown Party']
                        party = 'Unknown Party'

                    if party_id == UNKNOWN_PARTY_ID and party_comp not in party_id_missing.keys(
                    ):
                        party_id_missing[party_comp] = 1

                    person.party_memberships = {
                        election_data.slug: {
                            'id': party_id,
                            'name': party,
                            'imported_name': party_comp
                        }
                    }

                    person.record_version(change_metadata)
                    try:
                        person.save_to_popit(api)
                    except HttpClientError as hce:
                        print("Got an HttpClientError:", hce.content)
                        raise

        if len(party_id_missing) > 0:
            print("Unmatched party names:")
            for name in party_id_missing.keys():
                print(name)
コード例 #22
0
    def short_label(self):
        from candidates.election_specific import shorten_post_label

        return shorten_post_label(self.label)
コード例 #23
0
    def handle(self, **options):
        from slumber.exceptions import HttpClientError
        from candidates.cache import get_post_cached, UnknownPostException
        from candidates.election_specific import PARTY_DATA, shorten_post_label
        from candidates.models import PopItPerson
        from candidates.popit import create_popit_api_object

        spreadsheet_url = 'https://docs.google.com/spreadsheets/d/{0}/pub?output=csv'\
                              .format(GOOGLE_DOC_ID)

        candidate_list = requests.get(spreadsheet_url)

        content = StringIO(unicode(candidate_list.content))
        reader = csv.DictReader(content)

        api = create_popit_api_object()

        for row in reader:

            try:
                election_data = Election.objects.get_by_slug('council-member-2015')
                ocd_division = election_data.post_id_format.format(area_id=row['Ward'])
                post_data = get_post_cached(api, ocd_division)['result']
            except (UnknownPostException, memcache.Client.MemcachedKeyCharacterError):
                election_data = Election.objects.get_by_slug('school-board-2015')
                post_data = get_post_cached(api, election_data.post_id_format)['result']

            person_id = slugify(row['Name'])

            person = get_existing_popit_person(person_id)

            if person:
                print("Found an existing person:", row['Name'])
            else:
                print("No existing person, creating a new one:", row['Name'])
                person = PopItPerson()

            person.name = row['Name']

            # TODO: Get these attributes in the spreadsheet
            # person.gender = gender
            # if birth_date:
            #     person.birth_date = str(birth_date)
            # else:
            #     person.birth_date = None

            person.email = row['Campaign Email']
            person.facebook_personal_url = row["Candidate's Personal Facebook Profile"]
            person.facebook_page_url = row['Campaign Facebook Page']


            person.twitter_username = row['Campaign Twitter']\
                                          .replace('N', '')\
                                          .replace('N/A', '')\
                                          .replace('http://twitter.com/', '')\
                                          .replace('https://twitter.com/', '')

            person.linkedin_url = row['LinkedIn']
            person.homepage_url = row['Campaign Website\n']

            standing_in_election = {
                'post_id': post_data['id'],
                'name': shorten_post_label(post_data['label']),
            }
            if 'area' in post_data:
                standing_in_election['mapit_url'] = post_data['area']['identifier']
            person.standing_in = {
                election_data.slug: standing_in_election
            }

            if 'dfl' in row['Party'].lower():
                party_id = 'party:101'
            elif 'green' in row['Party'].lower():
                party_id = 'party:201'
            elif 'independence' in row['Party'].lower():
                party_id = 'party:301'
            else:
                party_id = 'party:401'


            party_name = PARTY_DATA.party_id_to_name[party_id]

            person.party_memberships = {
                election_data.slug: {
                    'id': party_id,
                    'name': party_name,
                }
            }

            person.set_identifier('import-id', person_id)
            change_metadata = get_change_metadata(
                None,
                'Imported candidate from Google Spreadsheet',
            )

            person.record_version(change_metadata)
            try:
                person.save_to_popit(api)

                # TODO: Get candidate Images
                # if image_url:
                #     enqueue_image(person, user, image_url)
            except HttpClientError as hce:
                print "Got an HttpClientError:", hce.content
                raise