update bots
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import datetime
|
||||
import re
|
||||
|
||||
from string import ascii_uppercase
|
||||
from typing import Tuple
|
||||
|
||||
from faker.typing import SexLiteral
|
||||
|
||||
from .. import BaseProvider, ElementsType
|
||||
|
||||
localized = True
|
||||
|
||||
|
||||
class Provider(BaseProvider):
|
||||
"""Implement default Passport provider for Faker."""
|
||||
|
||||
passport_number_formats: ElementsType = ()
|
||||
|
||||
def passport_dob(self) -> datetime.date:
|
||||
"""Generate a datetime date of birth."""
|
||||
birthday = self.generator.date_of_birth()
|
||||
return birthday
|
||||
|
||||
def passport_owner(self, gender: SexLiteral = "X") -> Tuple[str, str]:
|
||||
"""Generate a given_name and surname for a passport owner
|
||||
The ``gender`` argument is the gender marker of a passport owner, which is a one character string
|
||||
that is either male, female, or non-binary.
|
||||
"""
|
||||
if gender == "M":
|
||||
given_name = self.generator.parse("{{first_name_male}}")
|
||||
elif gender == "F":
|
||||
given_name = self.generator.parse("{{first_name_female}}")
|
||||
else:
|
||||
given_name = self.generator.parse("{{first_name_nonbinary}}")
|
||||
|
||||
surname = self.generator.parse("{{last_name}}")
|
||||
|
||||
return given_name, surname
|
||||
|
||||
def passport_number(self) -> str:
|
||||
"""Generate a passport number by replacing tokens to be alphanumeric"""
|
||||
temp = re.sub(
|
||||
r"\?",
|
||||
lambda x: self.random_element(ascii_uppercase),
|
||||
self.random_element(self.passport_number_formats),
|
||||
)
|
||||
return self.numerify(temp)
|
||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
from .. import ElementsType
|
||||
from .. import Provider as PassportProvider
|
||||
|
||||
|
||||
class Provider(PassportProvider):
|
||||
"""Implement passport provider for ``de_AT`` locale.
|
||||
|
||||
Sources:
|
||||
|
||||
- https://www.bmi.gv.at/607/Reisepass.aspx
|
||||
"""
|
||||
|
||||
passport_number_formats: ElementsType[str] = (
|
||||
"?#######",
|
||||
"??#######",
|
||||
)
|
||||
Binary file not shown.
@@ -0,0 +1,101 @@
|
||||
import random
|
||||
|
||||
from datetime import date, timedelta
|
||||
from typing import Tuple
|
||||
|
||||
from faker.typing import SexLiteral
|
||||
|
||||
from .. import Provider as PassportProvider
|
||||
|
||||
|
||||
class Provider(PassportProvider):
|
||||
"""Implement passport provider for ``en_US`` locale.
|
||||
|
||||
Sources:
|
||||
|
||||
- https://travel.state.gov/content/travel/en/passports/passport-help/next-generation-passport.html
|
||||
- https://www.vitalrecordsonline.com/glossary/passport-book-number
|
||||
"""
|
||||
|
||||
passport_number_formats = (
|
||||
# NGP
|
||||
"?########",
|
||||
# Pre-NGP
|
||||
"#########",
|
||||
)
|
||||
|
||||
def passport_dates(self, birthday: date = date.today()) -> Tuple[str, str, str]:
|
||||
"""Generates a formatted date of birth, issue, and expiration dates.
|
||||
issue and expiration dates are conditioned to fall within U.S. standards of 5 and 10 year expirations
|
||||
|
||||
|
||||
The ``birthday`` argument is a datetime.date object representing a date of birth.
|
||||
|
||||
Sources:
|
||||
|
||||
-https://travel.state.gov/content/travel/en/passports/passport-help/faqs.html
|
||||
"""
|
||||
birth_date = f"{birthday:%d %b %Y}"
|
||||
today = date.today()
|
||||
age = (today - birthday).days // 365
|
||||
if age < 16:
|
||||
expiry_years = 5
|
||||
issue_date = self.generator.date_time_between(today - timedelta(days=expiry_years * 365 - 1), today)
|
||||
# Checks if age is less than 5 so issue date is not before birthdate
|
||||
if age < 5:
|
||||
issue_date = self.generator.date_time_between(birthday, today)
|
||||
elif age >= 26:
|
||||
expiry_years = 10
|
||||
issue_date = self.generator.date_time_between(today - timedelta(days=expiry_years * 365 - 1), today)
|
||||
else:
|
||||
# In cases between age 16 and 26, the issue date is 5 years ago, but expiry may be in 10 or 5 years
|
||||
expiry_years = 5
|
||||
issue_date = self.generator.date_time_between(
|
||||
today - timedelta(days=expiry_years * 365 - 1), birthday + timedelta(days=16 * 365 - 1)
|
||||
)
|
||||
# all people over 21 must have been over 16 when they recieved passport or it will be expired otherwise
|
||||
if age >= 21:
|
||||
issue_date = self.generator.date_time_between(today - timedelta(days=expiry_years * 365 - 1), today)
|
||||
expiry_years = 10
|
||||
|
||||
if issue_date.day == 29 and issue_date.month == 2:
|
||||
issue_date -= timedelta(days=1)
|
||||
expiry_date = issue_date.replace(year=issue_date.year + expiry_years)
|
||||
|
||||
issue_date_format = f"{issue_date:%d %b %Y}"
|
||||
expiry_date_format = f"{expiry_date:%d %b %Y}"
|
||||
return birth_date, issue_date_format, expiry_date_format
|
||||
|
||||
def passport_gender(self, seed: int = 0) -> SexLiteral:
|
||||
"""Generates a string representing the gender displayed on a passport
|
||||
|
||||
Sources:
|
||||
|
||||
- https://williamsinstitute.law.ucla.edu/publications/x-gender-markers-passports/
|
||||
"""
|
||||
if seed != 0:
|
||||
random.seed(seed)
|
||||
|
||||
genders = ["M", "F", "X"]
|
||||
gender: SexLiteral = random.choices(genders, weights=[0.493, 0.493, 0.014], k=1)[0] # type: ignore
|
||||
return gender
|
||||
|
||||
def passport_full(self) -> str:
|
||||
"""Generates a formatted sting with US Passport information"""
|
||||
dob = self.passport_dob()
|
||||
birth_date, issue_date, expiry_date = self.passport_dates(dob)
|
||||
gender_g = self.passport_gender()
|
||||
given_name, surname = self.passport_owner(gender=gender_g)
|
||||
number = self.passport_number()
|
||||
|
||||
full_rep = """{first_name}\n{second_name}\n{gender}\n{dob}\n{issue}\n{expire}\n{num}\n"""
|
||||
full_rep = full_rep.format(
|
||||
first_name=given_name,
|
||||
second_name=surname,
|
||||
gender=gender_g,
|
||||
dob=birth_date,
|
||||
issue=issue_date,
|
||||
expire=expiry_date,
|
||||
num=number,
|
||||
)
|
||||
return full_rep
|
||||
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
from .. import ElementsType
|
||||
from .. import Provider as PassportProvider
|
||||
|
||||
|
||||
class Provider(PassportProvider):
|
||||
"""Implement passport provider for ``it_IT``.
|
||||
|
||||
Sources:
|
||||
|
||||
- https://www.poliziadistato.it/articolo/10301
|
||||
- https://www.poliziadistato.it/statics/32/note_tecniche.pdf
|
||||
"""
|
||||
|
||||
electronic_passport_number_formats: ElementsType[str] = (
|
||||
# standard passaporto elettronico (elettronic passport)
|
||||
# Format: 2 letters, 7 digits (e.g., YA1234567), used from 2010 on
|
||||
"??#######",
|
||||
)
|
||||
|
||||
def passport_number(self) -> str:
|
||||
"""
|
||||
Generate a valid Italian passport number
|
||||
|
||||
The format consist in 2 uppercase letters followed by 7 digits.
|
||||
"""
|
||||
|
||||
# select the passport number format
|
||||
format = self.random_element(self.electronic_passport_number_formats)
|
||||
|
||||
return self.bothify(format).upper()
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
from typing import Dict, Tuple
|
||||
|
||||
from faker.typing import SexLiteral
|
||||
|
||||
from ... import ElementsType
|
||||
from .. import Provider as BaseProvider
|
||||
|
||||
GENDER_TO_GENERATOR: Dict[SexLiteral, str] = {
|
||||
"F": "{{last_name_female}} {{first_name_female}} {{middle_name_female}}",
|
||||
"M": "{{last_name_male}} {{first_name_male}} {{middle_name_male}}",
|
||||
"X": "{{last_name_male}} {{first_name_male}} {{middle_name_male}}",
|
||||
}
|
||||
|
||||
|
||||
class Provider(BaseProvider):
|
||||
passport_number_formats: ElementsType = (
|
||||
"## ## ######",
|
||||
"#### ######",
|
||||
)
|
||||
|
||||
def passport_owner(self, gender: SexLiteral = "M") -> Tuple[str, str]:
|
||||
generator_string = GENDER_TO_GENERATOR[gender]
|
||||
last_name, first_name, middle_name = self.generator.parse(generator_string).split()
|
||||
|
||||
first_name_united_with_middle = first_name + " " + middle_name
|
||||
return last_name, first_name_united_with_middle
|
||||
Binary file not shown.
Reference in New Issue
Block a user