diff --git a/.gitignore b/.gitignore index 65caf74..06304ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ *.pyc test.py -build/ -dist/ -py_term.egg-info -py-term-0.1/ +build/** +dist/** +pyterm.egg-info/** +pyterm-0.1/ +.idea/** +/Code_restructured_and_many_other_changes_.patch diff --git a/MANIFEST.in b/MANIFEST.in index bb3ec5f..d8bab85 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,2 @@ include README.md +LICENSE diff --git a/README.md b/README.md index dff7ec9..a356664 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,44 @@ -# py-term -Python module to style terminal output, moving and positioning the cursor. +# pyterm -**Python 2 and 3 compatible** - -![alt text](pyterm.jpg "See? amazing!") +Python 3 package to easily handle style terminal output, moving and positioning the cursor and some other features. +This project is heavily based on [gravmatt/py-term](https://github.com/gravmatt/py-term]github.com) project. ## Installation Install through **pip**. -``` -$ pip install py-term +```shell +$ pip3 install git+https://github.com/havocesp/pyterm ``` or get from source -``` -$ git clone https://github.com/gravmatt/py-term.git -$ cd py-term -$ python setup.py install +```shell +$ git clone https://github.com/havocesp/pyterm +$ cd pyterm +$ python3 setup.py install ``` ## Import module Import the module into your python project. -``` -import term +```python3 +from pyterm import Term as Tm ``` ## Usage -``` -term.write('Hello, ') -term.write('Python!') +```python +from pyterm import Term as Tm + +Tm.write('Hello, ') +Tm.write('Python!') > Hello, Python! -term.writeLine('Hello') -term.writeLine('Python!') +Tm.write_line('Hello') +Tm.write_line('Python!') > Hello > Python! @@ -48,23 +48,25 @@ term.writeLine('Python!') The first argument is the text output and all following arguments are for styling. -``` -term.writeLine(text, *style) +```python3 +from pyterm import Term as Tm -Or +Tm.write_line('text', Tm.BOLD) -text = term.format(text, *style) -term.writeLine(text) +text = Tm.style('text', Tm.DIM) +Tm.write_line(text) ``` ### Usage -``` -term.writeLine('Hello, Python!') +```python +from pyterm import Term as Tm + +Tm.write_line('Hello, Python!') -term.writeLine('This text line will be green', term.green) +Tm.write_line('This text line will be green', Tm.GREEN) -term.writeLine('Reverse the green color', term.green, term.reverse) +Tm.write_line('Reverse the green color', Tm.GREEN, Tm.REVERSE) ``` Or @@ -72,7 +74,7 @@ Or ``` output = term.format('Hello, ', term.green) + term.format('Python!', term.blue, term.bold) -term.writeLine(output) +term.write_line(output) term.write(term.format('All in one line', term.reverse)) ``` @@ -84,15 +86,15 @@ term.write(term.format('All in one line', term.reverse)) ``` # term.textCenter(text) -term.writeLine(term.textCenter('Super Python!')) +term.write_line(term.textCenter('Super Python!')) ``` **Right align** ``` -# term.textRight(text) +# term.text_right(text) -term.writeLine(term.textRight('Rene Tanczos (@gravmatt)')) +term.write_line(term.text_right('Rene Tanczos (@gravmatt)')) ( Function term.right() to align text is depricated because of naming conflicts! ) ``` @@ -172,21 +174,21 @@ array_of_positions (index 2) = array of tuples with start and stop points of the ## Set title ``` -term.setTitle('Hello Terminal') +term.set_title('Hello Terminal') # or clear it -term.clearTitle() +term.clear_title() ``` ## Set tab name ``` -term.setTab('Hello Tab') +term.set_tab('Hello Tab') # or clear it -term.clearTab() +term.clear_tab() ``` ## Cursor position @@ -201,9 +203,9 @@ term.pos(2, 15) Get the size of the terminal (lines and columns) ``` -(30, 100) = term.getSize() +(30, 100) = term.get_size() -# (lines, colums) = term.getSize() +# (lines, colums) = term.get_size() ``` Move the cursor to the home position (1, 1). @@ -224,13 +226,13 @@ term.right(value=1) Saves the current cursor position. ``` -term.saveCursor() +term.save_cursor() ``` Restore the previously stored cursor position. ``` -term.restoreCursor() +term.restore_cursor() ``` Clear the terminal screen. @@ -242,19 +244,19 @@ term.clear() Clear the entire line on the current cursor position. ``` -term.clearLine() +term.clear_line() ``` Clear line from the current cursor position to the end. ``` -term.clearLineFromPos() +term.clear_line_from_pos() ``` Clear line from begin to current cursor position. ``` -term.clearLineToPos() +term.clear_line_to_pos() ``` ## Licence diff --git a/README.rst b/README.rst deleted file mode 100644 index 3f52ac2..0000000 --- a/README.rst +++ /dev/null @@ -1,331 +0,0 @@ -py-term -======= - -Python module to style terminal output, moving and positioning the -cursor. - -**Python 2 and 3 compatible** - -Installation ------------- - -Install through **pip**. - -:: - - $ pip install py-term - -or get from source - -:: - - $ git clone https://github.com/gravmatt/py-term.git - $ cd py-term - $ python setup.py install - -Import module -------------- - -Import the module into your python project. - -:: - - import term - -Usage ------ - -:: - - term.write('Hello, ') - term.write('Python!') - - > Hello, Python! - - term.writeLine('Hello') - term.writeLine('Python!') - - > Hello - > Python! - -Style output ------------- - -The first argument is the text output and all following arguments are -for styling. - -:: - - term.writeLine(text, *style) - - Or - - text = term.format(text, *style) - term.writeLine(text) - -Usage -~~~~~ - -:: - - term.writeLine('Hello, Python!') - - term.writeLine('This text line will be green', term.green) - - term.writeLine('Reverse the green color', term.green, term.reverse) - -Or - -:: - - output = term.format('Hello, ', term.green) + term.format('Python!', term.blue, term.bold) - - term.writeLine(output) - - term.write(term.format('All in one line', term.reverse)) - -Text align -^^^^^^^^^^ - -**Center align** - -:: - - # term.textCenter(text) - - term.writeLine(term.textCenter('Super Python!')) - -**Right align** - -:: - - # term.textRight(text) - - term.writeLine(term.textRight('Rene Tanczos (@gravmatt)')) - - ( Function term.right() to align text is depricated because of naming conflicts! ) - -Style attributes -'''''''''''''''' - -+-------------------+----------------------------------------+ -| Code | Description | -+===================+========================================+ -| term.off | All attributes off | -+-------------------+----------------------------------------+ -| term.bold | Bold | -+-------------------+----------------------------------------+ -| term.dim | Dim | -+-------------------+----------------------------------------+ -| term.underscore | Underscore (monochrome display only) | -+-------------------+----------------------------------------+ -| term.blink | Blink | -+-------------------+----------------------------------------+ -| term.reverse | Reverse | -+-------------------+----------------------------------------+ -| term.hide | Hide | -+-------------------+----------------------------------------+ - -Text color -'''''''''' - -+----------------+-----------+ -| Code | Color | -+================+===========+ -| term.black | Black | -+----------------+-----------+ -| term.red | Red | -+----------------+-----------+ -| term.green | Green | -+----------------+-----------+ -| term.yellow | Yellow | -+----------------+-----------+ -| term.blue | Blue | -+----------------+-----------+ -| term.magenta | Magenta | -+----------------+-----------+ -| term.cyan | Cyan | -+----------------+-----------+ -| term.white | White | -+----------------+-----------+ - -Background color -'''''''''''''''' - -+------------------+-----------+ -| Code | Color | -+==================+===========+ -| term.bgblack | Black | -+------------------+-----------+ -| term.bgred | Red | -+------------------+-----------+ -| term.bggreen | Green | -+------------------+-----------+ -| term.bgyellow | Yellow | -+------------------+-----------+ -| term.bgblue | Blue | -+------------------+-----------+ -| term.bgMagenta | Magenta | -+------------------+-----------+ -| term.bgcyan | Cyan | -+------------------+-----------+ -| term.bgwhite | White | -+------------------+-----------+ - -Remove style attributes ------------------------ - -Removes style characters. - -(Good to call before you count a string) - -:: - - term.strip(formatted_text) - - hello = term.red + 'hello, world' + term.off - print hello - # '\x1b[31mhello, world\x1b[0m\x1b[27m' - - print term.strip(hello) - # hello, world - -Highlighting text ------------------ - -Simple highlighting of unformatted text strings - -:: - - def callback(matching_text): - return term.blue + matching_text + term.off - - output, match_count, array_of_positions = term.highlight(regex_pattern, text, callback) - -Return a tuple. - -output (index 0) = formatted text output - -match\_count (index 1) = match count of the pattern - -array\_of\_positions (index 2) = array of tuples with start and stop -points of the matches [(4, 6), (9, 11), ..] - -Set title ---------- - -:: - - term.setTitle('Hello Terminal') - - # or clear it - - term.clearTitle() - -Set tab name ------------- - -:: - - term.setTab('Hello Tab') - - # or clear it - - term.clearTab() - -Cursor position ---------------- - -Move the cursor to a specific position. - -:: - - term.pos(line, column) - - term.pos(2, 15) - -Get the size of the terminal (lines and columns) - -:: - - (30, 100) = term.getSize() - - # (lines, colums) = term.getSize() - -Move the cursor to the home position (1, 1). - -:: - - term.homePos() - -Moves the current cursor position up, down, left or right by the -specified value. - -:: - - term.up(value=1) - term.down(value=1) - term.left(value=1) - term.right(value=1) - -Saves the current cursor position. - -:: - - term.saveCursor() - -Restore the previously stored cursor position. - -:: - - term.restoreCursor() - -Clear the terminal screen. - -:: - - term.clear() - -Clear the entire line on the current cursor position. - -:: - - term.clearLine() - -Clear line from the current cursor position to the end. - -:: - - term.clearLineFromPos() - -Clear line from begin to current cursor position. - -:: - - term.clearLineToPos() - -Licence -------- - -The MIT License (MIT) - -Copyright (c) 2015-2021 René Tanczos - -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. diff --git a/pyterm.jpg b/pyterm.jpg deleted file mode 100644 index 73dc034..0000000 Binary files a/pyterm.jpg and /dev/null differ diff --git a/pyterm/__init__.py b/pyterm/__init__.py new file mode 100644 index 0000000..dc00062 --- /dev/null +++ b/pyterm/__init__.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""pyterm + + - File: pyterm/__init__.py + - Author: Havocesp + - Created: 2023-03-22 + - +""" +from pyterm.constants import __all_constants__ +from pyterm.core import Term +from pyterm.model import Color + +Tm = Term + +__version__ = '0.7.2' + +__all__ = [ + 'Term', + 'Tm', + 'Color', + '__version__', + *__all_constants__ +] diff --git a/pyterm/constants.py b/pyterm/constants.py new file mode 100644 index 0000000..0b9c5da --- /dev/null +++ b/pyterm/constants.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""pyterm + + - File: pyterm/constants.py + - Author: Havocesp + - Created: 2023-03-22 + - +""" +BLINK = '\033[5m' +BOLD = '\033[1m' +DIM = '\033[2m' +HIDE = '\033[8m' +OFF = '\033[0m\033[27m' +REVERSE = ' \033[7m' +UNDERSCORE = '\033[4m' +UNDERLINE = UNDERSCORE + +BLACK = '\033[30m' +BLUE = '\033[34m' +CYAN = '\033[36m' +GREEN = '\033[32m' +MAGENTA = '\033[35m' +RED = '\033[31m' +WHITE = '\033[37m' +YELLOW = '\033[33m' + +BGBLACK = '\033[40m' +BGBLUE = '\033[44m' +BGCYAN = '\033[46m' +BGGREEN = '\033[42m' +BGMAGENTA = '\033[45m' +BGRED = '\033[41m' +BGWHITE = '\033[47m' +BGYELLOW = '\033[43m' + +# aliases +BK = BLACK +BL = BLUE +CY = CYAN +GN = GREEN +MG = MAGENTA +RD = RED +WH = WHITE +YL = YELLOW + +BGK = BGBLACK +BGL = BGBLUE +BGC = BGCYAN +BGG = BGGREEN +BGM = BGMAGENTA +BGR = BGRED +BGW = BGWHITE +BGY = BGYELLOW + +BLK = BLINK +BD = BOLD +DN = DIM +HD = HIDE +OF = OFF +RV = REVERSE +US = UNDERSCORE +UL = UNDERLINE + +__all_constants__ = [] + +__all__ = [ + 'BD', + 'BGBLACK', + 'BGBLUE', + 'BGC', + 'BGCYAN', + 'BGG', + 'BGGREEN', + 'BGK', + 'BGL', + 'BGM', + 'BGMAGENTA', + 'BGR', + 'BGRED', + 'BGW', + 'BGWHITE', + 'BGY', + 'BGYELLOW', + 'BK', + 'BL', + 'BLACK', + 'BLINK', + 'BLK', + 'BLUE', + 'BOLD', + 'CY', + 'CYAN', + 'DIM', + 'DN', + 'GN', + 'GREEN', + 'HD', + 'HIDE', + 'MAGENTA', + 'MG', + 'OF', + 'OFF', + 'RD', + 'RED', + 'REVERSE', + 'RV', + 'UNDERLINE', + 'UNDERSCORE', + 'US', + 'WH', + 'WHITE', + 'YELLOW', + 'YL', + 'UL', + '__all_constants__' +] + +__all_constants__.extend(__all__) diff --git a/pyterm/core.py b/pyterm/core.py new file mode 100644 index 0000000..192a74c --- /dev/null +++ b/pyterm/core.py @@ -0,0 +1,391 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""pyterm + + - File: pyterm/core.py + - Author: Havocesp + - Created: 2023-03-22 + - +""" + +import shutil +import sys +from typing import NoReturn, Text, Tuple + +import regex as re + +from pyterm.model import Color + + +class Term(Color): + """Term class for controlling the termina feature like output color, cursor position, etc.""" + + @classmethod + def _send(cls, cmd) -> NoReturn: + sys.stdout.write(cmd) + sys.stdout.flush() + + @classmethod + def pos(cls, line: int, column: int) -> NoReturn: + """ Set the cursor position to the given line and column. + + :param line: terminal line position. 1 is the first line. + :param column: terminal column position. 1 is the first column. + """ + cls._send(f'\033[{line};{column}f') + + @classmethod + def home_pos(cls) -> NoReturn: + """ Set the cursor position to the home position (1,1). """ + cls._send('\033[H') + + @classmethod + def up(cls, value: int = 1) -> NoReturn: + """ Move the cursor up the given number of lines. + + :param value: number of lines to move the cursor up. 1 is the default value. + """ + cls._send(f'\033[{value}A') + + @classmethod + def down(cls, value=1) -> NoReturn: + """ Move the cursor down the given number of lines. + + :param value: number of lines to move the cursor down. 1 is the default value. + """ + cls._send(f'\033[{value}B') + + @classmethod + def right(cls, value=1) -> NoReturn: + """ Move the cursor right the given number of columns. + + :param value: number of columns to move the cursor right. 1 is the default value. + """ + cls._send(f'\033[{value}C') + + @classmethod + def left(cls, value=1) -> NoReturn: + cls._send(f'\033[{value}D') + + @classmethod + def save_cursor(cls) -> NoReturn: + """ Save the current cursor position. """ + cls._send('\0337') + # _send('\033[s') + + @classmethod + def restore_cursor(cls) -> NoReturn: + cls._send('\0338') + # _send('\033[u') + + @classmethod + def clear(cls) -> NoReturn: + cls._send('\033[2J') + + @classmethod + def clear_line_from_pos(cls) -> NoReturn: + cls._send('\033[K') + + @classmethod + def clear_line_to_pos(cls) -> NoReturn: + cls._send('\033[1K') + + @classmethod + def clear_line(cls) -> NoReturn: + """ Clear the current line.""" + cls._send('\033[2K') + + @classmethod + def write(cls, text: Text, *style) -> NoReturn: + """ Write text to the terminal. + + :param text: text to write to the terminal. + :param Iterable[Color] style: style to apply to the text. + """ + cls._send(cls.style(text, *style)) + + @classmethod + def write_line(cls, text: Text, *style) -> NoReturn: + """ Write a line of text to the terminal. + + :param text: text to write to the terminal. + :param Iterable[Color] style: style to apply to the text. + """ + cls.write(f'{text}\n', *style) + + @classmethod + def set_title(cls, name: Text) -> NoReturn: + """ Set the terminal title. + + :param name: title to set. + """ + cls._send(f'\033]2;{name}\007') + + @classmethod + def clear_title(cls) -> NoReturn: + cls.set_title('') + + @classmethod + def set_tab(cls, name: str) -> NoReturn: + cls._send(f'\033]1;{name}\007') + + @classmethod + def clear_tab(cls) -> NoReturn: + cls.set_tab('') + + @classmethod + def strip(cls, text) -> NoReturn: + return re.sub(r'\x1b\[[0-9]{1,2}m', '', text) + + @classmethod + def center(cls, text) -> NoReturn: + ''' + DEPRICATED: Use textCenter() instead! + Will be removed in later verions! + ''' + return ' ' * (int(cls.get_size()[1] / 2) - int(len(cls.strip(text)) / 2)) + text + + @classmethod + def text_right(cls, text: Text) -> Text: + """Align text to the right of the terminal. + + :param text: text to align + :return: aligned text + """ + _diff = cls.term_cols() - len(cls.strip(text)) + return str(' ' * _diff) + text + + # @classmethod + # def get_size(cls): + # + # os_sys = platform.system() + # if os_sys in ['Linux', 'Darwin'] or os_sys.startswith('CYGWIN'): + # try: + # def _get_unix_terminal_size(fd): + # import fcntl, termios, struct + # return struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, 'rene')) + # + # cr = _get_unix_terminal_size(0) or _get_unix_terminal_size(1) or _get_unix_terminal_size(2) + # if not cr: + # fd = os.open(os.ctermid(), os.O_RDONLY) + # cr = _get_unix_terminal_size(fd) + # os.close(fd) + # return cr + # except: + # pass + # else: + # raise Exception('operating system not supported') + + @classmethod + def term_cols(cls) -> int: + return shutil.get_terminal_size().columns + + @classmethod + def term_rows(cls) -> int: + return shutil.get_terminal_size().lines + + @classmethod + def get_size(cls) -> Tuple: + return cls.term_rows(), cls.term_cols() + + @classmethod + def style(cls, text: Text, *style) -> Text: + return f'{"".join(style)}{text}{cls.OFF}' if style else text + + @classmethod + def highligth(cls, pattern, text, *style) -> Text: + """Apply a style to all matches of a regular expression pattern in a text. + + :param pattern: regular expression pattern to style to. + :param text: text to apply the style to words matching the pattern. + :param style: style to apply to the words that match the pattern. + :return: text with text words matching the pattern styled. + """ + positions = [] + for m in re.finditer(pattern, text, flags=re.MULTILINE): + match = m + if m: + positions = [match.span()] + + if positions: + for pos in positions: + styled_text_range = cls.style(text[pos[0]:pos[1]], *style) + text = text[:pos[0]] + styled_text_range + text[pos[1]:] + + return text + + @classmethod + def color(cls, text: Text, *color: Color) -> Text: + return cls.style(text, *color) + + # @classmethod + # def colorize(cls, text: Text, color: str, *style) -> Text: + # return(cls.style(text, color, *style)) + # + + @classmethod + def red(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.RED) + + @classmethod + def cyan(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.CYAN) + + @classmethod + def yellow(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.YELLOW) + + @classmethod + def magenta(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.MAGENTA) + + @classmethod + def white(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.WHITE) + + @classmethod + def black(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.BLACK) + + @classmethod + def blue(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.BLUE) + + @classmethod + def green(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.GREEN) + + @classmethod + def dim(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.DIM) + + @classmethod + def bold(cls, text: Text) -> Text: + """Format with color to a given text. + + :param text: text to apply the color to. + :return: colored text. + """ + return cls.color(text, cls.BOLD) + + def clear_lines(self, num: int = 1) -> NoReturn: + """Clear the current line.""" + for n in range(num): + self._send('\033[2K') + self.up() + + def save_pos(self) -> NoReturn: + """Save the current cursor position.""" + self._send('\033[s') + + def restore_pos(self) -> NoReturn: + """Restore the last saved cursor position.""" + self._send('\033[u') + + def home(self) -> NoReturn: + """Move the cursor to the home position.""" + self._send('\033[H') + + def hide_cursor(self) -> NoReturn: + """Hide the cursor.""" + self._send('\033[?25l') + + def show_cursor(self) -> NoReturn: + """Show the cursor.""" + self._send('\033[?25h') + + def underline(self, text: Text) -> Text: + """Underline the given text. + + :param text: text to underline. + :return: underlined text. + """ + return self.style(text, self.UNDERLINE) + + def blink(self, text: Text) -> Text: + """Blink the given text. + + :param text: text to blink. + :return: blinked text. + """ + return self.style(text, self.BLINK) + + def reverse(self, text: Text) -> Text: + """Reverse the given text. + + :param text: text to reverse. + :return: reversed text. + """ + return self.style(text, self.REVERSE) + + def set_icon(self, icon: Text) -> NoReturn: + """Set the terminal icon. + + :param icon: icon to set. + """ + self._send(f'\033]1;{icon}\007') + + def clear_icon(self) -> NoReturn: + """Clear the terminal icon.""" + self._send('\033]1;\007') + + def clear_to_end(self) -> NoReturn: + """Clear the screen from the current position to the end.""" + self._send('\033[0J') + + def clear_from_start(self) -> NoReturn: + """Clear the screen from the current position to the start.""" + self._send('\033[1J') + + def clear_line_to_end(self) -> NoReturn: + """Clear the current line from the current position to the end.""" + self._send('\033[0K') + + def clear_line_from_start(self) -> NoReturn: + """Clear the current line from the current position to the start.""" + self._send('\033[1K') diff --git a/pyterm/model.py b/pyterm/model.py new file mode 100644 index 0000000..a5950ab --- /dev/null +++ b/pyterm/model.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""pyterm + + - File: pyterm/model.py + - Author: Havocesp + - Created: 2023-03-22 + - +""" + +from pyterm.constants import * + + +class Color: + """Color class for controlling the terminal color.""" + + BLACK = BLACK + RED = RED + GREEN = GREEN + YELLOW = YELLOW + BLUE = BLUE + MAGENTA = MAGENTA + CYAN = CYAN + WHITE = WHITE + + OFF = OFF + BOLD = BOLD + UNDERLINE = UNDERLINE + BLINK = BLINK + REVERSE = REVERSE + DIM = DIM diff --git a/pyterm/utils.py b/pyterm/utils.py new file mode 100644 index 0000000..6676d9a --- /dev/null +++ b/pyterm/utils.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""pyterm + + - File: pyterm/utils.py + - Author: Havocesp + - Created: 2023-03-26 + - +""" + + +def get_caller_name() -> str: + """Get the caller name.""" + import inspect + return inspect.stack()[2][3] diff --git a/setup.py b/setup.py index 20910e3..e102323 100644 --- a/setup.py +++ b/setup.py @@ -1,53 +1,52 @@ -#!/usr/bin/env python - +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- import sys +from pathlib import Path + try: - from setuptools import setup + from setuptools import setup, find_packages except ImportError: from distutils.core import setup -if sys.version_info < (2, 6): - raise NotImplementedError("Sorry, you need at least Python 2.6 or Python 3.2+ to use py-term.") +if sys.version_info < (3, 6): + raise NotImplementedError("Sorry, you need at least Python 3.6 to use py-term.") + +import pyterm -import term +readme_file = Path(__file__).parent / 'README.md' -with open('README.md', 'r') as f: - longDesc = f.read() +if readme_file.is_file(): + long_desc = readme_file.read_text() +else: + long_desc = pyterm.__doc__ -setup(name='py-term', - version=term.__version__, - description='Python module to style terminal output, moving and positioning the cursor.', - long_description=longDesc, - long_description_content_type='text/markdown', - author='Rene Tanczos', - author_email='gravmatt@gmail.com', - url='https://github.com/gravmatt/py-term', - py_modules=['term'], - scripts=['term.py'], - license='MIT', - platforms=['MacOSX', 'UNIX/Linux'], - classifiers=['Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2.5', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.1', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Intended Audience :: Developers', - 'Programming Language :: Python', - 'Development Status :: 5 - Production/Stable', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: POSIX', - 'Topic :: Terminals', - 'Environment :: Console' - ], - ) +setup( + name='pyterm', + version=pyterm.__version__, + description='Python module to style terminal output, moving and positioning the cursor.', + long_description=long_desc, + long_description_content_type='text/markdown', + author='Havocesp', + packages=find_packages(exclude=['tests', 'tests.*', 'examples', 'examples.*', 'docs', 'docs.*', 'venv', 'venv.*', 'build', 'build.*', 'dist', 'dist.*']), + url='https://github.com/havocesp/pyterm', + py_modules=['pyterm'], + scripts=['pyterm'], + license='MIT', + platforms=['MacOSX', 'UNIX/Linux'], + classifiers=[ + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Intended Audience :: Developers', + 'Programming Language :: Python', + 'Development Status :: 5 - Production/Stable', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: POSIX', + 'Topic :: Terminals', + 'Environment :: Console' + ], +) diff --git a/term.py b/term.py deleted file mode 100644 index d64dab0..0000000 --- a/term.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -Copyright (c) 2015-2016, René Tanczos (Twitter @gravmatt) -The MIT License (MIT) - -pyterm helps positioning the cursor and styling output inside the terminal. - -Project on github https://github.com/gravmatt/py-term -""" - -__author__ = 'Rene Tanczos' -__version__ = '0.7' -__license__ = 'MIT' - -import sys -import re -import os -from subprocess import Popen, PIPE - - -off = '\033[0m\033[27m' -bold = '\033[1m' -dim = '\033[2m' -underscore = '\033[4m' -blink = '\033[5m' -reverse = ' \033[7m' -hide = '\033[8m' - -black = '\033[30m' -red = '\033[31m' -green = '\033[32m' -yellow = '\033[33m' -blue = '\033[34m' -magenta = '\033[35m' -cyan = '\033[36m' -white = '\033[37m' - -bgblack = '\033[40m' -bgred = '\033[41m' -bggreen = '\033[42m' -bgyellow = '\033[43m' -bgblue = '\033[44m' -bgmagenta = '\033[45m' -bgcyan = '\033[46m' -bgwhite = '\033[47m' - - -def send(cmd): - sys.stdout.write(cmd) - sys.stdout.flush() - - -def pos(line, column): - send('\033[%s;%sf' % (line, column)) - - -def homePos(): - send('\033[H') - - -def up(value=1): - send('\033[%sA' % value) - - -def down(value=1): - send('\033[%sB' % value) - - -def right(value=1): - send('\033[%sC' % value) - - -def left(value=1): - send('\033[%sD' % value) - - -def saveCursor(): - send('\0337') - # send('\033[s') - - -def restoreCursor(): - send('\0338') - # send('\033[u') - - -def clear(): - send('\033[2J') - - -def clearLineFromPos(): - send('\033[K') - - -def clearLineToPos(): - send('\033[1K') - - -def clearLine(): - send('\033[2K') - - -def write(text='', *style): - send(format(text, *style)) - - -def writeLine(text='', *style): - write(str(text) + '\n', *style) - - -def setTitle(name): - send('\033]2;%s\007' % name) - - -def clearTitle(): - setTitle('') - - -def setTab(name): - send('\033]1;%s\007' % name) - - -def clearTab(): - setTab('') - - -def strip(text): - return re.sub('\x1b\[[0-9]{1,2}m', '', text) - - -def textCenter(text): - return ' ' * (int(getSize()[1] / 2) - int(len(strip(text)) / 2)) + text - - -def center(text): - ''' - DEPRICATED: Use textCenter() instead! - Will be removed in later verions! - ''' - textCenter(text) - - -def textRight(text): - return ' ' * (getSize()[1] - len(strip(text))) + text - - -def getSize(): - import platform - os_sys = platform.system() - if(os_sys in ['Linux', 'Darwin'] or os_sys.startswith('CYGWIN')): - try: - def __get_unix_terminal_size(fd): - import fcntl, termios, struct - return struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, 'rene')) - cr = __get_unix_terminal_size(0) or __get_unix_terminal_size(1) or __get_unix_terminal_size(2) - if(not cr): - fd = os.open(os.ctermid(), os.O_RDONLY) - cr = __get_unix_terminal_size(fd) - os.close(fd) - return cr - except: - pass - else: - raise Exception('operating system not supported') - - -def format(text, *style): - if(style): - return '%s%s%s' % (''.join(style), text, off) - else: - return text - - -def highlight(pattern, text, func): - output = '' - idx = 0 - matches = [(m.start(), m.end()) for m in re.finditer(pattern, text)] - for p in matches: - output += text[idx:p[0]] - output += func(text[p[0]:p[1]]) - idx = p[1] - output += text[idx:] - return (output, len(matches), matches)