Merge branch 'master' into feat/new_config

Add StringIO and BytesIO to FakeIO.
Fixes bytes/string problem in update()
main
Fabien Benureau 9 years ago
commit 392ee0c3c1

@ -19,33 +19,29 @@ The different use cases are :
import re
from ..repo import Repository, InvalidReference
from ..repo import Repository
from ..uis import get_ui
from .. import pretty
from .. import color
def parser(subparsers):
parser = subparsers.add_parser('tag', help="add, remove and show tags")
parser.add_argument('citekeyOrTag', nargs='?', default = None,
parser.add_argument('citekeyOrTag', nargs='?', default=None,
help='citekey or tag.')
parser.add_argument('tags', nargs='*', default = None,
parser.add_argument('tags', nargs='?', default=None,
help='If the previous argument was a citekey, then '
'then a list of tags separated by a +.')
'a list of tags separated by a +.')
# TODO find a way to display clear help for multiple command semantics,
# indistinguisable for argparse. (fabien, 201306)
return parser
def _parse_tags(list_tags):
"""Transform 'math-ai network -search' in ['+math', '-ai', '+network', '-search']"""
tags = []
for s in list_tags:
tags += _parse_tag_seq(s)
return tags
def _parse_tag_seq(s):
"""Transform 'math-ai' in ['+math', '-ai']"""
tags = []
if s[0] == ':':
s = '-' + s[1:]
if s[0] not in ['+', '-']:
s = '+' + s
last = 0
@ -62,6 +58,7 @@ def _parse_tag_seq(s):
tags.append(s[last:])
return tags
def _tag_groups(tags):
plus_tags, minus_tags = [], []
for tag in tags:
@ -79,7 +76,6 @@ def command(conf, args):
citekeyOrTag = args.citekeyOrTag
tags = args.tags
rp = Repository(conf)
if citekeyOrTag is None:
@ -87,20 +83,21 @@ def command(conf, args):
else:
if rp.databroker.exists(citekeyOrTag):
p = rp.pull_paper(citekeyOrTag)
if tags == []:
if tags is None:
ui.message(color.dye_out(' '.join(sorted(p.tags)), 'tag'))
else:
add_tags, remove_tags = _tag_groups(_parse_tags(tags))
add_tags, remove_tags = _tag_groups(_parse_tag_seq(tags))
for tag in add_tags:
p.add_tag(tag)
for tag in remove_tags:
p.remove_tag(tag)
rp.push_paper(p, overwrite=True)
elif tags is not None:
ui.error(ui.error('no entry found for citekey {}.'.format(citekeyOrTag)))
ui.exit()
else:
# case where we want to find papers with specific tags
all_tags = [citekeyOrTag]
all_tags += tags
included, excluded = _tag_groups(_parse_tags(all_tags))
included, excluded = _tag_groups(_parse_tag_seq(citekeyOrTag))
papers_list = []
for p in rp.all_papers():
if (p.tags.issuperset(included) and
@ -108,4 +105,4 @@ def command(conf, args):
papers_list.append(p)
ui.message('\n'.join(pretty.paper_oneliner(p)
for p in papers_list))
for p in papers_list))

@ -27,11 +27,13 @@ def _get_encoding(conf):
return enc or 'utf-8'
return conf.get('terminal-encoding', enc or 'utf-8')
def get_ui():
if _ui is None:
return PrintUI() # no editor support. (#FIXME?)
return _ui
def init_ui(conf):
global _ui
_ui = InputUI(conf)

@ -1,6 +1,6 @@
import shutil
import StringIO
import io
from . import config
from . import uis
from . import color
@ -81,7 +81,7 @@ def update(conf, code_version, repo_version, path=None):
# comparing potential changes
with open(path, 'r') as f:
old_conf_text = f.read()
new_conf_text = StringIO.StringIO()
new_conf_text = io.BytesIO()
default_conf.write(outfile=new_conf_text)
if new_conf_text.getvalue() != old_conf_text:

@ -52,6 +52,17 @@ This ensure that your reference file is always up-to-date; you can cite a paper
and then add `\cite{Loeb_2012}` in your manuscript. After running the bash script, the citation will correctly appear in your compiled pdf.
Customization
-------------
Pubs is designed to interact well with your command line tool chain. You can add custom commands to pubs by defining aliases in your config file. Here are a few examples.
[alias]
print = open -w lp
count = !pubs list -k | wc -l
For more advanced functionalities, pubs also support plugins. Actually *alias* is itself a plugin!
Requirements
------------
- python >= 2.7 or >= 3.3

@ -103,6 +103,8 @@ class FakeIO(object):
fakefs_stringio = self.fake_open.Call(*args, **kwargs)
return UnicodeStringIOWrapper(fakefs_stringio)
BytesIO = real_io.BytesIO
StringIO = real_io.StringIO
def create_fake_fs(module_list):

@ -2,20 +2,25 @@
import unittest
import dotdot
from pubs.commands.tag_cmd import _parse_tags, _tag_groups
from pubs.commands.tag_cmd import _parse_tag_seq, _tag_groups
class TestTag(unittest.TestCase):
def test_tag_parsing(self):
def test_parse_tags(self):
self.assertEqual(['+abc', '+def9'], _parse_tag_seq('abc+def9'))
self.assertEqual(['+abc', '-def9'], _parse_tag_seq('abc-def9'))
self.assertEqual(['-abc', '-def9'], _parse_tag_seq('-abc-def9'))
self.assertEqual(['+abc', '-def9'], _parse_tag_seq('+abc-def9'))
self.assertEqual(['+abc', '+def9'], _parse_tags([ 'abc+def9']))
self.assertEqual(['+abc', '-def9'], _parse_tags([ 'abc-def9']))
self.assertEqual(['-abc', '-def9'], _parse_tags(['-abc-def9']))
self.assertEqual(['+abc', '-def9'], _parse_tags(['+abc-def9']))
self.assertEqual(({'math', 'romance'}, {'war'}), _tag_groups(_parse_tags(['-war+math+romance'])))
self.assertEqual(({'math', 'romance'}, {'war'}), _tag_groups(_parse_tags(['+math+romance-war'])))
self.assertEqual(({'math', 'romance'}, {'war'}), _tag_groups(_parse_tags(['math+romance-war'])))
def test_tag_groups(self):
self.assertEqual(({'math', 'romance'}, {'war'}),
_tag_groups(_parse_tag_seq('-war+math+romance')))
self.assertEqual(({'math', 'romance'}, {'war'}),
_tag_groups(_parse_tag_seq(':war+math+romance')))
self.assertEqual(({'math', 'romance'}, {'war'}),
_tag_groups(_parse_tag_seq('+math+romance-war')))
self.assertEqual(({'math', 'romance'}, {'war'}),
_tag_groups(_parse_tag_seq('math+romance-war')))
if __name__ == '__main__':

@ -7,8 +7,7 @@ import os
import dotdot
import fake_env
from pubs import pubs_cmd
from pubs import color, content, filebroker, uis, p3, endecoder
from pubs import pubs_cmd, update, color, content, filebroker, uis, p3, endecoder
from pubs.config import conf
import configobj
@ -58,7 +57,7 @@ class CommandTestCase(unittest.TestCase):
maxDiff = 1000000
def setUp(self):
self.fs = fake_env.create_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj])
self.fs = fake_env.create_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj, update])
self.default_pubs_dir = self.fs['os'].path.expanduser('~/.pubs')
def execute_cmds(self, cmds, capture_output=CAPTURE_OUTPUT):
@ -118,7 +117,7 @@ class DataCommandTestCase(CommandTestCase):
"""
def setUp(self):
CommandTestCase.setUp(self)
super(DataCommandTestCase, self).setUp()
fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'data'), 'data')
@ -251,6 +250,76 @@ class TestList(DataCommandTestCase):
self.assertEqual(0 + 1, len(outs[-1].split('\n')))
class TestTag(DataCommandTestCase):
def setUp(self):
super(TestTag, self).setUp()
init = ['pubs init',
'pubs add data/pagerank.bib',
'pubs add -k Turing1950 data/turing1950.bib',
]
self.execute_cmds(init)
def test_add_tag(self):
cmds = ['pubs tag Page99 search',
'pubs tag Turing1950 ai',
'pubs list',
]
correct = ['',
'',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | search\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) | ai\n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_add_tags(self):
"""Adds several tags at once.
Also checks that tags printed in alphabetic order.
"""
cmds = ['pubs tag Page99 search+network',
'pubs list',
]
correct = ['',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | network,search\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) \n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_remove_tag(self):
cmds = ['pubs tag Page99 search+network',
'pubs tag Page99 :network',
'pubs list',
]
correct = ['',
'',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | search\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) \n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_add_remove_tag(self):
cmds = ['pubs tag Page99 a',
'pubs tag Page99 b-a',
'pubs list',
]
correct = ['',
'',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | b\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) \n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_wrong_citekey(self):
cmds = ['pubs tag Page999 a',
]
with self.assertRaises(SystemExit):
self.execute_cmds(cmds)
class TestUsecase(DataCommandTestCase):
def test_first(self):

Loading…
Cancel
Save