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
« 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
5from werkzeug import MultiDict
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)
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 != ""
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 != ""
32 @classmethod
33 def form_diff(cls, a_formdata, b_formdata):
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
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
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}
66 else:
67 diff[k] = {"a" : "", "b": _serialise(v)}
69 return diff
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()
78 if form.alternative_title.data:
79 bibjson.alternative_title = form.alternative_title.data
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"])
86 if form.apc_url.data:
87 bibjson.apc_url = form.apc_url.data
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
101 if form.preservation_service_url.data:
102 bibjson.preservation_url = form.preservation_service_url.data
104 if form.copyright_author_retains.data:
105 bibjson.author_retains_copyright = form.copyright_author_retains.data == 'y'
107 if form.copyright_url.data:
108 bibjson.copyright_url = form.copyright_url.data
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
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
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)
132 if form.pissn.data:
133 bibjson.pissn = form.pissn.data
135 if form.eissn.data:
136 bibjson.eissn = form.eissn.data
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
143 if form.keywords.data:
144 bibjson.keywords = form.keywords.data
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
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)
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"]
174 if form.license_display_example_url.data:
175 bibjson.article_license_display_example_url = form.license_display_example_url.data
177 if form.boai.data:
178 bibjson.boai = form.boai.data == "y"
180 if form.oa_start.data:
181 bibjson.oa_start = form.oa_start.data
183 if form.oa_statement_url.data:
184 bibjson.oa_statement_url = form.oa_statement_url.data
186 if form.journal_url.data:
187 bibjson.journal_url = form.journal_url.data
189 if form.aims_scope_url.data:
190 bibjson.aims_scope_url = form.aims_scope_url.data
192 if form.author_instructions_url.data:
193 bibjson.author_instructions_url = form.author_instructions_url.data
195 if form.waiver_url.data:
196 bibjson.waiver_url = form.waiver_url.data
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
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)
211 if form.publication_time_weeks.data:
212 bibjson.publication_time_weeks = form.publication_time_weeks.data
214 if form.other_charges_url.data:
215 bibjson.other_charges_url = form.other_charges_url.data
217 if form.title.data:
218 bibjson.title = form.title.data
220 if form.apc.data:
221 bibjson.has_apc = form.apc.data == "y"
223 if form.has_other_charges.data:
224 has_other = form.has_other_charges.data == "y"
225 bibjson.has_other_charges = has_other
227 if form.has_waiver.data:
228 has_waiver = form.has_waiver.data == "y"
229 bibjson.has_waiver = has_waiver
231 if form.orcid_ids.data:
232 orcids = form.orcid_ids.data == "y"
233 bibjson.article_orcid = orcids
235 if form.open_citations.data:
236 oc = form.open_citations.data == "y"
237 bibjson.article_i4oc_open_citations = oc
239 if form.deposit_policy_url.data:
240 bibjson.deposit_policy_url = form.deposit_policy_url.data
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
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
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)
270 if getattr(form, 'owner', None):
271 owner = form.owner.data
272 if owner:
273 owner = owner.strip()
274 obj.set_owner(owner)
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)
282 if getattr(form, "editor", None):
283 editor = form.editor.data
284 if editor:
285 editor = editor.strip()
286 obj.set_editor(editor)
288 if getattr(form, "doaj_seal", None):
289 obj.set_seal(form.doaj_seal.data)
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)
297 forminfo['alternative_title'] = bibjson.alternative_title
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 })
306 forminfo["apc_url"] = bibjson.apc_url
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")
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
327 forminfo["publisher_name"] = bibjson.publisher_name
328 forminfo["publisher_country"] = bibjson.publisher_country
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")
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")
348 forminfo["review_url"] = bibjson.editorial_review_url
349 forminfo["pissn"] = bibjson.pissn
350 forminfo["eissn"] = bibjson.eissn
352 if bibjson.institution_name:
353 forminfo["institution_name"] = bibjson.institution_name
354 if bibjson.institution_country:
355 forminfo["institution_country"] = bibjson.institution_country
357 forminfo['keywords'] = bibjson.keywords # fixme: all keywords are being rendered as one single item
358 forminfo['language'] = bibjson.language
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
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
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"]
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
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"
416 forminfo["deposit_policy_url"] = bibjson.deposit_policy_url
418 # continuation information
419 forminfo["continues"] = bibjson.replaces
420 forminfo["continued_by"] = bibjson.is_replaced_by
421 forminfo["discontinued_date"] = bibjson.discontinued_date
423 # subject classifications
424 forminfo['subject'] = []
425 for s in bibjson.subject:
426 if "code" in s:
427 forminfo['subject'].append(s['code'])
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)
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
442 forminfo['doaj_seal'] = obj.has_seal()
445class JournalFormXWalk(JournalGenericXWalk):
447 @classmethod
448 def form2obj(cls, form):
449 journal = models.Journal()
450 bibjson = journal.bibjson()
452 # first do the generic crosswalk to bibjson
453 cls.form2bibjson(form, bibjson)
455 # then do the admin fields
456 cls.form2admin(form, journal)
458 return journal
460 @classmethod
461 def obj2form(cls, obj):
462 forminfo = {}
463 bibjson = obj.bibjson()
465 cls.bibjson2form(bibjson, forminfo)
466 cls.admin2form(obj, forminfo)
468 return forminfo