diff --git a/libbmc/bibtex.py b/libbmc/bibtex.py index 57be4f5..938863d 100644 --- a/libbmc/bibtex.py +++ b/libbmc/bibtex.py @@ -1,7 +1,7 @@ """ This file contains functions to deal with Bibtex files and edit them. -TODO: Unittests +TODO: Unittests + use bibtexparser writer """ import bibtexparser import re @@ -111,7 +111,10 @@ def delete(filename, identifier): bibtex = bibtex.entries_dict # Delete the bibtex entry - del(bibtex[identifier]) + try: + del(bibtex[identifier]) + except KeyError: + pass # Write the resulting BibTeX write(filename, bibtex) @@ -140,6 +143,41 @@ def get(filename, ignore_fields=[]): return bibtex +def get_entry_by_filter(filename, filter, ignore_fields=[]): + """ + Get an entry from a BibTeX file. + + :param filename: The name of the BibTeX file. + :param filter: A function returning ``True`` or ``False`` whether the \ + entry should be included or not. + :param ignore_fields: An optional list of fields to strip from the BibTeX \ + file. + + :returns: A ``bibtexparser.BibDatabase`` object representing the \ + first matching entry. ``None`` if entry was not found. + """ + # Open bibtex file + with open(filename, 'r', encoding="utf-8") as fh: + bibtex = bibtexparser.load(fh) + bibtex = bibtex.entries + + matching_entry = None + try: + # Try to fetch the matching entry dict + for entry in bibtex.items: + if filter(entry): + matching_entry = entry + except KeyError: + # If none found, return None + return None + + # Clean the entry dict if necessary + matching_entry = {k: matching_entry[k] + for k in matching_entry if k not in ignore_fields} + + return matching_entry + + def get_entry(filename, identifier, ignore_fields=[]): """ Get an entry from a BibTeX file. @@ -149,31 +187,31 @@ def get_entry(filename, identifier, ignore_fields=[]): :param ignore_fields: An optional list of fields to strip from the BibTeX \ file. - :returns: A ``bibtexparser`` dict representing the fetched entry. \ - ``None`` if entry was not found. + :returns: A ``bibtexparser.BibDatabase`` object representing the \ + fetched entry. ``None`` if entry was not found. """ - # Open bibtex file - with open(filename, 'r', encoding="utf-8") as fh: - bibtex = bibtexparser.load(fh) - bibtex = bibtex.entries_dict - - try: - # Try to fetch the matching entry dict - entry = bibtex[identifier] - except KeyError: - # If none found, return None - return None - - # Clean the entry dict if necessary - entry = {k: entry[k] for k in entry if k not in ignore_fields} - - return entry + return get_entry_by_filter(filename, + lambda x: x["ID"] == identifier, + ignore_fields) def to_filename(bibtex, mask=default_papers_filename_mask): """ Convert a bibtex entry to a formatted filename according to a given mask. + .. note :: + + Available masks out of the box are: + - ``journal`` + - ``title`` + - ``year`` + - ``first`` for the first author + - ``last`` for the last author + - ``authors`` for the list of authors + - ``arxiv_version`` (discarded if no arXiv version in the BibTeX) + + Filename is slugified after applying the masks. + :param bibtex: A dict representing a BibTeX entry, as the one from \ ``bibtexparser`` output. :param mask: A Python format string. diff --git a/libbmc/citations/bbl.py b/libbmc/citations/bbl.py index 66c2ada..3fde99e 100644 --- a/libbmc/citations/bbl.py +++ b/libbmc/citations/bbl.py @@ -1,8 +1,6 @@ """ This files contains all the functions to extract DOIs of citations from .bbl files. - -# TODO: Unittests """ import os import re diff --git a/libbmc/citations/bibtex.py b/libbmc/citations/bibtex.py index 4441b84..4c357d8 100644 --- a/libbmc/citations/bibtex.py +++ b/libbmc/citations/bibtex.py @@ -1,8 +1,6 @@ """ This files contains all the functions to extract DOIs of citations from BibTeX files. - -# TODO: Unittests """ import bibtexparser import os diff --git a/libbmc/citations/pdf.py b/libbmc/citations/pdf.py index 68ebedd..f64baa1 100644 --- a/libbmc/citations/pdf.py +++ b/libbmc/citations/pdf.py @@ -1,8 +1,6 @@ """ This files contains all the functions to extract DOIs of citations from PDF files. - -# TODO: Unittests """ import os import requests diff --git a/libbmc/citations/plaintext.py b/libbmc/citations/plaintext.py index 8f1ad32..bdd4f19 100644 --- a/libbmc/citations/plaintext.py +++ b/libbmc/citations/plaintext.py @@ -1,8 +1,6 @@ """ This files contains all the functions to extract DOIs of citations from plaintext files. - -# TODO: Unittests """ import os import requests diff --git a/libbmc/repositories/arxiv.py b/libbmc/repositories/arxiv.py index 1b0b97c..bea7f1f 100644 --- a/libbmc/repositories/arxiv.py +++ b/libbmc/repositories/arxiv.py @@ -443,8 +443,6 @@ def get_sources(arxiv_id): canonical form. :returns: A ``TarFile`` object of the sources of the arXiv preprint or \ ``None``. - - # TODO: Unittests """ try: r = requests.get(ARXIV_EPRINT_URL.format(arxiv_id=arxiv_id)) @@ -468,8 +466,6 @@ def get_bbl(arxiv_id): a canonical form. :returns: A list of the full text of the ``.bbl`` files (if any) \ or ``None``. - - # TODO: Unittests """ tf = get_sources(arxiv_id) bbl_files = [i for i in tf.getmembers() if i.name.endswith(".bbl")] @@ -490,9 +486,6 @@ def get_citations(arxiv_id): :param arxiv_id: The arXiv id (e.g. ``1401.2910`` or ``1401.2910v1``) in \ a canonical form. :returns: A dict of cleaned plaintext citations and their associated DOI. - - >>> get_citations("1401.2910") - # TODO: Unittests """ dois = {} # Get the list of bbl files for this preprint