Coverage for portality/lcc.py: 58%
95 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-22 15:59 +0100
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-22 15:59 +0100
1"""
2~~LCC:Data->LCCXML:Data~~
3"""
4from portality.models import LCC
7def loadLCC(source=None):
8 # use delayed imports, as this code will only rarely be run
9 import os
10 from lxml import etree
12 if source is None:
13 source = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "lccSubjects.xml")
15 doc = etree.parse(open(source))
16 root = doc.getroot()
18 nodes = {}
19 tree = {"name": "LCC", "children": []}
20 cpmap = {}
22 for element in root.findall("subject"):
23 nel = element.find("name")
24 cel = element.find("code")
25 pel = element.find("parent")
27 if nel is None:
28 continue
30 name = nel.text
31 code = None
32 parent = None
33 if cel is not None:
34 code = cel.text
35 if pel is not None:
36 parent = pel.text
38 node = {"name": name}
39 if code is not None:
40 node["code"] = code
42 nodes[name] = node
44 if parent is None:
45 tree["children"].append(node)
46 else:
47 cpmap[name] = parent
49 for child, parent in cpmap.items():
50 cn = nodes.get(child)
51 pn = nodes.get(parent)
52 if cn is None or pn is None:
53 continue
54 if "children" not in pn:
55 pn["children"] = []
56 pn["children"].append(cn)
58 lcc = LCC(**tree)
59 lcc.save()
62def lcc2choices(thelcc, level=-2):
63 level += 1
64 level_indicator = '--'
65 if 'children' in thelcc:
66 results = []
67 if thelcc['name'] != 'LCC':
68 # don't want the root + it doesn't have a code
69 results += [(thelcc['code'], level_indicator * level + thelcc['name'])]
70 for child in thelcc['children']:
71 results += lcc2choices(child, level=level)
72 return results
73 else:
74 # this is a leaf
75 if 'code' not in thelcc:
76 if thelcc['name'] == 'TMP':
77 # some weird leaf element at 1st level of the tree
78 # don't want to generate a choice for it, just ignore
79 return []
80 return [(thelcc['code'], level_indicator * level + thelcc['name'])]
83def lcc2jstree(thelcc):
84 if 'children' in thelcc:
85 results = []
86 if thelcc['name'] == 'LCC':
87 for child in thelcc['children']:
88 results += lcc2jstree(child)
89 else:
90 # don't want the root + it doesn't have a code
91 newnode = {
92 "id": thelcc['code'],
93 "text": thelcc['name'],
94 "children": []
95 }
96 for child in thelcc['children']:
97 newnode['children'] += lcc2jstree(child)
98 results.append(newnode)
100 return results
101 else:
102 # this is a leaf
103 if 'code' not in thelcc:
104 if thelcc['name'] == 'TMP':
105 # some weird leaf element at 1st level of the tree
106 # don't want to generate a choice for it, just ignore
107 return []
108 return [
109 {
110 "id": thelcc['code'],
111 "text": thelcc['name'],
112 "children": []
113 }
114 ]
117def lcc2flat_code_index(thelcc):
118 if 'children' in thelcc:
119 results = {}
120 if thelcc['name'] != 'LCC':
121 # don't want the root + it doesn't have a code
122 results.update({thelcc['code']: thelcc['name']})
123 for child in thelcc['children']:
124 results.update(lcc2flat_code_index(child))
125 return results
126 else:
127 # this is a leaf
128 if 'code' not in thelcc:
129 if thelcc['name'] == 'TMP':
130 # some weird leaf element at 1st level of the tree
131 # don't want to generate a choice for it, just ignore
132 return {}
133 return {thelcc['code']: thelcc['name']}
136lcc = LCC.pull('lcc')
137if not lcc:
138 loadLCC()
139lcc = LCC.pull('lcc')
140lcc_choices = []
141lcc_jstree = []
142lcc_index_by_code = {}
143if lcc:
144 lcc_choices = lcc2choices(lcc)
145 lcc_jstree = lcc2jstree(lcc)
146 lcc_index_by_code = lcc2flat_code_index(lcc)
149def lookup_code(code):
150 return lcc_index_by_code.get(code)