ryzom_log_cleaner/main.py

258 lines
8.5 KiB
Python
Raw Normal View History

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()