DataInputOutput.fn_file_operation_logger()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nop 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
"""
2
Data Input Output class
3
"""
4
# package to add support for multi-language (i18n)
5
import gettext
6
# package to handle files/folders and related metadata/operations
7
import os
8
9
# local packages
10
from .DataDiskRead import DataDiskRead
11
from .DataDiskWrite import DataDiskWrite
12
13
14
class DataInputOutput(DataDiskRead, DataDiskWrite):
15
    locale = None
16
17
    def __init__(self, in_language):
18
        file_parts = os.path.normpath(os.path.abspath(__file__)).replace('\\', os.path.altsep) \
19
            .split(os.path.altsep)
20
        locale_domain = file_parts[(len(file_parts) - 1)].replace('.py', '')
21
        locale_folder = os.path.normpath(os.path.join(
22
                os.path.join(os.path.altsep.join(file_parts[:-2]), 'project_locale'),
23
                locale_domain))
24
        self.locale = gettext.translation(locale_domain, localedir = locale_folder,
25
                                          languages = [in_language], fallback = True)
26
27
    @staticmethod
28
    def fn_add_missing_defaults_to_dict_message(in_dict):
29
        if 'field delimiter' not in in_dict:
30
            in_dict['field delimiter'] = os.pathsep
31
        if 'compression' not in in_dict:
32
            in_dict['compression'] = 'infer'
33
        if 'worksheet list' not in in_dict:
34
            in_dict['worksheet list'] = 0
35
        return in_dict
36
37
    def fn_build_feedback_for_logger(self, operation_details):
38
        messages = {}
39
        if operation_details['operation'] == 'load':
40
            files_counted = str(operation_details['files counted'])
41
            messages = {
42
                'failed' : self.locale.gettext(
43
                        'Error encountered on loading Pandas Data Frame '
44
                        + 'from {file_type} file type (see below)')
45
                    .replace('{file_type}', operation_details['format'].upper()),
46
                'success': self.locale.gettext(
47
                        'All {files_counted} files of type {file_type} '
48
                        + 'successfully added to a Pandas Data Frame')
49
                    .replace('{files_counted}', files_counted)
50
                    .replace('{file_type}', operation_details['format'].upper())
51
            }
52
        elif operation_details['operation'] == 'save':
53
            messages = {
54
                'failed' : self.locale.gettext(
55
                        'Error encountered on saving Pandas Data Frame '
56
                        + 'into a {file_type} file type (see below)')
57
                    .replace('{file_type}', operation_details['format'].upper()),
58
                'success': self.locale.gettext(
59
                        'Pandas Data Frame has just been saved to file "{file_name}", '
60
                        + 'considering {file_type} as file type')
61
                    .replace('{file_name}', operation_details['name'])
62
                    .replace('{file_type}', operation_details['format'].upper()),
63
            }
64
        return messages
65
66
    def fn_implemented_file_format_validation(self, local_logger, in_file_details):
67
        given_format_is_implemented = False
68
        if 'format' in in_file_details:
69
            given_format_is_implemented = True
70
            if in_file_details['format'].lower() not in self.implemented_disk_write_file_types:
71
                given_format_is_implemented = False
72
                local_logger.error(self.locale.gettext(
73
                        'File "format" attribute has a value of "{format_value}" '
74
                        + 'which is not among currently implemented values: '
75
                        + '"{implemented_file_formats}", '
76
                        + 'therefore desired file operation is not possible')
77
                                   .replace('{format_value}', in_file_details['format'].lower())
78
                                   .replace('{implemented_file_formats}',
79
                                            '", "'.join(self.implemented_disk_write_file_types)))
80
        else:
81
            local_logger.error(self.locale.gettext(
82
                    'File "format" attribute is mandatory in the file setting, but missing, '
83
                    + 'therefore desired file operation is not possible'))
84
        return given_format_is_implemented
85
86
    def fn_file_operation_logger(self, local_logger, in_logger_dict):
87
        messages = self.fn_build_feedback_for_logger(in_logger_dict)
88
        if in_logger_dict['error details'] is None:
89
            local_logger.info(messages['success'])
90
        else:
91
            local_logger.error(messages['failed'])
92
            local_logger.error(in_logger_dict['error details'])
93
94
    def fn_load_file_into_data_frame(self, in_logger, timer, in_dict):
95
        timer.start()
96
        if self.fn_implemented_file_format_validation(in_logger, in_dict):
97
            in_dict = self.fn_add_missing_defaults_to_dict_message(in_dict)
98
            in_dict.update({'operation': 'load'})
99
            in_dict = self.fn_pack_dict_message(in_dict, in_dict['file list'])
100
            in_dict = self.fn_internal_load_csv_file_into_data_frame(in_dict)
101
            in_dict = self.fn_internal_load_excel_file_into_data_frame(in_dict)
102
            in_dict = self.fn_internal_load_json_file_into_data_frame(in_dict)
103
            in_dict = self.fn_internal_load_parquet_file_into_data_frame(in_dict)
104
            in_dict = self.fn_internal_load_pickle_file_into_data_frame(in_dict)
105
            self.fn_file_operation_logger(in_logger, in_dict)
106
        timer.stop()
107
        return in_dict['out data frame']
108
109
    @staticmethod
110
    def fn_pack_dict_message(in_dict, in_file_list):
111
        if in_dict['format'].lower() in ('parquet', 'pickle') \
112
                and in_dict['compression'].lower() == 'none':
113
            in_dict['compression'] = None
114
        return {
115
            'compression'    : in_dict['compression'],
116
            'field delimiter': in_dict['field delimiter'],
117
            'files list'     : in_dict['file list'],
118
            'worksheet list' : in_dict['worksheet list'],
119
            'files counted'  : len(in_file_list),
120
            'error details'  : None,
121
            'format'         : in_dict['format'],
122
            'name'           : in_dict['name'],
123
            'in data frame'  : None,
124
            'operation'      : in_dict['operation'],
125
            'out data frame' : None,
126
        }
127
128
    def fn_store_data_frame_to_file(self, in_logger, timer, in_data_frame, in_dict):
129
        timer.start()
130
        if self.fn_implemented_file_format_validation(in_logger, in_dict):
131
            in_dict = self.fn_add_missing_defaults_to_dict_message(in_dict)
132
            in_dict.update({'operation': 'save'})
133
            in_dict = self.fn_pack_dict_message(in_dict, [])
134
            in_dict.update({'in data frame': in_data_frame})
135
            # special case treatment
136
            in_dict = self.fn_internal_store_data_frame_to_csv_file(in_dict)
137
            in_dict = self.fn_internal_store_data_frame_to_excel_file(in_dict)
138
            in_dict = self.fn_internal_store_data_frame_to_json_file(in_dict)
139
            in_dict = self.fn_internal_store_data_frame_to_parquet_file(in_dict)
140
            in_dict = self.fn_internal_store_data_frame_to_pickle_file(in_dict)
141
            self.fn_file_operation_logger(in_logger, in_dict)
142
        timer.stop()
143