Better handle utf-8 citekeys
Utf-8 citekeys generate errors in bibtexparser. Until this is fixed, this commit replace the stack-trace by a clear error message. related: #28
This commit is contained in:
parent
402cf62db0
commit
f843aebcbd
@ -24,13 +24,15 @@ def str2citekey(s):
|
|||||||
def check_citekey(citekey):
|
def check_citekey(citekey):
|
||||||
# TODO This is not the right way to test that (17/12/2012)
|
# TODO This is not the right way to test that (17/12/2012)
|
||||||
if ustr(citekey) != str2citekey(citekey):
|
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):
|
def verify_bibdata(bibdata):
|
||||||
if bibdata is None or len(bibdata) == 0:
|
if bibdata is None or len(bibdata) == 0:
|
||||||
raise ValueError('no valid bibdata')
|
raise ValueError(u"no valid bibdata")
|
||||||
if len(bibdata) > 1:
|
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):
|
def get_entry(bibdata):
|
||||||
verify_bibdata(bibdata)
|
verify_bibdata(bibdata)
|
||||||
@ -59,7 +61,7 @@ def generate_citekey(bibdata):
|
|||||||
first_author = entry[author_key][0]
|
first_author = entry[author_key][0]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'No author or editor defined: cannot generate a citekey.')
|
u"No author or editor defined: cannot generate a citekey.")
|
||||||
try:
|
try:
|
||||||
year = entry['year']
|
year = entry['year']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -106,7 +106,11 @@ def command(conf, args):
|
|||||||
ui.error('citekey already exist {}.'.format(citekey))
|
ui.error('citekey already exist {}.'.format(citekey))
|
||||||
ui.exit(1)
|
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
|
# tags
|
||||||
|
|
||||||
|
@ -77,10 +77,10 @@ def command(conf, args):
|
|||||||
try:
|
try:
|
||||||
p = papers[k]
|
p = papers[k]
|
||||||
if isinstance(p, Exception):
|
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:
|
else:
|
||||||
rp.push_paper(p)
|
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)
|
docfile = bibstruct.extract_docfile(p.bibdata)
|
||||||
if docfile is None:
|
if docfile is None:
|
||||||
ui.warning("No file for {}.".format(p.citekey))
|
ui.warning("No file for {}.".format(p.citekey))
|
||||||
@ -88,6 +88,6 @@ def command(conf, args):
|
|||||||
rp.push_doc(p.citekey, docfile, copy=copy)
|
rp.push_doc(p.citekey, docfile, copy=copy)
|
||||||
#FIXME should move the file if configured to do so.
|
#FIXME should move the file if configured to do so.
|
||||||
except KeyError:
|
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:
|
except IOError as e:
|
||||||
ui.error(e.message)
|
ui.error(e.message)
|
||||||
|
16
pubs/uis.py
16
pubs/uis.py
@ -60,15 +60,15 @@ class PrintUI(object):
|
|||||||
|
|
||||||
def info(self, message, **kwargs):
|
def info(self, message, **kwargs):
|
||||||
kwargs['file'] = self._stderr
|
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):
|
def warning(self, message, **kwargs):
|
||||||
kwargs['file'] = self._stderr
|
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):
|
def error(self, message, **kwargs):
|
||||||
kwargs['file'] = self._stderr
|
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):
|
def exit(self, error_code=1):
|
||||||
sys.exit(error_code)
|
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
|
if len(set(option_chars)) != len(option_chars): # duplicate chars, char choices are deactivated. #FIXME: should only deactivate ambiguous chars
|
||||||
option_chars = []
|
option_chars = []
|
||||||
|
|
||||||
option_str = '/'.join(["{}{}".format(color.dye_out(c, 'bold'), s[1:])
|
option_str = u'/'.join(["{}{}".format(color.dye_out(c, 'bold'), s[1:])
|
||||||
for c, s in zip(displayed_chars, options)])
|
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:
|
while True:
|
||||||
answer = self.input()
|
answer = self.input()
|
||||||
if answer is None or answer == '':
|
if answer is None or answer == '':
|
||||||
@ -126,7 +126,7 @@ class InputUI(PrintUI):
|
|||||||
return option_chars.index(answer.lower())
|
return option_chars.index(answer.lower())
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
self.message('Incorrect option.', option_str)
|
self.message(u'Incorrect option.', option_str)
|
||||||
|
|
||||||
|
|
||||||
def input_choice(self, options, option_chars, default=None, question=''):
|
def input_choice(self, options, option_chars, default=None, question=''):
|
||||||
@ -159,7 +159,7 @@ class InputUI(PrintUI):
|
|||||||
return option_chars.index(answer.lower())
|
return option_chars.index(answer.lower())
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
self.message('Incorrect option.', option_str)
|
self.message(u'Incorrect option.', option_str)
|
||||||
|
|
||||||
def input_yn(self, question='', default='y'):
|
def input_yn(self, question='', default='y'):
|
||||||
d = 0 if default in (True, 'y', 'yes') else 1
|
d = 0 if default in (True, 'y', 'yes') else 1
|
||||||
|
8
tests/data/utf8.bib
Normal file
8
tests/data/utf8.bib
Normal file
@ -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}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
@ -168,6 +169,16 @@ class TestAdd(DataCommandTestCase):
|
|||||||
bib_dir = self.fs['os'].path.join(self.default_pubs_dir, 'bib')
|
bib_dir = self.fs['os'].path.join(self.default_pubs_dir, 'bib')
|
||||||
self.assertEqual(set(self.fs['os'].listdir(bib_dir)), {'CustomCitekey.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):
|
def test_add_doc_nocopy_does_not_copy(self):
|
||||||
cmds = ['pubs init',
|
cmds = ['pubs init',
|
||||||
'pubs add /data/pagerank.bib --link -d /data/pagerank.pdf',
|
'pubs add /data/pagerank.bib --link -d /data/pagerank.pdf',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user