2020-03-21 21:15:02 +01:00
|
|
|
import datetime
|
2020-03-21 22:43:14 +01:00
|
|
|
import json
|
2020-03-21 21:15:02 +01:00
|
|
|
|
2020-03-22 19:27:30 +01:00
|
|
|
data_type = "__data_type"
|
|
|
|
content = "__content"
|
|
|
|
|
2020-03-21 21:15:02 +01:00
|
|
|
|
2020-03-31 10:31:05 +02:00
|
|
|
class Encoder():
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.custom = {Encoder:(lambda x:x, lambda x:x)}
|
|
|
|
self.JSONEncoder.custom = self.custom
|
2020-03-22 19:27:30 +01:00
|
|
|
def register(self, type_, encode, decode):
|
|
|
|
self.custom.update({type_: (encode, decode)})
|
|
|
|
|
|
|
|
def hook(self, dct):
|
|
|
|
if data_type in dct:
|
|
|
|
for ty in self.custom.keys():
|
|
|
|
if str(ty) == dct[data_type]:
|
|
|
|
return self.custom[ty][1](dct[content])
|
|
|
|
if dct[data_type] == "datetime.datetime":
|
|
|
|
return datetime.datetime.fromisoformat(dct['iso'])
|
|
|
|
elif dct[data_type] == "datetime.timedelta":
|
|
|
|
return datetime.timedelta(seconds=dct['totalseconds'])
|
|
|
|
return dct
|
2020-03-31 10:31:05 +02:00
|
|
|
class JSONEncoder(json.JSONEncoder) :
|
|
|
|
def default(self, obj):
|
|
|
|
if isinstance(obj, tuple(self.custom.keys())):
|
|
|
|
return {data_type: f'{type(obj)}', content: self.custom[type(obj)][0](obj)}
|
|
|
|
if isinstance(obj, (datetime.datetime)):
|
|
|
|
return {data_type: 'datetime.datetime', 'iso': obj.isoformat()}
|
|
|
|
if isinstance(obj, (datetime.timedelta)):
|
|
|
|
return {data_type: 'datetime.timedelta', 'totalseconds': obj.total_seconds()}
|
|
|
|
return json.JSONEncoder.default(self, obj)
|