Coverage for portality/models/v2/bibjson.py: 93%
667 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-19 18:38 +0100
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-19 18:38 +0100
1from portality.lib.seamless import SeamlessMixin, to_utf8_unicode
2from portality.models.v2 import shared_structs
3from portality import datasets
4from portality.lib import coerce
6class JournalLikeBibJSON(SeamlessMixin):
8 __SEAMLESS_STRUCT__ = shared_structs.JOURNAL_BIBJSON.get("structs", {}).get("bibjson")
10 __SEAMLESS_COERCE__ = coerce.COERCE_MAP
12 # constructor
13 def __init__(self, bibjson=None, **kwargs):
14 super(JournalLikeBibJSON, self).__init__(raw=bibjson, **kwargs)
16 @property
17 def data(self):
18 return self.__seamless__.data
20 ####################################################
21 # Current getters and setters
23 @property
24 def alternative_title(self):
25 return self.__seamless__.get_single("alternative_title")
27 @alternative_title.setter
28 def alternative_title(self, val):
29 self.__seamless__.set_with_struct("alternative_title", val)
31 @property
32 def boai(self):
33 return self.__seamless__.get_single("boai")
35 @boai.setter
36 def boai(self, val):
37 self.__seamless__.set_with_struct("boai", val)
39 @property
40 def discontinued_date(self):
41 return self.__seamless__.get_single("discontinued_date")
43 @discontinued_date.setter
44 def discontinued_date(self, val):
45 self.__seamless__.set_with_struct("discontinued_date", val)
47 @discontinued_date.deleter
48 def discontinued_date(self):
49 self.__seamless__.delete("discontinued_date")
51 @property
52 def discontinued_datestamp(self):
53 return self.__seamless__.get_single("discontinued_date", coerce=coerce.to_datestamp())
55 @property
56 def eissn(self):
57 return self.__seamless__.get_single("eissn")
59 @eissn.setter
60 def eissn(self, val):
61 self.__seamless__.set_with_struct("eissn", val)
63 @eissn.deleter
64 def eissn(self):
65 self.__seamless__.delete("eissn")
67 @property
68 def pissn(self):
69 return self.__seamless__.get_single("pissn")
71 @pissn.setter
72 def pissn(self, val):
73 self.__seamless__.set_with_struct("pissn", val)
75 @pissn.deleter
76 def pissn(self):
77 self.__seamless__.delete("pissn")
79 @property
80 def oa_start(self):
81 return self.__seamless__.get_single("oa_start")
83 @oa_start.setter
84 def oa_start(self, val):
85 self.__seamless__.set_with_struct("oa_start", val)
87 @oa_start.deleter
88 def oa_start(self):
89 self.__seamless__.delete("oa_start")
91 @property
92 def publication_time_weeks(self):
93 return self.__seamless__.get_single("publication_time_weeks")
95 @publication_time_weeks.setter
96 def publication_time_weeks(self, weeks):
97 self.__seamless__.set_with_struct("publication_time_weeks", weeks)
99 @property
100 def title(self):
101 return self.__seamless__.get_single("title")
103 @title.setter
104 def title(self, val):
105 self.__seamless__.set_with_struct("title", val)
107 @property
108 def is_replaced_by(self):
109 return self.__seamless__.get_list("is_replaced_by")
111 @is_replaced_by.setter
112 def is_replaced_by(self, val):
113 self.__seamless__.set_with_struct("is_replaced_by", val)
115 @is_replaced_by.deleter
116 def is_replaced_by(self):
117 self.__seamless__.delete("is_replaced_by")
119 def add_is_replaced_by(self, val):
120 self.__seamless__.add_to_list_with_struct("is_replaced_by", val)
122 @property
123 def keywords(self):
124 return self.__seamless__.get_list("keywords")
126 def add_keyword(self, keyword):
127 if keyword is not None:
128 self.__seamless__.add_to_list_with_struct("keywords", keyword.lower())
130 @keywords.setter
131 def keywords(self, keywords):
132 self.__seamless__.set_with_struct("keywords", keywords)
134 @property
135 def language(self):
136 return self.__seamless__.get_list("language")
138 @language.setter
139 def language(self, language):
140 self.__seamless__.set_with_struct("language", language)
142 def add_language(self, language):
143 self.__seamless__.add_to_list_with_struct("language", language)
145 @property
146 def licenses(self):
147 return self.__seamless__.get_list("license")
149 @property
150 def licences(self):
151 return self.licenses
153 def add_licence(self, license_type, url=None, by=None, sa=None, nc=None, nd=None):
154 self.add_license(license_type, url, by, sa, nc, nd)
156 def add_license(self, license_type, url=None, by=None, sa=None, nc=None, nd=None):
157 lobj = {"type": license_type}
158 if url is not None:
159 lobj["url"] = url
160 if by is not None:
161 lobj["BY"] = by
162 if sa is not None:
163 lobj["SA"] = sa
164 if nc is not None:
165 lobj["NC"] = nc
166 if nd is not None:
167 lobj["ND"] = nd
169 self.__seamless__.add_to_list_with_struct("license", lobj)
171 def remove_licenses(self):
172 self.__seamless__.delete("license")
174 @property
175 def replaces(self):
176 return self.__seamless__.get_list("replaces")
178 @replaces.setter
179 def replaces(self, val):
180 self.__seamless__.set_with_struct("replaces", val)
182 @replaces.deleter
183 def replaces(self):
184 self.__seamless__.delete("replaces")
186 def add_replaces(self, val):
187 self.__seamless__.add_to_list_with_struct("replaces", val)
189 @property
190 def subject(self):
191 return self.__seamless__.get_list("subject")
193 @subject.setter
194 def subject(self, subjects):
195 self.__seamless__.set_with_struct("subject", subjects)
197 @subject.deleter
198 def subject(self):
199 self.__seamless__.delete("subject")
201 def add_subject(self, scheme, term, code=None):
202 sobj = {"scheme": scheme, "term": term}
203 if code is not None:
204 sobj["code"] = code
205 self.__seamless__.add_to_list_with_struct("subject", sobj)
207 @property
208 def apc(self):
209 return self.__seamless__.get_list("apc.max")
211 def add_apc(self, currency, price):
212 self.__seamless__.add_to_list_with_struct("apc.max", {"currency": currency, "price" : price})
213 self.__seamless__.set_with_struct("apc.has_apc", True)
215 @property
216 def apc_url(self):
217 return self.__seamless__.get_single("apc.url")
219 @apc_url.setter
220 def apc_url(self, url):
221 self.__seamless__.set_with_struct("apc.url", url)
223 @property
224 def has_apc(self):
225 return self.__seamless__.get_single("apc.has_apc")
227 @has_apc.setter
228 def has_apc(self, val):
229 self.__seamless__.set_with_struct("apc.has_apc", val)
231 @property
232 def article_license_display(self):
233 return self.__seamless__.get_list("article.license_display")
235 @article_license_display.setter
236 def article_license_display(self, val):
237 self.__seamless__.set_with_struct("article.license_display", val)
239 # I've taken this out but left the commented code here to remind us. It used to be that you could
240 # have multiple license displays, but now you can't. The data model still allows for it, but the
241 # model should not, unless we reverse that decision at some point in the future
242 # def add_article_license_display(self, val):
243 # self.__seamless__.add_to_list_with_struct("article.license_display", val)
245 @property
246 def article_license_display_example_url(self):
247 return self.__seamless__.get_single("article.license_display_example_url")
249 @article_license_display_example_url.setter
250 def article_license_display_example_url(self, url):
251 self.__seamless__.set_with_struct("article.license_display_example_url", url)
253 @property
254 def article_orcid(self):
255 return self.__seamless__.get_single("article.orcid")
257 @article_orcid.setter
258 def article_orcid(self, val):
259 self.__seamless__.set_with_struct("article.orcid", val)
261 @property
262 def article_i4oc_open_citations(self):
263 return self.__seamless__.get_single("article.i4oc_open_citations")
265 @article_i4oc_open_citations.setter
266 def article_i4oc_open_citations(self, val):
267 self.__seamless__.set_with_struct("article.i4oc_open_citations", val)
269 @property
270 def author_retains_copyright(self):
271 return self.__seamless__.get_single("copyright.author_retains")
273 @author_retains_copyright.setter
274 def author_retains_copyright(self, val):
275 self.__seamless__.set_single("copyright.author_retains", val)
277 @property
278 def copyright_url(self):
279 return self.__seamless__.get_single("copyright.url")
281 @copyright_url.setter
282 def copyright_url(self, url):
283 self.__seamless__.set_with_struct("copyright.url", url)
285 @property
286 def deposit_policy(self):
287 return self.__seamless__.get_list("deposit_policy.service")
289 @deposit_policy.setter
290 def deposit_policy(self, policies):
291 self.__seamless__.set_with_struct("deposit_policy.service", policies)
292 if len(policies) > 0:
293 self.__seamless__.set_with_struct("deposit_policy.has_policy", True)
295 def add_deposit_policy(self, policy):
296 self.__seamless__.add_to_list_with_struct("deposit_policy.service", policy)
297 self.__seamless__.set_with_struct("deposit_policy.has_policy", True)
299 @property
300 def has_deposit_policy(self):
301 return self.__seamless__.get_single("deposit_policy.has_policy")
303 @has_deposit_policy.setter
304 def has_deposit_policy(self, val):
305 self.__seamless__.set_with_struct("deposit_policy.has_policy", val)
307 @property
308 def deposit_policy_url(self):
309 return self.__seamless__.get_single("deposit_policy.url")
311 @deposit_policy_url.setter
312 def deposit_policy_url(self, url):
313 self.__seamless__.set_with_struct("deposit_policy.url", url)
315 def set_unregistered_journal_policy(self, url):
316 self.deposit_policy_url = url
317 self.has_deposit_policy = True
319 def set_editorial_review(self, process, review_url, board_url=None):
320 self.__seamless__.set_with_struct("editorial.review_process", process)
321 self.__seamless__.set_with_struct("editorial.review_url", review_url)
322 if board_url is not None:
323 self.__seamless__.set_with_struct("editorial.board_url", board_url)
325 def add_editorial_review_process(self, process):
326 self.__seamless__.add_to_list_with_struct("editorial.review_process", process)
328 @property
329 def editorial_review_process(self):
330 return self.__seamless__.get_list("editorial.review_process")
332 @property
333 def editorial_review_url(self):
334 return self.__seamless__.get_single("editorial.review_url")
336 @editorial_review_url.setter
337 def editorial_review_url(self, url):
338 self.__seamless__.set_with_struct("editorial.review_url", url)
340 @property
341 def editorial_board_url(self):
342 return self.__seamless__.get_single("editorial.board_url")
344 @editorial_board_url.setter
345 def editorial_board_url(self, url):
346 self.__seamless__.set_with_struct("editorial.board_url", url)
348 @property
349 def institution_name(self):
350 return self.__seamless__.get_single("institution.name")
352 @institution_name.setter
353 def institution_name(self, val):
354 self.__seamless__.set_with_struct("institution.name", val)
356 @property
357 def institution_country(self):
358 return self.__seamless__.get_single("institution.country")
360 @institution_country.setter
361 def institution_country(self, country):
362 self.__seamless__.set_with_struct("institution.country", country)
364 @property
365 def has_other_charges(self):
366 return self.__seamless__.get_single("other_charges.has_other_charges")
368 @has_other_charges.setter
369 def has_other_charges(self, val):
370 self.__seamless__.set_with_struct("other_charges.has_other_charges", val)
372 @property
373 def other_charges_url(self):
374 return self.__seamless__.get_single("other_charges.url")
376 @other_charges_url.setter
377 def other_charges_url(self, url):
378 self.__seamless__.set_with_struct("other_charges.url", url)
380 @property
381 def pid_scheme(self):
382 return self.__seamless__.get_list("pid_scheme.scheme")
384 @pid_scheme.setter
385 def pid_scheme(self, schemes):
386 self.__seamless__.set_with_struct("pid_scheme.scheme", schemes)
387 if len(schemes) > 0:
388 self.__seamless__.set_with_struct("pid_scheme.has_pid_scheme", True)
389 else:
390 self.__seamless__.set_with_struct("pid_scheme.has_pid_scheme", False)
392 def add_pid_scheme(self, scheme):
393 self.__seamless__.add_to_list_with_struct("pid_scheme.scheme", scheme)
394 self.__seamless__.set_with_struct("pid_scheme.has_pid_scheme", True)
396 @property
397 def has_pid_scheme(self):
398 return self.__seamless__.get_single("pid_scheme.has_pid_scheme")
400 @has_pid_scheme.setter
401 def has_pid_scheme(self, val):
402 self.__seamless__.set_with_struct("pid_scheme.has_pid_scheme", val)
404 def set_plagiarism_detection(self, url, has_detection=True):
405 self.__seamless__.set_with_struct("plagiarism.detection", has_detection)
406 self.__seamless__.set_with_struct("plagiarism.url", url)
408 @property
409 def plagiarism_detection(self):
410 return self.__seamless__.get_single("plagiarism.detection")
412 @property
413 def plagiarism_url(self):
414 return self.__seamless__.get_single("plagiarism.url")
416 @plagiarism_url.setter
417 def plagiarism_url(self, url):
418 self.__seamless__.set_with_struct("plagiarism.url", url)
420 @property
421 def preservation(self):
422 return self.__seamless__.get_single("preservation")
424 @property
425 def preservation_services(self):
426 pres = self.preservation
427 if pres is None:
428 return []
429 if "service" in pres:
430 return pres["service"]
431 else:
432 return []
434 @property
435 def preservation_library(self):
436 pres = self.preservation
437 if pres is None:
438 return None
439 if "national_library" in pres:
440 return pres["national_library"]
441 return None
443 @property
444 def preservation_summary(self):
445 summary = []
446 summary += self.preservation_services
447 libs = self.preservation_library
448 if libs is not None:
449 for lib in libs:
450 summary.append(["A national library", lib])
451 return summary
453 def add_preservation_library(self, library):
454 self.__seamless__.add_to_list_with_struct("preservation.national_library", library)
455 self.has_preservation = True
457 def set_preservation(self, services, policy_url):
458 obj = {}
459 known = []
460 for p in services:
461 if isinstance(p, list):
462 k, v = p
463 if k.lower() == "a national library":
464 if "national_library" in obj:
465 obj["national_library"].append(v)
466 else:
467 obj["national_library"] = [v]
468 else:
469 known.append(p)
470 if len(known) > 0:
471 obj["service"] = known
472 if policy_url is not None:
473 obj["url"] = policy_url
475 self.__seamless__.set_with_struct("preservation", obj)
477 if self.preservation_services is not None or self.preservation_library is not None:
478 self.has_preservation = True
480 def add_preservation(self, services=None, libraries=None):
481 if services is not None:
482 if not isinstance(services, list):
483 services = [services]
484 for s in services:
485 self.__seamless__.add_to_list_with_struct("preservation.service", s)
486 if libraries is not None:
487 if not isinstance(libraries, list):
488 libraries = [libraries]
489 for l in libraries:
490 self.__seamless__.add_to_list_with_struct("preservation.national_library", l)
491 if self.preservation_services is not None or self.preservation_library is not None:
492 self.has_preservation = True
494 @property
495 def has_preservation(self):
496 return self.__seamless__.get_single("preservation.has_preservation")
498 @has_preservation.setter
499 def has_preservation(self, has_preservation):
500 self.__seamless__.set_single("preservation.has_preservation", has_preservation)
502 @property
503 def preservation_url(self):
504 return self.__seamless__.get_single("preservation.url")
506 @preservation_url.setter
507 def preservation_url(self, url):
508 self.__seamless__.set_with_struct("preservation.url", url)
510 @property
511 def publisher_name(self):
512 return self.__seamless__.get_single("publisher.name")
514 @publisher_name.setter
515 def publisher_name(self, val):
516 self.__seamless__.set_with_struct("publisher.name", val)
518 @property
519 def publisher_country(self):
520 return self.__seamless__.get_single("publisher.country")
522 @publisher_country.setter
523 def publisher_country(self, country):
524 self.__seamless__.set_with_struct("publisher.country", country)
526 @property
527 def review_process(self):
528 return self.__seamless__.get_list("editorial.review_proccess")
530 @review_process.setter
531 def review_process(self, review_process):
532 self.__seamless__.add_to_list_with_struct("editorial.review_process", review_process)
534 @property
535 def review_process_url(self):
536 return self.__seamless__.editorial.review_url
538 @review_process_url.setter
539 def review_process_url(self, url):
540 self.__seamless__.set_with_struct("editorial.review_url", url)
542 @property
543 def oa_statement_url(self):
544 return self.__seamless__.get_single("ref.oa_statement")
546 @oa_statement_url.setter
547 def oa_statement_url(self, url):
548 self.__seamless__.set_with_struct("ref.oa_statement", url)
550 @property
551 def journal_url(self):
552 return self.__seamless__.get_single("ref.journal")
554 @journal_url.setter
555 def journal_url(self, url):
556 self.__seamless__.set_with_struct("ref.journal", url)
558 @property
559 def aims_scope_url(self):
560 return self.__seamless__.get_single("ref.aims_scope")
562 @aims_scope_url.setter
563 def aims_scope_url(self, url):
564 self.__seamless__.set_with_struct("ref.aims_scope", url)
566 @property
567 def author_instructions_url(self):
568 return self.__seamless__.get_single("ref.author_instructions")
570 @author_instructions_url.setter
571 def author_instructions_url(self, url):
572 self.__seamless__.set_with_struct("ref.author_instructions", url)
574 @property
575 def license_terms_url(self):
576 return self.__seamless__.get_single("ref.license_terms")
578 @license_terms_url.setter
579 def license_terms_url(self, url):
580 self.__seamless__.set_with_struct("ref.license_terms", url)
582 @property
583 def has_waiver(self):
584 return self.__seamless__.get_single("waiver.has_waiver")
586 @has_waiver.setter
587 def has_waiver(self, url):
588 self.__seamless__.set_with_struct("waiver.has_waiver", url)
590 @property
591 def waiver_url(self):
592 return self.__seamless__.get_single("waiver.url")
594 @waiver_url.setter
595 def waiver_url(self, url):
596 self.__seamless__.set_with_struct("waiver.url", url)
598 #####################################################
599 ## External utility functions
601 def issns(self):
602 issns = []
603 if self.pissn:
604 issns.append(self.pissn)
605 if self.eissn:
606 issns.append(self.eissn)
607 return issns
609 def publisher_country_name(self):
610 if self.publisher_country is not None:
611 return datasets.get_country_name(self.publisher_country)
612 return None
614 def institution_country_name(self):
615 if self.institution_country is not None:
616 return datasets.get_country_name(self.institution_country)
617 return None
619 def language_name(self):
620 # copy the languages and convert them to their english forms
621 langs = [datasets.name_for_lang(l) for l in self.language]
622 langs = [to_utf8_unicode(l) for l in langs]
623 return list(set(langs))
625 def term_path(self, term):
626 from portality.lcc import lcc
627 return lcc.term_path(term)
629 def lcc_paths(self):
630 classification_paths = []
632 # calculate the classification paths
633 from portality.lcc import lcc # inline import since this hits the database
634 for subs in self.subjects():
635 scheme = subs.get("scheme")
636 term = subs.get("term")
637 if scheme == "LCC":
638 p = lcc.pathify(term)
639 if p is not None:
640 classification_paths.append(p)
642 # normalise the classification paths, so we only store the longest ones
643 classification_paths = lcc.longest(classification_paths)
645 return classification_paths
647 def lcc_codes_full_list(self):
648 full_list = set()
650 from portality.lcc import lcc # inline import since this hits the database
651 for subs in self.subjects():
652 scheme = subs.get("scheme")
653 if scheme != "LCC":
654 continue
655 code = subs.get("code")
656 expanded = lcc.expand_codes(code)
657 full_list.update(expanded)
659 return ["LCC:" + x for x in full_list if x is not None]
661 def lcc_paths_and_codes(self):
662 paths_and_codes = {}
664 # calculate the classification paths
665 from portality.lcc import lcc # inline import since this hits the database
666 for subs in self.subjects():
667 scheme = subs.get("scheme")
668 if scheme != "LCC":
669 continue
670 term = subs.get("term")
671 code = subs.get("code")
672 p = lcc.pathify(term)
673 if p is not None:
674 paths_and_codes[p] = "LCC:" + code
676 return [(x, paths_and_codes[x]) for x in lcc.longest(list(paths_and_codes.keys()))]
678 # to help with ToC - we prefer to refer to a journal by E-ISSN, or
679 # if not, then P-ISSN
680 def get_preferred_issn(self):
681 if self.eissn:
682 return self.eissn
683 if self.pissn:
684 return self.pissn
686 #####################################################
687 ## Internal utility functions
689 def _normalise_issn(self, issn):
690 if issn is None:
691 return issn
692 issn = issn.upper()
693 if len(issn) > 8: return issn
694 if len(issn) == 8:
695 if "-" in issn: return "0" + issn
696 else: return issn[:4] + "-" + issn[4:]
697 if len(issn) < 8:
698 if "-" in issn: return ("0" * (9 - len(issn))) + issn
699 else:
700 issn = ("0" * (8 - len(issn))) + issn
701 return issn[:4] + "-" + issn[4:]
703 #####################################################
704 ## Back Compat methods for v1 of the model
705 ## ALL DEPRECATED
707 @property
708 def publication_time(self):
709 return self.publication_time_weeks
711 @publication_time.setter
712 def publication_time(self, weeks):
713 self.publication_time_weeks = weeks
715 @property
716 def publisher(self):
717 return self.publisher_name
719 @publisher.setter
720 def publisher(self, val):
721 self.publisher_name = val
723 @property
724 def institution(self):
725 return self.institution_name
727 @institution.setter
728 def institution(self, val):
729 self.institution_name = val
731 def set_keywords(self, keywords):
732 self.keywords = keywords
734 def set_language(self, language):
735 self.language = language
737 @property
738 def persistent_identifier_scheme(self):
739 return self.pid_scheme
741 @persistent_identifier_scheme.setter
742 def persistent_identifier_scheme(self, schemes):
743 self.pid_scheme = schemes
745 def add_persistent_identifier_scheme(self, scheme):
746 self.add_pid_scheme(scheme)
748 def subjects(self):
749 return self.subject
751 def set_subjects(self, subjects):
752 self.subject = subjects
754 def remove_subjects(self):
755 del self.subject
757 def set_archiving_policy(self, policies, policy_url):
758 self.set_preservation(policies, policy_url)
760 def add_archiving_policy(self, policy_name):
761 self.add_preservation(policy_name)
763 @property
764 def flattened_archiving_policies(self):
765 summary = self.preservation_summary
766 if summary is None:
767 return []
768 return [": ".join(p) if isinstance(p, list) else p for p in self.preservation_summary]
770 # vocab of known identifier types
771 P_ISSN = "pissn"
772 E_ISSN = "eissn"
773 DOI = "doi"
775 IDENTIFIER_MAP = {
776 P_ISSN : "pissn",
777 E_ISSN : "eissn",
778 DOI : "doi"
779 }
781 def add_identifier(self, idtype, value):
782 field = self.IDENTIFIER_MAP.get(idtype)
783 if field is not None:
784 setattr(self, field, value)
785 return
786 raise RuntimeError("This object does not accept unrecognised identifier types")
788 def get_identifiers(self, idtype=None):
789 if idtype is None:
790 idents = []
791 if self.eissn:
792 idents.append({"type" : self.E_ISSN, "id" : self.eissn})
793 if self.pissn:
794 idents.append({"type" : self.P_ISSN, "id" : self.pissn})
795 return idents
796 field = self.IDENTIFIER_MAP.get(idtype)
797 if field is None:
798 raise RuntimeError("No identifier of type {x} known".format(x=idtype))
800 ident = getattr(self, field)
801 if ident is not None:
802 return [getattr(self, field)]
803 return []
805 def get_one_identifier(self, idtype=None):
806 if idtype is None:
807 raise RuntimeError("This object cannot return a generic identifier")
808 results = self.get_identifiers(idtype=idtype)
809 if len(results) > 0:
810 return results[0]
811 else:
812 return None
814 def _set_attr_with_no_check(self, name, value):
815 self.__setattr__(name, value, allow_coerce_failure=True)
817 # allowable values for the url types
818 HOMEPAGE = "homepage"
819 WAIVER_POLICY = "waiver_policy"
820 EDITORIAL_BOARD = "editorial_board"
821 AIMS_SCOPE = "aims_scope"
822 AUTHOR_INSTRUCTIONS = "author_instructions"
823 OA_STATEMENT = "oa_statement"
824 #FULLTEXT = "fulltext"
826 LINK_MAP = {
827 HOMEPAGE: "journal_url",
828 WAIVER_POLICY: "waiver_url",
829 EDITORIAL_BOARD: "editorial_board_url",
830 AIMS_SCOPE: "aims_scope_url",
831 AUTHOR_INSTRUCTIONS: "author_instructions_url",
832 OA_STATEMENT: "oa_statement_url"
833 }
835 def add_url(self, url, urltype=None, content_type=None):
836 if url is None:
837 # do not add empty URL-s
838 return
840 field = self.LINK_MAP.get(urltype)
841 if field is not None:
842 setattr(self, field, url)
843 return
844 raise RuntimeError("This object does not accept unrecognised url types")
846 def get_urls(self, urltype=None, unpack_urlobj=True):
847 if urltype is None:
848 raise RuntimeError("This object cannot return lists of urls")
850 field = self.LINK_MAP.get(urltype)
851 if field is None:
852 raise RuntimeError("No url of type {x} known".format(x=urltype))
854 url = getattr(self, field)
855 if unpack_urlobj:
856 return [url]
857 else:
858 return [{"type" : urltype, "url" : url}]
860 def get_single_url(self, urltype, unpack_urlobj=True):
861 urls = self.get_urls(urltype=urltype, unpack_urlobj=unpack_urlobj)
862 if len(urls) > 0:
863 return urls[0]
864 return None
866 @property
867 def first_pissn(self):
868 return self.pissn
870 @property
871 def first_eissn(self):
872 return self.eissn
874 @property
875 def country(self):
876 return self.publisher_country
878 @country.setter
879 def country(self, val):
880 self.publisher_country = val
882 @property
883 def open_access(self):
884 return self.boai
886 def set_open_access(self, open_access):
887 self.boai = open_access
889 def country_name(self):
890 return self.publisher_country_name()
892 #####################################################
893 ## Incompatible functions from v1
895 def set_license(self, license_type, url=None, version=None, open_access=None,
896 by=None, sa=None, nc=None, nd=None,
897 display=None, display_example_url=None):
898 """
899 # FIXME: why is there not a "remove license" function
900 if not license_title and not license_type: # something wants to delete the license
901 self._delete("license")
902 return
904 lobj = {"title": license_title, "type": license_type}
905 if url is not None:
906 lobj["url"] = url
907 if version is not None:
908 lobj["version"] = version
909 if open_access is not None:
910 lobj["open_access"] = open_access
911 if by is not None:
912 lobj["BY"] = by
913 if sa is not None:
914 lobj["SA"] = sa
915 if nc is not None:
916 lobj["NC"] = nc
917 if nd is not None:
918 lobj["ND"] = nd
919 if embedded is not None:
920 lobj["embedded"] = embedded
921 if embedded_example_url is not None:
922 lobj["embedded_example_url"] = embedded_example_url
924 self._set_with_struct("license", [lobj])
925 """
926 raise RuntimeError("set_license is not back compat")
928 def get_license(self):
929 """
930 ll = self._get_list("license")
931 if len(ll) > 0:
932 return ll[0]
933 return None
934 """
935 raise RuntimeError("get_license is not back compat")
937 def get_license_type(self):
938 """
939 lobj = self.get_license()
940 if lobj is not None:
941 return lobj['type']
942 return None
943 """
944 raise RuntimeError("get_license_type is not back compat")
946 @property
947 def editorial_review(self):
948 """
949 return self._get_single("editorial_review", default={})
950 """
951 raise RuntimeError("editorial_review is not back compat")
953 @property
954 def archiving_policy(self):
955 """
956 ap = self._get_single("archiving_policy", default={})
957 ret = {"policy" : []}
958 if "url" in ap:
959 ret["url"] = ap["url"]
960 if "known" in ap:
961 ret["policy"] += ap["known"]
962 if "nat_lib" in ap:
963 ret["policy"].append(["A national library", ap["nat_lib"]])
964 if "other" in ap:
965 ret["policy"].append(["Other", ap["other"]])
966 return ret
967 """
968 raise RuntimeError("archiving_policy is not back compat")
970 def remove_identifiers(self, idtype=None, id=None):
971 raise RuntimeError("remove_identifiers is not back compat")
973 def remove_urls(self, urltype=None, url=None):
974 raise RuntimeError("remove_urls is not back compat")