diff --git a/main.py b/main.py new file mode 100644 index 0000000..db24cf0 --- /dev/null +++ b/main.py @@ -0,0 +1,22 @@ +from src import gui +from src import trader +from threading import Thread +from argparse import Namespace, ArgumentParser + +def setup_args() -> Namespace: + parser = ArgumentParser( + description='Poe Trader', epilog="And that's how you trade") + + parser.add_argument( + '-l', '--logfile', help='Path of the logfile that should be used', default=r'D:\Poe\logs\Client.txt') + + return parser.parse_args() + + +if __name__ == "__main__": + args = setup_args() + app = gui.Gui() + my_thread = Thread(target=trader.read_log, args=(args.logfile, app)) + my_thread.start() + # read_log(args.logfile) + app.mainloop() \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/trader.py b/src/data.py similarity index 54% rename from trader.py rename to src/data.py index 94196c7..9aa32c9 100644 --- a/trader.py +++ b/src/data.py @@ -1,17 +1,7 @@ -import argparse -import time -import datetime from enum import Enum import re -import logging -from gui import Gui +import datetime -log = logging.getLogger(__name__) -logging.basicConfig(level=logging.DEBUG) - - -re_log = re.compile( - '(?P\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d) (\d+) (\S+) \[(?P\S+) (\S+) (\d+)\] (?P[#@%$&]?)(?P<\S+>)? ?(?P[^:]+): (?P.*)') re_trade = re.compile( 'Hi, I would like to buy your (?P.+) listed for (?P\d+) (?P\S+) in (?P\S+) \(stash tab "(?P.+)"; position: left (?P\d+), top (?P\d+)\)') @@ -82,54 +72,3 @@ class Message(): row=int(res['row']), col=int(res['col']), league=res['league']) - - -def parse_string(text: str) -> Message: - result = re_log.search(text) - if not result: - log.debug(f'Result is none for text "{text}"') - return None - date = datetime.datetime.strptime( - result.group('date'), '%Y/%m/%d %H:%M:%S') - guild = result.group('guild') - if guild: - guild = guild.strip('<>') - return Message(result.group('message'), date, result.group('user'), channel_mapping[result.group('channel')], guild) - - -def setup_args() -> argparse.Namespace: - parser = argparse.ArgumentParser( - description='Poe Trader', epilog="And that's how you trade") - - parser.add_argument( - '-l', '--logfile', help='Path of the logfile that should be used', default=r'D:\Poe\logs\Client.txt') - - return parser.parse_args() - - -def read_log(logfile) -> None: - logfile = open(logfile, 'r', encoding='utf8') - loglines = follow(logfile) - for line in loglines: - message = parse_string(line) - log.debug(message) - if message and message.channel is Channel.WHISPER: - log.info('TRADE') - trade = message.parse_trade() - - -def follow(thefile: str): - thefile.seek(0, 2) - while True: - line = thefile.readline() - if not line: - time.sleep(0.1) - continue - yield line - - -if __name__ == "__main__": - args = setup_args() - read_log(args.logfile) - app = Gui() - app.mainloop() diff --git a/gui.py b/src/gui.py similarity index 81% rename from gui.py rename to src/gui.py index c359af9..31928ae 100644 --- a/gui.py +++ b/src/gui.py @@ -1,7 +1,7 @@ from tkinter import ttk from tkinter import Tk from tkinter import Button - +from .data import Trade class Gui(Tk): def __init__(self, parent=None) -> None: @@ -13,11 +13,11 @@ class Gui(Tk): self.attributes('-topmost', True) # always on top self.tab_control = ttk.Notebook(self) self.tab_control.pack(expand=1, fill='both') - self.add_tab(1) - self.add_tab(2) - self.add_tab(3) + self.add_tab(1, None) + self.add_tab(2, None) + self.add_tab(3, None) - def add_tab(self, number: int) -> None: + def add_tab(self, number: int, trade: Trade) -> None: tab = ttk.Frame(self.tab_control) Button(tab, text='Accept').pack() Button(tab, text='Decline').pack() diff --git a/src/trader.py b/src/trader.py new file mode 100644 index 0000000..6bd767a --- /dev/null +++ b/src/trader.py @@ -0,0 +1,48 @@ +import time +import datetime +import re +import logging +from .data import Message, Channel, channel_mapping +from . import gui + +log = logging.getLogger(__name__) +logging.basicConfig(level=logging.DEBUG) + + +re_log = re.compile( + '(?P\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d) (\d+) (\S+) \[(?P\S+) (\S+) (\d+)\] (?P[#@%$&]?)(?P<\S+>)? ?(?P[^:]+): (?P.*)') + + +def parse_log(text: str) -> Message: + result = re_log.search(text) + if not result: + log.debug(f'Result is none for text "{text}"') + return None + date = datetime.datetime.strptime( + result.group('date'), '%Y/%m/%d %H:%M:%S') + guild = result.group('guild') + if guild: + guild = guild.strip('<>') + return Message(result.group('message'), date, result.group('user'), channel_mapping[result.group('channel')], guild) + + +def read_log(logfile: str, app: gui.Gui) -> None: + logfile = open(logfile, 'r', encoding='utf8') + loglines = follow(logfile) + for line in loglines: + message = parse_log(line) + log.debug(message) + if message and message.channel is Channel.WHISPER: + log.info('TRADE') + trade = message.parse_trade() + app.add_tab(30, trade) + + +def follow(thefile: str): + thefile.seek(0, 2) + while True: + line = thefile.readline() + if not line: + time.sleep(0.1) + continue + yield line