Implement sending reconciled balance via sms (free mobile)

This commit is contained in:
Gabriel Augendre 2021-12-04 16:42:59 +01:00
parent 4015018273
commit eef52773ab
7 changed files with 60 additions and 20 deletions

View file

@ -33,9 +33,9 @@ class BpvfProcessor(OfxBaseProcessor):
command_name = "bpvf" command_name = "bpvf"
def main(filename, keep, send): def main(filename, keep, send_method):
"""Import BPVF bank statement (OFX file).""" """Import BPVF bank statement (OFX file)."""
processor = BpvfProcessor(filename) processor = BpvfProcessor(filename)
if send: if send_method:
processor.send_reconciled_amount() processor.send_reconciled_amount(send_method)
processor.push_to_ynab(keep) processor.push_to_ynab(keep)

View file

@ -30,9 +30,9 @@ class CeProcessor(OfxBaseProcessor):
line_class = CeLine line_class = CeLine
def main(filename, keep, send): def main(filename, keep, send_method):
"""Import CE bank statement (OFX file).""" """Import CE bank statement (OFX file)."""
processor = CeProcessor(filename) processor = CeProcessor(filename)
if send: if send_method:
processor.send_reconciled_amount() processor.send_reconciled_amount(send_method)
processor.push_to_ynab(keep) processor.push_to_ynab(keep)

View file

@ -80,7 +80,7 @@ class LclProcessor(OfxBaseProcessor):
return ofx return ofx
def main(filename, keep, download, send): def main(filename, keep, download, send_method):
"""Import LCL bank statement (OFX file).""" """Import LCL bank statement (OFX file)."""
if download: if download:
if filename: if filename:
@ -91,6 +91,6 @@ def main(filename, keep, download, send):
) )
filename = LclDownloader().download() filename = LclDownloader().download()
processor = LclProcessor(filename) processor = LclProcessor(filename)
if send: if send_method:
processor.send_reconciled_amount() processor.send_reconciled_amount(send_method)
processor.push_to_ynab(keep) processor.push_to_ynab(keep)

View file

@ -33,10 +33,13 @@ class OfxBaseProcessor(BaseProcessor):
ofx = self._parse_file() ofx = self._parse_file()
return ofx.statements[0].transactions return ofx.statements[0].transactions
def send_reconciled_amount(self): def send_reconciled_amount(self, method):
amount = self._get_reconciled_amount() amount = self._get_reconciled_amount()
click.secho(f"Reconciled balance: {amount}. Sending...", fg="blue") click.secho(f"Reconciled balance: {amount}. Sending via {method}...", fg="blue")
self._send_mail(amount) if method == "email":
self._send_mail(amount)
elif method == "sms":
self._send_sms(amount)
def _get_reconciled_amount(self) -> Decimal: def _get_reconciled_amount(self) -> Decimal:
ofx = self._parse_file() ofx = self._parse_file()
@ -57,7 +60,7 @@ class OfxBaseProcessor(BaseProcessor):
if not config.email_setup: if not config.email_setup:
click.secho("Email is not properly setup", fg="yellow") click.secho("Email is not properly setup", fg="yellow")
return return
return requests.post( res = requests.post(
f"https://api.mailgun.net/v3/{config.mailgun_domain}/messages", f"https://api.mailgun.net/v3/{config.mailgun_domain}/messages",
auth=("api", config.mailgun_api_key), auth=("api", config.mailgun_api_key),
data={ data={
@ -67,3 +70,21 @@ class OfxBaseProcessor(BaseProcessor):
"text": f"Here's your reconciled balance: {amount}", "text": f"Here's your reconciled balance: {amount}",
}, },
) )
if res.status_code >= 400:
click.secho("Error while sending email", fg="yellow")
def _send_sms(self, amount: Decimal):
config = get_config(self.account_name)
if not config.sms_setup:
click.secho("SMS is not properly setup", fg="yellow")
return
res = requests.post(
f"https://smsapi.free-mobile.fr/sendmsg",
json={
"user": config.sms_user,
"pass": config.sms_key,
"msg": f"Reconciled balance: {amount}",
},
)
if res.status_code >= 400:
click.secho("Error while sending SMS", fg="yellow")

View file

@ -65,6 +65,8 @@ class Config:
mailgun_domain: Optional[str] = None mailgun_domain: Optional[str] = None
mailgun_from: Optional[str] = None mailgun_from: Optional[str] = None
email_recipient: Optional[str] = None email_recipient: Optional[str] = None
sms_user: Optional[str] = None
sms_key: Optional[str] = None
@property @property
def email_setup(self) -> bool: def email_setup(self) -> bool:
@ -78,6 +80,16 @@ class Config:
] ]
) )
@property
def sms_setup(self) -> bool:
"""Return true if all fields are setup for sms."""
return all(
[
self.sms_user,
self.sms_key,
]
)
def get_config(account: str) -> Config: def get_config(account: str) -> Config:
config = configparser.ConfigParser() config = configparser.ConfigParser()
@ -108,6 +120,8 @@ def get_config(account: str) -> Config:
mailgun_domain = section.get("mailgun_domain") mailgun_domain = section.get("mailgun_domain")
mailgun_from = section.get("mailgun_from") mailgun_from = section.get("mailgun_from")
email_recipient = section.get("email_recipient") email_recipient = section.get("email_recipient")
sms_user = section.get("sms_user")
sms_key = section.get("sms_key")
except KeyError as e: except KeyError as e:
return handle_config_file_error(config_file, e) return handle_config_file_error(config_file, e)
@ -121,6 +135,8 @@ def get_config(account: str) -> Config:
mailgun_domain, mailgun_domain,
mailgun_from, mailgun_from,
email_recipient, email_recipient,
sms_user,
sms_key,
) )

View file

@ -14,12 +14,15 @@ ARG_TO_OPTION = {
default=False, default=False,
show_default=True, show_default=True,
), ),
"send": click.option( "send_method": click.option(
"send", "send_method",
"--send/--no-send", "-s",
"--send-email/--no-send-email", "--send",
help="Send the reconciled amount via email.", help=(
default=False, "Send the reconciled amount via the chosen method. "
"Accepted methods: sms, email"
),
default="",
show_default=True, show_default=True,
), ),
"download": click.option( "download": click.option(

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "ofx-processor" name = "ofx-processor"
version = "3.3.0" version = "3.4.0"
description = "Personal ofx processor" description = "Personal ofx processor"
readme = "README.md" readme = "README.md"
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"