From 8b0baede8857668cb6b6f2a8ce61ca6e6ea12d23 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Tue, 25 Jun 2013 13:07:18 +0200 Subject: [PATCH 01/13] FIX bug in color handling --- papers/files.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/papers/files.py b/papers/files.py index 0af1cda..752262c 100644 --- a/papers/files.py +++ b/papers/files.py @@ -21,10 +21,10 @@ try: import pybtex.database.output.bibyaml except ImportError: - print(ui.dye('error', ui.error) + - ": you need to install Pybtex; try running 'pip install" + print(color.dye('error', color.error) + + ": you need to install Pybtex; try running 'pip install " "pybtex' or 'easy_install pybtex'") - + exit(-1) _papersdir = None From 4f132737e490ebbef26605100bc65634936e3be5 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Tue, 25 Jun 2013 16:55:48 +0200 Subject: [PATCH 02/13] made init command more robust --- papers/commands/init_cmd.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/papers/commands/init_cmd.py b/papers/commands/init_cmd.py index a4ccba8..948a66b 100644 --- a/papers/commands/init_cmd.py +++ b/papers/commands/init_cmd.py @@ -24,13 +24,14 @@ def command(config, ui, path, doc_dir): else: papersdir = os.path.join(os.getcwd(), path) configs.add_and_write_option('papers', 'papers-directory', papersdir) - if not os.path.exists(papersdir): - ui.print_('Initializing papers in {}.'.format( - color.dye(papersdir, color.filepath))) - repo = Repository() - repo.init(papersdir) # Creates directories - repo.save() # Saves empty repository description - else: - ui.error('papers already present in {}.'.format( - color.dye(papersdir, color.filepath))) - ui.exit() + if os.path.exists(papersdir): + if len(os.listdir(papersdir)) > 0: + ui.error('directory {} is not empty.'.format( + color.dye(papersdir, color.filepath))) + ui.exit() + + ui.print_('Initializing papers in {}.'.format( + color.dye(papersdir, color.filepath))) + repo = Repository() + repo.init(papersdir) # Creates directories + repo.save() # Saves empty repository description \ No newline at end of file From 4e6b062a6416f691a957c6870599713b1a23b19c Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Tue, 25 Jun 2013 23:09:26 +0200 Subject: [PATCH 03/13] update command for updating repository format --- papers/commands/__init__.py | 1 + papers/commands/update_cmd.py | 19 +++++++++++++++++++ papers/papers | 1 + 3 files changed, 21 insertions(+) create mode 100644 papers/commands/update_cmd.py diff --git a/papers/commands/__init__.py b/papers/commands/__init__.py index bde2380..5ee8934 100644 --- a/papers/commands/__init__.py +++ b/papers/commands/__init__.py @@ -10,3 +10,4 @@ import remove_cmd import websearch_cmd import tags_cmd import attach_cmd +import update_cmd diff --git a/papers/commands/update_cmd.py b/papers/commands/update_cmd.py new file mode 100644 index 0000000..6c521b9 --- /dev/null +++ b/papers/commands/update_cmd.py @@ -0,0 +1,19 @@ +from .. import repo +from .. import color + +def parser(subparsers, config): + parser = subparsers.add_parser('update', help='update the repository to the lastest format') + return parser + + +def command(config, ui): + rp = repo.Repository.from_directory(config) + msg = ("You should backup the paper directory {} before continuing." + "Continue ?").format(color.dye(rp.papersdir, color.filepath)) + sure = ui.input_yn(question=msg, default='n') + if sure: + for p in rp.all_papers(): + tags = set(p.metadata['tags']) + tags = tags.union(p.metadata['labels']) + p.metadata.pop('labels', []) + rp.save_paper(p) diff --git a/papers/papers b/papers/papers index 55281b8..7f5edfe 100755 --- a/papers/papers +++ b/papers/papers @@ -22,6 +22,7 @@ cmds = collections.OrderedDict([ ('websearch', commands.websearch_cmd), ('tags', commands.tags_cmd), ('attach', commands.attach_cmd), + ('update', commands.update_cmd), ]) config = configs.read_config() From d30d5f32c4e7434bfba22df5cf494df3c00b25c8 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Tue, 25 Jun 2013 23:36:15 +0200 Subject: [PATCH 04/13] "label" renamed as "tag" in the metadata file (and everywhere else). Use the update command to update your metadata files. Tags is now a property of the Paper class, so one can use : print(p.tags) p.tags = ['math', 'romance'] --- TODO | 1 - papers/commands/add_cmd.py | 2 +- papers/commands/list_cmd.py | 12 ++++++------ papers/commands/tags_cmd.py | 2 +- papers/paper.py | 27 +++++++++++++++++++++++++-- papers/repo.py | 8 ++++---- tests/test_paper.py | 2 +- 7 files changed, 38 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 2f22223..03f876f 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ TODO list ========= - manage cross-references -+ labels - find (authors) duplicates + remove command - stats command diff --git a/papers/commands/add_cmd.py b/papers/commands/add_cmd.py index 41d4126..bea1d6c 100644 --- a/papers/commands/add_cmd.py +++ b/papers/commands/add_cmd.py @@ -45,7 +45,7 @@ def command(config, ui, bibfile, docfile, label, copy): else: p = Paper.load(bibfile) if label is not None: - p.metadata['labels'] = label.split() + p.tags = set(label.split()) # Check if another doc file is specified in bibtex docfile2 = extract_doc_path_from_bibdata(p, ui) if docfile is None: diff --git a/papers/commands/list_cmd.py b/papers/commands/list_cmd.py index 37946d2..57f0e16 100644 --- a/papers/commands/list_cmd.py +++ b/papers/commands/list_cmd.py @@ -9,7 +9,7 @@ def parser(subparsers, config): default=False, dest='citekeys', help='Only returns citekeys of matching papers.') parser.add_argument('query', nargs='*', - help='Paper query (e.g. "year: 2000" or "labels: math")') + help='Paper query (e.g. "year: 2000" or "tags: math")') return parser @@ -23,12 +23,12 @@ def command(config, ui, citekeys, query): paper_strings = [] for n, p in papers: bibdesc = pretty.bib_oneliner(p.bibentry) - paper_strings.append((u'{num:d}: [{citekey}] {descr} {labels}'.format( + paper_strings.append((u'{num:d}: [{citekey}] {descr} {tags}'.format( num=int(n), citekey=color.dye(p.citekey, color.purple), descr=bibdesc, - labels=color.dye(' '.join(p.metadata.get('labels', [])), - color.purple, bold=True), + tags=color.dye(' '.join(p.tags), + color.purple, bold=True), )).encode('utf-8')) ui.print_('\n'.join(paper_strings)) @@ -45,8 +45,8 @@ def test_paper(query_string, p): field = tmp[0] value = tmp[1] - if field in ['labels', 'l', 'tags', 't']: - if value not in p.metadata['labels']: + if field in ['tags', 't']: + if value not in p.tags: return False elif field in ['author', 'authors', 'a']: # that is the very ugly if not 'author' in p.bibentry.persons: diff --git a/papers/commands/tags_cmd.py b/papers/commands/tags_cmd.py index ce43ee7..c56384d 100644 --- a/papers/commands/tags_cmd.py +++ b/papers/commands/tags_cmd.py @@ -9,5 +9,5 @@ def parser(subparsers, config): def command(config, ui): """List existing tags""" rp = Repository.from_directory(config) - for tag in rp.get_labels(): + for tag in rp.get_tags(): ui.print_(tag) diff --git a/papers/paper.py b/papers/paper.py index 2f003e6..55d5705 100644 --- a/papers/paper.py +++ b/papers/paper.py @@ -20,7 +20,7 @@ CITEKEY_EXCLUDE_RE = re.compile('[%s]' BASE_META = { 'external-document': None, - 'labels': [], + 'tags': [], 'notes': [], } @@ -250,7 +250,30 @@ class Paper(object): return papers -class PaperInRepo(Paper): + # tags + + @property + def tags(self): + return self.metadata.setdefault('tags', set()) + + @tags.setter + def tags(self, value): + if not hasattr(value, '__iter__'): + raise ValueError, 'tags must be iterables' + self.metadata['tags'] = set(value) + + def add_tag(self, tag): + self.tags.add(tag) + + def remove_tag(self, tag): + """Remove a tag from a paper. Fails silently.""" + try: + self.tags.pop(tag) + except KeyError: + pass + + +class PaperInRepo(Paper): # TODO document why this class exists (fabien, 2013/06) def __init__(self, repo, *args, **kwargs): Paper.__init__(self, *args, **kwargs) diff --git a/papers/repo.py b/papers/repo.py index 4db7a67..6486890 100644 --- a/papers/repo.py +++ b/papers/repo.py @@ -198,11 +198,11 @@ class Repository(object): new_doc_file = os.path.join(doc_path, citekey + ext) shutil.copy(doc_file, new_doc_file) - def get_labels(self): - labels = set() + def get_tags(self): + tags = set() for p in self.all_papers(): - labels = labels.union(p.metadata.get('labels', [])) - return labels + tags = tags.union(p.tags) + return tags @classmethod def from_directory(cls, config, papersdir=None): diff --git a/tests/test_paper.py b/tests/test_paper.py index be99a90..43b37c6 100644 --- a/tests/test_paper.py +++ b/tests/test_paper.py @@ -24,7 +24,7 @@ entries: META = """ external-document: null notes: [] -labels: [] +tags: [] """ From 8290eeaa9b7e09a37c64eada680338c162da18bd Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 11:00:28 +0200 Subject: [PATCH 05/13] FIX bug in bold colors --- papers/color.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/papers/color.py b/papers/color.py index 5c2a078..794d028 100644 --- a/papers/color.py +++ b/papers/color.py @@ -24,7 +24,7 @@ filepath = cyan def dye(s, color=end, bold=False): assert color[0] == '\033' if bold: - s = '\033[1' + s[3:] + color = '\033[1' + color[3:] return color + s + end _dye = dye From 4d3ce2e2d8776058557340c53f4bb7ebaf72674c Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 11:08:19 +0200 Subject: [PATCH 06/13] factorized list command print code into helpers --- papers/commands/helpers.py | 14 ++++++++++++++ papers/commands/list_cmd.py | 31 +++++++++++++++++-------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/papers/commands/helpers.py b/papers/commands/helpers.py index c857fd3..33988b4 100644 --- a/papers/commands/helpers.py +++ b/papers/commands/helpers.py @@ -1,5 +1,6 @@ from .. import files from .. import color +from .. import pretty from ..repo import InvalidReference from ..paper import NoDocumentFile @@ -51,3 +52,16 @@ def parse_reference(ui, rp, ref): def parse_references(ui, rp, refs): citekeys = [parse_reference(ui, rp, ref) for ref in refs] return citekeys + +def paper_oneliner(p, n = 0, citekey_only = False): + if citekey_only: + return p.citekey + else: + bibdesc = pretty.bib_oneliner(p.bibentry) + return (u'{num:d}: [{citekey}] {descr} {tags}'.format( + num=int(n), + citekey=color.dye(p.citekey, color.purple), + descr=bibdesc, + tags=color.dye(' '.join(p.tags), + color.purple, bold=True), + )).encode('utf-8') diff --git a/papers/commands/list_cmd.py b/papers/commands/list_cmd.py index 57f0e16..badaef3 100644 --- a/papers/commands/list_cmd.py +++ b/papers/commands/list_cmd.py @@ -1,6 +1,7 @@ from .. import pretty from .. import repo from .. import color +from . import helpers def parser(subparsers, config): @@ -17,20 +18,22 @@ def command(config, ui, citekeys, query): rp = repo.Repository.from_directory(config) papers = [(n, p) for n, p in enumerate(rp.all_papers()) if test_paper(query, p)] - if citekeys: - paper_strings = [p.citekey for n, p in papers] - else: - paper_strings = [] - for n, p in papers: - bibdesc = pretty.bib_oneliner(p.bibentry) - paper_strings.append((u'{num:d}: [{citekey}] {descr} {tags}'.format( - num=int(n), - citekey=color.dye(p.citekey, color.purple), - descr=bibdesc, - tags=color.dye(' '.join(p.tags), - color.purple, bold=True), - )).encode('utf-8')) - ui.print_('\n'.join(paper_strings)) + # if citekeys: + # paper_strings = [p.citekey for n, p in papers] + # else: + # paper_strings = [] + # print p.tags + # print color.dye(' '.join(p.tags), color.purple) + # for n, p in papers: + # bibdesc = pretty.bib_oneliner(p.bibentry) + # paper_strings.append((u'{num:d}: [{citekey}] {descr} {tags}'.format( + # num=int(n), + # citekey=color.dye(p.citekey, color.purple), + # descr=bibdesc, + # tags=color.dye(' '.join(p.tags), + # color.purple, bold=True), + # )).encode('utf-8')) + ui.print_('\n'.join(helpers.paper_oneliner(p, n = n, citekey_only = citekeys) for n, p in papers)) # TODO author is not implemented, should we do it by last name only or more From 637eab1059b7566a3429818444a29d4914e30605 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 11:38:08 +0200 Subject: [PATCH 07/13] removed dead code in list --- papers/commands/list_cmd.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/papers/commands/list_cmd.py b/papers/commands/list_cmd.py index badaef3..bfa8edd 100644 --- a/papers/commands/list_cmd.py +++ b/papers/commands/list_cmd.py @@ -18,21 +18,6 @@ def command(config, ui, citekeys, query): rp = repo.Repository.from_directory(config) papers = [(n, p) for n, p in enumerate(rp.all_papers()) if test_paper(query, p)] - # if citekeys: - # paper_strings = [p.citekey for n, p in papers] - # else: - # paper_strings = [] - # print p.tags - # print color.dye(' '.join(p.tags), color.purple) - # for n, p in papers: - # bibdesc = pretty.bib_oneliner(p.bibentry) - # paper_strings.append((u'{num:d}: [{citekey}] {descr} {tags}'.format( - # num=int(n), - # citekey=color.dye(p.citekey, color.purple), - # descr=bibdesc, - # tags=color.dye(' '.join(p.tags), - # color.purple, bold=True), - # )).encode('utf-8')) ui.print_('\n'.join(helpers.paper_oneliner(p, n = n, citekey_only = citekeys) for n, p in papers)) From a1895103fcec62338582ad9645e8e01b9317ef44 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 11:45:34 +0200 Subject: [PATCH 08/13] new and improved tag(s) command ! (will be renamed 'tag' in next commit) 'git tag ref' returns the tags of the ref 'git tag tag1' return the refs which have tag1 as tag 'git tag ref tag1,tag2' add tag1 and tag2 to ref 'git tag ref :tag1,tag2' remove tag1 and add tag2 to ref --- papers/commands/tags_cmd.py | 60 ++++++++++++++++++++++++++++++++----- papers/paper.py | 8 ++--- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/papers/commands/tags_cmd.py b/papers/commands/tags_cmd.py index c56384d..7d8eab7 100644 --- a/papers/commands/tags_cmd.py +++ b/papers/commands/tags_cmd.py @@ -1,13 +1,59 @@ -from ..repo import Repository +""" +This command is all about tags. +The different use cases are : +1. > papers tag + Returns the list of all tags +2. > papers tag citekey + Return the list of tags of the given citekey +3. > papers tag citekey math + Add 'math' to the list of tags of the given citekey +4. > papers tag citekey :math + Remove 'math' for the list of tags of the given citekey +5. > papers tag citekey math,romance,:war + Add 'math' and 'romance' tags to the given citekey, and remove the 'war' tag +6. > papers tag math + If 'math' is not a citekey, then display all papers with the tag 'math' +""" +from ..repo import Repository, InvalidReference +from . import helpers def parser(subparsers, config): - parser = subparsers.add_parser('tags', help="list existing tags") + parser = subparsers.add_parser('tags', help="add, remove and show tags") + parser.add_argument('referenceOrTag', nargs='?', default = None, + help='reference to the paper (citekey or number), or ' + 'tag.') + parser.add_argument('tags', nargs='?', default = None, + help='If the previous argument was a reference, then ' + 'then a list of tags separated by commas.') + # TODO find a way to display clear help for multiple command semantics, + # indistinguisable for argparse. (fabien, 201306) return parser - -def command(config, ui): - """List existing tags""" +def command(config, ui, referenceOrTag, tags): + """Add, remove and show tags""" rp = Repository.from_directory(config) - for tag in rp.get_tags(): - ui.print_(tag) + + if referenceOrTag is None: + for tag in rp.get_tags(): + ui.print_(tag) + else: + try: + citekey = rp.citekey_from_ref(referenceOrTag) + p = rp.get_paper(citekey) + if tags is None: + ui.print_(' '.join(p.tags)) + else: + tags = tags.split(',') + for tag in tags: + if tag[0] == ':': + p.remove_tag(tag[1:]) + else: + p.add_tag(tag) + rp.save_paper(p) + except InvalidReference: + tag = referenceOrTag + papers_list = [(p, n) for n, p in enumerate(rp.all_papers()) + if tag in p.tags] + ui.print_('\n'.join(helpers.paper_oneliner(p, n) + for p, n in papers_list)) \ No newline at end of file diff --git a/papers/paper.py b/papers/paper.py index 55d5705..037b5a6 100644 --- a/papers/paper.py +++ b/papers/paper.py @@ -69,6 +69,7 @@ def get_safe_metadata(meta): base_meta = Paper.create_meta() if meta is not None: base_meta.update(meta) + base_meta['tags'] = set(base_meta['tags']) return base_meta @@ -266,11 +267,8 @@ class Paper(object): self.tags.add(tag) def remove_tag(self, tag): - """Remove a tag from a paper. Fails silently.""" - try: - self.tags.pop(tag) - except KeyError: - pass + """Remove a tag from a paper if present.""" + self.tags.discard(tag) class PaperInRepo(Paper): # TODO document why this class exists (fabien, 2013/06) From 52a95af1841d9465b579295e993ad3b646a943c0 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 11:55:36 +0200 Subject: [PATCH 09/13] renamed tags command into tag --- papers/commands/__init__.py | 2 +- papers/commands/{tags_cmd.py => tag_cmd.py} | 2 +- papers/papers | 24 ++++++++++----------- 3 files changed, 14 insertions(+), 14 deletions(-) rename papers/commands/{tags_cmd.py => tag_cmd.py} (94%) diff --git a/papers/commands/__init__.py b/papers/commands/__init__.py index 5ee8934..26691fa 100644 --- a/papers/commands/__init__.py +++ b/papers/commands/__init__.py @@ -8,6 +8,6 @@ import open_cmd import edit_cmd import remove_cmd import websearch_cmd -import tags_cmd +import tag_cmd import attach_cmd import update_cmd diff --git a/papers/commands/tags_cmd.py b/papers/commands/tag_cmd.py similarity index 94% rename from papers/commands/tags_cmd.py rename to papers/commands/tag_cmd.py index 7d8eab7..398d8a2 100644 --- a/papers/commands/tags_cmd.py +++ b/papers/commands/tag_cmd.py @@ -19,7 +19,7 @@ from ..repo import Repository, InvalidReference from . import helpers def parser(subparsers, config): - parser = subparsers.add_parser('tags', help="add, remove and show tags") + parser = subparsers.add_parser('tag', help="add, remove and show tags") parser.add_argument('referenceOrTag', nargs='?', default = None, help='reference to the paper (citekey or number), or ' 'tag.') diff --git a/papers/papers b/papers/papers index 7f5edfe..1399f67 100755 --- a/papers/papers +++ b/papers/papers @@ -10,19 +10,19 @@ from papers import configs from papers import commands cmds = collections.OrderedDict([ - ('init', commands.init_cmd), - ('add', commands.add_cmd), + ('init', commands.init_cmd), + ('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), - ('remove', commands.remove_cmd), - ('open', commands.open_cmd), - ('websearch', commands.websearch_cmd), - ('tags', commands.tags_cmd), - ('attach', commands.attach_cmd), - ('update', commands.update_cmd), + ('import', commands.import_cmd), + ('export', commands.export_cmd), + ('list', commands.list_cmd), + ('edit', commands.edit_cmd), + ('remove', commands.remove_cmd), + ('open', commands.open_cmd), + ('websearch', commands.websearch_cmd), + ('tag', commands.tag_cmd), + ('attach', commands.attach_cmd), + ('update', commands.update_cmd), ]) config = configs.read_config() From eb10c0dff1816fc3020bd4c640d07465743d360a Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 12:00:09 +0200 Subject: [PATCH 10/13] FIX s/label/tags/ in add_cmd --- papers/commands/add_cmd.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/papers/commands/add_cmd.py b/papers/commands/add_cmd.py index bea1d6c..5da2d02 100644 --- a/papers/commands/add_cmd.py +++ b/papers/commands/add_cmd.py @@ -10,7 +10,7 @@ def parser(subparsers, config): parser.add_argument('-b', '--bibfile', help='bibtex, bibtexml or bibyaml file', default=None) parser.add_argument('-d', '--docfile', help='pdf or ps file', default=None) - parser.add_argument('-l', '--label', help='label associated to the paper', + parser.add_argument('-t', '--tags', help='tags associated to the paper, separated by commas', default=None) parser.add_argument('-c', '--copy', action='store_true', default=None, help="copy document files into library directory (default)") @@ -19,7 +19,7 @@ def parser(subparsers, config): return parser -def command(config, ui, bibfile, docfile, label, copy): +def command(config, ui, bibfile, docfile, tags, copy): """ :param bibfile: bibtex file (in .bib, .bibml or .yaml format. :param docfile: path (no url yet) to a pdf or ps file @@ -44,8 +44,8 @@ def command(config, ui, bibfile, docfile, label, copy): p = Paper(bibentry=bib, citekey=key) else: p = Paper.load(bibfile) - if label is not None: - p.tags = set(label.split()) + if tags is not None: + p.tags = set(tags.split(',')) # Check if another doc file is specified in bibtex docfile2 = extract_doc_path_from_bibdata(p, ui) if docfile is None: From 0fe6b50dc2147ef9375e034b227c8c869b108486 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 14:28:18 +0200 Subject: [PATCH 11/13] clarified user prompt in add_cmd --- papers/commands/add_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/papers/commands/add_cmd.py b/papers/commands/add_cmd.py index 5da2d02..8a97537 100644 --- a/papers/commands/add_cmd.py +++ b/papers/commands/add_cmd.py @@ -37,7 +37,7 @@ def command(config, ui, bibfile, docfile, tags, copy): cont = False except Exception: cont = ui.input_yn( - question='Invalid bibfile. Edit again or abort?', + question='Invalid bibfile. Edit again ?', default='y') if not cont: ui.exit() From 2981d6d9cc8d7f3c2a93abf835edb3e230c71995 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 15:17:03 +0200 Subject: [PATCH 12/13] websearch accepts multiple keyword --- papers/commands/websearch_cmd.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/papers/commands/websearch_cmd.py b/papers/commands/websearch_cmd.py index f12b70f..be05e4e 100644 --- a/papers/commands/websearch_cmd.py +++ b/papers/commands/websearch_cmd.py @@ -5,12 +5,13 @@ import urllib def parser(subparsers, config): parser = subparsers.add_parser('websearch', help="launch a search on Google Scholar") - parser.add_argument("search_string", + parser.add_argument("search_string", nargs = '*', help="the search query (anything googly is possible)") return parser def command(config, ui, search_string): + print search_string url = ("https://scholar.google.fr/scholar?q=%s&lr=" - % (urllib.quote_plus(search_string))) + % (urllib.quote_plus(' '.join(search_string)))) webbrowser.open(url) From 467e9f471344f8d2be3205259d1e314461e18ba1 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 15:34:26 +0200 Subject: [PATCH 13/13] add_cmd automatically recognize the format when using the editor --- papers/files.py | 39 ++++++++++++++++++++++++++++++++------- papers/paper.py | 2 +- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/papers/files.py b/papers/files.py index 752262c..8be8a5d 100644 --- a/papers/files.py +++ b/papers/files.py @@ -1,6 +1,7 @@ import os import subprocess import tempfile +from cStringIO import StringIO import yaml @@ -122,7 +123,7 @@ def load_externalbibfile(fullbibpath): filename, ext = os.path.splitext(os.path.split(fullbibpath)[1]) if ext[1:] in FORMATS_INPUT.keys(): with open(fullbibpath) as f: - return parse_bibdata(f, ext[1:]) + return _parse_bibdata_formated_stream(f, ext[1:]) else: print('{}: {} not recognized format for bibliography'.format( color.dye('error', color.error), @@ -130,14 +131,38 @@ def load_externalbibfile(fullbibpath): exit(-1) -def parse_bibdata(content, format_): - """Parse bib data from string. - +def _parse_bibdata_formated_stream(stream, fmt): + """Parse a stream for bibdata, using the supplied format.""" + try: + parser = FORMATS_INPUT[fmt].Parser() + data = parser.parse_stream(stream) + if data.entries.keys() > 0: + return data + except Exception: + pass + raise ValueError, 'content format is not recognized.' + +def parse_bibdata(content, format_ = None): + """Parse bib data from string or stream. + + Raise ValueError if no bibdata is present. :content: stream - :param format_: (bib|xml|yml) + :param format_: (bib|xml|yml) if format is None, tries to recognize the + format automatically. """ - parser = FORMATS_INPUT[format_].Parser() - return parser.parse_stream(content) + fmts = [format_] + if format_ is None: + fmts = FORMATS_INPUT.keys() + # we need to reuse the content + content = content if type(content) == str else str(content.read()) + + for fmt in fmts: + try: + return _parse_bibdata_formated_stream(StringIO(content), fmt) + except Exception: + pass + + raise ValueError, 'content format is not recognized.' def editor_input(config, initial="", suffix=None): diff --git a/papers/paper.py b/papers/paper.py index 037b5a6..d0405a5 100644 --- a/papers/paper.py +++ b/papers/paper.py @@ -44,7 +44,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), 'yml') + bib_data = files.parse_bibdata(StringIO(content)) first_key = bib_data.entries.keys()[0] first_entry = bib_data.entries[first_key] return first_key, first_entry