Adds command to add multiple reference at once.
Also fixes a few bugs.
This commit is contained in:
parent
a1e69cdf61
commit
655fb25bfa
@ -1,5 +1,6 @@
|
|||||||
import add_cmd
|
import add_cmd
|
||||||
|
import add_library_cmd
|
||||||
import init_cmd
|
import init_cmd
|
||||||
import list_cmd
|
import list_cmd
|
||||||
import open_cmd
|
import open_cmd
|
||||||
import websearch_cmd
|
import websearch_cmd
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
import os
|
|
||||||
try:
|
|
||||||
import ConfigParser as configparser
|
|
||||||
except ImportError:
|
|
||||||
import configparser
|
|
||||||
|
|
||||||
from .. import color
|
|
||||||
from .. import files
|
|
||||||
from .. import pretty
|
|
||||||
from .. import repo
|
from .. import repo
|
||||||
|
|
||||||
|
|
||||||
@ -22,4 +13,4 @@ def command(config, pdffile, bibfile):
|
|||||||
:param bibtex bibtex file (in .bib, .bibml or .yaml format.
|
:param bibtex bibtex file (in .bib, .bibml or .yaml format.
|
||||||
"""
|
"""
|
||||||
rp = repo.Repository()
|
rp = repo.Repository()
|
||||||
rp.add_paper(pdffile, bibfile)
|
rp.add_paper_from_paths(pdffile, bibfile)
|
||||||
|
15
papers/commands/add_library_cmd.py
Normal file
15
papers/commands/add_library_cmd.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from .. import repo
|
||||||
|
|
||||||
|
|
||||||
|
def parser(subparsers, config):
|
||||||
|
parser = subparsers.add_parser('add_library',
|
||||||
|
help='add a set of papers to the repository')
|
||||||
|
parser.add_argument('bibfile', help='bibtex, bibtexml or bibyaml file')
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def command(config, bibfile):
|
||||||
|
"""
|
||||||
|
:param bibtex bibtex file (in .bib, .bibml or .yaml format.
|
||||||
|
"""
|
||||||
|
rp = repo.Repository()
|
||||||
|
rp.add_papers(bibfile)
|
@ -16,7 +16,7 @@ def command(config):
|
|||||||
for n in sorted(rp.numbers.keys()):
|
for n in sorted(rp.numbers.keys()):
|
||||||
paper = rp.paper_from_number(n, fatal = True)
|
paper = rp.paper_from_number(n, fatal = True)
|
||||||
bibdesc = pretty.bib_oneliner(paper.bib_data)
|
bibdesc = pretty.bib_oneliner(paper.bib_data)
|
||||||
articles.append('{:3d} {}{}{}{} {}'.format(int(paper.number), color.purple, paper.citekey, color.end, (8-len(paper.citekey))*' ', bibdesc))
|
articles.append(u'{:3d} {}{}{}{} {}'.format(int(paper.number), color.purple, paper.citekey, color.end, (8-len(paper.citekey))*' ', bibdesc))
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".tmp", delete=True) as tmpf:
|
with tempfile.NamedTemporaryFile(suffix=".tmp", delete=True) as tmpf:
|
||||||
tmpf.write('\n'.join(articles))
|
tmpf.write('\n'.join(articles))
|
||||||
|
@ -4,6 +4,11 @@ import files
|
|||||||
import color
|
import color
|
||||||
import pretty
|
import pretty
|
||||||
|
|
||||||
|
|
||||||
|
class NoDocumentFile(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Paper(object):
|
class Paper(object):
|
||||||
"""Paper class. The object is responsible for the integrity of its own data,
|
"""Paper class. The object is responsible for the integrity of its own data,
|
||||||
and for loading and writing it to disc.
|
and for loading and writing it to disc.
|
||||||
@ -20,7 +25,7 @@ class Paper(object):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_bibpdffiles(cls, pdfpath, bibpath):
|
def from_bibpdffiles(cls, pdfpath, bibpath):
|
||||||
bib_data = cls.import_bibdata(bibpath)
|
bib_data = cls.import_bibdata(bibpath)
|
||||||
name, meta = cls.create_meta(pdfpath, bib_data)
|
name, meta = cls.create_meta(bib_data, pdfpath=pdfpath)
|
||||||
p = Paper(name, bib_data = bib_data, metadata = meta)
|
p = Paper(name, bib_data = bib_data, metadata = meta)
|
||||||
|
|
||||||
return p
|
return p
|
||||||
@ -32,6 +37,20 @@ class Paper(object):
|
|||||||
self.metadata = metadata
|
self.metadata = metadata
|
||||||
self.citekey = citekey
|
self.citekey = citekey
|
||||||
self.number = number
|
self.number = number
|
||||||
|
|
||||||
|
def has_file(self):
|
||||||
|
"""Whether there exist a document file for this entry.
|
||||||
|
"""
|
||||||
|
return self.metadata['path'] is not None
|
||||||
|
|
||||||
|
def get_file_path(self):
|
||||||
|
if self.has_file():
|
||||||
|
return self.metadata['path']
|
||||||
|
else:
|
||||||
|
raise NoDocumentFile
|
||||||
|
|
||||||
|
def check_file(self):
|
||||||
|
return files.check_file(self.get_file_path())
|
||||||
|
|
||||||
def save_to_disc(self):
|
def save_to_disc(self):
|
||||||
files.save_bibdata(self.bib_data, self.name)
|
files.save_bibdata(self.bib_data, self.name)
|
||||||
@ -50,12 +69,19 @@ class Paper(object):
|
|||||||
return bib_data
|
return bib_data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_meta(cls, pdfpath, bib_data):
|
def create_meta(cls, bib_data, pdfpath=None):
|
||||||
|
|
||||||
fullpdfpath = os.path.abspath(pdfpath)
|
if pdfpath is None:
|
||||||
files.check_file(fullpdfpath)
|
name = bib_data.entries.keys()[0]
|
||||||
|
# TODO this introduces a bug and a security issue since the name
|
||||||
name, ext = files.name_from_path(pdfpath)
|
# is used to generate a file name that is written. It should be
|
||||||
|
# escaped here. (22/10/2012)
|
||||||
|
fullpdfpath, ext = None, None
|
||||||
|
else:
|
||||||
|
fullpdfpath = os.path.abspath(pdfpath)
|
||||||
|
files.check_file(fullpdfpath)
|
||||||
|
|
||||||
|
name, ext = files.name_from_path(pdfpath)
|
||||||
|
|
||||||
meta = {}
|
meta = {}
|
||||||
|
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
import papers
|
|
||||||
from papers import commands
|
from papers import commands
|
||||||
|
|
||||||
cmds = collections.OrderedDict([
|
cmds = collections.OrderedDict([
|
||||||
('init', commands.init_cmd),
|
('init', commands.init_cmd),
|
||||||
('add' , commands.add_cmd),
|
('add' , commands.add_cmd),
|
||||||
|
('add_library', commands.add_library_cmd),
|
||||||
('list', commands.list_cmd),
|
('list', commands.list_cmd),
|
||||||
('open', commands.open_cmd),
|
('open', commands.open_cmd),
|
||||||
('websearch', commands.websearch_cmd)
|
('websearch', commands.websearch_cmd)
|
||||||
@ -27,4 +27,4 @@ args.config = config
|
|||||||
cmd = args.command
|
cmd = args.command
|
||||||
del args.command
|
del args.command
|
||||||
|
|
||||||
cmds[cmd].command(**vars(args))
|
cmds[cmd].command(**vars(args))
|
||||||
|
@ -3,26 +3,30 @@
|
|||||||
import color
|
import color
|
||||||
|
|
||||||
def person_repr(p):
|
def person_repr(p):
|
||||||
return ' '.join(s for s in [' '.join(p.first(abbr = True)),
|
return u' '.join(s for s in [u' '.join(p.first(abbr = True)),
|
||||||
' '.join(p.middle(abbr = True)),
|
u' '.join(p.middle(abbr = True)),
|
||||||
' '.join(p.prelast(abbr = False)),
|
u' '.join(p.prelast(abbr = False)),
|
||||||
' '.join(p.last(abbr = False)),
|
u' '.join(p.last(abbr = False)),
|
||||||
' '.join(p.lineage(abbr = True))] if s)
|
u' '.join(p.lineage(abbr = True))] if s)
|
||||||
|
|
||||||
def bib_oneliner(bib_data):
|
def bib_oneliner(bib_data):
|
||||||
article = bib_data.entries[list(bib_data.entries.keys())[0]]
|
article = bib_data.entries[list(bib_data.entries.keys())[0]]
|
||||||
authors = ', '.join(person_repr(p) for p in article.persons['author'])
|
authors = ', '.join(person_repr(p) for p in article.persons['author'])
|
||||||
title = article.fields['title']
|
title = article.fields['title']
|
||||||
year = article.fields['year']
|
year = article.fields.get('year', '')
|
||||||
journal = article.fields['journal']
|
journal = ''
|
||||||
return '{}{}{} \"{}{}{}\" {}{}{} {}({}{}{}){}'.format(
|
field = 'journal'
|
||||||
|
if article.type == 'inproceedings':
|
||||||
|
field = 'booktitle'
|
||||||
|
journal = article.fields.get(field, '')
|
||||||
|
return u'{}{}{} \"{}{}{}\" {}{}{} {}({}{}{}){}'.format(
|
||||||
color.green, authors, color.grey, color.bcyan, title, color.grey,
|
color.green, authors, color.grey, color.bcyan, title, color.grey,
|
||||||
color.yellow, journal, color.end, color.grey, color.end, year,
|
color.yellow, journal, color.end, color.grey, color.end, year,
|
||||||
color.grey, color.end)
|
color.grey, color.end)
|
||||||
|
|
||||||
def bib_desc(bib_data):
|
def bib_desc(bib_data):
|
||||||
article = bib_data.entries[list(bib_data.entries.keys())[0]]
|
article = bib_data.entries[list(bib_data.entries.keys())[0]]
|
||||||
s = '\n'.join('author: {}'.format(person_repr(p)) for p in article.persons['author'])
|
s = u'\n'.join(u'author: {}'.format(person_repr(p)) for p in article.persons['author'])
|
||||||
s += '\n'
|
s += u'\n'
|
||||||
s += '\n'.join('{}: {}'.format(k, v) for k, v in article.fields.items())
|
s += u'\n'.join(u'{}: {}'.format(k, v) for k, v in article.fields.items())
|
||||||
return s
|
return s
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import files
|
import files
|
||||||
import color
|
import color
|
||||||
|
|
||||||
from paper import Paper
|
from paper import Paper
|
||||||
|
|
||||||
alphabet = 'abcdefghijklmopqrstuvwxyz'
|
alphabet = 'abcdefghijklmopqrstuvwxyz'
|
||||||
@ -57,10 +58,12 @@ class Repository(object):
|
|||||||
|
|
||||||
# creating new papers
|
# creating new papers
|
||||||
|
|
||||||
def add_paper(self, pdfpath, bibpath):
|
def add_paper_from_paths(self, pdfpath, bibpath):
|
||||||
|
|
||||||
p = Paper.from_bibpdffiles(pdfpath, bibpath)
|
p = Paper.from_bibpdffiles(pdfpath, bibpath)
|
||||||
|
self.add_paper(p)
|
||||||
|
|
||||||
|
def add_paper(self, p):
|
||||||
# updating papersconfig
|
# updating papersconfig
|
||||||
p.citekey = self.create_citekey(p.bib_data)
|
p.citekey = self.create_citekey(p.bib_data)
|
||||||
p.number = self.create_number()
|
p.number = self.create_number()
|
||||||
@ -74,18 +77,40 @@ class Repository(object):
|
|||||||
# writing all to disk
|
# writing all to disk
|
||||||
files.save_papers(self.papers_config)
|
files.save_papers(self.papers_config)
|
||||||
p.save_to_disc()
|
p.save_to_disc()
|
||||||
|
print "Added: %s" % p.citekey
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
def add_papers(self, bibpath):
|
||||||
|
bib_data = Paper.import_bibdata(bibpath)
|
||||||
|
for k in bib_data.entries:
|
||||||
|
sub_bib = type(bib_data)(preamble=bib_data._preamble)
|
||||||
|
sub_bib.add_entry(k, bib_data.entries[k])
|
||||||
|
name, meta = Paper.create_meta(sub_bib, pdfpath=None)
|
||||||
|
p = Paper(name, bib_data = sub_bib, metadata = meta)
|
||||||
|
self.add_paper(p)
|
||||||
|
|
||||||
def create_citekey(self, bib_data, allowed = tuple()):
|
def create_citekey(self, bib_data, allowed = tuple()):
|
||||||
"""Create a cite key unique to a given bib_data"""
|
"""Create a cite key unique to a given bib_data.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
KeyError if no author is defined.
|
||||||
|
"""
|
||||||
article = bib_data.entries[list(bib_data.entries.keys())[0]]
|
article = bib_data.entries[list(bib_data.entries.keys())[0]]
|
||||||
first_author = article.persons['author'][0]
|
author_key = 'author'
|
||||||
year = article.fields['year']
|
if not 'author' in article.persons:
|
||||||
|
author_key = 'editor'
|
||||||
|
try:
|
||||||
|
first_author = article.persons[author_key][0]
|
||||||
|
except KeyError:
|
||||||
|
raise(ValueError,
|
||||||
|
'No author or editor defined: cannot generate a citekey.')
|
||||||
|
try:
|
||||||
|
year = article.fields['year']
|
||||||
|
except KeyError:
|
||||||
|
year = ''
|
||||||
prefix = '{}{}'.format(first_author.last()[0][:6], year)
|
prefix = '{}{}'.format(first_author.last()[0][:6], year)
|
||||||
|
|
||||||
letter = 0
|
letter = 0
|
||||||
citekey = None
|
|
||||||
|
|
||||||
citekey = prefix
|
citekey = prefix
|
||||||
while citekey in self.citekeys and citekey not in allowed:
|
while citekey in self.citekeys and citekey not in allowed:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user