Browse Source

Reworked the log helper

pull/1/head
Eugenio Parodi 5 years ago
parent
commit
b51301533c
  1. 2
      README.md
  2. 0
      TermTk/TTk/__init__.py
  3. 86
      TermTk/TTk/log.py
  4. 0
      TermTk/__init__.py
  5. 0
      TermTk/libbpytop/LICENSE
  6. 0
      TermTk/libbpytop/README.md
  7. 0
      TermTk/libbpytop/__init__.py
  8. 16
      TermTk/libbpytop/canvas..py
  9. 6
      TermTk/libbpytop/input.py
  10. 15
      TermTk/libbpytop/term.py
  11. 11
      docs/TODO.md
  12. 31
      tests/test.input.py
  13. 72
      ttk/log.py

2
README.md

@ -1,2 +1,2 @@
# py-ttk
# pyTermTk
Python Terminal Toolkit

0
ttk/__init__.py → TermTk/TTk/__init__.py

86
TermTk/TTk/log.py

@ -0,0 +1,86 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# This code is inspired by
# https://github.com/ceccopierangiolieugenio/pyCuT/blob/master/cupy/CuTCore/CuDebug.py
import inspect
from collections.abc import Callable
class _TTkContext:
__slots__ = ['file', 'line', 'function']
def __init__(self, cf):
self.file = cf[1]
self.line = cf[2]
self.function = cf[3]
def __str__(self):
return f"{self.file}:{self.line} [{self.function}]"
class TTkLog:
DebugMsg = 0x0001
InfoMsg = 0x0002
ErrorMsg = 0x0004
WarningMsg = 0x0008
CriticalMsg = 0x0010
FatalMsg = 0x0020
SystemMsg = CriticalMsg
_messageHandler: Callable = None
@staticmethod
def _process_msg(mode: int, msg: str):
if TTkLog._messageHandler is not None:
curframe = inspect.currentframe()
calframe = inspect.getouterframes(curframe,1)
if len(calframe) > 2:
ctx = _TTkContext(calframe[2])
TTkLog._messageHandler(mode, ctx, msg)
@staticmethod
def debug(msg):
TTkLog._process_msg(TTkLog.DebugMsg, msg)
@staticmethod
def info(msg):
TTkLog._process_msg(TTkLog.InfoMsg, msg)
@staticmethod
def error(msg):
TTkLog._process_msg(TTkLog.ErrorMsg, msg)
@staticmethod
def warn(msg):
TTkLog._process_msg(TTkLog.WarningMsg, msg)
@staticmethod
def critical(msg):
TTkLog._process_msg(TTkLog.CriticalMsg, msg)
@staticmethod
def fatal(msg):
TTkLog._process_msg(TTkLog.FatalMsg, msg)
@staticmethod
def installMessageHandler(mh: Callable):
TTkLog._messageHandler = mh

0
TermTk/__init__.py

0
ttk/libbpytop/LICENSE → TermTk/libbpytop/LICENSE

0
ttk/libbpytop/README.md → TermTk/libbpytop/README.md

0
ttk/libbpytop/__init__.py → TermTk/libbpytop/__init__.py

16
TermTk/libbpytop/canvas..py

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# Copyright 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
# Copyright 2020 Aristocratos (https://github.com/aristocratos/bpytop)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

6
ttk/libbpytop/input.py → TermTk/libbpytop/input.py

@ -27,6 +27,8 @@ except Exception as e:
print(f'ERROR: {e}')
exit(1)
from TermTk.TTk import TTkLog
class MouseEvent:
# Keys
NoButton = 0x00000000 # The button state does not refer to any button (see QMouseEvent::button()).
@ -138,6 +140,7 @@ class Input:
m = mouse_re.match(input_key)
if not m:
# TODO: Return Error
TTkLog.error("UNHANDLED: "+input_key.replace("\033","<ESC>"))
continue
code = int(m.group(1))
x = int(m.group(2))
@ -170,7 +173,8 @@ class Input:
key = MouseEvent.Wheel
evt = MouseEvent.Down
mevt = MouseEvent(x, y, key, evt, m.group(0).replace("\033", "<ESC>"))
else:
TTkLog.error("UNHANDLED: "+input_key.replace("\033","<ESC>"))
input_key = ""
if callback is not None:
callback(kevt, mevt)

15
ttk/libbpytop/term.py → TermTk/libbpytop/term.py

@ -44,6 +44,19 @@ class Term:
_sigWinChCb = None
@staticmethod
def init(mouse: bool = True, title: str = "TermTk"):
Term.push(Term.alt_screen, Term.clear, Term.hide_cursor, Term.title("BpyTOP"))
if mouse:
Term.push(Term.mouse_on)
Term.echo(False)
@staticmethod
def exit():
Term.push(Term.mouse_off, Term.mouse_direct_off)
Term.echo(True)
@staticmethod
def echo(on: bool):
"""Toggle input echo"""
@ -79,5 +92,7 @@ class Term:
@staticmethod
def registerResizeCb(callback):
Term._sigWinChCb = callback
# Dummy call to retrieve the terminal size
Term._sigWinCh(signal.SIGWINCH, None)
signal.signal(signal.SIGWINCH, Term._sigWinCh)

11
docs/TODO.md

@ -1,11 +1,13 @@
- [ ] Handle Logs
# TODO
- [ ] Follow [PEP 8](https://www.python.org/dev/peps/pep-0008/) coding style
- [ ] Terminal Helper
- [ ] Events
- [x] Window : SIGWINCH triggered when the terminal is resized
- [ ] Input Class
- [ ] Return Error if Mouse RE does not match
- [x] Handle the Paste Buffer
- [ ] Handle the middle button mouse paste
- [ ] Investigate the middle mouse button paste
*note: It works only in "INSERT" mode on Vim*
- [ ] Handle Special Keys (UP, Down, . . .)
- [ ] Events
https://tkinterexamples.com/events/events.html
@ -13,3 +15,8 @@
- [x] Keyboard
- [x] Mouse
- [ ] Canvas Class
- [ ] Logs
- [x] Log Class
- [ ] Log helpers
- [ ] logger auto integration
- [ ] stdout until mainLoop

31
tests/test.input.py

@ -2,35 +2,36 @@ import sys, os
import logging
sys.path.append(os.path.join(sys.path[0],'..'))
import ttk.libbpytop as lbt
import ttk
import TermTk.libbpytop as lbt
from TermTk.TTk import TTkLog
def message_handler(mode, context, message):
if mode == ttk.InfoMsg: mode = 'INFO'
elif mode == ttk.WarningMsg: mode = 'WARNING'
elif mode == ttk.CriticalMsg: mode = 'CRITICAL'
elif mode == ttk.FatalMsg: mode = 'FATAL'
else: mode = 'DEBUG'
logging.debug(f"{mode} {context.file} {message}")
log = logging.debug
if mode == TTkLog.InfoMsg: log = logging.info
elif mode == TTkLog.WarningMsg: log = logging.warning
elif mode == TTkLog.CriticalMsg: log = logging.critical
elif mode == TTkLog.FatalMsg: log = logging.fatal
elif mode == TTkLog.ErrorMsg: log = logging.error
log(f"{context.file} {message}")
logging.basicConfig(level=logging.DEBUG,
format='(%(threadName)-9s) %(message)s',)
ttk.installMessageHandler(message_handler)
format='%(levelname)s:(%(threadName)-9s) %(message)s',)
TTkLog.installMessageHandler(message_handler)
ttk.info("Retrieve Keyboard, Mouse press/drag/wheel Events")
ttk.info("Press q or <ESC> to exit")
TTkLog.info("Retrieve Keyboard, Mouse press/drag/wheel Events")
TTkLog.info("Press q or <ESC> to exit")
lbt.Term.push(lbt.Term.mouse_on)
lbt.Term.echo(False)
def keyCallback(kevt=None, mevt=None):
if kevt is not None:
ttk.info(f"Key Event: {kevt}")
TTkLog.info(f"Key Event: {kevt}")
if mevt is not None:
ttk.info(f"Mouse Event: {mevt}")
TTkLog.info(f"Mouse Event: {mevt}")
def winCallback(width, height):
ttk.info(f"Resize: w:{width}, h:{height}")
TTkLog.info(f"Resize: w:{width}, h:{height}")
lbt.Term.registerResizeCb(winCallback)
lbt.Input.get_key(keyCallback)

72
ttk/log.py

@ -1,72 +0,0 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# This code is inspired by
# https://github.com/ceccopierangiolieugenio/pyCuT/blob/master/cupy/CuTCore/CuDebug.py
import inspect
DebugMsg = 0 # A message generated by the Debug() function.
InfoMsg = 4 # A message generated by the Info() function.
WarningMsg = 1 # A message generated by the Warning() function.
CriticalMsg = 2 # A message generated by the Critical() function.
FatalMsg = 3 # A message generated by the Fatal() function.
SystemMsg = CriticalMsg
_MessageHandler = None
def _process_msg(mode, msg):
global _MessageHandler
if _MessageHandler is not None:
curframe = inspect.currentframe()
calframe = inspect.getouterframes(curframe,1)
if len(calframe) > 2:
class context:
__slots__ = ('file', 'line', 'function')
def __str__(self):
return f"{self.file}:{self.line} [{self.function}]"
ctx = context()
ctx.file = calframe[2][1]
ctx.line = calframe[2][2]
ctx.function = calframe[2][3]
_MessageHandler(mode, ctx, msg)
def debug(msg):
_process_msg(DebugMsg, msg)
def info(msg):
_process_msg(InfoMsg, msg)
def warn(msg):
_process_msg(WarningMsg, msg)
def critical(msg):
_process_msg(CriticalMsg, msg)
def fatal(msg):
_process_msg(FatalMsg, msg)
def installMessageHandler(mh):
global _MessageHandler
_MessageHandler = mh
Loading…
Cancel
Save