diff --git a/dr1p4ns1.py b/dr1p4ns1.py index e9bfaaa..bd8caaa 100644 --- a/dr1p4ns1.py +++ b/dr1p4ns1.py @@ -2,8 +2,12 @@ #################################################################################################### ####################### from glob import glob from time import sleep +from collections import namedtuple import sys,tty,os,termios,shutil #################################################################################################### ####################### +#################################################################################################### ####################### + #### +#################################################################################################### ####################### """MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ####################### MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh+MMMMMMMMMMMMMMhsMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ####################### MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMm/ oMMMMMMMMMMMMMMm +NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ####################### @@ -36,10 +40,19 @@ MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN+` `+NMMMMMMMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNs. -hMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ####################### MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMdyymMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM""" ####################### #################################################################################################### ####################### - + ##### +#################################################################################################### ####################### +#################################################################################################### ####################### +FIFO_PATH = f"{os.path.expanduser('~')}/.weechat/weechat_fifo" ##### +FIFO_ENABLED = True ##### +COPY_PATH = f"{os.path.expanduser('~')}/Pictures" ##### +DELETE_PATH = "/tmp" ##### +#################################################################################################### ####################### +#################################################################################################### ####################### + ##### ### "00", "01", "02", "03", "04", "05", "06", "07", ########################################### ### "08", "09", "10", "11", "12", "13", "14", "15", ########################################### - + ##### 0xFFFFFF, 0x000000, 0x00007F, 0x009300, 0xFF0000, 0x7F0000, 0x9C009C, 0xFC7F00, ########################################### 0xFFFF00, 0x00FC00, 0x009393, 0x00FFFF, 0x0000FC, 0xFF00FF, 0x7F7F7F, 0xD2D2D2, ########################################### ##### @@ -64,7 +77,24 @@ MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMdyymMMMMMMMMMMMMMMMMMMMMMMMMMMM ##### ############################################################################################################################# ############################################################################################################################# - +def getfiles(argv=""): + PATH="" + if len(argv) > 1: + if argv[1] == ".": + PATH="" + else: + PATH=f'{argv[1]}/' + if len(argv) == 1: + PATH="" + files=glob(PATH+"*") + FILES=[] + for _ in files: + if _.lower()[-4:]==".ans": + FILES.append(_) + if len(FILES)==0: + print('ERROR: NO ANSI FILES IN THE PATH SPECIFIED',end='') + sys.exit(1) + return FILES ########################################################################################################## CLASS DR1P4NS1 - 2 class dr1p4ns1: ############################################################################################################ LOOKUP TABLE @@ -137,7 +167,6 @@ class dr1p4ns1: self.height=height self.filename=ansifile self.openansi(ansifile) - #self.openascii() self.code='\x1b[0m' self.cmps=[] self.op=[] @@ -149,7 +178,7 @@ class dr1p4ns1: ######################################################################################################### FILE OPERATIONS def fifo(self,s): s=[s] - f=open(f"{os.path.expanduser('~')}/.weechat/weechat_fifo","w") + f=open(FIFO_PATH,"w") [f.write("*{}\n".format(x)) for x in s] f.close() ######################################################################################################### FILE OPERATIONS @@ -157,7 +186,7 @@ class dr1p4ns1: f=open(s,'rb') self.ansifile=f.read().decode('cp437') f.close() - ############################################################################################# DEBUGGING - FILE OPERATIONS + ############################################################################################################### DEBUGGING def openascii(self): f=open('ansiscii/work.asc','r') self.reference=f.read() @@ -250,7 +279,7 @@ class dr1p4ns1: code=self.ansifile[i:] self.codes.append([code,i,len(self.ansifile)]) if code[1:6].upper()=="SAUCE": - self.getsauce(code[1:]) + self.getsauce() else: if 64 <= ord(_) <= 126: try: @@ -352,6 +381,7 @@ class dr1p4ns1: color_bg=_ colors=f"{color_set}" processed_colors.append(colors) + self.processed = processed irc_processed=[] terminal_processed=[] color_table=[1,5,3,7,2,6,10,15,14,4,9,8,12,13,11,0]; @@ -425,8 +455,6 @@ class dr1p4ns1: bold_before.append(int(bg_color)) else: bold_before.append(int(fg_color)) - # else: - # print('how are you here') newcode='\x03' bold_before.sort() for _ in bold_before: @@ -445,17 +473,15 @@ class dr1p4ns1: _line=_line.replace(code_replace,newcode,1) irc_processed.append(_line) terminal_processed.append(line) - for _ in terminal_processed: - print(_) - if self.pump: - for i,theline in enumerate(irc_processed): - self.fifo(theline) #################################################################################################################### TOOL - def getsauce(self,sauce): - self.sauce=sauce + def getsauce(self): + f=open(self.filename,'rb') + l=f.read() + f.close() + self.sauce=l[-128:] self.sauce_found=True - self.width=ord(self.sauce[96]) - self.height=ord(self.sauce[98]) + self.width=self.sauce[96] + self.height=self.sauce[98] offset=len("SAUCE") self.sauce_version=str(int(self.sauce[offset:offset+2].strip())) offset+=2 @@ -533,114 +559,659 @@ class dr1p4ns1: #################################################################################################################### TOOL def invert_dict(self,d): return {v: k for k, v in d.items()} - ########################################################################################################## CLASS MAIN - 4 + #################################################################################################################### BOOT def boot(self): if self.DEBUG: print("\n\x1b[1;31m[ HEXDUMP ]\x1b[0m\n") self.printhex() self.codedump() self.processdump() -############################################################################################################################# -def getkey(): - old_settings = termios.tcgetattr(sys.stdin) - tty.setcbreak(sys.stdin.fileno()) - try: - while True: - b = os.read(sys.stdin.fileno(), 3).decode() - if len(b) == 3: - k = ord(b[2]) - else: - k = ord(b) - key_mapping = { - 112: 'p', - 27: 'esc', - 67: 'right', - 68: 'left', - 113: 'q', - 120: 'x', - 99: 'c', - 82: 'R' - } - return key_mapping.get(k, chr(k)) - finally: - termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings) -################################################################################################################### ENTRY - 1 -if __name__ == "__main__": - ####################################### - if len(sys.argv) > 1: - PATH='' - if sys.argv[1]=='.': - PATH=os.getcwd() - files=glob(PATH+"/*.ans") - files+=glob(PATH+"/*.ANS") - else: - files=glob(sys.argv[1]+"/*.ans") - files+=glob(sys.argv[1]+"/*.ANS") - else: - files=glob('ansiscii/*.ans') - files+=glob('ansiscii/*.ANS') - ####################################### - if len(files)==0: - print('ERROR: NO ANSI FILES IN THE PATH SPECIFIED',end='') - sys.exit(1) - ####################################### - index=0 - try: - print(f'loading: {files[index]}') - d=dr1p4ns1(ansifile=files[index],width=80,debug=False) - except: - pass - ####################################### - try: - while True: - B='\x1b[1;94m'; C='\x1b[1;94m'; S='\x1b[1;36m'; M='\x1b[1;92m'; E='\x1b[0m' - msg=f"{B}[ {C}DR1P {B}] {S}- {B}[ {C}q{S}: {M}quit{S}, {C}c{S}: {M}copy{S}, {C}R{S}: {M}remove{S}, {C}p{S}: {M}pump{S}, {C}left{S}: {M}previous{S}, {C}right{S}: {M}next {B}] {S}- {C}filename{S}: {M}" - msg+=f"{d.filename}{E}" - print(msg) - k = getkey() - if k == 'left': - index-=1 - if index < 0: index=len(files)-1 - try: - print(f'{C}loading{B}: {S}{files[index]}') - d=dr1p4ns1(ansifile=files[index],width=80,debug=False) - except: - pass - elif k == 'right': - index+=1 - if index >= len(files): index=0 - try: - print(f'{C}loading{B}: {S}{files[index]}') - d=dr1p4ns1(ansifile=files[index],width=80,debug=False) - except: - pass - elif k == 'esc' or k == 'q' or k == 'x': - quit() - elif k == 'R': - print('file removed: placed in /tmp directory') - sleep(3) - shutil.copyfile(d.filename,f'/tmp/{str(d.filename).split("/")[1]}') - os.remove(d.filename) - elif k == 'p': - print('pump') # - d=dr1p4ns1(ansifile=files[index],width=80,debug=False,pump=True) - sleep(1) - elif k == 'c': - try: - shutil.copyfile(d.filename,f'pump/{str(d.filename).split("/")[1]}') - print(f'{C}file copied to pump directory') - except: - print(f'{M}file was not copied') - else: - index+=1 - if index >= len(files): index=0 - try: - d=dr1p4ns1(ansifile=files[index],width=80,debug=False) - except: - pass - ####################################### - except (KeyboardInterrupt, SystemExit): - os.system('stty sane') - ####################################### +####################################################################################### HUMAN INTERFACE * * * * * * * * * * * +class UI: + def __init__(self,files=""): + self.REMOVED=False + self.files=files + self.uis_menu() + ################################################################################### HUMAN INTERFACE * * * * * * * * * * * + def getkey(self): + old_settings = termios.tcgetattr(sys.stdin) + tty.setcbreak(sys.stdin.fileno()) + try: + while True: + b = os.read(sys.stdin.fileno(), 3).decode() + if len(b) == 3: + k = ord(b[2]) + else: + k = ord(b) + key_mapping = { + 112: 'p', + 27: 'esc', + 67: 'right', + 68: 'left', + 113: 'q', + 120: 'x', + 99: 'c', + 82: 'R' + } + return key_mapping.get(k, chr(k)) + finally: + termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings) + ################################################################################### HUMAN INTERFACE * * * * * * * * * * * + def uis_menu(self): + index=0 + try: + print(f'loading: {self.files[index]}') + d=dr1p4ns1(ansifile=self.files[index],width=80,debug=False) + decoder=ANSIDecoder(self.files[index],d.width) + decoder.as_terminal() + except: + pass + ####################################### + try: + while True: + B='\x1b[1;94m'; C='\x1b[1;94m'; S='\x1b[1;36m'; M='\x1b[1;92m'; E='\x1b[0m'; R='\x1b[31m' + msg=f"{B}[ {C}DR1P {B}] {S}- {B}[ {C}q{S}: {M}quit{S}, {C}c{S}: {M}copy{S}, {C}R{S}: {M}remove{S}, {C}p{S}: {M}pump{S}, " + msg+=f"{C}left{S}: {M}previous{S}, {C}right{S}: {M}next {B}] {S}- " + msg+=f"{C}filename{S}: {M}{d.filename} {S}- {B}[{C}{index+1}{S}/{C}{len(self.files)}{B}]{E}" + if self.REMOVED==True: msg+=f'{R} - FILE REMOVED' + print(msg) + k = self.getkey() + if k == 'left': + index-=1 + if index < 0: index=len(self.files)-1 + try: + self.REMOVED=False + if len(self.files) == 0: + print(f'{B}NO FILES LEFT IN QUEUE - {R} EXITING') + sleep(1) + break + print(f'{C}loading{B}: {S}{self.files[index]}') + d=dr1p4ns1(ansifile=self.files[index],width=80,debug=False) + decoder=ANSIDecoder(self.files[index],d.width) + decoder.as_terminal() + except: + pass + elif k == 'right': + index+=1 + if index >= len(self.files): index=0 + try: + self.REMOVED=False + if len(self.files) == 0: + print(f'{B}NO FILES LEFT IN QUEUE - {R} EXITING') + sleep(1) + break + print(f'{C}loading{B}: {S}{self.files[index]}') + d=dr1p4ns1(ansifile=self.files[index],width=80,debug=False) + decoder=ANSIDecoder(self.files[index],d.width) + decoder.as_terminal() + except: + pass + elif k == 'esc' or k == 'q' or k == 'x': + quit() + elif k == 'c': + try: + if not self.files[index].find('/') == -1: + FILEPATH=f'{COPY_PATH}/{str(self.files[index]).split("/")[1]}' + shutil.copyfile(self.files[index],FILEPATH) + print(f'{C}{self.files[index]} copied to {FILEPATH}') + else: + FILEPATH=f'{COPY_PATH}/{self.files[index]}' + shutil.copyfile(self.files[index],FILEPATH) + print(f'{C}{self.files[index]} {M}copied to {C}{FILEPATH}') + except: + print(f'{C}{self.files[index]} {M}was not copied') + sleep(1) + decoder.as_terminal() + elif k == 'p': + try: + if FIFO_ENABLED: + decoder=ANSIDecoder(self.files[index],d.width) + decoder.as_irc() + print(f'{M}pumping: pumping {C}{self.files[index]} {M}to fifo - {C}{FIFO_PATH}') + else: + print(f'{M}pumping disabled - fifo not detected in path: {C}{FIFO_PATH}') + except Exception as e: + print(f'{M}pumping failed - {e}') + sleep(3) + decoder.as_terminal() + elif k == 'R': + try: + if not self.files[index].find('/') == -1: + FILEPATH=f'{DELETE_PATH}/{str(self.files[index]).split("/")[1]}' + shutil.copyfile(self.files[index],FILEPATH) + else: + FILEPATH=f'{DELETE_PATH}/{self.files[index]}' + shutil.copyfile(self.files[index],FILEPATH) + os.remove(self.files[index]) + self.REMOVED=True + buffer=self.files[index] + self.files.remove(self.files[index]) + print(f'{R}{buffer} removed: placed in {DELETE_PATH} directory') + except: + print(f'{C}{self.files[index]} {M}was not removed') + sleep(3) + decoder.as_terminal() -######################################################################################################################### EOF + else: + index+=1 + if index >= len(self.files): index=0 + try: + self.REMOVED=False + if len(self.files) == 0: + print(f'{B}NO FILES LEFT IN QUEUE - {R} EXITING') + sleep(1) + break + d=dr1p4ns1(ansifile=self.files[index],width=80,debug=False) + decoder=ANSIDecoder(self.files[index],d.width) + decoder.as_terminal() + except: + pass + ####################################### + except (KeyboardInterrupt, SystemExit): + os.system('stty sane') +############################################################################################################################# +class ANSIDecodeError(ValueError): + pass +############################################################################################################################# +class ANSIDecoder: +############################################################################################################################# + PALETTES = { + 'vga': { + False: ['000', 'a00', '0a0', 'a50', '00a', 'a0a', '0aa', 'aaa'], + True: ['555', 'f55', '5f5', 'ff5', '55f', 'f5f', '5ff', 'fff'], + }, + 'workbench': { + False: ['aaa', '000', 'fff', '68b', '00f', 'f0f', '0ff', 'fff'], + True: ['aaa', '000', 'fff', '68b', '00f', 'f0f', '0ff', 'fff'], + } + } + ######################################################################################################################### + PALETTE_NAMES = PALETTES.keys() + REMAPPED_CHARS = { + '\x00': ' ', + '\x01': '\u263a', + '\x02': '\u263b', + '\x03': '\u2665', + '\x04': '\u2666', + '\x05': '\u2663', + '\x06': '\u2660', + '\x10': '\u25ba', + '\x11': '\u25c4', + '\x16': '\u25ac', + '\x1d': '\u2194', + '\x1e': '\u25b2', + '\x1f': '\u25bc', + } + ######################################################################################################################### + DEFAULT_FG = 7 + DEFAULT_BG = 0 + ######################################################################################################################### + Attribute = namedtuple('Attribute', ['fg', 'bg', 'bright', 'underline']) + ######################################################################################################################### + DEFAULT_ATTR = Attribute(fg=DEFAULT_FG, bg=DEFAULT_BG, bright=False, underline=False) + def __init__(self,files="",width=80): + #stream=None, palette='vga', width=80, strict=False + self.current_line = [] + self.buffer = [self.current_line] + self.palette = self.PALETTES['vga'] + self.x = 0 + self.y = 0 + self.saved_x = 0 + self.saved_y = 0 + self.current_attr = self.DEFAULT_ATTR + self.width = width + self.strict = False + self.filename=files + stream=open(self.filename,'rt',encoding='cp437') + if stream: + self.play(stream) + ######################################################################################################################### + def write_char(self, char): + # Handle an ordinary character + try: + self.current_line[self.x] = (self.current_attr, char) + except IndexError: + # X position is out of range; append to current line + while len(self.current_line) < self.x: + self.current_line.append((self.DEFAULT_ATTR, ' ')) + self.current_line.append((self.current_attr, char)) + + self.x += 1 + if self.x >= self.width: + self.write_newline() + ######################################################################################################################### + def set_cursor(self, x=None, y=None): + if x is not None: + self.x = max(x, 0) + if y is not None: + self.y = max(y, 0) + + try: + self.current_line = self.buffer[self.y] + except IndexError: + while len(self.buffer) <= self.y: + self.current_line = [] + self.buffer.append(self.current_line) + ######################################################################################################################### + def write_newline(self): + # Handle a line break + self.set_cursor(x=0, y=(self.y + 1)) + ######################################################################################################################### + def set_attr(self, fg=None, bg=None, bright=None, underline=None): + if fg is None: + fg = self.current_attr.fg + if bg is None: + bg = self.current_attr.bg + if bright is None: + bright = self.current_attr.bright + if underline is None: + underline = self.current_attr.underline + + self.current_attr = self.Attribute(fg=fg, bg=bg, bright=bright, underline=underline) + ######################################################################################################################### + def write_escape(self, code, params): + if code == 'm': + for param in params: + if param == 0: + self.current_attr = self.DEFAULT_ATTR + elif param == 1: + self.set_attr(bright=True) + elif param == 2 or param == 22: + self.set_attr(bright=False) + elif param == 4: + self.set_attr(underline=True) + elif param == 24: + self.set_attr(underline=False) + elif 30 <= param <= 37: + self.set_attr(fg=(param - 30)) + elif 40 <= param <= 47: + self.set_attr(bg=(param - 40)) + else: + if self.strict: + raise ANSIDecodeError("Unsupported parameter to 'm' escape sequence: %r" % param) + elif code == 'J': + if params == [] or params == [0]: + # erase from cursor to end of screen + del self.current_line[self.x:] + del self.buffer[(self.y + 1):] + elif params == [1]: + # erase up to cursor + for i in range(0, self.y): + del self.buffer[i][:] + try: + for i in range(0, self.x + 1): + self.current_line[i] = (self.DEFAULT_ATTR, ' ') + except IndexError: + del self.current_line[:] + elif params == [2]: + # erase entire screen + for i in range(0, self.y): + del self.buffer[i][:] + del self.buffer[(self.y + 1):] + else: + if self.strict: + raise ANSIDecodeError("Unrecognised parameters to 'J' escape sequence: %r" % params) + elif code == 'K': + if params == [] or params == [0]: + # erase from cursor to end of line + del self.current_line[self.x:] + elif params == [1]: + # erase up to cursor + try: + for i in range(0, self.x + 1): + self.current_line[i] = (self.DEFAULT_ATTR, ' ') + except IndexError: + del self.current_line[:] + elif params == [2]: + # erase entire line + del self.current_line[:] + else: + if self.strict: + raise ANSIDecodeError("Unrecognised parameters to 'K' escape sequence: %r" % params) + + elif code == 'A': + # move cursor up N lines + if not params: + self.set_cursor(y=(self.y - 1)) + elif len(params) == 1: + self.set_cursor(y=(self.y - params[0])) + elif self.strict: + raise ANSIDecodeError("Expected 0 or 1 param to 'A' escape sequence, got %d" % len(params)) + + elif code == 'B': + # move cursor down N lines + if not params: + self.set_cursor(y=(self.y + 1)) + elif len(params) == 1: + self.set_cursor(y=(self.y + params[0])) + elif self.strict: + raise ANSIDecodeError("Expected 0 or 1 param to 'B' escape sequence, got %d" % len(params)) + + elif code == 'C': + # move cursor right N cols + if not params: + self.set_cursor(x=(self.x + 1)) + elif len(params) == 1: + self.set_cursor(x=(self.x + params[0])) + elif self.strict: + raise ANSIDecodeError("Expected 0 or 1 param to 'C' escape sequence, got %d" % len(params)) + + elif code == 'D': + # move cursor left N cols + if not params: + self.set_cursor(x=(self.x - 1)) + elif len(params) == 1: + self.set_cursor(x=(self.x - params[0])) + elif self.strict: + raise ANSIDecodeError("Expected 0 or 1 param to 'D' escape sequence, got %d" % len(params)) + + elif code == 'E': + # move cursor to beginning of next line, N lines down + if not params: + self.set_cursor(x=0, y=(self.y + 1)) + elif len(params) == 1: + self.set_cursor(x=0, y=(self.y + params[0])) + elif self.strict: + raise ANSIDecodeError("Expected 0 or 1 param to 'E' escape sequence, got %d" % len(params)) + + elif code == 'F': + # move cursor to beginning of previous line, N lines up + if not params: + self.set_cursor(x=0, y=(self.y - 1)) + elif len(params) == 1: + self.set_cursor(x=0, y=(self.y - params[0])) + elif self.strict: + raise ANSIDecodeError("Expected 0 or 1 param to 'F' escape sequence, got %d" % len(params)) + + elif code == 'G': + # move cursor to column N + if len(params) == 1: + self.set_cursor(x=params[0]) + elif self.strict: + raise ANSIDecodeError("Expected 1 param to 'G' escape sequence, got %d" % len(params)) + + elif code == 'H' or code == 'f': + # move cursor to (line, col) + if not params: + self.set_cursor(x=0, y=0) + elif len(params) == 2: + self.set_cursor(x=params[1] - 1, y=params[0] - 1) + elif self.strict: + raise ANSIDecodeError("Expected 0 or 2 param to '%s' escape sequence, got %d" % (code, len(params))) + + elif code == 'h': + if params == [7]: + # enable line wrapping + pass + elif self.strict: + raise ANSIDecodeError("Unrecognised params to 'h' - got %r" % params) + + elif code == 's': + # save cursor position + if params and self.strict: + raise ANSIDecodeError("Unrecognised params to 's' - got %r" % params) + self.saved_x = self.x + self.saved_y = self.y + + elif code == 'u': + # restore cursor position + if params and self.strict: + raise ANSIDecodeError("Unrecognised params to 'u' - got %r" % params) + self.set_cursor(x=self.saved_x, y=self.saved_y) + + else: + if self.strict: + raise ANSIDecodeError("Unrecognised escape code: %r" % code) + ######################################################################################################################### + def play(self, f): + while True: + # Read file a character at a time + char = f.read(1) + if not char: + # End of file + break + elif char >= ' ': + self.write_char(char) + elif char == '\x0a': # LF + self.write_newline() + elif char == '\x0d': # CR + continue + elif char in self.REMAPPED_CHARS: + self.write_char(self.REMAPPED_CHARS[char]) + elif char == '\x1a': + # EOF when using SAUCE records + break + elif char == '\x1b': + # Handle an escape sequence + char = f.read(1) + # Next character is expected to be '[' + if char != '[': + if self.strict: + raise ANSIDecodeError("Unrecognised character after ESC: %r" % char) + continue + params = [] + param = None + private = False + while True: + char = f.read(1) + if '0' <= char <= '9': + if param is None: + param = int(char) + else: + param = param * 10 + int(char) + elif char == ';': + if param is None: + if self.strict: + raise ANSIDecodeError("Encountered ';' character without parameter") + else: + params.append(param) + param = None + elif char == ' ': + pass + elif char == '?': + private = True + else: + if param is not None: + params.append(param) + + if not private: + self.write_escape(char, params) + break + elif self.strict: + raise ANSIDecodeError("Unrecognised character: %r" % char) + ######################################################################################################################### + def fifo(self,s): + s=[s] + f=open(FIFO_PATH,"w") + [f.write("*{}\n".format(x)) for x in s] + f.close() + ################################################################################################### RE-ENCODING ENCODINGS + def as_irc_lines(self): + default_fg=7 + default_bg=0 + color_table=[1,5,3,7,2,6,10,15,14,4,9,8,12,13,11,0] + color_fg=color_table[default_fg] + color_bg=color_table[default_bg] + offset_bold=0 + reset_bold=False + last_attr = None + processing='' + self.fifo(f"filename: {self.filename}") + for i,line in enumerate(self.buffer): + for n,(attr, char) in enumerate(line): + ####################################################################################### FOR LINE + if attr[2]: + offset_bold=8 + else: + offset_bold=0 + color_fg=color_table[attr[0]+offset_bold] + color_bg=color_table[attr[1]] + if attr != last_attr: + if last_attr==None: + processing+=f'\x03{color_table[attr[0]]},{color_table[attr[1]]}' + color_fg=color_table[attr[0]] + color_bg=color_table[attr[1]] + else: + if n==0 and not attr[0]==default_fg: + if attr[2]: + processing+=f'\x03{color_table[attr[0]+offset_bold]},{color_table[attr[1]]}' + color_fg=color_table[attr[0]+offset_bold] + color_bg=color_table[attr[1]] + else: + processing+=f'\x03{color_table[attr[0]]},{color_table[attr[1]]}' + color_fg=color_table[attr[0]] + color_bg=color_table[attr[1]] + elif n==0 and attr[2]: + processing+=f'\x03{color_table[attr[0]+offset_bold]},{color_table[attr[1]]}' + color_fg=attr[0]+offset_bold + color_bg=attr[1] + if not attr[2]==last_attr[2] and not n==0: + if attr[0] == last_attr[0] and not attr[1] == last_attr[1]: + processing+=f'\x03{color_table[attr[0]+offset_bold]},{color_table[attr[1]]}' + color_fg=attr[0]+offset_bold + color_bg=attr[1] + elif attr[0] == last_attr[0] and attr[1] == last_attr[1]: + processing+=f'\x03{color_table[attr[0]+offset_bold]}' + color_fg=attr[0]+offset_bold + elif not attr[0] == last_attr[0] and attr[1] == last_attr[1]: + processing+=f'\x03{color_table[attr[0]+offset_bold]}' + color_fg=attr[0]+offset_bold + elif not attr[0] == last_attr[0] and not attr[1] == last_attr[1]: + processing+=f'\x03{color_table[attr[0]+offset_bold]},{color_table[attr[1]]}' + color_fg=attr[0]+offset_bold + color_bg=attr[1] + elif not attr[0]==last_attr[0] and not attr[1]==last_attr[1] and not n==0: + processing+=f'\x03{color_table[attr[0]+offset_bold]},{color_table[attr[1]]}' + color_fg=attr[0]+offset_bold + color_bg=attr[1] + elif not attr[0]==last_attr[0] and not n==0: + if attr[2]: + processing+=f'\x03{color_table[attr[0]+offset_bold]}' + color_fg=attr[0]+offset_bold + else: + if not '\x30' <= char <= '\x39': + processing+=f'\x03{color_table[attr[0]]},{color_table[attr[1]]}' + else: + processing+=f'\x03{color_table[attr[0]]},{str(color_table[attr[1]]).zfill(2)}' + color_fg=attr[0] + elif not attr[1]==last_attr[1] and not n==0: + if attr[2]: + processing+=f'\x03{color_table[attr[0]+offset_bold]},{color_table[attr[1]]}' + color_fg=attr[0]+offset_bold + color_bg=attr[1] + else: + processing+=f'\x03{color_table[attr[0]]},{color_table[attr[1]]}' + color_fg=attr[0] + color_bg=attr[1] + else: + if n==0 and not attr[0]==default_fg: + if attr[2]: + processing+=f'\x03{color_table[attr[0]+offset_bold]},{color_table[attr[1]]}' + color_fg=color_table[attr[0]+offset_bold] + color_bg=color_table[attr[1]] + else: + processing+=f'\x03{color_table[attr[0]]},{color_table[attr[1]]}' + color_fg=color_table[attr[0]] + color_bg=color_table[attr[1]] + if len(processing) == 0: + processing+=f"\x0315,1" + processing+=char + last_attr=attr + if len(self.buffer[i]) == 0: + self.output_lines.append(f"\x031,1{'█'*self.width}") + else: + distance=int(self.width)-len(line) + processing+=f"\x031,1{'█'*distance}" + self.output_lines.append(processing) + processing='' + ######################################################################################################################### + def as_irc(self): + self.output_lines=[] + self.as_irc_lines() + for _ in self.output_lines: + self.fifo(_) + pass + ################################################################################################### RE-ENCODING ENCODINGS + def as_terminal_lines(self): + default_fg=7 + default_bg=0 + last_attr = None + processing='' + for i,line in enumerate(self.buffer): + for n,(attr, char) in enumerate(line): + if attr != last_attr: + if last_attr == None: + processing+=f'\x1b[{attr[0]+30};{attr[1]+40}m' + else: + if n==0 and not attr[0]==default_fg: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30};{attr[1]+40}m' + else: + processing+=f'\x1b[0;{attr[0]+30};{attr[1]+40}m' + elif n==0 and attr[2]: + processing+=f'\x1b[1;{attr[0]+30};{attr[1]+40}m' + elif n==0 and not attr[2]: + processing+=f'\x1b[0;{attr[0]+30};{attr[1]+40}m' + if not attr[2]==last_attr[2] and not n==0: + if attr[0] == last_attr[0] and not attr[1] == last_attr[1]: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30};{attr[1]+40}m' + else: + processing+=f'\x1b[0;{attr[0]+30};{attr[1]+40}m' + elif attr[0] == last_attr[0] and attr[1] == last_attr[1]: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30}m' + else: + processing+=f'\x1b[0;{attr[0]+30}m' + elif not attr[0] == last_attr[0] and attr[1] == last_attr[1]: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30}m' + else: + processing+=f'\x1b[0;{attr[0]+30}m' + elif not attr[0] == last_attr[0] and not attr[1] == last_attr[1]: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30};{attr[1]+40}m' + else: + processing+=f'\x1b[0;{attr[0]+30};{attr[1]+40}m' + elif not attr[0]==last_attr[0] and not attr[1]==last_attr[1] and not n==0: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30};{attr[1]+40}m' + else: + processing+=f'\x1b[0;{attr[0]+30};{attr[1]+40}m' + elif not attr[0]==last_attr[0] and not n==0: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30}m' + else: + processing+=f'\x1b[{attr[0]+30};{attr[1]+40}m' + elif not attr[1]==last_attr[1] and not n==0: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30};{attr[1]+40}m' + else: + processing+=f'\x1b[0;{attr[0]+30};{attr[1]+40}m' + else: + if n==0 and not attr[0]==default_fg: + if attr[2]: + processing+=f'\x1b[1;{attr[0]+30};{attr[1]+40}m' + else: + processing+=f'\x1b[0;{attr[0]+30};{attr[1]+40}m' + processing+=char + last_attr=attr + self.output_lines.append(processing + '\x1b[40;37m') + processing='' + ######################################################################################################################### + def as_terminal(self): + self.output_lines=[] + self.as_terminal_lines() + for _ in self.output_lines: + print(_) + pass +################################################################################################################### ENTRY - 1 +if __name__=="__main__": + FIFO_ENABLED = os.path.exists(FIFO_PATH) + files = getfiles(sys.argv) + ui = UI(files) + # for _ in files: + # d=dr1p4ns1(ansifile=_,width=80,debug=False) + # decoder=ANSIDecoder(_,d.width) + # # decoder.as_irc() + # decoder.as_terminal() \ No newline at end of file