-
Notifications
You must be signed in to change notification settings - Fork 16
/
journal_form.py
486 lines (397 loc) · 20.5 KB
/
journal_form.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
from werkzeug.datastructures import MultiDict
from portality import models, lcc
from portality.datasets import licenses
from portality.forms.utils import expanded2compact
from portality.models import Account
class JournalGenericXWalk(object):
"""
~~Journal:Crosswalk->Journal:Form~~
~~->Journal:Model~~
"""
@classmethod
def forminfo2multidict(cls, forminfo):
formdata = expanded2compact(forminfo,
join_lists={"keywords": ",", "subject": ","},
repeat_lists=["preservation_service_library", "language"]
)
return MultiDict(formdata)
@classmethod
def is_new_editor_group(cls, form, old):
old_eg = old.editor_group
new_eg = form.editor_group.data
return old_eg != new_eg and new_eg is not None and new_eg != ""
@classmethod
def is_new_editor(cls, form, old):
old_ed = old.editor
new_ed = form.editor.data
return old_ed != new_ed and new_ed is not None and new_ed != ""
@classmethod
def form_diff(cls, a_formdata, b_formdata):
def _serialise(x):
if isinstance(x, list):
return "; ".join(sorted([_serialise(y) for y in x]))
elif isinstance(x, dict):
kvs = []
for k, v in x.items():
kvs.append(k + ":" + str(v))
kvs.sort()
return ", ".join(kvs)
else:
return x
diff = {}
for k, v in b_formdata.items():
if k in a_formdata:
if isinstance(a_formdata[k], list):
for entry in a_formdata[k]:
if entry not in v:
diff[k] = {"a" : _serialise(a_formdata[k]), "b" : _serialise(v)}
break
for entry in v:
if entry not in a_formdata[k]:
diff[k] = {"a": _serialise(a_formdata[k]), "b": _serialise(v)}
break
elif isinstance(a_formdata[k], dict):
pass # No instances of this in our current form, so leaving it out
else:
if a_formdata[k] != v:
diff[k] = {"a" : a_formdata[k], "b" : v}
else:
diff[k] = {"a" : "", "b": _serialise(v)}
return diff
@classmethod
def form2bibjson(cls, form, bibjson):
# pre-strip all the form content whitespace
for field in form:
if hasattr(field.data, "strip"):
field.data = field.data.strip()
if form.alternative_title.data:
bibjson.alternative_title = form.alternative_title.data
for apc_record in form.apc_charges.data:
if not apc_record["apc_currency"] and not apc_record["apc_max"]:
continue
bibjson.add_apc(apc_record["apc_currency"], apc_record["apc_max"])
if form.apc_url.data:
bibjson.apc_url = form.apc_url.data
if form.preservation_service.data:
pres_services = [e for e in form.preservation_service.data if e not in ["national_library", "none", "other"]]
if "other" in form.preservation_service.data and form.preservation_service_other.data:
pres_services.append(form.preservation_service_other.data)
bibjson.set_preservation(pres_services, None)
if "national_library" in form.preservation_service.data and form.preservation_service_library.data:
libs = [x for x in form.preservation_service_library.data if x]
for lib in libs:
bibjson.add_preservation_library(lib)
if "none" in form.preservation_service.data:
bibjson.has_preservation = False
if form.preservation_service_url.data:
bibjson.preservation_url = form.preservation_service_url.data
if form.copyright_author_retains.data:
bibjson.author_retains_copyright = form.copyright_author_retains.data == 'y'
if form.copyright_url.data:
bibjson.copyright_url = form.copyright_url.data
if form.publisher_name.data:
bibjson.publisher_name = form.publisher_name.data
if form.publisher_country.data:
bibjson.publisher_country = form.publisher_country.data
if form.deposit_policy.data:
dep_services = [e for e in form.deposit_policy.data if e not in ["none", "other"]]
if "other" in form.deposit_policy.data and form.deposit_policy_other.data:
dep_services.append(form.deposit_policy_other.data)
if dep_services:
bibjson.deposit_policy = dep_services
else:
bibjson.has_deposit_policy = False
if form.review_process.data or form.review_url.data:
processes = None
if form.review_process.data:
processes = [e for e in form.review_process.data if e not in ["other"]]
if "other" in form.review_process.data and form.review_process_other.data:
processes.append(form.review_process_other.data)
bibjson.set_editorial_review(processes, form.review_url.data, form.editorial_board_url.data)
if form.pissn.data:
bibjson.pissn = form.pissn.data
if form.eissn.data:
bibjson.eissn = form.eissn.data
if form.institution_name.data:
bibjson.institution_name = form.institution_name.data
if form.institution_country.data:
bibjson.institution_country = form.institution_country.data
if form.keywords.data:
bibjson.keywords = form.keywords.data
if form.language.data:
norm_language = [x for x in form.language.data if x != ""]
if norm_language:
bibjson.language = norm_language # select multiple field - gives a list back
lurl = form.license_terms_url.data
if lurl:
bibjson.license_terms_url = lurl
if form.license.data:
for ltype in form.license.data:
by, nc, nd, sa = None, None, None, None
if ltype in licenses:
by = licenses[ltype]['BY']
nc = licenses[ltype]['NC']
nd = licenses[ltype]['ND']
sa = licenses[ltype]['SA']
lurl = licenses[ltype]["url"]
elif form.license_attributes.data:
by = True if 'BY' in form.license_attributes.data else False
nc = True if 'NC' in form.license_attributes.data else False
nd = True if 'ND' in form.license_attributes.data else False
sa = True if 'SA' in form.license_attributes.data else False
bibjson.add_license(ltype, url=lurl, by=by, nc=nc, nd=nd, sa=sa)
# FIXME: this is not quite what we planned
if form.license_display.data:
bibjson.article_license_display = ["Embed"] if form.license_display.data == "y" else ["No"]
if form.license_display_example_url.data:
bibjson.article_license_display_example_url = form.license_display_example_url.data
if form.boai.data:
bibjson.boai = form.boai.data == "y"
if form.oa_start.data:
bibjson.oa_start = form.oa_start.data
if form.oa_statement_url.data:
bibjson.oa_statement_url = form.oa_statement_url.data
if form.journal_url.data:
bibjson.journal_url = form.journal_url.data
if form.aims_scope_url.data:
bibjson.aims_scope_url = form.aims_scope_url.data
if form.author_instructions_url.data:
bibjson.author_instructions_url = form.author_instructions_url.data
if form.waiver_url.data:
bibjson.waiver_url = form.waiver_url.data
if form.persistent_identifiers.data:
schemes = [e for e in form.persistent_identifiers.data if e not in ["none", "other"]]
if "other" in form.persistent_identifiers.data and form.persistent_identifiers_other.data:
schemes.append(form.persistent_identifiers_other.data)
if len(schemes) > 0:
bibjson.pid_scheme = schemes
elif "none" in form.persistent_identifiers.data:
bibjson.has_pid_scheme = False
if form.plagiarism_detection.data:
has_detection = form.plagiarism_detection.data == "y"
bibjson.set_plagiarism_detection(form.plagiarism_url.data, has_detection)
if form.publication_time_weeks.data:
bibjson.publication_time_weeks = form.publication_time_weeks.data
if form.other_charges_url.data:
bibjson.other_charges_url = form.other_charges_url.data
if form.title.data:
bibjson.title = form.title.data
if form.apc.data:
bibjson.has_apc = form.apc.data == "y"
if form.has_other_charges.data:
has_other = form.has_other_charges.data == "y"
bibjson.has_other_charges = has_other
if form.has_waiver.data:
has_waiver = form.has_waiver.data == "y"
bibjson.has_waiver = has_waiver
if form.orcid_ids.data:
orcids = form.orcid_ids.data == "y"
bibjson.article_orcid = orcids
if form.open_citations.data:
oc = form.open_citations.data == "y"
bibjson.article_i4oc_open_citations = oc
if form.deposit_policy_url.data:
bibjson.deposit_policy_url = form.deposit_policy_url.data
# continuations information
if getattr(form, "continues", None):
bibjson.replaces = form.continues.data
if getattr(form, "continued_by", None):
bibjson.is_replaced_by = form.continued_by.data
if getattr(form, "discontinued_date", None):
bibjson.discontinued_date = form.discontinued_date.data
# subject information
if getattr(form, "subject", None):
new_subjects = []
incoming = form.subject.data
if not isinstance(incoming, list):
incoming = [x.strip() for x in form.subject.data.split(",")]
for code in incoming:
sobj = {"scheme": 'LCC', "term": lcc.lookup_code(code), "code": code}
new_subjects.append(sobj)
bibjson.subject = new_subjects
@classmethod
def form2admin(cls, form, obj):
if getattr(form, "notes", None):
for formnote in form.notes.data:
if formnote["note"]:
note_date = formnote["note_date"]
note_id = formnote["note_id"]
obj.add_note(formnote["note"], date=note_date, id=note_id,
author_id=formnote["note_author_id"])
if getattr(form, 'owner', None):
owner = form.owner.data
if owner:
owner = owner.strip()
obj.set_owner(owner)
if getattr(form, 'editor_group', None):
editor_group = form.editor_group.data
if editor_group:
editor_group = editor_group.strip()
obj.set_editor_group(editor_group)
if getattr(form, "editor", None):
editor = form.editor.data
if editor:
editor = editor.strip()
obj.set_editor(editor)
if getattr(form, "doaj_seal", None):
obj.set_seal(form.doaj_seal.data)
@classmethod
def bibjson2form(cls, bibjson, forminfo):
from portality.models import JournalLikeBibJSON
from portality.forms.application_forms import ApplicationFormFactory
from portality.datasets import get_currency_code
assert isinstance(bibjson, JournalLikeBibJSON)
forminfo['alternative_title'] = bibjson.alternative_title
# when we crosswalk the apc currency we also have to check that it is current
# so that we only present information to the form is the form is capable of
# presenting it on to the user
forminfo["apc_charges"] = []
for apc_record in bibjson.apc:
currency = apc_record.get("currency")
check = get_currency_code(currency, fail_if_not_found=True)
if check is None:
continue
forminfo["apc_charges"].append({
"apc_currency" : apc_record.get("currency"),
"apc_max" : apc_record.get("price")
})
forminfo["apc_url"] = bibjson.apc_url
pres_choices = [x for x, y in ApplicationFormFactory.choices_for("preservation_service")]
if bibjson.preservation_services is not None:
forminfo["preservation_service"] = [x for x in bibjson.preservation_services if x in pres_choices]
forminfo["preservation_service_other"] = " ".join([x for x in bibjson.preservation_services if x not in pres_choices])
if len(forminfo["preservation_service_other"]) > 0:
forminfo["preservation_service"].append("other")
if "preservation_service" not in forminfo:
forminfo["preservation_service"] = []
if bibjson.preservation_library:
forminfo["preservation_service_library"] = bibjson.preservation_library
forminfo["preservation_service"].append("national_library")
if bibjson.has_preservation is False and len(forminfo["preservation_service"]) == 0:
forminfo["preservation_service"].append("none")
forminfo["preservation_service_url"] = bibjson.preservation_url
if bibjson.author_retains_copyright is not None:
forminfo["copyright_author_retains"] = "y" if bibjson.author_retains_copyright else "n"
forminfo["copyright_url"] = bibjson.copyright_url
forminfo["publisher_name"] = bibjson.publisher_name
forminfo["publisher_country"] = bibjson.publisher_country
dep_choices = [x for x, y in ApplicationFormFactory.choices_for("deposit_policy")]
if bibjson.deposit_policy:
forminfo["deposit_policy"] = [x for x in bibjson.deposit_policy if x in dep_choices]
forminfo["deposit_policy_other"] = " ".join([x for x in bibjson.deposit_policy if x not in dep_choices])
if len(forminfo["deposit_policy_other"]) > 0:
forminfo["deposit_policy"].append("other")
if "deposit_policy" not in forminfo:
forminfo["deposit_policy"] = []
if bibjson.has_deposit_policy is False and len(forminfo["deposit_policy"]) == 0:
forminfo["deposit_policy"].append("none")
review_choices = [x for x, y in ApplicationFormFactory.choices_for("review_process")]
if bibjson.editorial_review_process:
forminfo["review_process"] = [x for x in bibjson.editorial_review_process if x in review_choices]
forminfo["review_process_other"] = " ".join([x for x in bibjson.editorial_review_process if x not in review_choices])
if len(forminfo["review_process_other"]) > 0:
forminfo["review_process"].append("other")
forminfo["review_url"] = bibjson.editorial_review_url
forminfo["pissn"] = bibjson.pissn
forminfo["eissn"] = bibjson.eissn
if bibjson.institution_name:
forminfo["institution_name"] = bibjson.institution_name
if bibjson.institution_country:
forminfo["institution_country"] = bibjson.institution_country
forminfo['keywords'] = bibjson.keywords # fixme: all keywords are being rendered as one single item
forminfo['language'] = bibjson.language
license_attributes = []
ltypes = []
for l in bibjson.licenses:
ltypes.append(l.get("type"))
if l.get("type") == "Publisher's own license":
if l.get("BY"): license_attributes.append("BY")
if l.get("SA"): license_attributes.append("SA")
if l.get("NC"): license_attributes.append("NC")
if l.get("ND"): license_attributes.append("ND")
forminfo["license_attributes"] = license_attributes
forminfo["license"] = ltypes
if bibjson.article_license_display is not None and len(bibjson.article_license_display) > 0:
forminfo["license_display"] = "y" if "Embed" in bibjson.article_license_display else "n"
forminfo["license_display_example_url"] = bibjson.article_license_display_example_url
if bibjson.boai is not None:
forminfo["boai"] = 'y' if bibjson.boai else 'n'
forminfo["license_terms_url"] = bibjson.license_terms_url
if bibjson.oa_start:
forminfo["oa_start"] = bibjson.oa_start
forminfo["oa_statement_url"] = bibjson.oa_statement_url
forminfo["journal_url"] = bibjson.journal_url
forminfo["aims_scope_url"] = bibjson.aims_scope_url
forminfo["editorial_board_url"] = bibjson.editorial_board_url
forminfo["author_instructions_url"] = bibjson.author_instructions_url
forminfo["waiver_url"] = bibjson.waiver_url
pid_choices = [x for x, y in ApplicationFormFactory.choices_for("persistent_identifiers")]
if bibjson.pid_scheme:
forminfo["persistent_identifiers"] = [x for x in bibjson.pid_scheme if x in pid_choices]
forminfo["persistent_identifiers_other"] = " ".join([x for x in bibjson.pid_scheme if x not in pid_choices])
if len(forminfo["persistent_identifiers_other"]) > 0:
forminfo["persistent_identifiers"].append("other")
if bibjson.has_pid_scheme is False: # distinct from None
forminfo["persistent_identifiers"] = ["none"]
if bibjson.plagiarism_detection is not None:
forminfo["plagiarism_detection"] = "y" if bibjson.plagiarism_detection else "n"
forminfo["plagiarism_url"] = bibjson.plagiarism_url
forminfo["publication_time_weeks"] = bibjson.publication_time_weeks
forminfo["other_charges_url"] = bibjson.other_charges_url
forminfo['title'] = bibjson.title
# FIXME: these translations don't handle partial records (i.e. drafts)
# we may want to add some methods to allow the settedness of these fields to be checked
if bibjson.has_apc is not None:
forminfo["apc"] = "y" if bibjson.has_apc else "n"
if bibjson.has_other_charges is not None:
forminfo["has_other_charges"] = "y" if bibjson.has_other_charges else "n"
if bibjson.has_waiver is not None:
forminfo["has_waiver"] = "y" if bibjson.has_waiver else "n"
if bibjson.article_orcid is not None:
forminfo["orcid_ids"] = "y" if bibjson.article_orcid else "n"
if bibjson.article_i4oc_open_citations is not None:
forminfo["open_citations"] = "y" if bibjson.article_i4oc_open_citations else "n"
forminfo["deposit_policy_url"] = bibjson.deposit_policy_url
# continuation information
forminfo["continues"] = bibjson.replaces
forminfo["continued_by"] = bibjson.is_replaced_by
forminfo["discontinued_date"] = bibjson.discontinued_date
# subject classifications
forminfo['subject'] = []
for s in bibjson.subject:
if "code" in s:
forminfo['subject'].append(s['code'])
@classmethod
def admin2form(cls, obj, forminfo):
forminfo['notes'] = []
for n in obj.ordered_notes:
author_id = n.get('author_id', '')
note_author_name = f'{Account.get_name_safe(author_id)}({author_id})' if author_id else ''
note_obj = {'note': n['note'], 'note_date': n['date'], 'note_id': n['id'],
'note_author': note_author_name,
'note_author_id': author_id,
}
forminfo['notes'].append(note_obj)
forminfo['owner'] = obj.owner
if obj.editor_group is not None:
forminfo['editor_group'] = obj.editor_group
if obj.editor is not None:
forminfo['editor'] = obj.editor
forminfo['doaj_seal'] = obj.has_seal()
class JournalFormXWalk(JournalGenericXWalk):
@classmethod
def form2obj(cls, form):
journal = models.Journal()
bibjson = journal.bibjson()
# first do the generic crosswalk to bibjson
cls.form2bibjson(form, bibjson)
# then do the admin fields
cls.form2admin(form, journal)
return journal
@classmethod
def obj2form(cls, obj):
forminfo = {}
bibjson = obj.bibjson()
cls.bibjson2form(bibjson, forminfo)
cls.admin2form(obj, forminfo)
return forminfo