xmlgenerator 0.2.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xmlgenerator
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Generates XML documents from XSD schemas
5
5
  Home-page: https://github.com/lexakimov/xmlgenerator
6
6
  Author: Alexey Akimov
@@ -247,6 +247,7 @@ In the `value_override` sections, you can specify either a string value or speci
247
247
  | `output_filename` | String described by the `output_filename_template` configuration parameter |
248
248
  | `uuid` | Random UUIDv4 |
249
249
  | `regex("pattern")` | Random string value matching the specified regular expression |
250
+ | `any('A', "B", C)` | Random value from enumeration |
250
251
  | `number(A, B)` | Random number between A and B |
251
252
  | `date("2010-01-01", "2025-01-01")` | Random date within the specified range |
252
253
  | `last_name` | Last Name |
@@ -218,6 +218,7 @@ In the `value_override` sections, you can specify either a string value or speci
218
218
  | `output_filename` | String described by the `output_filename_template` configuration parameter |
219
219
  | `uuid` | Random UUIDv4 |
220
220
  | `regex("pattern")` | Random string value matching the specified regular expression |
221
+ | `any('A', "B", C)` | Random value from enumeration |
221
222
  | `number(A, B)` | Random number between A and B |
222
223
  | `date("2010-01-01", "2025-01-01")` | Random date within the specified range |
223
224
  | `last_name` | Last Name |
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='xmlgenerator',
5
- version='0.2.0',
5
+ version='0.2.1',
6
6
  packages=find_packages(exclude=("tests", "tests.*")),
7
7
  entry_points={
8
8
  'console_scripts': [
@@ -49,7 +49,7 @@ def _main():
49
49
 
50
50
  logger.debug('found %s schemas', len(xsd_files))
51
51
  for xsd_file in xsd_files:
52
- logger.debug('processing schema: %s', xsd_file.name)
52
+ logger.info('processing schema: %s', xsd_file.name)
53
53
 
54
54
  # get configuration override for current schema
55
55
  local_config = config.get_for_file(xsd_file.name)
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  import re
3
3
 
4
- import rstr
5
4
  import xmlschema
6
5
  from lxml import etree
7
6
  from xmlschema.validators import XsdComplexType, XsdAtomicRestriction, XsdTotalDigitsFacet, XsdElement, \
@@ -296,10 +295,11 @@ class XmlGenerator:
296
295
 
297
296
  def _generate_string(self, target_name, patterns, min_length, max_length):
298
297
  rnd = self.randomizer.rnd
298
+ re_gen = self.randomizer.re_gen
299
299
  if patterns is not None:
300
300
  # Генерация строки по regex
301
301
  random_pattern = rnd.choice(patterns)
302
- xeger = rstr.xeger(random_pattern.attrib['value'])
302
+ xeger = re_gen.xeger(random_pattern.attrib['value'])
303
303
  xeger = re.sub(r'\s', ' ', xeger)
304
304
  if min_length > -1 and len(xeger) < min_length:
305
305
  logger.warning(
@@ -358,29 +358,43 @@ class XmlGenerator:
358
358
  raise RuntimeError("not yet implemented")
359
359
 
360
360
  def _generate_datetime(self):
361
- raise RuntimeError("not yet implemented")
361
+ random_datetime = self.randomizer.random_datetime()
362
+ formatted = random_datetime.isoformat()
363
+ return formatted
362
364
 
363
365
  def _generate_date(self):
364
- raise RuntimeError("not yet implemented")
366
+ random_date = self.randomizer.random_date()
367
+ formatted = random_date.isoformat()
368
+ return formatted
365
369
 
366
370
  def _generate_time(self):
367
- raise RuntimeError("not yet implemented")
371
+ random_time = self.randomizer.random_time()
372
+ formatted = random_time.isoformat()
373
+ return formatted
368
374
 
369
375
  def _generate_gyearmonth(self):
370
- raise RuntimeError("not yet implemented")
376
+ random_date = self.randomizer.random_date()
377
+ formatted = random_date.strftime('%Y-%m')
378
+ return formatted
371
379
 
372
380
  def _generate_gyear(self):
373
381
  rnd = self.randomizer.rnd
374
- return rnd.randint(2000, 2050)
382
+ return str(rnd.randint(2000, 2050))
375
383
 
376
384
  def _generate_gmonthday(self):
377
- raise RuntimeError("not yet implemented")
385
+ random_date = self.randomizer.random_date()
386
+ formatted = random_date.strftime('--%m-%d')
387
+ return formatted
378
388
 
379
389
  def _generate_gday(self):
380
- raise RuntimeError("not yet implemented")
390
+ random_date = self.randomizer.random_date()
391
+ formatted = random_date.strftime('---%d')
392
+ return formatted
381
393
 
382
394
  def _generate_gmonth(self):
383
- raise RuntimeError("not yet implemented")
395
+ random_date = self.randomizer.random_date()
396
+ formatted = random_date.strftime('--%m--')
397
+ return formatted
384
398
 
385
399
  def _generate_hex_binary(self):
386
400
  raise RuntimeError("not yet implemented")
@@ -2,8 +2,9 @@ import logging
2
2
  import random
3
3
  import string
4
4
  import sys
5
- from datetime import datetime, timedelta
5
+ from datetime import datetime, date, time, timedelta
6
6
 
7
+ import rstr
7
8
  from faker import Faker
8
9
 
9
10
  logger = logging.getLogger(__name__)
@@ -20,6 +21,7 @@ class Randomizer:
20
21
  self.rnd = random.Random(seed)
21
22
  self.fake = Faker(locale='ru_RU')
22
23
  self.fake.seed_instance(seed)
24
+ self.re_gen = rstr.Rstr(self.rnd)
23
25
 
24
26
  def ascii_string(self, min_length=-1, max_length=-1):
25
27
  min_length = min_length if min_length and min_length > -1 else 1
@@ -31,7 +33,31 @@ class Randomizer:
31
33
  letters = string.ascii_letters # Все буквы латиницы (a-z, A-Z)
32
34
  return ''.join(self.rnd.choice(letters) for _ in range(length))
33
35
 
34
- def random_date(self, start_date: str, end_date: str) -> datetime:
36
+ def random_date(self, start_date: str = '1990-01-01', end_date: str = '2025-12-31') -> date:
37
+ # Преобразуем строки в объекты datetime
38
+ start = date.fromisoformat(start_date)
39
+ end = date.fromisoformat(end_date)
40
+
41
+ # Вычисляем разницу в днях между начальной и конечной датой
42
+ delta = (end - start).days
43
+
44
+ # Генерируем случайное количество дней в пределах delta
45
+ random_days = self.rnd.randint(0, delta)
46
+
47
+ # Добавляем случайное количество дней к начальной дате
48
+ return start + timedelta(days=random_days)
49
+
50
+ def random_time(self, start_time: str = '00:00:00', end_time: str = '23:59:59') -> time:
51
+ start = time.fromisoformat(start_time)
52
+ end = time.fromisoformat(end_time)
53
+
54
+ random_h = self.rnd.randint(start.hour, end.hour)
55
+ random_m = self.rnd.randint(start.minute, end.minute)
56
+ random_s = self.rnd.randint(start.second, end.second)
57
+
58
+ return time(hour=random_h, minute=random_m, second=random_s)
59
+
60
+ def random_datetime(self, start_date: str = '1990-01-01', end_date: str = '2025-12-31') -> datetime:
35
61
  # Преобразуем строки в объекты datetime
36
62
  start = datetime.strptime(start_date, "%Y-%m-%d")
37
63
  end = datetime.strptime(end_date, "%Y-%m-%d")
@@ -1,17 +1,16 @@
1
1
  import logging
2
2
  import re
3
- import uuid
4
-
5
- import rstr
6
3
 
7
4
  from xmlgenerator.randomization import Randomizer
8
5
 
9
6
  __all__ = ['Substitutor']
10
7
 
11
- _pattern = re.compile(pattern=r'\{\{\s*(?:(?P<function>\S*?)(?:\(\s*(?P<argument>[^)]*)\s*\))?\s*(?:\|\s*(?P<modifier>.*?))?)?\s*}}')
8
+ _pattern = re.compile(
9
+ r'\{\{\s*(?:(?P<function>\S*?)(?:\(\s*(?P<argument>[^)]*)\s*\))?\s*(?:\|\s*(?P<modifier>.*?))?)?\s*}}')
12
10
 
13
11
  logger = logging.getLogger(__name__)
14
12
 
13
+
15
14
  class Substitutor:
16
15
  def __init__(self, randomizer: Randomizer):
17
16
  fake = randomizer.fake
@@ -20,18 +19,19 @@ class Substitutor:
20
19
  self._global_context = {}
21
20
  self.providers_dict = {
22
21
  # Функции локального контекста
23
- "source_filename": lambda: self._local_context["source_filename"],
24
- "source_extracted": lambda: self._local_context["source_extracted"],
25
- "output_filename": lambda: self.get_output_filename(),
26
-
27
- 'uuid': lambda: str(uuid.uuid4()),
28
- "regex": lambda a: rstr.xeger(a),
29
- "number": self._rand_int,
30
- "date": self._rand_date,
31
-
32
- "last_name": fake.last_name_male,
33
- "first_name": fake.first_name_male,
34
- "middle_name": fake.middle_name_male,
22
+ 'source_filename': lambda: self._local_context["source_filename"],
23
+ 'source_extracted': lambda: self._local_context["source_extracted"],
24
+ 'output_filename': lambda: self.get_output_filename(),
25
+
26
+ 'uuid': lambda: fake.uuid4(),
27
+ 'regex': self._rand_regex,
28
+ 'any': self._rand_any,
29
+ 'number': self._rand_int,
30
+ 'date': self._rand_date,
31
+
32
+ 'last_name': fake.last_name_male,
33
+ 'first_name': fake.first_name_male,
34
+ 'middle_name': fake.middle_name_male,
35
35
  'address_text': fake.address,
36
36
  'administrative_unit': fake.administrative_unit,
37
37
  'house_number': fake.building_number,
@@ -48,6 +48,16 @@ class Substitutor:
48
48
  'snils_formatted': randomizer.snils_formatted,
49
49
  }
50
50
 
51
+ def _rand_regex(self, a):
52
+ pattern = a.strip("'").strip('"')
53
+ return self.randomizer.re_gen.xeger(pattern)
54
+
55
+ def _rand_any(self, a):
56
+ args = str(a).split(sep=",")
57
+ value = self.randomizer.rnd.choice(args)
58
+ value = value.strip(' ').strip("'").strip('"')
59
+ return value
60
+
51
61
  def _rand_int(self, a):
52
62
  args = str(a).split(sep=",")
53
63
  return str(self.randomizer.rnd.randint(int(args[0]), int(args[1])))
@@ -56,8 +66,8 @@ class Substitutor:
56
66
  args = str(a).split(sep=",")
57
67
  date_from = args[0].strip(' ').strip("'").strip('"')
58
68
  date_until = args[1].strip(' ').strip("'").strip('"')
59
- random_date = self.randomizer.random_date(date_from, date_until)
60
- return random_date.strftime('%Y%m%d') # TODO externalize pattern
69
+ random_date = self.randomizer.random_datetime(date_from, date_until)
70
+ return random_date.strftime('%Y%m%d') # TODO externalize pattern
61
71
 
62
72
  def reset_context(self, xsd_filename, config_local):
63
73
  self._local_context.clear()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xmlgenerator
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Generates XML documents from XSD schemas
5
5
  Home-page: https://github.com/lexakimov/xmlgenerator
6
6
  Author: Alexey Akimov
@@ -247,6 +247,7 @@ In the `value_override` sections, you can specify either a string value or speci
247
247
  | `output_filename` | String described by the `output_filename_template` configuration parameter |
248
248
  | `uuid` | Random UUIDv4 |
249
249
  | `regex("pattern")` | Random string value matching the specified regular expression |
250
+ | `any('A', "B", C)` | Random value from enumeration |
250
251
  | `number(A, B)` | Random number between A and B |
251
252
  | `date("2010-01-01", "2025-01-01")` | Random date within the specified range |
252
253
  | `last_name` | Last Name |
File without changes
File without changes