You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.3 KiB

import os
from pybtex.database import Entry, BibliographyData, FieldDict, Person
from .. import repo
from .. import endecoder
from .. import bibstruct
from .. import color
from ..paper import Paper
from ..configs import config
from ..uis import get_ui
def parser(subparsers):
parser = subparsers.add_parser('import',
help='import paper(s) to the repository')
parser.add_argument('bibpath',
help='path to bibtex, bibtexml or bibyaml file (or directory)')
parser.add_argument('-c', '--copy', action='store_true', default=None,
help="copy document files into library directory (default)")
parser.add_argument('-C', '--nocopy', action='store_false', dest='copy',
help="don't copy document files (opposite of -c)")
parser.add_argument('keys', nargs='*',
help="one or several keys to import from the file")
return parser
def many_from_path(bibpath):
"""Extract list of papers found in bibliographic files in path.
The behavior is to:
- ignore wrong entries,
- overwrite duplicated entries.
:returns: dictionary of (key, paper | exception)
if loading of entry failed, the excpetion is returned in the
dictionary in place of the paper
"""
coder = endecoder.EnDecoder()
bibpath = os.path.expanduser(bibpath)
if os.path.isdir(bibpath):
all_files = [os.path.join(bibpath, f) for f in os.listdir(bibpath)
if os.path.splitext(f)[-1][1:] in list(coder.decode_fmt.keys())]
else:
all_files = [bibpath]
biblist = []
for filepath in all_files:
with open(filepath, 'r') as f:
biblist.append(coder.decode_bibdata(f.read()))
papers = {}
for b in biblist:
for k in b.entries:
try:
bibdata = BibliographyData()
bibdata.entries[k] = b.entries[k]
papers[k] = Paper(bibdata, citekey=k)
except ValueError, e:
papers[k] = e
return papers
def command(args):
"""
:param bibpath: path (no url yet) to a bibliography file
"""
ui = get_ui()
bibpath = args.bibpath
copy = args.copy
if copy is None:
copy = config().import_copy
rp = repo.Repository(config())
# Extract papers from bib
papers = many_from_path(bibpath)
keys = args.keys or papers.keys()
for k in keys:
try:
p = papers[k]
if isinstance(p, Exception):
ui.error('could not load entry for citekey {}.'.format(k))
else:
docfile = bibstruct.extract_docfile(p.bibdata)
if docfile is None:
ui.warning("no file for {}.".format(p.citekey))
else:
copy_doc = args.copy
if copy_doc is None:
copy_doc = config().import_copy
if copy_doc:
docfile = rp.databroker.copy_doc(p.citekey, docfile)
p.docpath = docfile
rp.push_paper(p)
ui.print_('{} imported'.format(color.dye(p.citekey, color.cyan)))
except KeyError:
ui.error('no entry found for citekey {}.'.format(k))
except IOError, e:
ui.error(e.message)