def editEntry(entry, file_id='both'): bibtex = backend.getBibtex(entry, file_id) if bibtex is False: tools.warning("Entry "+entry+" does not exist.") return False if file_id == 'file': filename = entry else: filename = bibtex['file'] new_bibtex = checkBibtex(filename, tools.parsed2Bibtex(bibtex)) # Tag update if new_bibtex['tag'] != bibtex['tag']: print("Editing tag, moving file.") new_name = backend.getNewName(new_bibtex['file'], new_bibtex, new_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 new_bibtex['file'] = new_name try: shutil.move(bibtex['file'], new_bibtex['file']) except shutil.Error: tools.warning('Unable to move file '+bibtex['file']+' to ' + new_bibtex['file'] + ' according to tag edit.') try: if not os.listdir(os.path.dirname(bibtex['file'])): os.rmdir(os.path.dirname(bibtex['file'])) except OSError: tools.warning("Unable to delete empty tag dir " + os.path.dirname(bibtex['file'])) try: with open(config.get("folder")+'index.bib', 'r', encoding='utf-8') \ as fh: index = BibTexParser(fh.read()) index = index.get_entry_dict() except (TypeError, IOError): tools.warning("Unable to open index file.") return False index[new_bibtex['id']] = new_bibtex backend.bibtexRewrite(index) return True
def editEntry(entry, file_id='both'): bibtex = backend.getBibtex(entry, file_id) if bibtex is False: tools.warning("Entry " + entry + " does not exist.") return False if file_id == 'file': filename = entry else: filename = bibtex['file'] new_bibtex = checkBibtex(filename, tools.parsed2Bibtex(bibtex)) # Tag update if new_bibtex['tag'] != bibtex['tag']: print("Editing tag, moving file.") new_name = backend.getNewName(new_bibtex['file'], new_bibtex, new_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 new_bibtex['file'] = new_name try: shutil.move(bibtex['file'], new_bibtex['file']) except shutil.Error: tools.warning('Unable to move file ' + bibtex['file'] + ' to ' + new_bibtex['file'] + ' according to tag edit.') try: if not os.listdir(os.path.dirname(bibtex['file'])): os.rmdir(os.path.dirname(bibtex['file'])) except OSError: tools.warning("Unable to delete empty tag dir " + os.path.dirname(bibtex['file'])) try: with open(config.get("folder")+'index.bib', 'r', encoding='utf-8') \ as fh: index = bibtexparser.load(fh) index = index.entries_dict except (TypeError, IOError): tools.warning("Unable to open index file.") return False index[new_bibtex['id']] = new_bibtex backend.bibtexRewrite(index) return True
def bibtexAppend(data): """Append data to the main bibtex file data is a dict for one entry in bibtex, as the one from bibtexparser output """ try: with open(config.get("folder")+'index.bib', 'a', encoding='utf-8') \ as fh: fh.write(tools.parsed2Bibtex(data)+"\n") except IOError as e: raise e tools.warning("Unable to open index file.") return False
def bibtexAppend(data): """Append data to the main bibtex file data is a dict for one entry in bibtex, as the one from bibtexparser output """ try: with open(config.get("folder")+'index.bib', 'a', encoding='utf-8') \ as fh: fh.write(tools.parsed2Bibtex(data) + "\n") except IOError as e: raise e tools.warning("Unable to open index file.") return False
def bibtexRewrite(data): """Rewrite the bibtex index file. data is a dict of bibtex entry dict. """ bibtex = '' for entry in data.keys(): bibtex += tools.parsed2Bibtex(data[entry])+"\n" try: with open(config.get("folder")+'index.bib', 'w', encoding='utf-8') \ as fh: fh.write(bibtex) except (IOError, TypeError): tools.warning("Unable to open index file.") return False
def bibtexRewrite(data): """Rewrite the bibtex index file. data is a dict of bibtex entry dict. """ bibtex = '' for entry in data.keys(): bibtex += tools.parsed2Bibtex(data[entry]) + "\n" try: with open(config.get("folder")+'index.bib', 'w', encoding='utf-8') \ as fh: fh.write(bibtex) except (IOError, TypeError): tools.warning("Unable to open index file.") return False
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 ''
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.loads(bib.bibtex()) fetched_bibtex = fetched_bibtex.entries_dict fetched_bibtex = fetched_bibtex[list(fetched_bibtex.keys())[0]] try: del(fetched_bibtex['file']) except KeyError: pass return tools.parsed2Bibtex(fetched_bibtex) return ''
def addFile(src, filetype, manual, autoconfirm, tag, rename=True): """ 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.loads(bibtex) bibtex = bibtex.entries_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 if rename: 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 try: shutil.copy2(src, new_name) except shutil.Error: new_name = False sys.exit("Unable to move file to library dir " + config.get("folder") + ".") else: new_name = src bibtex['file'] = os.path.abspath(new_name) # 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
def checkBibtex(filename, bibtex_string): print("The bibtex entry found for " + filename + " is:") bibtex = bibtexparser.loads(bibtex_string) bibtex = bibtex.entries_dict try: bibtex = bibtex[list(bibtex.keys())[0]] # Check entries are correct if "title" not in bibtex: raise AssertionError if "authors" not in bibtex and "author" not in bibtex: raise AssertionError if "year" not in bibtex: raise AssertionError # 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): print("Missing author, year or title in bibtex.") 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.loads(tmpfile.read().decode('utf-8') + "\n") bibtex = bibtex.entries_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
sys.exit() elif args.func == 'search': raise Exception('TODO') elif args.func == 'open': for filename in args.ids: if not openFile(filename): sys.exit("Unable to open file associated " + "to ident " + filename) sys.exit() elif args.func == 'export': bibtex = '' for id in args.ids: bibtex += tools.parsed2Bibtex(backend.getBibtex(id, clean=True)) print(bibtex.strip()) sys.exit elif args.func == 'resync': confirm = tools.rawInput("Resync files and bibtex index? [y/N] ") if confirm.lower() == 'y': resync() sys.exit() elif args.func == 'update': if args.entries is None: entries = backend.getEntries() else: entries = args.entries for entry in entries:
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
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
print(paper) elif args.func == 'search': raise Exception('TODO') elif args.func == 'open': for filename in args.ids: if not openFile(filename): sys.exit("Unable to open file associated " + "to ident "+filename) sys.exit() elif args.func == 'export': bibtex = '' for id in args.ids: bibtex += tools.parsed2Bibtex(backend.getBibtex(id, clean=True)) print(bibtex.strip()) sys.exit elif args.func == 'resync': confirm = tools.rawInput("Resync files and bibtex index? [y/N] ") if confirm.lower() == 'y': resync() sys.exit() elif args.func == 'update': if args.entries is None: entries = backend.getEntries() else: entries = args.entries for entry in entries: