1b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# -*- coding: ascii -*-
2b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
3b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Copyright 2007, 2008, 2009, 2010, 2011
4b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Andr\xe9 Malo or his licensors, as applicable
5b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
6b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Licensed under the Apache License, Version 2.0 (the "License");
7b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# you may not use this file except in compliance with the License.
8b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# You may obtain a copy of the License at
9b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
10b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#     http://www.apache.org/licenses/LICENSE-2.0
11b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang#
12b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# Unless required by applicable law or agreed to in writing, software
13b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# distributed under the License is distributed on an "AS IS" BASIS,
14b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# See the License for the specific language governing permissions and
16b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# limitations under the License.
17b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang"""
18b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang=================
19b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang Terminal writer
20b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang=================
21b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang"""
22b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__author__ = u"Andr\xe9 Malo"
23b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang__docformat__ = "restructuredtext en"
24b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
25b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport sys as _sys
26b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
27b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
28b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangclass _INFO(dict):
29b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Terminal info dict """
30b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
31b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def __init__(self):
32b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Initialization """
33b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        dict.__init__(self, {
34b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'NORMAL': '',
35b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'BOLD': '',
36b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'ERASE': '\n',
37b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'RED': '',
38b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'YELLOW': '',
39b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            'GREEN': '',
40b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        })
41b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        try:
42b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            import curses as _curses
43b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        except ImportError:
44b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            # fixup if a submodule of curses failed.
45b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            if 'curses' in _sys.modules:
46b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                del _sys.modules['curses']
47b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        else:
48b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            try:
49b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                _curses.setupterm()
50b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            except (TypeError, _curses.error):
51b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                pass
52b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang            else:
53b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                def make_color(color):
54b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    """ Make color control string """
55b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    seq = _curses.tigetstr('setaf')
56b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    if seq is not None:
57b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        # XXX may fail - need better logic
58b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                        seq = seq.replace("%p1", "") % color
59b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    return seq
60b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
61b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self['NORMAL'] = _curses.tigetstr('sgr0')
62b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self['BOLD'] = _curses.tigetstr('bold')
63b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
64b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                erase = _curses.tigetstr('el1')
65b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                if erase is not None:
66b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                    self['ERASE'] = erase + _curses.tigetstr('cr')
67b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
68b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self['RED'] = make_color(_curses.COLOR_RED)
69b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self['YELLOW'] = make_color(_curses.COLOR_YELLOW)
70b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang                self['GREEN'] = make_color(_curses.COLOR_GREEN)
71b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
72b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    def __getitem__(self, key):
73b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        """ Deliver always """
74b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        dict.get(self, key) or ""
75b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
76b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
77b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef terminfo():
78b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Get info singleton """
79b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # pylint: disable = E1101, W0612
80b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    if terminfo.info is None:
81b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        terminfo.info = _INFO()
82b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return terminfo.info
83b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangterminfo.info = None
84b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
85b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
86b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef write(fmt, **kwargs):
87b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Write stuff on the terminal """
88b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    parm = dict(terminfo())
89b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    parm.update(kwargs)
90b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    _sys.stdout.write(fmt % parm)
91b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    _sys.stdout.flush()
92b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
93b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
94b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef green(bmt, **kwargs):
95b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Write something in green on screen """
96b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    announce("%%(GREEN)s%s%%(NORMAL)s" % bmt, **kwargs)
97b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
98b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
99b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef red(bmt, **kwargs):
100b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Write something in red on the screen """
101b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    announce("%%(BOLD)s%%(RED)s%s%%(NORMAL)s" % bmt, **kwargs)
102b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
103b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
104b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef yellow(fmt, **kwargs):
105b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Write something in yellow on the screen """
106b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    announce("%%(BOLD)s%%(YELLOW)s%s%%(NORMAL)s" % fmt, **kwargs)
107b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
108b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
109b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangdef announce(fmt, **kwargs):
110b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    """ Announce something """
111b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    write(fmt, **kwargs)
112b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    _sys.stdout.write("\n")
113b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    _sys.stdout.flush()
114b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
115b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
116