Merge branch 'feature/fastercolor' into develop. Read on for details.
The interface of color has changed. color.colored(s, 'red') becomes color.dye(s, color.red) The code behind it is simpler and shorter. The decision to use color or not is made when the UI class is instanciated, and the configuration is read. There is no need to handle it on a per-file basis. The default before repository instanciation is with color, but that might (should) change.
This commit is contained in:
commit
db14fb94f3
@ -1,60 +1,38 @@
|
|||||||
# display
|
"""
|
||||||
|
Small code to handle colored text
|
||||||
|
"""
|
||||||
|
|
||||||
BOLD = '\033[1m'
|
bold = '\033[1m'
|
||||||
END = '\033[0m'
|
end = '\033[0m'
|
||||||
|
|
||||||
COLORS = {
|
black = '\033[0;30m'
|
||||||
'black' : '\033[0;30m',
|
red = '\033[0;31m'
|
||||||
'red' : '\033[0;31m',
|
green = '\033[0;32m'
|
||||||
'green' : '\033[0;32m',
|
yellow = '\033[0;33m'
|
||||||
'yellow': '\033[0;33m',
|
blue = '\033[0;34m'
|
||||||
'blue' : '\033[0;34m',
|
purple = '\033[0;35m'
|
||||||
'purple': '\033[0;35m',
|
cyan = '\033[0;36m'
|
||||||
'cyan' : '\033[0;36m',
|
grey = '\033[0;37m'
|
||||||
'grey' : '\032[0;37m',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Bold
|
ok = green
|
||||||
BCOLORS = {
|
error = red
|
||||||
'black' : '\033[1;30m',
|
normal = grey
|
||||||
'red' : '\033[1;31m',
|
citekey = purple
|
||||||
'green' : '\033[1;32m',
|
filepath = cyan
|
||||||
'yellow': '\033[1;33m',
|
|
||||||
'blue' : '\033[1;34m',
|
|
||||||
'purple': '\033[1;35m',
|
|
||||||
'cyan' : '\033[1;36m',
|
|
||||||
'grey' : '\033[1;37m',
|
|
||||||
}
|
|
||||||
|
|
||||||
# application specific
|
def dye(s, color=end, bold=False):
|
||||||
ALIASES = {
|
assert color[0] == '\033'
|
||||||
'ok' : 'green',
|
if bold:
|
||||||
'error' : 'red',
|
s = '\033[1' + s[3:]
|
||||||
'normal' : 'grey',
|
return color + s + end
|
||||||
'citekey' : 'purple',
|
|
||||||
'filepath': 'cyan',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_dye = dye
|
||||||
def colored(s, color=None, bold=False):
|
def _nodye(s, **kwargs):
|
||||||
if color in ALIASES:
|
|
||||||
color = ALIASES[color]
|
|
||||||
try:
|
|
||||||
if bold:
|
|
||||||
color_code = BCOLORS[color]
|
|
||||||
else:
|
|
||||||
color_code = COLORS[color]
|
|
||||||
except KeyError:
|
|
||||||
if bold:
|
|
||||||
color_code = BOLD
|
|
||||||
else:
|
|
||||||
color_code = ''
|
|
||||||
if color_code != '':
|
|
||||||
end_code = END
|
|
||||||
else:
|
|
||||||
end_code = ''
|
|
||||||
return color_code + s + end_code
|
|
||||||
|
|
||||||
|
|
||||||
def not_colored(s, **kwargs):
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def color_setup(config):
|
||||||
|
global dye
|
||||||
|
if config.getboolean(configs.MAIN_SECTION, 'color'):
|
||||||
|
dye = _dye
|
||||||
|
else:
|
||||||
|
dye = _nodye
|
@ -26,11 +26,11 @@ def command(config, ui, path, doc_dir):
|
|||||||
configs.add_and_write_option('papers', 'papers-directory', papersdir)
|
configs.add_and_write_option('papers', 'papers-directory', papersdir)
|
||||||
if not os.path.exists(papersdir):
|
if not os.path.exists(papersdir):
|
||||||
ui.print_('Initializing papers in {}.'.format(
|
ui.print_('Initializing papers in {}.'.format(
|
||||||
ui.colored(papersdir, 'filepath')))
|
color.dye(papersdir, color.filepath)))
|
||||||
repo = Repository()
|
repo = Repository()
|
||||||
repo.init(papersdir) # Creates directories
|
repo.init(papersdir) # Creates directories
|
||||||
repo.save() # Saves empty repository description
|
repo.save() # Saves empty repository description
|
||||||
else:
|
else:
|
||||||
ui.error('papers already present in {}.'.format(
|
ui.error('papers already present in {}.'.format(
|
||||||
ui.colored(papersdir, 'filepath')))
|
color.dye(papersdir, color.filepath)))
|
||||||
ui.exit()
|
ui.exit()
|
||||||
|
@ -13,13 +13,13 @@ def command(config, ui, cmd):
|
|||||||
articles = []
|
articles = []
|
||||||
for n, p in enumerate(rp.all_papers()):
|
for n, p in enumerate(rp.all_papers()):
|
||||||
if test_paper(cmd, p):
|
if test_paper(cmd, p):
|
||||||
bibdesc = pretty.bib_oneliner(p.bibentry, color=ui.color)
|
bibdesc = pretty.bib_oneliner(p.bibentry)
|
||||||
articles.append((u'{num:d}: [{citekey}] {descr} {labels}'.format(
|
articles.append((u'{num:d}: [{citekey}] {descr} {labels}'.format(
|
||||||
num=int(n),
|
num=int(n),
|
||||||
citekey=ui.colored(rp.citekeys[n], 'purple'),
|
citekey=color.dye(rp.citekeys[n], color.purple),
|
||||||
descr=bibdesc,
|
descr=bibdesc,
|
||||||
labels=ui.colored(' '.join(p.metadata.get('labels', [])),
|
labels=color.dye(' '.join(p.metadata.get('labels', [])),
|
||||||
'purple'),
|
color.purple),
|
||||||
)).encode('utf-8'))
|
)).encode('utf-8'))
|
||||||
ui.print_('\n'.join(articles))
|
ui.print_('\n'.join(articles))
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ def command(config, ui, citekey):
|
|||||||
filepath = paper.get_document_path()
|
filepath = paper.get_document_path()
|
||||||
subprocess.Popen([config.get(configs.MAIN_SECTION, 'open-cmd'),
|
subprocess.Popen([config.get(configs.MAIN_SECTION, 'open-cmd'),
|
||||||
filepath])
|
filepath])
|
||||||
print("%s opened." % ui.colored(filepath, 'filepath'))
|
print('{} opened.'.format(color.dye(filepath, color.filepath)))
|
||||||
except NoDocumentFile:
|
except NoDocumentFile:
|
||||||
ui.error("No document associated with the entry %s."
|
ui.error('No document associated with the entry {}.'.format(
|
||||||
% ui.colored(citekey, 'citekey'))
|
color.dye(citekey, color.citekey)))
|
||||||
ui.exit()
|
ui.exit()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from .. import repo
|
from .. import repo
|
||||||
|
import color
|
||||||
|
|
||||||
def parser(subparsers, config):
|
def parser(subparsers, config):
|
||||||
parser = subparsers.add_parser('remove', help='removes a paper')
|
parser = subparsers.add_parser('remove', help='removes a paper')
|
||||||
@ -14,7 +14,7 @@ def command(config, ui, reference):
|
|||||||
paper = rp.paper_from_citekey(key)
|
paper = rp.paper_from_citekey(key)
|
||||||
are_you_sure = ("Are you sure you want to delete paper [%s]"
|
are_you_sure = ("Are you sure you want to delete paper [%s]"
|
||||||
" (this will also delete associated documents)?"
|
" (this will also delete associated documents)?"
|
||||||
% ui.colored(paper.citekey, color='citekey'))
|
% color.dye(paper.citekey, color.citekey))
|
||||||
sure = ui.input_yn(question=are_you_sure, default='n')
|
sure = ui.input_yn(question=are_you_sure, default='n')
|
||||||
if sure:
|
if sure:
|
||||||
rp.remove(paper.citekey)
|
rp.remove(paper.citekey)
|
||||||
|
@ -4,7 +4,7 @@ import tempfile
|
|||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from .color import colored
|
from . import ui
|
||||||
from . import configs
|
from . import configs
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -20,9 +20,9 @@ try:
|
|||||||
import pybtex.database.output.bibyaml
|
import pybtex.database.output.bibyaml
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print(colored('error', 'error')
|
print(ui.dye('error', ui.error) +
|
||||||
+ ': you need to install Pybtex; try running \'pip install'
|
": you need to install Pybtex; try running 'pip install"
|
||||||
'pybtex\' or \'easy_install pybtex\'')
|
"pybtex' or 'easy_install pybtex'")
|
||||||
|
|
||||||
|
|
||||||
_papersdir = None
|
_papersdir = None
|
||||||
@ -49,9 +49,9 @@ def name_from_path(fullpdfpath, verbose=False):
|
|||||||
name, ext = os.path.splitext(os.path.split(fullpdfpath)[1])
|
name, ext = os.path.splitext(os.path.split(fullpdfpath)[1])
|
||||||
if verbose:
|
if verbose:
|
||||||
if ext != '.pdf' and ext != '.ps':
|
if ext != '.pdf' and ext != '.ps':
|
||||||
print(colored('warning', 'yellow')
|
print('{}: extension {} not recognized'.format(
|
||||||
+ '{: extension {ext} not recognized'.format(
|
color.dye('warning', color.warning),
|
||||||
ext=colored(ext, 'cyan')))
|
color.dye(ext, color.cyan)))
|
||||||
return name, ext
|
return name, ext
|
||||||
|
|
||||||
|
|
||||||
@ -73,9 +73,9 @@ def write_yamlfile(filepath, datamap):
|
|||||||
with open(filepath, 'w') as f:
|
with open(filepath, 'w') as f:
|
||||||
yaml.dump(datamap, f)
|
yaml.dump(datamap, f)
|
||||||
except IOError:
|
except IOError:
|
||||||
print(colored('error', 'error')
|
print('{}: impossible to read or write on file {}'.format(
|
||||||
+ ': impossible to read file {}'.format(
|
color.dye('error', color.error),
|
||||||
colored(filepath, 'filepath')))
|
color.dye(filepath, color.filepath)))
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
@ -85,9 +85,9 @@ def read_yamlfile(filepath):
|
|||||||
with open(filepath, 'r') as f:
|
with open(filepath, 'r') as f:
|
||||||
return yaml.load(f)
|
return yaml.load(f)
|
||||||
except IOError:
|
except IOError:
|
||||||
print(colored('error', 'error')
|
print('{}: impossible to read file {}'.format(
|
||||||
+ ': impossible to read file {}'.format(
|
color.dye('error', color.error),
|
||||||
colored(filepath, 'filepath')))
|
color.dye(filepath, color.filepath)))
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
@ -123,9 +123,9 @@ def load_externalbibfile(fullbibpath):
|
|||||||
with open(fullbibpath) as f:
|
with open(fullbibpath) as f:
|
||||||
return parse_bibdata(f, ext[1:])
|
return parse_bibdata(f, ext[1:])
|
||||||
else:
|
else:
|
||||||
print(colored('error', 'error')
|
print('{}: {} not recognized format for bibliography'.format(
|
||||||
+ ': {} not recognized format for bibliography'.format(
|
color.dye('error', color.error),
|
||||||
colored(ext, 'cyan')))
|
color.dye(ext, color.cyan)))
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from ...color import colored
|
|
||||||
from ... import repo
|
from ... import repo
|
||||||
from ...paper import NoDocumentFile
|
from ...paper import NoDocumentFile
|
||||||
from ... import configs
|
from ... import configs
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# display formatting
|
# display formatting
|
||||||
|
|
||||||
from color import colored, not_colored
|
from . import color
|
||||||
from pybtex.bibtex.utils import bibtex_purify
|
from pybtex.bibtex.utils import bibtex_purify
|
||||||
|
|
||||||
|
|
||||||
@ -27,10 +27,6 @@ def short_authors(bibentry):
|
|||||||
|
|
||||||
|
|
||||||
def bib_oneliner(bibentry, color=True):
|
def bib_oneliner(bibentry, color=True):
|
||||||
if color:
|
|
||||||
col_func = colored
|
|
||||||
else:
|
|
||||||
col_func = not_colored
|
|
||||||
authors = short_authors(bibentry)
|
authors = short_authors(bibentry)
|
||||||
title = bibtex_purify(bibentry.fields['title'])
|
title = bibtex_purify(bibentry.fields['title'])
|
||||||
year = bibtex_purify(bibentry.fields.get('year', ''))
|
year = bibtex_purify(bibentry.fields.get('year', ''))
|
||||||
@ -40,9 +36,9 @@ def bib_oneliner(bibentry, color=True):
|
|||||||
field = 'booktitle'
|
field = 'booktitle'
|
||||||
journal = bibtex_purify(bibentry.fields.get(field, ''))
|
journal = bibtex_purify(bibentry.fields.get(field, ''))
|
||||||
return u'{authors} \"{title}\" {journal} ({year})'.format(
|
return u'{authors} \"{title}\" {journal} ({year})'.format(
|
||||||
authors=col_func(authors, 'cyan'),
|
authors=color.dye(authors, color.cyan),
|
||||||
title=title,
|
title=title,
|
||||||
journal=col_func(journal, 'yellow'),
|
journal=color.dye(journal, color.yellow),
|
||||||
year=year,
|
year=year,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import glob
|
|||||||
|
|
||||||
from . import files
|
from . import files
|
||||||
from .paper import PaperInRepo, NoDocumentFile
|
from .paper import PaperInRepo, NoDocumentFile
|
||||||
from .color import colored
|
from . import color
|
||||||
from . import configs
|
from . import configs
|
||||||
|
|
||||||
|
|
||||||
@ -48,9 +48,9 @@ class Repository(object):
|
|||||||
return self.citekeys[int(ref)]
|
return self.citekeys[int(ref)]
|
||||||
except (IndexError, ValueError):
|
except (IndexError, ValueError):
|
||||||
if fatal:
|
if fatal:
|
||||||
print(colored('error', 'error')
|
print('{}: no paper with reference {}'.format(
|
||||||
+ ': no paper with reference {}'.format(
|
color.dye('error', color.error),
|
||||||
colored(ref, 'citekey')))
|
color.dye(ref, color.citekey)))
|
||||||
exit(-1)
|
exit(-1)
|
||||||
raise(IOError('file not found'))
|
raise(IOError('file not found'))
|
||||||
|
|
||||||
|
16
papers/ui.py
16
papers/ui.py
@ -2,7 +2,7 @@ import sys
|
|||||||
|
|
||||||
from .beets_ui import _encoding, input_
|
from .beets_ui import _encoding, input_
|
||||||
|
|
||||||
from .color import colored
|
from . import color
|
||||||
from . import configs
|
from . import configs
|
||||||
|
|
||||||
|
|
||||||
@ -12,13 +12,7 @@ class UI:
|
|||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.encoding = _encoding(config)
|
self.encoding = _encoding(config)
|
||||||
self.color = config.getboolean(configs.MAIN_SECTION, 'color')
|
color.setup(config)
|
||||||
|
|
||||||
def colored(self, s, *args, **kwargs):
|
|
||||||
if self.color:
|
|
||||||
return colored(s, *args, **kwargs)
|
|
||||||
else:
|
|
||||||
return s
|
|
||||||
|
|
||||||
def print_(self, *strings):
|
def print_(self, *strings):
|
||||||
"""Like print, but rather than raising an error when a character
|
"""Like print, but rather than raising an error when a character
|
||||||
@ -47,7 +41,7 @@ class UI:
|
|||||||
"""
|
"""
|
||||||
displayed_chars = [s.upper() if i == default else s
|
displayed_chars = [s.upper() if i == default else s
|
||||||
for i, s in enumerate(option_chars)]
|
for i, s in enumerate(option_chars)]
|
||||||
option_str = ', '.join(["[%s]%s" % (self.colored(c, 'cyan'), o)
|
option_str = ', '.join(["[%s]%s" % (color.dye(c, color.cyan), o)
|
||||||
for c, o in zip(displayed_chars, options)])
|
for c, o in zip(displayed_chars, options)])
|
||||||
self.print_(question, option_str)
|
self.print_(question, option_str)
|
||||||
while True:
|
while True:
|
||||||
@ -71,7 +65,7 @@ class UI:
|
|||||||
sys.exit(error_code)
|
sys.exit(error_code)
|
||||||
|
|
||||||
def error(self, message):
|
def error(self, message):
|
||||||
self.print_("%s: %s" % (colored('error', 'red'), message))
|
self.print_("%s: %s" % (color.dye('error', color.red), message))
|
||||||
|
|
||||||
def warning(self, message):
|
def warning(self, message):
|
||||||
self.print_("%s: %s" % (colored('warning', 'yellow'), message))
|
self.print_("%s: %s" % (color.dye('warning', color.yellow), message))
|
||||||
|
10
tests/test_color.py
Normal file
10
tests/test_color.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import testenv
|
||||||
|
from papers import color
|
||||||
|
|
||||||
|
def perf_color():
|
||||||
|
s = str(range(1000))
|
||||||
|
for _ in range(5000000):
|
||||||
|
color.dye(s, color.red)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
perf_color()
|
3
tests/testenv.py
Normal file
3
tests/testenv.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Adjusting paths.
|
||||||
|
import os, sys
|
||||||
|
sys.path.insert(0, os.path.abspath(os.path.join(__file__, '../..')))
|
Loading…
x
Reference in New Issue
Block a user