diff --git a/papers/commands/edit_cmd.py b/papers/commands/edit_cmd.py index 8bec6c9..31157f9 100644 --- a/papers/commands/edit_cmd.py +++ b/papers/commands/edit_cmd.py @@ -1,7 +1,7 @@ -import subprocess - from ..color import colored +from ..files import editor_input from .. import repo +from ..paper import get_bibentry_from_string def parser(subparsers, config): @@ -17,13 +17,32 @@ def parser(subparsers, config): def command(config, ui, reference): rp = repo.Repository.from_directory() key = rp.citekey_from_ref(reference, fatal=True) + paper = rp.paper_from_citekey(key) filepath = rp.path_to_paper_file(key, 'bib') - subprocess.call([config.get('papers', 'edit-cmd'), - filepath]) - # TODO use editor_input from files.py instead of directly editing the file. - # Then chack that output file is correctly formmatted and that citekey has - # not changed or is still a valid citekey. - print('{} editing {}.'.format( - colored('Done', 'ok'), - colored(filepath, 'filepath') - )) + editor = config.get('papers', 'edit-cmd') + with open(filepath) as f: + content = f.read() + while True: + # Get new content from user + content = editor_input(editor, content) + # Parse new content + new_key, bib = get_bibentry_from_string(content) + paper.update(key=key, bib=bib) + # TODO merge into an update method + paper.citekey = new_key + paper.bibentry = bib + try: + rp.update(paper, old_citekey=key) + break + except repo.CiteKeyAlreadyExists: + options = ['overwrite', 'edit again', 'abort'] + choice = options[ui.input_choice( + options, + ['o', 'e', 'a'], + question='A paper already exist with this citekey.' + )] + if choice == 'abort': + break + elif choice == 'overwrite': + rp.update(paper, old_citekey=key, overwrite=True) + # else edit again diff --git a/papers/paper.py b/papers/paper.py index 5b4ff22..941faec 100644 --- a/papers/paper.py +++ b/papers/paper.py @@ -42,7 +42,7 @@ def get_bibentry_from_file(bibfile): def get_bibentry_from_string(content): """Extract first entry (supposed to be the only one) from given file. """ - bib_data = files.parse_bibdata(StringIO(content)) + bib_data = files.parse_bibdata(StringIO(content), 'yml') first_key = bib_data.entries.keys()[0] first_entry = bib_data.entries[first_key] return first_key, first_entry @@ -70,6 +70,12 @@ def get_safe_metadata(metapath): return files.read_yamlfile(metapath) +def check_citekey(citekey): + # TODO This is not the right way to test that (17/12/2012) + if unicode(citekey) != str2citekey(citekey): + raise(ValueError("Invalid citekey: %s" % citekey)) + + class NoDocumentFile(Exception): pass @@ -89,9 +95,7 @@ class Paper(object): if not metadata: metadata = Paper.create_meta() self.metadata = metadata - # TODO This is not the right way to test that (17/12/2012) - if unicode(citekey) != str2citekey(citekey): - raise(ValueError("Invalid citekey: %s" % citekey)) + check_citekey(citekey) self.citekey = citekey def __eq__(self, other): @@ -158,6 +162,15 @@ class Paper(object): files.save_bibdata(bibdata, bib_filepath) files.save_meta(self.metadata, meta_filepath) + def update(self, key=None, bib=None, meta=None): + if key is not None: + check_citekey(key) + self.citekey = key + if bib is not None: + self.bibentry = bib + if meta is not None: + self.metadata = meta + def get_document_file_from_bibdata(self, remove=False): """Try extracting document file from bib data. Raises NoDocumentFile if not found. diff --git a/papers/repo.py b/papers/repo.py index 985f796..f49d230 100644 --- a/papers/repo.py +++ b/papers/repo.py @@ -15,6 +15,10 @@ META_DIR = 'meta' DOC_DIR = 'doc' +class CiteKeyAlreadyExists(Exception): + pass + + class Repository(object): def __init__(self, config=None): @@ -86,7 +90,7 @@ class Repository(object): def update(self, paper, old_citekey=None, overwrite=False): """Updates a paper, eventually changing its citekey. The paper should be in repository. If the citekey changes, - the new citekey should be free excpet if the overwrite argumnent + the new citekey should be free except if the overwrite argument is set to True. """ if old_citekey is None: @@ -99,7 +103,7 @@ class Repository(object): else: if self.has_paper(paper.citekey): if not overwrite: - raise(ValueError, + raise(CiteKeyAlreadyExists, "There is already a paper with citekey: %s." % paper.citekey) else: @@ -116,8 +120,9 @@ class Repository(object): self.remove(old_citekey) def remove(self, citekey): - self.citekeys.remove(citekey) paper = self.paper_from_citekey(citekey) + self.citekeys.remove(citekey) + self.save() for f in ('bib', 'meta'): os.remove(self.path_to_paper_file(citekey, f)) # Eventually remove associated document @@ -196,7 +201,7 @@ class Repository(object): else: doc_path = self.get_document_directory() if not (os.path.exists(doc_path) and os.path.isdir(doc_path)): - raise(ValueError, + raise(NoDocumentFile, "Document directory %s, does not exist." % doc_path) ext = os.path.splitext(doc_file)[1] new_doc_file = os.path.join(doc_path, citekey + ext)