diff --git a/.gitignore b/.gitignore index 2f2544e..9dbd4cd 100644 --- a/.gitignore +++ b/.gitignore @@ -133,4 +133,5 @@ dmypy.json # Other Pipfile.lock -phone_gen/__version__.py \ No newline at end of file +phone_gen/__version__.py +/TODO.txt diff --git a/.travis.yml b/.travis.yml index 4bed15b..e72662c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ jobs: after_success: false env: - - PHONENUMBERS="-U phonenumbers" # last version + - PHONENUMBERS="8.12.3" # last version python: - "pypy3" @@ -38,13 +38,14 @@ python: - "3.7" - "3.8" install: - - pip install $PHONENUMBERS + - pip install phonenumbers==$PHONENUMBERS - pip install pytest-cov==2.8.1 - pip install pytest==5.4.2 - pip install -e . script: - pip freeze | grep phonenumbers - pytest tests + deploy: provider: pypi user: $PYPI_USER @@ -53,7 +54,7 @@ deploy: distributions: bdist_wheel --universal on: tags: true - repo: tolstislon/phone_gen + repo: tolstislon/phone-gen python: "3.8" after_success: diff --git a/Pipfile b/Pipfile index beea502..c981456 100644 --- a/Pipfile +++ b/Pipfile @@ -9,7 +9,6 @@ pytest = "==5.4.2" pytest-cov = "==2.8.1" phonenumbers = "==8.12.3" black = "==19.10b0" -mypy = "==0.770" flake8 = "==3.8.1" pep8-naming = "==0.10.0" diff --git a/README.md b/README.md index 3992382..9cabeff 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # Phone Gen -[![Build Status](https://travis-ci.com/tolstislon/phone_gen.svg?branch=master)](https://travis-ci.com/tolstislon/phone_gen) -[![codecov](https://codecov.io/gh/tolstislon/phone-gen/branch/master/graph/badge.svg)](https://codecov.io/gh/tolstislon/phone-gen) [![PyPI](https://img.shields.io/pypi/v/phone-gen?color=%2301a001&label=version&logo=version)](https://pypi.org/project/phone-gen/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/phone-gen.svg)](https://pypi.org/project/phone-gen/) [![PyPI - Implementation](https://img.shields.io/pypi/implementation/phone-gen)](https://pypi.org/project/phone-gen/) +[![Downloads](https://pepy.tech/badge/phone-gen)](https://pepy.tech/project/phone-gen) +[![Build Status](https://travis-ci.com/tolstislon/phone_gen.svg?branch=master)](https://travis-ci.com/tolstislon/phone-gen) +[![codecov](https://codecov.io/gh/tolstislon/phone-gen/branch/master/graph/badge.svg)](https://codecov.io/gh/tolstislon/phone-gen) -Phone number generator for [Google's libphonenumber library](https://github.com/google/libphonenumber) +International phone number generation -This module was created exclusively for generating test data, when it is necessary to enter phone numbers in fields that are validated by the `libphonenumber` library or its ports. +This module was created exclusively for generating test data Installation @@ -23,7 +24,7 @@ Example ```python from phone_gen import PhoneNumber -phone_number = PhoneNumber('GB') +phone_number = PhoneNumber("GB") # Get a phone number number = phone_number.get_number() @@ -53,16 +54,50 @@ def phone_number(): def test_one(phone_number): - number = phone_number('DE') + number = phone_number("DE") ... ``` +Using the CLI +---- +```bash +usage: phone-gen [-h] [-v] [-n] country + +International phone number generation + +positional arguments: + country Country code example: GB + +optional arguments: + -h, --help show this help message and exit + -v, --version show program's version number and exit + -n, --not-full Get a phone number without a country code + +``` + +Example +```bash +# Get a phone number +$ phone-gen GB ++44199561679 + +# Get a phone number without a country code +$ phone-gen GB -n +199561343 +``` + Resources ---- -* [libphonenumber](https://github.com/google/libphonenumber) +* [Google's libphonenumber](https://github.com/google/libphonenumber) * Modified [strgen](https://github.com/paul-wolf/strgen) library Contributing ---- -Contributions are very welcome. \ No newline at end of file +Contributions are very welcome. + + +Changelog +---- +* **1.1.0** Added cli +* **1.0.0** The first stable release \ No newline at end of file diff --git a/phone_gen/__init__.py b/phone_gen/__init__.py index 069b47d..6a803c6 100644 --- a/phone_gen/__init__.py +++ b/phone_gen/__init__.py @@ -1,4 +1,35 @@ -from .generator import PhoneNumber +""" +Phone number generator for Google's libphonenumber library +https://github.com/google/libphonenumber + +This module was created exclusively for generating test data, when it is +necessary to enter phone numbers in fields that are validated by the +`libphonenumber` library or its ports. + +---- +from phone_gen import PhoneNumber + +phone_number = PhoneNumber('GB') + +# Get a phone number +number = phone_number.get_number() +print(number) # +442908124840 + +# Get a country code +country_code = phone_number.get_code() +print(country_code) # 44 + +# Get a phone number without a country code +number = phone_number.get_number(full=False) +print(number) # 183782623 +---- + +Resources: + * libphonenumber https://github.com/google/libphonenumber + * Modified strgen https://github.com/paul-wolf/strgen +""" + +from ._generator import PhoneNumber try: from .__version__ import version as __version__ diff --git a/phone_gen/generator.py b/phone_gen/_generator.py similarity index 97% rename from phone_gen/generator.py rename to phone_gen/_generator.py index 36a946d..5af0ae6 100644 --- a/phone_gen/generator.py +++ b/phone_gen/_generator.py @@ -1,6 +1,3 @@ -""" -Modified StringGenerator https://github.com/paul-wolf/strgen -""" import random import string from abc import ABCMeta, abstractmethod @@ -44,6 +41,10 @@ class NumberGeneratorSyntaxException(NumberGeneratorException): """Syntax Exception""" +class PhoneNumberNotFound(Exception): + """Not found country""" + + class StringNode(metaclass=ABCMeta): """The abstract class for all nodes""" @@ -87,6 +88,10 @@ def render(self) -> str: class NumberGenerator: + """ + Modified StringGenerator https://github.com/paul-wolf/strgen + """ + _code = {"d": string.digits} def __init__(self, pattern: str): @@ -268,7 +273,7 @@ class PhoneNumber: def __init__(self, code: str): self._country = PATTERNS["data"].get(code.upper(), {}) if not self._country: - raise NumberGeneratorException("Not found country {}".format(code)) + raise PhoneNumberNotFound("Not found country {}".format(code)) self._generator = NumberGenerator(self._country["pattern"]) @property diff --git a/phone_gen/cli.py b/phone_gen/cli.py new file mode 100644 index 0000000..c37a406 --- /dev/null +++ b/phone_gen/cli.py @@ -0,0 +1,29 @@ +import argparse + +from . import __version__ +from ._generator import NumberGeneratorException, PhoneNumber, PhoneNumberNotFound + +parser = argparse.ArgumentParser( + prog="phone-gen", + add_help=True, + description="International phone number generation", +) +parser.add_argument( + "-v", "--version", action="version", version="%(prog)s {}".format(__version__) +) +parser.add_argument("country", help="Country code example: GB", metavar="country") +parser.add_argument( + "-n", + "--not-full", + action="store_false", + help="Get a phone number without a country code", + dest="full", +) + + +def main(): + args = parser.parse_args() + try: + print(PhoneNumber(args.country).get_number(args.full)) + except (PhoneNumberNotFound, NumberGeneratorException) as error: + print("Error: {}".format(error.args[0])) diff --git a/setup.py b/setup.py index a5fe949..1342de5 100644 --- a/setup.py +++ b/setup.py @@ -13,14 +13,17 @@ license='MIT License', author='tolstislon', author_email='tolstislon@gmail.com', - description='Phone number generator for libphonenumber', + description='International phone number generation', long_description=long_description, long_description_content_type='text/markdown', use_scm_version={"write_to": "phone_gen/__version__.py"}, setup_requires=['setuptools_scm'], + entry_points={ + 'console_scripts': ['phone-gen=phone_gen.cli:main'], + }, python_requires='>=3.5', include_package_data=True, - keywords=[], + keywords=['testing', 'test-data', 'phone-number', 'phone'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..91d9bf3 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,30 @@ +import os +import random + +import phonenumbers +import pytest + +from phone_gen.patterns import PATTERNS + + +@pytest.mark.parametrize('country', random.sample(tuple(PATTERNS['data'].keys()), 20)) +def test_get_country(capfd, country): + os.system('phone-gen {}'.format(country)) + captured = capfd.readouterr() + num_obg = phonenumbers.parse(captured.out, country) + assert phonenumbers.is_valid_number_for_region(num_obg, country) + + +@pytest.mark.parametrize('country', random.sample(tuple(PATTERNS['data'].keys()), 20)) +def test_get_without_country_code(capfd, country): + os.system('phone-gen {} -n'.format(country)) + captured = capfd.readouterr() + code = PATTERNS['data'][country]['code'] + num_obg = phonenumbers.parse('{}{}'.format(code, captured.out), country) + assert phonenumbers.is_valid_number_for_region(num_obg, country) + + +def test_invalid_country(capfd): + os.system('phone-gen qwe') + captured = capfd.readouterr() + assert captured.out.strip() == 'Error: Not found country qwe' diff --git a/tests/test_generator.py b/tests/test_generator.py index 2929df5..aefa289 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -2,7 +2,7 @@ import pytest -from phone_gen.generator import NumberGenerator, NumberGeneratorException, NumberGeneratorSyntaxException +from phone_gen._generator import NumberGenerator, NumberGeneratorException, NumberGeneratorSyntaxException def test_one(): diff --git a/tests/test_phone.py b/tests/test_phone.py index be68dc5..eb812b0 100644 --- a/tests/test_phone.py +++ b/tests/test_phone.py @@ -1,9 +1,11 @@ +import random + import phonenumbers import pytest -import random + from phone_gen import PhoneNumber +from phone_gen._generator import PhoneNumberNotFound from phone_gen.patterns import PATTERNS -from phone_gen.generator import NumberGeneratorException @pytest.mark.parametrize('count', range(15)) @@ -26,5 +28,5 @@ def test_get_code(): def test_invalid_country(): - with pytest.raises(NumberGeneratorException): + with pytest.raises(PhoneNumberNotFound): PhoneNumber('qwe')