153 lines
4.8 KiB
Python
153 lines
4.8 KiB
Python
# Copyright 2014 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
from __future__ import print_function
|
|
|
|
import json
|
|
import os
|
|
|
|
import six
|
|
import yaml
|
|
|
|
from fuelclient.cli import error
|
|
from fuelclient import consts
|
|
from fuelclient import utils
|
|
|
|
|
|
class Serializer(object):
|
|
"""Serializer class - contains all logic responsible for
|
|
printing to stdout, reading and writing files to file system.
|
|
"""
|
|
serializers = {
|
|
"json": {
|
|
"w": lambda d: json.dumps(d, indent=4),
|
|
"r": utils.safe_deserialize(json.loads)
|
|
},
|
|
"yaml": {
|
|
"w": lambda d: yaml.safe_dump(d, default_flow_style=False),
|
|
"r": utils.safe_deserialize(yaml.load)
|
|
}
|
|
}
|
|
|
|
format_flags = False
|
|
default_format = "yaml"
|
|
format = default_format
|
|
|
|
def __init__(self, format=None):
|
|
if format and format in self.serializers:
|
|
self.format = format
|
|
self.format_flags = True
|
|
|
|
@property
|
|
def serializer(self):
|
|
"""Returns dicts with methods for loadin/dumping current fromat.
|
|
|
|
Returned dict's keys:
|
|
* 'w' - from 'writing', method for serializing/dumping data
|
|
* 'r' - from 'reading', method for deserializing/loading data
|
|
"""
|
|
return self.serializers[self.format]
|
|
|
|
def serialize(self, data):
|
|
"""Shortcut for serializing data with current format."""
|
|
return self.serializer['w'](data)
|
|
|
|
def deserialize(self, data):
|
|
"""Shortcut for deserializing data with current format."""
|
|
return self.serializer['r'](data)
|
|
|
|
@classmethod
|
|
def from_params(cls, params):
|
|
return cls(format=getattr(params,
|
|
consts.SERIALIZATION_FORMAT_FLAG, None))
|
|
|
|
def print_formatted(self, data):
|
|
print(self.serializer["w"](data))
|
|
|
|
def print_to_output(self, formatted_data, arg, print_method=print):
|
|
if self.format_flags:
|
|
self.print_formatted(formatted_data)
|
|
else:
|
|
if six.PY2 and isinstance(arg, six.text_type):
|
|
arg = arg.encode('utf-8')
|
|
print_method(arg)
|
|
|
|
def prepare_path(self, path):
|
|
return "{0}.{1}".format(
|
|
path, self.format
|
|
)
|
|
|
|
def write_to_path(self, path, data):
|
|
full_path = self.prepare_path(path)
|
|
return self.write_to_full_path(full_path, data)
|
|
|
|
def write_to_full_path(self, path, data):
|
|
try:
|
|
with open(path, "w") as file_to_write:
|
|
self.write_to_file(file_to_write, data)
|
|
except IOError as e:
|
|
raise error.InvalidFileException(
|
|
"Can't write to file '{0}': {1}.".format(
|
|
path, e.strerror))
|
|
return path
|
|
|
|
def read_from_file(self, path):
|
|
return self.read_from_full_path(self.prepare_path(path))
|
|
|
|
def read_from_full_path(self, full_path):
|
|
try:
|
|
with open(full_path, "r") as file_to_read:
|
|
return self.serializer["r"](file_to_read.read())
|
|
except IOError as e:
|
|
raise error.InvalidFileException(
|
|
"Can't open file '{0}': {1}.".format(full_path, e.strerror))
|
|
|
|
def write_to_file(self, file_obj, data):
|
|
"""Writes to opened file or file like object
|
|
:param file_obj: opened file
|
|
:param data: any serializable object
|
|
"""
|
|
serialized = self.serializer["w"](data)
|
|
file_obj.write(serialized)
|
|
|
|
|
|
class FileFormatBasedSerializer(Serializer):
|
|
|
|
def get_serializer(self, path):
|
|
extension = os.path.splitext(path)[1][1:]
|
|
if extension not in self.serializers:
|
|
raise error.BadDataException(
|
|
'No serializer for provided file {0}'.format(path))
|
|
return self.serializers[extension]
|
|
|
|
def write_to_file(self, full_path, data):
|
|
serializer = self.get_serializer(full_path)
|
|
with open(full_path, "w+") as f:
|
|
f.write(serializer["w"](data))
|
|
return full_path
|
|
|
|
def read_from_file(self, full_path):
|
|
serializer = self.get_serializer(full_path)
|
|
with open(full_path, "r") as f:
|
|
return serializer["r"](f.read())
|
|
|
|
|
|
def listdir_without_extensions(dir_path):
|
|
return six.moves.filter(
|
|
lambda f: f != "",
|
|
six.moves.map(
|
|
lambda f: f.split(".")[0],
|
|
os.listdir(dir_path)
|
|
)
|
|
)
|