Skip to content

Commit

Permalink
added json serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Istvan Bozso committed Feb 12, 2020
1 parent 2b17866 commit f1341ca
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 8 deletions.
6 changes: 5 additions & 1 deletion utils/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ def call(cls, cmd, *args, **kwargs):


class Path(object):
__slots__ = ("path",)
json_serialize = (
"path",
)

__slots__ = json_serialize

def __init__(self, path):
self.path = path
Expand Down
40 changes: 34 additions & 6 deletions utils/simpledoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import re
import os.path as path
import base64

class DocError(Exception):
pass
Expand Down Expand Up @@ -646,7 +647,7 @@ def inner(self, *args, **kwargs):
return inner

stags = {
"meta", "link", "img", "source", "iframe",
"meta", "link", "source", "iframe",
}

for stag in stags:
Expand Down Expand Up @@ -677,7 +678,8 @@ class ImagePaths(object):
__slots__ = ("paths", "doc", "width",)

def __init__(self, doc, width, *paths):
self.doc, self.width, self.paths = doc, width, frozenset(paths)
self.doc, self.width, self.paths, self.bundle = \
doc, width, frozenset(paths), doc.bundle

def search(self, name):
m = map(lambda p: path.join(p, name), self.paths)
Expand Down Expand Up @@ -731,11 +733,16 @@ def img(self, name, *args, **kwargs):


class HTML(SimpleDoc):
@classmethod
def new(cls, *args, **kwargs):
kwargs.setdefault("stag_end", ">")
return cls(*args, **kwargs)
__slots__ = (
"bundle",
)

def __init__(self, *args, **kwargs):
kwargs.setdefault("stag_end", ">")
self.bundle = bool(kwargs.get("bundle", False))

SimpleDoc.__init__(self, *args, **kwargs)


@staticmethod
def presentation(*args, **kwargs):
Expand All @@ -744,6 +751,27 @@ def presentation(*args, **kwargs):
def use(self, lib):
lib.add(self)


def img(self, *args, **kwargs):
path = kwargs.pop("src")

if self.bundle:
ext = path.splitext(path)[1]

with open(path, "rb") as f:
enc = base64.b64encode(f.read())

src = "data:image/%s;base64,%s" % (
ext, enc
)

else:
src = path

kwargs["src"] = path

self.stag("img", *args, **kwargs)

def image_paths(self, width, *paths):
return ImagePaths(self, width, *paths)

Expand Down
90 changes: 89 additions & 1 deletion utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import sys
import functools as ft
import json

__all__ = (
"Seq", "flat", "new_type", "str_t", "isiter", "all_same",
"make_object", "cat", "compose", "fs", "load", "Enum", "namespace",
"export",
"export", "JSONSave"
)

py3 = sys.version_info[0] == 3
Expand Down Expand Up @@ -279,3 +280,90 @@ def enum(self, **kwargs):

def load(name, path):
return SourceFileLoader(name, path).load_module()


class JSONSave(object):

class Encoder(json.JSONEncoder):
def default(self, obj):
try:
return {
key: getattr(obj, key)
for key in obj.json_serialize
}
except AttributeError:
return json.JSONEncoder.default(self, obj)


json_options = {
"indent": 4,
"cls": Encoder,
}

def save_to(self, path, **kwargs):
with open(path, "w") as f:
self.save(f)

@staticmethod
def save_any(obj, writable, **kwargs):
try:
kwargs.update(obj.json_options)
except AttributeError:
kwargs.update(JSONSave.json_options)

json.dump(obj, writable, **kwargs)


def save(self, writable, **kwargs):
self.save_any(self, writable, **kwargs)

@classmethod
def from_dict(cls, d, *args, **kwargs):
ret = cls(*args, **kwargs)

for key in cls.json_serialize:
try:
val = d[key]
except KeyError:
val = None

setattr(ret, key, val)

return ret

@classmethod
def load_from(cls, path, *args, **kwargs):
ret = cls(*args, **kwargs)

with open(path, "r") as f:
ret.load(f, **kwargs)

return ret

def load(self, readable, **kwargs):
kwargs.update(self.json_options)

self = json.load(self, readable, **kwargs)

@classmethod
def tree_from(cls, path, *args, **kwargs):
with open(path, "r") as f:
return cls.load_tree(f, *args, **kwargs)

@classmethod
def load_tree(cls, readable, *args, **kwargs):
d = json.load(readable, **kwargs, **self.json_options)

dd = {}
for key, val in d.items():
if isinstance(val, dict):
dd[key] = cls.from_dict(val, *args, **kwargs)
else:
dd[key] = tuple(
cls.from_dict(elem, *args, **kwargs)
for elem in val
)

return namespace(**dd)


0 comments on commit f1341ca

Please sign in to comment.