def update_popit_person(self, popit_person_id, ppc_data, image_filename):
        from candidates.models import PopItPerson
        from ..images import image_uploaded_already

        # Get the existing data first:
        person_data, _ = self.get_person(popit_person_id)
        previous_versions = person_data.pop("versions")
        new_person_data = self.get_person_data_from_ppc(ppc_data)
        # Remove any empty keys, we don't want to overwrite exiting
        # data with nothing:
        keys = new_person_data.keys()
        warnings = []
        for key in keys:
            if not new_person_data[key]:
                del new_person_data[key]
            # Also make sure that we don't overwrite any existing
            # fields that are filled in with different values:
            if key not in ("standing_in", "party_memberships"):
                new_person_data_value = new_person_data.get(key)
                person_data_value = person_data.get(key)
                if (person_data_value and new_person_data_value
                        and new_person_data_value != person_data_value):
                    if key_value_appeared_in_previous_version(
                            key, new_person_data_value, previous_versions):
                        warning_message = "[{0}] it looks as if a previous "
                        warning_message += "version had {1}, so not "
                        warning_message += "overwriting the current value {2}"
                        warnings.append(
                            warning_message.format(key, new_person_data_value,
                                                   person_data_value))
                        del new_person_data[key]
                    else:
                        warnings.append("[{}] replacing      {}".format(
                            key, person_data_value))
                        warnings.append("[{}] with new value {}".format(
                            key, new_person_data_value))
        if warnings:
            print("Warnings for person/{} {}".format(
                popit_person_id, person_data["name"]).encode("utf-8"))
            for warning in warnings:
                print("  ...", warning.encode("utf-8"))
        merged_person_data = merge_person_data(person_data, new_person_data)
        change_metadata = get_change_metadata(
            None,
            "Updated candidate from official PPC data ({})".format(
                ppc_data["party_slug"]),
        )
        person = PopItPerson.create_from_reduced_json(merged_person_data)
        person.record_version(change_metadata)
        person_id = person.save_to_popit(self.api)
        if image_filename:
            if image_uploaded_already(self.api.persons, person_id,
                                      image_filename):
                print("That image has already been uploaded!")
            else:
                print("Uploading image...")
                self.upload_person_image(person_id, image_filename,
                                         ppc_data["image_url"])
        person.invalidate_cache_entries()
        return person_id
 def update_popit_person(self, popit_person_id, ppc_data, image_filename):
     from candidates.models import PopItPerson
     from ..images import image_uploaded_already
     # Get the existing data first:
     person_data, _ = self.get_person(popit_person_id)
     previous_versions = person_data.pop('versions')
     new_person_data = self.get_person_data_from_ppc(ppc_data)
     # Remove any empty keys, we don't want to overwrite exiting
     # data with nothing:
     keys = new_person_data.keys()
     warnings = []
     for key in keys:
         if not new_person_data[key]:
             del new_person_data[key]
         # Also make sure that we don't overwrite any existing
         # fields that are filled in with different values:
         if key not in ('standing_in', 'party_memberships'):
             new_person_data_value = new_person_data.get(key)
             person_data_value = person_data.get(key)
             if person_data_value and new_person_data_value and new_person_data_value != person_data_value:
                 if key_value_appeared_in_previous_version(
                     key,
                     new_person_data_value,
                     previous_versions
                 ):
                     warning_message = "[{0}] it looks as if a previous "
                     warning_message += "version had {1}, so not "
                     warning_message += "overwriting the current value {2}"
                     warnings.append(warning_message.format(
                         key,
                         new_person_data_value,
                         person_data_value
                     ))
                     del new_person_data[key]
                 else:
                     warnings.append("[{0}] replacing      {1}".format(key, person_data_value))
                     warnings.append("[{0}] with new value {1}".format(key, new_person_data_value))
     if warnings:
         print("Warnings for person/{0} {1}".format(
             popit_person_id, person_data['name']
         ).encode('utf-8'))
         for warning in warnings:
             print("  ...", warning.encode('utf-8'))
     merged_person_data = merge_person_data(person_data, new_person_data)
     change_metadata = get_change_metadata(
         None,
         'Updated candidate from official PPC data ({0})'.format(ppc_data['party_slug']),
     )
     person = PopItPerson.create_from_reduced_json(merged_person_data)
     person.record_version(change_metadata)
     person_id = person.save_to_popit(self.api)
     if image_filename:
         if image_uploaded_already(self.api.persons, person_id, image_filename):
             print("That image has already been uploaded!")
         else:
             print("Uploading image...")
             self.upload_person_image(person_id, image_filename, ppc_data['image_url'])
     person.invalidate_cache_entries()
     return person_id
 def add_popit_person(self, ppc_data, image_filename):
     change_metadata = get_change_metadata(
         None,
         'Created new candidate from official PPC data ({0})'.format(ppc_data['party_slug']),
     )
     person_data = self.get_person_data_from_ppc(ppc_data)
     person = PopItPerson.create_from_reduced_json(person_data)
     person.record_version(change_metadata)
     person_id = person.save_to_popit(self.api)
     if image_filename:
         self.upload_person_image(person_id, image_filename, ppc_data['image_url'])
     person.invalidate_cache_entries()
     return person_id
 def test_get_person_data_from_dict_clear_email(self):
     form_data = {
         'name': 'John Doe',
         'email': '',
         'birth_date': '',
         'wikipedia_url': 'http://en.wikipedia.org/wiki/John_Doe',
         'homepage_url': '',
         'twitter_username': '******',
         'facebook_personal_url': '',
         'facebook_page_url': '',
         'party_ppc_page_url': '',
     }
     expected_result = {
         'birth_date':
         None,
         'contact_details': [{
             'type': 'twitter',
             'value': 'foobar'
         }],
         'email':
         '',
         'gender':
         '',
         'honorific_prefix':
         '',
         'honorific_suffix':
         '',
         'id':
         None,
         'links': [{
             'note': 'wikipedia',
             'url': 'http://en.wikipedia.org/wiki/John_Doe'
         }],
         'memberships': [],
         'name':
         u'John Doe',
         'party_memberships': {},
         'standing_in': {},
     }
     p = PopItPerson.create_from_reduced_json(form_data)
     self.assertEqual(p.popit_data, expected_result)
 def test_get_person_data_from_dict_clear_email(self):
     form_data = {
         'name': 'John Doe',
         'email': '',
         'birth_date': '',
         'wikipedia_url': 'http://en.wikipedia.org/wiki/John_Doe',
         'homepage_url': '',
         'twitter_username': '******',
         'facebook_personal_url': '',
         'facebook_page_url': '',
         'party_ppc_page_url': '',
     }
     expected_result = {
         'birth_date': None,
         'contact_details': [
             {
                 'type': 'twitter',
                 'value': 'foobar'
             }
         ],
         'email': '',
         'gender': '',
         'honorific_prefix': '',
         'honorific_suffix': '',
         'id': None,
         'links': [
             {
                 'note': 'wikipedia', 'url': 'http://en.wikipedia.org/wiki/John_Doe'
             }
         ],
         'memberships': [],
         'name': u'John Doe',
         'party_memberships': {},
         'standing_in': {},
     }
     p = PopItPerson.create_from_reduced_json(form_data)
     self.assertEqual(
         p.popit_data,
         expected_result
     )
Exemple #6
0
    def test_update_tessa_jowell(self, mock_invalidate_person,
                                 mock_invalidate_posts, mocked_put):

        mock_api = MagicMock()
        mock_api.persons = FakePersonCollection

        old_person_data = {
            "birth_date": '1947',
            "email": "*****@*****.**",
            "facebook_page_url": "",
            "facebook_personal_url": "",
            "gender": "",
            "homepage_url": "http://foo.example.org",
            "honorific_prefix": "",
            "honorific_suffix": "",
            "id": "2009",
            "identifiers": [],
            "image": None,
            "linkedin_url": "",
            "name": "Tessa Jowell",
            "other_names": [],
            "party_memberships": {
                "2010": {
                    "id": "party:53",
                    "name": "Labour Party"
                },
                "2015": {
                    "id": "party:53",
                    "name": "Labour Party"
                }
            },
            "party_ppc_page_url": "",
            "proxy_image": None,
            "standing_in": {
                "2010": {
                    "mapit_url": "http://mapit.mysociety.org/area/65808",
                    "name": "Dulwich and West Norwood",
                    "post_id": "65808",
                },
                "2015": {
                    "mapit_url": "http://mapit.mysociety.org/area/65913",
                    "name": "Camberwell and Peckham",
                    "post_id": "65913",
                }
            },
            "twitter_username": "******",
            "wikipedia_url": "",
        }

        new_person_data = deepcopy(old_person_data)
        new_person_data['standing_in']['2015'] = {
            "mapit_url": "http://mapit.mysociety.org/area/65808",
            "name": "Dulwich and West Norwood",
            "post_id": "65808",
        }

        previous_version = {
            'data': {
                "name": "Tessa Jowell",
                "standing_in": {
                    "2010": {
                        "mapit_url": "http://mapit.mysociety.org/area/65808",
                        "name": "Dulwich and West Norwood",
                        "post_id": "65808",
                    },
                    "2015": {
                        "mapit_url": "http://mapit.mysociety.org/area/65913",
                        "name": "Camberwell and Peckham",
                        "post_id": "65913",
                    }
                },
            }
        }

        person = PopItPerson.create_from_reduced_json(old_person_data)
        person.update_from_reduced_json(new_person_data)
        person.versions = [previous_version]
        person.record_version(
            {
                'information_source': 'A change made for testing purposes',
                'username': '******',
                'version_id': '6054aa38b30b4418',
                'timestamp': '2014-09-28T14:02:44.567413',
            }, )
        person.save_to_popit(mock_api)

        self.assertEqual(2, len(mocked_put.call_args_list))

        first_put_call_args = {
            'birth_date':
            '1947',
            'contact_details': [],
            'email':
            u'*****@*****.**',
            'gender':
            '',
            'honorific_prefix':
            '',
            'honorific_suffix':
            '',
            'id':
            '2009',
            'identifiers': [],
            'name':
            u'Tessa Jowell',
            'links': [],
            'other_names': [],
            'party_memberships':
            None,
            'standing_in':
            None,
            'versions': [{
                'username': '******',
                'information_source': 'A change made for testing purposes',
                'version_id': '6054aa38b30b4418',
                'timestamp': '2014-09-28T14:02:44.567413',
                'data': new_person_data
            }, previous_version],
        }

        second_put_call_args = {
            'birth_date':
            '1947',
            'contact_details': [{
                'type': 'twitter',
                'value': 'jowellt'
            }],
            'email':
            u'*****@*****.**',
            'gender':
            '',
            'honorific_prefix':
            '',
            'honorific_suffix':
            '',
            'id':
            '2009',
            'identifiers': [],
            'name':
            u'Tessa Jowell',
            'links': [{
                'note': 'homepage',
                'url': 'http://foo.example.org'
            }],
            'other_names': [],
            'party_memberships': {
                '2010': {
                    'id': 'party:53',
                    'name': 'Labour Party'
                },
                '2015': {
                    'id': 'party:53',
                    'name': 'Labour Party'
                }
            },
            'standing_in': {
                '2015': {
                    'name': 'Dulwich and West Norwood',
                    'mapit_url': 'http://mapit.mysociety.org/area/65808',
                    'post_id': '65808',
                },
                '2010': {
                    'name': 'Dulwich and West Norwood',
                    'mapit_url': 'http://mapit.mysociety.org/area/65808',
                    'post_id': '65808',
                }
            },
            'versions': [{
                'username': '******',
                'information_source': 'A change made for testing purposes',
                'version_id': '6054aa38b30b4418',
                'timestamp': '2014-09-28T14:02:44.567413',
                'data': new_person_data
            }, previous_version],
        }

        self.assertTrue(
            equal_call_args(
                [first_put_call_args],
                mocked_put.call_args_list[0][0],
            ),
            "Unexpected first PUT (the one blanking out standing_in and party_memberships",
        )

        self.assertTrue(
            equal_call_args(
                [second_put_call_args],
                mocked_put.call_args_list[1][0],
            ),
            "Unexpected second PUT (the one with real standing_in and party_memberships",
        )

        self.assertEqual(4, mock_api.memberships.post.call_count)

        posted_memberships = [
            c[0][0] for c in mock_api.memberships.post.call_args_list
        ]

        self.assertEqual(posted_memberships, [
            {
                "election": "2015",
                "end_date": "9999-12-31",
                "person_id": "2009",
                "post_id": "65808",
                "role": "Candidate",
                "start_date": "2010-05-07"
            },
            {
                "election": "2010",
                "end_date": "2010-05-06",
                "person_id": "2009",
                "post_id": "65808",
                "role": "Candidate",
                "start_date": "2005-05-06"
            },
            {
                "end_date": "9999-12-31",
                "organization_id": "party:53",
                "person_id": "2009",
                "start_date": "2010-05-07"
            },
            {
                "end_date": "2010-05-06",
                "organization_id": "party:53",
                "person_id": "2009",
                "start_date": "2005-05-06"
            },
        ])

        mock_invalidate_person.assert_called_with('2009')

        mock_invalidate_posts.assert_called_with(set(['65808', '65913']))
    def test_update_tessa_jowell(
            self,
            mock_invalidate_person,
            mock_invalidate_posts,
            mocked_put
    ):

        mock_api = MagicMock()
        mock_api.persons = FakePersonCollection

        old_person_data = {
            "birth_date": '1947',
            "email": "*****@*****.**",
            "facebook_page_url": "",
            "facebook_personal_url": "",
            "gender": "",
            "homepage_url": "http://foo.example.org",
            "honorific_prefix": "",
            "honorific_suffix": "",
            "id": "2009",
            "identifiers": [],
            "image": None,
            "linkedin_url": "",
            "name": "Tessa Jowell",
            "other_names": [],
            "party_memberships": {
                "2010": {
                    "id": "party:53",
                    "name": "Labour Party"
                },
                "2015": {
                    "id": "party:53",
                    "name": "Labour Party"
                }
            },
            "party_ppc_page_url": "",
            "proxy_image": None,
            "standing_in": {
                "2010": {
                    "mapit_url": "http://mapit.mysociety.org/area/65808",
                    "name": "Dulwich and West Norwood",
                    "post_id": "65808",
                },
                "2015": {
                    "mapit_url": "http://mapit.mysociety.org/area/65913",
                    "name": "Camberwell and Peckham",
                    "post_id": "65913",
                }
            },
            "twitter_username": "******",
            "wikipedia_url": "",
        }

        new_person_data = deepcopy(old_person_data)
        new_person_data['standing_in']['2015'] = {
            "mapit_url": "http://mapit.mysociety.org/area/65808",
            "name": "Dulwich and West Norwood",
            "post_id": "65808",
        }

        previous_version = {
            'data': {
                "name": "Tessa Jowell",
                "standing_in": {
                    "2010": {
                        "mapit_url": "http://mapit.mysociety.org/area/65808",
                        "name": "Dulwich and West Norwood",
                        "post_id": "65808",
                    },
                    "2015": {
                        "mapit_url": "http://mapit.mysociety.org/area/65913",
                        "name": "Camberwell and Peckham",
                        "post_id": "65913",
                    }
                },
            }
        }

        person = PopItPerson.create_from_reduced_json(old_person_data)
        person.update_from_reduced_json(new_person_data)
        person.versions = [previous_version]
        person.record_version(
            {
                'information_source': 'A change made for testing purposes',
                'username': '******',
                'version_id': '6054aa38b30b4418',
                'timestamp': '2014-09-28T14:02:44.567413',
            },
        )
        person.save_to_popit(mock_api)

        self.assertEqual(2, len(mocked_put.call_args_list))

        first_put_call_args = {
                'birth_date': '1947',
                'contact_details': [],
                'email': u'*****@*****.**',
                'gender': '',
                'honorific_prefix': '',
                'honorific_suffix': '',
                'id': '2009',
                'identifiers': [],
                'name': u'Tessa Jowell',
                'links': [],
                'other_names': [],
                'party_memberships': None,
                'standing_in': None,
                'versions': [
                    {
                        'username': '******',
                        'information_source': 'A change made for testing purposes',
                        'version_id': '6054aa38b30b4418',
                        'timestamp': '2014-09-28T14:02:44.567413',
                        'data': new_person_data
                    },
                    previous_version
                ],
            }

        second_put_call_args = {
                'birth_date': '1947',
                'contact_details': [
                    {
                        'type': 'twitter',
                        'value': 'jowellt'
                    }
                ],
                'email': u'*****@*****.**',
                'gender': '',
                'honorific_prefix': '',
                'honorific_suffix': '',
                'id': '2009',
                'identifiers': [],
                'name': u'Tessa Jowell',
                'links': [
                    {
                        'note': 'homepage',
                        'url': 'http://foo.example.org'
                    }
                ],
                'other_names': [],
                'party_memberships': {
                    '2010': {
                        'id': 'party:53',
                        'name': 'Labour Party'
                    },
                    '2015': {
                        'id': 'party:53',
                        'name': 'Labour Party'
                    }
                },
                'standing_in': {
                    '2015': {
                        'name': 'Dulwich and West Norwood',
                        'mapit_url': 'http://mapit.mysociety.org/area/65808',
                        'post_id': '65808',
                    },
                    '2010': {
                        'name': 'Dulwich and West Norwood',
                        'mapit_url': 'http://mapit.mysociety.org/area/65808',
                        'post_id': '65808',
                    }
                },
                'versions': [
                    {
                        'username': '******',
                        'information_source': 'A change made for testing purposes',
                        'version_id': '6054aa38b30b4418',
                        'timestamp': '2014-09-28T14:02:44.567413',
                        'data': new_person_data
                    },
                    previous_version
                ],
            }


        self.assertTrue(
            equal_call_args(
                [first_put_call_args],
                mocked_put.call_args_list[0][0],
            ),
            "Unexpected first PUT (the one blanking out standing_in and party_memberships",
        )

        self.assertTrue(
            equal_call_args(
                [second_put_call_args],
                mocked_put.call_args_list[1][0],
            ),
            "Unexpected second PUT (the one with real standing_in and party_memberships",
        )

        self.assertEqual(4, mock_api.memberships.post.call_count)

        posted_memberships = [
            c[0][0]
            for c in mock_api.memberships.post.call_args_list
        ]

        self.assertEqual(
            posted_memberships,
            [
                {
                    "election": "2015",
                    "end_date": "9999-12-31",
                    "person_id": "2009",
                    "post_id": "65808",
                    "role": "Candidate",
                    "start_date": "2010-05-07"
                },
                {
                    "election": "2010",
                    "end_date": "2010-05-06",
                    "person_id": "2009",
                    "post_id": "65808",
                    "role": "Candidate",
                    "start_date": "2005-05-06"
                },
                {
                    "end_date": "9999-12-31",
                    "organization_id": "party:53",
                    "person_id": "2009",
                    "start_date": "2010-05-07"
                },
                {
                    "end_date": "2010-05-06",
                    "organization_id": "party:53",
                    "person_id": "2009",
                    "start_date": "2005-05-06"
                },
            ]
        )

        mock_invalidate_person.assert_called_with('2009')

        mock_invalidate_posts.assert_called_with(set(['65808', '65913']))