initial commit

Signed-off-by: Keenan Tims <ktims@gotroot.ca>
This commit is contained in:
2025-04-24 00:28:12 -07:00
commit 0b13bb3692
6 changed files with 1053 additions and 0 deletions

54
parsers.py Normal file
View File

@@ -0,0 +1,54 @@
from decimal import Decimal
from email.message import EmailMessage
from model import Transaction
import re
from uuid import UUID
from datetime import datetime
from logging import debug
from abc import ABC, abstractmethod
class TransactionParser(ABC):
@abstractmethod
def match(self, msg: EmailMessage) -> bool:
pass
@abstractmethod
def extract(self, msg: EmailMessage) -> Transaction:
pass
class TransactionParsingFailed(Exception):
pass
class RogersBankParser(TransactionParser):
EXTRACT_RE = re.compile(
r"Attempt of \$(\d+\.\d{2}) was made on ([A-z]{3} \d{1,2}, \d{4})[^<]*at ([^<]+) in"
)
def __init__(self, account_id: UUID):
self.account_id = account_id
def match(self, msg: EmailMessage) -> bool:
return (
msg["From"] == "Rogers Bank <onlineservices@RogersBank.com>"
and msg["Subject"] == "Purchase amount alert"
)
def extract(self, msg: EmailMessage) -> Transaction:
matches = RogersBankParser.EXTRACT_RE.search(msg.get_body().as_string())
if matches is None:
return TransactionParsingFailed("No matches for extraction RE")
amount = Decimal(matches[1])
date_raw = matches[2]
payee = matches[3]
date = datetime.strptime(date_raw, "%b %d, %Y").date()
return Transaction(
account=self.account_id,
date=date,
amount=amount,
payee=payee,
notes="via email",
imported_id=msg["Message-ID"],
)