import tkinter as tk import tkinter.ttk as ttk from tkinter import filedialog from tk_tooltip import CreateToolTip import re channel_names = [ "SAY", # 0 "SHOUT", # 1 "TEAM", # 2 "GUILD", # 3 # "CIVILIZATION", # Unused # "TERRITORY", # Unused "UNIVERSE", # 4 "TELL", # 5 # "PLAYER", # Unused # "ARROUND", # Unused "REGION", # 6 "DYN0", # 7 "DYN1", # 8 "DYN2", # 9 "DYN3", # 10 "DYN4", # 11 "EMOTES", # 12 "SYSTEM", # 13 ] system_info_categories = [ ("SYS", "Default system messages"), ("BC", "Broadcast messages"), ("TAGBC", "Tagged Broadcast messages"), ("XP", "XP Gain"), ("SP", "SP Gain"), ("TTL", "Title"), ("TSK", "Task"), ("ZON", "Zone"), ("DG", "Damage to me"), ("DMG", "Damage to me"), ("DGP", "Damage to me from player"), ("DGM", "Damage from me"), ("MIS", "Opponent misses"), ("MISM", "I miss"), ("ITM", "Item"), ("ITMO", "Item other in group"), ("ITMF", "Item failed"), ("SPL", "Spell to me"), ("SPLM", "Spell from me"), ("EMT", "Emote"), ("MTD", "Message of the day"), ("FORLD", "Forage locate deposit"), ("CHK", "Failed check"), ("CHKCB", "Failed check in combat"), ("PVPTM", "PVP Timer"), ("THM", "Thema finished (encyclopedia)"), ("AMB", "Ambiance (Occupation)"), ("ISE", "Item special effect"), ("ISE2", "Item special effect centered text"), ("OSM", "Outpost state message"), ("AROUND", "Around channel system message"), ("R2_INVITE", "Ring invitation"), ] def get_input_filepath(): global input_filepath filepath = filedialog.askopenfilename( filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")], initialdir='/'.join(ent_input.get().split('/')[:-1 if '.' in ent_input.get() else len(ent_input.get())]) ) if not filepath: return input_filepath = filepath ent_input.delete(0, tk.END) ent_input.insert(0, input_filepath) def get_output_filepath(): global output_filepath filepath = filedialog.askdirectory( initialdir=ent_output.get() ) if not filepath: return output_filepath = filepath ent_output.delete(0, tk.END) ent_output.insert(0, output_filepath) def toggle_channel(index): def tgl_chan(): if chan_toggle[index]: btn_chan_toggle[index].config(relief="raised", bg="#ffcccb") chan_toggle[index] = False if channel_names[index] == "SYSTEM": frm_btn_sys.grid_remove() else: btn_chan_toggle[index].config(relief="sunken", bg="#99e599") chan_toggle[index] = True if channel_names[index] == "SYSTEM": frm_btn_sys.grid() return tgl_chan def toggle_system(index): def tgl_sys(): if sys_toggle[index]: btn_sys_toggle[index].config(relief="raised", bg="#ffcccb") sys_toggle[index] = False else: btn_sys_toggle[index].config(relief="sunken", bg="#99e599") sys_toggle[index] = True return tgl_sys input_filepath = '' output_filepath = '' btn_chan_toggle = [] btn_sys_toggle = [] chan_toggle = [False] * len(channel_names) sys_toggle = [False] * len(system_info_categories) ent_input = None ent_output = None ent_outfile = None frm_btn_sys = None btn_process = None window = None def create_ui(): global btn_chan_toggle global btn_sys_toggle global chan_toggle global sys_toggle global ent_input global ent_output global ent_outfile global frm_btn_sys global window global btn_process window = tk.Tk() window.title("Ryzom Log Cleaner") window.columnconfigure(0, weight=1) #window.rowconfigure([0,1], minsize=50) btn_input = tk.Button(window, text="Input file", command=get_input_filepath) ent_input = tk.Entry(window, text="Input path") # ent_input.insert(0, "~/log.txt") btn_output = tk.Button(window, text="Output directory", command=get_output_filepath) ent_output = tk.Entry(window, text="Output path") # ent_output.insert(0, "~/cleaned/") frm_outfile = tk.Frame(window) lbl_outfile = tk.Label(frm_outfile, text="Output filename:") ent_outfile = tk.Entry(frm_outfile, text="Output filename") btn_input.grid(row=0, column=1) ent_input.grid(row=0, column=0, sticky='ew') btn_output.grid(row=1, column=1) ent_output.grid(row=1, column=0, sticky='ew') frm_outfile.grid(row=2, column=0, columnspan=2, sticky='ew') frm_outfile.columnconfigure(1, weight=1) lbl_outfile.grid(row=0, column=0) ent_outfile.grid(row=0, column=1, sticky='ew') lbl_channel_select = tk.Label(window, text="Select channels to keep:") lbl_channel_select.grid(row=3, column=0, sticky='w') btn_chan_toggle = [] frm_btn_channel = tk.Frame(window) frm_btn_channel.grid(row=4, column=0, columnspan=2, sticky='ew') frm_btn_channel.columnconfigure([0,1,2,3], weight=1) frm_btn_channel.rowconfigure([0,1,2], weight=1) for i,name in enumerate(channel_names): btn_chan_toggle.append(tk.Button(frm_btn_channel, text=name, command=toggle_channel(i), bg="#ffcccb")) btn_chan_toggle[i].grid(row=int(i/4), column=i%4, sticky='ew') btn_sys_toggle = [] frm_btn_sys = tk.Frame(window, bg="#808080", borderwidth=5) frm_btn_sys.grid(row=5, column=0, columnspan=2, sticky='e') frm_btn_sys.columnconfigure([0,1,2,3,4,5,6], weight=1) frm_btn_sys.rowconfigure([0,1,2,3,4], weight=1) for i,(name,tooltip) in enumerate(system_info_categories): btn_sys_toggle.append(tk.Button(frm_btn_sys, text=name, command=toggle_system(i), bg="#ffcccb")) btn_sys_toggle[i].grid(row=int(i/7), column=i%7, sticky='ew') ttp_sys = CreateToolTip(btn_sys_toggle[i], tooltip) btn_process = tk.Button(window, text="Process!", command=process_file) btn_process.grid(row=6, column=0, columnspan=2, sticky='ew') # Default selection chan_toggle = [False] * len(channel_names) sys_toggle = [False] * len(system_info_categories) toggle_channel(0)() toggle_channel(1)() toggle_channel(12)() toggle_channel(13)() toggle_system(7)() return window color_regex = re.compile('@\{[A-F0-9]{4}\}') keep_color = False keep_channel = False language_flag = False original_part = False translated_part = True def process_file(): chan_pattern = '|'.join(['\(' + name + '\)' for i,name in enumerate(channel_names[:-2]) if chan_toggle[i]]) if chan_toggle[-2]: chan_pattern += '|\(SAY/EMT\)' if chan_toggle[-1]: if sys_toggle[0]: chan_pattern += '|\(SYSTEM\)' for i,(name,tooltip) in enumerate(system_info_categories[1:]): if sys_toggle[i+1]: chan_pattern += '|\(SYSTEM/' + name + '\)' chan_regex = re.compile(chan_pattern) with open(ent_input.get(), 'r', errors='surrogateescape') as in_file, open(ent_output.get() + '/' + ent_outfile.get(), 'w', errors='surrogateescape') as out_file: orig_lines = 0 filtered_lines = 0 btn_process["text"] = "Started Processing..." for line in in_file: orig_lines += 1 if chan_regex.search(line) == None: continue if not keep_color: line = color_regex.sub('',line) if not keep_channel: line = line[line.find(') * ')+4:] translation_start = line.find('{:') if translation_start != -1 and not language_flag: line = line[:translation_start+1] + line[translation_start+5:] translation_end = line.find('}@{') if translation_end != -1 and not original_part: line = line[:translation_start] + line[translation_end+3:] # char_name_start = line.find(' * ') + 3 if not keep_color or line.find('}') == -1 else line.find('}') + 1 # char_name = ' '.join(line[char_name_start:line[char_name_start:].find(':')].split(' ')[:-1]) # if char_name[0] == '[' and char_name[2] == ']': # char_name = char_name[3:] # channel_name = line[21:line.find(')')] out_file.write(line.lstrip()) filtered_lines += 1 btn_process["text"]="Processing done! (" + str(filtered_lines) + " lines kept out of " + str(orig_lines) + " original lines)" if __name__ == '__main__': window = create_ui() window.mainloop()