File helpgen/category.py changed (mode: 100644) (index 3046570..2275901) |
1 |
1 |
#!/usr/bin/env python |
#!/usr/bin/env python |
2 |
2 |
""" A category corresponds to a Item with no content, simply children. """ |
""" A category corresponds to a Item with no content, simply children. """ |
3 |
3 |
|
|
4 |
|
import os |
|
5 |
|
import sys |
|
6 |
|
|
|
7 |
4 |
from item import Item |
from item import Item |
8 |
5 |
|
|
9 |
6 |
class Category(Item): |
class Category(Item): |
10 |
|
def __init__(self, path=None): |
|
11 |
|
if path is not None: |
|
12 |
|
if not os.path.exists(path): |
|
13 |
|
raise FileNotFoundError('category path not found.', path) |
|
14 |
|
assert os.path.isdir(path), 'non-dir given to Category constructor.' |
|
15 |
|
|
|
16 |
|
# Open our metadata file. It should be named category.yaml/yml |
|
17 |
|
metapath = os.path.join(path, 'category.yml') |
|
18 |
|
if not os.path.exists(metapath): |
|
19 |
|
metapath = os.path.join(path, 'category.yaml') |
|
20 |
|
if not os.path.exists(metapath): |
|
21 |
|
raise FileNotFoundError('Category metadata file not found.', |
|
22 |
|
metapath) |
|
23 |
|
super(Category, self).__init__(metapath) |
|
24 |
|
|
|
25 |
|
def can_have_children(self): |
|
26 |
|
""" Category children are expected to be Categories or Documents. """ |
|
27 |
|
return True |
|
28 |
|
|
|
29 |
|
if __name__ == '__main__': |
|
30 |
|
args = sys.argv[1:] |
|
31 |
|
if len(args) == 0: |
|
32 |
|
print("expected directory path") |
|
33 |
|
exit() |
|
34 |
|
|
|
35 |
|
cat = Category(args[0]) |
|
36 |
|
print(cat.name()) |
|
|
7 |
|
metafile = 'category.yml' |
|
8 |
|
can_child = ['Document', 'Category'] |
37 |
9 |
|
|
File helpgen/item.py changed (mode: 100644) (index 6d4b4da..0b0baac) |
... |
... |
import os |
9 |
9 |
import yaml |
import yaml |
10 |
10 |
|
|
11 |
11 |
class Item: |
class Item: |
12 |
|
def __init__(self, path=None): |
|
|
12 |
|
metafile = None |
|
13 |
|
can_child = None |
|
14 |
|
|
|
15 |
|
def __init__(self, path=None, name=None): |
13 |
16 |
""" Initializes the Item by parsing the Yaml file, if provided.""" |
""" Initializes the Item by parsing the Yaml file, if provided.""" |
14 |
17 |
self.path = '' |
self.path = '' |
15 |
18 |
self.metadata = None |
self.metadata = None |
16 |
19 |
self.parent = None |
self.parent = None |
17 |
20 |
self.children = [] |
self.children = [] |
18 |
21 |
|
|
19 |
|
if path is not None: |
|
|
22 |
|
if name is not None: |
|
23 |
|
assert len(name), 'cannot give empty name to item.' |
|
24 |
|
self.metadata = {} |
|
25 |
|
self.metadata['name'] = name |
|
26 |
|
elif path is not None: |
20 |
27 |
assert len(path), 'Empty path given to Item constructor.' |
assert len(path), 'Empty path given to Item constructor.' |
21 |
28 |
if not os.path.exists(path): |
if not os.path.exists(path): |
22 |
29 |
raise FileNotFoundError('path to meta document is invalid.', |
raise FileNotFoundError('path to meta document is invalid.', |
23 |
30 |
path) |
path) |
|
31 |
|
# If path is a directory, we guess the path to the metafile |
|
32 |
|
# base on the static class variable that defines it. |
|
33 |
|
if os.path.isdir(path): |
|
34 |
|
assert self.metafile is not None, 'not metafile set for item.' |
|
35 |
|
path = os.path.join(path, self.metafile) |
|
36 |
|
if not os.path.exists(path): |
|
37 |
|
raise FileNotFoundError('metafile does not exist.', path) |
24 |
38 |
with open(path) as f: |
with open(path) as f: |
25 |
39 |
self.metadata = yaml.safe_load(f) |
self.metadata = yaml.safe_load(f) |
26 |
40 |
self.path = path |
self.path = path |
27 |
41 |
|
|
28 |
|
def can_have_children(self): |
|
29 |
|
""" Whether or not this item can have children. """ |
|
30 |
|
return False |
|
|
42 |
|
def __str__(self): |
|
43 |
|
return self.name() + ' (' + type(self).__name__ + ')' |
31 |
44 |
|
|
32 |
45 |
def _get_value(self, name, lang=''): |
def _get_value(self, name, lang=''): |
33 |
46 |
""" Get the value designated by name or its translation. |
""" Get the value designated by name or its translation. |
|
... |
... |
class Item: |
72 |
85 |
|
|
73 |
86 |
def is_included_in(self, editions): |
def is_included_in(self, editions): |
74 |
87 |
""" Whether the item should be included in the given edition(s). """ |
""" Whether the item should be included in the given edition(s). """ |
75 |
|
if self.metadata is None return False |
|
76 |
|
if 'editions' not in self.metadata return True |
|
|
88 |
|
if self.metadata is None: |
|
89 |
|
return False |
|
90 |
|
if 'editions' not in self.metadata: |
|
91 |
|
return True |
77 |
92 |
if isinstance(editions, str): |
if isinstance(editions, str): |
78 |
|
if editions in self.metadata.editions return True |
|
|
93 |
|
if editions in self.metadata['editions']: |
|
94 |
|
return True |
79 |
95 |
return False |
return False |
80 |
96 |
if isinstance(editions, list): |
if isinstance(editions, list): |
81 |
97 |
for edition in editions: |
for edition in editions: |
82 |
|
if edition in self.metadata.editions return True |
|
|
98 |
|
if edition in self.metadata['editions']: |
|
99 |
|
return True |
83 |
100 |
return False |
return False |
84 |
101 |
|
|
85 |
|
def set_parent(self, parent): |
|
86 |
|
""" Set the parent of this Item. Called by add_child(). """ |
|
87 |
|
assert isinstance(parent, Item), 'cannot set non-Item as parent.' |
|
88 |
|
self.parent = parent |
|
|
102 |
|
def has_parent(self, candidate): |
|
103 |
|
""" Whether this item has the given candidate as a parent. """ |
|
104 |
|
assert candidate != self, 'invalid check of item is self-parent.' |
|
105 |
|
if self.parent is None: |
|
106 |
|
return False |
|
107 |
|
if self.parent == candidate: |
|
108 |
|
return True |
|
109 |
|
return self.parent.has_parent(candidate) |
89 |
110 |
|
|
90 |
|
def add_child(self, child): |
|
|
111 |
|
def add_child(self, candidate): |
91 |
112 |
""" Add a child to this Item. """ |
""" Add a child to this Item. """ |
92 |
|
assert isinstance(child, Item), 'cannot set non-Item as child.' |
|
93 |
|
assert self.can_have_children(), 'item cannot have children.' |
|
94 |
|
children += child |
|
95 |
|
child.set_parent(self) |
|
|
113 |
|
assert isinstance(candidate, Item), 'cannot set non-Item as child.' |
|
114 |
|
assert candidate != self, 'item cannot add itself as child.' |
|
115 |
|
assert self.can_child is not None, 'item cannot have children.' |
|
116 |
|
assert candidate.type() in self.can_child, \ |
|
117 |
|
'candidate item not allowed as child' |
|
118 |
|
assert not self.has_parent(candidate), \ |
|
119 |
|
'candidate is already a parent of item.' |
|
120 |
|
self.children.append(candidate) |
|
121 |
|
candidate.parent = self |
|
122 |
|
|
|
123 |
|
def type(self): |
|
124 |
|
""" Shortcut to the item type name. """ |
|
125 |
|
return type(self).__name__ |
96 |
126 |
|
|
97 |
127 |
def name(self, lang=''): |
def name(self, lang=''): |
98 |
128 |
""" Name of the item. Return translated value if lang is given. """ |
""" Name of the item. Return translated value if lang is given. """ |
99 |
129 |
return self._get_value('name', lang=lang) |
return self._get_value('name', lang=lang) |
100 |
130 |
|
|
|
131 |
|
|
File helpgen/utils.py added (mode: 100644) (index 0000000..13eba53) |
|
1 |
|
#!/usr/bin/env python |
|
2 |
|
|
|
3 |
|
from os import path as ospath |
|
4 |
|
|
|
5 |
|
from project import Project |
|
6 |
|
from category import Category |
|
7 |
|
from document import Document |
|
8 |
|
|
|
9 |
|
def open_item(path): |
|
10 |
|
""" Attempts to open the item based on the given folder path. """ |
|
11 |
|
if not ospath.exists(path): |
|
12 |
|
return None |
|
13 |
|
if not ospath.isdir(path): |
|
14 |
|
return None |
|
15 |
|
|
|
16 |
|
# We check for all known metafile names to try to guess what the item |
|
17 |
|
# might be. |
|
18 |
|
|
|
19 |
|
if ospath.exists(ospath.join(path, Project.metafile)): |
|
20 |
|
return Project(path) |
|
21 |
|
if ospath.exists(ospath.join(path, Category.metafile)): |
|
22 |
|
return Category(path) |
|
23 |
|
if ospath.exists(ospath.join(path, Document.metafile)): |
|
24 |
|
return Document(path) |
|
25 |
|
return None |
|
26 |
|
|
|
27 |
|
def child_tree(item, level=0): |
|
28 |
|
""" Prints the family tree of the given object. """ |
|
29 |
|
if item is None: |
|
30 |
|
return |
|
31 |
|
spaces='' |
|
32 |
|
for i in range(level): |
|
33 |
|
spaces+=' ' |
|
34 |
|
print(spaces + str(item)) |
|
35 |
|
if item.children is None or len(item.children) == 0: |
|
36 |
|
return |
|
37 |
|
for child in item.children: |
|
38 |
|
child_tree(child, level+2) |