diff --git a/config.py b/config.py
index 4348b16..3de0886 100755
--- a/config.py
+++ b/config.py
@@ -108,4 +108,4 @@
# Testing Bibcode for GET
-EXPORT_SERVICE_TEST_BIBCODE_GET = 'TEST..BIBCODE..GET.'
+EXPORT_SERVICE_TEST_BIBCODE_GET = ['TEST..BIBCODE..GET.']
diff --git a/exportsrv/cslstyles/agu.csl b/exportsrv/cslstyles/agu.csl
new file mode 100644
index 0000000..e9ae3a5
--- /dev/null
+++ b/exportsrv/cslstyles/agu.csl
@@ -0,0 +1,730 @@
+
+
diff --git a/exportsrv/cslstyles/ams.csl b/exportsrv/cslstyles/ams.csl
new file mode 100644
index 0000000..46c1b27
--- /dev/null
+++ b/exportsrv/cslstyles/ams.csl
@@ -0,0 +1,261 @@
+
+
diff --git a/exportsrv/cslstyles/gsa.csl b/exportsrv/cslstyles/gsa.csl
new file mode 100644
index 0000000..df18f21
--- /dev/null
+++ b/exportsrv/cslstyles/gsa.csl
@@ -0,0 +1,202 @@
+
+
diff --git a/exportsrv/formatter/ads.py b/exportsrv/formatter/ads.py
index 4417d19..e669391 100755
--- a/exportsrv/formatter/ads.py
+++ b/exportsrv/formatter/ads.py
@@ -63,7 +63,7 @@ class adsOrganizer:
plain, citation_bibliography, bibliography = range(3)
class adsCSLStyle:
- ads_CLS = ['aastex', 'icarus', 'mnras', 'soph', 'aspc', 'apsj', 'aasj', 'ieee']
+ ads_CLS = ['aastex', 'icarus', 'mnras', 'soph', 'aspc', 'apsj', 'aasj', 'ieee', 'agu', 'gsa', 'ams']
def verify(self, style):
if (style in self.ads_CLS):
diff --git a/exportsrv/formatter/bibTexFormat.py b/exportsrv/formatter/bibTexFormat.py
index 9514714..54b7953 100755
--- a/exportsrv/formatter/bibTexFormat.py
+++ b/exportsrv/formatter/bibTexFormat.py
@@ -196,14 +196,14 @@ def __get_fields(self, a_doc):
return OrderedDict(fields)
- def __get_author_list(self, a_doc, field, maxauthor, authorcutoff):
+ def __get_author_list(self, a_doc, field, max_author, author_cutoff):
"""
format authors/editors
:param a_doc:
:param field: author or editor
- :param maxauthor:
- :param authorcutoff:
+ :param max_author:
+ :param author_cutoff:
:return:
"""
if field not in a_doc:
@@ -211,14 +211,18 @@ def __get_author_list(self, a_doc, field, maxauthor, authorcutoff):
and_str = ' and '
author_list = ''
# if number of authors exceed the maximum that we display, cut to shorter list
- # only if maxauthor is none zero, zero is indication of return all available authors
- cut_authors = (len(a_doc[field]) > authorcutoff) and not maxauthor == 0
+ # only if max_author is none zero, zero is indication of return all available authors
+ cut_authors = (len(a_doc[field]) > author_cutoff) and not max_author == 0
for author, i in zip(a_doc[field], range(len(a_doc[field]))):
- author_parts = encode_laTex_author(author).split(',', 1)
+ # there should be up to only two commas, just in case there is not
+ author_parts = encode_laTex_author(author).split(',', 2)
author_list += '{' + author_parts[0] + '}'
if (len(author_parts) == 2):
author_list += ',' + author_parts[1]
- if cut_authors and i + 1 == maxauthor:
+ # there is suffix, insert it first
+ elif (len(author_parts) == 3):
+ author_list += ',' + author_parts[2] + ',' + author_parts[1]
+ if cut_authors and i + 1 == max_author:
# if reached number of required authors return
return author_list + " and et al."
author_list += and_str
@@ -226,13 +230,13 @@ def __get_author_list(self, a_doc, field, maxauthor, authorcutoff):
return author_list
- def __get_author_lastname_list(self, a_doc, maxauthor):
+ def __get_author_lastname_list(self, a_doc, max_author):
"""
format authors
:param a_doc:
:param field:
- :param maxauthor:
+ :param max_author:
:return:
"""
if 'author' not in a_doc:
@@ -243,12 +247,12 @@ def __get_author_lastname_list(self, a_doc, maxauthor):
author_parts = author.split(',', 1)
author_list += author_parts[0]
author_count += 1
- if author_count == maxauthor:
+ if author_count == max_author:
return author_list
return author_list
- def __get_affiliation_list(self, a_doc, maxauthor, authorcutoff):
+ def __get_affiliation_list(self, a_doc, max_author, author_cutoff):
"""
format affiliation
@@ -257,21 +261,20 @@ def __get_affiliation_list(self, a_doc, maxauthor, authorcutoff):
"""
if 'aff' not in a_doc:
return ''
- counter = self.generate_counter_id(maxauthor if maxauthor != 0 else len(a_doc['aff']))
+ counter = self.generate_counter_id(len(a_doc['aff']))
separator = ', '
affiliation_list = ''
- affiliation_count = 0
# if number of affiliations exceed the maximum that we display, cut to shorter list
- # only if maxauthor is none zero (note number of authors and number of affiliations displayed should match),
+ # only if max_author is none zero (note number of authors and number of affiliations displayed should match),
# zero is indication of return all available affiliations
- cut_affiliations = (len(a_doc['aff']) > authorcutoff) and not maxauthor == 0
+ cut_affiliations = (len(a_doc['aff']) > author_cutoff) and not max_author == 0
addCount = not (a_doc.get('doctype', '') in ['phdthesis', 'mastersthesis'])
for affiliation, i in zip(a_doc['aff'], range(len(a_doc['aff']))):
if (addCount):
affiliation_list += counter[i] + '(' + affiliation + ')' + separator
else:
affiliation_list += affiliation + separator
- if cut_affiliations and i + 1 == maxauthor:
+ if cut_affiliations and i + 1 == max_author:
# if reached number of required affiliations stop
break
# do not need the last separator
@@ -292,13 +295,13 @@ def __add_keywords(self, a_doc):
return encode_laTex(', '.join(a_doc.get('keyword', '')))
- def __get_journal(self, a_doc, journalformat):
+ def __get_journal(self, a_doc, journal_format):
"""
let client decide on the format of journal, macro if one is available, abbreviated journal name, or full journal name
note that for doctype = software this field is ignored
:param a_doc:
- :param journalformat
+ :param journal_format
:return:
"""
doctype = a_doc.get('doctype', '')
@@ -313,12 +316,12 @@ def __get_journal(self, a_doc, journalformat):
return encode_laTex(''.join(a_doc.get('pub', '')))
# use macro (default)
- if journalformat == adsJournalFormat.macro or journalformat == adsJournalFormat.default:
+ if journal_format == adsJournalFormat.macro or journal_format == adsJournalFormat.default:
journal_macros = dict([(k, v) for k, v in current_app.config['EXPORT_SERVICE_AASTEX_JOURNAL_MACRO']])
return journal_macros.get(self.get_bibstem(a_doc.get('bibstem', '')), encode_laTex(''.join(a_doc.get('pub', ''))))
- elif journalformat == adsJournalFormat.abbreviated:
+ elif journal_format == adsJournalFormat.abbreviated:
return encode_laTex(Format(None).get_pub_abbrev(a_doc.get('bibstem', '')))
- elif journalformat == adsJournalFormat.full:
+ elif journal_format == adsJournalFormat.full:
return encode_laTex(''.join(a_doc.get('pub', '')))
@@ -382,12 +385,12 @@ def __add_in_eprint(self, fields, values, output_format):
:param output_format:
:return:
"""
- field = fields.split('|')
- value = values.split(':')
- if len(field) != 2 and len(value) != 2:
+ field_parts = fields.split('|')
+ value_parts = values.split(':')
+ if len(field_parts) != 2 and len(value_parts) != 2:
return ''
result = ''
- for f, v in zip(field, value):
+ for f, v in zip(field_parts, value_parts):
result += self.__add_in(f, v, output_format)
return result
@@ -431,13 +434,11 @@ def __format_key(self, a_doc):
if (field[2] == 'author'):
match = re.search(r'%(\d)H', field[1])
if match:
- maxauthor = int(match.group(1))
+ max_author = int(match.group(1))
else:
- maxauthor = 1
+ max_author = 1
+ authors = self.__get_author_lastname_list(a_doc, max_author)
# need to make sure the key is returned in ascii format
- authors = self.__get_author_lastname_list(a_doc, maxauthor)
- if type(authors) != str:
- authors = authors.decode('utf-8', 'ignore')
key = key.replace(field[1], unidecode(authors))
elif (field[2] == 'year'):
key = key.replace(field[1], a_doc.get('year', ''))
@@ -467,15 +468,15 @@ def __get_key(self, index):
return self.__format_key(self.from_solr['response'].get('docs')[index])
- def __get_doc(self, index, include_abs, maxauthor, authorcutoff, journalformat):
+ def __get_doc(self, index, include_abs, max_author, author_cutoff, journal_format):
"""
for each document from Solr, get the fields, and format them accordingly
:param index:
:param include_abs:
- :param maxauthor:
- :param authorcutoff:
- :param journalformat:
+ :param max_author:
+ :param author_cutoff:
+ :param journal_format:
:return:
"""
format_style_bracket_quotes = u'{0:>13} = "{{{1}}}"'
@@ -489,11 +490,11 @@ def __get_doc(self, index, include_abs, maxauthor, authorcutoff, journalformat):
fields = self.__get_fields(a_doc)
for field in fields:
if (field == 'author') or (field == 'editor'):
- text += self.__add_in(fields[field], self.__get_author_list(a_doc, field, maxauthor, authorcutoff), format_style_bracket)
+ text += self.__add_in(fields[field], self.__get_author_list(a_doc, field, max_author, author_cutoff), format_style_bracket)
elif (field == 'title'):
text += self.__add_in(fields[field], encode_laTex(''.join(a_doc.get(field, ''))), format_style_bracket_quotes)
elif (field == 'aff'):
- text += self.__field_wrapped(fields[field], self.__get_affiliation_list(a_doc, maxauthor, authorcutoff), format_style_bracket)
+ text += self.__field_wrapped(fields[field], self.__get_affiliation_list(a_doc, max_author, author_cutoff), format_style_bracket)
elif (field == 'pub_raw'):
# pub_raw goes to howpublished when doc_type is @misc
# we want to display pub_raw in howpublished only if publisher data is not available
@@ -502,7 +503,7 @@ def __get_doc(self, index, include_abs, maxauthor, authorcutoff, journalformat):
continue
text += self.__add_in(fields[field], self.__add_clean_pub_raw(a_doc), format_style_bracket)
elif (field == 'pub'):
- text += self.__add_in(fields[field], self.__get_journal(a_doc, journalformat), format_style_bracket)
+ text += self.__add_in(fields[field], self.__get_journal(a_doc, journal_format), format_style_bracket)
elif (field == 'doi'):
# 8/5/22 checked couple of sites including https://citation.crosscite.org/ that do not escape doi
# so remove escaping doi, and let the underscore be dealt with on the latex side
@@ -565,13 +566,13 @@ def __enumerate_keys(self):
return self.enumerated_keys
- def get(self, include_abs, maxauthor, authorcutoff, journalformat=adsJournalFormat.macro):
+ def get(self, include_abs, max_author, author_cutoff, journal_format=adsJournalFormat.macro):
"""
:param include_abs: if ture include abstract
- :param maxauthor:
- :param authorcutoff:
- :param journalformat:
+ :param max_author:
+ :param author_cutoff:
+ :param journal_format:
:return: result of formatted records in a dict
"""
num_docs = 0
@@ -581,7 +582,7 @@ def get(self, include_abs, maxauthor, authorcutoff, journalformat=adsJournalForm
if self.enumeration:
self.__enumerate_keys()
for index in range(num_docs):
- ref_BibTex.append(self.__get_doc(index, include_abs, maxauthor, authorcutoff, journalformat))
+ ref_BibTex.append(self.__get_doc(index, include_abs, max_author, author_cutoff, journal_format))
result_dict = {}
result_dict['msg'] = 'Retrieved {} abstracts, starting with number 1.'.format(num_docs)
result_dict['export'] = ''.join(record for record in ref_BibTex)
diff --git a/exportsrv/formatter/csl.py b/exportsrv/formatter/csl.py
index c1280f6..e2e2d5a 100755
--- a/exportsrv/formatter/csl.py
+++ b/exportsrv/formatter/csl.py
@@ -125,6 +125,11 @@ def __update_data(self):
for data in self.for_cls:
data['container-title'] = encode_laTex(data['container-title'])
data['title'] = encode_laTex(data['title'])
+ # remove doi indicator for these styles
+ elif self.csl_style in ['agu', 'gsa', 'ams']:
+ for data in self.for_cls:
+ if len(data.get('DOI', '')) > 0:
+ data['DOI'] = data['DOI'].lstrip('doi:')
def __update_author_etal(self, author, the_rest, bibcode):
@@ -199,12 +204,12 @@ def __format_output(self, cita, biblio, bibcode, index):
:param index:
:return:
"""
- # apsj is a special case, display biblio as csl has format, just adjust translate characters for LaTex
- if (self.csl_style == 'apsj') or (self.csl_style == 'ieee'):
+ # these are text formats and do not need citation specified specifically like the latex formats
+ if self.csl_style in ['apsj', 'ieee', 'agu', 'gsa', 'ams']:
cita_author, cita_year = '', ''
- biblio_author = cita
+ biblio_author = cita if self.csl_style == 'apsj' else ''
biblio_rest = biblio.replace(cita,'')
- # do not need this, but since we are sending the format all the fields, empty bibcode
+ # do not need this, but since we are sending the formats all the fields, empty the bibcode
bibcode = ''
else:
cita_author, cita_year = self.__tokenize_cita(cita)
@@ -231,7 +236,10 @@ def __format_output(self, cita, biblio, bibcode, index):
'aspc': u'\\bibitem[{}({})]{{{}}} {}{}',
'aasj': u'\\bibitem[{}({})]{{{}}} {}{}',
'apsj': u'{}{}{}{}{}',
- 'ieee': u'{}{}{}{}{}'
+ 'ieee': u'{}{}{}{}{}',
+ 'agu': u'{}{}{}{}{}',
+ 'gsa': u'{}{}{}{}{}',
+ 'ams': u'{}{}{}{}{}',
}
return format_style[self.csl_style].format(cita_author, cita_year, bibcode, biblio_author, biblio_rest)
@@ -255,7 +263,7 @@ def get(self, export_organizer=adsOrganizer.plain):
return result_dict
if (export_organizer == adsOrganizer.citation_bibliography):
for cita, item, bibcode in zip(self.citation_item, self.bibliography.bibliography(), self.bibcode_list):
- results.append(bibcode + '\n' + str(self.bibliography.cite(cita, '')) + '\n' + str(item) + '\n')
+ results.append("%s\n%s\n%s\n"%(bibcode, str(self.bibliography.cite(cita, '')), str(item)))
return ''.join(result for result in results)
if (export_organizer == adsOrganizer.bibliography):
for item in self.bibliography.bibliography():
diff --git a/exportsrv/formatter/latexencode.py b/exportsrv/formatter/latexencode.py
index bfbde13..33813f4 100644
--- a/exportsrv/formatter/latexencode.py
+++ b/exportsrv/formatter/latexencode.py
@@ -967,7 +967,7 @@ def utf8tolatex(s, non_ascii_only=False, brackets=True, substitute_bad_chars=Fal
-if __name__ == '__main__':
+if __name__ == '__main__': # pragma: no cover
try:
diff --git a/exportsrv/tests/unittests/stubdata/cslTest.py b/exportsrv/tests/unittests/stubdata/cslTest.py
index 31c8cf9..f347098 100755
--- a/exportsrv/tests/unittests/stubdata/cslTest.py
+++ b/exportsrv/tests/unittests/stubdata/cslTest.py
@@ -15,3 +15,9 @@
data_AASJ= {'msg': 'Retrieved 23 abstracts, starting with number 1.', 'export': u"\\bibitem[No author(2018)]{2018Wthr...73Q..35.} No author\\ 2018, Weather, 73, 35. doi:10.1002/wea.3072.\n\\bibitem[Fal'ko, \\& Thomas(2018)]{2018TDM.....5a0201F} Fal'ko, V., \\& Thomas, C.-W.\\ 2018, 2D Materials, 5, 010201. doi:10.1088/2053-1583/aa9403.\n\\bibitem[Parkin, et al.(2018)]{2018Spin....877001P} Parkin, S., Chantrell, R., \\& Chang, C.-R.\\ 2018, Spin, 8, 1877001. doi:10.1142/S2010324718770015.\n\\bibitem[Dessauges-Zavadsky, \\& Pfenniger(2018)]{2018SAAS...38.....D} Dessauges-Zavadsky, M., \\& Pfenniger, D.\\ 2018, Millimeter Astronomy: Saas-Fee Advanced Course 38. Swiss Society for Astrophysics and Astronomy, Saas-Fee Advanced Course, Volume 38. ISBN 978-3-662-57545-1. Springer-Verlag GmbH Germany, part of Springer Nature, 2018, 38. doi:10.1007/978-3-662-57546-8.\n\\bibitem[Pustilnik, et al.(2018)]{2018PhRvL.120b9901P} Pustilnik, M., van Heck, B., Lutchyn, R.~M., et al.\\ 2018, \\prl, 120, 029901. doi:10.1103/PhysRevLett.120.029901.\n\\bibitem[Carton(2017)]{2017PhDT........14C} Carton, D.\\ 2017, Ph.D. Thesis. doi:10.5281/zenodo.581221.\n\\bibitem[Kohler(2017)]{2017nova.pres.2388K} Kohler, S.\\ 2017, AAS Nova Highlights, 2388.\n\\bibitem[Green(2017)]{2017CBET.4403....2G} Green, D.~W.~E.\\ 2017, Central Bureau Electronic Telegrams, 4403.\n\\bibitem[Casey(2017)]{2017ascl.soft06009C} Casey, A.~R.\\ 2017, Astrophysics Source Code Library. ascl:1706.009.\n\\bibitem[Siltala, et al.(2017)]{2017yCat.113380453S} Siltala, J., Jetsu, L., Hackman, T., et al.\\ 2017, VizieR Online Data Catalog, J/AN/338/453.\n\\bibitem[Waagen(2017)]{2017AAVSN.429....1W} Waagen, E.~O.\\ 2017, AAVSO Special Notice \\#429, 429.\n\\bibitem[Yan(2017)]{2017sptz.prop13168Y} Yan, L.\\ 2017, Spitzer Proposal, 13168.\n\\bibitem[Azankpo(2017)]{2017MsT..........2A} Azankpo, S.\\ 2017, Masters Thesis, 2.\n\\bibitem[Rotaru, et al.(2016)]{2016emo6.rept.....R} Rotaru, A., Pteancu, M., \\& Zaharia, C.\\ 2016, http://www.astronomy.ro/forum/viewtopic.php?p=159287\\#159287 (Comments in Romanian).\n\\bibitem[Velasco(2016)]{2016iac..talk..872V} Velasco, S.\\ 2016, IAC Talks, Astronomy and Astrophysics Seminars from the Instituto de Astrof\\ísica de Canarias.\n\\bibitem[Liu, et al.(2009)]{2009bcet.book...65L} Liu, C.~W., Alekseyev, V.~Y., Allwardt, J.~R., et al.\\ 2009, Biophysics and the Challenges of Emerging Threats, 65. doi:10.1007/978-90-481-2368-1\\_5.\n\\bibitem[Mahabal, et al.(2007)]{2007AAS...210.2104M} Mahabal, A.~A., Drake, A.~J., Djorgovski, S.~G., et al.\\ 2007, \\aas.\n\\bibitem[., \\& .(2007)]{2007RJPh....1...35.} ., S.~N.~A., \\& ., E.~C.~O.\\ 2007, Research Journal of Physics, 1, 35. doi:10.3923/rjp.2007.35.41.\n\\bibitem[Miller(1995)]{1995ans..agar..390M} Miller, J.~L.\\ 1995, In AGARD, 390.\n\\bibitem[Nayfeh, \\& Balachandran(1995)]{1995anda.book.....N} Nayfeh, A.~H., \\& Balachandran, B.\\ 1995, Wiley series in nonlinear science, New York; Chichester: Wiley, |c1995.\n\\bibitem[Ginsparg(1988)]{1991hep.th....8028G} Ginsparg, P.\\ 1988, arXiv e-prints, hep-th/9108028.\n\\bibitem[Khatib, et al.(1983)]{1983aiaa.meetY....K} Khatib, A.~R., Ellis, J., French, J., et al.\\ 1983, AIAA, Aerospace Sciences Meeting.\n\\bibitem[Thornton, et al.(2012)]{2012ddsw.rept.....T} Thornton, P.~E., Thornton, M.~M., Mayer, B.~W., et al.\\ 2012, Oak Ridge National Laboratory (ORNL) Distributed Active Archive Center for Biogeochemical Dynamics (DAAC.\n"}
data_ieee= {'msg': 'Retrieved 23 abstracts, starting with number 1.', 'export': u"[1]No author, \u201cBook reviews\u201d, Weather, vol. 73, no. 1, pp. 35\u201335, 2018. doi:10.1002/wea.3072.\n[2]Fal'ko, V. and Thomas, C.-W., \u201c2D Materials: maintaining editorial quality\u201d, 2D Materials, vol. 5, no. 1, Art. no. 010201, 2018. doi:10.1088/2053-1583/aa9403.\n[3]Parkin, S., Chantrell, R., and Chang, C.-R., \u201cObituary: In Memoriam Professor Dr. Shoucheng Zhang, Consulting Editor\u201d, Spin, vol. 8, no. 4, Art. no. 1877001, 2018. doi:10.1142/S2010324718770015.\n[4]Dessauges-Zavadsky, M. and Pfenniger, D., \u201cMillimeter Astronomy\u201d, SAAS...38, 2018. doi:10.1007/978-3-662-57546-8.\n[5]Pustilnik, M., van Heck, B., Lutchyn, R. M., and Glazman, L. I., \u201cErratum: Quantum Criticality in Resonant Andreev Conduction [Phys. Rev. Lett. 119, 116802 (2017)]\u201d, Physical Review Letters, vol. 120, no. 2, Art. no. 029901, 2018. doi:10.1103/PhysRevLett.120.029901.\n[6]Carton, D., \u201cResolving Gas-Phase Metallicity In Galaxies\u201d, PhDT, 2017. doi:10.5281/zenodo.581221.\n[7]Kohler, S., \u201cA 3D View of a Supernova Remnant\u201d, AAS Nova Highlights, Art. no. 2388, 2017.\n[8]Green, D. W. E., \u201cPotential New Meteor Shower from Comet C/2015 D4 (Borisov)\u201d, CBET.4403, 2017.\n[9]Casey, A. R., \u201csick: Spectroscopic inference crank\u201d, Astrophysics Source Code Library, Art. no. ascl:1706.009, 2017. ascl:1706.009.\n[10]Siltala, J., \u201cVizieR Online Data Catalog: BM CVn V-band differential light curve (Siltala+, 2017)\u201d, VizieR Online Data Catalog, Art. no. J/AN/338/453, 2017.\n[11]Waagen, E. O., \u201cV694 Mon (MWC 560) spectroscopy requested\u201d, AAVSN.429, 2017.\n[12]Yan, L., \u201cConfirm the Nature of a TDE Candidate in ULIRG F01004-2237 Using Spitzer mid-IR Light Curves\u201d, Spitzer Proposal, p. 13168, 2017.\n[13]Azankpo, S., \u201cSurface Accuracy and Pointing Error Prediction of a 32 m Diameter Class Radio Astronomy Telescope\u201d, MsT, 2017.\n[14]Rotaru, A., Pteancu, M., and Zaharia, C., \u201cThe penumbral Moon's eclipse form 16 september 2016\u201d, emo6.rept, 2016.\n[15]Velasco, S., \u201cLiving on the edge: Adaptive Optics+Lucky Imaging\u201d, IAC Talks, Astronomy and Astrophysics Seminars from the Instituto de Astrofísica de Canarias, p. 872, 2016.\n[16]Liu, C. W., \u201cThe Diversity of Nuclear Magnetic Resonance Spectroscopy\u201d, in Biophysics and the Challenges of Emerging Threats, 2009, p. 65. doi:10.1007/978-90-481-2368-1_5.\n[17]Mahabal, A. A., \u201cTime Domain Exploration with the Palomar-QUEST Sky Survey\u201d, vol. 210, Art. no. 21.04, 2007.\n[18]., S. N. A. and ., E. C. O., \u201cAnalysis of Thermal Losses in the Flat-Plate Collector of a Thermosyphon Solar Water Heater\u201d, Research Journal of Physics, vol. 1, no. 1, pp. 35\u201341, 2007. doi:10.3923/rjp.2007.35.41.\n[19]Miller, J. L., \u201cSpacecraft navigation requirements\u201d, in In AGARD, 1995, pp. 390\u2013405.\n[20]Nayfeh, A. H. and Balachandran, B., Applied nonlinear dynamics: analytical, computational and experimental methods. 1995.\n[21]Ginsparg, P., \u201cApplied Conformal Field Theory\u201d, arXiv e-prints, Art. no. hep-th/9108028, 1988.\n[22]Khatib, A. R., Ellis, J., French, J., Null, G., Yunck, T., and Wu, S., \u201cAutonomous navigation using lunar beacons\u201d, in AIAA, Aerospace Sciences Meeting, 1983.\n[23]Thornton, P. E., “Daymet: Daily surface weather on a 1 km grid for North America, 1980-2008”, Oak Ridge National Laboratory (ORNL) Distributed Active Archive Center for Biogeochemical Dynamics (DAAC, 2012.\n"}
+
+data_agu= {'msg': 'Retrieved 23 abstracts, starting with number 1.', 'export': "No author (2018) Book reviews Weather, 73(1), 35–35. https://doi.org/10.1002/wea.3072\nFal'ko, V., & Thomas, C.-W. (2018) 2D Materials: maintaining editorial quality 2D Materials, 5(1), 010201. https://doi.org/10.1088/2053-1583/aa9403\nParkin, S., Chantrell, R., & Chang, C.-R. (2018) Obituary: In Memoriam Professor Dr. Shoucheng Zhang, Consulting Editor Spin, 8(4), 1877001. https://doi.org/10.1142/S2010324718770015\nDessauges-Zavadsky, M., & Pfenniger, D. (2018) Millimeter Astronomy (SAAS...38) Millimeter Astronomy: Saas-Fee Advanced Course 38. Swiss Society for Astrophysics and Astronomy, Saas-Fee Advanced Course, Volume 38. ISBN 978-3-662-57545-1. Springer-Verlag GmbH Germany, part of Springer Nature, 2018 (Vol. 38). https://doi.org/10.1007/978-3-662-57546-8\nPustilnik, M., van Heck, B., Lutchyn, R. M., & Glazman, L. I. (2018) Erratum: Quantum Criticality in Resonant Andreev Conduction [Phys. Rev. Lett. 119, 116802 (2017)] Physical Review Letters, 120(2), 029901. https://doi.org/10.1103/PhysRevLett.120.029901\nCarton, D. (2017) Resolving Gas-Phase Metallicity In Galaxies (PhDT) Ph.D. Thesis. https://doi.org/10.5281/zenodo.581221\nKohler, S. (2017) A 3D View of a Supernova Remnant AAS Nova Highlights (2388).\nGreen, D. W. E. (2017) Potential New Meteor Shower from Comet C/2015 D4 (Borisov) (CBET.4403) Central Bureau Electronic Telegrams (Vol. 4403, p. 2).\nCasey, A. R. (2017) sick: Spectroscopic inference crank Astrophysics Source Code Library. ascl:1706.009\nSiltala, J., Jetsu, L., Hackman, T., Henry, G. W., Immonen, L., Kajatkari, P., et al. (2017) VizieR Online Data Catalog: BM CVn V-band differential light curve (Siltala+, 2017) VizieR Online Data Catalog (J/AN/338/453).\nWaagen, E. O. (2017) V694 Mon (MWC 560) spectroscopy requested (AAVSN.429) AAVSO Special Notice #429 (Vol. 429, p. 1).\nYan, L. (2017) Confirm the Nature of a TDE Candidate in ULIRG F01004-2237 Using Spitzer mid-IR Light Curves Spitzer Proposal, 13168.\nAzankpo, S. (2017) Surface Accuracy and Pointing Error Prediction of a 32 m Diameter Class Radio Astronomy Telescope (MsT) Masters Thesis.\nRotaru, A., Pteancu, M., & Zaharia, C. (2016) The penumbral Moon's eclipse form 16 september 2016 (emo6.rept) http://www.astronomy.ro/forum/viewtopic.php?p=159287#159287 (Comments in Romanian).\nVelasco, S. (2016) Living on the edge: Adaptive Optics+Lucky Imaging IAC Talks, Astronomy and Astrophysics Seminars from the Instituto de Astrofísica de Canarias, p. 872.\nLiu, C. W., Alekseyev, V. Y., Allwardt, J. R., Bankovich, A. J., Cade-Menun, B. J., Davis, R. W., et al. (2009) The Diversity of Nuclear Magnetic Resonance Spectroscopy In Biophysics and the Challenges of Emerging Threats (p. 65). https://doi.org/10.1007/978-90-481-2368-1_5\nMahabal, A. A., Drake, A. J., Djorgovski, S. G., Donalek, C., Glikman, E., Graham, M. J., et al. (2007) Time Domain Exploration with the Palomar-QUEST Sky Survey American Astronomical Society Meeting Abstracts #210, 210, 21.04.\n., S. N. A., & ., E. C. O. (2007) Analysis of Thermal Losses in the Flat-Plate Collector of a Thermosyphon Solar Water Heater Research Journal of Physics, 1(1), 35–41. https://doi.org/10.3923/rjp.2007.35.41\nMiller, J. L. (1995) Spacecraft navigation requirements In In AGARD (pp. 390–405).\nNayfeh, A. H., & Balachandran, B. (1995) Applied nonlinear dynamics: analytical, computational and experimental methods Wiley series in nonlinear science, New York; Chichester: Wiley, |c1995.\nGinsparg, P. (1988) Applied Conformal Field Theory arXiv e-prints (hep-th/9108028).\nKhatib, A. R., Ellis, J., French, J., Null, G., Yunck, T., & Wu, S. (1983) Autonomous navigation using lunar beacons In AIAA, Aerospace Sciences Meeting.\nThornton, P. E., Thornton, M. M., Mayer, B. W., Wilhelmi, N., Wei, Y., Devarakonda, R., & Cook, R. (2012) Daymet: Daily surface weather on a 1 km grid for North America, 1980-2008 Oak Ridge National Laboratory (ORNL) Distributed Active Archive Center for Biogeochemical Dynamics (DAAC.\n"}
+
+data_gsa= {'msg': 'Retrieved 23 abstracts, starting with number 1.', 'export': "No author, 2018, Book reviews: Weather, v. 73, p. 35–35, doi:10.1002/wea.3072.\nFal'ko, V., and Thomas, C.-W., 2018, 2D Materials: maintaining editorial quality: 2D Materials, v. 5, 010201, doi:10.1088/2053-1583/aa9403.\nParkin, S., Chantrell, R., and Chang, C.-R., 2018, Obituary: In Memoriam Professor Dr. Shoucheng Zhang, Consulting Editor: Spin, v. 8, 1877001, doi:10.1142/S2010324718770015.\nDessauges-Zavadsky, M., and Pfenniger, D., 2018, Millimeter Astronomy: SAAS...38, doi:10.1007/978-3-662-57546-8.\nPustilnik, M., van Heck, B., Lutchyn, R.M., and Glazman, L.I., 2018, Erratum: Quantum Criticality in Resonant Andreev Conduction [Phys. Rev. Lett. 119, 116802 (2017)]: Physical Review Letters, v. 120, 029901, doi:10.1103/PhysRevLett.120.029901.\nCarton, D., 2017, Resolving Gas-Phase Metallicity In Galaxies [PhDT], doi:10.5281/zenodo.581221.\nKohler, S., 2017, A 3D View of a Supernova Remnant: AAS Nova Highlights, 2388.\nGreen, D.W.E., 2017, Potential New Meteor Shower from Comet C/2015 D4 (Borisov): CBET.4403, 2 p.\nCasey, A.R., 2017, sick: Spectroscopic inference crank: Astrophysics Source Code Library, ascl:1706.009, ascl:1706.009.\nSiltala, J. et al., 2017, VizieR Online Data Catalog: BM CVn V-band differential light curve (Siltala+, 2017): VizieR Online Data Catalog, J/AN/338/453.\nWaagen, E.O., 2017, V694 Mon (MWC 560) spectroscopy requested: AAVSN.429, 1 p.\nYan, L., 2017, Confirm the Nature of a TDE Candidate in ULIRG F01004-2237 Using Spitzer mid-IR Light Curves: Spitzer Proposal, p. 13168.\nAzankpo, S., 2017, Surface Accuracy and Pointing Error Prediction of a 32 m Diameter Class Radio Astronomy Telescope [MsT].\nRotaru, A., Pteancu, M., and Zaharia, C., 2016, The penumbral Moon's eclipse form 16 september 2016: emo6.rept.\nVelasco, S., 2016, Living on the edge: Adaptive Optics+Lucky Imaging: IAC Talks, Astronomy and Astrophysics Seminars from the Instituto de Astrofísica de Canarias, p. 872.\nLiu, C.W. et al., 2009, The Diversity of Nuclear Magnetic Resonance Spectroscopy, in Biophysics and the Challenges of Emerging Threats, doi:10.1007/978-90-481-2368-1_5.\nMahabal, A.A. et al., 2007, Time Domain Exploration with the Palomar-QUEST Sky Survey: American Astronomical Society Meeting Abstracts #210, v. 210, 21.04.\n., S.N.A., and ., E.C.O., 2007, Analysis of Thermal Losses in the Flat-Plate Collector of a Thermosyphon Solar Water Heater: Research Journal of Physics, v. 1, p. 35–41, doi:10.3923/rjp.2007.35.41.\nMiller, J.L., 1995, Spacecraft navigation requirements, in In AGARD.\nNayfeh, A.H., and Balachandran, B., 1995, Applied nonlinear dynamics: analytical, computational and experimental methods.\nGinsparg, P., 1988, Applied Conformal Field Theory: arXiv e-prints, hep-th/9108028.\nKhatib, A.R., Ellis, J., French, J., Null, G., Yunck, T., and Wu, S., 1983, Autonomous navigation using lunar beacons, in AIAA, Aerospace Sciences Meeting.\nThornton, P.E., Thornton, M.M., Mayer, B.W., Wilhelmi, N., Wei, Y., Devarakonda, R., and Cook, R., 2012, Daymet: Daily surface weather on a 1 km grid for North America, 1980-2008: Oak Ridge National Laboratory (ORNL) Distributed Active Archive Center for Biogeochemical Dynamics (DAAC,.\n"}
+
+data_ams= {'msg': 'Retrieved 23 abstracts, starting with number 1.', 'export': "No author, 2018: Book reviews 73, 35–35, https://doi.org/10.1002/wea.3072.\nFal'ko, V., and C.-W. Thomas, 2018: 2D Materials: maintaining editorial quality 5, 010201, https://doi.org/10.1088/2053-1583/aa9403.\nParkin, S., R. Chantrell, and C.-R. Chang, 2018: Obituary: In Memoriam Professor Dr. Shoucheng Zhang, Consulting Editor 8, 1877001, https://doi.org/10.1142/S2010324718770015.\nDessauges-Zavadsky, M., and D. Pfenniger, 2018: Millimeter Astronomy 38, https://doi.org/10.1007/978-3-662-57546-8.\nPustilnik, M., B. van Heck, R. M. Lutchyn, and L. I. Glazman, 2018: Erratum: Quantum Criticality in Resonant Andreev Conduction [Phys. Rev. Lett. 119, 116802 (2017)] 120, 029901, https://doi.org/10.1103/PhysRevLett.120.029901.\nCarton, D., 2017: Resolving Gas-Phase Metallicity In Galaxies https://doi.org/10.5281/zenodo.581221.\nKohler, S., 2017: A 3D View of a Supernova Remnant 2388.\nGreen, D. W. E., 2017: Potential New Meteor Shower from Comet C/2015 D4 (Borisov) 4403, 2.\nCasey, A. R., 2017: sick: Spectroscopic inference crank ascl:1706.009, ascl:1706.009.\nSiltala, J., 2017: VizieR Online Data Catalog: BM CVn V-band differential light curve (Siltala+, 2017) J/AN/338/453.\nWaagen, E. O., 2017: V694 Mon (MWC 560) spectroscopy requested 429, 1.\nYan, L., 2017: Confirm the Nature of a TDE Candidate in ULIRG F01004-2237 Using Spitzer mid-IR Light Curves 13168.\nAzankpo, S., 2017: Surface Accuracy and Pointing Error Prediction of a 32 m Diameter Class Radio Astronomy Telescope 2.\nRotaru, A., M. Pteancu, and C. Zaharia, 2016: The penumbral Moon's eclipse form 16 september 2016.\nVelasco, S., 2016: Living on the edge: Adaptive Optics+Lucky Imaging 872.\nLiu, C. W., 2009: The Diversity of Nuclear Magnetic Resonance Spectroscopy. Biophysics and the Challenges of Emerging Threats, p. 65, https://doi.org/10.1007/978-90-481-2368-1_5.\nMahabal, A. A., 2007: Time Domain Exploration with the Palomar-QUEST Sky Survey 210, 21.04.\n., S. N. A., and E. C. O. ., 2007: Analysis of Thermal Losses in the Flat-Plate Collector of a Thermosyphon Solar Water Heater 1, 35–41, https://doi.org/10.3923/rjp.2007.35.41.\nMiller, J. L., 1995: Spacecraft navigation requirements. In AGARD, 390–405.\nNayfeh, A. H., and B. Balachandran, 1995: Applied nonlinear dynamics: analytical, computational and experimental methods.\nGinsparg, P., 1988: Applied Conformal Field Theory hep-th/9108028.\nKhatib, A. R., J. Ellis, J. French, G. Null, T. Yunck, and S. Wu, 1983: Autonomous navigation using lunar beacons. AIAA, Aerospace Sciences Meeting.\nThornton, P. E., M. M. Thornton, B. W. Mayer, N. Wilhelmi, Y. Wei, R. Devarakonda, and R. Cook, 2012: Daymet: Daily surface weather on a 1 km grid for North America, 1980-2008.\n"}
diff --git a/exportsrv/tests/unittests/stubdata/solrdata.py b/exportsrv/tests/unittests/stubdata/solrdata.py
index 6be71ef..e7d389c 100644
--- a/exportsrv/tests/unittests/stubdata/solrdata.py
+++ b/exportsrv/tests/unittests/stubdata/solrdata.py
@@ -1417,9 +1417,9 @@
}
},
u'response': {
- 'numFound': 3,
- 'start': 0,
- 'docs': [
+ u'numFound': 3,
+ u'start': 0,
+ u'docs': [
{
u'bibcode': u'2019Sci...365..565B',
u'comment': [u'Galaxies B and C from figures 2 are not in SIMBAD.'],
@@ -1435,7 +1435,6 @@
}
}
-
data_16 = \
{
u'responseHeader':{
@@ -1658,4 +1657,272 @@
}
]
}
+}
+
+data_18 = \
+{
+ u'responseHeader': {
+ u'status': 0,
+ u'QTime': 141,
+ u'params': {
+ u'q': u'bibcode:(2001physics...2042S OR 2017isra.book.....T OR 1990ApJ...355..726W OR 1978Navig..25..121S OR 2013Ecogr..36.1058M OR 2009AGUFMPP31D1382A OR 1992ApJ...392..310W OR 1971ApJ...164..399S)',
+ u'fl': u'bibcode,author',
+ u'_': u'1731959426353'
+ }
+ },
+ u'response':{
+ u'numFound':8,
+ u'start':0,
+ u'docs':[
+ {
+ u'bibcode': u'2001physics...2042S',
+ u'author':[u'Smith, Frank D., Jr']},
+ {
+ u'bibcode': u'2017isra.book.....T',
+ u'author':[u'Thompson, A. Richard', u'Moran, James M.', u'Swenson, George W., Jr.']},
+ {
+ u'bibcode': u'1990ApJ...355..726W',
+ u'author':[u'Wang, Y. -M.', u'Sheeley, N. R., Jr.']},
+ {
+ u'bibcode': u'1978Navig..25..121S',
+ u'author':[u'Spilker, J. J., Jr.']},
+ {
+ u'bibcode': u'2009AGUFMPP31D1382A',
+ u'author':[u'Anderson, D. G.', u'Goodyear, A. C.', u'Stafford, T. W., Jr.', u'Kennett, J.', u'West, A.']},
+ {
+ u'bibcode': u'1992ApJ...392..310W',
+ u'author':[u'Wang, Y. -M.', u'Sheeley, N. R., Jr.']},
+ {
+ u'bibcode': u'1971ApJ...164..399S',
+ u'author':[u'Spitzer, Lyman, Jr.', u'Hart, Michael H.']},
+ {
+ u'bibcode': u'2013Ecogr..36.1058M',
+ u'author':[u'Merow, Cory', u'Smith, Matthew J.', u'Silander, John A., Jr.']}
+ ]
+ }
+}
+
+data_19 = \
+{
+ u'responseHeader': {
+ u'status': 0,
+ u'QTime': 42,
+ u'params': {
+ 'q':'author:\'shapurian,g\'',
+ u'fl': u'bibcode,author,pub_raw,year',
+ u'_': u'1732120045561'
+ }
+ },
+ u'response':{
+ u'numFound':3,
+ u'start':0,
+ u'docs':[
+ {
+ u'bibcode': u'2023arXiv231208579S',
+ u'author':[u'Shapurian, Golnaz', u'Kurtz, Michael J', u'Accomazzi, Alberto'],
+ u'pub_raw': u'eprint arXiv:2312.08579',
+ u'year': u'2023'},
+ {
+ u'bibcode': u'2024arXiv240611400S',
+ u'author':[u'Shapurian, Golnaz'],
+ u'pub_raw': u'eprint arXiv:2406.11400',
+ u'year': u'2024'},
+ {
+ u'bibcode': u'2023AAS...24117714K',
+ u'author':[u'Koch, Jennifer', u'Shapurian, Golnaz', u'Grant, Carolyn', u'Thompson, Donna', u'ADS Team'],
+ u'pub_raw': u'American Astronomical Society Meeting #241, id. 177.14. Bulletin of the American Astronomical Society, Vol. 55, No. 2 e-id 2023n2i177p14',
+ u'year': u'2023'}
+ ]
+ }
+}
+
+data_20 = \
+{
+ u'responseHeader': {
+ u'status': 0,
+ u'QTime': 163,
+ u'params': {
+ 'q':'author:\'^André\'',
+ u'fl': u'bibcode,author,pub_raw,year',
+ u'_': u'1732120045561'
+ }
+ },
+ u'response':{
+ u'numFound':1,
+ u'start':0,
+ u'docs':[
+ {
+ u'bibcode': u'2014prpl.conf...27A',
+ u'author': [u'André, P.', u'Di Francesco, J.', u'Ward-Thompson, D.', u'Inutsuka, S. -I.', u'Pudritz, R. E.', u'Pineda, J. E.'],
+ u'pub_raw': u'Protostars and Planets VI, Henrik Beuther, Ralf S. Klessen, Cornelis P. Dullemond, and Thomas Henning (eds.), University of Arizona Press, Tucson, p.27-51',
+ u'year': u'2014'}
+ ]
+ }
+}
+
+data_21 = \
+{
+ u'responseHeader': {
+ u'status': 0,
+ u'QTime': 51,
+ u'params': {
+ u'q': u'author:"^accomazzi" year:2019',
+ u'indent': u'on',
+ u'fl': u'bibcode,author,pub,year',
+ u'wt': u'json',
+ u'_': u'1560183872951'
+ }
+ },
+ u'response': {
+ u'numFound': 3,
+ u'start': 0,
+ u'docs': [
+ {
+ u'year': u'2019',
+ u'bibcode': u'2019AAS...23338108A',
+ u'bibstem': [u'AAS', u'AAS...233'],
+ u'author': [u'Accomazzi, Alberto', u'Kurtz, Michael J.', u'Henneken, Edwin', u'Grant, Carolyn S.',
+ u'Thompson, Donna M.', u'Chyla, Roman', u'McDonald, Stephen',
+ u'Blanco-Cuaresma, Sergi', u'Shapurian, Golnaz', u'Hostetler, Timothy',
+ u'Templeton, Matthew', u'Lockhart, Kelly'],
+ u'pub': u'American Astronomical Society Meeting Abstracts #233'
+ },
+ {
+ u'year': u'2019',
+ u'bibcode': u'2019AAS...23320704A',
+ u'bibstem': [u'AAS', u'AAS...233'],
+ u'author': [u'Accomazzi, Alberto'],
+ u'pub': u'American Astronomical Society Meeting Abstracts #233'
+ },
+ {
+ u'year': u'2019',
+ u'bibcode': u'2019hsax.conf..526G',
+ u'author': [u'Garzón, F.', u'Patrick, L.', u'Hammersley, P.', u'Streblyanska, A.',
+ u'Insausti, M.', u'Barreto, M.', u'Fernández, P.', u'Joven, E.',
+ u'López, P.', u'Mato, A.', u'Moreno, H.', u'Núñez, M.', u'Patrón, J.',
+ u'Pascual, S.', u'Cardiel, N.'],
+ u'pub': u'Highlights on Spanish Astrophysics X',
+ u'bibstem': [u'hsax', u'hsax.conf']
+ }
+ ]
+ }
+}
+
+data_22 = \
+{
+ u'responseHeader': {
+ u'status': 0,
+ u'QTime': 29,
+ u'params': {
+ u'q': u'author:"accomazzi" AND doctype:eprint AND year:2021',
+ u'fl': u'bibcode,eid,eprint',
+ u'sort': u'bibcode desc',
+ u'rows': u'300',
+ u'_': u'1642527401469'
+ }
+ },
+ u'response': {
+ u'numFound': 2,
+ u'start': 0,
+ u'docs': [
+ {
+ u'bibcode': u'2021arXiv211200590G',
+ u'eid': u'arXiv:2112.00590'
+ },
+ {
+ u'bibcode': u'2021arXiv210601477C',
+ u'eid': u'arXiv:2106.01477'
+ }
+ ]
+ }
+}
+
+data_23 = \
+{
+ u'responseHeader': {
+ u'status': 0,
+ u'QTime': 1,
+ u'params': {
+ u'sort': u'date desc',
+ u'fq': u'{!bitset}',
+ u'rows': u'19',
+ u'q': u'*:*',
+ u'start': u'0',
+ u'wt': u'json',
+ u'fl': u'author,title,year,date,pub,pub_raw,issue,volume,page,page_range,aff,doi,abstract,num_citations,read_count,bibcode,identification,copyright,keyword,doctype,num_references,comment,property,esources,data'
+ }
+ },
+ u'response': {
+ u'start': 0,
+ u'numFound': 4,
+ u'docs': [
+ {
+ u'title': [u'A Microwave Free-Space Method Using Artificial Lens with Anti-reflection Layer'],
+ u'author': [ u'Zhang, Yangjun', u'Aratani, Yuki', u'Nakazima, Hironari' ]
+ },
+ {
+ u'author': [u'Ryan, R. E.', u'McCullough, P. R.']
+ },
+ {
+ u'title': [ u'Resolving Gas-Phase Metallicity In Galaxies']
+ },
+ {
+ u'bibcode': u'2017ascl.soft06009C'
+ }
+ ]
+ }
+}
+
+data_24 = \
+{
+ u'responseHeader': {
+ u'status': 0,
+ u'QTime': 2,
+ u'params': {
+ u'q': u'title:"lt;"',
+ u'indent': u'on',
+ u'fl': u'bibcode,title,abstract',
+ u'wt': u'json',
+ u'_': u'1592510843440'
+ }
+ },
+ u'response': {
+ u'numFound': 4,
+ u'start': 0,
+ u'docs': [
+ {
+ u'bibcode': u'2016JLwT...34.4926L',
+ u'title': [u'Study of SiO{}_{{{x}}} (1 < x lt; 2) Thin-Film Optical Waveguides']
+ },
+ {
+ u'bibcode': u'2016ApJ...832..124B',
+ u'abstract': u'Using Hubble Space Telescope Cosmic Origins Spectrograph observations of 89 QSO sightlines through the Sloan Digital Sky Survey footprint, we study the relationships between C IV absorption systems and the properties of nearby galaxies, as well as the large-scale environment. To maintain sensitivity to very faint galaxies, we restrict our sample to 0.0015< z< 0.015, which defines a complete galaxy survey to L≳ 0.01 L\\ast or stellar mass {M}* ≳ {10}8 {M}☉ . We report two principal findings. First, for galaxies with impact parameter ρ < 1 {r}{vir}, C IV detection strongly depends on the luminosity/stellar mass of the nearby galaxy. C IV is preferentially associated with galaxies with {M}* > {10}9.5 {M}☉ ; lower-mass galaxies rarely exhibit significant C IV absorption (covering fraction {f}C={9}-6+12 % for 11 galaxies with {M}* < {10}9.5 {M}☉ ). Second, C IV detection within the {M}* > {10}9.5 {M}☉ population depends on environment. Using a fixed-aperture environmental density metric for galaxies with ρ < 160 kpc at z< 0.055, we find that {57}-13+12 % (8/14) of galaxies in low-density regions (regions with fewer than seven L> 0.15 L\\ast galaxies within 1.5 Mpc) have affiliated C IV absorption; however, none (0/7) of the galaxies in denser regions show C IV. Similarly, the C IV detection rate is lower for galaxies residing in groups with dark matter halo masses of {M}{halo}> {10}12.5 {M}☉ . In contrast to C IV, H I is pervasive in the circumgalactic medium without regard to mass or environment. These results indicate that C IV absorbers with {log} N({{C}} {{IV}})≳ 13.5 {{cm}}-2 trace the halos of {M}* > {10}9.5 {M}☉ galaxies but also reflect larger-scale environmental conditions.'
+ },
+ {
+ u'bibcode': u'2015hst..prop14424B',
+ u'title': [u'STIS CCD Amp A, C, & D Gains']
+ },
+ {
+ u'bibcode': u'2016BaltA..25..310K',
+ u'abstract': u'We use the Apparent Motion Parameters (AMP) method for the determination of orbits of visual double stars (Kiselev & Kiyaeva 1980). The quality of AMP orbits is completely dependent on the precision of parameters of relative positions and motions at the same instant. They are calculated on the basis of a short arc of observations. To determine these parameters, we use recent high precision observations obtained with the best modern techniques. New orbits of three stars are presented.'
+ }
+ ]
+ }
+}
+
+data_25 = \
+{
+ u'responseHeader': {
+ u'status': 1,
+ u'QTime': 1,
+ u'params': {
+ u'sort': u'date desc',
+ u'fq': u'{!bitset}',
+ u'rows': u'19',
+ u'q': u'*:*',
+ u'start': u'0',
+ u'wt': u'json',
+ u'fl': u'author,title,year,date,pub,pub_raw,issue,volume,page,page_range,aff,doi,abstract,num_citations,read_count,bibcode,identification,copyright,keyword,doctype,num_references,comment,property,esources,data'
+ }
+ }
}
\ No newline at end of file
diff --git a/exportsrv/tests/unittests/test_export_service.py b/exportsrv/tests/unittests/test_export_service.py
index 058754b..b42fe27 100755
--- a/exportsrv/tests/unittests/test_export_service.py
+++ b/exportsrv/tests/unittests/test_export_service.py
@@ -13,7 +13,7 @@
import exportsrv.views as views
from exportsrv.tests.unittests.stubdata import solrdata, bibTexTest, fieldedTest, xmlTest, cslTest, customTest, voTableTest, rssTest
-from exportsrv.formatter.ads import adsCSLStyle, adsJournalFormat
+from exportsrv.formatter.ads import adsCSLStyle, adsJournalFormat, adsOrganizer
from exportsrv.formatter.format import Format
from exportsrv.formatter.bibTexFormat import BibTexFormat
from exportsrv.formatter.fieldedFormat import FieldedFormat
@@ -24,151 +24,253 @@
from exportsrv.formatter.voTableFormat import VOTableFormat
from exportsrv.formatter.rssFormat import RSSFormat
from exportsrv.formatter.toLaTex import encode_laTex
+from exportsrv.formatter.latexencode import utf8tolatex
from exportsrv.utils import get_eprint, replace_html_entity
+from exportsrv.views import get_export_format_for_journal_style
class TestExports(TestCase):
+
def create_app(self):
- app_ = app.create_app()
- return app_
+ """ create app """
+
+ self.current_app = app.create_app()
+ return self.current_app
+
def setUp(self):
""" executed before each test """
+
# prevent display of the following warning from citeproc
# /Users/gshapurian/code/export_service/python/lib/python3.8/site-packages/citeproc/source/__init__.py:31: UserWarning: The following arguments for Reference are unsupported: bibstem
# warn('The following arguments for {} are '.format(cls_name) +
warnings.filterwarnings(action='ignore', category=UserWarning, module='citeproc')
+
def tearDown(self):
""" executed after each test """
+
pass
+
def test_bibtex(self):
+ """ test Bibtex format """
+
# format the stubdata using the code
- bibtex_export = BibTexFormat(solrdata.data, "%R").get(include_abs=False, maxauthor=10, authorcutoff=200, journalformat=1)
+ bibtex_export = BibTexFormat(solrdata.data, "%R").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=1)
# now compare it with an already formatted data that we know is correct
assert (bibtex_export == bibTexTest.data)
+
def test_bibtex_with_abs(self):
+ """ test BibTex with abstract format """
+
# format the stubdata using the code
- bibtex_export = BibTexFormat(solrdata.data, "%R").get(include_abs=True, maxauthor=0, authorcutoff=200, journalformat=1)
+ bibtex_export = BibTexFormat(solrdata.data, "%R").get(include_abs=True, max_author=0, author_cutoff=200, journal_format=1)
# now compare it with an already formatted data that we know is correct
assert (bibtex_export == bibTexTest.data_with_abs)
+
def test_ads(self):
+ """ test fielded format ADS """
+
# format the stubdata using the code
fielded_export = FieldedFormat(solrdata.data).get_ads_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_ads)
+
def test_endnote(self):
+ """ test fielded format endnote """
+
# format the stubdata using the code
fielded_export = FieldedFormat(solrdata.data).get_endnote_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_endnote)
+
def test_procite(self):
+ """ test fielded format procite """
+
# format the stubdata using the code
fielded_export = FieldedFormat(solrdata.data).get_procite_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_procite)
+
def test_refman(self):
+ """ test fielded format refman """
+
# format the stubdata using the code
fielded_export = FieldedFormat(solrdata.data).get_refman_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_refman)
+
def test_refworks(self):
+ """ test fielded format refworks """
+
# format the stubdata using the code
fielded_export = FieldedFormat(solrdata.data).get_refworks_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_refworks)
+
def test_medlars(self):
+ """ test fielded format medlars """
+
# format the stubdata using the code
fielded_export = FieldedFormat(solrdata.data).get_medlars_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_medlars)
+
def test_dublinxml(self):
+ """ test xml format Dublin """
+
# format the stubdata using the code
xml_export = XMLFormat(solrdata.data).get_dublincore_xml()
# now compare it with an already formatted data that we know is correct
assert(xml_export == xmlTest.data_dublin_core)
+
def test_refxml(self):
+ """ test xml format Reference """
+
# format the stubdata using the code
xml_export = XMLFormat(solrdata.data).get_reference_xml(include_abs=False)
# now compare it with an already formatted data that we know is correct
assert(xml_export == xmlTest.data_ref)
+
def test_refxml_with_abs(self):
+ """ test xml format Reference with abstract"""
+
# format the stubdata using the code
xml_export = XMLFormat(solrdata.data).get_reference_xml(include_abs=True)
# now compare it with an already formatted data that we know is correct
assert(xml_export == xmlTest.data_ref_with_abs)
+
def test_jatsxml(self):
+ """ test xml format Jats """
+
# format the stubdata using the code
xml_export = XMLFormat(solrdata.data).get_jats_xml()
# now compare it with an already formatted data that we know is correct
assert(xml_export == xmlTest.data_jats)
+
def test_jatsxml_one_record(self):
+ """ test xml format Jats when there is only one record """
+
# format the stubdata using the code
xml_export = XMLFormat(solrdata.data_2).get_jats_xml()
# now compare it with an already formatted data that we know is correct
assert(xml_export == xmlTest.data_jats_one_record)
+
def test_aastex(self):
+ """ test csl format aastex """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'aastex', adsFormatter.latex).get()
# now compare it with an already formatted data that we know is correct
assert (csl_export == cslTest.data_AASTex)
+
def test_icarus(self):
+ """ test csl format icarus """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'icarus', adsFormatter.latex).get()
# now compare it with an already formatted data that we know is correct
assert (csl_export == cslTest.data_Icarus)
+
def test_mnras(self):
+ """ test csl format mnras """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'mnras', adsFormatter.latex).get()
# now compare it with an already formatted data that we know is correct
assert(csl_export == cslTest.data_MNRAS)
+
def test_soph(self):
+ """ test csl format soph """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'soph', adsFormatter.latex).get()
# now compare it with an already formatted data that we know is correct
assert (csl_export == cslTest.data_SoPh)
+
def test_aspc(self):
+ """ test csl format aspc """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'aspc', adsFormatter.latex).get()
# now compare it with an already formatted data that we know is correct
assert (csl_export == cslTest.data_ASPC)
+
def test_apsj(self):
+ """ test csl format apsj """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'apsj', adsFormatter.latex).get()
# now compare it with an already formatted data that we know is correct
assert (csl_export == cslTest.data_APSJ)
+
def test_aasj(self):
+ """ test csl format aasj """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'aasj', adsFormatter.latex).get()
# now compare it with an already formatted data that we know is correct
assert (csl_export == cslTest.data_AASJ)
+
def test_ieee(self):
+ """ test csl format ieee """
+
# format the stubdata using the code
csl_export = CSL(CSLJson(solrdata.data).get(), 'ieee', adsFormatter.unicode).get()
# now compare it with an already formatted data that we know is correct
assert (csl_export == cslTest.data_ieee)
+
+ def test_agu(self):
+ """ test csl format agu """
+
+ # format the stubdata using the code
+ csl_export = CSL(CSLJson(solrdata.data).get(), 'agu', adsFormatter.unicode).get()
+ # now compare it with an already formatted data that we know is correct
+ assert (csl_export == cslTest.data_agu)
+
+
+ def test_gsa(self):
+ """ test csl format gsa """
+
+ # format the stubdata using the code
+ csl_export = CSL(CSLJson(solrdata.data).get(), 'gsa', adsFormatter.unicode).get()
+ # now compare it with an already formatted data that we know is correct
+ assert (csl_export == cslTest.data_gsa)
+
+
+ def test_ams(self):
+ """ test csl format ams """
+
+ # format the stubdata using the code
+ csl_export = CSL(CSLJson(solrdata.data).get(), 'ams', adsFormatter.unicode).get()
+ # now compare it with an already formatted data that we know is correct
+ assert (csl_export == cslTest.data_ams)
+
+
def test_custom(self):
+ """ test custom format """
+
# format the stubdata using the code
custom_format = CustomFormat(custom_format=r'%ZEncoding:latex\\bibitem[%2.1m\\(%Y)]{%2H%Y}\ %5.3l\ %Y\,%j\,%V\,%p ')
custom_format.set_json_from_solr(solrdata.data)
@@ -178,60 +280,96 @@ def test_custom(self):
assert (custom_format.get_solr_fields() == 'author,year,pub,volume,page,page_range,bibcode,bibstem')
def test_ads_formatter(self):
+ """ test adsFormatter class's verify method """
+
assert(adsFormatter().verify('1') == True)
assert(adsFormatter().verify(1) == True)
assert(adsFormatter().verify('10') == False)
assert(adsFormatter().verify(10) == False)
def test_default_solr_fields(self):
+ """ test default list of solr fields """
+
default_fields = 'author,title,year,pubdate,pub,pub_raw,issue,volume,page,page_range,aff,aff_canonical,doi,abstract,' \
'read_count,bibcode,identifier,copyright,keyword,doctype,[citations],comment,pubnote,version,' \
'property,esources,data,isbn,eid,issn,arxiv_class,editor,series,publisher,bibstem,page_count,orcid_pub'
assert (views.default_solr_fields() == default_fields)
+ # test when there a limit is defined for authors and affilations
+ author_limit = 3
+ default_fields_limited = default_fields + f',[fields author={author_limit}],[fields aff={author_limit}],[fields aff_canonical={author_limit}]'
+ assert (views.default_solr_fields(author_limit) == default_fields_limited)
+
+
def test_bibtex_success(self):
+ """ test views return_bibTex_format_export when succeed """
+
response = views.return_bibTex_format_export(solrdata.data, False, '%R', 10, 200, 1)
assert(response._status_code == 200)
+
def test_bibtex_no_data(self):
+ """ test views return_bibTex_format_export when error """
+
response = views.return_bibTex_format_export(None, False, '', 0, 0, 1)
assert(response._status_code == 404)
+
def test_fielded_success(self):
+ """ test views return_fielded_format_export when succeed for each fielded format """
+
for fielded_style in ['ADS','EndNote','ProCite','Refman','RefWorks','MEDLARS']:
response = views.return_fielded_format_export(solrdata.data, fielded_style)
assert(response._status_code == 200)
+
def test_fielded_no_data(self):
+ """ test views return_fielded_format_export when error for each fielded format """
+
for fielded_style in ['ADS','EndNote','ProCite','Refman','RefWorks','MEDLARS']:
response = views.return_fielded_format_export(None, fielded_style)
assert(response._status_code == 404)
+
def test_xml_success(self):
+ """ test views return_xml_format_export when succeed for each format """
+
for xml_style in ['DublinCore','Reference','ReferenceAbs']:
response = views.return_xml_format_export(solrdata.data, xml_style)
assert(response._status_code == 200)
+
def test_xml_no_data(self):
+ """ test views return_xml_format_export when error for each format """
+
for xml_style in ['DublinCore','Reference','ReferenceAbs']:
response = views.return_xml_format_export(None, xml_style)
assert(response._status_code == 404)
+
def test_csl(self):
+ """ test views return_csl_format_export when succeed for each format """
+
export_format = 2
journal_macro = 1
- for csl_style in ['aastex','icarus','mnras', 'soph', 'aspc', 'apsj', 'aasj', 'ieee']:
+ for csl_style in ['aastex','icarus','mnras', 'soph', 'aspc', 'apsj', 'aasj', 'ieee', 'agu', 'gsa', 'ams']:
response = views.return_csl_format_export(solrdata.data, csl_style, export_format, journal_macro)
assert(response._status_code == 200)
+
def test_csl_no_data(self):
+ """ test views return_csl_format_export when error for each format """
+
export_format = 2
journal_macro = 1
- for csl_style in ['aastex','icarus','mnras', 'soph', 'aspc', 'apsj', 'aasj', 'ieee']:
+ for csl_style in ['aastex','icarus','mnras', 'soph', 'aspc', 'apsj', 'aasj', 'ieee', 'agu', 'gsa', 'ams']:
response = views.return_csl_format_export(None, csl_style, export_format, journal_macro)
assert(response._status_code == 404)
- def test_eprint(self):
+
+ def test_eprintid(self):
+ """ test extracting eprint id """
+
a_doc_no_eprint = solrdata.data['response'].get('docs')[0]
assert (get_eprint(a_doc_no_eprint) == '')
@@ -249,33 +387,10 @@ def test_eprint(self):
}
assert (get_eprint(a_doc_ascl) == 'ascl:1308.009')
+
def test_replace_html_entity(self):
- solr_data = \
- {
- "responseHeader": {
- "status": 0,
- "QTime": 2,
- "params": {
- "q": "title:\"lt;\"",
- "indent": "on",
- "fl": "bibcode,title,abstract",
- "wt": "json",
- "_": "1592510843440"}},
- "response": {"numFound": 4, "start": 0, "docs": [
- {
- "bibcode": "2016JLwT...34.4926L",
- "title": ["Study of SiO{}_{{{x}}} (1 < x lt; 2) Thin-Film Optical Waveguides"]},
- {
- "abstract": "Using Hubble Space Telescope Cosmic Origins Spectrograph observations of 89 QSO sightlines through the Sloan Digital Sky Survey footprint, we study the relationships between C IV absorption systems and the properties of nearby galaxies, as well as the large-scale environment. To maintain sensitivity to very faint galaxies, we restrict our sample to 0.0015< z< 0.015, which defines a complete galaxy survey to L≳ 0.01 L\\ast or stellar mass {M}* ≳ {10}8 {M}☉ . We report two principal findings. First, for galaxies with impact parameter ρ < 1 {r}{vir}, C IV detection strongly depends on the luminosity/stellar mass of the nearby galaxy. C IV is preferentially associated with galaxies with {M}* > {10}9.5 {M}☉ ; lower-mass galaxies rarely exhibit significant C IV absorption (covering fraction {f}C={9}-6+12 % for 11 galaxies with {M}* < {10}9.5 {M}☉ ). Second, C IV detection within the {M}* > {10}9.5 {M}☉ population depends on environment. Using a fixed-aperture environmental density metric for galaxies with ρ < 160 kpc at z< 0.055, we find that {57}-13+12 % (8/14) of galaxies in low-density regions (regions with fewer than seven L> 0.15 L\\ast galaxies within 1.5 Mpc) have affiliated C IV absorption; however, none (0/7) of the galaxies in denser regions show C IV. Similarly, the C IV detection rate is lower for galaxies residing in groups with dark matter halo masses of {M}{halo}> {10}12.5 {M}☉ . In contrast to C IV, H I is pervasive in the circumgalactic medium without regard to mass or environment. These results indicate that C IV absorbers with {log} N({{C}} {{IV}})≳ 13.5 {{cm}}-2 trace the halos of {M}* > {10}9.5 {M}☉ galaxies but also reflect larger-scale environmental conditions.",
- "bibcode": "2016ApJ...832..124B"},
- {
- "bibcode": "2015hst..prop14424B",
- "title": ["STIS CCD Amp A, C, & D Gains"]},
- {
- "bibcode": "2016BaltA..25..310K",
- "abstract": "We use the Apparent Motion Parameters (AMP) method for the determination of orbits of visual double stars (Kiselev & Kiyaeva 1980). The quality of AMP orbits is completely dependent on the precision of parameters of relative positions and motions at the same instant. They are calculated on the basis of a short arc of observations. To determine these parameters, we use recent high precision observations obtained with the best modern techniques. New orbits of three stars are presented."},
- ]}
- }
+ """ test to verify html entities are replace correctly in the title and abstract """
+
# note that if there is a entity error in the text it does not get replaced (ie, the first title lt; missing &)
result = OrderedDict([
('1_title', [u'Study of SiO{}_{{{x}}} (1 < x lt; 2) Thin-Film Optical Waveguides']),
@@ -283,133 +398,104 @@ def test_replace_html_entity(self):
('3_title', [u'STIS CCD Amp A, C, & D Gains']),
('4_abstract', u'We use the Apparent Motion Parameters (AMP) method for the determination of orbits of visual double stars (Kiselev & Kiyaeva 1980). The quality of AMP orbits is completely dependent on the precision of parameters of relative positions and motions at the same instant. They are calculated on the basis of a short arc of observations. To determine these parameters, we use recent high precision observations obtained with the best modern techniques. New orbits of three stars are presented.'),
])
- for key, doc in zip(result.keys(), solr_data['response']['docs']):
+ for key, doc in zip(result.keys(), solrdata.data_24['response']['docs']):
if isinstance(doc[key[2:]], list):
assert(replace_html_entity(doc[key[2:]][0], encode_style=adsFormatter.unicode) == result[key][0])
elif isinstance(doc[key[2:]], str):
assert(replace_html_entity(doc[key[2:]], encode_style=adsFormatter.unicode) == result[key])
+
def test_format_status(self):
+ """ test to verify the Format class's get_status method """
+
format_export = Format(solrdata.data)
assert(format_export.get_status() == 0)
+
def test_format_no_num_docs(self):
- solr_data = \
- {
- "responseHeader":{
- "status":1,
- "QTime":1,
- "params":{
- "sort":"date desc",
- "fq":"{!bitset}",
- "rows":"19",
- "q":"*:*",
- "start":"0",
- "wt":"json",
- "fl":"author,title,year,date,pub,pub_raw,issue,volume,page,page_range,aff,doi,abstract,num_citations,read_count,bibcode,identification,copyright,keyword,doctype,num_references,comment,property,esources,data"
- }
- }
- }
- format_export = Format(solr_data)
+ """ test to verify that Format class can handle when there are no docs """
+
+ format_export = Format(solrdata.data_25)
assert(format_export.get_num_docs() == 0)
+
def test_votable(self):
+ """ test votable export format """
+
# format the stubdata using the code
votable_export = VOTableFormat(solrdata.data).get()
# now compare it with an already formatted data that we know is correct
assert (votable_export == voTableTest.data)
+
def test_rss(self):
+ """ test rss export format """
+
# format the stubdata using the code
rss_export = RSSFormat(solrdata.data).get()
# now compare it with an already formatted data that we know is correct
assert (rss_export == rssTest.data)
- def test_votable_success(self):
+
+ def test_views_return_votable_format_export_success(self):
+ """ test views module return_votable_format_export method when successed"""
+
response = views.return_votable_format_export(solrdata.data)
assert(response._status_code == 200)
- def test_votable_no_data(self):
+
+ def test_views_return_votable_format_export_no_data(self):
+ """ test views module return_votable_format_export method when errors """
+
response = views.return_votable_format_export(None)
assert(response._status_code == 404)
- def test_rss_success(self):
+
+ def test_views_return_rss_format_export_success(self):
+ """ test views module return_rss_format_export method when successed"""
+
response = views.return_rss_format_export(solrdata.data, '')
assert(response._status_code == 200)
- def test_rss_no_data(self):
+
+ def test_views_return_rss_format_export_no_data(self):
+ """ test views module return_rss_format_export method when errors """
+
response = views.return_rss_format_export(None, '')
assert(response._status_code == 404)
+
def test_rss_authors(self):
- solr_data = \
- {
- "responseHeader": {
- "status": 0,
- "QTime": 1,
- "params": {
- "sort": "date desc",
- "fq": "{!bitset}",
- "rows": "19",
- "q": "*:*",
- "start": "0",
- "wt": "json",
- "fl": "author,title,year,date,pub,pub_raw,issue,volume,page,page_range,aff,doi,abstract,num_citations,read_count,bibcode,identification,copyright,keyword,doctype,num_references,comment,property,esources,data"
- }
- },
- "response": {
- "start": 0,
- "numFound": 4,
- "docs": [
- {
- "title": [
- "A Microwave Free-Space Method Using Artificial Lens with Anti-reflection Layer"
- ],
- "author": [
- "Zhang, Yangjun",
- "Aratani, Yuki",
- "Nakazima, Hironari"
- ],
- },
- {
- "author": [
- "Ryan, R. E.",
- "McCullough, P. R."
- ],
- },
- {
- "title": [
- "Resolving Gas-Phase Metallicity In Galaxies"
- ],
- },
- {
- "bibcode": "2017ascl.soft06009C",
- },
- ]
- }
- }
+ """ test rss format for various types of available metadata """
+
rss_export = RSSFormat(solrdata.data)
# both author and title exists
- assert(rss_export._RSSFormat__get_author_title(solr_data['response'].get('docs')[0]) ==
+ assert(rss_export._RSSFormat__get_author_title(solrdata.data_23['response'].get('docs')[0]) ==
'Zhang, Yangjun: A Microwave Free-Space Method Using Artificial Lens with Anti-reflection Layer')
# only author
- assert(rss_export._RSSFormat__get_author_title(solr_data['response'].get('docs')[1]) == 'Ryan, R. E.')
+ assert(rss_export._RSSFormat__get_author_title(solrdata.data_23['response'].get('docs')[1]) == 'Ryan, R. E.')
# only title
- assert(rss_export._RSSFormat__get_author_title(solr_data['response'].get('docs')[2]) ==
+ assert(rss_export._RSSFormat__get_author_title(solrdata.data_23['response'].get('docs')[2]) ==
'Resolving Gas-Phase Metallicity In Galaxies')
# neither author nor title exists
- assert(rss_export._RSSFormat__get_author_title(solr_data['response'].get('docs')[3]) == '')
+ assert(rss_export._RSSFormat__get_author_title(solrdata.data_23['response'].get('docs')[3]) == '')
+
def test_all_gets(self):
+ """ test all the get endpoints """
+
function_names = [views.bibTex_format_export_get, views.bibTex_abs_format_export_get,
views.fielded_ads_format_export_get, views.fielded_endnote_format_export_get,
views.fielded_procite_format_export_get, views.fielded_refman_format_export_get,
views.fielded_refworks_format_export_get, views.fielded_medlars_format_export_get,
views.xml_dublincore_format_export_get, views.xml_ref_format_export_get,
- views.xml_refabs_format_export_get, views.csl_aastex_format_export_get,
- views.csl_icarus_format_export_get, views.csl_mnras_format_export_get,
- views.csl_soph_format_export_get, views.votable_format_export_get,
- views.rss_format_export_get, views.csl_ieee_format_export_get]
+ views.xml_refabs_format_export_get, views.xml_jats_format_export_get,
+ views.csl_aastex_format_export_get, views.csl_icarus_format_export_get,
+ views.csl_mnras_format_export_get, views.csl_soph_format_export_get,
+ views.votable_format_export_get, views.rss_format_export_get,
+ views.csl_ieee_format_export_get, views.csl_aspc_format_export_get,
+ views.csl_aasj_format_export_get, views.csl_apsj_format_export_get,
+ views.csl_agu_format_export_get, views.csl_gsa_format_export_get, views.csl_ams_format_export_get]
bibcode = self.app.config['EXPORT_SERVICE_TEST_BIBCODE_GET']
for f in function_names:
if f == views.rss_format_export_get:
@@ -418,135 +504,86 @@ def test_all_gets(self):
response = f(bibcode)
assert (response._status_code == 200)
+
def test_all_posts(self):
+ """ test all the post endpoints """
+
endpoints = ['/bibtex', '/bibtexabs', '/ads', '/endnote', '/procite', '/ris', '/refworks', '/medlars',
- '/dcxml', '/refxml', '/refabsxml', '/aastex', '/icarus', '/mnras', '/soph', 'votable',
- 'rss', '/ieee']
- payload = {'bibcode': self.app.config['EXPORT_SERVICE_TEST_BIBCODE_GET'],
- 'link': ''}
+ '/dcxml', '/refxml', '/refabsxml', '/jatsxml', '/aastex', '/icarus', '/mnras', '/soph',
+ '/aspc', '/apsj', '/aasj', '/ieee', '/agu', '/gsa', '/ams',
+ '/custom', '/csl', '/votable', '/rss']
+
+ payload_base = {'bibcode': self.app.config['EXPORT_SERVICE_TEST_BIBCODE_GET']}
+ payload_specific = {
+ '/bibtex': {'maxauthor': 0, 'authorcutoff': 0},
+ '/rss': {'link': ''},
+ '/custom': {'format': '%R'},
+ '/csl': {'style': 'aastex', 'format': '1', 'journalformat': '2'}
+ }
+
for ep in endpoints:
+ payload = {**payload_base, **payload_specific.get(ep, {})}
response = self.client.post(ep, data=json.dumps(payload))
assert (response._status_code == 200)
+
+ def test_posts_endpoint_payload_except(self):
+ """ test the post endpoints when there is no payload """
+
+ endpoints = ['/bibtex', '/bibtexabs', '/ads', '/endnote', '/procite', '/ris', '/refworks', '/medlars',
+ '/dcxml', '/refxml', '/refabsxml', '/jatsxml', '/aastex', '/icarus', '/mnras', '/soph',
+ '/aspc', '/apsj', '/aasj', '/ieee', '/agu', '/gsa', '/ams',
+ '/custom', '/csl', '/votable', '/rss']
+
+ for ep in endpoints:
+ response = self.client.post(ep, data=None)
+ assert (response._status_code == 400)
+ assert (response.data == b'{"error": "no information received"}')
+
+
def test_bibtex_keyformat_endpoint(self):
+ """ test the BibTeX endpoint with a specific key format and author limit """
+
payload = {'bibcode': self.app.config['EXPORT_SERVICE_TEST_BIBCODE_GET'],
- 'link': '',
'keyformat': '%1H:%Y:%q',
'maxauthor': 2}
response = self.client.post('/bibtex', data=json.dumps(payload))
assert (response._status_code == 200)
+
def test_bibtex_keyformat(self):
- solr_data = \
- {
- "responseHeader": {
- "status": 0,
- "QTime": 51,
- "params": {
- "q": "author:\"^accomazzi\" year:2019",
- "indent": "on",
- "fl": "bibcode,author,pub,year",
- "wt": "json",
- "_": "1560183872951"}},
- "response": {"numFound": 3, "start": 0, "docs": [
- {
- "year": "2019",
- "bibcode": "2019AAS...23338108A",
- "bibstem": ["AAS",
- "AAS...233"],
- "author": ["Accomazzi, Alberto",
- "Kurtz, Michael J.",
- "Henneken, Edwin",
- "Grant, Carolyn S.",
- "Thompson, Donna M.",
- "Chyla, Roman",
- "McDonald, Stephen",
- "Blanco-Cuaresma, Sergi",
- "Shapurian, Golnaz",
- "Hostetler, Timothy",
- "Templeton, Matthew",
- "Lockhart, Kelly"],
- "pub": "American Astronomical Society Meeting Abstracts #233"},
- {
- "year": "2019",
- "bibcode": "2019AAS...23320704A",
- "bibstem":["AAS",
- "AAS...233"],
- "author": ["Accomazzi, Alberto"],
- "pub": "American Astronomical Society Meeting Abstracts #233"},
- {
- "year":"2019",
- "bibcode":"2019hsax.conf..526G",
- "author":["Garzón, F.",
- "Patrick, L.",
- "Hammersley, P.",
- "Streblyanska, A.",
- "Insausti, M.",
- "Barreto, M.",
- "Fernández, P.",
- "Joven, E.",
- "López, P.",
- "Mato, A.",
- "Moreno, H.",
- "Núñez, M.",
- "Patrón, J.",
- "Pascual, S.",
- "Cardiel, N."],
- "pub":"Highlights on Spanish Astrophysics X",
- "bibstem":["hsax",
- "hsax.conf"]
- }
- ]}
- }
- bibtex_export = BibTexFormat(solr_data, "%1H:%Y:%q")
+ """ test BibTex class to generate key format, including when eprint is specified """
+
+ bibtex_export = BibTexFormat(solrdata.data_20, "%1H:%Y:%q")
# both author and title exists
- assert(bibtex_export._BibTexFormat__format_key(solr_data['response'].get('docs')[0]) == 'Accomazzi:2019:AAS')
+ assert(bibtex_export._BibTexFormat__format_key(solrdata.data_21['response'].get('docs')[0]) == 'Accomazzi:2019:AAS')
# verify that key is ascii
- assert(bibtex_export._BibTexFormat__format_key(solr_data['response'].get('docs')[2]) == 'Garzon:2019:hsax')
+ assert(bibtex_export._BibTexFormat__format_key(solrdata.data_21['response'].get('docs')[2]) == 'Garzon:2019:hsax')
# if keyformat is eprintid and there is no eid in the record
- bibtex_export = BibTexFormat(solr_data, "%X")
+ bibtex_export = BibTexFormat(solrdata.data_20, "%X")
# must return the default bibcode
- assert(bibtex_export._BibTexFormat__format_key(solr_data['response'].get('docs')[0]) == '2019AAS...23338108A')
+ assert(bibtex_export._BibTexFormat__format_key(solrdata.data_21['response'].get('docs')[0]) == '2019AAS...23338108A')
- solr_data = \
- {
- "responseHeader": {
- "status": 0,
- "QTime": 29,
- "params": {
- "q": "author:\"accomazzi\" AND doctype:eprint AND year:2021",
- "fl": "bibcode,eid,eprint",
- "sort": "bibcode desc",
- "rows": "300",
- "_": "1642527401469"}},
- "response": {"numFound": 2, "start": 0, "docs": [
- {
- "bibcode": "2021arXiv211200590G",
- "eid": "arXiv:2112.00590"},
- {
- "bibcode": "2021arXiv210601477C",
- "eid": "arXiv:2106.01477"}]
- }
- }
# keyformat is eprintid
- bibtex_export = BibTexFormat(solrdata.data, "%X")
- assert(bibtex_export._BibTexFormat__format_key(solr_data['response'].get('docs')[0]) == 'arXiv:2112.00590')
+ bibtex_export = BibTexFormat(solrdata.data_22, "%X")
+ assert(bibtex_export._BibTexFormat__format_key(solrdata.data_22['response'].get('docs')[0]) == 'arXiv:2112.00590')
+
def test_no_journal_macro(self):
- # test by passing replacing journal macros for journal names
+ """ test by passing replacing journal macros for journal names """
# bibTex format
# display full journal name
- bibtex_export = BibTexFormat(solrdata.data_5, "%R").get(include_abs=False, maxauthor=10, authorcutoff=200, journalformat=3).get('export', '')
+ bibtex_export = BibTexFormat(solrdata.data_5, "%R").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=3).get('export', '')
bibtex_full_journal_name = u'@ARTICLE{2018PhRvL.120b9901P,\n author = {{Pustilnik}, M. and {van Heck}, B. and {Lutchyn}, R.~M. and {Glazman}, L.~I.},\n title = "{Erratum: Quantum Criticality in Resonant Andreev Conduction [Phys. Rev. Lett. 119, 116802 (2017)]}",\n journal = {Physical Review Letters},\n year = 2018,\n month = jan,\n volume = {120},\n number = {2},\n eid = {029901},\n pages = {029901},\n doi = {10.1103/PhysRevLett.120.029901},\n adsurl = {https://ui.adsabs.harvard.edu/abs/2018PhRvL.120b9901P},\n adsnote = {Provided by the SAO/NASA Astrophysics Data System}\n}\n\n'
assert (bibtex_export == bibtex_full_journal_name)
# display abbreviated journal name
- bibtex_export = BibTexFormat(solrdata.data_5, "%R").get(include_abs=False, maxauthor=10, authorcutoff=200, journalformat=2).get('export', '')
+ bibtex_export = BibTexFormat(solrdata.data_5, "%R").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=2).get('export', '')
bibtex_abbrev_journal_name = u'@ARTICLE{2018PhRvL.120b9901P,\n author = {{Pustilnik}, M. and {van Heck}, B. and {Lutchyn}, R.~M. and {Glazman}, L.~I.},\n title = "{Erratum: Quantum Criticality in Resonant Andreev Conduction [Phys. Rev. Lett. 119, 116802 (2017)]}",\n journal = {PhRvL},\n year = 2018,\n month = jan,\n volume = {120},\n number = {2},\n eid = {029901},\n pages = {029901},\n doi = {10.1103/PhysRevLett.120.029901},\n adsurl = {https://ui.adsabs.harvard.edu/abs/2018PhRvL.120b9901P},\n adsnote = {Provided by the SAO/NASA Astrophysics Data System}\n}\n\n'
assert (bibtex_export == bibtex_abbrev_journal_name)
# macro (default)
- bibtex_export = BibTexFormat(solrdata.data_5, "%R").get(include_abs=False, maxauthor=10, authorcutoff=200, journalformat=0).get('export', '')
+ bibtex_export = BibTexFormat(solrdata.data_5, "%R").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=0).get('export', '')
bibtex_default_journal_name = u'@ARTICLE{2018PhRvL.120b9901P,\n author = {{Pustilnik}, M. and {van Heck}, B. and {Lutchyn}, R.~M. and {Glazman}, L.~I.},\n title = "{Erratum: Quantum Criticality in Resonant Andreev Conduction [Phys. Rev. Lett. 119, 116802 (2017)]}",\n journal = {\\prl},\n year = 2018,\n month = jan,\n volume = {120},\n number = {2},\n eid = {029901},\n pages = {029901},\n doi = {10.1103/PhysRevLett.120.029901},\n adsurl = {https://ui.adsabs.harvard.edu/abs/2018PhRvL.120b9901P},\n adsnote = {Provided by the SAO/NASA Astrophysics Data System}\n}\n\n'
assert (bibtex_export == bibtex_default_journal_name)
@@ -572,15 +609,19 @@ def test_no_journal_macro(self):
aastex_abbrev_journal_name = u'\\bibitem[Ajani et al.(2021)]{2021A&A...645L..11A} Ajani, V., Starck, J.-L., \\& Pettorino, V.\\ 2021, A\\&A, 645, L11. doi:10.1051/0004-6361/202039988\n'
assert (csl_export == aastex_abbrev_journal_name)
+
def test_bibtex_enumeration(self):
- # test bibtex key_format enumeration
+ """ test bibtex key_format enumeration """
+
bibtex_export = BibTexFormat(solrdata.data_6, "%1H%Y%zm")
key_formats_enumerated = ['Accomazzi2020', 'Accomazzi2019a', 'Accomazzi2015', 'Accomazzi2019b', 'Accomazzi2019c',
'Accomazzi2018a', 'Accomazzi2018b', 'Accomazzi2017', 'Accomazzi2018c', 'Accomazzi2018d']
assert (bibtex_export._BibTexFormat__enumerate_keys() == key_formats_enumerated)
+
def test_tmp_bibcode_format(self):
- # test bibcodes that have no volume and page but doi for all CSL formats
+ """ test bibcodes that have no volume and page but doi for all CSL formats """
+
csl_export_output = {
'aastex': u'\\bibitem[Aharon(2005)]{2005GML...tmp....1A} Aharon, P.\\ 2005, Geo-Marine Letters. doi:10.1007/s00367-005-0006-y\n',
'icarus': u'\\bibitem[Aharon(2005)]{2005GML...tmp....1A} Aharon, P.\\ 2005.\\ Catastrophic flood outbursts in mid-continent left imprints in the Gulf of Mexico.\\ Geo-Marine Letters. doi:10.1007/s00367-005-0006-y\n',
@@ -589,16 +630,21 @@ def test_tmp_bibcode_format(self):
'aspc': u'\\bibitem[Aharon(2005)]{2005GML...tmp....1A} Aharon, P.\\ 2005, Geo-Marine Letters. doi:10.1007/s00367-005-0006-y.\n',
'apsj': u'P. Aharon, (2005). doi:10.1007/s00367-005-0006-y.\n',
'aasj': u'\\bibitem[Aharon(2005)]{2005GML...tmp....1A} Aharon, P.\\ 2005, Geo-Marine Letters. doi:10.1007/s00367-005-0006-y.\n',
- 'ieee': u'[1]Aharon, P., “Catastrophic flood outbursts in mid-continent left imprints in the Gulf of Mexico”, Geo-Marine Letters, 2005. doi:10.1007/s00367-005-0006-y.\n'
+ 'ieee': u'[1]Aharon, P., “Catastrophic flood outbursts in mid-continent left imprints in the Gulf of Mexico”, Geo-Marine Letters, 2005. doi:10.1007/s00367-005-0006-y.\n',
+ 'agu': u'Aharon, P. (2005) Catastrophic flood outbursts in mid-continent left imprints in the Gulf of Mexico Geo-marine Letters. https://doi.org/10.1007/s00367-005-0006-y\n',
+ 'gsa': u'Aharon, P., 2005, Catastrophic flood outbursts in mid-continent left imprints in the Gulf of Mexico: Geo-Marine Letters,, doi:10.1007/s00367-005-0006-y.\n',
+ 'ams': u'Aharon, P., 2005: Catastrophic flood outbursts in mid-continent left imprints in the Gulf of Mexico https://doi.org/10.1007/s00367-005-0006-y.\n',
}
- cls_default_formats = [adsFormatter.latex] * 6 + [adsFormatter.unicode] * 2
+ cls_default_formats = [adsFormatter.latex] * 6 + [adsFormatter.unicode] * 5
for style, format in zip(adsCSLStyle.ads_CLS, cls_default_formats):
csl_export = CSL(CSLJson(solrdata.data_7).get(), style, format).get().get('export', '')
assert (csl_export == csl_export_output[style])
+
def test_encode_doi(self):
- # test doi that is encoded properly
+ """ test doi that is encoded properly """
+
csl_export_output = {
'aastex': u'\\bibitem[Greisen(2003)]{2003ASSL..285..109G} Greisen, E.~W.\\ 2003, Information Handling in Astronomy - Historical Vistas, 109. doi:10.1007/0-306-48080-8\\_7\n',
'icarus': u'\\bibitem[Greisen(2003)]{2003ASSL..285..109G} Greisen, E.~W.\\ 2003.\\ AIPS, the VLA, and the VLBA.\\ Information Handling in Astronomy - Historical Vistas 109. doi:10.1007/0-306-48080-8\\_7\n',
@@ -607,40 +653,53 @@ def test_encode_doi(self):
'aspc': u'\\bibitem[Greisen(2003)]{2003ASSL..285..109G} Greisen, E.~W.\\ 2003, Information Handling in Astronomy - Historical Vistas, 109. doi:10.1007/0-306-48080-8\\_7.\n',
'apsj': u'E.~W. Greisen, in {\\bf 285}, 109. doi:10.1007/0-306-48080-8_7.\n',
'aasj': u'\\bibitem[Greisen(2003)]{2003ASSL..285..109G} Greisen, E. W.\\ 2003, Information Handling in Astronomy - Historical Vistas, 109. doi:10.1007/0-306-48080-8\\_7.\n',
- 'ieee': u'[1]Greisen, E. W., “AIPS, the VLA, and the VLBA”, in Information Handling in Astronomy - Historical Vistas, vol. 285, 2003, p. 109. doi:10.1007/0-306-48080-8_7.\n'
+ 'ieee': u'[1]Greisen, E. W., “AIPS, the VLA, and the VLBA”, in Information Handling in Astronomy - Historical Vistas, vol. 285, 2003, p. 109. doi:10.1007/0-306-48080-8_7.\n',
+ 'agu': u'Greisen, E. W. (2003) AIPS, the VLA, and the VLBA In Information Handling in Astronomy - Historical Vistas (Vol. 285, p. 109). https://doi.org/10.1007/0-306-48080-8_7\n',
+ 'gsa': u'Greisen, E.W., 2003, AIPS, the VLA, and the VLBA, in Information Handling in Astronomy - Historical Vistas, doi:10.1007/0-306-48080-8_7.\n',
+ 'ams': u'Greisen, E. W., 2003: AIPS, the VLA, and the VLBA. Information Handling in Astronomy - Historical Vistas, Vol. 285 of, p. 109, https://doi.org/10.1007/0-306-48080-8_7.\n',
}
- cls_default_formats = [adsFormatter.latex] * 6 + [adsFormatter.unicode] * 2
+ cls_default_formats = [adsFormatter.latex] * 6 + [adsFormatter.unicode] * 5
for style, format in zip(adsCSLStyle.ads_CLS, cls_default_formats):
csl_export = CSL(CSLJson(solrdata.data_10).get(), style, format).get().get('export', '')
assert (csl_export == csl_export_output[style])
+
def test_encode_latex_greek_alphabet(self):
- # test mapping of greek letter macros
+ """ test mapping of greek letter macros """
+
title = 'Measurement of the \\Sigma\\ beam asymmetry for the \\omega\\ photo-production off the proton and the neutron at GRAAL'
title_encoded = r'Measurement of the \textbackslash{}Sigma\textbackslash{} beam asymmetry for the \textbackslash{}omega\textbackslash{} photo-production off the proton and the neutron at GRAAL'
assert(encode_laTex(title) == title_encoded)
+
def test_misc_with_and_without_publiser(self):
- # test misc for BibTex with and without publisher
+ """ test misc for BibTex with and without publisher """
+
# if publisher, display it, if not, format pub_raw in howpublished
expected_bibtex_export = u'@software{2023zndo...8083529K,\n author = {{Karras}, Oliver},\n title = "{Analysis of the State and Evolution of Empirical Research in Requirements Engineering}",\n year = 2023,\n month = jun,\n eid = {10.5281/zenodo.8083529},\n doi = {10.5281/zenodo.8083529},\n version = {v1.0},\n publisher = {Zenodo},\n adsurl = {https://ui.adsabs.harvard.edu/abs/2023zndo...8083529K},\n adsnote = {Provided by the SAO/NASA Astrophysics Data System}\n}\n\n@MISC{2023BoSAB..34......,\n title = "{Proceedings da XLV Reuni{\\~a}o Anual da SAB}",\n howpublished = {Boletim da Sociedade Astr{\\^o}nomica Brasileira. Proceedings da XLV Reuni{\\~a}o Anual da SAB},\n year = 2023,\n month = jan,\n adsurl = {https://ui.adsabs.harvard.edu/abs/2023BoSAB..34......},\n adsnote = {Provided by the SAO/NASA Astrophysics Data System}\n}\n\n@dataset{2012ddsw.rept.....T,\n author = {{Thornton}, P.~E. and {Thornton}, M.~M. and {Mayer}, B.~W. and {Wilhelmi}, N. and {Wei}, Y. and {Devarakonda}, R. and {Cook}, R.},\n title = "{Daymet: Daily surface weather on a 1 km grid for North America, 1980-2008}",\n howpublished = {Oak Ridge National Laboratory (ORNL) Distributed Active Archive Center for Biogeochemical Dynamics (DAAC)},\n year = 2012,\n month = apr,\n doi = {10.3334/ORNLDAAC/1219},\n adsurl = {https://ui.adsabs.harvard.edu/abs/2012ddsw.rept.....T},\n adsnote = {Provided by the SAO/NASA Astrophysics Data System}\n}\n\n'
- bibtex_export = BibTexFormat(solrdata.data_16, "%R").get(include_abs=False, maxauthor=10, authorcutoff=200, journalformat=3).get('export', '')
+ bibtex_export = BibTexFormat(solrdata.data_16, "%R").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=3).get('export', '')
assert(bibtex_export == expected_bibtex_export)
+
def test_bibtex_publisher(self):
- # format the publisher stubdata using the code
- bibtex_export = BibTexFormat(solrdata.data_17, "%R").get(include_abs=False, maxauthor=10, authorcutoff=200, journalformat=1)
+ """ format the publisher stubdata using the code """
+
+ bibtex_export = BibTexFormat(solrdata.data_17, "%R").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=1)
# now compare it with an already formatted data that we know is correct
assert (bibtex_export == bibTexTest.data_publisher)
+
def test_bibtex_with_abs_publisher(self):
- # format the publisher stubdata using the code
- bibtex_export = BibTexFormat(solrdata.data_17, "%R").get(include_abs=True, maxauthor=0, authorcutoff=200, journalformat=1)
+ """ format the publisher stubdata using the code """
+
+ bibtex_export = BibTexFormat(solrdata.data_17, "%R").get(include_abs=True, max_author=0, author_cutoff=200, journal_format=1)
# now compare it with an already formatted data that we know is correct
assert (bibtex_export == bibTexTest.data_with_abs_publisher)
+
def test_custom_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
custom_format = CustomFormat(custom_format=r'%ZEncoding:latex\\bibitem[%2.1m\\(%Y)]{%2H%Y}\ %5.3l\ %Y\,%j\,%V\,%p\,Publisher:%pb ')
custom_format.set_json_from_solr(solrdata.data_17)
# now compare it with an already formatted data that we know is correct
@@ -648,56 +707,74 @@ def test_custom_publisher(self):
# verify correct solr fields are fetched
assert (custom_format.get_solr_fields() == 'author,year,pub,volume,publisher,page,page_range,bibcode,bibstem')
+
def test_ads_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
fielded_export = FieldedFormat(solrdata.data_17).get_ads_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_ads_publisher)
+
def test_endnote_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
fielded_export = FieldedFormat(solrdata.data_17).get_endnote_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_endnote_publisher)
+
def test_procite_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
fielded_export = FieldedFormat(solrdata.data_17).get_procite_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_procite_publisher)
+
def test_refman_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
fielded_export = FieldedFormat(solrdata.data_17).get_refman_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_refman_publisher)
+
def test_refworks_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
fielded_export = FieldedFormat(solrdata.data_17).get_refworks_fielded()
# now compare it with an already formatted data that we know is correct
assert (fielded_export == fieldedTest.data_refworks_publisher)
+
def test_dublinxml_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
xml_export = XMLFormat(solrdata.data_17).get_dublincore_xml()
# now compare it with an already formatted data that we know is correct
assert(xml_export == xmlTest.data_dublin_core_publisher)
+
def test_refxml_with_abs_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
xml_export = XMLFormat(solrdata.data_17).get_reference_xml(include_abs=True)
# now compare it with an already formatted data that we know is correct
assert (xml_export == xmlTest.data_ref_with_abs_publisher)
+
def test_jatsxml_publisher(self):
- # format the publisher stubdata using the code
+ """ format the publisher stubdata using the code """
+
xml_export = XMLFormat(solrdata.data_17).get_jats_xml()
# now compare it with an already formatted data that we know is correct
assert(xml_export == xmlTest.data_jats_publisher)
+
def test_endnote_conf_loc(self):
- # test extracting conference location from pub_raw
+ """ test extracting conference location from pub_raw """
+
fielded_export = FieldedFormat({})
fielded_export._FieldedFormat__setup_conf_loc()
@@ -721,5 +798,251 @@ def test_endnote_conf_loc(self):
assert(fielded_export._FieldedFormat__get_conf_loc(pub_raw) == conference_location)
+ def test_encode_laTex(self):
+ """ test for various scenarios in the encode_laTex function """
+
+ # text with one $ sign, escape it
+ text1 = "This is a test with one $ sign."
+ expected1 = "This is a test with one \$ sign."
+ self.assertEqual(encode_laTex(text1), expected1)
+
+ # text with math mode chunks (even count of $), no substitution in the math mode
+ text2 = "This is a $ math mode $ example."
+ expected2 = "This is a $ math mode $ example."
+ self.assertEqual(encode_laTex(text2), expected2)
+
+
+ def test_utf8tolatex(self):
+ """ test the main loop of utf8tolatex function to ensure correct processing of ASCII and non-ASCII characters """
+
+ text = "Consider these characters: #, &, α, Θ, ☃, ♞."
+
+ expected1 = r"Consider these characters: {\#}, {\&}, {\ensuremath{\alpha}}, {\ensuremath{\Theta}}, ☃, ♞."
+ self.assertEqual(utf8tolatex(text, non_ascii_only=False, brackets=True, substitute_bad_chars=False, ascii_no_brackets=False), expected1)
+
+ expected2 = r"Consider these characters: #, &, \ensuremath{\alpha}, \ensuremath{\Theta}, {\bfseries ?}, {\bfseries ?}."
+ self.assertEqual(utf8tolatex(text, non_ascii_only=True, brackets=False, substitute_bad_chars=True, ascii_no_brackets=False), expected2)
+
+
+ def test_generate_counter_id(self):
+ """ test when the generated id string is longer that needs to be three characters long """
+ length = (26**2) + 2
+ counter_ids = Format(from_solr={}).generate_counter_id(length)
+ self.assertEqual(len(counter_ids), 678)
+ self.assertEqual(counter_ids[0], 'AA')
+ self.assertEqual(counter_ids[-1], 'AAB')
+
+
+ def test_adsOrganizer_citation_bibliography(self):
+ """ test adsOrganizer's citation_bibliography option """
+
+ csl_export = CSL(CSLJson(solrdata.data_16).get(), 'ieee', adsFormatter.latex).get(adsOrganizer.citation_bibliography)
+ expected_results = [
+ '2023zndo...8083529K', '', '[1]Karras, O., “Analysis of the State and Evolution of Empirical Research in Requirements Engineering”, Zenodo, Art. no. 10.5281/zenodo.8083529, Zenodo, 2023.',
+ '2023BoSAB..34......', '', '[2]No author, “Proceedings da XLV Reunião Anual da SAB”, BoSAB..34, 2023.',
+ '2012ddsw.rept.....T', '', '[3]Thornton, P. E., “Daymet: Daily surface weather on a 1 km grid for North America, 1980-2008”, Oak Ridge National Laboratory (ORNL) Distributed Active Archive Center for Biogeochemical Dynamics (DAAC, 2012.',
+ ''
+ ]
+ self.assertEqual(csl_export.split('\n'), expected_results)
+
+ # send it an unrecognizable export_organizer id
+ self.assertEqual(CSL(CSLJson(solrdata.data_16).get(), 'ieee', adsFormatter.latex).get(export_organizer=10), None)
+
+
+ def test_adsFormatter_is_number(self):
+ """ test adsFormatter's is_number method """
+
+ # U+2162 Roman numeral three
+ self.assertTrue(adsFormatter()._adsFormatter__is_number("Ⅲ"))
+ # not a number
+ self.assertFalse(adsFormatter()._adsFormatter__is_number("ABC"))
+
+
+ def test_adsFormatter_native_encoding(self):
+ """ test adsFormatter's native_encoding function to ensure the correct encoding is determined """
+
+ instance = adsFormatter()
+
+ # where native_format is in native_latex
+ self.assertEqual(instance.native_encoding('BibTex'), adsFormatter.latex)
+
+ # where native_format is in native_xml
+ self.assertEqual(instance.native_encoding('DublinCore'), adsFormatter.xml)
+
+ # where native_format is not in either list
+ self.assertEqual(instance.native_encoding('UnknownFormat'), adsFormatter.unicode)
+
+
+ def test_adsJournalFormat_verify(self):
+ """ test adsJournalFormat's verify function """
+
+ self.assertTrue(adsJournalFormat().verify(style=adsJournalFormat.full))
+ # give it an undefined style
+ self.assertFalse(adsJournalFormat().verify(style=10))
+
+
+ def test_bibtex_authors_w_suffix(self):
+ """ test bibtex format, formatting authors with suffix """
+
+ bibtex_export = BibTexFormat(solrdata.data_18, "%R")
+ expected_results = [
+ '{Smith}, Jr, Frank D.',
+ '{Thompson}, A. Richard and {Moran}, James M. and {Swenson}, Jr., George W.',
+ '{Wang}, Y. -M. and {Sheeley}, Jr., N.~R.',
+ '{Spilker}, Jr., J.~J.',
+ '{Anderson}, D.~G. and {Goodyear}, A.~C. and {Stafford}, Jr., T.~W. and {Kennett}, J. and {West}, A.',
+ '{Wang}, Y. -M. and {Sheeley}, Jr., N.~R.',
+ '{Spitzer}, Jr., Lyman and {Hart}, Michael H.',
+ '{Merow}, Cory and {Smith}, Matthew J. and {Silander}, Jr., John A.',
+ ]
+
+ for a_doc, expected_result in zip(bibtex_export.from_solr['response'].get('docs'), expected_results):
+ self.assertEqual(bibtex_export._BibTexFormat__get_author_list(a_doc, 'author', max_author=0, author_cutoff=25), expected_result)
+
+
+ def test_bibtex_authors_w_suffix_et_al(self):
+ """ test bibtex format, formatting authors with suffix, shorten the list """
+
+ bibtex_export = BibTexFormat(solrdata.data_18, "%R")
+ expected_results = [
+ '{Smith}, Jr, Frank D.',
+ '{Thompson}, A. Richard and et al.',
+ '{Wang}, Y. -M. and {Sheeley}, Jr., N.~R.',
+ '{Spilker}, Jr., J.~J.',
+ '{Anderson}, D.~G. and et al.',
+ '{Wang}, Y. -M. and {Sheeley}, Jr., N.~R.',
+ '{Spitzer}, Jr., Lyman and {Hart}, Michael H.',
+ '{Merow}, Cory and et al.',
+ ]
+
+ for a_doc, expected_result in zip(bibtex_export.from_solr['response'].get('docs'), expected_results):
+ # show one author is more than 2
+ self.assertEqual(bibtex_export._BibTexFormat__get_author_list(a_doc, 'author', max_author=1, author_cutoff=2), expected_result)
+
+
+ def test_get_author_lastname_list(self):
+ """ test Bibtex format's get_author_lastname_list method """
+
+ bibtex_export = BibTexFormat(solrdata.data_18, "%R")
+
+ expected_results = [
+ 'Smith',
+ 'ThompsonMoranSwenson',
+ 'WangSheeley',
+ 'Spilker',
+ 'AndersonGoodyearStaffordKennettWest',
+ 'WangSheeley',
+ 'SpitzerHart',
+ 'MerowSmithSilander',
+ ]
+
+ for a_doc, expected_result in zip(bibtex_export.from_solr['response'].get('docs'), expected_results):
+ self.assertEqual(bibtex_export._BibTexFormat__get_author_lastname_list(a_doc, max_author=10), expected_result)
+
+
+ def test_get_affiliation_list(self):
+ """ test Bibtex format's get_affiliation_list method """
+
+ # when there is no aff in a doc
+ bibtex_export = BibTexFormat(solrdata.data_8, "%R")
+
+ for a_doc in bibtex_export.from_solr['response'].get('docs'):
+ self.assertEqual(bibtex_export._BibTexFormat__get_affiliation_list(a_doc, max_author=0, author_cutoff=25), '')
+
+ bibtex_export = BibTexFormat(solrdata.data_9, "%R")
+
+ # when there are aff and doctype is not thesis
+ expected_results = [
+ r'AA(AIM, CEA, CNRS, Universit{\'e} Paris-Saclay, Universit{\'e} de Paris, Sorbonne Paris Cit{\'e}, 91191, Gif-sur-Yvette, France), AB(AIM, CEA, CNRS, Universit{\'e} Paris-Saclay, Universit{\'e} de Paris, Sorbonne Paris Cit{\'e}, 91191, Gif-sur-Yvette, France), AC(AIM, CEA, CNRS, Universit{\'e} Paris-Saclay, Universit{\'e} de Paris, Sorbonne Paris Cit{\'e}, 91191, Gif-sur-Yvette, France)'
+ ]
+
+ for a_doc, expected_result in zip(bibtex_export.from_solr['response'].get('docs'), expected_results):
+ self.assertEqual(bibtex_export._BibTexFormat__get_affiliation_list(a_doc, max_author=0, author_cutoff=25), expected_result)
+
+ # now returned just one author
+ expected_results = [
+ r'AA(AIM, CEA, CNRS, Universit{\'e} Paris-Saclay, Universit{\'e} de Paris, Sorbonne Paris Cit{\'e}, 91191, Gif-sur-Yvette, France)'
+ ]
+
+ for a_doc, expected_result in zip(bibtex_export.from_solr['response'].get('docs'), expected_results):
+ print(bibtex_export._BibTexFormat__get_affiliation_list(a_doc, max_author=1, author_cutoff=2))
+ self.assertEqual(bibtex_export._BibTexFormat__get_affiliation_list(a_doc, max_author=1, author_cutoff=2), expected_result)
+
+
+ def test_bibtex_add_clean_pub_raw(self):
+ """ test bibtex format's add_clean_pub_raw method """
+
+ bibtex_export = BibTexFormat(solrdata.data_9, "%R")
+
+ expected_result = 'Astronomy \& Astrophysics, Volume 645, id.L11, 8 pp.'
+
+ result = bibtex_export._BibTexFormat__add_clean_pub_raw(bibtex_export.from_solr['response'].get('docs')[0])
+
+ self.assertEqual(result, expected_result)
+
+
+ def test_bibtex_add_in_eprint(self):
+ """ Test Bibtex format's add_in_eprint method """
+
+ bibtex_export = BibTexFormat(solrdata.data_9, "%R")
+
+ a_doc = bibtex_export.from_solr['response'].get('docs')[0]
+
+ self.assertEqual(bibtex_export._BibTexFormat__add_in_eprint('archivePrefix|eprint', get_eprint(a_doc), u'{0:>13} = {{{1}}}'), 'archivePrefix = {arXiv},\n eprint = {2101.01542},\n')
+
+ # now send input that are not correct
+ self.assertEqual(bibtex_export._BibTexFormat__add_in_eprint('eprint', 'can be empty too', u'{0:>13} = {{{1}}}'), '')
+
+
+ def test_bibtex_keyformat_enumeration(self):
+ """ text Bibtex format's get method check for keyformat enumeration """
+
+ bibtex_export = BibTexFormat(solrdata.data_19, "%zm%H").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=1)
+
+ assert (bibtex_export == {'msg': 'Retrieved 3 abstracts, starting with number 1.', 'export': '{Shapuriana\n}\n\n{Shapurianb\n}\n\n{Koch\n}\n\n'})
+
+
+ def test_bibtex_keyformat_ascii(self):
+ """ text Bibtex format's get method check for keyformat being ascii """
+
+ bibtex_export = BibTexFormat(solrdata.data_20, "%H").get(include_abs=False, max_author=10, author_cutoff=200, journal_format=1)
+
+ assert (bibtex_export == {'msg': 'Retrieved 1 abstracts, starting with number 1.', 'export': '{Andre\n}\n\n'})
+
+
+ def test_bibtex_field_wrapped(self):
+ """ text Bibtex format's field_wrapped method when no value is passed in to return empty string """
+
+ assert (BibTexFormat(solrdata.data_20, "%H")._BibTexFormat__field_wrapped('', '', ''), '')
+
+
+ def test_bibtex_get_journal(self):
+ """ text Bibtex format's get_journal method when doctype is software to return empty string """
+
+ bibtex_export = BibTexFormat(solrdata.data_16, "%R")
+ a_doc = bibtex_export.from_solr['response'].get('docs')[0]
+
+ assert (BibTexFormat(solrdata.data_10, "%R")._BibTexFormat__get_journal(a_doc, ''), None)
+
+
+ def test_bibtex_format_line_wrapped(self):
+ """ text Bibtex format's format_line_wrapped """
+
+ assert (BibTexFormat(solrdata.data_20, "%H")._BibTexFormat__format_line_wrapped('author', 'Di Francesco, J.', u'{0:>13} = {{{1}}}'), 'author = {Di Francesco, J.}')
+
+
+ def test_views_get_export_format_for_journal_style(self):
+ """ test views module's get_export_format_for_journal_style method """
+
+ # if payload is not valid, knowing the style aastex is useless
+ assert (get_export_format_for_journal_style(payload={}, style='aastex') == -1)
+
+ # if style is one of these, ['icarus', 'mnras', 'soph', 'apsj'], return value is 3
+ assert (get_export_format_for_journal_style(payload={}, style='icarus') == 3)
+
+ # when style is unknown
+ assert (get_export_format_for_journal_style(payload={}, style='') == -1)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/exportsrv/tests/unittests/test_export_service_error.py b/exportsrv/tests/unittests/test_export_service_error.py
index b61e8f7..1f7c3f3 100755
--- a/exportsrv/tests/unittests/test_export_service_error.py
+++ b/exportsrv/tests/unittests/test_export_service_error.py
@@ -3,8 +3,14 @@
from flask_testing import TestCase
import unittest
import json
+from datetime import datetime
+
+import xml.etree.ElementTree as ET
import exportsrv.app as app
+from exportsrv.formatter.rssFormat import RSSFormat
+from exportsrv.formatter.strftime import strftime
+from exportsrv.formatter.latexencode import utf8tolatex
class TestExportsError(TestCase):
def create_app(self):
@@ -61,13 +67,18 @@ def test_missing_payload_param(self):
"""
Ensure that all of the payload params were passed in, otherwise returns 400
"""
+ endpoints = ['/csl', '/custom']
payload = {'bibcode': '', 'style': '', 'format': ''}
- for route in ['/csl', '/custom']:
- r = self.client.post(route, data=json.dumps(payload))
+ expected_errors = [
+ b'{"error": "unrecognizable style (supprted formats are: aastex, icarus, mnras, soph, aspc, apsj, aasj, ieee, agu, gsa, ams)"}',
+ b'{"error": "invalid custom format"}'
+ ]
+ for endpoint, expected_error in zip(endpoints, expected_errors):
+ r = self.client.post(endpoint, data=json.dumps(payload))
status = r.status_code
response = r.data
self.assertEqual(status, 400)
- self.assertEqual(response, b'{"error": "not all the needed information received"}')
+ self.assertEqual(response, expected_error)
def test_non_exist_style(self):
@@ -75,7 +86,7 @@ def test_non_exist_style(self):
Ensure that if payload contains the supported styles for each endpoints otherwise returns 400
"""
payload = {'bibcode': '1989ApJ...342L..71R', 'style': 'nonExsistingStyle', 'format': 'nonEsistingFormat'}
- end_point = {'/csl':b'{"error": "unrecognizable style (supprted formats are: aastex, icarus, mnras, soph, aspc, apsj, aasj, ieee)"}'}
+ end_point = {'/csl':b'{"error": "unrecognizable style (supprted formats are: aastex, icarus, mnras, soph, aspc, apsj, aasj, ieee, agu, gsa, ams)"}'}
for key in end_point:
r = self.client.post(key, data=json.dumps(payload))
status = r.status_code
@@ -98,5 +109,39 @@ def test_non_exist_format(self):
self.assertEqual(response, end_point[key])
+ def test_rss_add_in_with_empty_value(self):
+ """
+ Test rss format add_in for when the element is not availabe
+ """
+ parent = ET.Element('parent')
+ instance = RSSFormat(from_solr={})
+
+ # call the __add_in method with an empty value
+ instance._RSSFormat__add_in(parent, 'testField', '')
+
+ # check that the element was added and the text is 'Not Available'
+ added_element = parent.find('testField')
+ self.assertIsNotNone(added_element, "The element was not added.")
+ self.assertEqual(added_element.text, 'Not Available', "The text is not 'Not Available'.")
+
+
+ def test_strftime_when_illegal_format_raises_type_error(self):
+ """
+ test strftime function in the strftime module
+ """
+ dt = datetime(2022, 2, 2)
+ # triggers the _illegal_s search condition
+ illegal_format = "%s"
+
+ with self.assertRaises(TypeError):
+ strftime(dt, illegal_format)
+
+ def test_utf8tolatex_when_empty_string(self):
+ """
+ send empty string to latexencode's utf8tolatex function
+ """
+ self.assertTrue(utf8tolatex("") == "")
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/exportsrv/views.py b/exportsrv/views.py
index 912e009..8b7bf88 100755
--- a/exportsrv/views.py
+++ b/exportsrv/views.py
@@ -21,14 +21,21 @@
-def default_solr_fields():
+def default_solr_fields(author_limit=0):
"""
+ :param author_limit:
:return: list of fields needed from solr
"""
+ if author_limit == 0:
+ return 'author,title,year,pubdate,pub,pub_raw,issue,volume,page,page_range,aff,aff_canonical,doi,abstract,' \
+ 'read_count,bibcode,identifier,copyright,keyword,doctype,[citations],comment,pubnote,version,' \
+ 'property,esources,data,isbn,eid,issn,arxiv_class,editor,series,publisher,bibstem,page_count,orcid_pub'
+ # if the limit is specified, include it in
return 'author,title,year,pubdate,pub,pub_raw,issue,volume,page,page_range,aff,aff_canonical,doi,abstract,' \
'read_count,bibcode,identifier,copyright,keyword,doctype,[citations],comment,pubnote,version,' \
- 'property,esources,data,isbn,eid,issn,arxiv_class,editor,series,publisher,bibstem,page_count,orcid_pub'
+ 'property,esources,data,isbn,eid,issn,arxiv_class,editor,series,publisher,bibstem,page_count,orcid_pub,' \
+ f'[fields author={author_limit}],[fields aff={author_limit}],[fields aff_canonical={author_limit}]'
def return_response(results, status, request_type=''):
@@ -61,7 +68,7 @@ def return_response(results, status, request_type=''):
return None
-def return_bibTex_format_export(solr_data, include_abs, keyformat, maxauthor, authorcutoff, journalformat, request_type='POST'):
+def return_bibTex_format_export(solr_data, include_abs, keyformat, max_author, author_cutoff, journal_format, request_type='POST'):
"""
:param include_abs:
@@ -69,7 +76,7 @@ def return_bibTex_format_export(solr_data, include_abs, keyformat, maxauthor, au
"""
if (solr_data is not None):
bibTex_export = BibTexFormat(solr_data, keyformat=keyformat)
- return return_response(bibTex_export.get(include_abs=include_abs, maxauthor=maxauthor, authorcutoff=authorcutoff, journalformat=journalformat),
+ return return_response(bibTex_export.get(include_abs=include_abs, max_author=max_author, author_cutoff=author_cutoff, journal_format=journal_format),
200, request_type)
return return_response({'error': 'no result from solr'}, 404)
@@ -164,42 +171,77 @@ def return_rss_format_export(solr_data, link, request_type='POST'):
return return_response({'error': 'no result from solr'}, 404)
-def read_value_list_or_not(payload, field):
+def get_payload(request):
"""
+
+ :param request:
+ :return:
+ """
+ try:
+ payload = request.get_json(force=True) # post data in json
+ except:
+ payload = dict(request.form) # post data in form encoding
+
+ if not payload:
+ return {'error': 'no information received'}, 400
+ if 'bibcode' not in payload:
+ return {'error': 'no bibcode found in payload (parameter name is `bibcode`)'}, 400
+
+ return {'payload': payload}, 200
+
+def get_a_payload_value(payload, key):
+ """
+
+ :param payload:
+ :param key:
+ :return:
+ """
+ if type(payload[key]) is list:
+ return payload[key][0]
+ return payload[key]
+
+def get_export_journal_format_from_payload(payload):
+ """
+ local method to read journal format parameter
+ 1: Use AASTeX macros (default)
+ 2: Use Journal Abbreviations
+ 3: Use Full Journal Name
:param payload:
- :param field:
:return:
"""
- if type(payload[field]) is list:
- return payload[field][0]
- return payload[field]
+ if 'journalformat' in payload:
+ journal_format = get_a_payload_value(payload, 'journalformat')
+ if not adsJournalFormat().verify(journal_format):
+ journal_format = adsJournalFormat.default
+ else:
+ journal_format = adsJournalFormat.default
+ return journal_format
-def export_post(request, style, format=-1):
+def export_post_payload_base(payload, style, format=-1):
"""
- :param request:
+ :param payload:
:param style:
:param format:
:return:
"""
- try:
- payload = request.get_json(force=True) # post data in json
- except:
- payload = dict(request.form) # post data in form encoding
-
- if not payload:
- return {'error': 'no information received'}, 400
- if 'bibcode' not in payload:
- return {'error': 'no bibcode found in payload (parameter name is `bibcode`)'}, 400
if 'sort' in payload:
- sort = read_value_list_or_not(payload, 'sort')
+ sort = get_a_payload_value(payload, 'sort')
else:
sort = 'date desc, bibcode desc'
+ if 'authorlimit' in payload:
+ author_limit = get_a_payload_value(payload, 'authorlimit')
+ else:
+ author_limit = 0
bibcodes = payload['bibcode']
+ # verify bibcode is a list and has at least one non empty element
+ if not isinstance(bibcodes, list) or not any(bibcodes):
+ return return_response({'error': 'at least one bibcode is needed in the list'}, 400)
+
if format == -1:
current_app.logger.info('received request with bibcodes={bibcodes} to export in {style} style using sort order={sort}'.
format(bibcodes=','.join(bibcodes), style=style, sort=sort))
@@ -211,73 +253,56 @@ def export_post(request, style, format=-1):
if current_app.config['EXPORT_SERVICE_TEST_BIBCODE_GET'] == bibcodes:
return solrdata.data, 200
- return get_solr_data(bibcodes=bibcodes, fields=default_solr_fields(), sort=sort, encode_style=adsFormatter().native_encoding(format)), 200
+ return get_solr_data(bibcodes=bibcodes, fields=default_solr_fields(author_limit), sort=sort, encode_style=adsFormatter().native_encoding(format)), 200
+
-def export_post_extras(request, style):
+def export_post_payload_BibTex(payload, style):
"""
- :param request:
+ :param payload:
:param style:
:return:
"""
- def read_journal_format_param(payload):
- """
- local method to read journal format parameter
- 1: Use AASTeX macros (default)
- 2: Use Journal Abbreviations
- 3: Use Full Journal Name
- :param payload:
- :return:
- """
- if 'journalformat' in payload:
- journalformat = read_value_list_or_not(payload, 'journalformat')
- if not adsJournalFormat().verify(journalformat):
- journalformat = adsJournalFormat.default
- else:
- journalformat = adsJournalFormat.default
- return journalformat
+ if 'maxauthor' in payload:
+ max_author = get_a_payload_value(payload, 'maxauthor')
+ if max_author < 0:
+ max_author = 0
+ elif style == 'BibTex':
+ max_author = 10
+ else:
+ # for BibTex Abs default is to display all authors and hence 0
+ max_author = 0
+ if 'keyformat' in payload:
+ keyformat = get_a_payload_value(payload, 'keyformat')
+ else:
+ keyformat = '%R'
+ if 'authorcutoff' in payload:
+ author_cutoff = get_a_payload_value(payload, 'authorcutoff')
+ if author_cutoff <= 0:
+ author_cutoff = 200
+ else:
+ author_cutoff = 200
+ journal_format = get_export_journal_format_from_payload(payload)
+ return max_author, keyformat, author_cutoff, journal_format
- try:
- payload = request.get_json(force=True) # post data in json
- except:
- payload = dict(request.form) # post data in form encoding
-
- if style in ['BibTex', 'BibTex Abs']:
- if payload:
- if 'maxauthor' in payload:
- maxauthor = read_value_list_or_not(payload, 'maxauthor')
- if maxauthor < 0:
- maxauthor = 0
- elif style == 'BibTex':
- maxauthor = 10
- else:
- # for BibTex Abs default is to display all authors and hence 0
- maxauthor = 0
- if 'keyformat' in payload:
- keyformat = read_value_list_or_not(payload, 'keyformat')
- else:
- keyformat = '%R'
- if 'authorcutoff' in payload:
- authorcutoff = read_value_list_or_not(payload, 'authorcutoff')
- if authorcutoff <= 0:
- authorcutoff = 200
- else:
- authorcutoff = 200
- journalformat = read_journal_format_param(payload)
- return maxauthor, keyformat, authorcutoff, journalformat
- return None, None, None
+def get_export_format_for_journal_style(payload, style):
+ """
- # for /cls formats default for the following 3 is to turn into macro
+ :param payload:
+ :param style:
+ :return:
+ """
+ # for the following 3 there is a param to specify if journal should be turn into the macro
if style in ['aastex', 'aspc', 'aasj']:
if payload:
- return read_journal_format_param(payload)
- return None
+ return get_export_journal_format_from_payload(payload)
+
# default for the following four is to keep the full journal name, and hence 3
if style in ['icarus', 'mnras', 'soph', 'apsj']:
return 3
-
+
return -1
@@ -311,12 +336,15 @@ def bibTex_format_export_post():
:return:
"""
- results, status = export_post(request, 'BibTex')
+ results, status = get_payload(request)
if status == 200:
- maxauthor, keyformat, authorcutoff, journalformat = export_post_extras(request, 'BibTex')
- return return_bibTex_format_export(solr_data=results, include_abs=False,
- keyformat=keyformat, maxauthor=maxauthor, authorcutoff=authorcutoff,
- journalformat=journalformat)
+ payload = results['payload']
+ results, status = export_post_payload_base(payload, 'BibTex')
+ if status == 200:
+ max_author, keyformat, author_cutoff, journal_format = export_post_payload_BibTex(payload, 'BibTex')
+ return return_bibTex_format_export(solr_data=results, include_abs=False,
+ keyformat=keyformat, max_author=max_author, author_cutoff=author_cutoff,
+ journal_format=journal_format)
return return_response(results, status)
@@ -329,7 +357,7 @@ def bibTex_format_export_get(bibcode):
:return:
"""
return return_bibTex_format_export(solr_data=export_get(bibcode, 'BibTex'), include_abs=False,
- keyformat='%R', maxauthor=10, authorcutoff=200, journalformat=1, request_type='GET')
+ keyformat='%R', max_author=10, author_cutoff=200, journal_format=1, request_type='GET')
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
@@ -339,12 +367,15 @@ def bibTex_abs_format_export_post():
:return:
"""
- results, status = export_post(request, 'BibTex Abs')
+ results, status = get_payload(request)
if status == 200:
- maxauthor, keyformat, authorcutoff, journalformat = export_post_extras(request, 'BibTex Abs')
- return return_bibTex_format_export(solr_data=results, include_abs=True,
- keyformat=keyformat, maxauthor=maxauthor, authorcutoff=authorcutoff,
- journalformat=journalformat)
+ payload = results['payload']
+ results, status = export_post_payload_base(payload, 'BibTex Abs')
+ if status == 200:
+ max_author, keyformat, author_cutoff, journal_format = export_post_payload_BibTex(payload, 'BibTex Abs')
+ return return_bibTex_format_export(solr_data=results, include_abs=True,
+ keyformat=keyformat, max_author=max_author, author_cutoff=author_cutoff,
+ journal_format=journal_format)
return return_response(results, status)
@@ -357,7 +388,7 @@ def bibTex_abs_format_export_get(bibcode):
:return:
"""
return return_bibTex_format_export(solr_data=export_get(bibcode, 'BibTex Abs'), include_abs=True,
- keyformat='%R', maxauthor=0, authorcutoff=200, journalformat=1, request_type='GET')
+ keyformat='%R', max_author=0, author_cutoff=200, journal_format=1, request_type='GET')
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
@@ -367,9 +398,11 @@ def fielded_ads_format_export_post():
:return:
"""
- results, status = export_post(request, 'ADS')
+ results, status = get_payload(request)
if status == 200:
- return return_fielded_format_export(solr_data=results, fielded_style='ADS', request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'ADS')
+ if status == 200:
+ return return_fielded_format_export(solr_data=results, fielded_style='ADS', request_type='POST')
return return_response(results, status)
@@ -391,9 +424,11 @@ def fielded_endnote_format_export_post():
:return:
"""
- results, status = export_post(request, 'EndNote')
+ results, status = get_payload(request)
if status == 200:
- return return_fielded_format_export(solr_data=results, fielded_style='EndNote', request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'EndNote')
+ if status == 200:
+ return return_fielded_format_export(solr_data=results, fielded_style='EndNote', request_type='POST')
return return_response(results, status)
@@ -415,9 +450,11 @@ def fielded_procite_format_export_post():
:return:
"""
- results, status = export_post(request, 'ProCite')
+ results, status = get_payload(request)
if status == 200:
- return return_fielded_format_export(solr_data=results, fielded_style='ProCite', request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'ProCite')
+ if status == 200:
+ return return_fielded_format_export(solr_data=results, fielded_style='ProCite', request_type='POST')
return return_response(results, status)
@@ -439,9 +476,11 @@ def fielded_refman_format_export_post():
:return:
"""
- results, status = export_post(request, 'Refman')
+ results, status = get_payload(request)
if status == 200:
- return return_fielded_format_export(solr_data=results, fielded_style='Refman', request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'Refman')
+ if status == 200:
+ return return_fielded_format_export(solr_data=results, fielded_style='Refman', request_type='POST')
return return_response(results, status)
@@ -463,9 +502,11 @@ def fielded_refworks_format_export_post():
:return:
"""
- results, status = export_post(request, 'RefWorks')
+ results, status = get_payload(request)
if status == 200:
- return return_fielded_format_export(solr_data=results, fielded_style='RefWorks', request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'RefWorks')
+ if status == 200:
+ return return_fielded_format_export(solr_data=results, fielded_style='RefWorks', request_type='POST')
return return_response(results, status)
@@ -487,9 +528,11 @@ def fielded_medlars_format_export_post():
:return:
"""
- results, status = export_post(request, 'MEDLARS')
+ results, status = get_payload(request)
if status == 200:
- return return_fielded_format_export(solr_data=results, fielded_style='MEDLARS', request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'MEDLARS')
+ if status == 200:
+ return return_fielded_format_export(solr_data=results, fielded_style='MEDLARS', request_type='POST')
return return_response(results, status)
@@ -511,9 +554,11 @@ def xml_dublincore_format_export_post():
:return:
"""
- results, status = export_post(request, 'DublinCore')
+ results, status = get_payload(request)
if status == 200:
- return return_xml_format_export(solr_data=results, xml_style='DublinCore')
+ results, status = export_post_payload_base(results['payload'], 'DublinCore')
+ if status == 200:
+ return return_xml_format_export(solr_data=results, xml_style='DublinCore')
return return_response(results, status)
@@ -535,9 +580,11 @@ def xml_ref_format_export_post():
:return:
"""
- results, status = export_post(request, 'Reference')
+ results, status = get_payload(request)
if status == 200:
- return return_xml_format_export(solr_data=results, xml_style='Reference')
+ results, status = export_post_payload_base(results['payload'], 'Reference')
+ if status == 200:
+ return return_xml_format_export(solr_data=results, xml_style='Reference')
return return_response(results, status)
@@ -559,9 +606,11 @@ def xml_refabs_format_export_post():
:return:
"""
- results, status = export_post(request, 'ReferenceAbs')
+ results, status = get_payload(request)
if status == 200:
- return return_xml_format_export(solr_data=results, xml_style='ReferenceAbs')
+ results, status = export_post_payload_base(results['payload'], 'ReferenceAbs')
+ if status == 200:
+ return return_xml_format_export(solr_data=results, xml_style='ReferenceAbs')
return return_response(results, status)
@@ -583,9 +632,11 @@ def xml_jats_format_export_post():
:return:
"""
- results, status = export_post(request, 'JATS')
+ results, status = get_payload(request)
if status == 200:
- return return_xml_format_export(solr_data=results, xml_style='JATS')
+ results, status = export_post_payload_base(results['payload'], 'JATS')
+ if status == 200:
+ return return_xml_format_export(solr_data=results, xml_style='JATS')
return return_response(results, status)
@@ -607,12 +658,15 @@ def csl_aastex_format_export_post():
:return:
"""
- results, status = export_post(request, 'aastex', 2)
+ results, status = get_payload(request)
if status == 200:
- journal_format = export_post_extras(request, 'aastex')
- return return_csl_format_export(solr_data=results,
- csl_style='aastex', export_format=adsFormatter.latex, journal_format=journal_format,
- request_type='POST')
+ payload = results['payload']
+ results, status = export_post_payload_base(payload, 'aastex', 2)
+ if status == 200:
+ journal_format = get_export_journal_format_from_payload(payload)
+ return return_csl_format_export(solr_data=results,
+ csl_style='aastex', export_format=adsFormatter.latex, journal_format=journal_format,
+ request_type='POST')
return return_response(results, status)
@@ -635,10 +689,12 @@ def csl_icarus_format_export_post():
:return:
"""
- results, status = export_post(request, 'icarus', 2)
+ results, status = get_payload(request)
if status == 200:
- return return_csl_format_export(solr_data=results,
- csl_style='icarus', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'icarus', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='icarus', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
return return_response(results, status)
@@ -661,10 +717,12 @@ def csl_mnras_format_export_post():
:return:
"""
- results, status = export_post(request, 'mnras', 2)
+ results, status = get_payload(request)
if status == 200:
- return return_csl_format_export(solr_data=results,
- csl_style='mnras', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'mnras', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='mnras', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
return return_response(results, status)
@@ -687,10 +745,12 @@ def csl_soph_format_export_post():
:return:
"""
- results, status = export_post(request, 'soph', 2)
+ results, status = get_payload(request)
if status == 200:
- return return_csl_format_export(solr_data=results,
- csl_style='soph', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'soph', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='soph', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
return return_response(results, status)
@@ -707,173 +767,319 @@ def csl_soph_format_export_get(bibcode):
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/csl', methods=['POST'])
-def csl_format_export():
- try:
- payload = request.get_json(force=True) # post data in json
- except:
- payload = dict(request.form) # post data in form encoding
+@bp.route('/aspc', methods=['POST'])
+def csl_aspc_format_export_post():
+ """
- if not payload:
- return return_response({'error': 'no information received'}, 400)
- if 'bibcode' not in payload:
- return return_response({'error': 'no bibcode found in payload (parameter name is `bibcode`)'}, 400)
- if 'style' not in payload:
- return return_response({'error': 'no style found in payload (parameter name is `style`)'}, 400)
- if 'format' not in payload:
- return return_response({'error': 'no output format found in payload (parameter name is `format`)'}, 400)
- if 'sort' in payload:
- sort = read_value_list_or_not(payload, 'sort')
- else:
- sort = 'date desc, bibcode desc'
+ :return:
+ """
+ results, status = get_payload(request)
+ if status == 200:
+ results, status = export_post_payload_base(results['payload'], 'aspc', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='aspc', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
+ return return_response(results, status)
- bibcodes = payload['bibcode']
- csl_style = payload['style']
- export_format = payload['format']
- if (len(bibcodes) == 0) or (len(csl_style) == 0) or (export_format == None):
- return return_response({'error': 'not all the needed information received'}, 400)
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/aspc/', methods=['GET'])
+def csl_aspc_format_export_get(bibcode):
+ """
+
+ :param bibcode:
+ :return:
+ """
+ return return_csl_format_export(solr_data=export_get(bibcode, 'aspc', 2),
+ csl_style='aspc', export_format=adsFormatter.latex, journal_format=3, request_type='GET')
- if (not adsCSLStyle().verify(csl_style)):
- return return_response({'error': 'unrecognizable style (supprted formats are: ' + adsCSLStyle().get() + ')'}, 400)
- if (not adsFormatter().verify(export_format)):
- return return_response({'error': 'unrecognizable format (supprted formats are: unicode=1, html=2, latex=3)'}, 400)
- current_app.logger.info('received request with bibcodes={bibcodes} to export in {csl_style} style with output format {export_format} style using sort order={sort}'.
- format(bibcodes=','.join(bibcodes), csl_style=csl_style, export_format=export_format, sort=sort))
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/aasj', methods=['POST'])
+def csl_aasj_format_export_post():
+ """
- solr_data = get_solr_data(bibcodes=bibcodes, fields=default_solr_fields(), sort=sort, encode_style=export_format)
- journal_format = export_post_extras(request, csl_style)
- return return_csl_format_export(solr_data, csl_style, export_format, journal_format)
+ :return:
+ """
+ results, status = get_payload(request)
+ if status == 200:
+ results, status = export_post_payload_base(results['payload'], 'aasj', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='aasj', export_format=adsFormatter.latex, journal_format=adsJournalFormat.full, request_type='POST')
+ return return_response(results, status)
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/custom', methods=['POST'])
-def custom_format_export():
- try:
- payload = request.get_json(force=True) # post data in json
- except:
- payload = dict(request.form) # post data in form encoding
+@bp.route('/aasj/', methods=['GET'])
+def csl_aasj_format_export_get(bibcode):
+ """
- if not payload:
- return return_response({'error': 'no information received'}, 400)
- if 'bibcode' not in payload:
- return return_response({'error': 'no bibcode found in payload (parameter name is `bibcode`)'}, 400)
- if 'format' not in payload:
- return return_response({'error': 'no custom format found in payload (parameter name is `format`)'}, 400)
- if 'sort' in payload:
- sort = read_value_list_or_not(payload, 'sort')
- else:
- sort = 'date desc, bibcode desc'
+ :param bibcode:
+ :return:
+ """
+ return return_csl_format_export(solr_data=export_get(bibcode, 'aasj', 2),
+ csl_style='aasj', export_format=adsFormatter.latex, journal_format=3, request_type='GET')
- bibcodes = payload['bibcode']
- try:
- custom_format_str = read_value_list_or_not(payload, 'format')
- except Exception as e:
- return return_response({'error': 'unable to read custom format'}, 400)
- current_app.logger.info('received request with bibcodes={bibcodes} to export in a custom format: {custom_format_str} style using sort order={sort}'.
- format(bibcodes=','.join(bibcodes), custom_format_str=custom_format_str.encode('utf8'), sort=sort))
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/apsj', methods=['POST'])
+def csl_apsj_format_export_post():
+ """
- if (len(bibcodes) == 0) or (len(custom_format_str) == 0):
- return return_response({'error': 'not all the needed information received'}, 400)
+ :return:
+ """
+ results, status = get_payload(request)
+ if status == 200:
+ results, status = export_post_payload_base(results['payload'], 'apsj', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='apsj', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='POST')
+ return return_response(results, status)
- # pass the user defined format to CustomFormat to parse and we would be able to get which fields
- # in Solr we need to query on
- custom_export = CustomFormat(custom_format=custom_format_str)
- fields = custom_export.get_solr_fields()
- # now get the required data from Solr and send it to customFormat for formatting
- solr_data = get_solr_data(bibcodes=bibcodes, fields=fields, sort=sort)
- if (solr_data is not None):
- if ('error' in solr_data):
- return return_response({'error': 'unable to query solr'}, 400)
- custom_export.set_json_from_solr(solr_data)
- return return_response(custom_export.get(), 200, 'POST')
- return return_response({'error': 'no result from solr'}, 404)
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/apsj/', methods=['GET'])
+def csl_apsj_format_export_get(bibcode):
+ """
+
+ :param bibcode:
+ :return:
+ """
+ return return_csl_format_export(solr_data=export_get(bibcode, 'apsj', 2),
+ csl_style='apsj', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='GET')
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/votable', methods=['POST'])
-def votable_format_export_post():
+@bp.route('/ieee', methods=['POST'])
+def csl_ieee_format_export_post():
"""
:return:
"""
- results, status = export_post(request, 'VOTable')
+ results, status = get_payload(request)
if status == 200:
- return return_votable_format_export(solr_data=results, request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'ieee', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='ieee', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='POST')
return return_response(results, status)
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/votable/', methods=['GET'])
-def votable_format_export_get(bibcode):
+@bp.route('/ieee/', methods=['GET'])
+def csl_ieee_format_export_get(bibcode):
"""
:param bibcode:
:return:
"""
- return return_votable_format_export(solr_data=export_get(bibcode, 'VOTable'), request_type='GET')
+ return return_csl_format_export(solr_data=export_get(bibcode, 'ieee', 2),
+ csl_style='ieee', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='GET')
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/rss', methods=['POST'])
-def rss_format_export_post():
+@bp.route('/agu', methods=['POST'])
+def csl_agu_format_export_post():
"""
:return:
"""
- try:
- payload = request.get_json(force=True) # post data in json
- except:
- payload = dict(request.form) # post data in form encoding
+ results, status = get_payload(request)
+ if status == 200:
+ results, status = export_post_payload_base(results['payload'], 'agu', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='agu', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='POST')
+ return return_response(results, status)
- if 'link' in payload:
- link = read_value_list_or_not(payload, 'link')
- else:
- link = ''
- results, status = export_post(request, 'RSS')
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/agu/', methods=['GET'])
+def csl_agu_format_export_get(bibcode):
+ """
+
+ :param bibcode:
+ :return:
+ """
+ return return_csl_format_export(solr_data=export_get(bibcode, 'agu', 2),
+ csl_style='agu', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='GET')
+
+
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/gsa', methods=['POST'])
+def csl_gsa_format_export_post():
+ """
+
+ :return:
+ """
+ results, status = get_payload(request)
if status == 200:
- return return_rss_format_export(solr_data=results, link=link)
+ results, status = export_post_payload_base(results['payload'], 'gsa', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='gsa', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='POST')
return return_response(results, status)
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/rss//', defaults={'link': ''}, methods=['GET'])
-@bp.route('/rss//', methods=['GET'])
-def rss_format_export_get(bibcode, link):
+@bp.route('/gsa/', methods=['GET'])
+def csl_gsa_format_export_get(bibcode):
"""
:param bibcode:
- :param link:
:return:
"""
- return return_rss_format_export(solr_data=export_get(bibcode, 'RSS'), link=link, request_type='GET')
+ return return_csl_format_export(solr_data=export_get(bibcode, 'gsa', 2),
+ csl_style='gsa', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='GET')
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/ieee', methods=['POST'])
-def csl_ieee_format_export_post():
+@bp.route('/ams', methods=['POST'])
+def csl_ams_format_export_post():
"""
:return:
"""
- results, status = export_post(request, 'ieee', 2)
+ results, status = get_payload(request)
if status == 200:
- return return_csl_format_export(solr_data=results,
- csl_style='ieee', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='POST')
+ results, status = export_post_payload_base(results['payload'], 'ams', 2)
+ if status == 200:
+ return return_csl_format_export(solr_data=results,
+ csl_style='ams', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='POST')
return return_response(results, status)
@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
-@bp.route('/ieee/', methods=['GET'])
-def csl_ieee_format_export_get(bibcode):
+@bp.route('/ams/', methods=['GET'])
+def csl_ams_format_export_get(bibcode):
"""
:param bibcode:
:return:
"""
- return return_csl_format_export(solr_data=export_get(bibcode, 'ieee', 2),
- csl_style='ieee', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='GET')
+ return return_csl_format_export(solr_data=export_get(bibcode, 'ams', 2),
+ csl_style='ams', export_format=adsFormatter.unicode, journal_format=adsJournalFormat.full, request_type='GET')
+
+
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/csl', methods=['POST'])
+def csl_format_export():
+ """
+
+ :return:
+ """
+ results, status = get_payload(request)
+ if status == 200:
+ payload = results['payload']
+
+ if 'style' not in payload:
+ return return_response({'error': 'no style found in payload (parameter name is `style`)'}, 400)
+ if 'format' not in payload:
+ return return_response({'error': 'no output format found in payload (parameter name is `format`)'}, 400)
+
+ csl_style = payload['style']
+ export_format = payload['format']
+
+ if (not adsCSLStyle().verify(csl_style)):
+ return return_response({'error': 'unrecognizable style (supprted formats are: ' + adsCSLStyle().get() + ')'}, 400)
+ if (not adsFormatter().verify(export_format)):
+ return return_response({'error': 'unrecognizable format (supprted formats are: unicode=1, html=2, latex=3)'}, 400)
+
+ results, status = export_post_payload_base(payload, csl_style, export_format)
+ if status == 200:
+ export_journal_format = get_export_format_for_journal_style(payload, csl_style)
+ return return_csl_format_export(results, csl_style, export_format, export_journal_format)
+
+ return return_response(results, status)
+
+
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/custom', methods=['POST'])
+def custom_format_export():
+ """
+
+ :return:
+ """
+ results, status = get_payload(request)
+ if status == 200:
+ payload = results['payload']
+
+ if 'format' not in payload:
+ return return_response({'error': 'no custom format found in payload (parameter name is `format`)'}, 400)
+
+ custom_format_str = get_a_payload_value(payload, 'format')
+
+ if (len(custom_format_str) == 0):
+ return return_response({'error': 'invalid custom format'}, 400)
+
+ # pass the user defined format to CustomFormat to parse and we would be able to get which fields
+ # in Solr we need to query on
+ custom_export = CustomFormat(custom_format=custom_format_str)
+ fields = custom_export.get_solr_fields()
+
+ results, status = export_post_payload_base(payload, 'custom')
+ if status == 200:
+ custom_export.set_json_from_solr(results)
+ return return_response(custom_export.get(), 200, 'POST')
+
+ return return_response(results, status)
+
+
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/votable', methods=['POST'])
+def votable_format_export_post():
+ """
+
+ :return:
+ """
+ results, status = get_payload(request)
+ if status == 200:
+ results, status = export_post_payload_base(results['payload'], 'VOTable')
+ if status == 200:
+ return return_votable_format_export(solr_data=results, request_type='POST')
+ return return_response(results, status)
+
+
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/votable/', methods=['GET'])
+def votable_format_export_get(bibcode):
+ """
+
+ :param bibcode:
+ :return:
+ """
+ return return_votable_format_export(solr_data=export_get(bibcode, 'VOTable'), request_type='GET')
+
+
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/rss', methods=['POST'])
+def rss_format_export_post():
+ """
+
+ :return:
+ """
+ results, status = get_payload(request)
+ if status == 200:
+ payload = results['payload']
+ results, status = export_post_payload_base(payload, 'RSS')
+ if status == 200:
+ if 'link' in payload:
+ link = get_a_payload_value(payload, 'link')
+ else:
+ link = ''
+ return return_rss_format_export(solr_data=results, link=link)
+ return return_response(results, status)
+
+
+@advertise(scopes=[], rate_limit=[1000, 3600 * 24])
+@bp.route('/rss//', defaults={'link': ''}, methods=['GET'])
+@bp.route('/rss//', methods=['GET'])
+def rss_format_export_get(bibcode, link):
+ """
+
+ :param bibcode:
+ :param link:
+ :return:
+ """
+ return return_rss_format_export(solr_data=export_get(bibcode, 'RSS'), link=link, request_type='GET')