161 lines
5.4 KiB
Python
161 lines
5.4 KiB
Python
from enum import Enum
|
|
from typing import Union
|
|
import re
|
|
import datetime
|
|
import logging
|
|
|
|
re_trade = re.compile(
|
|
r'Hi, I would like to buy your (?P<item>.+) listed for (?P<amount>\d+) (?P<currency>\S+) in (?P<league>\S+) '
|
|
r'\(stash tab "(?P<tab>.+)"; position: left (?P<col>\d+), top (?P<row>\d+)\)'
|
|
)
|
|
re_log = re.compile(
|
|
r'(?P<date>\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d) (\d+) (\S+) \[(?P<level>\S+) (\S+) (\d+)\] '
|
|
r'(?P<channel>[#@%$&]?)(?P<ToFrom>To|From)?\s?(?P<guild><\S+>)? ?(?P<user>[^:]+): (?P<message>.*)'
|
|
)
|
|
re_clipboard = None
|
|
re_clipboard_prefix = None
|
|
|
|
log = logging.getLogger(__name__)
|
|
logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s:: %(message)s')
|
|
|
|
|
|
def compile_regex(conf: dict):
|
|
global re_trade, re_log, re_clipboard, re_clipboard_prefix
|
|
if 'General' in conf:
|
|
if 're_log' in conf['Parser']:
|
|
re_log = re.compile(conf['Parser']['re_log'])
|
|
if 're_trade' in conf['Parser']:
|
|
re_trade = re.compile(conf['Parser']['re_trade'])
|
|
if 're_clipboard_prefix' in conf['Parser']:
|
|
re_clipboard = re.compile(conf['Parser']['re_clipboard_prefix'] + conf['Parser']['re_trade'])
|
|
re_clipboard_prefix = re.compile(conf['Parser']['re_clipboard_prefix'] + '.*')
|
|
|
|
|
|
class Channel(Enum):
|
|
WHISPER = 0
|
|
GLOBAL = 1
|
|
PARTY = 2
|
|
LOCAL = 3
|
|
TRADE = 4
|
|
GUILD = 5
|
|
|
|
|
|
channel_mapping = {'#': Channel.GLOBAL,
|
|
'@': Channel.WHISPER,
|
|
'%': Channel.PARTY,
|
|
'': Channel.LOCAL,
|
|
'$': Channel.TRADE,
|
|
'&': Channel.GUILD}
|
|
|
|
|
|
class Trade():
|
|
def __init__(self,
|
|
nrItems: int,
|
|
item: str,
|
|
amount: float,
|
|
currency: str,
|
|
tab: str,
|
|
row: str,
|
|
col: str,
|
|
league: str) -> None:
|
|
self.nrItems = int(nrItems) if nrItems else None
|
|
self.item = item
|
|
self.amount = amount
|
|
self.currency = currency
|
|
self.tab = tab
|
|
self.row = int(row) if row else None
|
|
self.col = int(col) if col else None
|
|
self.league = league
|
|
|
|
@classmethod
|
|
def by_regex_result(cls, res):
|
|
return cls(nrItems=res['nrItems'],
|
|
item=res['item'],
|
|
amount=float(res['amount']),
|
|
currency=res['currency'],
|
|
tab=res['tab'],
|
|
row=res['row'],
|
|
col=res['col'],
|
|
league=res['league'])
|
|
|
|
def __str__(self) -> str:
|
|
return f'Trade: {self.nrItems} {self.item} for {self.amount} {self.currency} in {self.tab} ({self.row}/{self.col}) in {self.league} league'
|
|
|
|
def __hash__(self) -> int:
|
|
return hash((self.nrItems, self.item, self.amount, self.currency, self.tab, self.row, self.col, self.league))
|
|
|
|
def __eq__(self, __o: object) -> bool:
|
|
return (isinstance(__o, self.__class__)
|
|
and self.nrItems == __o.nrItems
|
|
and self.item == __o.item
|
|
and self.amount == __o.amount
|
|
and self.currency == __o.currency
|
|
and self.tab == __o.tab
|
|
and self.row == __o.row
|
|
and self.col == __o.col
|
|
and self.league == __o.league)
|
|
|
|
|
|
class Message():
|
|
def __init__(self,
|
|
message: str,
|
|
date: datetime.datetime,
|
|
user: str,
|
|
channel: Channel,
|
|
guild: Union[str, None] = None,
|
|
to_from: Union[str, None] = None) -> None:
|
|
self.message = message
|
|
self.date = date
|
|
self.channel = channel
|
|
self.user = user
|
|
self.guild = guild
|
|
self.to_from = to_from
|
|
self.trade: Union[Trade, None] = None
|
|
if self.channel is Channel.WHISPER:
|
|
self.parse_trade()
|
|
|
|
@classmethod
|
|
def from_text(cls, text: str):
|
|
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 cls(result.group('message'),
|
|
date,
|
|
result.group('user'),
|
|
channel_mapping[result.group('channel')],
|
|
guild,
|
|
result.group('ToFrom'))
|
|
|
|
def __str__(self) -> str:
|
|
text = f'Message: {self.date} - {self.channel.name}: '
|
|
if self.to_from:
|
|
text = text + f'{self.to_from} '
|
|
if self.guild:
|
|
text = text + f'<{self.guild}> '
|
|
text = text + f'{self.user}: {self.message}'
|
|
return text
|
|
|
|
def parse_trade(self) -> None:
|
|
res = re_trade.search(self.message)
|
|
if res:
|
|
self.trade = Trade.by_regex_result(res)
|
|
|
|
def unique_trade(self) -> int:
|
|
assert self.trade
|
|
return hash((self.user, self.trade.__hash__()))
|
|
|
|
def unique_user_item(self) -> int:
|
|
assert self.trade
|
|
if self.to_from == 'From':
|
|
# Item in my stash.
|
|
return hash((self.trade.item, self.trade.tab, self.trade.row, self.trade.col, self.trade.league))
|
|
else:
|
|
# Item in a stash from another char
|
|
return hash((self.trade.item, self.trade.league))
|