irongit

A parser inspired by the django orm.

was able to upload

huncholanehuncholaneauthored
parent 97bc066commit 3f1d5c2aca9918b23c8f8bcbe6b081d5895ed4f1Browse files

8 files changed, +187 -0

+3-0README.md
@@ -0,0 +1,3 @@
1+# Gparser
2+
3+### Parser Created by Ghost Systems
+2-0build/lib/parsers/__init__.py
@@ -0,0 +1,2 @@
1+from .parser import Parser
2+from .fields import *
+18-0build/lib/parsers/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-0build/lib/parsers/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-0build/lib/parsers/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-0build/lib/parsers/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-0build/lib/parsers/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
+22-0setup.py
@@ -1 +1,23 @@
11 import setuptools
2+
3+
4+with open('README.md', 'r') as fh:
5+ long_description = fh.read()
6+
7+
8+setuptools.setup(
9+ name='ghostparser',
10+ version='0.11',
11+ author="Lane Henslee",
12+ author_email="huncho@ghostsystems.io",
13+ description="A django orm inspired parser.",
14+ long_description=long_description,
15+ long_description_content_type="text/markdown",
16+ url="https://github.com/javatechy/dokr",
17+ packages=setuptools.find_packages(),
18+ classifiers=[
19+ "Programming Language :: Python :: 3",
20+ "License :: OSI Approved :: MIT License",
21+ "Operating System :: OS Independent",
22+ ],
23+)