tree generation

This commit is contained in:
Amber 2023-12-25 09:12:22 +01:00
parent 40bde46f8b
commit ede81b4f32
16 changed files with 158 additions and 15 deletions

View File

@ -10,7 +10,7 @@ def dcsnap(path: str, filename=None):
def diffsnap(last_tree, current_tree, path='./', bres={}):
'''
snapshot is a tree represented by dictionary {k, val} when k can be folder or file
snapshot is a tree represented by dictionary {k, val} when k can be folder or file name
and val can be a dictionary or an hash
@param last_tree snapshot computed at time t0
@ -20,22 +20,40 @@ def diffsnap(last_tree, current_tree, path='./', bres={}):
changed = bres.setdefault('changed', [])
added = bres.setdefault('added', [])
keys_added = set(current_tree.keys()) - set(last_tree.keys())
## name last is a dir
if keys_added:
for key_added in keys_added:
print(f'file {path}{key_added} subtree added in current snapshot')
item = {
'name' : key_added,
# 'path' : '%s%s' % (path, name_last),
'type' : 'dir' if isinstance(current_tree[key_added], dict) else 'file',
'hash' : current_tree[key_added],
}
added.append(item)
for name_last, hsh_last in last_tree.items():
hsh_current = current_tree.get(name_last)
# is_dir_last = True if isinstance(hsh_last, dict) else False
# if name_last == 'pino.txt':
# import pdb
# pdb.set_trace()
last_type = 'dir' if isinstance(hsh_last, dict) else 'file'
item = {
'name' : name_last,
'path' : path,
# 'last_hash' : hsh_last,
}
if hsh_current is None:
## the name in not founded in current snapshot - Subtree removed (or moved)
print(f'{path}{name_last} present in last_tree but removed in current_tree, subtree {name_last} removed in current_tree')
item.update({
'last_type' : 'dir',
'type' : last_type,
'hash' : hsh_last,
})
removed.append(item)
continue
@ -57,7 +75,6 @@ def diffsnap(last_tree, current_tree, path='./', bres={}):
item.update({
'last_type' : last_type,
'current_type' : current_type,
'last_hash' : hsh_last,
'cur_hash' : hsh_current,
})
changed.append(item)
@ -69,17 +86,22 @@ def diffsnap(last_tree, current_tree, path='./', bres={}):
continue
print(f'file {path}{name_last} subtree changed in current snapshot')
keys_added = set(hsh_current.keys()) - set(hsh_last.keys())
## name last is a dir
if keys_added:
for key_added in keys_added:
print(f'file {path}{name_last}/{key_added} subtree added in current snapshot')
item.update({
'name' : key_added,
'path' : '%s%s' % (path, name_last),
'current_type' : 'dir' if isinstance(current_tree[name_last][key_added], dict) else 'file'
})
added.append(item)
#########
###
# keys_added = set(hsh_current.keys()) - set(hsh_last.keys())
# ## name last is a dir
# if keys_added:
# for key_added in keys_added:
# print(f'file {path}{name_last}/{key_added} subtree added in current snapshot')
# item.update({
# 'name' : key_added,
# 'path' : '%s%s' % (path, name_last),
# 'type' : 'dir' if isinstance(current_tree[name_last][key_added], dict) else 'file',
# 'hash' : current_tree[name_last][key_added],
# })
# added.append(item)
#####
###########
diffsnap(hsh_last, hsh_current, path='%s%s/' % (path,name_last), bres = {
'removed' : removed,
@ -90,6 +112,7 @@ def diffsnap(last_tree, current_tree, path='./', bres={}):
def findsubtree(snapshot, subtree, path='./'):
'''
@param subtree dict
find the exact subtree in snapshot
'''
subtree_key = list(subtree.keys())[0]
subtree_val = list(subtree.values())[0]
@ -98,7 +121,10 @@ def findsubtree(snapshot, subtree, path='./'):
if snap_key != subtree_key:
if isinstance(snap_val, dict):
path = '%s%s/' % (path, snap_key)
findsubtree(snap_val, subtree, path)
return findsubtree(snap_val, subtree, path)
else:
if snap_val == subtree_val:
return (True, path)
print(f'subtree found in snapshot in path {path}')
return (False, '')

Binary file not shown.

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python
if __name__ == '__main__':
print('python masync script: #!/usr/bin/env python ')
@ -7,4 +8,33 @@ if __name__ == '__main__':
last_local_tree_hash = {'taglioCapelli4.jpg': '5af62402ec7716e8d729b0683061f0c4', 'taglioCapelli5.jpg': '9c42961af589a279c4c828925291153b', 'pino.txt': 'd41d8cd98f00b204e9800998ecf8427e', 'taglioCapelli6.jpg': '4059905eab817c33ee48f912af80fdb7', 'spartiti_sepu': {'IMG_20220626_081839.jpg': '3c14e508124c928d59b393a571e2f751', 'IMG_20220626_081951.jpg': 'd484638ac09cbe40f8753de3f1b3c4a6'}, 'preferiti.txt': 'af45981ef2be534dbb37f96833d3fd04'}
from snapshot.generate import local as _genlocal
from snapshot import snap as _snap
from tools import pretty_print as _pretty_print
local_tree_hash = _genlocal.generate_tree_hash('/home/luca/sharednotes_dev/')
diff = {}
_snap.diffsnap(last_local_tree_hash, local_tree_hash, bres=diff)
processed = {}
processed['added'] = diff['added']
processed['changed'] = diff['changed']
removed = diff.get('removed') or []
for item in removed:
subtree = {
item['name']: item['hash']
}
(found, path) = _snap.findsubtree(local_tree_hash, subtree)
if not found:
cancelled = processed.setdefault('cancelled', [])
cancelled.append(item)
continue
moved = processed.setdefault('moved', [])
item['dest_path'] = path
moved.append(item)
_pretty_print.pp(processed)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,5 @@
import json
def pp(json_obj, indent=2):
dumps = json.dumps(json_obj, indent=2)
print(dumps)

68
src/tools/tree_repr.py Normal file
View File

@ -0,0 +1,68 @@
import os
LEVEL_INDENT = 6
EMPTY_TREE_LINE_LENGTH = 160
EMPTY_TREE_LINE = ' ' * EMPTY_TREE_LINE_LENGTH
def mount_str_at(source_str, index, mount_str):
l = len(mount_str)
return source_str[:index] + mount_str + source_str[index+l:]
def level2indent(l):
if not l:
return 1
return LEVEL_INDENT * l
def produce_treeline(prec_seps, lsep):
tree_line = EMPTY_TREE_LINE[:]
lseps = prec_seps[:]
lseps.append(lsep)
for level_n, (sep, item) in enumerate(lseps):
tomount = sep
if item:
tomount = sep + item
tree_line = mount_str_at(tree_line, level2indent(level_n), tomount)
return tree_line.rstrip()
def nerd_tree(startpath, prec_seps=[]):
if not startpath.endswith('/'):
tosplit = startpath
startpath = startpath + '/'
else:
tosplit = startpath[:-1]
rootnode = tosplit.split('/')[-1]
items = os.listdir(startpath)
nerd_tree_txt = rootnode
for n, item in enumerate(items):
if item == '__pycache__':
continue
islast = (n==len(items) -1)
sep = '├── '
if islast:
sep = '└── '
if not islast:
psep_char = ''
else:
psep_char = ''
if os.path.isdir(startpath+item):
seps = prec_seps[:]
seps.append((psep_char, ''))
treeline = produce_treeline(prec_seps, (sep, ' ')) + ' ' + nerd_tree(startpath+item, prec_seps=seps)
else:
treeline = produce_treeline(prec_seps, (sep, item))
nerd_tree_txt += '\n' + treeline
return nerd_tree_txt

14
src/tree_structure.txt Normal file
View File

@ -0,0 +1,14 @@
src
├── lib - contains low level libraries
│ │
│ │
│ ├── snapshot - libraries for generating, dumping and read snapshot
│ │ │
│ │ ├── generate - dump the snapshot
│ │ │
│ │ │
│ └── dump.py - dump the snapshot
└── iface
└──snap.py - Interface to low level library