70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
from typing import Dict, List, Tuple
|
|
|
|
from .. import BaseProvider
|
|
from .isbn import ISBN10, ISBN13, MAX_LENGTH
|
|
|
|
localized = True
|
|
|
|
|
|
class Provider(BaseProvider):
|
|
"""Generates fake ISBNs.
|
|
|
|
See https://www.isbn-international.org/content/what-isbn for the
|
|
format of ISBNs.
|
|
See https://www.isbn-international.org/range_file_generation for the
|
|
list of rules pertaining to each prefix/registration group.
|
|
"""
|
|
|
|
rules: Dict[str, Dict[str, List[Tuple[str, str, int]]]] = {}
|
|
|
|
def _body(self) -> List[str]:
|
|
"""Generate the information required to create an ISBN-10 or
|
|
ISBN-13.
|
|
"""
|
|
ean: str = self.random_element(self.rules.keys())
|
|
reg_group: str = self.random_element(self.rules[ean].keys())
|
|
|
|
# Given the chosen ean/group, decide how long the
|
|
# registrant/publication string may be.
|
|
# We must allocate for the calculated check digit, so
|
|
# subtract 1
|
|
reg_pub_len: int = MAX_LENGTH - len(ean) - len(reg_group) - 1
|
|
|
|
# Generate a registrant/publication combination
|
|
reg_pub: str = self.numerify("#" * reg_pub_len)
|
|
|
|
# Use rules to separate the registrant from the publication
|
|
rules = self.rules[ean][reg_group]
|
|
registrant, publication = self._registrant_publication(reg_pub, rules)
|
|
return [ean, reg_group, registrant, publication]
|
|
|
|
@staticmethod
|
|
def _registrant_publication(reg_pub: str, rules: List[Tuple[str, str, int]]) -> Tuple[str, str]:
|
|
"""Separate the registration from the publication in a given
|
|
string.
|
|
|
|
:param reg_pub: A string of digits representing a registration
|
|
and publication.
|
|
:param rules: A list of registrant rules which designate where
|
|
to separate the values in the string.
|
|
:returns: A (registrant, publication) tuple of strings.
|
|
"""
|
|
for rule in rules:
|
|
if rule[0] <= reg_pub[:-1] <= rule[1]:
|
|
reg_len = rule[2]
|
|
break
|
|
else:
|
|
raise Exception(f"Registrant/Publication '{reg_pub}' not found in registrant rule list.")
|
|
registrant, publication = reg_pub[:reg_len], reg_pub[reg_len:]
|
|
return registrant, publication
|
|
|
|
def isbn13(self, separator: str = "-") -> str:
|
|
ean, group, registrant, publication = self._body()
|
|
isbn = ISBN13(ean, group, registrant, publication)
|
|
return isbn.format(separator)
|
|
|
|
def isbn10(self, separator: str = "-") -> str:
|
|
ean, group, registrant, publication = self._body()
|
|
isbn = ISBN10(ean, group, registrant, publication)
|
|
return isbn.format(separator)
|