From 320462d73dbb486d8c93a70406cf5a6ace5c77b0 Mon Sep 17 00:00:00 2001 From: Sit Melai Date: Fri, 19 Nov 2021 16:56:52 +0100 Subject: [PATCH] Add multi file input for processing and organising of logs --- README.md | 12 + main.py | 642 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 458 insertions(+), 196 deletions(-) diff --git a/README.md b/README.md index 5ac55e3..8adbaf1 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,15 @@ Attention ! Il laisse quelques fichiers dans le dossier courant. Gardez les logs Auteur : Zatalyz. Tout est sous licence CC0, c'est de l'assemblage de bons conseils et de tests, rien de transcendant. Plus de détail dans chaque script. + +## Python version +The script uses basic python3 with no additional 3rd part libraries. The main file is main.py and the only other file it uses is tk_tooltip.py. +To just run the GUI, run: +`python3 main.py` + +### +If you want to create a binary for distribution, it seems that pyinstaller is the easiest way. +Just run: + +`pip3 install pyinstaller` +`pyinstaller --onefile --noconsole --clean --log-level=WARN --strip main.py tk_tooltip.py` diff --git a/main.py b/main.py index 313cadc..474bb7d 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,5 @@ import tkinter as tk -import tkinter.ttk as ttk +from tkinter import ttk from tkinter import filedialog from tk_tooltip import CreateToolTip import re @@ -62,207 +62,457 @@ system_info_categories = [ ("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) - +class GUI: + color_regex = re.compile('@\{[A-F0-9]{4}\}') -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 __init__(self): + self.originalfolderlog = '' + self.keep_color = False + self.keep_channel = False + self.keep_lang_flag = False + self.keep_original_part = False + self.keep_translated_part = False + self.keep_timestamp = False + self.replace_charname = False + + self.window = tk.Tk() + self.window.title("Ryzom Log Cleaner") -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() + self.window.columnconfigure(0, weight=1) + #self.window.rowconfigure([0,1], minsize=50) + + self.ntb_file_selection = ttk.Notebook(self.window) + + ### Single file tab + self.frm_single_file = tk.Frame(self.window) + self.frm_single_file.columnconfigure(0, weight=1) + btn_input = tk.Button(self.frm_single_file, text="Input file", command=self.get_input_filepath) + self.ent_input = tk.Entry(self.frm_single_file, text="Input path") + # ent_input.insert(0, "~/log.txt") + btn_output = tk.Button(self.frm_single_file, text="Output file", command=self.get_output_filepath) + self.ent_output = tk.Entry(self.frm_single_file, text="Output path") + # ent_output.insert(0, "~/cleaned/") + self.frm_charname = tk.Frame(self.frm_single_file) + lbl_charname = tk.Label(self.frm_charname, text="Char name:") + self.ent_charname = tk.Entry(self.frm_charname, text="Charname") + self.ent_charname.insert(0, "Select input file to auto-fill") + + btn_input.grid(row=0, column=1, sticky='ew') + self.ent_input.grid(row=0, column=0, sticky='ew') + btn_output.grid(row=1, column=1, sticky='ew') + self.ent_output.grid(row=1, column=0, sticky='ew') + + self.frm_charname.grid(row=2, column=0, columnspan=2, sticky='ew') + self.frm_charname.columnconfigure(1, weight=1) + + lbl_charname.grid(row=0, column=0) + self.ent_charname.grid(row=0, column=1, sticky='ew') + + + ### Multi file tab + self.frm_multi_file = tk.Frame(self.window) + self.frm_multi_file.columnconfigure(0, weight=1) + btn_input_multi = tk.Button(self.frm_multi_file, text="Input files", command=self.get_input_filepaths) + self.ent_input_multi = tk.Entry(self.frm_multi_file, text="Input paths") + # ent_input.insert(0, "~/log.txt") + btn_output_multi = tk.Button(self.frm_multi_file, text="Output directory", command=self.get_output_directory) + self.ent_output_multi = tk.Entry(self.frm_multi_file, text="Output paths") + # ent_output.insert(0, "~/cleaned/") + self.frm_charname_multi = tk.Frame(self.frm_multi_file) + lbl_charname_multi = tk.Label(self.frm_charname_multi, text="Char name (detected from file name of each file if empty):") + self.ent_charname_multi = tk.Entry(self.frm_charname_multi, text="Charname Multi") + + btn_input_multi.grid(row=0, column=1, sticky='ew') + self.ent_input_multi.grid(row=0, column=0, sticky='ew') + btn_output_multi.grid(row=1, column=1, sticky='ew') + self.ent_output_multi.grid(row=1, column=0, sticky='ew') + + self.frm_charname_multi.grid(row=2, column=0, columnspan=2, sticky='ew') + self.frm_charname_multi.columnconfigure(1, weight=1) + + lbl_charname_multi.grid(row=0, column=0) + self.ent_charname_multi.grid(row=0, column=1, sticky='ew') + + + ### Organise logs tab + self.frm_organise_logs = tk.Frame(self.window) + self.frm_organise_logs.columnconfigure(0, weight=1) + btn_input_orgalogs = tk.Button(self.frm_organise_logs, text="Input directory", command=self.get_input_dir_orgalogs) + self.ent_input_orgalogs = tk.Entry(self.frm_organise_logs, text="Input dir") + # ent_input.insert(0, "~/log.txt") + btn_output_orgalogs = tk.Button(self.frm_organise_logs, text="(Empty) Output directory", command=self.get_output_dir_orgalogs) + self.ent_output_orgalogs = tk.Entry(self.frm_organise_logs, text="Output dir") + # ent_output.insert(0, "~/cleaned/") + self.frm_charname_orgalogs = tk.Frame(self.frm_organise_logs) + lbl_charname_orgalogs = tk.Label(self.frm_charname_orgalogs, text="Char name (detected from file name of each file if empty):") + self.ent_charname_orgalogs = tk.Entry(self.frm_charname_orgalogs, text="Charname Orgalogs") + + btn_input_orgalogs.grid(row=0, column=1, sticky='ew') + self.ent_input_orgalogs.grid(row=0, column=0, sticky='ew') + btn_output_orgalogs.grid(row=1, column=1, sticky='ew') + self.ent_output_orgalogs.grid(row=1, column=0, sticky='ew') + + self.frm_charname_orgalogs.grid(row=2, column=0, columnspan=2, sticky='ew') + self.frm_charname_orgalogs.columnconfigure(1, weight=1) + + lbl_charname_orgalogs.grid(row=0, column=0) + self.ent_charname_orgalogs.grid(row=0, column=1, sticky='ew') + + self.btn_organise = tk.Button(self.frm_organise_logs, text="Organise!", command=self.organise_logs) + self.btn_organise.grid(row=10, column=0, columnspan=2, sticky='ew') + + + + ### Setup tab notebook + self.ntb_file_selection.add(self.frm_single_file, text="Single file input/output") + self.ntb_file_selection.add(self.frm_multi_file, text="Multi file input/output") + self.ntb_file_selection.add(self.frm_organise_logs, text="Organise logs") + self.ntb_file_selection.grid(row=0, column=0, columnspan=2, sticky='ew', ipady='2.5') + def on_tab_change(event): + tab = event.widget.tab('current')['text'] + if tab == "Single file input/output": + self.btn_process.config(command=self.process_file) + self.frm_process_settings.grid(in_=self.frm_single_file) + elif tab == "Multi file input/output": + self.btn_process.config(command=self.process_files) + self.frm_process_settings.grid(in_=self.frm_multi_file) + self.ntb_file_selection.bind('<>', on_tab_change) + + + self.frm_process_settings = tk.Frame(self.window) + self.frm_process_settings.grid(row=5, column=0, columnspan=2, sticky='ew', in_=self.frm_single_file) + self.frm_process_settings.columnconfigure([0,1], weight=1) + + + sep_general_settings = ttk.Separator(self.frm_process_settings, orient='horizontal') + sep_general_settings.grid(row=5, column=0, columnspan=2, sticky='ew', pady='5') + + ### General settings + self.frm_general_settings = tk.Frame(self.frm_process_settings) + self.frm_general_settings.grid(row=6, column=0, columnspan=2, sticky='ew', pady='5') + self.frm_general_settings.columnconfigure([0,1,2], weight=1) + + self.btn_keep_color = tk.Button(self.frm_general_settings, text="Keep color", command=self.toggle_setting("keep_color"), bg="#ffcccb") + self.btn_keep_channel = tk.Button(self.frm_general_settings, text="Keep channel name", command=self.toggle_setting("keep_channel"), bg="#ffcccb") + self.btn_keep_lang_flag = tk.Button(self.frm_general_settings, text="Keep language flag", command=self.toggle_setting("keep_lang_flag"), bg="#ffcccb") + self.btn_keep_original_part = tk.Button(self.frm_general_settings, text="Keep original text", command=self.toggle_setting("keep_original_part"), bg="#ffcccb") + self.btn_keep_translated_part = tk.Button(self.frm_general_settings, text="Keep translated text", command=self.toggle_setting("keep_translated_part"), bg="#ffcccb") + self.btn_keep_timestamp = tk.Button(self.frm_general_settings, text="Keep timestamp", command=self.toggle_setting("keep_timestamp"), bg="#ffcccb") + self.btn_replace_charname = tk.Button(self.frm_general_settings, text="Replace charname", command=self.toggle_setting("replace_charname"), bg="#ffcccb") + + self.btn_keep_color.grid(row=0, column=0, sticky='ew') + self.btn_keep_channel.grid(row=0, column=1, sticky='ew') + self.btn_keep_lang_flag.grid(row=0, column=2, sticky='ew') + self.btn_keep_original_part.grid(row=1, column=0, sticky='ew') + self.btn_keep_translated_part.grid(row=1, column=1, sticky='ew') + self.btn_keep_timestamp.grid(row=1, column=2, sticky='ew') + self.btn_replace_charname.grid(row=2, column=0, sticky='ew') + + sep_channels = ttk.Separator(self.frm_process_settings, orient='horizontal') + sep_channels.grid(row=10, column=0, columnspan=2, sticky='ew') + + lbl_channel_select = tk.Label(self.frm_process_settings, text="Select channels to keep:") + lbl_channel_select.grid(row=11, column=0, sticky='w') + + self.btn_chan_toggle = [] + + self.frm_btn_channel = tk.Frame(self.frm_process_settings) + self.frm_btn_channel.grid(row=12, column=0, columnspan=2, sticky='ew') + self.frm_btn_channel.columnconfigure([0,1,2,3], weight=1) + self.frm_btn_channel.rowconfigure([0,1,2], weight=1) + for i,name in enumerate(channel_names): + self.btn_chan_toggle.append(tk.Button(self.frm_btn_channel, text=name, command=self.toggle_channel(i), bg="#ffcccb")) + self.btn_chan_toggle[i].grid(row=int(i/4), column=i%4, sticky='ew') + + self.btn_sys_toggle = [] + + self.frm_btn_sys = tk.Frame(self.frm_process_settings, bg="#808080", borderwidth=5) + self.frm_btn_sys.grid(row=13, column=0, columnspan=2, sticky='e') + self.frm_btn_sys.columnconfigure([0,1,2,3,4,5,6], weight=1) + self.frm_btn_sys.rowconfigure([0,1,2,3,4], weight=1) + for i,(name,tooltip) in enumerate(system_info_categories): + self.btn_sys_toggle.append(tk.Button(self.frm_btn_sys, text=name, command=self.toggle_system(i), bg="#ffcccb")) + self.btn_sys_toggle[i].grid(row=int(i/7), column=i%7, sticky='ew') + ttp_sys = CreateToolTip(self.btn_sys_toggle[i], tooltip) + + self.btn_process = tk.Button(self.frm_process_settings, text="Process!", command=self.process_file) + self.btn_process.grid(row=20, column=0, columnspan=2, sticky='ew') + + # Default selection + self.chan_toggle = [False] * len(channel_names) + self.sys_toggle = [False] * len(system_info_categories) + self.toggle_channel(0)() + self.toggle_channel(1)() + self.toggle_channel(12)() + self.toggle_channel(13)() + self.toggle_system(7)() + self.toggle_setting("keep_translated_part")() + + def toggle_setting(self, setting): + def tgl_pref(): + if getattr(self, setting): + getattr(self, f"btn_{setting}").config(relief="raised", bg="#ffcccb") + setattr(self, setting, False) + else: + getattr(self, f"btn_{setting}").config(relief="sunken", bg="#99e599") + setattr(self, setting, True) + return tgl_pref + + def get_input_filepath(self): + filepath = filedialog.askopenfilename( + filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")], + initialdir=os.path.dirname(self.ent_input.get()) + ) + if not filepath: + return + self.ent_input.delete(0, tk.END) + self.ent_input.insert(0, filepath) + filename = os.path.basename(filepath) + name_start = filename.find("log_") + name_end = filename.find("_", name_start+4) + if name_end == -1: + name_end = filename.find(".", name_start+4) + if name_start != -1: + self.ent_charname.delete(0, tk.END) + self.ent_charname.insert(0, os.path.basename(filepath)[name_start+4:name_end]) + + def get_output_filepath(self): + filepath = filedialog.asksaveasfilename( + filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")], + initialdir=os.path.dirname(self.ent_output.get()) + ) + if not filepath: + return + self.ent_output.delete(0, tk.END) + self.ent_output.insert(0, filepath) + + def get_input_filepaths(self): + filepaths = filedialog.askopenfilenames( + filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")], + initialdir=os.path.dirname(self.ent_input_multi.get().split(';')[0]) + ) + if not filepaths: + return + self.ent_input_multi.delete(0, tk.END) + self.ent_input_multi.insert(0, ';'.join(filepaths)) + + def get_output_directory(self): + directory = filedialog.askdirectory( + initialdir=self.ent_output_multi.get() + ) + if not directory: + return + self.ent_output_multi.delete(0, tk.END) + self.ent_output_multi.insert(0, directory) + + def get_input_dir_orgalogs(self): + directory = filedialog.askdirectory( + initialdir=self.ent_input_orgalogs.get() + ) + if not directory: + return + self.ent_input_orgalogs.delete(0, tk.END) + self.ent_input_orgalogs.insert(0, directory) + + def get_output_dir_orgalogs(self): + directory = filedialog.askdirectory( + initialdir=self.ent_output_orgalogs.get() + ) + if not directory: + return + self.ent_output_orgalogs.delete(0, tk.END) + self.ent_output_orgalogs.insert(0, directory) + + + def toggle_channel(self, index): + def tgl_chan(): + if self.chan_toggle[index]: + self.btn_chan_toggle[index].config(relief="raised", bg="#ffcccb") + self.chan_toggle[index] = False + if channel_names[index] == "SYSTEM": + self.frm_btn_sys.grid_remove() + else: + self.btn_chan_toggle[index].config(relief="sunken", bg="#99e599") + self.chan_toggle[index] = True + if channel_names[index] == "SYSTEM": + self.frm_btn_sys.grid() + return tgl_chan + + def toggle_system(self,index): + def tgl_sys(): + if self.sys_toggle[index]: + self.btn_sys_toggle[index].config(relief="raised", bg="#ffcccb") + self.sys_toggle[index] = False + else: + self.btn_sys_toggle[index].config(relief="sunken", bg="#99e599") + self.sys_toggle[index] = True + return tgl_sys + + def process_file(self): + if not self.check_path_exists("ent_input"): + return + chan_pattern = '|'.join(['\(' + name + '\)' for i,name in enumerate(channel_names[:-2]) if self.chan_toggle[i]]) + if self.chan_toggle[-2]: + chan_pattern += '|\(SAY/EMT\)' + if self.chan_toggle[-1]: + if self.sys_toggle[0]: + chan_pattern += '|\(SYSTEM\)' + for i,(name,tooltip) in enumerate(system_info_categories[1:]): + if self.sys_toggle[i+1]: + chan_pattern += '|\(SYSTEM/' + name + '\)' + chan_regex = re.compile(chan_pattern) + with open(self.ent_input.get(), 'r', errors='surrogateescape') as in_file, open(self.ent_output.get(), 'w', errors='surrogateescape') as out_file: + orig_lines = 0 + filtered_lines = 0 + self.btn_process["text"] = "Started Processing..." + for line in in_file: + orig_lines += 1 + if chan_regex.search(line) == None: + continue + if not self.keep_color: + line = self.color_regex.sub('',line) + if not self.keep_channel: + line = line[:20] + line[line.find(') * ')+1:] + if not self.keep_timestamp: + line = line[20:] + original_start = line.find('{:') + if original_start != -1 and not self.keep_lang_flag: + line = line[:original_start+1] + line[original_start+5:] + original_end = line.find('}@{') + if original_end != -1 and not self.keep_translated_part: + line = line[:original_end+4] + '\n' + if original_end != -1 and not self.keep_original_part: + original_text_start = original_start + (5 if self.keep_lang_flag else 1) + line = line[:original_text_start] + line[original_end:] + if original_end != -1: + original_end = line.find('}@{') + line = line[:original_start] + line[original_start+1:original_end] + line[original_end+4:] + + if self.replace_charname: + char_name_start = line.find(' * ') + 3 if not self.keep_color or line.find('}') == -1 else line.find('}') + 1 + if line[char_name_start] == '[' and line[char_name_start+2] == ']': + char_name_start += 3 + char_name_end = line.find(':', char_name_start) + char_name_end -= len(line[:char_name_end].rstrip().split(' ')[-1]) + 1 + (len(line[:char_name_end])-len(line[:char_name_end].rstrip())) + char_name = line[char_name_start:char_name_end] + + if char_name == "Vous" or char_name == "You" or char_name == "Du": + line = line[:char_name_start] + ' '.join([s.capitalize() for s in self.ent_charname.get().split(' ')]) + line[char_name_end:] + + line = line[:line.find(' * ')] + line[line.find(' * ')+3:] + # channel_name = line[21:line.find(')')] + out_file.write(line.lstrip()) + filtered_lines += 1 + self.btn_process["text"]="Processing done! (" + str(filtered_lines) + " lines kept out of " + str(orig_lines) + " original lines)" + + def process_files(self): + input_filepaths = self.ent_input_multi.get().split(';') + for filepath in input_filepaths: + filename = os.path.basename(filepath) + self.ent_input.delete(0, tk.END) + self.ent_input.insert(0, filepath) + self.ent_output.delete(0, tk.END) + self.ent_output.insert(0, os.path.join(self.ent_output_multi.get(), filename)) + if len(self.ent_charname_multi.get()) == 0: + name_start = filename.find("log_") + name_end = filename.find("_", name_start+4) + if name_end == -1: + name_end = filename.find(".", name_start+4) + if name_start != -1: + self.ent_charname.delete(0, tk.END) + self.ent_charname.insert(0, os.path.basename(filepath)[name_start+4:name_end]) + else: + self.ent_charname.delete(0, tk.END) + self.ent_charname.insert(0, self.ent_charname_multi.get()) + + self.process_file() + + + def organise_logs(self): + if not self.check_path_exists("ent_output_orgalogs") or not self.check_path_exists("ent_input_orgalogs"): + return + self.my_pathes = {} + for dirpath, _, filenames in os.walk(self.ent_input_orgalogs.get()): + for f in filenames: + with open(os.path.join(dirpath, f), 'r', errors='surrogateescape') as in_f: + last_year = -1 + last_month = -1 + last_day = -1 + out_f = None + if len(self.ent_charname_orgalogs.get()) == 0: + name_start = f.find("log_") + name_end = f.find("_", name_start+4) + if name_end == -1: + name_end = f.find(".", name_start+4) + if name_start != -1: + self.ent_charname_orgalogs.delete(0, tk.END) + self.ent_charname_orgalogs.insert(0, f[name_start+4:name_end]) + charname = self.ent_charname_orgalogs.get().lower() + manual_check_p = self.make_path_safe(os.path.join(self.ent_output_orgalogs.get(), f"log_{charname}_manual_check.log")) + manual_check_f = open(manual_check_p, 'a', errors='surrogateescape') + for line in in_f: + year_end = line.find('/') + unclassified = False + year = month = day = 0 + if year_end == -1 or year_end+3 >= len(line) or line[year_end+3] != '/': + if last_year != -1: + year, month, day = last_year, last_month, last_day + else: + unclassified = True + else: + try: + year = int(line[:year_end]) + month = int(line[year_end+1:year_end+3]) + day = int(line[year_end+4:year_end+6]) + except ValueError: + unclassified = True + if not unclassified and (year != last_year or month != last_month or day != last_day): + if out_f != None: + out_f.close() + out_p = self.make_path_safe(os.path.join(self.ent_output_orgalogs.get(), charname, f"{year:04d}", f"{month:02d}", f"log_{charname}_{year:04d}_{month:02d}_{day:02d}.log")) + out_f = open(out_p, 'a', errors='surrogateescape') + if unclassified: + manual_check_f.write(line) + else: + out_f.write(line) + last_year = year + last_month = month + last_day = day + if out_f != None: + out_f.close() + manual_check_f.close() + + def make_path_safe(self, path): + if path in self.my_pathes: + return self.my_pathes[path] + (dirpath, filename) = os.path.split(path) + (basefile, ext) = os.path.splitext(filename) + if ext == '': + os.makedirs(path, exist_ok=True) + self.my_pathes[path] = path + return path 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 + os.makedirs(dirpath, exist_ok=True) + counter = 1 + new_path = path + while os.path.exists(new_path): + new_path = os.path.join(dirpath, f"{basefile}_{counter}{ext}") + counter += 1 + self.my_pathes[path] = new_path + return new_path + + + def check_path_exists(self, attribute): + if not hasattr(self, attribute) or getattr(self, attribute) == None or not os.path.exists(getattr(self, attribute).get()): + tk.messagebox.showerror(title="Error in files selection", message=f"Error with input/output files. Make sur the input/output files or directories are set and exist") + return False + return True -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)" - -originalfolderlog = "./logsource" -finalfolder = "./final_logs" -charname = "test" -tmpfolder = "./tmpfolder" - -def order_logs(): - (dirpath, _, filenames) = os.walk(originalfolderlog).next() - for f in filenames: - with open(os.path.join(dirpath, f), 'r') as in_f: - + if __name__ == '__main__': - window = create_ui() + gui = GUI() - window.mainloop() + gui.window.mainloop()