irongit

A parser inspired by the django orm.

firrst commit

huncholanehuncholaneauthored
commit 97bc0667543b77bc2670e554de504dfaa4d0dfa6Browse files

14 files changed, +180 -0

+17-0main.py
@@ -0,0 +1,17 @@
1+import parsers
2+
3+
4+class Test(parsers.Parser):
5+ a = parsers.BooleanField()
6+ b = parsers.HourMinuteIntField()
7+
8+ def __str__(self):
9+ return f'{self.id} {self.a}'
10+
11+
12+t1 = Test(a='23', b='02:32')
13+t1.save()
14+t2 = Test(a='', b='2342')
15+t2.save()
16+for obj in Test.objects.all():
17+ print(obj.a)
+2-0parsers/__init__.py
@@ -0,0 +1,2 @@
1+from .parser import Parser
2+from .fields import *
+0-0parsers/__pycache__/__init__.cpython-310.pyc

Binary file changed.

+0-0parsers/__pycache__/exceptions.cpython-310.pyc

Binary file changed.

+0-0parsers/__pycache__/fields.cpython-310.pyc

Binary file changed.

+0-0parsers/__pycache__/manager.cpython-310.pyc

Binary file changed.

+0-0parsers/__pycache__/parser.cpython-310.pyc

Binary file changed.

+0-0parsers/__pycache__/translators.cpython-310.pyc

Binary file changed.

+18-0parsers/exceptions.py
@@ -0,0 +1,18 @@
1+class UniqueParseError(Exception):
2+ def __init__(self, field, val) -> None:
3+ super().__init__(f'{field} must be unique. {val} already exists.')
4+
5+
6+class MissingFieldsParseError(Exception):
7+ def __init__(self, cls, missing_fields):
8+ super().__init__(f'{cls} missing {missing_fields}.')
9+
10+
11+class ExtraFieldsParseError(Exception):
12+ def __init__(self, cls, extra_fields):
13+ super().__init__(f'{cls} does not contain {extra_fields}.')
14+
15+
16+class CreateWithIdParseError(Exception):
17+ def __init__(self, cls):
18+ super().__init__(f'{cls} cannot use id on creation.')
+45-0parsers/fields.py
@@ -0,0 +1,45 @@
1+from . import translators
2+
3+
4+def default_function(x):
5+ return x
6+
7+
8+class Field:
9+ translator = default_function
10+
11+ def __init__(self, translator=None, unique=True):
12+ if translator:
13+ self.translator = translator
14+ self.unique = unique
15+
16+ def convert(self, val):
17+ return self.translator(val)
18+
19+
20+class HourMinuteDeltaField(Field):
21+ translator = translators.hour_minute_to_delta
22+
23+
24+class HourMinuteIntField(Field):
25+ translator = translators.hour_minute_to_int
26+
27+
28+class PhoneField(Field):
29+ translator = translators.phone
30+
31+
32+class StrField(Field):
33+ translator = str
34+
35+
36+class IntField(Field):
37+ translator = int
38+
39+
40+class FloatField(Field):
41+ translator = float
42+
43+
44+class BooleanField(Field):
45+ translator = bool
+26-0parsers/manager.py
@@ -0,0 +1,26 @@
1+from .exceptions import *
2+
3+
4+class Manager:
5+
6+ def __init__(self):
7+ self.objects = []
8+
9+ def set_cls(self, cls):
10+ """The Parser object tells the manager to use it"""
11+ self.cls = cls
12+
13+ def create(self, **kwargs):
14+ """Create and save object"""
15+ cls = self.cls
16+ obj = cls(**kwargs)
17+ self.append(obj)
18+
19+ def all(self):
20+ return self.objects
21+
22+ def append(self, obj):
23+ self.objects.append(obj)
24+
25+ def count(self):
26+ return len(self.objects)
+39-0parsers/parser.py
@@ -0,0 +1,39 @@
1+from .manager import Manager
2+from .fields import Field, IntField
3+from .exceptions import *
4+
5+
6+class Parser:
7+ id = IntField()
8+ objects = Manager()
9+
10+ def __init__(self, **kwargs):
11+ self.objects.set_cls(self)
12+ missing_fields = set(self.fields())-set(kwargs)
13+ if 'id' not in missing_fields:
14+ raise CreateWithIdParseError(self)
15+ missing_fields = missing_fields-{'id'}
16+ if missing_fields:
17+ raise MissingFieldsParseError(self, missing_fields)
18+ extra_fields = set(kwargs)-set(self.fields())
19+ if extra_fields:
20+ raise ExtraFieldsParseError(self, extra_fields)
21+ kwargs['id'] = self.objects.count()
22+ for name, field in self.field_items():
23+ setattr(self, name, field.convert(kwargs[name]))
24+
25+ def save(self):
26+ self.objects.append(self)
27+
28+ def fields(self):
29+ """Gets the fields for the current object"""
30+ fields = {}
31+ for attr in dir(self):
32+ item = getattr(self, attr)
33+ if issubclass(type(item), Field):
34+ fields[attr] = item
35+ return fields
36+
37+ def field_items(self):
38+ """Returns key value pairs for fields"""
39+ return self.fields().items()
+32-0parsers/translators.py
@@ -0,0 +1,32 @@
1+"""
2+Translator functions for the basics.
3+"""
4+import re
5+import datetime as dt
6+
7+
8+def split_hour_minute(str):
9+ """Extracts hours and minutes into separate strings"""
10+ str = ''.join(re.findall(r'\d+', str))
11+ return str[:-2], str[-2:]
12+
13+
14+def hour_minute_to_delta(cls, str):
15+ """Converts hour and minute string into a time delta"""
16+ hours, minutes = split_hour_minute(str)
17+ return dt.timedelta(hours=int(hours), minutes=int(minutes))
18+
19+
20+def hour_minute_to_int(cls, str):
21+ """Converts hours and minutes to a total number of minutes"""
22+ hours, minutes = split_hour_minute(str)
23+ return int(minutes)+int(hours)*60
24+
25+
26+def phone(cls, str):
27+ """Converts numbers to a phone number with country code readiness"""
28+ nums = ''.join(re.findall(r'\d+'), str)
29+ if nums[:3] == '011':
30+ return '+'+nums[3:]
31+ else:
32+ return '+1'+nums
+1-0setup.py
@@ -0,0 +1 @@
1+import setuptools