From 42931b44d94961ea6af3ed14395ce50f76c5a476 Mon Sep 17 00:00:00 2001 From: Graham Blair Date: Wed, 3 Jan 2024 12:07:06 -0800 Subject: [PATCH] Eliminate potential infinite loop --- db.py | 8 ++++---- monarch_money_helper.py | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/db.py b/db.py index 3dcaf16..7f72184 100644 --- a/db.py +++ b/db.py @@ -101,13 +101,13 @@ def remove_recurring_transaction(self, id): session.commit() logger.info("Removed recurring transaction") - def get_past_due_recurring_transactions(self): - def is_next_recurrence_before_now(txn): + def get_past_due_recurring_transactions(self, exclude_ids=set()): + def txn_filter(txn): rules = rrule.rrulestr(rrule_for_txn(txn)) - return rules.after(txn.previous_occurrence) < datetime.now() + return rules.after(txn.previous_occurrence) < datetime.now() and txn.id not in exclude_ids self.clean_up_expired_recurring_transactions() - return list(filter(is_next_recurrence_before_now, self.get_all_recurring_transactions())) + return list(filter(txn_filter, self.get_all_recurring_transactions())) def clean_up_expired_recurring_transactions(self): stmt = select(RecurringTransaction) diff --git a/monarch_money_helper.py b/monarch_money_helper.py index c66f76b..4857dc0 100644 --- a/monarch_money_helper.py +++ b/monarch_money_helper.py @@ -149,6 +149,7 @@ def process_recurring_transactions(self): txns = self.db.get_past_due_recurring_transactions() logger.info("%s recurring transactions to process in first iteration" % len(txns)) + skipped_ids = set() while txns: for txn in txns: logger.info("Creating transaction for \"%s\"" % txn) @@ -157,5 +158,8 @@ def process_recurring_transactions(self): if self.add_transaction(txn.description, txn.amount, txn.category, next_occurrence, "RECUR:%s:%s" % (txn.dedupe_string, next_occurrence.isoformat()), notes=txn.notes): # only run the completion logic if the transaction now exists self.db.process_recurring_transaction_completion(txn.id) - txns = self.db.get_past_due_recurring_transactions() + else: + skipped_ids.add(txn.id) + + txns = self.db.get_past_due_recurring_transactions(exclude_ids=skipped_ids) logger.info("%s recurring transactions to process in next iteration" % len(txns))