diff --git a/picowatch_d/picowatch.py b/picowatch_d/picowatch.py index 72113bc..eb1f6b7 100644 --- a/picowatch_d/picowatch.py +++ b/picowatch_d/picowatch.py @@ -39,8 +39,36 @@ from typing import Dict, List, Optional, Tuple, Union BUFFER_SIZE: int = 126 CURRENT_DIRECTORY: str = os.getcwd().replace('\\', '/') -def strpad(text: str, length: int = 30) -> str: - return text + ' ' * (length - len(text)) + +class Tab(): + colsize: Tuple = () + + def __init__(self, *length: int): + self.colsize = length + + def blank(self, text: str = '-'): + print(text * sum(self.colsize)) + + def print(self, *texts: str): + def coltext(text: str, length: int = 20) -> str: + if len(text) >= length: + text = text[:(length - 4) if length > 5 else length] + '...' + + return text + ' ' * (length - len(text)) + + line = '' + + for i, text in enumerate(texts[:len(self.colsize)]): + line += coltext(text, self.colsize[i]) + + for text in texts[len(self.colsize):]: + line += coltext(text) + + print(line) + + def labels(self, *texts: str, blank_text: str = '-'): + self.print(*texts) + self.blank(blank_text) class Telnet: @@ -131,9 +159,9 @@ class Pyboard(object): def close(self): self.serial.close() - def loading(self) -> int: + def transfer_status(self) -> int: arrows = ['◜', '◝', '◞', '◟'] - sys.stdout.write(f'[∘] Loading... {arrows[self.i]}\r') + sys.stdout.write(f'[∘] Transfering... {arrows[self.i]}\r') sys.stdout.flush() self.i = (self.i + 1) % 4 @@ -187,7 +215,7 @@ class Pyboard(object): self.stdout_write_bytes(stream_data) data = data[-max_len:] elif show_status: - self.loading() + self.transfer_status() else: timeout += 1 time.sleep(0.0001) @@ -230,7 +258,7 @@ class Pyboard(object): for i in range(0, len(command), BUFFER_SIZE): if not stream_output: - self.loading() + self.transfer_status() self.serial.write(command[i: min(i + BUFFER_SIZE, len(command))]) time.sleep(0.0001) @@ -259,18 +287,18 @@ class Pyboard(object): for call in traceback[1][:-2].split('\\r\\n'): reason += f'{call}\n' - raise Exception(f'-------------------\n{reason.strip()}') + raise Exception(f'{"-"* 45}\n{reason.strip()}') else: - raise Exception(f'-------------------\n{exception}') + raise Exception(f'{"-" * 45}\n{exception}') return data.strip() -class PicoTerminal(object): - _pyboard: Pyboard +class PyboardTerminal(object): + pyboard: Pyboard def __init__(self, pyboard: Pyboard): - self._pyboard = pyboard + self.pyboard = pyboard def checksum(self, source: str, data: str) -> str: output = self.terminal(f""" @@ -291,7 +319,10 @@ class PicoTerminal(object): for c in data: v ^= ord(c) - return f'{v}:{output}' + if int(v) == int(output): + return 'OK' + + return f'{v} != {output}' def get(self, filename: str) -> Tuple[bytes, bool]: if not filename.startswith('/'): @@ -330,7 +361,7 @@ class PicoTerminal(object): if os.path.dirname(filename): self.mkdir(os.path.dirname(filename)) - with self._pyboard as terminal: + with self.pyboard as terminal: size = len(data) terminal(f"""fh = open("{filename}", "wb")""") @@ -505,7 +536,7 @@ class PicoTerminal(object): print(str(e)) def terminal(self, command: str, stream_output: bool = False) -> str: - with self._pyboard as terminal: + with self.pyboard as terminal: try: return terminal(command, stream_output=stream_output) except Exception as e: @@ -513,37 +544,36 @@ class PicoTerminal(object): class Picowatch(object): - pico_terminal: PicoTerminal + terminal: PyboardTerminal def __init__(self, pyboard: Pyboard): - self.pico_terminal = PicoTerminal(pyboard) + self.terminal = PyboardTerminal(pyboard) signal.signal(signal.SIGINT, lambda a, b: self.interupt()) def interupt(self): - self.pico_terminal._pyboard.send_ctrl_c() + self.terminal.pyboard.send_ctrl_c() def terminal(self, command: str): - self.pico_terminal.terminal(command, stream_output=True) + self.terminal.terminal(command, stream_output=True) def listing(self, remote: str = '/'): - status, output, exception = self.pico_terminal.ls(remote) + status, output, exception = self.terminal.ls(remote) if status: - print('-' * 60) - print('[ ]', strpad('filename'), 'size|exception') - print('-' * 60) + tab = Tab(4, 30, 15, 30) + tab.labels('[ ]', 'Filename', 'Size (kb)', 'Exception') for name, size in output: if size == -1: - print('[*]', strpad(name[1:]), '-') + tab.print('[*]', name[1:], '-') else: - print('[*]', strpad(name[1:]), f'{size}b') + tab.print('[*]', name[1:], f'{size}b') else: - print('[?]', strpad(remote), exception) + tab.print('[?]', remote, '', str(exception)) def contents(self, remote: str): try: - content, _ = self.pico_terminal.get(remote) + content, _ = self.terminal.get(remote) for ln in content.decode('utf-8').split('\n'): print(ln) @@ -570,26 +600,24 @@ class Picowatch(object): elif os.path.exists(local): queue.append((local, filepath)) - print('-' * 60) - print('[ ]', strpad('filename'), 'checksum|exception') - print('-' * 60) + tab = Tab(4, 30, 15, 30) + tab.labels('[ ]', 'Filename', 'Checksum', 'Exception') for filename, remote in queue: try: - print('[↑]', strpad(filename), self.pico_terminal.upload(filename, remote)) + tab.print('[↑]', filename, self.terminal.upload(filename, remote)) except Exception as e: - print('[?]', strpad(filename), str(e)) + tab.print('[?]', filename, '-', str(e)) def download(self, filepath: str): if filepath.startswith('.'): filepath = filepath[1:] - status, output, exception = self.pico_terminal.ls(filepath) + status, output, exception = self.terminal.ls(filepath) if status: - print('-' * 60) - print('[ ]', strpad('filename'), 'checksum|exception') - print('-' * 60) + tab = Tab(4, 30, 15, 30) + tab.labels('', 'Filename', 'Checksum', 'Exception') for remote, size in output: if size == -1: @@ -600,50 +628,70 @@ class Picowatch(object): if not size == -1: try: - print('[↓]', strpad(local), self.pico_terminal.download(remote, local)) + tab.print('[↓]', local, self.terminal.download(remote, local)) except Exception as e: - print('[?]', strpad(local), str(e)) + tab.print('[?]', local, '', str(e)) else: - print('[?]', strpad(filepath), exception) + tab.print('[?]', filepath, '', exception) def delete(self, filepath: str): - status, output, exception = self.pico_terminal.rm(filepath) + status, output, exception = self.terminal.rm(filepath) if status: - print('-' * 60) - print('[ ]', strpad('filename'), 'exception') - print('-' * 60) + tab = Tab(4, 30, 30) + tab.labels('[ ]', 'Filename', 'Exception') for remote, checked, message in output: local = f'.{remote}' if checked: - print('[-]', strpad(local)) + tab.print('[-]', local) else: - print('[?]', strpad(local), message) + tab.print('[?]', local, message) else: - print('[?]', strpad(filepath), exception) + tab.print('[?]', filepath, exception) def compare(self, source: str): - content, _ = self.pico_terminal.get(source) + content, _ = self.terminal.get(source) fh, filename = tempfile.mkstemp() try: with os.fdopen(fh, 'wb') as tmp: tmp.write(content) - subprocess.Popen(f'code --diff "./src/{source}" "{filename}"', stdout=subprocess.PIPE, shell=True).communicate() - print(filename) + subprocess.Popen(f'code --diff "{filename}" "./src/{source}"', stdout=subprocess.PIPE, shell=True).communicate() finally: - input('<<< ') + input('Press Enter to delete temp file.') os.remove(filename) def status(self): - status_out = subprocess.check_output(['git', 'status', '-s']) - print(status_out) + changes = [] + + try: + output = subprocess.check_output(['git', 'status', '-s']) + + for filename in [f.strip() for f in output.decode('utf-8').split('\n')]: + if not filename: + continue + + status, filename = filename.split(' ') + + if filename.startswith('src/'): + if status in ['A', 'M', '??']: + changes.append((1, filename)) + elif status == 'D': + changes.append((0, filename)) + except: + pass + + tab = Tab(4, 40) + tab.labels('[ ]', 'Filename') + + for status, filename in changes: + tab.print('[+]' if status == 1 else '[-]', filename) def launch(self, filepath: str): - self.pico_terminal.launch(filepath) + self.terminal.launch(filepath) def watch(self, filename: str): if filename.startswith('/'): @@ -653,7 +701,7 @@ class Picowatch(object): filename = './' + filename with open(filename, 'r') as fh: - self.pico_terminal.terminal(fh.read(), stream_output=True) + self.terminal.terminal(fh.read(), stream_output=True) @@ -714,34 +762,3 @@ while True: print(f'"{message}" is not recognized.') except Exception as e: print(str(e)) - - -# def git_status(): -# '''Get the status of the local git repo''' -# global modified, deleted, added -# # A Dictionary with status-list pairs -# delta = {'M' : modified, 'D' : deleted, '?' : added, 'A' : added} -# # Get the output of the 'git status -s' CMD command as a string -# status_out = subprocess.check_output(['git', 'status', '-s']) -# # Split recived output to lines -# files = status_out.split('\n') -# # Sort the filenames to their appropriate list -# for filename in files: -# # Avoid errors (last line of output might be '') -# if len(filename) < 1: -# continue -# # Remove all spaces in filename -# filename = filename.replace(' ', '') -# # Get the status and remove it from file name -# file_status = filename[0] -# filename = filename[1:] -# # Untracked files are prefixed by '??' so we need to remove one '?' -# if file_status == '?': -# filename = filename[1:] -# # If status unfamilier, ignore the file -# # TODO: add 'other' list -# # TODO: Dispose of unwanted extansions here -# if file_status not in delta.keys(): -# continue -# delta[file_status].append(filename) -# stage_file(filename) \ No newline at end of file