mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Code cleanup / reorganize
This commit is contained in:
parent
5631719836
commit
a263039958
5 changed files with 46 additions and 56 deletions
|
@ -4,7 +4,9 @@ import re
|
||||||
import logging
|
import logging
|
||||||
import argparse
|
import argparse
|
||||||
import copy
|
import copy
|
||||||
|
import datetime
|
||||||
from collections import deque, OrderedDict
|
from collections import deque, OrderedDict
|
||||||
|
from json.encoder import JSONEncoder
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
|
@ -560,3 +562,40 @@ class PositionalsFirstHelpFormatter(argparse.HelpFormatter):
|
||||||
|
|
||||||
# prefix with 'usage:'
|
# prefix with 'usage:'
|
||||||
return "%s%s\n\n" % (prefix, usage)
|
return "%s%s\n\n" % (prefix, usage)
|
||||||
|
|
||||||
|
|
||||||
|
class JSONExtendedEncoder(JSONEncoder):
|
||||||
|
|
||||||
|
"""Extended JSON encoder
|
||||||
|
|
||||||
|
Extend default JSON encoder to recognize more types and classes. It will
|
||||||
|
never raise an exception if the object can't be encoded and return its repr
|
||||||
|
instead.
|
||||||
|
|
||||||
|
The following objects and types are supported:
|
||||||
|
- set: converted into list
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def default(self, o):
|
||||||
|
|
||||||
|
import pytz # Lazy loading, this takes like 3+ sec on a RPi2 ?!
|
||||||
|
|
||||||
|
"""Return a serializable object"""
|
||||||
|
# Convert compatible containers into list
|
||||||
|
if isinstance(o, set) or (hasattr(o, "__iter__") and hasattr(o, "next")):
|
||||||
|
return list(o)
|
||||||
|
|
||||||
|
# Display the date in its iso format ISO-8601 Internet Profile (RFC 3339)
|
||||||
|
if isinstance(o, datetime.date):
|
||||||
|
if o.tzinfo is None:
|
||||||
|
o = o.replace(tzinfo=pytz.utc)
|
||||||
|
return o.isoformat()
|
||||||
|
|
||||||
|
# Return the repr for object that json can't encode
|
||||||
|
logger.warning(
|
||||||
|
"cannot properly encode in JSON the object %s, " "returned repr is: %r",
|
||||||
|
type(o),
|
||||||
|
o,
|
||||||
|
)
|
||||||
|
return repr(o)
|
||||||
|
|
|
@ -21,9 +21,9 @@ from moulinette.core import MoulinetteError, MoulinetteValidationError
|
||||||
from moulinette.interfaces import (
|
from moulinette.interfaces import (
|
||||||
BaseActionsMapParser,
|
BaseActionsMapParser,
|
||||||
ExtendedArgumentParser,
|
ExtendedArgumentParser,
|
||||||
|
JSONExtendedEncoder,
|
||||||
)
|
)
|
||||||
from moulinette.utils import log
|
from moulinette.utils import log
|
||||||
from moulinette.utils.serialize import JSONExtendedEncoder
|
|
||||||
from moulinette.utils.text import random_ascii
|
from moulinette.utils.text import random_ascii
|
||||||
|
|
||||||
logger = log.getLogger("moulinette.interface.api")
|
logger = log.getLogger("moulinette.interface.api")
|
||||||
|
|
|
@ -5,7 +5,7 @@ import sys
|
||||||
import getpass
|
import getpass
|
||||||
import locale
|
import locale
|
||||||
import logging
|
import logging
|
||||||
from argparse import SUPPRESS
|
import argparse
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ from moulinette.core import MoulinetteError, MoulinetteValidationError
|
||||||
from moulinette.interfaces import (
|
from moulinette.interfaces import (
|
||||||
BaseActionsMapParser,
|
BaseActionsMapParser,
|
||||||
ExtendedArgumentParser,
|
ExtendedArgumentParser,
|
||||||
|
JSONExtendedEncoder,
|
||||||
)
|
)
|
||||||
from moulinette.utils import log
|
from moulinette.utils import log
|
||||||
|
|
||||||
|
@ -32,17 +33,14 @@ from moulinette.utils import log
|
||||||
# But it display instead:
|
# But it display instead:
|
||||||
# Error: unable to parse arguments 'firewall' because: sequence item 0: expected str instance, NoneType found
|
# Error: unable to parse arguments 'firewall' because: sequence item 0: expected str instance, NoneType found
|
||||||
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
|
|
||||||
def monkey_get_action_name(argument):
|
def monkey_get_action_name(argument):
|
||||||
if argument is None:
|
if argument is None:
|
||||||
return None
|
return None
|
||||||
elif argument.option_strings:
|
elif argument.option_strings:
|
||||||
return "/".join(argument.option_strings)
|
return "/".join(argument.option_strings)
|
||||||
elif argument.metavar not in (None, SUPPRESS):
|
elif argument.metavar not in (None, argparse.SUPPRESS):
|
||||||
return argument.metavar
|
return argument.metavar
|
||||||
elif argument.dest not in (None, SUPPRESS):
|
elif argument.dest not in (None, argparse.SUPPRESS):
|
||||||
return argument.dest
|
return argument.dest
|
||||||
elif argument.choices:
|
elif argument.choices:
|
||||||
return "{" + ",".join(argument.choices) + "}"
|
return "{" + ",".join(argument.choices) + "}"
|
||||||
|
@ -307,7 +305,7 @@ class ActionsMapParser(BaseActionsMapParser):
|
||||||
|
|
||||||
# Append each top parser action to the global group
|
# Append each top parser action to the global group
|
||||||
for action in top_parser._actions:
|
for action in top_parser._actions:
|
||||||
action.dest = SUPPRESS
|
action.dest = argparse.SUPPRESS
|
||||||
self.global_parser._add_action(action)
|
self.global_parser._add_action(action)
|
||||||
|
|
||||||
# Implement virtual properties
|
# Implement virtual properties
|
||||||
|
@ -509,8 +507,6 @@ class Interface:
|
||||||
if output_as:
|
if output_as:
|
||||||
if output_as == "json":
|
if output_as == "json":
|
||||||
import json
|
import json
|
||||||
from moulinette.utils.serialize import JSONExtendedEncoder
|
|
||||||
|
|
||||||
print(json.dumps(ret, cls=JSONExtendedEncoder))
|
print(json.dumps(ret, cls=JSONExtendedEncoder))
|
||||||
else:
|
else:
|
||||||
plain_print_dict(ret)
|
plain_print_dict(ret)
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
import logging
|
|
||||||
from json.encoder import JSONEncoder
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
logger = logging.getLogger("moulinette.utils.serialize")
|
|
||||||
|
|
||||||
|
|
||||||
# JSON utilities -------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
class JSONExtendedEncoder(JSONEncoder):
|
|
||||||
|
|
||||||
"""Extended JSON encoder
|
|
||||||
|
|
||||||
Extend default JSON encoder to recognize more types and classes. It will
|
|
||||||
never raise an exception if the object can't be encoded and return its repr
|
|
||||||
instead.
|
|
||||||
|
|
||||||
The following objects and types are supported:
|
|
||||||
- set: converted into list
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def default(self, o):
|
|
||||||
|
|
||||||
import pytz # Lazy loading, this takes like 3+ sec on a RPi2 ?!
|
|
||||||
|
|
||||||
"""Return a serializable object"""
|
|
||||||
# Convert compatible containers into list
|
|
||||||
if isinstance(o, set) or (hasattr(o, "__iter__") and hasattr(o, "next")):
|
|
||||||
return list(o)
|
|
||||||
|
|
||||||
# Display the date in its iso format ISO-8601 Internet Profile (RFC 3339)
|
|
||||||
if isinstance(o, datetime.date):
|
|
||||||
if o.tzinfo is None:
|
|
||||||
o = o.replace(tzinfo=pytz.utc)
|
|
||||||
return o.isoformat()
|
|
||||||
|
|
||||||
# Return the repr for object that json can't encode
|
|
||||||
logger.warning(
|
|
||||||
"cannot properly encode in JSON the object %s, " "returned repr is: %r",
|
|
||||||
type(o),
|
|
||||||
o,
|
|
||||||
)
|
|
||||||
return repr(o)
|
|
|
@ -1,5 +1,5 @@
|
||||||
from datetime import datetime as dt
|
from datetime import datetime as dt
|
||||||
from moulinette.utils.serialize import JSONExtendedEncoder
|
from moulinette.interface import JSONExtendedEncoder
|
||||||
|
|
||||||
|
|
||||||
def test_json_extended_encoder(caplog):
|
def test_json_extended_encoder(caplog):
|
||||||
|
|
Loading…
Add table
Reference in a new issue