Coverage for portality/models/v1/bibjson.py: 82%

144 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-19 18:38 +0100

1from portality.lib import dataobj 

2from portality.models.v1 import shared_structs 

3 

4class GenericBibJSON(dataobj.DataObj): 

5 # vocab of known identifier types 

6 P_ISSN = "pissn" 

7 E_ISSN = "eissn" 

8 DOI = "doi" 

9 

10 # allowable values for the url types 

11 HOMEPAGE = "homepage" 

12 WAIVER_POLICY = "waiver_policy" 

13 EDITORIAL_BOARD = "editorial_board" 

14 AIMS_SCOPE = "aims_scope" 

15 AUTHOR_INSTRUCTIONS = "author_instructions" 

16 OA_STATEMENT = "oa_statement" 

17 FULLTEXT = "fulltext" 

18 

19 # constructor 

20 def __init__(self, bibjson=None, **kwargs): 

21 self._add_struct(shared_structs.SHARED_BIBJSON.get("structs", {}).get("bibjson")) 

22 # construct_maintain_reference is enforced here, don't allow override with kwargs 

23 kwargs.pop('construct_maintain_reference', None) 

24 super(GenericBibJSON, self).__init__(raw=bibjson, construct_maintain_reference=True, **kwargs) 

25 

26 #################################################### 

27 # shared simple property getter and setters 

28 

29 @property 

30 def title(self): 

31 return self._get_single("title") 

32 

33 @title.setter 

34 def title(self, val): 

35 self._set_with_struct("title", val) 

36 

37 ##################################################### 

38 # complex getters and setters 

39 

40 

41 ## work with the identifiers 

42 

43 def add_identifier(self, idtype, value): 

44 self._delete_from_list("identifier", matchsub={"type": idtype}) 

45 idobj = {"type" : idtype, "id" : self._normalise_identifier(idtype, value)} 

46 self._add_to_list_with_struct("identifier", idobj) 

47 

48 def get_identifiers(self, idtype=None): 

49 if idtype is None: 

50 return self._get_list("identifier") 

51 

52 ids = [] 

53 for identifier in self._get_list("identifier"): 

54 if identifier.get("type") == idtype and identifier.get("id") not in ids: 

55 ids.append(identifier.get("id")) 

56 return ids 

57 

58 def get_one_identifier(self, idtype=None): 

59 results = self.get_identifiers(idtype=idtype) 

60 if len(results) > 0: 

61 return results[0] 

62 else: 

63 return None 

64 

65 def remove_identifiers(self, idtype=None, id=None): 

66 # if we are to remove all identifiers, this is easy 

67 if idtype is None and id is None: 

68 self._delete("identifier") 

69 return 

70 

71 match = {} 

72 if idtype is not None: 

73 match["type"] = idtype 

74 if id is not None: 

75 match["id"] = id 

76 self._delete_from_list("identifier", matchsub=match) 

77 

78 def _normalise_identifier(self, idtype, value): 

79 if idtype in [self.P_ISSN, self.E_ISSN]: 

80 return self._normalise_issn(value) 

81 return value 

82 

83 def _normalise_issn(self, issn): 

84 issn = issn.upper() 

85 if len(issn) > 8: return issn 

86 if len(issn) == 8: 

87 if "-" in issn: return "0" + issn 

88 else: return issn[:4] + "-" + issn[4:] 

89 if len(issn) < 8: 

90 if "-" in issn: return ("0" * (9 - len(issn))) + issn 

91 else: 

92 issn = ("0" * (8 - len(issn))) + issn 

93 return issn[:4] + "-" + issn[4:] 

94 

95 ## work with keywords 

96 

97 @property 

98 def keywords(self): 

99 return self._get_list("keywords") 

100 

101 def add_keyword(self, keyword): 

102 if keyword is not None: 

103 self._add_to_list_with_struct("keywords", keyword.lower()) 

104 

105 def set_keywords(self, keywords): 

106 if type(keywords) is list: 

107 keywords = [w.lower() for w in keywords] 

108 self._set_with_struct("keywords", keywords) 

109 else: 

110 if keywords is not None: 

111 self._set_with_struct("keywords", keywords.lower()) 

112 

113 ## work with urls 

114 

115 def add_url(self, url, urltype=None, content_type=None): 

116 if url is None: 

117 # do not add empty URL-s 

118 return 

119 

120 urlobj = {"url": url} 

121 if urltype is not None: 

122 urlobj["type"] = urltype 

123 if content_type is not None: 

124 urlobj["content_type"] = content_type 

125 

126 self._add_to_list_with_struct("link", urlobj) 

127 

128 def get_urls(self, urltype=None, unpack_urlobj=True): 

129 if urltype is None: 

130 return self._get_list("link") 

131 

132 urls = [] 

133 for link in self._get_list("link"): 

134 if link.get("type") == urltype: 

135 if unpack_urlobj: 

136 urls.append(link.get("url")) 

137 else: 

138 urls.append(link) 

139 return urls 

140 

141 def get_single_url(self, urltype, unpack_urlobj=True): 

142 urls = self.get_urls(urltype=urltype, unpack_urlobj=unpack_urlobj) 

143 if len(urls) > 0: 

144 return urls[0] 

145 return None 

146 

147 def remove_urls(self, urltype=None, url=None): 

148 # if we are to remove all urls, this is easy 

149 if urltype is None and url is None: 

150 self._delete("link") 

151 return 

152 

153 match = {} 

154 if urltype is not None: 

155 match["type"] = urltype 

156 if url is not None: 

157 match["url"] = id 

158 self._delete_from_list("link", matchsub=match) 

159 

160 ## work with subjects 

161 

162 def add_subject(self, scheme, term, code=None): 

163 sobj = {"scheme" : scheme, "term" : term} 

164 if code is not None: 

165 sobj["code"] = code 

166 self._add_to_list_with_struct("subject", sobj) 

167 

168 def subjects(self): 

169 return self._get_list("subject") 

170 

171 def set_subjects(self, subjects): 

172 self._set_with_struct("subject", subjects) 

173 

174 def remove_subjects(self): 

175 self._delete("subject") 

176 

177 def lcc_paths(self): 

178 classification_paths = [] 

179 

180 # calculate the classification paths 

181 from portality.lcc import lcc # inline import since this hits the database 

182 for subs in self.subjects(): 

183 scheme = subs.get("scheme") 

184 term = subs.get("term") 

185 if scheme == "LCC": 

186 p = lcc.pathify(term) 

187 if p is not None: 

188 classification_paths.append(p) 

189 

190 # normalise the classification paths, so we only store the longest ones 

191 classification_paths = lcc.longest(classification_paths) 

192 

193 return classification_paths 

194 

195 def issns(self): 

196 issns = [] 

197 issns += self.get_identifiers(self.P_ISSN) 

198 issns += self.get_identifiers(self.E_ISSN) 

199 return issns 

200 

201 @property 

202 def first_pissn(self): 

203 return self.get_identifiers(self.P_ISSN)[0] 

204 

205 @property 

206 def first_eissn(self): 

207 return self.get_identifiers(self.E_ISSN)[0]