Coverage for jbank/management/commands/wsedi_download.py : 0%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#pylint: disable=logging-format-interpolation,too-many-locals,too-many-branches
2import base64
3import logging
4import os
5import pytz
6from django.core.management.base import CommandParser
7from django.utils.timezone import now
8from jutil.xml import xml_to_dict
9from jbank.helpers import process_pain002_file_content, parse_start_and_end_date
10from jbank.models import WsEdiConnection
11from jbank.wsedi import wsedi_get, wsedi_execute
12from jutil.command import SafeCommand
15logger = logging.getLogger(__name__)
18class Command(SafeCommand):
19 help = """
20 Download Finnish bank files
21 """
23 def add_arguments(self, parser: CommandParser):
24 parser.add_argument('path', type=str)
25 parser.add_argument('--verbose', action='store_true')
26 parser.add_argument('--overwrite', action='store_true')
27 parser.add_argument('--file-type', type=str, help='E.g. TO, SVM, XP, NDCORPAYL, pain.002.001.03')
28 parser.add_argument('--status', type=str, default='', help='E.g. DLD, NEW')
29 parser.add_argument('--file-reference', type=str, help='Download single file based on file reference')
30 parser.add_argument('--list-only', action='store_true')
31 parser.add_argument('--process-pain002', action='store_true')
32 parser.add_argument('--start-date', type=str)
33 parser.add_argument('--end-date', type=str)
34 parser.add_argument('--ws', type=int)
36 def do(self, *args, **options): # pylint: disable=too-many-statements
37 ws = WsEdiConnection.objects.get(id=options['ws']) if options['ws'] else None
38 assert ws is None or isinstance(ws, WsEdiConnection)
39 if ws and not ws.enabled:
40 logger.info('WS connection %s not enabled, exiting', ws)
41 return
43 start_date, end_date = parse_start_and_end_date(pytz.timezone('Europe/Helsinki'), **options)
44 path = os.path.abspath(options['path'])
45 command = 'DownloadFileList'
46 time_now = now()
47 file_reference = options['file_reference']
48 if file_reference:
49 command = 'DownloadFile'
50 status = options['status']
51 file_type = options['file_type']
52 if command == 'DownloadFileList' and not file_type:
53 print('--file-type required (e.g. TO, SVM, XP, NDCORPAYL, pain.002.001.03)')
54 return
55 if ws:
56 content = wsedi_execute(ws, command=command, file_type=file_type, status=status, start_date=start_date, end_date=end_date,
57 file_reference=file_reference, verbose=options['verbose'])
58 data = xml_to_dict(content, array_tags=['FileDescriptor'])
59 else:
60 res = wsedi_get(command=command, file_type=file_type, status=status, file_reference=file_reference, verbose=options['verbose'])
61 data = res.json()
62 # "FileDescriptors": {
63 # "FileDescriptor": [
64 # {
65 # "FileReference": "535283541",
66 # "TargetId": "NONE",
67 # "UserFilename": "STOL001.FMV80KT2.WEBSER.PS",
68 # "ParentFileReference": "1218",
69 # "FileType": "TO",
70 # "FileTimestamp": "2017-12-18T20:33:09.362+02:00",
71 # "Status": "DLD",
72 # "LastDownloadTimestamp": "2017-12-19T12:36:34.490+02:00",
73 # "ForwardedTimestamp": "2017-12-18T20:33:09.362+02:00",
74 # "Deletable": "false",
75 # "CustomerNumber": "06720106",
76 # "Modifier": "06720106",
77 # "ModifiedTimestamp": "2017-12-19T12:36:34.490+02:00",
78 # "SourceId": "A",
79 # "Environment": "PRODUCTION"
80 # },
81 # ...
83 if command == 'DownloadFileList':
84 if 'FileDescriptors' in data and data['FileDescriptors'] is not None and 'FileDescriptor' in data['FileDescriptors']:
85 for fd in data['FileDescriptors']['FileDescriptor']:
86 file_reference = fd['FileReference']
87 file_type = fd['FileType']
88 file_basename = file_reference + '.' + file_type
89 file_path = os.path.join(path, file_basename)
90 if options['list_only']:
91 print('{file_reference} ({file_type}/{status}): {user_filename} ({timestamp})'.format(
92 file_reference=file_reference, file_type=file_type, status=fd.get('Status'),
93 user_filename=fd.get('UserFilename'), timestamp=fd.get('FileTimestamp')))
94 continue
95 if options['overwrite'] or not os.path.isfile(file_path):
96 command = 'DownloadFile'
97 if ws:
98 content = wsedi_execute(ws, command=command, file_type=file_type, status='', file_reference=file_reference,
99 verbose=options['verbose'])
100 file_data = xml_to_dict(content)
101 else:
102 res = wsedi_get(command=command, file_type=file_type, status='', file_reference=file_reference, verbose=options['verbose'])
103 file_data = res.json()
104 if 'Content' not in file_data:
105 logger.error('WS-EDI {} HTTP {} but Content block missing: {}'.format(command, res.status_code, file_data))
106 raise Exception("WS-EDI {} HTTP {} but Content block missing".format(command, res.status_code))
107 bcontent = base64.b64decode(file_data['Content'])
108 with open(file_path, 'wb') as fp:
109 fp.write(bcontent)
110 logger.info('Wrote file {}'.format(file_path))
112 # process selected files immediately
113 if options['process_pain002'] and file_type in ['XP', 'pain.002.001.03', 'NDCORPAYL']:
114 process_pain002_file_content(bcontent, file_path, created=time_now)
115 else:
116 print('Skipping old file {}'.format(file_path))
117 else:
118 print('Empty file list downloaded')
119 elif command == 'DownloadFile':
120 bcontent = base64.b64decode(data['Content'])
121 file_path = os.path.join(path, file_reference)
122 if options['overwrite'] or not os.path.isfile(file_path):
123 with open(file_path, 'wb') as fp:
124 fp.write(bcontent)
125 logger.info('Wrote file {}'.format(file_path))
126 else:
127 print('Skipping old file {}'.format(file_path))