# Path: g_sorcery/exceptions.py
# class FileJSONError(GSorceryError):
#     pass
# 
# Path: g_sorcery/fileutils.py
# class FileJSONData(object):
#     """
#     Class for files with JSON compatible data.
#     """
#     def __init__(self, directory, name, mandatories=None):
#         """
#         Args:
#             directory: File directory.
#             name: File name.
#             mandatories: List of requiered keys.
#         """
#         self.directory = os.path.abspath(directory)
#         self.name = name
#         self.path = os.path.join(directory, name)
#         if not mandatories:
#             self.mandatories = []
#         else:
#             self.mandatories = mandatories
# 
#     def read(self):
#         """
#         Read file.
#         """
#         if not os.path.exists(self.directory):
#             os.makedirs(self.directory)
#         content = {}
#         if not os.path.isfile(self.path):
#             for key in self.mandatories:
#                 content[key] = ""
#             self.write_content(content)
#         else:
#             content = self.read_content()
#             for key in self.mandatories:
#                 if not key in content:
#                     raise FileJSONError('lack of mandatory key: ' + key)
# 
#         return content
# 
#     def read_content(self):
#         """
#         Real read operation with deserialization. Should be overridden.
#         """
#         return []
# 
#     def write(self, content):
#         """
#         Write file.
#         """
#         for key in self.mandatories:
#             if not key in content:
#                 raise FileJSONError('lack of mandatory key: ' + key)
#         if not os.path.exists(self.directory):
#             os.makedirs(self.directory)
#         self.write_content(content)
# 
#     def write_content(self, content):
#         """
#         Real write operation with serialization. Should be overridden.
#         """
#         pass
# 
# Path: g_sorcery/serialization.py
# def from_raw_serializable(sobj):
#     """
#     Build object from the raw serializable object.
#     """
#     if isinstance(sobj, dict):
#         res = {k: from_raw_serializable(v) for k, v in sobj.items()}
#         return step_from_raw_serializable(res)
#     elif isinstance(sobj, list):
#         return [from_raw_serializable(item) for item in sobj]
#     else:
#         return sobj
# 
# def to_raw_serializable(obj):
#     """
#     Convert object to the raw serializable type.
#     Logic is the same as in the standard json encoder.
#     """
#     if isinstance(obj, basestring) \
#        or obj is None \
#        or obj is True \
#        or obj is False \
#        or isinstance(obj, int) \
#        or isinstance(obj, float):
#         return obj
#     elif isinstance(obj, dict):
#         return {k: to_raw_serializable(v) for k, v in obj.items()}
#     elif isinstance(obj, (list, tuple)):
#         return [to_raw_serializable(item) for item in obj]
# 
#     else:
#         sobj = step_to_raw_serializable(obj)
#         if not sobj:
#             raise TypeError('Non serializable object: ', obj)
#         return to_raw_serializable(sobj)


import bson
from g_sorcery.exceptions import FileJSONError
from g_sorcery.fileutils import FileJSONData
from g_sorcery.serialization import from_raw_serializable, to_raw_serializable
# -*- coding: utf-8 -*-

"""
    file_bson.py
    ~~~~~~~~~~~~

    bson file format support

    :copyright: (c) 2015 by Jauhien Piatlicki
    :license: GPL-2, see LICENSE for more details.
"""



class FileBSON(FileJSONData):
    """
    Class for BSON files. Supports custom JSON serialization
    provided by g_sorcery.serialization.
    """
    def read_content(self):
        """
        Read BSON file.
        """
        content = {}
        bcnt = None
        with open(self.path, 'rb') as f:
            bcnt = bson.BSON(f.read())
        if not bcnt:
            raise FileJSONError('failed to read: ', self.path)
        rawcnt = bcnt.decode()

# Path: g_sorcery/exceptions.py
# class FileJSONError(GSorceryError):
#     pass
# 
# Path: g_sorcery/fileutils.py
# class FileJSONData(object):
#     """
#     Class for files with JSON compatible data.
#     """
#     def __init__(self, directory, name, mandatories=None):
#         """
#         Args:
#             directory: File directory.
#             name: File name.
#             mandatories: List of requiered keys.
#         """
#         self.directory = os.path.abspath(directory)
#         self.name = name
#         self.path = os.path.join(directory, name)
#         if not mandatories:
#             self.mandatories = []
#         else:
#             self.mandatories = mandatories
# 
#     def read(self):
#         """
#         Read file.
#         """
#         if not os.path.exists(self.directory):
#             os.makedirs(self.directory)
#         content = {}
#         if not os.path.isfile(self.path):
#             for key in self.mandatories:
#                 content[key] = ""
#             self.write_content(content)
#         else:
#             content = self.read_content()
#             for key in self.mandatories:
#                 if not key in content:
#                     raise FileJSONError('lack of mandatory key: ' + key)
# 
#         return content
# 
#     def read_content(self):
#         """
#         Real read operation with deserialization. Should be overridden.
#         """
#         return []
# 
#     def write(self, content):
#         """
#         Write file.
#         """
#         for key in self.mandatories:
#             if not key in content:
#                 raise FileJSONError('lack of mandatory key: ' + key)
#         if not os.path.exists(self.directory):
#             os.makedirs(self.directory)
#         self.write_content(content)
# 
#     def write_content(self, content):
#         """
#         Real write operation with serialization. Should be overridden.
#         """
#         pass
# 
# Path: g_sorcery/serialization.py
# def from_raw_serializable(sobj):
#     """
#     Build object from the raw serializable object.
#     """
#     if isinstance(sobj, dict):
#         res = {k: from_raw_serializable(v) for k, v in sobj.items()}
#         return step_from_raw_serializable(res)
#     elif isinstance(sobj, list):
#         return [from_raw_serializable(item) for item in sobj]
#     else:
#         return sobj
# 
# def to_raw_serializable(obj):
#     """
#     Convert object to the raw serializable type.
#     Logic is the same as in the standard json encoder.
#     """
#     if isinstance(obj, basestring) \
#        or obj is None \
#        or obj is True \
#        or obj is False \
#        or isinstance(obj, int) \
#        or isinstance(obj, float):
#         return obj
#     elif isinstance(obj, dict):
#         return {k: to_raw_serializable(v) for k, v in obj.items()}
#     elif isinstance(obj, (list, tuple)):
#         return [to_raw_serializable(item) for item in obj]
# 
#     else:
#         sobj = step_to_raw_serializable(obj)
#         if not sobj:
#             raise TypeError('Non serializable object: ', obj)
#         return to_raw_serializable(sobj)


# Path: g_sorcery/file_bson/file_bson.py
import bson
from g_sorcery.exceptions import FileJSONError
from g_sorcery.fileutils import FileJSONData
from g_sorcery.serialization import from_raw_serializable, to_raw_serializable

# -*- coding: utf-8 -*-

"""
    file_bson.py
    ~~~~~~~~~~~~

    bson file format support

    :copyright: (c) 2015 by Jauhien Piatlicki
    :license: GPL-2, see LICENSE for more details.
"""



class FileBSON(FileJSONData):
    """
    Class for BSON files. Supports custom JSON serialization
    provided by g_sorcery.serialization.
    """
    def read_content(self):
        """
        Read BSON file.
        """
        content = {}
        bcnt = None
        with open(self.path, 'rb') as f:
            bcnt = bson.BSON(f.read())
        if not bcnt:
            raise FileJSONError('failed to read: ', self.path)
        rawcnt = bcnt.decode()

        content = from_raw_serializable(rawcnt)