Skip to content

Commit cca60a9

Browse files
henrykraphaelm
authored andcommitted
Add full FinTS parser. Significantly changes the internal API, as segments are now lists of lists.
Fully supports all escaping and binary content. Decodes 'normal' data from ISO-8859-1 to Python strings, leaves binary data as binary. Still broken: get_holdings()/HIWPD
1 parent a598030 commit cca60a9

3 files changed

Lines changed: 194 additions & 93 deletions

File tree

fints/client.py

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from .segments.saldo import HKSAL
1818
from .segments.statement import HKKAZ
1919
from .segments.transfer import HKCCS, HKCCM
20-
from .utils import mt940_to_array, MT535_Miniparser, split_for_data_groups, split_for_data_elements, Password
20+
from .utils import mt940_to_array, MT535_Miniparser, Password
2121

2222
logger = logging.getLogger(__name__)
2323

@@ -56,11 +56,9 @@ def _get_msg():
5656
logger.debug('Got HKSPA response: {}'.format(resp))
5757
dialog.end()
5858

59-
accounts = resp._find_segment('HISPA')
60-
accountlist = accounts.split('+')[1:]
59+
seg = resp._find_segment('HISPA')
6160
self.accounts = []
62-
for acc in accountlist:
63-
arr = acc.split(':')
61+
for arr in seg[1:]:
6462
self.accounts.append(SEPAAccount(
6563
iban=arr[1], bic=arr[2], accountnumber=arr[3], subaccount=arr[4], blz=arr[6]
6664
))
@@ -111,14 +109,11 @@ def _get_msg():
111109

112110
logger.info('Fetching done.')
113111

114-
re_data = re.compile(r'[^@]*@([0-9]+)@(.+)', flags=re.MULTILINE | re.DOTALL)
115112
statement = []
116113
for resp in responses:
117114
seg = resp._find_segment('HIKAZ')
118-
if seg:
119-
m = re_data.match(seg)
120-
if m:
121-
statement += mt940_to_array(m.group(2))
115+
## FIXME What is the encoding of MT940 messages?
116+
statement += mt940_to_array(seg[1].decode('iso-8859-1'))
122117

123118
logger.debug('Statement: {}'.format(statement))
124119

@@ -130,11 +125,11 @@ def _create_statement_message(self, dialog: FinTSDialog, account: SEPAAccount, s
130125

131126
if hversion in (4, 5, 6):
132127
acc = ':'.join([
133-
account.accountnumber, account.subaccount, str(280), account.blz
128+
account.accountnumber, account.subaccount or '', str(280), account.blz
134129
])
135130
elif hversion == 7:
136131
acc = ':'.join([
137-
account.iban, account.bic, account.accountnumber, account.subaccount, str(280), account.blz
132+
account.iban, account.bic, account.accountnumber, account.subaccount or '', str(280), account.blz
138133
])
139134
else:
140135
raise ValueError('Unsupported HKKAZ version {}'.format(hversion))
@@ -177,7 +172,7 @@ def _get_msg():
177172

178173
# find segment and split up to balance part
179174
seg = resp._find_segment('HISAL')
180-
arr = split_for_data_elements(split_for_data_groups(seg)[4])
175+
arr = seg[4]
181176

182177
# get balance date
183178
date = datetime.datetime.strptime(arr[3], "%Y%m%d").date()
@@ -190,11 +185,11 @@ def _create_balance_message(self, dialog: FinTSDialog, account: SEPAAccount):
190185

191186
if hversion in (1, 2, 3, 4, 5, 6):
192187
acc = ':'.join([
193-
account.accountnumber, account.subaccount, str(280), account.blz
188+
account.accountnumber, account.subaccount or '', str(280), account.blz
194189
])
195190
elif hversion == 7:
196191
acc = ':'.join([
197-
account.iban, account.bic, account.accountnumber, account.subaccount, str(280), account.blz
192+
account.iban, account.bic, account.accountnumber, account.subaccount or '', str(280), account.blz
198193
])
199194
else:
200195
raise ValueError('Unsupported HKSAL version {}'.format(hversion))
@@ -232,6 +227,8 @@ def _get_msg():
232227
# end dialog
233228
dialog.end()
234229

230+
231+
## FIXME BROKEN
235232
# find segment and split up to balance part
236233
seg = resp._find_segment('HIWPD')
237234
if seg:
@@ -249,11 +246,11 @@ def _create_get_holdings_message(self, dialog: FinTSDialog, account: SEPAAccount
249246

250247
if hversion in (1, 2, 3, 4, 5, 6):
251248
acc = ':'.join([
252-
account.accountnumber, account.subaccount, str(280), account.blz
249+
account.accountnumber, account.subaccount or '', str(280), account.blz
253250
])
254251
elif hversion == 7:
255252
acc = ':'.join([
256-
account.iban, account.bic, account.accountnumber, account.subaccount, str(280), account.blz
253+
account.iban, account.bic, account.accountnumber, account.subaccount or '', str(280), account.blz
257254
])
258255
else:
259256
raise ValueError('Unsupported HKSAL version {}'.format(hversion))
@@ -428,20 +425,18 @@ def start_sepa_debit(self, account: SEPAAccount, pain_message: str, tan_method,
428425

429426
def _tan_requiring_response(self, dialog, resp):
430427
seg = resp._find_segment('HITAN')
431-
s = split_for_data_groups(seg)
432-
spl = split_for_data_elements(s[0])
433-
if spl[2] == '3':
428+
if seg[0][2] == '3':
434429
model = TANChallenge3
435-
elif spl[2] == '4':
430+
elif seg[0][2] == '4':
436431
model = TANChallenge4
437-
elif spl[2] == '5':
432+
elif seg[0][2] == '5':
438433
model = TANChallenge5
439-
elif spl[2] == '6':
434+
elif seg[0][2] == '6':
440435
model = TANChallenge6
441436
else:
442437
raise NotImplementedError(
443438
"HITAN segment version {} is currently not implemented".format(
444-
spl[2]
439+
seg[0][2]
445440
)
446441
)
447442
return model(dialog, *s[1:1 + len(model.args)])
@@ -481,9 +476,8 @@ def get_tan_description(self):
481476
dialog.end()
482477

483478
seg = resp._find_segment('HITAB')
484-
deg = split_for_data_groups(seg)
485479

486-
return deg[2]
480+
return seg[2]
487481

488482

489483
class FinTS3PinTanClient(FinTS3Client):

fints/connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ def send(self, msg: FinTSMessage):
1919
)
2020
if r.status_code < 200 or r.status_code > 299:
2121
raise FinTSConnectionError('Bad status code {}'.format(r.status_code))
22-
return base64.b64decode(r.content.decode('iso-8859-1')).decode('iso-8859-1')
22+
return base64.b64decode(r.content.decode('iso-8859-1'))

0 commit comments

Comments
 (0)