Coverage for portality/lcc.py: 58%

95 statements  

« 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 

5 

6 

7def loadLCC(source=None): 

8 # use delayed imports, as this code will only rarely be run 

9 import os 

10 from lxml import etree 

11 

12 if source is None: 

13 source = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "lccSubjects.xml") 

14 

15 doc = etree.parse(open(source)) 

16 root = doc.getroot() 

17 

18 nodes = {} 

19 tree = {"name": "LCC", "children": []} 

20 cpmap = {} 

21 

22 for element in root.findall("subject"): 

23 nel = element.find("name") 

24 cel = element.find("code") 

25 pel = element.find("parent") 

26 

27 if nel is None: 

28 continue 

29 

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 

37 

38 node = {"name": name} 

39 if code is not None: 

40 node["code"] = code 

41 

42 nodes[name] = node 

43 

44 if parent is None: 

45 tree["children"].append(node) 

46 else: 

47 cpmap[name] = parent 

48 

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) 

57 

58 lcc = LCC(**tree) 

59 lcc.save() 

60 

61 

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'])] 

81 

82 

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) 

99 

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 ] 

115 

116 

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']} 

134 

135 

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) 

147 

148 

149def lookup_code(code): 

150 return lcc_index_by_code.get(code)