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'
|
||||
END = '\033[0m'
|
||||
bold = '\033[1m'
|
||||
end = '\033[0m'
|
||||
|
||||
COLORS = {
|
||||
'black' : '\033[0;30m',
|
||||
'red' : '\033[0;31m',
|
||||
'green' : '\033[0;32m',
|
||||
'yellow': '\033[0;33m',
|
||||
'blue' : '\033[0;34m',
|
||||
'purple': '\033[0;35m',
|
||||
'cyan' : '\033[0;36m',
|
||||
'grey' : '\032[0;37m',
|
||||
}
|
||||
black = '\033[0;30m'
|
||||
red = '\033[0;31m'
|
||||
green = '\033[0;32m'
|
||||
yellow = '\033[0;33m'
|
||||
blue = '\033[0;34m'
|
||||
purple = '\033[0;35m'
|
||||
cyan = '\033[0;36m'
|
||||
grey = '\033[0;37m'
|
||||
|
||||
# Bold
|
||||
BCOLORS = {
|
||||
'black' : '\033[1;30m',
|
||||
'red' : '\033[1;31m',
|
||||
'green' : '\033[1;32m',
|
||||
'yellow': '\033[1;33m',
|
||||
'blue' : '\033[1;34m',
|
||||
'purple': '\033[1;35m',
|
||||
'cyan' : '\033[1;36m',
|
||||
'grey' : '\033[1;37m',
|
||||
}
|
||||
ok = green
|
||||
error = red
|
||||
normal = grey
|
||||
citekey = purple
|
||||
filepath = cyan
|
||||
|
||||
# application specific
|
||||
ALIASES = {
|
||||
'ok' : 'green',
|
||||
'error' : 'red',
|
||||
'normal' : 'grey',
|
||||
'citekey' : 'purple',
|
||||
'filepath': 'cyan',
|
||||
}
|
||||
def dye(s, color=end, bold=False):
|
||||
assert color[0] == '\033'
|
||||
if bold:
|
||||
s = '\033[1' + s[3:]
|
||||
return color + s + end
|
||||
|
||||
|
||||
def colored(s, color=None, bold=False):
|
||||
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):
|
||||
_dye = dye
|
||||
def _nodye(s, **kwargs):
|
||||
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)
|
||||
if not os.path.exists(papersdir):
|
||||
ui.print_('Initializing papers in {}.'.format(
|
||||
ui.colored(papersdir, 'filepath')))
|
||||
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(
|
||||
ui.colored(papersdir, 'filepath')))
|
||||
color.dye(papersdir, color.filepath)))
|
||||
ui.exit()
|
||||
|
@ -13,13 +13,13 @@ def command(config, ui, cmd):
|
||||
articles = []
|
||||
for n, p in enumerate(rp.all_papers()):
|
||||
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(
|
||||
num=int(n),
|
||||
citekey=ui.colored(rp.citekeys[n], 'purple'),
|
||||
citekey=color.dye(rp.citekeys[n], color.purple),
|
||||
descr=bibdesc,
|
||||
labels=ui.colored(' '.join(p.metadata.get('labels', [])),
|
||||
'purple'),
|
||||
labels=color.dye(' '.join(p.metadata.get('labels', [])),
|
||||
color.purple),
|
||||
)).encode('utf-8'))
|
||||
ui.print_('\n'.join(articles))
|
||||
|
||||
|
@ -20,8 +20,8 @@ def command(config, ui, citekey):
|
||||
filepath = paper.get_document_path()
|
||||
subprocess.Popen([config.get(configs.MAIN_SECTION, 'open-cmd'),
|
||||
filepath])
|
||||
print("%s opened." % ui.colored(filepath, 'filepath'))
|
||||
print('{} opened.'.format(color.dye(filepath, color.filepath)))
|
||||
except NoDocumentFile:
|
||||
ui.error("No document associated with the entry %s."
|
||||
% ui.colored(citekey, 'citekey'))
|
||||
ui.error('No document associated with the entry {}.'.format(
|
||||
color.dye(citekey, color.citekey)))
|
||||
ui.exit()
|
||||
|
@ -1,5 +1,5 @@
|
||||
from .. import repo
|
||||
|
||||
import color
|
||||
|
||||
def parser(subparsers, config):
|
||||
parser = subparsers.add_parser('remove', help='removes a paper')
|
||||
@ -14,7 +14,7 @@ def command(config, ui, reference):
|
||||
paper = rp.paper_from_citekey(key)
|
||||
are_you_sure = ("Are you sure you want to delete paper [%s]"
|
||||
" (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')
|
||||
if sure:
|
||||
rp.remove(paper.citekey)
|
||||
|
@ -4,7 +4,7 @@ import tempfile
|
||||
|
||||
import yaml
|
||||
|
||||
from .color import colored
|
||||
from . import ui
|
||||
from . import configs
|
||||
|
||||
try:
|
||||
@ -20,9 +20,9 @@ try:
|
||||
import pybtex.database.output.bibyaml
|
||||
|
||||
except ImportError:
|
||||
print(colored('error', 'error')
|
||||
+ ': you need to install Pybtex; try running \'pip install'
|
||||
'pybtex\' or \'easy_install pybtex\'')
|
||||
print(ui.dye('error', ui.error) +
|
||||
": you need to install Pybtex; try running 'pip install"
|
||||
"pybtex' or 'easy_install pybtex'")
|
||||
|
||||
|
||||
_papersdir = None
|
||||
@ -49,9 +49,9 @@ def name_from_path(fullpdfpath, verbose=False):
|
||||
name, ext = os.path.splitext(os.path.split(fullpdfpath)[1])
|
||||
if verbose:
|
||||
if ext != '.pdf' and ext != '.ps':
|
||||
print(colored('warning', 'yellow')
|
||||
+ '{: extension {ext} not recognized'.format(
|
||||
ext=colored(ext, 'cyan')))
|
||||
print('{}: extension {} not recognized'.format(
|
||||
color.dye('warning', color.warning),
|
||||
color.dye(ext, color.cyan)))
|
||||
return name, ext
|
||||
|
||||
|
||||
@ -73,9 +73,9 @@ def write_yamlfile(filepath, datamap):
|
||||
with open(filepath, 'w') as f:
|
||||
yaml.dump(datamap, f)
|
||||
except IOError:
|
||||
print(colored('error', 'error')
|
||||
+ ': impossible to read file {}'.format(
|
||||
colored(filepath, 'filepath')))
|
||||
print('{}: impossible to read or write on file {}'.format(
|
||||
color.dye('error', color.error),
|
||||
color.dye(filepath, color.filepath)))
|
||||
exit(-1)
|
||||
|
||||
|
||||
@ -85,9 +85,9 @@ def read_yamlfile(filepath):
|
||||
with open(filepath, 'r') as f:
|
||||
return yaml.load(f)
|
||||
except IOError:
|
||||
print(colored('error', 'error')
|
||||
+ ': impossible to read file {}'.format(
|
||||
colored(filepath, 'filepath')))
|
||||
print('{}: impossible to read file {}'.format(
|
||||
color.dye('error', color.error),
|
||||
color.dye(filepath, color.filepath)))
|
||||
exit(-1)
|
||||
|
||||
|
||||
@ -123,9 +123,9 @@ def load_externalbibfile(fullbibpath):
|
||||
with open(fullbibpath) as f:
|
||||
return parse_bibdata(f, ext[1:])
|
||||
else:
|
||||
print(colored('error', 'error')
|
||||
+ ': {} not recognized format for bibliography'.format(
|
||||
colored(ext, 'cyan')))
|
||||
print('{}: {} not recognized format for bibliography'.format(
|
||||
color.dye('error', color.error),
|
||||
color.dye(ext, color.cyan)))
|
||||
exit(-1)
|
||||
|
||||
|
||||
|
@ -15,7 +15,6 @@ import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from ...color import colored
|
||||
from ... import repo
|
||||
from ...paper import NoDocumentFile
|
||||
from ... import configs
|
||||
|
@ -1,6 +1,6 @@
|
||||
# display formatting
|
||||
|
||||
from color import colored, not_colored
|
||||
from . import color
|
||||
from pybtex.bibtex.utils import bibtex_purify
|
||||
|
||||
|
||||
@ -27,10 +27,6 @@ def short_authors(bibentry):
|
||||
|
||||
|
||||
def bib_oneliner(bibentry, color=True):
|
||||
if color:
|
||||
col_func = colored
|
||||
else:
|
||||
col_func = not_colored
|
||||
authors = short_authors(bibentry)
|
||||
title = bibtex_purify(bibentry.fields['title'])
|
||||
year = bibtex_purify(bibentry.fields.get('year', ''))
|
||||
@ -40,9 +36,9 @@ def bib_oneliner(bibentry, color=True):
|
||||
field = 'booktitle'
|
||||
journal = bibtex_purify(bibentry.fields.get(field, ''))
|
||||
return u'{authors} \"{title}\" {journal} ({year})'.format(
|
||||
authors=col_func(authors, 'cyan'),
|
||||
authors=color.dye(authors, color.cyan),
|
||||
title=title,
|
||||
journal=col_func(journal, 'yellow'),
|
||||
journal=color.dye(journal, color.yellow),
|
||||
year=year,
|
||||
)
|
||||
|
||||
|
@ -4,7 +4,7 @@ import glob
|
||||
|
||||
from . import files
|
||||
from .paper import PaperInRepo, NoDocumentFile
|
||||
from .color import colored
|
||||
from . import color
|
||||
from . import configs
|
||||
|
||||
|
||||
@ -48,9 +48,9 @@ class Repository(object):
|
||||
return self.citekeys[int(ref)]
|
||||
except (IndexError, ValueError):
|
||||
if fatal:
|
||||
print(colored('error', 'error')
|
||||
+ ': no paper with reference {}'.format(
|
||||
colored(ref, 'citekey')))
|
||||
print('{}: no paper with reference {}'.format(
|
||||
color.dye('error', color.error),
|
||||
color.dye(ref, color.citekey)))
|
||||
exit(-1)
|
||||
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 .color import colored
|
||||
from . import color
|
||||
from . import configs
|
||||
|
||||
|
||||
@ -12,13 +12,7 @@ class UI:
|
||||
|
||||
def __init__(self, config):
|
||||
self.encoding = _encoding(config)
|
||||
self.color = config.getboolean(configs.MAIN_SECTION, 'color')
|
||||
|
||||
def colored(self, s, *args, **kwargs):
|
||||
if self.color:
|
||||
return colored(s, *args, **kwargs)
|
||||
else:
|
||||
return s
|
||||
color.setup(config)
|
||||
|
||||
def print_(self, *strings):
|
||||
"""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
|
||||
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)])
|
||||
self.print_(question, option_str)
|
||||
while True:
|
||||
@ -71,7 +65,7 @@ class UI:
|
||||
sys.exit(error_code)
|
||||
|
||||
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):
|
||||
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