|
|
|
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)
|