diff --git a/pubs/bibstruct.py b/pubs/bibstruct.py index c21af76..bc6f6b9 100644 --- a/pubs/bibstruct.py +++ b/pubs/bibstruct.py @@ -24,13 +24,15 @@ def str2citekey(s): def check_citekey(citekey): # TODO This is not the right way to test that (17/12/2012) if ustr(citekey) != str2citekey(citekey): - raise ValueError("Invalid citekey: %s" % citekey) + raise ValueError(u"Invalid `{}` citekey; ".format(citekey) + + u"utf-8 citekeys are not supported yet.\n" + u"See https://github.com/pubs/pubs/issues/28 for details.") def verify_bibdata(bibdata): if bibdata is None or len(bibdata) == 0: - raise ValueError('no valid bibdata') + raise ValueError(u"no valid bibdata") if len(bibdata) > 1: - raise ValueError('ambiguous: multiple entries in the bibdata.') + raise ValueError(u"ambiguous: multiple entries in the bibdata.") def get_entry(bibdata): verify_bibdata(bibdata) @@ -59,7 +61,7 @@ def generate_citekey(bibdata): first_author = entry[author_key][0] except KeyError: raise ValueError( - 'No author or editor defined: cannot generate a citekey.') + u"No author or editor defined: cannot generate a citekey.") try: year = entry['year'] except KeyError: diff --git a/pubs/commands/add_cmd.py b/pubs/commands/add_cmd.py index 6267a47..1fb2dd9 100644 --- a/pubs/commands/add_cmd.py +++ b/pubs/commands/add_cmd.py @@ -106,7 +106,11 @@ def command(conf, args): ui.error('citekey already exist {}.'.format(citekey)) ui.exit(1) - p = paper.Paper.from_bibentry(bibentry, citekey=citekey) + try: + p = paper.Paper.from_bibentry(bibentry, citekey=citekey) + except Exception as e: + ui.error(e.args[0]) + ui.exit(1) # tags diff --git a/pubs/commands/import_cmd.py b/pubs/commands/import_cmd.py index e9ffa94..128acd8 100644 --- a/pubs/commands/import_cmd.py +++ b/pubs/commands/import_cmd.py @@ -77,10 +77,10 @@ def command(conf, args): try: p = papers[k] if isinstance(p, Exception): - ui.error('Could not load entry for citekey {}.'.format(k)) + ui.error(u'Could not load entry for citekey {}.'.format(k)) else: rp.push_paper(p) - ui.info('{} imported.'.format(color.dye_out(p.citekey, 'citekey'))) + ui.info(u'{} imported.'.format(color.dye_out(p.citekey, 'citekey'))) docfile = bibstruct.extract_docfile(p.bibdata) if docfile is None: ui.warning("No file for {}.".format(p.citekey)) @@ -88,6 +88,6 @@ def command(conf, args): rp.push_doc(p.citekey, docfile, copy=copy) #FIXME should move the file if configured to do so. except KeyError: - ui.error('No entry found for citekey {}.'.format(k)) + ui.error(u'No entry found for citekey {}.'.format(k)) except IOError as e: ui.error(e.message) diff --git a/pubs/uis.py b/pubs/uis.py index bc503ac..0fb354d 100644 --- a/pubs/uis.py +++ b/pubs/uis.py @@ -60,15 +60,15 @@ class PrintUI(object): def info(self, message, **kwargs): kwargs['file'] = self._stderr - print('{}: {}'.format(color.dye_err('info', 'ok'), message), **kwargs) + print(u'{}: {}'.format(color.dye_err('info', 'ok'), message), **kwargs) def warning(self, message, **kwargs): kwargs['file'] = self._stderr - print('{}: {}'.format(color.dye_err('warning', 'warning'), message), **kwargs) + print(u'{}: {}'.format(color.dye_err('warning', 'warning'), message), **kwargs) def error(self, message, **kwargs): kwargs['file'] = self._stderr - print('{}: {}'.format(color.dye_err('error', 'error'), message), **kwargs) + print(u'{}: {}'.format(color.dye_err('error', 'error'), message), **kwargs) def exit(self, error_code=1): sys.exit(error_code) @@ -109,10 +109,10 @@ class InputUI(PrintUI): if len(set(option_chars)) != len(option_chars): # duplicate chars, char choices are deactivated. #FIXME: should only deactivate ambiguous chars option_chars = [] - option_str = '/'.join(["{}{}".format(color.dye_out(c, 'bold'), s[1:]) - for c, s in zip(displayed_chars, options)]) + option_str = u'/'.join(["{}{}".format(color.dye_out(c, 'bold'), s[1:]) + for c, s in zip(displayed_chars, options)]) - self.message('{}: {} {}: '.format(color.dye_err('prompt', 'warning'), question, option_str), end='') + self.message(u'{}: {} {}: '.format(color.dye_err('prompt', 'warning'), question, option_str), end='') while True: answer = self.input() if answer is None or answer == '': @@ -126,7 +126,7 @@ class InputUI(PrintUI): return option_chars.index(answer.lower()) except ValueError: pass - self.message('Incorrect option.', option_str) + self.message(u'Incorrect option.', option_str) def input_choice(self, options, option_chars, default=None, question=''): @@ -159,7 +159,7 @@ class InputUI(PrintUI): return option_chars.index(answer.lower()) except ValueError: pass - self.message('Incorrect option.', option_str) + self.message(u'Incorrect option.', option_str) def input_yn(self, question='', default='y'): d = 0 if default in (True, 'y', 'yes') else 1 diff --git a/tests/data/utf8.bib b/tests/data/utf8.bib new file mode 100644 index 0000000..3ea09ad --- /dev/null +++ b/tests/data/utf8.bib @@ -0,0 +1,8 @@ +@book{hausdorff1949grundzüge, + author = {Hausdorff, Felix}, + title = {Grundzüge der Mengenlehre}, + publisher = {Chelsea Pub. Co}, + year = {1949}, + address = {New York}, + isbn = {978-0-8284-0061-9} +} diff --git a/tests/test_usecase.py b/tests/test_usecase.py index 297a686..5bc1ed4 100644 --- a/tests/test_usecase.py +++ b/tests/test_usecase.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import print_function, unicode_literals import unittest @@ -168,6 +169,16 @@ class TestAdd(DataCommandTestCase): bib_dir = self.fs['os'].path.join(self.default_pubs_dir, 'bib') self.assertEqual(set(self.fs['os'].listdir(bib_dir)), {'CustomCitekey.bib'}) + def test_add_utf8_citekey(self): + err = ("error: Invalid `hausdorff1949grundzüge` citekey; " + "utf-8 citekeys are not supported yet.\n" + "See https://github.com/pubs/pubs/issues/28 for details.") # actually not checked + cmds = ['pubs init', + ('pubs add /data/utf8.bib', [], '', err), + ] + with self.assertRaises(SystemExit): + self.execute_cmds(cmds) + def test_add_doc_nocopy_does_not_copy(self): cmds = ['pubs init', 'pubs add /data/pagerank.bib --link -d /data/pagerank.pdf',