Skip to content

Commit

Permalink
moving from pybtex to bibtextparser, fixed major regressions.
Browse files Browse the repository at this point in the history
* only bibtex format is supported
* all tests except test_repo.py and edit test pass
* edit and update commands were not updated
* removed --format argument from export, only bibtex is supported.
  • Loading branch information
benureau committed Apr 13, 2014
1 parent c692f23 commit d3736e2
Show file tree
Hide file tree
Showing 44 changed files with 530 additions and 472 deletions.
1 change: 1 addition & 0 deletions .ackrc
@@ -1 +1,2 @@
--ignore-directory=is:build
--ignore-directory=is:pubs.egg-info
3 changes: 1 addition & 2 deletions NOTES
Expand Up @@ -14,13 +14,12 @@ A paper correspond to 3 files :

About strings:
--------------
- pybtex seems to store entries as utf-8 (TODO: check)
- so assumption is made that everything is utf-8
- conversions are performed at print time

Config values:
--------------
[papers]
[pubs]
open-cmd = open
edit-cmd = edit
import-copy = True
Expand Down
2 changes: 1 addition & 1 deletion pubs/__init__.py
@@ -1 +1 @@
__version__ = 4
__version__ = 4
35 changes: 20 additions & 15 deletions pubs/bibstruct.py
Expand Up @@ -21,20 +21,25 @@ def check_citekey(citekey):
raise ValueError("Invalid citekey: %s" % citekey)

def verify_bibdata(bibdata):
if not hasattr(bibdata, 'entries') or len(bibdata.entries) == 0:
raise ValueError('no entries in the bibdata.')
if len(bibdata.entries) > 1:
if bibdata is None or len(bibdata) == 0:
raise ValueError('no valid bibdata')
if len(bibdata) > 1:
raise ValueError('ambiguous: multiple entries in the bibdata.')

def get_entry(bibdata):
verify_bibdata(bibdata)
return bibdata.entries.iteritems().next()
for e in bibdata.items():
return e

def extract_citekey(bibdata):
verify_bibdata(bibdata)
citekey, entry = get_entry(bibdata)
return citekey

def author_last(author_str):
""" Return the last name of the author """
return author_str.split(',')[0]

def generate_citekey(bibdata):
""" Generate a citekey from bib_data.
Expand All @@ -44,17 +49,17 @@ def generate_citekey(bibdata):
"""
citekey, entry = get_entry(bibdata)

author_key = 'author' if 'author' in entry.persons else 'editor'
author_key = 'author' if 'author' in entry else 'editor'
try:
first_author = entry.persons[author_key][0]
first_author = entry[author_key][0]
except KeyError:
raise ValueError(
'No author or editor defined: cannot generate a citekey.')
try:
year = entry.fields['year']
year = entry['year']
except KeyError:
year = ''
citekey = u'{}{}'.format(u''.join(first_author.last()), year)
citekey = u'{}{}'.format(u''.join(author_last(first_author)), year)

return str2citekey(citekey)

Expand All @@ -67,21 +72,21 @@ def extract_docfile(bibdata, remove=False):
citekey, entry = get_entry(bibdata)

try:
if 'file' in entry.fields:
field = entry.fields['file']
if 'file' in entry:
field = entry['file']
# Check if this is mendeley specific
for f in field.split(':'):
if len(f) > 0:
break
if remove:
entry.fields.pop('file')
entry.pop('file')
# This is a hck for Mendeley. Make clean
if f[0] != '/':
f = '/' + f
return f
if 'attachments' in entry.fields:
return entry.fields['attachments']
if 'pdf' in entry.fields:
return entry.fields['pdf']
if 'attachments' in entry:
return entry['attachments']
if 'pdf' in entry:
return entry['pdf']
except (KeyError, IndexError):
return None
2 changes: 1 addition & 1 deletion pubs/commands/add_cmd.py
Expand Up @@ -108,7 +108,7 @@ def command(args):
if copy_doc is None:
copy_doc = config().import_copy
if copy_doc:
docfile = rp.databroker.copy_doc(citekey, docfile)
docfile = rp.databroker.add_doc(citekey, docfile)

# create the paper

Expand Down
2 changes: 1 addition & 1 deletion pubs/commands/attach_cmd.py
Expand Up @@ -34,7 +34,7 @@ def command(args):
try:
document = args.document
if copy:
document = rp.databroker.copy_doc(paper.citekey, document)
document = rp.databroker.add_doc(paper.citekey, document)
else:
pass # TODO warn if file does not exists
paper.docpath = document
Expand Down
21 changes: 19 additions & 2 deletions pubs/commands/edit_cmd.py
Expand Up @@ -15,6 +15,24 @@ def parser(subparsers):
return parser


def edit_meta(citekey):
rp = repo.Repository(config())
coder = endecoder.EnDecoder()
filepath = os.path.join(rp.databroker.databroker.filebroker.metadir(), citekey+'.yaml')
with open(filepath) as f:
content = f.read()



def edit_bib(citekey):
rp = repo.Repository(config())
coder = endecoder.EnDecoder()
filepath = os.path.join(rp.databroker.databroker.filebroker.bibdir(), citekey+'.bib')
with open(filepath) as f:
content = f.read()



def command(args):

ui = get_ui()
Expand All @@ -26,8 +44,7 @@ def command(args):
if meta:
filepath = os.path.join(rp.databroker.databroker.filebroker.metadir(), citekey+'.yaml')
else:
filepath = os.path.join(rp.databroker.databroker.filebroker.bibdir(), citekey+'.bibyaml')

filepath = os.path.join(rp.databroker.databroker.filebroker.bibdir(), citekey+'.bib')

with open(filepath) as f:
content = f.read()
Expand Down
15 changes: 6 additions & 9 deletions pubs/commands/export_cmd.py
@@ -1,8 +1,6 @@
from __future__ import print_function
import sys

from pybtex.database import BibliographyData

from .. import repo
from ..configs import config
from ..uis import get_ui
Expand All @@ -11,20 +9,19 @@
def parser(subparsers):
parser = subparsers.add_parser('export',
help='export bibliography')
parser.add_argument('-f', '--bib-format', default='bibtex',
help='export format')
# parser.add_argument('-f', '--bib-format', default='bibtex',
# help='export format')
parser.add_argument('citekeys', nargs='*',
help='one or several citekeys')
return parser


def command(args):
"""
:param bib_format (in 'bibtex', 'yaml')
"""
# :param bib_format (only 'bibtex' now)

ui = get_ui()
bib_format = args.bib_format

rp = repo.Repository(config())

Expand All @@ -36,12 +33,12 @@ def command(args):

if len(papers) == 0:
papers = rp.all_papers()
bib = BibliographyData()
bib = {}
for p in papers:
bib.add_entry(p.citekey, p.bibentry)
bib[p.citekey] = p.bibentry
try:
exporter = endecoder.EnDecoder()
bibdata_raw = exporter.encode_bibdata(bib, fmt=bib_format)
bibdata_raw = exporter.encode_bibdata(bib)
print(bibdata_raw, end='')
except KeyError:
ui.error("Invalid output format: %s." % bib_format)
13 changes: 6 additions & 7 deletions pubs/commands/import_cmd.py
@@ -1,8 +1,6 @@
import os
import datetime

from pybtex.database import Entry, BibliographyData, FieldDict, Person

from .. import repo
from .. import endecoder
from .. import bibstruct
Expand Down Expand Up @@ -41,8 +39,9 @@ def many_from_path(bibpath):

bibpath = os.path.expanduser(bibpath)
if os.path.isdir(bibpath):
print([os.path.splitext(f)[-1][1:] for f in os.listdir(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())]
if os.path.splitext(f)[-1][1:] == 'bib']
else:
all_files = [bibpath]

Expand All @@ -53,10 +52,10 @@ def many_from_path(bibpath):

papers = {}
for b in biblist:
for k in b.entries:
for k in b.keys():
try:
bibdata = BibliographyData()
bibdata.entries[k] = b.entries[k]
bibdata = {}
bibdata[k] = b[k]

papers[k] = Paper(bibdata, citekey=k)
papers[k].added = datetime.datetime.now()
Expand Down Expand Up @@ -94,7 +93,7 @@ def command(args):
if copy_doc is None:
copy_doc = config().import_copy
if copy_doc:
docfile = rp.databroker.copy_doc(p.citekey, docfile)
docfile = rp.databroker.add_doc(p.citekey, docfile)

p.docpath = docfile
rp.push_paper(p)
Expand Down
21 changes: 8 additions & 13 deletions pubs/commands/list_cmd.py
@@ -1,9 +1,9 @@
from .. import repo
from .. import pretty
from .. import bibstruct
from ..configs import config
from ..uis import get_ui


class InvalidQuery(ValueError):
pass

Expand Down Expand Up @@ -56,20 +56,15 @@ def _get_field_value(query_block):
return (field, value)


def _lower(string, lower=True):
if lower:
return string.lower()
else:
return string

def _lower(s, lower=True):
return s.lower() if lower else s

def _check_author_match(paper, query, case_sensitive=False):
"""Only checks within last names."""
if not 'author' in paper.bibentry.persons:
if not 'author' in paper.bibentry:
return False
return any([query in _lower(name, lower=(not case_sensitive))
for p in paper.bibentry.persons['author']
for name in p.last()])
return any([query == _lower(bibstruct.author_last(p), lower=(not case_sensitive))
for p in paper.bibentry['author']])


def _check_tag_match(paper, query, case_sensitive=False):
Expand All @@ -78,7 +73,7 @@ def _check_tag_match(paper, query, case_sensitive=False):


def _check_field_match(paper, field, query, case_sensitive=False):
return query in _lower(paper.bibentry.fields[field],
return query in _lower(paper.bibentry[field],
lower=(not case_sensitive))


Expand All @@ -92,7 +87,7 @@ def _check_query_block(paper, query_block, case_sensitive=None):
return _check_tag_match(paper, value, case_sensitive=case_sensitive)
elif field == 'author':
return _check_author_match(paper, value, case_sensitive=case_sensitive)
elif field in paper.bibentry.fields:
elif field in paper.bibentry:
return _check_field_match(paper, field, value,
case_sensitive=case_sensitive)
else:
Expand Down
22 changes: 11 additions & 11 deletions pubs/datacache.py
Expand Up @@ -4,15 +4,15 @@
class DataCache(object):
""" DataCache class, provides a very similar interface as DataBroker
Has two roles :
Has two roles :
1. Provides a buffer between the commands and the hard drive.
Until a command request a hard drive ressource, it does not touch it.
2. Keeps a up-to-date, pickled version of the repository, to speed up things
when they are a lot of files. Update are also done only when required.
Changes are detected using data modification timestamps.
For the moment, only (1) is implemented.
"""
"""
def __init__(self, directory, create=False):
self.directory = directory
self._databroker = None
Expand All @@ -30,16 +30,16 @@ def _create(self):

def pull_metadata(self, citekey):
return self.databroker.pull_metadata(citekey)

def pull_bibdata(self, citekey):
return self.databroker.pull_bibdata(citekey)

def push_metadata(self, citekey, metadata):
self.databroker.push_metadata(citekey, metadata)

def push_bibdata(self, citekey, bibdata):
self.databroker.push_bibdata(citekey, bibdata)

def push(self, citekey, metadata, bibdata):
self.databroker.push(citekey, metadata, bibdata)

Expand All @@ -59,23 +59,23 @@ def listing(self, filestats=True):
def verify(self, bibdata_raw):
"""Will return None if bibdata_raw can't be decoded"""
return self.databroker.verify(bibdata_raw)

# docbroker

def in_docsdir(self, docpath):
return self.databroker.in_docsdir(docpath)

def real_docpath(self, docpath):
return self.databroker.real_docpath(docpath)
return self.databroker.real_docpath(docpath)

def copy_doc(self, citekey, source_path, overwrite=False):
def add_doc(self, citekey, source_path, overwrite=False):
return self.databroker.add_doc(citekey, source_path, overwrite=overwrite)

def remove_doc(self, docpath, silent=True):
return self.databroker.remove_doc(docpath, silent=silent)

def rename_doc(self, docpath, new_citekey):
return self.databroker.rename_doc(docpath, new_citekey)
return self.databroker.rename_doc(docpath, new_citekey)

# notesbroker

Expand All @@ -94,7 +94,7 @@ def rename_note(self, old_citekey, new_citekey):
# def __init__(self, cache, directory):
# self.cache = cache
# self.directory = directory

# def changes(self):
# """ Returns the list of modified files since the last cache was saved to disk"""
# pass

0 comments on commit d3736e2

Please sign in to comment.