Coverage for portality/crosswalks/journal_form.py: 88%

358 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-22 15:59 +0100

1from portality import models, lcc 

2from portality.datasets import licenses 

3from portality.forms.utils import expanded2compact 

4 

5from werkzeug import MultiDict 

6 

7class JournalGenericXWalk(object): 

8 """ 

9 ~~Journal:Crosswalk->Journal:Form~~ 

10 ~~->Journal:Model~~ 

11 """ 

12 @classmethod 

13 def forminfo2multidict(cls, forminfo): 

14 formdata = expanded2compact(forminfo, 

15 join_lists={"keywords": ",", "subject": ","}, 

16 repeat_lists=["preservation_service_library", "language"] 

17 ) 

18 return MultiDict(formdata) 

19 

20 @classmethod 

21 def is_new_editor_group(cls, form, old): 

22 old_eg = old.editor_group 

23 new_eg = form.editor_group.data 

24 return old_eg != new_eg and new_eg is not None and new_eg != "" 

25 

26 @classmethod 

27 def is_new_editor(cls, form, old): 

28 old_ed = old.editor 

29 new_ed = form.editor.data 

30 return old_ed != new_ed and new_ed is not None and new_ed != "" 

31 

32 @classmethod 

33 def form_diff(cls, a_formdata, b_formdata): 

34 

35 def _serialise(x): 

36 if isinstance(x, list): 

37 return "; ".join(sorted([_serialise(y) for y in x])) 

38 elif isinstance(x, dict): 

39 kvs = [] 

40 for k, v in x.items(): 

41 kvs.append(k + ":" + str(v)) 

42 kvs.sort() 

43 return ", ".join(kvs) 

44 else: 

45 return x 

46 

47 diff = {} 

48 for k, v in b_formdata.items(): 

49 if k in a_formdata: 

50 if isinstance(a_formdata[k], list): 

51 for entry in a_formdata[k]: 

52 if entry not in v: 

53 diff[k] = {"a" : _serialise(a_formdata[k]), "b" : _serialise(v)} 

54 break 

55 for entry in v: 

56 if entry not in a_formdata[k]: 

57 diff[k] = {"a": _serialise(a_formdata[k]), "b": _serialise(v)} 

58 break 

59 

60 elif isinstance(a_formdata[k], dict): 

61 pass # No instances of this in our current form, so leaving it out 

62 else: 

63 if a_formdata[k] != v: 

64 diff[k] = {"a" : a_formdata[k], "b" : v} 

65 

66 else: 

67 diff[k] = {"a" : "", "b": _serialise(v)} 

68 

69 return diff 

70 

71 @classmethod 

72 def form2bibjson(cls, form, bibjson): 

73 # pre-strip all the form content whitespace 

74 for field in form: 

75 if hasattr(field.data, "strip"): 

76 field.data = field.data.strip() 

77 

78 if form.alternative_title.data: 

79 bibjson.alternative_title = form.alternative_title.data 

80 

81 for apc_record in form.apc_charges.data: 

82 if not apc_record["apc_currency"] and not apc_record["apc_max"]: 

83 continue 

84 bibjson.add_apc(apc_record["apc_currency"], apc_record["apc_max"]) 

85 

86 if form.apc_url.data: 

87 bibjson.apc_url = form.apc_url.data 

88 

89 if form.preservation_service.data: 

90 pres_services = [e for e in form.preservation_service.data if e not in ["national_library", "none", "other"]] 

91 if "other" in form.preservation_service.data and form.preservation_service_other.data: 

92 pres_services.append(form.preservation_service_other.data) 

93 bibjson.set_preservation(pres_services, None) 

94 if "national_library" in form.preservation_service.data and form.preservation_service_library.data: 

95 libs = [x for x in form.preservation_service_library.data if x] 

96 for lib in libs: 

97 bibjson.add_preservation_library(lib) 

98 if "none" in form.preservation_service.data: 

99 bibjson.has_preservation = False 

100 

101 if form.preservation_service_url.data: 

102 bibjson.preservation_url = form.preservation_service_url.data 

103 

104 if form.copyright_author_retains.data: 

105 bibjson.author_retains_copyright = form.copyright_author_retains.data == 'y' 

106 

107 if form.copyright_url.data: 

108 bibjson.copyright_url = form.copyright_url.data 

109 

110 if form.publisher_name.data: 

111 bibjson.publisher_name = form.publisher_name.data 

112 if form.publisher_country.data: 

113 bibjson.publisher_country = form.publisher_country.data 

114 

115 if form.deposit_policy.data: 

116 dep_services = [e for e in form.deposit_policy.data if e not in ["none", "other"]] 

117 if "other" in form.deposit_policy.data and form.deposit_policy_other.data: 

118 dep_services.append(form.deposit_policy_other.data) 

119 if dep_services: 

120 bibjson.deposit_policy = dep_services 

121 else: 

122 bibjson.has_deposit_policy = False 

123 

124 if form.review_process.data or form.review_url.data: 

125 processes = None 

126 if form.review_process.data: 

127 processes = [e for e in form.review_process.data if e not in ["other"]] 

128 if "other" in form.review_process.data and form.review_process_other.data: 

129 processes.append(form.review_process_other.data) 

130 bibjson.set_editorial_review(processes, form.review_url.data, form.editorial_board_url.data) 

131 

132 if form.pissn.data: 

133 bibjson.pissn = form.pissn.data 

134 

135 if form.eissn.data: 

136 bibjson.eissn = form.eissn.data 

137 

138 if form.institution_name.data: 

139 bibjson.institution_name = form.institution_name.data 

140 if form.institution_country.data: 

141 bibjson.institution_country = form.institution_country.data 

142 

143 if form.keywords.data: 

144 bibjson.keywords = form.keywords.data 

145 

146 if form.language.data: 

147 norm_language = [x for x in form.language.data if x != ""] 

148 if norm_language: 

149 bibjson.language = norm_language # select multiple field - gives a list back 

150 

151 lurl = form.license_terms_url.data 

152 if lurl: 

153 bibjson.license_terms_url = lurl 

154 if form.license.data: 

155 for ltype in form.license.data: 

156 by, nc, nd, sa = None, None, None, None 

157 if ltype in licenses: 

158 by = licenses[ltype]['BY'] 

159 nc = licenses[ltype]['NC'] 

160 nd = licenses[ltype]['ND'] 

161 sa = licenses[ltype]['SA'] 

162 lurl = licenses[ltype]["url"] 

163 elif form.license_attributes.data: 

164 by = True if 'BY' in form.license_attributes.data else False 

165 nc = True if 'NC' in form.license_attributes.data else False 

166 nd = True if 'ND' in form.license_attributes.data else False 

167 sa = True if 'SA' in form.license_attributes.data else False 

168 bibjson.add_license(ltype, url=lurl, by=by, nc=nc, nd=nd, sa=sa) 

169 

170 # FIXME: this is not quite what we planned 

171 if form.license_display.data: 

172 bibjson.article_license_display = ["Embed"] if form.license_display.data == "y" else ["No"] 

173 

174 if form.license_display_example_url.data: 

175 bibjson.article_license_display_example_url = form.license_display_example_url.data 

176 

177 if form.boai.data: 

178 bibjson.boai = form.boai.data == "y" 

179 

180 if form.oa_start.data: 

181 bibjson.oa_start = form.oa_start.data 

182 

183 if form.oa_statement_url.data: 

184 bibjson.oa_statement_url = form.oa_statement_url.data 

185 

186 if form.journal_url.data: 

187 bibjson.journal_url = form.journal_url.data 

188 

189 if form.aims_scope_url.data: 

190 bibjson.aims_scope_url = form.aims_scope_url.data 

191 

192 if form.author_instructions_url.data: 

193 bibjson.author_instructions_url = form.author_instructions_url.data 

194 

195 if form.waiver_url.data: 

196 bibjson.waiver_url = form.waiver_url.data 

197 

198 if form.persistent_identifiers.data: 

199 schemes = [e for e in form.persistent_identifiers.data if e not in ["none", "other"]] 

200 if "other" in form.persistent_identifiers.data and form.persistent_identifiers_other.data: 

201 schemes.append(form.persistent_identifiers_other.data) 

202 if len(schemes) > 0: 

203 bibjson.pid_scheme = schemes 

204 elif "none" in form.persistent_identifiers.data: 

205 bibjson.has_pid_scheme = False 

206 

207 if form.plagiarism_detection.data: 

208 has_detection = form.plagiarism_detection.data == "y" 

209 bibjson.set_plagiarism_detection(form.plagiarism_url.data, has_detection) 

210 

211 if form.publication_time_weeks.data: 

212 bibjson.publication_time_weeks = form.publication_time_weeks.data 

213 

214 if form.other_charges_url.data: 

215 bibjson.other_charges_url = form.other_charges_url.data 

216 

217 if form.title.data: 

218 bibjson.title = form.title.data 

219 

220 if form.apc.data: 

221 bibjson.has_apc = form.apc.data == "y" 

222 

223 if form.has_other_charges.data: 

224 has_other = form.has_other_charges.data == "y" 

225 bibjson.has_other_charges = has_other 

226 

227 if form.has_waiver.data: 

228 has_waiver = form.has_waiver.data == "y" 

229 bibjson.has_waiver = has_waiver 

230 

231 if form.orcid_ids.data: 

232 orcids = form.orcid_ids.data == "y" 

233 bibjson.article_orcid = orcids 

234 

235 if form.open_citations.data: 

236 oc = form.open_citations.data == "y" 

237 bibjson.article_i4oc_open_citations = oc 

238 

239 if form.deposit_policy_url.data: 

240 bibjson.deposit_policy_url = form.deposit_policy_url.data 

241 

242 # continuations information 

243 if getattr(form, "continues", None): 

244 bibjson.replaces = form.continues.data 

245 if getattr(form, "continued_by", None): 

246 bibjson.is_replaced_by = form.continued_by.data 

247 if getattr(form, "discontinued_date", None): 

248 bibjson.discontinued_date = form.discontinued_date.data 

249 

250 # subject information 

251 if getattr(form, "subject", None): 

252 new_subjects = [] 

253 incoming = form.subject.data 

254 if not isinstance(incoming, list): 

255 incoming = [x.strip() for x in form.subject.data.split(",")] 

256 for code in incoming: 

257 sobj = {"scheme": 'LCC', "term": lcc.lookup_code(code), "code": code} 

258 new_subjects.append(sobj) 

259 bibjson.subject = new_subjects 

260 

261 @classmethod 

262 def form2admin(cls, form, obj): 

263 if getattr(form, "notes", None): 

264 for formnote in form.notes.data: 

265 if formnote["note"]: 

266 note_date = formnote["note_date"] 

267 note_id = formnote["note_id"] 

268 obj.add_note(formnote["note"], date=note_date, id=note_id) 

269 

270 if getattr(form, 'owner', None): 

271 owner = form.owner.data 

272 if owner: 

273 owner = owner.strip() 

274 obj.set_owner(owner) 

275 

276 if getattr(form, 'editor_group', None): 

277 editor_group = form.editor_group.data 

278 if editor_group: 

279 editor_group = editor_group.strip() 

280 obj.set_editor_group(editor_group) 

281 

282 if getattr(form, "editor", None): 

283 editor = form.editor.data 

284 if editor: 

285 editor = editor.strip() 

286 obj.set_editor(editor) 

287 

288 if getattr(form, "doaj_seal", None): 

289 obj.set_seal(form.doaj_seal.data) 

290 

291 @classmethod 

292 def bibjson2form(cls, bibjson, forminfo): 

293 from portality.models import JournalLikeBibJSON 

294 from portality.forms.application_forms import ApplicationFormFactory 

295 assert isinstance(bibjson, JournalLikeBibJSON) 

296 

297 forminfo['alternative_title'] = bibjson.alternative_title 

298 

299 forminfo["apc_charges"] = [] 

300 for apc_record in bibjson.apc: 

301 forminfo["apc_charges"].append({ 

302 "apc_currency" : apc_record.get("currency"), 

303 "apc_max" : apc_record.get("price") 

304 }) 

305 

306 forminfo["apc_url"] = bibjson.apc_url 

307 

308 pres_choices = [x for x, y in ApplicationFormFactory.choices_for("preservation_service")] 

309 if bibjson.preservation_services is not None: 

310 forminfo["preservation_service"] = [x for x in bibjson.preservation_services if x in pres_choices] 

311 forminfo["preservation_service_other"] = " ".join([x for x in bibjson.preservation_services if x not in pres_choices]) 

312 if len(forminfo["preservation_service_other"]) > 0: 

313 forminfo["preservation_service"].append("other") 

314 if "preservation_service" not in forminfo: 

315 forminfo["preservation_service"] = [] 

316 if bibjson.preservation_library: 

317 forminfo["preservation_service_library"] = bibjson.preservation_library 

318 forminfo["preservation_service"].append("national_library") 

319 if bibjson.has_preservation is False and len(forminfo["preservation_service"]) == 0: 

320 forminfo["preservation_service"].append("none") 

321 

322 forminfo["preservation_service_url"] = bibjson.preservation_url 

323 if bibjson.author_retains_copyright is not None: 

324 forminfo["copyright_author_retains"] = "y" if bibjson.author_retains_copyright else "n" 

325 forminfo["copyright_url"] = bibjson.copyright_url 

326 

327 forminfo["publisher_name"] = bibjson.publisher_name 

328 forminfo["publisher_country"] = bibjson.publisher_country 

329 

330 dep_choices = [x for x, y in ApplicationFormFactory.choices_for("deposit_policy")] 

331 if bibjson.deposit_policy: 

332 forminfo["deposit_policy"] = [x for x in bibjson.deposit_policy if x in dep_choices] 

333 forminfo["deposit_policy_other"] = " ".join([x for x in bibjson.deposit_policy if x not in dep_choices]) 

334 if len(forminfo["deposit_policy_other"]) > 0: 

335 forminfo["deposit_policy"].append("other") 

336 if "deposit_policy" not in forminfo: 

337 forminfo["deposit_policy"] = [] 

338 if bibjson.has_deposit_policy is False and len(forminfo["deposit_policy"]) == 0: 

339 forminfo["deposit_policy"].append("none") 

340 

341 review_choices = [x for x, y in ApplicationFormFactory.choices_for("review_process")] 

342 if bibjson.editorial_review_process: 

343 forminfo["review_process"] = [x for x in bibjson.editorial_review_process if x in review_choices] 

344 forminfo["review_process_other"] = " ".join([x for x in bibjson.editorial_review_process if x not in review_choices]) 

345 if len(forminfo["review_process_other"]) > 0: 

346 forminfo["review_process"].append("other") 

347 

348 forminfo["review_url"] = bibjson.editorial_review_url 

349 forminfo["pissn"] = bibjson.pissn 

350 forminfo["eissn"] = bibjson.eissn 

351 

352 if bibjson.institution_name: 

353 forminfo["institution_name"] = bibjson.institution_name 

354 if bibjson.institution_country: 

355 forminfo["institution_country"] = bibjson.institution_country 

356 

357 forminfo['keywords'] = bibjson.keywords # fixme: all keywords are being rendered as one single item 

358 forminfo['language'] = bibjson.language 

359 

360 license_attributes = [] 

361 ltypes = [] 

362 for l in bibjson.licenses: 

363 ltypes.append(l.get("type")) 

364 if l.get("type") == "Publisher's own license": 

365 if l.get("BY"): license_attributes.append("BY") 

366 if l.get("SA"): license_attributes.append("SA") 

367 if l.get("NC"): license_attributes.append("NC") 

368 if l.get("ND"): license_attributes.append("ND") 

369 forminfo["license_attributes"] = license_attributes 

370 forminfo["license"] = ltypes 

371 

372 if bibjson.article_license_display is not None and len(bibjson.article_license_display) > 0: 

373 forminfo["license_display"] = "y" if "Embed" in bibjson.article_license_display else "n" 

374 forminfo["license_display_example_url"] = bibjson.article_license_display_example_url 

375 if bibjson.boai is not None: 

376 forminfo["boai"] = 'y' if bibjson.boai else 'n' 

377 forminfo["license_terms_url"] = bibjson.license_terms_url 

378 if bibjson.oa_start: 

379 forminfo["oa_start"] = bibjson.oa_start 

380 forminfo["oa_statement_url"] = bibjson.oa_statement_url 

381 forminfo["journal_url"] = bibjson.journal_url 

382 forminfo["aims_scope_url"] = bibjson.aims_scope_url 

383 forminfo["editorial_board_url"] = bibjson.editorial_board_url 

384 forminfo["author_instructions_url"] = bibjson.author_instructions_url 

385 forminfo["waiver_url"] = bibjson.waiver_url 

386 

387 pid_choices = [x for x, y in ApplicationFormFactory.choices_for("persistent_identifiers")] 

388 if bibjson.pid_scheme: 

389 forminfo["persistent_identifiers"] = [x for x in bibjson.pid_scheme if x in pid_choices] 

390 forminfo["persistent_identifiers_other"] = " ".join([x for x in bibjson.pid_scheme if x not in pid_choices]) 

391 if len(forminfo["persistent_identifiers_other"]) > 0: 

392 forminfo["persistent_identifiers"].append("other") 

393 if bibjson.has_pid_scheme is False: # distinct from None 

394 forminfo["persistent_identifiers"] = ["none"] 

395 

396 if bibjson.plagiarism_detection is not None: 

397 forminfo["plagiarism_detection"] = "y" if bibjson.plagiarism_detection else "n" 

398 forminfo["plagiarism_url"] = bibjson.plagiarism_url 

399 forminfo["publication_time_weeks"] = bibjson.publication_time_weeks 

400 forminfo["other_charges_url"] = bibjson.other_charges_url 

401 forminfo['title'] = bibjson.title 

402 

403 # FIXME: these translations don't handle partial records (i.e. drafts) 

404 # we may want to add some methods to allow the settedness of these fields to be checked 

405 if bibjson.has_apc is not None: 

406 forminfo["apc"] = "y" if bibjson.has_apc else "n" 

407 if bibjson.has_other_charges is not None: 

408 forminfo["has_other_charges"] = "y" if bibjson.has_other_charges else "n" 

409 if bibjson.has_waiver is not None: 

410 forminfo["has_waiver"] = "y" if bibjson.has_waiver else "n" 

411 if bibjson.article_orcid is not None: 

412 forminfo["orcid_ids"] = "y" if bibjson.article_orcid else "n" 

413 if bibjson.article_i4oc_open_citations is not None: 

414 forminfo["open_citations"] = "y" if bibjson.article_i4oc_open_citations else "n" 

415 

416 forminfo["deposit_policy_url"] = bibjson.deposit_policy_url 

417 

418 # continuation information 

419 forminfo["continues"] = bibjson.replaces 

420 forminfo["continued_by"] = bibjson.is_replaced_by 

421 forminfo["discontinued_date"] = bibjson.discontinued_date 

422 

423 # subject classifications 

424 forminfo['subject'] = [] 

425 for s in bibjson.subject: 

426 if "code" in s: 

427 forminfo['subject'].append(s['code']) 

428 

429 @classmethod 

430 def admin2form(cls, obj, forminfo): 

431 forminfo['notes'] = [] 

432 for n in obj.ordered_notes: 

433 note_obj = {'note': n['note'], 'note_date': n['date'], 'note_id': n['id']} 

434 forminfo['notes'].append(note_obj) 

435 

436 forminfo['owner'] = obj.owner 

437 if obj.editor_group is not None: 

438 forminfo['editor_group'] = obj.editor_group 

439 if obj.editor is not None: 

440 forminfo['editor'] = obj.editor 

441 

442 forminfo['doaj_seal'] = obj.has_seal() 

443 

444 

445class JournalFormXWalk(JournalGenericXWalk): 

446 

447 @classmethod 

448 def form2obj(cls, form): 

449 journal = models.Journal() 

450 bibjson = journal.bibjson() 

451 

452 # first do the generic crosswalk to bibjson 

453 cls.form2bibjson(form, bibjson) 

454 

455 # then do the admin fields 

456 cls.form2admin(form, journal) 

457 

458 return journal 

459 

460 @classmethod 

461 def obj2form(cls, obj): 

462 forminfo = {} 

463 bibjson = obj.bibjson() 

464 

465 cls.bibjson2form(bibjson, forminfo) 

466 cls.admin2form(obj, forminfo) 

467 

468 return forminfo