forked from davidnemec/bitwarden-to-keepass
-
Notifications
You must be signed in to change notification settings - Fork 0
/
folder.py
59 lines (49 loc) · 1.87 KB
/
folder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import collections
from typing import Callable, Deque, List, Optional
from pykeepass.group import Group as KPGroup
class Folder:
id: Optional[str]
name: Optional[str]
children: List['Folder']
parent: Optional['Folder']
keepass_group: Optional[KPGroup]
def __init__(self, id: Optional[str]):
self.id = id
self.name = None
self.children = []
self.parent = None
self.keepass_group = None
def add_child(self, child: 'Folder'):
self.children.append(child)
child.parent = self
# logic was lifted directly from https://github.com/bitwarden/jslib/blob/ecdd08624f61ccff8128b7cb3241f39e664e1c7f/common/src/misc/serviceUtils.ts#L7
def nested_traverse_insert(root: Folder, name_parts: List[str], new_folder: Folder, delimiter: str) -> None:
if len(name_parts) == 0:
return
end: bool = len(name_parts) == 1
part_name: str = name_parts[0]
for child in root.children:
if child.name != part_name:
continue
if end and child.id != new_folder.id:
# Another node with the same name.
new_folder.name = part_name
root.add_child(new_folder)
return
nested_traverse_insert(child, name_parts[1:], new_folder, delimiter)
return
if end:
new_folder.name = part_name
root.add_child(new_folder)
return
new_part_name: str = part_name + delimiter + name_parts[1]
new_name_parts: List[str] = [new_part_name]
new_name_parts.extend(name_parts[2:])
nested_traverse_insert(root, new_name_parts, new_folder, delimiter)
def bfs_traverse_execute(root: Folder, callback: Callable[[Folder], None]) -> None:
queue: Deque[Folder] = collections.deque()
queue.extend(root.children)
while queue:
child: Folder = queue.popleft()
queue.extend(child.children)
callback(child)