linter &c

This commit is contained in:
Keenan Tims 2025-04-24 01:05:49 -07:00
parent 0b13bb3692
commit f453222bf7
5 changed files with 71 additions and 24 deletions

25
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,25 @@
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.5 # Check for the latest version
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/asottile/reorder-python-imports
rev: v3.11.0 # Check for the latest version
hooks:
- id: reorder-python-imports
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0 # Check for the latest version
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: requirements-txt-fixer
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0 # Check for the latest version
hooks:
- id: flake8

View File

@ -1,7 +1,8 @@
from dataclasses import dataclass from dataclasses import dataclass
from uuid import UUID
from datetime import date from datetime import date
from decimal import Decimal from decimal import Decimal
from uuid import UUID
@dataclass @dataclass
class Transaction: class Transaction:
@ -10,4 +11,4 @@ class Transaction:
amount: Decimal amount: Decimal
payee: str # imported_payee in API payee: str # imported_payee in API
notes: str notes: str
imported_id: str imported_id: str

View File

@ -1,16 +1,18 @@
import re
from abc import ABC
from abc import abstractmethod
from datetime import datetime
from decimal import Decimal from decimal import Decimal
from email.message import EmailMessage from email.message import EmailMessage
from model import Transaction from email.message import Message
import re
from uuid import UUID from uuid import UUID
from datetime import datetime
from logging import debug from model import Transaction
from abc import ABC, abstractmethod
class TransactionParser(ABC): class TransactionParser(ABC):
@abstractmethod @abstractmethod
def match(self, msg: EmailMessage) -> bool: def match(self, msg: Message) -> bool:
pass pass
@abstractmethod @abstractmethod
@ -30,16 +32,19 @@ class RogersBankParser(TransactionParser):
def __init__(self, account_id: UUID): def __init__(self, account_id: UUID):
self.account_id = account_id self.account_id = account_id
def match(self, msg: EmailMessage) -> bool: def match(self, msg: Message) -> bool:
return ( return (
msg["From"] == "Rogers Bank <onlineservices@RogersBank.com>" msg["From"] == "Rogers Bank <onlineservices@RogersBank.com>"
and msg["Subject"] == "Purchase amount alert" and msg["Subject"] == "Purchase amount alert"
) )
def extract(self, msg: EmailMessage) -> Transaction: def extract(self, msg: EmailMessage) -> Transaction:
matches = RogersBankParser.EXTRACT_RE.search(msg.get_body().as_string()) body = msg.get_body()
if body is None:
raise TransactionParsingFailed("No body of message found")
matches = RogersBankParser.EXTRACT_RE.search(body.as_string())
if matches is None: if matches is None:
return TransactionParsingFailed("No matches for extraction RE") raise TransactionParsingFailed("No matches for extraction RE")
amount = Decimal(matches[1]) amount = Decimal(matches[1])
date_raw = matches[2] date_raw = matches[2]
payee = matches[3] payee = matches[3]

2
setup.cfg Normal file
View File

@ -0,0 +1,2 @@
[flake8]
max-line-length = 100

View File

@ -1,17 +1,22 @@
#!/usr/bin/env python #!/usr/bin/env python
import asyncio
from email.message import EmailMessage
import logging
import asyncio, ssl, email
from os import getenv
from imaplib import IMAP4
from logging import info, debug, error, warning
from pprint import pprint
from model import Transaction
from config import PARSERS
from parsers import TransactionParsingFailed
import email.policy import email.policy
import logging
import os import os
import ssl
from email.message import EmailMessage
from imaplib import IMAP4
from logging import debug
from logging import error
from logging import info
from logging import warning
from os import getenv
from pprint import pprint
from typing import cast
from config import PARSERS
from model import Transaction
from parsers import TransactionParsingFailed
IMAP_SERVER = getenv("IMAP_SERVER") IMAP_SERVER = getenv("IMAP_SERVER")
IMAP_PORT = int(getenv("IMAP_PORT", 143)) IMAP_PORT = int(getenv("IMAP_PORT", 143))
@ -32,7 +37,14 @@ async def ticker(interval: float):
async def submit_transaction(t: Transaction): async def submit_transaction(t: Transaction):
cmd=ACTUAL_PATH + f' -a "{t.account}"' + f' -p "{t.payee}"' + f' -m "{t.amount}"' + f' -d "{t.date}"' f' -n "{t.notes}"' cmd = (
ACTUAL_PATH
+ f' -a "{t.account}"'
+ f' -p "{t.payee}"'
+ f' -m "{t.amount}"'
+ f' -d "{t.date}"'
f' -n "{t.notes}"'
)
debug("Actual command: %s", cmd) debug("Actual command: %s", cmd)
proc = await asyncio.create_subprocess_shell( proc = await asyncio.create_subprocess_shell(
cmd=cmd, cmd=cmd,
@ -47,7 +59,9 @@ async def submit_transaction(t: Transaction):
async def process_message(msg_b: bytes): async def process_message(msg_b: bytes):
debug("parsing message") debug("parsing message")
msg = email.message_from_bytes(msg_b, policy=email.policy.default) msg = cast(
EmailMessage, email.message_from_bytes(msg_b, policy=email.policy.default)
)
pprint(msg) pprint(msg)
info( info(
"Found message from %s to %s subject %s", "Found message from %s to %s subject %s",