Implement propagating account data to ads
This commit is contained in:
@@ -18,23 +18,61 @@ class Sinks(util.Base):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.account_info = {}
|
||||
|
||||
def __irc_started__(self):
|
||||
self.startup()
|
||||
|
||||
def startup(self):
|
||||
"""
|
||||
We NEED the other libraries, and we initialise fast, so don't make
|
||||
any race conditions by relying on something that might not be there.
|
||||
"""
|
||||
self.fidor = sinks.fidor.Fidor()
|
||||
self.nordigen = sinks.nordigen.Nordigen()
|
||||
self.truelayer = sinks.truelayer.TrueLayer(self)
|
||||
# setattr(self.truelayer, "sinks", self)
|
||||
|
||||
def got_transactions(self, bank, account_id, transactions):
|
||||
print("GOT transactions", bank, account_id, transactions)
|
||||
if not transactions:
|
||||
return False
|
||||
transaction_ids = [x["transaction_id"] for x in transactions]
|
||||
print("IDS", transaction_ids)
|
||||
new_key_name = f"new.transactions.{bank}.{account_id}"
|
||||
old_key_name = f"transactions.{bank}.{account_id}"
|
||||
r.sset(new_key_name, transaction_ids)
|
||||
# for transaction_id in transaction_ids:
|
||||
if not transaction_ids:
|
||||
return
|
||||
r.sadd(new_key_name, *transaction_ids)
|
||||
|
||||
difference = r.sdiff(new_key_name, old_key_name)
|
||||
print("difference", difference)
|
||||
difference = list(r.sdiff(new_key_name, old_key_name))
|
||||
|
||||
difference = util.convert(difference)
|
||||
|
||||
new_transactions = [x for x in transactions if x["transaction_id"] in difference]
|
||||
|
||||
# Rename the new key to the old key so we can run the diff again
|
||||
r.rename(new_key_name, old_key_name)
|
||||
for transaction in new_transactions:
|
||||
self.tx.transaction(transaction)
|
||||
|
||||
# self.transactions.transaction(transactions)
|
||||
def got_account_info(self, subclass, account_infos):
|
||||
"""
|
||||
Called when we get account information from an API provider.
|
||||
:param subclass: class name that called it, truelayer, fidor, etc
|
||||
:param account_infos: dict of dicts of account information
|
||||
:param account_infos: dict
|
||||
"""
|
||||
|
||||
for bank, accounts in account_infos.items():
|
||||
for account in list(accounts):
|
||||
if len(account["account_number"]) == 1:
|
||||
account_infos[bank].remove(account)
|
||||
currencies = [account["currency"] for bank, accounts in account_infos.items() for account in accounts]
|
||||
|
||||
self.account_info = account_infos
|
||||
self.currencies = currencies
|
||||
|
||||
# parsed_details =
|
||||
# {"EUR": {"IBAN": "xxx", "BIC": "xxx"},
|
||||
# "GBP": {"SORT": "04-04-04", "ACCOUNT": "1922-2993"}}
|
||||
# self.markets.distribute_account_details(currencies, account_infos)
|
||||
|
||||
@@ -23,6 +23,8 @@ class TrueLayer(util.Base):
|
||||
self.sinks = sinks
|
||||
self.tokens = {}
|
||||
self.banks = {}
|
||||
self.refresh_tokens = {}
|
||||
self.authed = False
|
||||
|
||||
# Get the banks from the config and cache them
|
||||
self.get_mapped_accounts()
|
||||
@@ -35,6 +37,15 @@ class TrueLayer(util.Base):
|
||||
# -> set self.tokens[bank] = access_token
|
||||
self.lc.start(int(settings.TrueLayer.TokenRefreshSec))
|
||||
|
||||
def __authed__(self):
|
||||
"""
|
||||
Called when we have received all the API tokens.
|
||||
"""
|
||||
# Get the account information and pass it to the main function
|
||||
self.log.info("All accounts authenticated: " + ", ".join(self.tokens.keys()))
|
||||
account_infos = self.get_all_account_info()
|
||||
self.sinks.got_account_info("truelayer", account_infos)
|
||||
|
||||
self.lc_tx = LoopingCall(self.transaction_loop)
|
||||
self.lc_tx.start(int(settings.TrueLayer.RefreshSec))
|
||||
|
||||
@@ -123,8 +134,12 @@ class TrueLayer(util.Base):
|
||||
refresh_tokens = loads(settings.TrueLayer.RefreshKeys)
|
||||
# Set the cached entry
|
||||
self.refresh_tokens = refresh_tokens
|
||||
|
||||
for bank in refresh_tokens:
|
||||
self.get_new_token(bank)
|
||||
rtrn = self.get_new_token(bank)
|
||||
if not rtrn:
|
||||
self.log.error(f"Error getting token for {bank}")
|
||||
return
|
||||
|
||||
def get_new_token(self, bank):
|
||||
"""
|
||||
@@ -133,6 +148,7 @@ class TrueLayer(util.Base):
|
||||
:type account:
|
||||
"""
|
||||
if bank not in self.refresh_tokens:
|
||||
self.log.error(f"Bank {bank} not in refresh tokens")
|
||||
return
|
||||
|
||||
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
||||
@@ -146,17 +162,22 @@ class TrueLayer(util.Base):
|
||||
try:
|
||||
parsed = r.json()
|
||||
except JSONDecodeError:
|
||||
self.log.error(f"Failed to decode JSON: {r.content}")
|
||||
return False
|
||||
if r.status_code == 200:
|
||||
if "access_token" in parsed.keys():
|
||||
self.tokens[bank] = parsed["access_token"]
|
||||
self.log.info(f"Refreshed access token for {bank}")
|
||||
# self.log.info(f"Refreshed access token for {bank}")
|
||||
if len(self.refresh_tokens.keys()) == len(self.tokens.keys()) and not self.authed:
|
||||
# We are now fully authenticated and ready to start loops!
|
||||
self.__authed__()
|
||||
self.authed = True
|
||||
return True
|
||||
else:
|
||||
self.log.error(f"Token refresh didn't contain access token: {parsed}", parsed=parsed)
|
||||
self.log.error(f"Token refresh didn't contain access token: {parsed}")
|
||||
return False
|
||||
else:
|
||||
self.log.error(f"Cannot refresh token: {parsed}", parsed=parsed)
|
||||
self.log.error(f"Cannot refresh token: {parsed}")
|
||||
return False
|
||||
|
||||
def get_accounts(self, bank):
|
||||
@@ -183,7 +204,7 @@ class TrueLayer(util.Base):
|
||||
try:
|
||||
parsed = r.json()
|
||||
except JSONDecodeError:
|
||||
self.log.error("Error parsing accounts response: {content}", content=r.content)
|
||||
self.log.error(f"Error parsing accounts response: {r.content}")
|
||||
return False
|
||||
|
||||
return parsed
|
||||
@@ -192,6 +213,17 @@ class TrueLayer(util.Base):
|
||||
existing_entry = loads(settings.TrueLayer.Maps)
|
||||
self.banks = existing_entry
|
||||
|
||||
def get_all_account_info(self):
|
||||
to_return = {}
|
||||
for bank in self.banks:
|
||||
for account_id in self.banks[bank]:
|
||||
account_data = self.get_account(bank, account_id)
|
||||
if bank in to_return:
|
||||
to_return[bank].append(account_data)
|
||||
else:
|
||||
to_return[bank] = [account_data]
|
||||
return to_return
|
||||
|
||||
def get_account(self, bank, account_id):
|
||||
account_data = self._get_account(bank, account_id)
|
||||
if "results" not in account_data:
|
||||
@@ -241,7 +273,9 @@ class TrueLayer(util.Base):
|
||||
try:
|
||||
parsed = r.json()
|
||||
except JSONDecodeError:
|
||||
self.log.error("Error parsing transactions response: {content}", content=r.content)
|
||||
self.log.error(f"Error parsing transactions response: {r.content}")
|
||||
return False
|
||||
if "results" in parsed:
|
||||
return parsed["results"]
|
||||
else:
|
||||
return False
|
||||
|
||||
return parsed["results"]
|
||||
|
||||
Reference in New Issue
Block a user