mirror of
https://github.com/deadc0de6/catcli
synced 2024-11-15 18:14:01 +00:00
size attr fix for #36
This commit is contained in:
parent
3dbec74e96
commit
7e9a6806ee
@ -6,9 +6,10 @@ Class that represents the catcli catalog
|
||||
"""
|
||||
|
||||
import os
|
||||
from typing import Optional
|
||||
from anytree.exporter import JsonExporter # type: ignore
|
||||
from typing import Optional, List, Dict, Tuple, Union, Any
|
||||
from anytree.exporter import JsonExporter, DictExporter # type: ignore
|
||||
from anytree.importer import JsonImporter # type: ignore
|
||||
from anytree import AnyNode # type: ignore
|
||||
|
||||
# local imports
|
||||
from catcli import nodes
|
||||
@ -29,7 +30,7 @@ class Catalog:
|
||||
@debug: debug mode
|
||||
@force: force overwrite if exists
|
||||
"""
|
||||
self.path = path
|
||||
self.path = os.path.expanduser(path)
|
||||
self.debug = debug
|
||||
self.force = force
|
||||
self.metanode: Optional[NodeMeta] = None
|
||||
@ -85,7 +86,8 @@ class Catalog:
|
||||
def _save_json(self, top: NodeTop) -> bool:
|
||||
"""export the catalog in json"""
|
||||
self._debug(f'saving {top} to json...')
|
||||
exp = JsonExporter(indent=2, sort_keys=True)
|
||||
dexporter = DictExporter(attriter=attriter)
|
||||
exp = JsonExporter(dictexporter=dexporter, indent=2, sort_keys=True)
|
||||
with open(self.path, 'w', encoding='UTF-8') as file:
|
||||
exp.write(top, file)
|
||||
self._debug(f'Catalog saved to json \"{self.path}\"')
|
||||
@ -93,7 +95,7 @@ class Catalog:
|
||||
|
||||
def _restore_json(self, string: str) -> Optional[NodeTop]:
|
||||
"""restore the tree from json"""
|
||||
imp = JsonImporter()
|
||||
imp = JsonImporter(dictimporter=_DictImporter(debug=self.debug))
|
||||
self._debug('import from string...')
|
||||
root = imp.import_(string)
|
||||
self._debug(f'Catalog imported from json \"{self.path}\"')
|
||||
@ -103,3 +105,54 @@ class Catalog:
|
||||
top = NodeTop(root.name, children=root.children)
|
||||
self._debug(f'top imported: {top}')
|
||||
return top
|
||||
|
||||
|
||||
class _DictImporter():
|
||||
|
||||
def __init__(self,
|
||||
nodecls: AnyNode = AnyNode,
|
||||
debug: bool = False):
|
||||
self.nodecls = nodecls
|
||||
self.debug = debug
|
||||
|
||||
def import_(self, data: Dict[str, str]) -> AnyNode:
|
||||
"""Import tree from `data`."""
|
||||
return self.__import(data)
|
||||
|
||||
def __import(self, data: Union[str, Any],
|
||||
parent: AnyNode = None) -> AnyNode:
|
||||
"""overwrite parent imoprt"""
|
||||
assert isinstance(data, dict)
|
||||
assert "parent" not in data
|
||||
attrs = dict(data)
|
||||
# replace attr
|
||||
attrs = back_attriter(attrs, debug=self.debug)
|
||||
children: Union[str, Any] = attrs.pop("children", [])
|
||||
node = self.nodecls(parent=parent, **attrs)
|
||||
for child in children:
|
||||
self.__import(child, parent=node)
|
||||
return node
|
||||
|
||||
|
||||
def back_attriter(adict: Dict[str, str],
|
||||
debug: bool = False) -> Dict[str, str]:
|
||||
"""replace attribute on json restore"""
|
||||
attrs = {}
|
||||
for k, val in adict.items():
|
||||
if k == 'size':
|
||||
if debug:
|
||||
Logger.debug(f'changing {k}={val}')
|
||||
k = 'nodesize'
|
||||
attrs[k] = val
|
||||
return attrs
|
||||
|
||||
|
||||
def attriter(attrs: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
||||
"""replace attribute on json save"""
|
||||
newattr = []
|
||||
for attr in attrs:
|
||||
k, val = attr
|
||||
if k == 'nodesize':
|
||||
k = 'size'
|
||||
newattr.append((k, val))
|
||||
return newattr
|
||||
|
@ -74,21 +74,21 @@ class CatcliFilesystem(fuse.LoggingMixIn, fuse.Operations): # type: ignore
|
||||
|
||||
maccess = time()
|
||||
mode: Any = S_IFREG
|
||||
size: int = 0
|
||||
nodesize: int = 0
|
||||
if entry.type == nodes.TYPE_ARCHIVED:
|
||||
mode = S_IFREG
|
||||
size = entry.size
|
||||
nodesize = entry.nodesize
|
||||
elif entry.type == nodes.TYPE_DIR:
|
||||
mode = S_IFDIR
|
||||
size = entry.size
|
||||
nodesize = entry.nodesize
|
||||
maccess = entry.maccess
|
||||
elif entry.type == nodes.TYPE_FILE:
|
||||
mode = S_IFREG
|
||||
size = entry.size
|
||||
nodesize = entry.nodesize
|
||||
maccess = entry.maccess
|
||||
elif entry.type == nodes.TYPE_STORAGE:
|
||||
mode = S_IFDIR
|
||||
size = entry.size
|
||||
nodesize = entry.nodesize
|
||||
maccess = entry.ts
|
||||
elif entry.type == nodes.TYPE_META:
|
||||
mode = S_IFREG
|
||||
@ -98,7 +98,7 @@ class CatcliFilesystem(fuse.LoggingMixIn, fuse.Operations): # type: ignore
|
||||
return {
|
||||
'st_mode': (mode), # file type
|
||||
'st_nlink': 1, # count hard link
|
||||
'st_size': size,
|
||||
'st_size': nodesize,
|
||||
'st_ctime': maccess, # attr last modified
|
||||
'st_mtime': maccess, # content last modified
|
||||
'st_atime': maccess, # access time
|
||||
|
@ -138,29 +138,31 @@ class Noder:
|
||||
@store: store the size in the node
|
||||
"""
|
||||
if node.type == nodes.TYPE_FILE:
|
||||
self._debug(f'size of {node.type} \"{node.name}\": {node.size}')
|
||||
return node.size
|
||||
node.__class__ = NodeFile
|
||||
msg = f'size of {node.type} \"{node.name}\": {node.nodesize}'
|
||||
self._debug(msg)
|
||||
return node.nodesize
|
||||
msg = f'getting node size recursively for \"{node.name}\"'
|
||||
self._debug(msg)
|
||||
size: int = 0
|
||||
fullsize: int = 0
|
||||
for i in node.children:
|
||||
if node.type == nodes.TYPE_DIR:
|
||||
sub_size = self.rec_size(i, store=store)
|
||||
if store:
|
||||
i.size = sub_size
|
||||
size += sub_size
|
||||
i.nodesize = sub_size
|
||||
fullsize += sub_size
|
||||
continue
|
||||
if node.type == nodes.TYPE_STORAGE:
|
||||
sub_size = self.rec_size(i, store=store)
|
||||
if store:
|
||||
i.size = sub_size
|
||||
size += sub_size
|
||||
i.nodesize = sub_size
|
||||
fullsize += sub_size
|
||||
continue
|
||||
self._debug(f'skipping {node.name}')
|
||||
if store:
|
||||
node.size = size
|
||||
self._debug(f'size of {node.type} \"{node.name}\": {size}')
|
||||
return size
|
||||
node.nodesize = fullsize
|
||||
self._debug(f'size of {node.type} \"{node.name}\": {fullsize}')
|
||||
return fullsize
|
||||
|
||||
###############################################################
|
||||
# public helpers
|
||||
@ -261,7 +263,7 @@ class Noder:
|
||||
parent: str, archive: str) -> NodeArchived:
|
||||
"""create a new node for archive data"""
|
||||
return NodeArchived(name=name, relpath=path,
|
||||
parent=parent, size=0, md5='',
|
||||
parent=parent, nodesize=0, md5='',
|
||||
archive=archive)
|
||||
|
||||
###############################################################
|
||||
@ -351,7 +353,7 @@ class Noder:
|
||||
fullpath = os.path.join(storage.name, parents)
|
||||
out.append(fullpath.replace('"', '""')) # full path
|
||||
|
||||
out.append(size_to_str(node.size, raw=raw)) # size
|
||||
out.append(size_to_str(node.nodesize, raw=raw)) # size
|
||||
out.append(epoch_to_str(storage.ts)) # indexed_at
|
||||
if self._has_attr(node, 'maccess'):
|
||||
out.append(epoch_to_str(node.maccess)) # maccess
|
||||
@ -392,9 +394,11 @@ class Noder:
|
||||
"""
|
||||
if node.type == nodes.TYPE_TOP:
|
||||
# top node
|
||||
node.__class__ = NodeTop
|
||||
Logger.stdout_nocolor(f'{pre}{node.name}')
|
||||
elif node.type == nodes.TYPE_FILE:
|
||||
# node of type file
|
||||
node.__class__ = NodeFile
|
||||
name = node.name
|
||||
if withpath:
|
||||
if recalcparent:
|
||||
@ -407,7 +411,7 @@ class Noder:
|
||||
attr_str = ''
|
||||
if node.md5:
|
||||
attr_str = f', md5:{node.md5}'
|
||||
size = size_to_str(node.size, raw=raw)
|
||||
size = size_to_str(node.nodesize, raw=raw)
|
||||
compl = f'size:{size}{attr_str}'
|
||||
if withstorage:
|
||||
content = Logger.get_bold_text(storage.name)
|
||||
@ -415,6 +419,7 @@ class Noder:
|
||||
NodePrinter.print_file_native(pre, name, compl)
|
||||
elif node.type == nodes.TYPE_DIR:
|
||||
# node of type directory
|
||||
node.__class__ = NodeDir
|
||||
name = node.name
|
||||
if withpath:
|
||||
if recalcparent:
|
||||
@ -428,13 +433,14 @@ class Noder:
|
||||
if withstorage:
|
||||
storage = self._get_storage(node)
|
||||
attr: List[Tuple[str, str]] = []
|
||||
if node.size:
|
||||
attr.append(('totsize', size_to_str(node.size, raw=raw)))
|
||||
if node.nodesize:
|
||||
attr.append(('totsize', size_to_str(node.nodesize, raw=raw)))
|
||||
if withstorage:
|
||||
attr.append(('storage', Logger.get_bold_text(storage.name)))
|
||||
NodePrinter.print_dir_native(pre, name, depth=depth, attr=attr)
|
||||
elif node.type == nodes.TYPE_STORAGE:
|
||||
# node of type storage
|
||||
node.__class__ = NodeStorage
|
||||
sztotal = size_to_str(node.total, raw=raw)
|
||||
szused = size_to_str(node.total - node.free, raw=raw)
|
||||
nbchildren = len(node.children)
|
||||
@ -467,6 +473,7 @@ class Noder:
|
||||
node.attr)
|
||||
elif node.type == nodes.TYPE_ARCHIVED:
|
||||
# archive node
|
||||
node.__class__ = NodeArchived
|
||||
if self.arc:
|
||||
NodePrinter.print_archive_native(pre, node.name, node.archive)
|
||||
else:
|
||||
@ -775,9 +782,9 @@ class Noder:
|
||||
def _sort_size(node: NodeAny) -> float:
|
||||
"""sorting nodes by size"""
|
||||
try:
|
||||
if not node.size:
|
||||
if not node.nodesize:
|
||||
return 0
|
||||
return float(node.size)
|
||||
return float(node.nodesize)
|
||||
except AttributeError:
|
||||
return 0
|
||||
|
||||
|
@ -84,7 +84,7 @@ class NodeFile(NodeAny):
|
||||
def __init__(self, # type: ignore[no-untyped-def]
|
||||
name: str,
|
||||
relpath: str,
|
||||
size: int,
|
||||
nodesize: int,
|
||||
md5: str,
|
||||
maccess: float,
|
||||
parent=None,
|
||||
@ -94,7 +94,7 @@ class NodeFile(NodeAny):
|
||||
self.name = name
|
||||
self.type = TYPE_FILE
|
||||
self.relpath = relpath
|
||||
self.size = size
|
||||
self.nodesize = nodesize
|
||||
self.md5 = md5
|
||||
self.maccess = maccess
|
||||
self.parent = parent
|
||||
@ -111,7 +111,7 @@ class NodeDir(NodeAny):
|
||||
def __init__(self, # type: ignore[no-untyped-def]
|
||||
name: str,
|
||||
relpath: str,
|
||||
size: int,
|
||||
nodesize: int,
|
||||
maccess: float,
|
||||
parent=None,
|
||||
children=None):
|
||||
@ -120,7 +120,7 @@ class NodeDir(NodeAny):
|
||||
self.name = name
|
||||
self.type = TYPE_DIR
|
||||
self.relpath = relpath
|
||||
self.size = size
|
||||
self.nodesize = nodesize
|
||||
self.maccess = maccess
|
||||
self.parent = parent
|
||||
if children:
|
||||
@ -136,7 +136,7 @@ class NodeArchived(NodeAny):
|
||||
def __init__(self, # type: ignore[no-untyped-def]
|
||||
name: str,
|
||||
relpath: str,
|
||||
size: int,
|
||||
nodesize: int,
|
||||
md5: str,
|
||||
archive: str,
|
||||
parent=None,
|
||||
@ -146,7 +146,7 @@ class NodeArchived(NodeAny):
|
||||
self.name = name
|
||||
self.type = TYPE_ARCHIVED
|
||||
self.relpath = relpath
|
||||
self.size = size
|
||||
self.nodesize = nodesize
|
||||
self.md5 = md5
|
||||
self.archive = archive
|
||||
self.parent = parent
|
||||
@ -164,7 +164,7 @@ class NodeStorage(NodeAny):
|
||||
name: str,
|
||||
free: int,
|
||||
total: int,
|
||||
size: int,
|
||||
nodesize: int,
|
||||
ts: float,
|
||||
attr: str,
|
||||
parent=None,
|
||||
@ -176,7 +176,7 @@ class NodeStorage(NodeAny):
|
||||
self.free = free
|
||||
self.total = total
|
||||
self.attr = attr
|
||||
self.size = size
|
||||
self.nodesize = nodesize
|
||||
self.ts = ts # pylint: disable=C0103
|
||||
self.parent = parent
|
||||
if children:
|
||||
|
Loading…
Reference in New Issue
Block a user