From 3e6a1403b9b1782e3b627c00b5f7ed49920ff3df Mon Sep 17 00:00:00 2001 From: Olivier Mangin Date: Thu, 14 Mar 2013 15:49:04 +0100 Subject: [PATCH] Adds basic export capabilities. --- papers/commands/__init__.py | 1 + papers/commands/export_cmd.py | 29 +++++++++++++++++++++++++++++ papers/files.py | 27 ++++++++++++++++++--------- papers/papers | 1 + papers/ui.py | 3 +++ tests/test_repo.py | 7 ++++--- 6 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 papers/commands/export_cmd.py diff --git a/papers/commands/__init__.py b/papers/commands/__init__.py index 61d61fb..b36a71e 100644 --- a/papers/commands/__init__.py +++ b/papers/commands/__init__.py @@ -1,6 +1,7 @@ import add_cmd import add_library_cmd import import_cmd +import export_cmd import init_cmd import list_cmd import open_cmd diff --git a/papers/commands/export_cmd.py b/papers/commands/export_cmd.py new file mode 100644 index 0000000..3a97063 --- /dev/null +++ b/papers/commands/export_cmd.py @@ -0,0 +1,29 @@ +import sys + +import pybtex +from pybtex.database import BibliographyData + +from .. import repo +from .. import files + + +def parser(subparsers, config): + parser = subparsers.add_parser('export', + help='export bibliography') + parser.add_argument('-f', '--bib-format', default='bibtex', + help="export format") + return parser + + +def command(config, ui, bib_format): + """ + :param bib_format (in 'bibtex', 'yaml') + """ + rp = repo.Repository.from_directory() + bib = BibliographyData() + for p in rp.all_papers(): + bib.add_entry(p.citekey, p.bibentry) + try: + files.write_bibdata(bib, sys.stdout, bib_format) + except KeyError: + ui.error("Invalid output format: %s." % bib_format) diff --git a/papers/files.py b/papers/files.py index 302de4e..6c65718 100644 --- a/papers/files.py +++ b/papers/files.py @@ -27,11 +27,16 @@ except ImportError: _papersdir = None BIB_EXTENSIONS = ['.bib', '.bibyaml', '.bibml', '.yaml'] -FORMATS = {'bib': pybtex.database.input.bibtex, - 'xml': pybtex.database.input.bibtexml, - 'yml': pybtex.database.input.bibyaml, - 'yaml': pybtex.database.input.bibyaml, - 'bibyaml': pybtex.database.input.bibyaml} +FORMATS_INPUT = {'bib': pybtex.database.input.bibtex, + 'xml': pybtex.database.input.bibtexml, + 'yml': pybtex.database.input.bibyaml, + 'yaml': pybtex.database.input.bibyaml, + 'bibyaml': pybtex.database.input.bibyaml} +FORMATS_OUTPUT = {'bib': pybtex.database.output.bibtex, + 'xml': pybtex.database.output.bibtexml, + 'yml': pybtex.database.output.bibyaml, + 'yaml': pybtex.database.output.bibyaml, + 'bibyaml': pybtex.database.output.bibyaml} def clean_path(path): @@ -112,10 +117,14 @@ def load_bibdata(filename, filepath): return load_externalbibfile(filepath) +def write_bibdata(bib_data, file_, format_): + writer = FORMATS_OUTPUT[format_].Writer() + writer.write_stream(bib_data, file_) + + def save_bibdata(bib_data, filepath): with open(filepath, 'w') as f: - parser = pybtex.database.output.bibyaml.Writer() - parser.write_stream(bib_data, f) + write_bibdata(bib_data, f, 'yaml') def save_meta(meta_data, filepath): @@ -131,7 +140,7 @@ def load_meta(filepath): def load_externalbibfile(fullbibpath): check_file(fullbibpath, fail=True) filename, ext = os.path.splitext(os.path.split(fullbibpath)[1]) - if ext[1:] in FORMATS.keys(): + if ext[1:] in FORMATS_INPUT.keys(): with open(fullbibpath) as f: return parse_bibdata(f, ext[1:]) else: @@ -147,7 +156,7 @@ def parse_bibdata(content, format_): :content: stream :param format_: (bib|xml|yml) """ - parser = FORMATS[format_].Parser() + parser = FORMATS_INPUT[format_].Parser() return parser.parse_stream(content) diff --git a/papers/papers b/papers/papers index 994940f..3eb1da5 100755 --- a/papers/papers +++ b/papers/papers @@ -14,6 +14,7 @@ cmds = collections.OrderedDict([ ('add', commands.add_cmd), ('add_library', commands.add_library_cmd), ('import', commands.import_cmd), + ('export', commands.export_cmd), ('list', commands.list_cmd), ('edit', commands.edit_cmd), ('open', commands.open_cmd), diff --git a/papers/ui.py b/papers/ui.py index 85cda81..33f1368 100644 --- a/papers/ui.py +++ b/papers/ui.py @@ -63,3 +63,6 @@ class UI: d = 0 if default in (True, 'y', 'yes') else 1 return (True, False)[self.input_choice(['yes', 'no'], ['y', 'n'], default=d, question=question)] + + def error(self, message): + self.print_("%s: %s" % (colored('error', 'red'), message)) diff --git a/tests/test_repo.py b/tests/test_repo.py index 7d799d8..3717f61 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -4,7 +4,8 @@ import shutil import os import fixtures -from papers.repo import Repository, _str_incr, _to_suffix, BIB_DIR, META_DIR +from papers.repo import (Repository, _str_incr, _to_suffix, BIB_DIR, META_DIR, + CiteKeyAlreadyExists) from papers.paper import PaperInRepo @@ -65,9 +66,9 @@ class TestUpdatePaper(TestRepo): with self.assertRaises(ValueError): self.repo.update(fixtures.doe2013, old_citekey='zou') - def test_raises_value_error_on_existing_destination(self): + def test_error_on_existing_destination(self): self.repo.add_paper(fixtures.doe2013) - with self.assertRaises(ValueError): + with self.assertRaises(CiteKeyAlreadyExists): self.repo.update(fixtures.turing1950, old_citekey='Doe2013') def test_updates_same_key(self):