Exemple #1
0
def updateArXiv(entry):
    """Look for new versions of arXiv entry `entry`

    Returns False if no new versions or not an arXiv entry,
    Returns the new bibtex otherwise.
    """
    bibtex = getBibtex(entry)
    # Check arXiv
    if('archiveprefix' not in bibtex or
       'arXiv' not in bibtex['archiveprefix']):
        return False

    arxiv_id = bibtex['eprint']
    arxiv_id_no_v = re.sub(r'v\d+\Z', '', arxiv_id)
    ids = set(arxiv_id)

    for entry in getEntries():
        if('archiveprefix' not in bibtex or
           'arXiv' not in bibtex['archiveprefix']):
            continue
        ids.add(bibtex['eprint'])

    last_bibtex = BibTexParser(fetcher.arXiv2Bib(arxiv_id_no_v))
    last_bibtex = last_bibtex.get_entry_dict()
    last_bibtex = last_bibtex[list(last_bibtex.keys())[0]]

    if last_bibtex['eprint'] not in ids:
        return last_bibtex
    else:
        return False
Exemple #2
0
def getBibtex(entry, file_id='both', clean=False):
    """Returns the bibtex entry corresponding to entry, as a dict

    entry is either a filename or a bibtex ident
    file_id is file or id or both to search for a file / id / both
    clean is to clean the ignored fields specified in config
    """
    try:
        with open(config.get("folder")+'index.bib', 'r', encoding='utf-8') \
                as fh:
            bibtex = BibTexParser(fh.read())
        bibtex = bibtex.get_entry_dict()
    except (TypeError, IOError):
        tools.warning("Unable to open index file.")
        return False

    bibtex_entry = False
    if file_id == 'both' or file_id == 'id':
        try:
            bibtex_entry = bibtex[entry]
        except KeyError:
            pass
    if file_id == 'both' or file_id == 'file':
        if os.path.isfile(entry):
            for key in bibtex.keys():
                if os.path.samefile(bibtex[key]['file'], entry):
                    bibtex_entry = bibtex[key]
                    break
    if clean:
        for field in config.get("ignore_fields"):
            try:
                del(bibtex_entry[field])
            except KeyError:
                pass
    return bibtex_entry
Exemple #3
0
def deleteId(ident):
    """Delete a file based on its id in the bibtex file"""
    try:
        with open(config.get("folder")+'index.bib', 'r', encoding='utf-8') \
                as fh:
            bibtex = BibTexParser(fh.read())
        bibtex = bibtex.get_entry_dict()
    except (IOError, TypeError):
        tools.warning("Unable to open index file.")
        return False

    if ident not in bibtex.keys():
        return False

    try:
        os.remove(bibtex[ident]['file'])
    except (KeyError, OSError):
        tools.warning("Unable to delete file associated to id "+ident+" : " +
                      bibtex[ident]['file'])

    try:
        if not os.listdir(os.path.dirname(bibtex[ident]['file'])):
            os.rmdir(os.path.dirname(bibtex[ident]['file']))
    except (KeyError, OSError):
        tools.warning("Unable to delete empty tag dir " +
                      os.path.dirname(bibtex[ident]['file']))

    try:
        del(bibtex[ident])
        bibtexRewrite(bibtex)
    except KeyError:
        tools.warning("No associated bibtex entry in index for file " +
                      bibtex[ident]['file'])
    return True
Exemple #4
0
def getEntries():
    """Returns the list of all entries in the bibtex index"""
    try:
        with open(config.get("folder")+'index.bib', 'r', encoding='utf-8') \
                as fh:
            bibtex = BibTexParser(fh.read())
        bibtex = bibtex.get_entry_dict()
    except (TypeError, IOError):
        tools.warning("Unable to open index file.")
        return False

    return list(bibtex.keys())
Exemple #5
0
def openFile(ident):
    try:
        with open(config.get("folder")+'index.bib', 'r', encoding='utf-8') \
                as fh:
            bibtex = BibTexParser(fh.read())
        bibtex = bibtex.get_entry_dict()
    except (TypeError, IOError):
        tools.warning("Unable to open index file.")
        return False

    if ident not in list(bibtex.keys()):
        return False
    else:
        subprocess.Popen(['xdg-open', bibtex[ident]['file']])
        return True
Exemple #6
0
def arXiv2Bib(arxiv):
    """Returns bibTeX string of metadata for a given arXiv id

    arxiv is an arxiv id
    """
    bibtex = arxiv_metadata.arxiv2bib([arxiv])
    for bib in bibtex:
        if isinstance(bib, arxiv_metadata.ReferenceErrorInfo):
            continue
        else:
            fetched_bibtex = BibTexParser(bib.bibtex())
            fetched_bibtex = fetched_bibtex.get_entry_dict()
            fetched_bibtex = fetched_bibtex[list(fetched_bibtex.keys())[0]]
            try:
                del(fetched_bibtex['file'])
            except KeyError:
                pass
            return tools.parsed2Bibtex(fetched_bibtex)
    return ''
Exemple #7
0
def deleteFile(filename):
    """Delete a file based on its filename"""
    try:
        with open(config.get("folder")+'index.bib', 'r', encoding='utf-8') \
                as fh:
            bibtex = BibTexParser(fh.read())
        bibtex = bibtex.get_entry_dict()
    except (TypeError, IOError):
        tools.warning("Unable to open index file.")
        return False

    found = False
    for key in list(bibtex.keys()):
        try:
            if os.path.samefile(bibtex[key]['file'], filename):
                found = True
                try:
                    os.remove(bibtex[key]['file'])
                except (KeyError, OSError):
                    tools.warning("Unable to delete file associated to id " +
                                  key+" : "+bibtex[key]['file'])

                try:
                    if not os.listdir(os.path.dirname(filename)):
                        os.rmdir(os.path.dirname(filename))
                except OSError:
                    tools.warning("Unable to delete empty tag dir " +
                                  os.path.dirname(filename))

                try:
                    del(bibtex[key])
                except KeyError:
                    tools.warning("No associated bibtex entry in index for " +
                                  "file " + bibtex[key]['file'])
        except (KeyError, OSError):
            pass
    if found:
        bibtexRewrite(bibtex)
    elif os.path.isfile(filename):
        os.remove(filename)
    return found
Exemple #8
0
class TestFetcher(unittest.TestCase):
    def setUp(self):
        config.set("folder", tempfile.mkdtemp()+"/")
        self.bibtex_article_string = """
@article{1303.3130v1,
        abstract={We study the role of the dipolar interaction, correctly accounting for the
Dipolar-Induced Resonance (DIR), in a quasi-one-dimensional system of ultracold
bosons. We first show how the DIR affects the lowest-energy states of two
particles in a harmonic trap. Then, we consider a deep optical lattice loaded
with ultracold dipolar bosons. We describe this many-body system using an
atom-dimer extended Bose-Hubbard model. We analyze the impact of the DIR on the
phase diagram at T=0 by exact diagonalization of a small-sized system. In
particular, the resonance strongly modifies the range of parameters for which a
mass density wave should occur.},
        archiveprefix={arXiv},
        author={N. Bartolo and D. J. Papoular and L. Barbiero and C. Menotti and A. Recati},
        eprint={1303.3130v1},
        file={%sN_Bartolo_A_Recati-j-2013.pdf},
        link={http://arxiv.org/abs/1303.3130v1},
        month={Mar},
        primaryclass={cond-mat.quant-gas},
        tag={},
        title={Dipolar-Induced Resonance for Ultracold Bosons in a Quasi-1D Optical
Lattice},
        year={2013},
}""" % config.get("folder")
        self.bibtex_article = BibTexParser(self.bibtex_article_string).get_entry_dict()
        self.bibtex_article = self.bibtex_article[list(self.bibtex_article.keys())[0]]

        self.bibtex_book_string = """
@book{9780521846516,
    author={C. J. Pethick and H. Smith},
    isbn={9780521846516},
    publisher={Cambridge University Press},
    title={Bose-Einstein Condensation In Dilute Gases},
    year={2008},
}
"""
        self.bibtex_book = BibTexParser(self.bibtex_book_string).get_entry_dict()
        self.bibtex_book = self.bibtex_book[list(self.bibtex_book.keys())[0]]

    def test_getNewName_article(self):
        self.assertEqual(getNewName("test.pdf", self.bibtex_article),
                         config.get("folder")+"N_Bartolo_A_Recati-j-2013-v1.pdf")

    def test_getNewName_article_override(self):
        self.assertEqual(getNewName("test.pdf", self.bibtex_article, override_format="%f"),
                         config.get("folder")+"N_Bartolo.pdf")

    def test_getNewName_book(self):
        self.assertEqual(getNewName("test.pdf", self.bibtex_book),
                         config.get("folder")+"C_J_Pethick_H_Smith-Bose-Einstein_Condensation_In_Dilute_Gases.pdf")

    def test_getNewName_book_override(self):
        self.assertEqual(getNewName("test.pdf", self.bibtex_book, override_format="%a"),
                         config.get("folder")+"C_J_Pethick_H_Smith.pdf")

    def test_bibtexAppend(self):
        bibtexAppend(self.bibtex_article)
        with open(config.get("folder")+'index.bib', 'r') as fh:
            self.assertEqual(fh.read(),
                             '@article{1303.3130v1,\n\tabstract={We study the role of the dipolar interaction, correctly accounting for the\nDipolar-Induced Resonance (DIR), in a quasi-one-dimensional system of ultracold\nbosons. We first show how the DIR affects the lowest-energy states of two\nparticles in a harmonic trap. Then, we consider a deep optical lattice loaded\nwith ultracold dipolar bosons. We describe this many-body system using an\natom-dimer extended Bose-Hubbard model. We analyze the impact of the DIR on the\nphase diagram at T=0 by exact diagonalization of a small-sized system. In\nparticular, the resonance strongly modifies the range of parameters for which a\nmass density wave should occur.},\n\tarchiveprefix={arXiv},\n\tauthor={N. Bartolo and D. J. Papoular and L. Barbiero and C. Menotti and A. Recati},\n\teprint={1303.3130v1},\n\tfile={'+config.get("folder")+'N_Bartolo_A_Recati-j-2013.pdf},\n\tlink={http://arxiv.org/abs/1303.3130v1},\n\tmonth={Mar},\n\tprimaryclass={cond-mat.quant-gas},\n\ttag={},\n\ttitle={Dipolar-Induced Resonance for Ultracold Bosons in a Quasi-1D Optical\nLattice},\n\tyear={2013},\n}\n\n\n')

    def test_bibtexEdit(self):
        bibtexAppend(self.bibtex_article)
        bibtexEdit(self.bibtex_article['id'], {'id': 'bidule'})
        with open(config.get("folder")+'index.bib', 'r') as fh:
            self.assertEqual(fh.read(),
                             '@article{bidule,\n\tabstract={We study the role of the dipolar interaction, correctly accounting for the\nDipolar-Induced Resonance (DIR), in a quasi-one-dimensional system of ultracold\nbosons. We first show how the DIR affects the lowest-energy states of two\nparticles in a harmonic trap. Then, we consider a deep optical lattice loaded\nwith ultracold dipolar bosons. We describe this many-body system using an\natom-dimer extended Bose-Hubbard model. We analyze the impact of the DIR on the\nphase diagram at T=0 by exact diagonalization of a small-sized system. In\nparticular, the resonance strongly modifies the range of parameters for which a\nmass density wave should occur.},\n\tarchiveprefix={arXiv},\n\tauthor={N. Bartolo and D. J. Papoular and L. Barbiero and C. Menotti and A. Recati},\n\teprint={1303.3130v1},\n\tfile={'+config.get("folder")+'N_Bartolo_A_Recati-j-2013.pdf},\n\tlink={http://arxiv.org/abs/1303.3130v1},\n\tmonth={Mar},\n\tprimaryclass={cond-mat.quant-gas},\n\ttag={},\n\ttitle={Dipolar-Induced Resonance for Ultracold Bosons in a Quasi-1D Optical\nLattice},\n\tyear={2013},\n}\n\n\n')

    def test_bibtexRewrite(self):
        bibtexAppend(self.bibtex_book)
        bibtexRewrite({0: self.bibtex_article})
        with open(config.get("folder")+'index.bib', 'r') as fh:
            self.assertEqual(fh.read(),
                             '@article{1303.3130v1,\n\tabstract={We study the role of the dipolar interaction, correctly accounting for the\nDipolar-Induced Resonance (DIR), in a quasi-one-dimensional system of ultracold\nbosons. We first show how the DIR affects the lowest-energy states of two\nparticles in a harmonic trap. Then, we consider a deep optical lattice loaded\nwith ultracold dipolar bosons. We describe this many-body system using an\natom-dimer extended Bose-Hubbard model. We analyze the impact of the DIR on the\nphase diagram at T=0 by exact diagonalization of a small-sized system. In\nparticular, the resonance strongly modifies the range of parameters for which a\nmass density wave should occur.},\n\tarchiveprefix={arXiv},\n\tauthor={N. Bartolo and D. J. Papoular and L. Barbiero and C. Menotti and A. Recati},\n\teprint={1303.3130v1},\n\tfile={%sN_Bartolo_A_Recati-j-2013.pdf},\n\tlink={http://arxiv.org/abs/1303.3130v1},\n\tmonth={Mar},\n\tprimaryclass={cond-mat.quant-gas},\n\ttag={},\n\ttitle={Dipolar-Induced Resonance for Ultracold Bosons in a Quasi-1D Optical\nLattice},\n\tyear={2013},\n}\n\n\n' % config.get("folder"))

    def test_deleteId(self):
        self.bibtex_article['file'] = config.get("folder")+'test.pdf'
        bibtexAppend(self.bibtex_article)
        open(config.get("folder")+'test.pdf', 'w').close()
        deleteId(self.bibtex_article['id'])
        with open(config.get("folder")+'index.bib', 'r') as fh:
            self.assertEqual(fh.read().strip(), "")
        self.assertFalse(os.path.isfile(config.get("folder")+'test.pdf'))

    def test_deleteFile(self):
        self.bibtex_article['file'] = config.get("folder")+'test.pdf'
        bibtexAppend(self.bibtex_article)
        open(config.get("folder")+'test.pdf', 'w').close()
        deleteFile(self.bibtex_article['file'])
        with open(config.get("folder")+'index.bib', 'r') as fh:
            self.assertEqual(fh.read().strip(), "")
        self.assertFalse(os.path.isfile(config.get("folder")+'test.pdf'))

    def test_diffFilesIndex(self):
        # TODO
        return

    def test_getBibtex(self):
        bibtexAppend(self.bibtex_article)
        got = getBibtex(self.bibtex_article['id'])
        self.assertEqual(got, self.bibtex_article)

    def test_getBibtex_id(self):
        bibtexAppend(self.bibtex_article)
        got = getBibtex(self.bibtex_article['id'], file_id='id')
        self.assertEqual(got, self.bibtex_article)

    def test_getBibtex_file(self):
        self.bibtex_article['file'] = config.get("folder")+'test.pdf'
        open(config.get("folder")+'test.pdf', 'w').close()
        bibtexAppend(self.bibtex_article)
        got = getBibtex(self.bibtex_article['file'], file_id='file')
        self.assertEqual(got, self.bibtex_article)

    def test_getBibtex_clean(self):
        config.set("ignore_fields", ['id', 'abstract'])
        bibtexAppend(self.bibtex_article)
        got = getBibtex(self.bibtex_article['id'], clean=True)
        for i in config.get("ignore_fields"):
            self.assertNotIn(i, got)

    def test_getEntries(self):
        bibtexAppend(self.bibtex_article)
        self.assertEqual(getEntries(),
                         [self.bibtex_article['id']])

    def test_updateArxiv(self):
        # TODO
        return

    def test_search(self):
        # TODO
        return

    def tearDown(self):
        shutil.rmtree(config.get("folder"))
Exemple #9
0
def addFile(src, filetype, manual, autoconfirm, tag):
    """
    Add a file to the library
    """
    doi = False
    arxiv = False
    isbn = False

    if not manual:
        try:
            if filetype == 'article' or filetype is None:
                id_type, article_id = fetcher.findArticleID(src)
                if id_type == "DOI":
                    doi = article_id
                elif id_type == "arXiv":
                    arxiv = article_id

            if filetype == 'book' or (doi is False and arxiv is False and
                                      filetype is None):
                isbn = fetcher.findISBN(src)
        except KeyboardInterrupt:
            doi = False
            arxiv = False
            isbn = False

    if doi is False and isbn is False and arxiv is False:
        if filetype is None:
            tools.warning("Could not determine the DOI nor the arXiv id nor " +
                          "the ISBN for "+src+". Switching to manual entry.")
            doi_arxiv_isbn = ''
            while(doi_arxiv_isbn not in
                  ['doi', 'arxiv', 'isbn', 'manual', 'skip']):
                doi_arxiv_isbn = (tools.rawInput("DOI / arXiv " +
                                                 "/ ISBN / manual / skip? ").
                                  lower())
            if doi_arxiv_isbn == 'doi':
                doi = tools.rawInput('DOI? ')
            elif doi_arxiv_isbn == 'arxiv':
                arxiv = tools.rawInput('arXiv id? ')
            elif doi_arxiv_isbn == 'isbn':
                isbn = tools.rawInput('ISBN? ')
            elif doi_arxiv_isbn == 'skip':
                return False
        elif filetype == 'article':
            tools.warning("Could not determine the DOI nor the arXiv id for " +
                          src+", switching to manual entry.")
            doi_arxiv = ''
            while doi_arxiv not in ['doi', 'arxiv', 'manual', 'skip']:
                doi_arxiv = (tools.rawInput("DOI / arXiv / manual / skip? ").
                             lower())
            if doi_arxiv == 'doi':
                doi = tools.rawInput('DOI? ')
            elif doi_arxiv == 'arxiv':
                arxiv = tools.rawInput('arXiv id? ')
            elif doi_arxiv == 'skip':
                return False
        elif filetype == 'book':
            isbn_manual = ''
            while isbn_manual not in ['isbn', 'manual', 'skip']:
                isbn_manual = tools.rawInput("ISBN / manual / skip? ").lower()
            if isbn_manual == 'isbn':
                isbn = (tools.rawInput('ISBN? ').
                        replace(' ', '').
                        replace('-', ''))
            elif isbn_manual == 'skip':
                return False
    elif doi is not False:
        print("DOI for "+src+" is "+doi+".")
    elif arxiv is not False:
        print("ArXiv id for "+src+" is "+arxiv+".")
    elif isbn is not False:
        print("ISBN for "+src+" is "+isbn+".")

    if doi is not False and doi != '':
        # Add extra \n for bibtexparser
        bibtex = fetcher.doi2Bib(doi).strip().replace(',', ",\n")+"\n"
    elif arxiv is not False and arxiv != '':
        bibtex = fetcher.arXiv2Bib(arxiv).strip().replace(',', ",\n")+"\n"
    elif isbn is not False and isbn != '':
        # Idem
        bibtex = fetcher.isbn2Bib(isbn).strip()+"\n"
    else:
        bibtex = ''

    bibtex = BibTexParser(bibtex)
    bibtex = bibtex.get_entry_dict()
    if len(bibtex) > 0:
        bibtex_name = list(bibtex.keys())[0]
        bibtex = bibtex[bibtex_name]
        bibtex_string = tools.parsed2Bibtex(bibtex)
    else:
        bibtex_string = ''

    if not autoconfirm:
        bibtex = checkBibtex(src, bibtex_string)

    if not autoconfirm:
        tag = tools.rawInput("Tag for this paper (leave empty for default) ? ")
    else:
        tag = args.tag
    bibtex['tag'] = tag

    new_name = backend.getNewName(src, bibtex, tag)

    while os.path.exists(new_name):
        tools.warning("file "+new_name+" already exists.")
        default_rename = new_name.replace(tools.getExtension(new_name),
                                          " (2)"+tools.getExtension(new_name))
        rename = tools.rawInput("New name ["+default_rename+"]? ")
        if rename == '':
            new_name = default_rename
        else:
            new_name = rename
    bibtex['file'] = new_name

    try:
        shutil.copy2(src, new_name)
    except shutil.Error:
        new_name = False
        sys.exit("Unable to move file to library dir " +
                 config.get("folder")+".")

    # Remove first page of IOP papers
    try:
        if 'IOP' in bibtex['publisher'] and bibtex['type'] == 'article':
            tearpages.tearpage(new_name)
    except (KeyError, shutil.Error, IOError):
        pass

    backend.bibtexAppend(bibtex)
    return new_name
Exemple #10
0
def checkBibtex(filename, bibtex_string):
    print("The bibtex entry found for "+filename+" is:")

    bibtex = BibTexParser(bibtex_string)
    bibtex = bibtex.get_entry_dict()
    try:
        bibtex = bibtex[list(bibtex.keys())[0]]
        # Check entries are correct
        assert bibtex['title']
        if bibtex['type'] == 'article':
            assert bibtex['authors']
        elif bibtex['type'] == 'book':
            assert bibtex['author']
        assert bibtex['year']
        # Print the bibtex and confirm
        print(tools.parsed2Bibtex(bibtex))
        check = tools.rawInput("Is it correct? [Y/n] ")
    except KeyboardInterrupt:
        sys.exit()
    except (IndexError, KeyError, AssertionError):
        check = 'n'

    try:
        old_filename = bibtex['file']
    except KeyError:
        old_filename = False

    while check.lower() == 'n':
        with tempfile.NamedTemporaryFile(suffix=".tmp") as tmpfile:
            tmpfile.write(bibtex_string.encode('utf-8'))
            tmpfile.flush()
            subprocess.call([EDITOR, tmpfile.name])
            tmpfile.seek(0)
            bibtex = BibTexParser(tmpfile.read().decode('utf-8')+"\n")

        bibtex = bibtex.get_entry_dict()
        try:
            bibtex = bibtex[list(bibtex.keys())[0]]
        except (IndexError, KeyError):
            tools.warning("Invalid bibtex entry")
            bibtex_string = ''
            tools.rawInput("Press Enter to go back to editor.")
            continue
        if('authors' not in bibtex and 'title' not in bibtex and 'year' not in
           bibtex):
            tools.warning("Invalid bibtex entry")
            bibtex_string = ''
            tools.rawInput("Press Enter to go back to editor.")
            continue

        if old_filename is not False and 'file' not in bibtex:
            tools.warning("Invalid bibtex entry. No filename given.")
            tools.rawInput("Press Enter to go back to editor.")
            check = 'n'
        else:
            bibtex_string = tools.parsed2Bibtex(bibtex)
            print("\nThe bibtex entry for "+filename+" is:")
            print(bibtex_string)
            check = tools.rawInput("Is it correct? [Y/n] ")
    if old_filename is not False and old_filename != bibtex['file']:
        try:
            print("Moving file to new location…")
            shutil.move(old_filename, bibtex['file'])
        except shutil.Error:
            tools.warning("Unable to move file "+old_filename+" to " +
                          bibtex['file']+". You should check it manually.")

    return bibtex