Source code for multipie.util.util_binary
"""
For binary data.
"""
import os
import gzip
import pickle
import copy
from multipie.core.multipie_info import __bin_dir__
from multipie.util.util import do_black
# ==================================================
[docs]
class BinaryManager(dict):
suffix = ".pkl"
# ==================================================
def __init__(self, filename=None, topdir=None, subdir=None, verbose=False, comment=""):
"""
Binary data manager.
Args:
filename (str, optional): file name to load.
topdir (str, optional): top directory. [default: multipie/binary_data]
subdir (str, optional): sub directory.
verbose (bool, optional): verbose comment ?
comment (str, optional): comment.
"""
self.topdir = topdir
self.subdir = subdir
self.verbose = verbose
self.comment = ""
self.add_comment(comment)
if filename is not None:
self.load_binary(filename)
# ==================================================
def __str__(self):
"""
Convert to str.
Returns:
- (str) -- comment of data.
"""
return '"""\n' + self.comment.strip(" \n") + '\n"""'
# ==================================================
def __repr__(self):
"""
Dump data.
Returns:
- (str) -- data string.
"""
s = str(dict(super().items()))
return s
# ==================================================
[docs]
def set_topdir(self, topdir):
"""
Set top directory.
Args:
topdir (str): top directory.
"""
self.topdir = topdir
# ==================================================
# ==================================================
[docs]
def set_subdir(self, subdir):
"""
Set sub directory.
Args:
subdir (str): sub directory.
"""
self.subdir = subdir
# ==================================================
[docs]
def clear(self):
"""
Clear data.
"""
super().clear()
self.comment = ""
# ==================================================
[docs]
def to_dict(self):
"""
Convert data to dict.
Returns:
- (dict) -- data in dict.
"""
dic = {"header": self.comment, "data": dict(copy.deepcopy(self))}
return dic
# ==================================================
[docs]
def from_dict(self, d):
"""
Set data from dict.
"""
self.clear()
self.update(d.get("data", {}))
comment = d.get("header", "")
if comment != "":
self.add_comment(comment)
# ==================================================
[docs]
def save_binary(self, filename, detail=True):
"""
Save data as binary.
Args:
filename (str): file name. (extension is .pkl).
detail (bool, optional): detailed info. ?
"""
fullpath = self.get_fullpath(filename)
os.makedirs(os.path.dirname(fullpath), exist_ok=True)
dic = self.to_dict()
bs = pickle.dumps(dic, protocol=pickle.HIGHEST_PROTOCOL)
with gzip.open(fullpath, mode="wb") as f:
f.write(bs)
if self.verbose:
print(f"save binary to '{fullpath}'.")
if detail:
if self.comment != "":
print(self.__str__())
info = list(self.keys())
print(f"keys = {info}.")
size = os.path.getsize(fullpath)
print(f"binary size = {size:,} Bytes.")
# ==================================================
[docs]
def load_binary(self, filename):
"""
Load binary data.
Args:
filename (str): file name. (extension is .pkl).
Returns:
- (bool) -- return True if error occurs, otherwise False.
"""
self.clear()
fullpath = self.get_fullpath(filename)
if not os.path.exists(fullpath):
print(f"cannot open '{fullpath}'.")
return True
with gzip.open(fullpath, "rb") as f:
bs = f.read()
data = pickle.loads(bs)
self.from_dict(data)
if self.verbose:
print(f"load binary from '{fullpath}'.")
if self.comment != "":
print(self.__str__())
return False
# ==================================================
[docs]
def get_cwd(self):
"""
Get working directory.
Returns:
- (str) -- working directory.
"""
if self.topdir is None:
cwd = __bin_dir__
else:
cwd = self.topdir
if self.subdir is not None:
cwd = os.path.join(cwd, self.subdir)
return cwd
# ==================================================
[docs]
def get_fullpath(self, filename):
"""
Get full path name.
Args:
filename (str): file name.
Returns:
- (str) -- full path name.
"""
ext = os.path.splitext(filename)[1]
if ext not in [self.suffix]:
filename += self.suffix
topdir = self.get_cwd()
ofile = os.path.join(topdir, filename)
return ofile
# ==================================================
[docs]
def convert_binary_to_text(filename, out_filename=None, verbose=False):
"""
Convert binary to text file.
Args:
filename (str): binary file name.
out_filename (str, optional): text file name.
verbose (bool, optional): verbose ?
Note:
- text file name becomes binary_filename_pkl.py if out_filename is not given.
"""
bm = BinaryManager(filename, verbose=True)
if out_filename is None:
if filename.endswith(BinaryManager.suffix):
out_filename = filename.replace(BinaryManager.suffix, "_" + BinaryManager.suffix[1:] + ".py")
else:
out_filename = filename + "_" + BinaryManager.suffix[1:] + ".py"
topdir = bm.get_cwd()
out_filename = os.path.join(topdir, out_filename)
with open(out_filename, mode="w", encoding="utf-8") as f:
s = str(bm) + "\n" + f"{filename} =" + repr(bm)
print(s, file=f)
do_black(topdir)
if verbose:
print(f"convert to '{out_filename}'.")