_faker.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. """ Integrate Faker to the Mixer. """
  2. import decimal as dc
  3. import locale as pylocale
  4. from collections import defaultdict
  5. from faker import Factory, Generator
  6. from faker.config import DEFAULT_LOCALE, AVAILABLE_LOCALES, PROVIDERS
  7. from faker.providers import BaseProvider
  8. SMALLINT = 32768 # Safe in most databases according to Django docs
  9. GENRES = ('general', 'pop', 'dance', 'traditional', 'rock', 'alternative', 'rap', 'country',
  10. 'jazz', 'gospel', 'latin', 'reggae', 'comedy', 'historical', 'action', 'animation',
  11. 'documentary', 'family', 'adventure', 'fantasy', 'drama', 'crime', 'horror', 'music',
  12. 'mystery', 'romance', 'sport', 'thriller', 'war', 'western', 'fiction', 'epic',
  13. 'tragedy', 'parody', 'pastoral', 'culture', 'art', 'dance', 'drugs', 'social')
  14. class MixerProvider(BaseProvider):
  15. """ Implement some mixer methods. """
  16. def __init__(self, generator):
  17. self.providers = []
  18. self.generator = generator
  19. def load(self, providers=PROVIDERS, locale=None):
  20. if locale is None:
  21. locale = self.generator.locale
  22. for pname in providers:
  23. pcls, lang_found = Factory._get_provider_class(pname, locale)
  24. provider = pcls(self.generator)
  25. provider.__provider__ = pname
  26. provider.__lang__ = lang_found
  27. self.generator.add_provider(provider)
  28. def big_integer(self):
  29. """ Get a big integer.
  30. Get integer from -9223372036854775808 to 9223372036854775807.
  31. """
  32. return self.generator.random_int(-9223372036854775808, 9223372036854775807)
  33. def ip_generic(self, protocol=None):
  34. """ Get IP (v4 or v6) address.
  35. :param protocol:
  36. Set protocol to 'ipv4' or 'ipv6'. Generate either IPv4 or
  37. IPv6 address if none.
  38. """
  39. if protocol == 'ipv4':
  40. return self.generator.ipv4()
  41. if protocol == 'ipv6':
  42. return self.generator.ipv6()
  43. return self.generator.ipv4() if self.generator.boolean() else self.generator.ipv6()
  44. def positive_decimal(self, **kwargs):
  45. """ Get a positive decimal. """
  46. return self.generator.pydecimal(positive=True, **kwargs)
  47. def positive_integer(self, max=2147483647): # noqa
  48. """ Get a positive integer. """
  49. return self.random_int(0, max=max) # noqa
  50. def small_integer(self, min=-SMALLINT, max=SMALLINT): # noqa
  51. """ Get a positive integer. """
  52. return self.random_int(min=min, max=max) # noqa
  53. def small_positive_integer(self, max=SMALLINT): # noqa
  54. """ Get a positive integer. """
  55. return self.random_int(0, max=max) # noqa
  56. @staticmethod
  57. def uuid():
  58. import uuid
  59. return str(uuid.uuid1())
  60. def genre(self):
  61. return self.random_element(GENRES)
  62. def percent(self):
  63. return self.random_int(0, 100)
  64. def percent_decimal(self):
  65. return dc.Decimal("0.%d" % self.random_int(0, 99)) + dc.Decimal('0.01')
  66. def title(self):
  67. words = self.generator.words(6)
  68. return " ".join(words).title()
  69. def coordinates(self):
  70. return (self.generator.latitude(), self.generator.longitude())
  71. def pybytes(self, size=20):
  72. return self.pystr(size).encode('utf-8')
  73. class MixerGenerator(Generator):
  74. """ Support dynamic locales switch. """
  75. def __init__(self, locale=DEFAULT_LOCALE, providers=PROVIDERS, **config):
  76. self._locale = None
  77. self._envs = defaultdict(self.__create_env)
  78. self.locale = locale
  79. super(MixerGenerator, self).__init__(**config)
  80. self.env.load(providers)
  81. def __create_env(self):
  82. return MixerProvider(self)
  83. def __getattr__(self, name):
  84. return getattr(self.env, name)
  85. @property
  86. def providers(self):
  87. return self.env.providers
  88. @providers.setter
  89. def providers(self, value):
  90. self.env.providers = value
  91. @property
  92. def locale(self):
  93. return self._locale
  94. @locale.setter
  95. def locale(self, value):
  96. value = pylocale.normalize(value.replace('-', '_')).split('.')[0]
  97. if value not in AVAILABLE_LOCALES:
  98. value = DEFAULT_LOCALE
  99. if value == self._locale:
  100. return None
  101. nenv = self._envs[value]
  102. senv = self.env
  103. self._locale = value
  104. if senv.providers and not nenv.providers:
  105. nenv.load([p.__provider__ for p in senv.providers], value)
  106. @property
  107. def env(self):
  108. return self._envs[self._locale]
  109. def set_formatter(self, name, method):
  110. if not hasattr(self.env, name):
  111. setattr(self.env, name, method)
  112. faker = MixerGenerator()