示例#1
0
 def test_get_fml_username_variations(self):
     """
     Are all of the first, middle, and last name variations generated, including initials?
     """
     generated_usernames = get_fml_name_variations(
         self.first_name, self.middle_name, self.last_name, True
     )
     generated_usernames.sort()
     expected_usernames = [
         ('James', 'Herbert', 'Bond'), ('J', 'Herbert', 'Bond'), ('James', 'H', 'Bond'),
         ('James', 'Herbert', 'B'), ('J', 'H', 'Bond'), ('J', 'Herbert', 'B'),
         ('James', 'H', 'B'), ('J', 'H', 'B')
     ]
     expected_usernames.sort()
     self.assertListEqual(generated_usernames, expected_usernames)
示例#2
0
    def _enumerate_probable_usernames(self):
        """
        Build a simple list of user names based on a person's full name.

        Limit our formatting to only the special symbols in ``._`` and alphanumeric characters in
        ``a-zA-Z0-9``.  Usernames of services such as Gmail, Yahoo, Outlook.com, LinkedIn, AngelList,
        and Twitter are restricted to these characters despite RFCs allowing more characters (
        including unicode in some cases).

        Email: :rfc:`3696`

        .. todo::
            * Expand our variations to include numbers once we obtain age, birthday, etc
            * Translate non-latin characters to their latin equivalent

        :return: None
        """

        fml_pattern = '{f}{s1}{m}{s2}{l}'
        common_special_characters = ['.', '_', '']  # '' To represent *no special character*
        name_variations = []
        generated_usernames = set()

        # Normalize characters in each name to their decomposed equivalents
        first_name = ''.join([
            c for c in unicodedata.normalize('NFKD', self.person.first_name)
            if not unicodedata.combining(c)
         ])
        middle_name = ''.join([
            c for c in unicodedata.normalize('NFKD', self.person.middle_name)
            if not unicodedata.combining(c)
        ]) if self.person.has_middle_name() else None
        last_name = ''.join([
            c for c in unicodedata.normalize('NFKD', self.person.last_name)
            if not unicodedata.combining(c)
        ])

        # Build a list of name variations. E.g. (James, Bond), (J, Bond), or (J, H, Bond)
        if middle_name:
            name_variations.extend(get_fml_name_variations(first_name, middle_name, last_name, True))
            name_variations.extend(get_fml_name_variations(last_name, first_name, middle_name, True))
            name_variations.extend(get_fml_name_variations(middle_name, last_name, first_name, True))

        name_variations.extend(get_fl_name_variations(first_name, last_name, True))
        name_variations.extend(get_fl_name_variations(last_name, first_name, True))

        # Generate names by concatenating them together with combinations of the special symbols
        for name in name_variations:
            # Each part of the name can be separated by a special character
            for symbol in common_special_characters:
                if len(name) == 2:      # First and Last
                    generated_usernames.add(symbol.join(name))
                elif len(name) == 3:    # First, Middle, and Last
                    first, middle, last = name
                    # We can have combinations of two symbols separating the names
                    for symbol2 in common_special_characters:
                        generated_usernames.add(
                            fml_pattern.format(f=first, m=middle, l=last, s1=symbol, s2=symbol2)
                        )

        self.probable_usernames = generated_usernames