X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=fulbank%2Ffsb.py;h=723f61be2e25b79396c8322b0d01c49d95286a36;hb=c526374d7861581204f40aa046002e5f3942d405;hp=ef413ae91232bd29d69f82b200b370ceb98140ab;hpb=61fd054fe24ac51425b1cdf03f90ed2cbacc63bd;p=fulbank.git diff --git a/fulbank/fsb.py b/fulbank/fsb.py index ef413ae..723f61b 100644 --- a/fulbank/fsb.py +++ b/fulbank/fsb.py @@ -1,6 +1,7 @@ -import json, http.cookiejar, binascii, time, pickle +import json, http.cookiejar, binascii, time, datetime, pickle, hashlib from urllib import request, parse from bs4 import BeautifulSoup as soup +from . import currency, auth soupify = lambda cont: soup(cont, "html.parser") apibase = "https://online.swedbank.se/TDE_DAP_Portal_REST_WEB/api/" @@ -52,13 +53,28 @@ class transaction(object): self.account = account self._data = data + _datefmt = "%Y-%m-%d" + + @property + def value(self): return currency.currency.get(resolve(self._data, ("currency",))).parse(resolve(self._data, ("amount",))) @property - def amount(self): return float(resolve(self._data, ("amount",))) + def message(self): return resolve(self._data, ("description",)) + @property + def date(self): + p = time.strptime(resolve(self._data, ("accountingDate",)), self._datefmt) + return datetime.date(p.tm_year, p.tm_mon, p.tm_mday) + @property - def message(self): return resolve(self._data, ("details", "message")) + def hash(self): + dig = hashlib.sha256() + dig.update(str(self.date.toordinal()).encode("ascii") + b"\0") + dig.update(self.message.encode("utf-8") + b"\0") + dig.update(str(self.value.amount).encode("ascii") + b"\0") + dig.update(self.value.currency.symbol.encode("ascii") + b"\0") + return dig.hexdigest() def __repr__(self): - return "#" % (self.amount, self.message) + return "#" % (self.value, self.message) class account(object): def __init__(self, sess, id, idata): @@ -80,13 +96,21 @@ class account(object): @property def fullnumber(self): return resolve(self.data, ("fullyFormattedNumber",)) @property + def balance(self): return currency.currency.get(resolve(self.data, ("balance", "currencyCode"))).parse(resolve(self.data, ("balance", "amount"))) + @property def name(self): return resolve(self._idata, ("name",)) def transactions(self): pagesz = 50 - data = self.sess._jreq("v5/engagement/transactions/" + self.id, transactionsPerPage=pagesz, page=1) - for tx in resolve(data, ("transactions",)): - yield transaction(self, tx) + page = 1 + while True: + data = self.sess._jreq("v5/engagement/transactions/" + self.id, transactionsPerPage=pagesz, page=page) + txlist = resolve(data, ("transactions",)) + if len(txlist) < 1: + break + for tx in txlist: + yield transaction(self, tx) + page += 1 def __repr__(self): return "#" % (self.fullnumber, self.name) @@ -144,7 +168,9 @@ class session(object): rolesw = linkurl(resolve(prof["banks"][0], ("privateProfile", "links", "next", "uri"))) self._jreq(rolesw, method="POST") - def auth_bankid(self, user): + def auth_bankid(self, user, conv=None): + if conv is None: + conv = auth.default() data = self._jreq("v5/identification/bankid/mobile", data = { "userId": user, "useEasyLogin": False, @@ -152,13 +178,15 @@ class session(object): if data.get("status") != "USER_SIGN": raise fmterror("unexpected bankid status: " + str(data.get("status"))) vfy = linkurl(resolve(data, ("links", "next", "uri"))) + fst = None while True: time.sleep(3) vdat = self._jreq(vfy) st = vdat.get("status") - if st == "USER_SIGN": - continue - elif st == "CLIENT_NOT_STARTED": + if st in {"USER_SIGN", "CLIENT_NOT_STARTED"}: + if st != fst: + conv.message("Status: %s" % (st,), auth.conv.msg_info) + fst = st continue elif st == "COMPLETE": self._postlogin() @@ -214,4 +242,4 @@ class session(object): @classmethod def load(cls, filename): with open(filename, "rb") as fp: - return picke.load(fp) + return pickle.load(fp)