Passed
Push — master ( ad1f56...e8e600 )
by Daniel
01:39
created

BasicNeeds.fn_validate_single_value()   B

Complexity

Conditions 5

Size

Total Lines 19
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 19
nop 4
dl 0
loc 19
rs 8.9833
c 0
b 0
f 0
1
"""
2
BasicNeeds - useful functions library
3
4
This library has functions useful to keep main logic short and simple
5
"""
6
# package to handle date and times
7
from datetime import date, datetime, timedelta
8
# package to use for checksum calculations (in this file)
9
import hashlib
10
# package to handle json files
11
import json
12
# package to handle files/folders and related metadata/operations
13
import os.path
14
# package regular expressions
15
import re
16
17
18
class BasicNeeds:
19
    cfg_dtls = {}
20
21
    def fn_check_inputs(self, input_parameters, input_script):
22
        # checking log folder first as there's all further messages will be stored
23
        self.fn_validate_single_value(os.path.dirname(input_parameters.output_log_file), 'folder',
24
                                      'log file')
25
        # checking input file as the main point of whole logic revolves around it
26
        self.fn_validate_single_value(input_parameters.input_file, 'file', 'input file')
27
        # checking script specific inputs
28
        if input_script == 'converter':
29
            self.fn_validate_single_value(os.path.dirname(input_parameters.output_file), 'folder',
30
                                          'output file')
31
        elif input_script == 'publish_data_source':
32
            self.fn_validate_single_value(input_parameters.input_credentials_file, 'file',
33
                                          'credentials file')
34
            self.fn_validate_single_value(input_parameters.tableau_server, 'url',
35
                                          'Tableau Server URL')
36
37
    def fn_final_message(self, local_logger, log_file_name, performance_in_seconds):
38
        total_time_string = str(timedelta(seconds=performance_in_seconds))
39
        if log_file_name == 'None':
40
            self.fn_timestamped_print('Application finished, whole script took '
41
                                      + total_time_string)
42
        else:
43
            local_logger.info(f'Total execution time was ' + total_time_string)
44
            self.fn_timestamped_print('Application finished, '
45
                                      + 'for complete logged details please check '
46
                                      + log_file_name)
47
48
    def fn_get_file_content(self, in_file_handler, in_content_type):
49
        if in_content_type == 'json':
50
            try:
51
                json_interpreted_details = json.load(in_file_handler)
52
                self.fn_timestamped_print('I have interpreted JSON structure from given file')
53
                return json_interpreted_details
54
            except Exception as e:
55
                self.fn_timestamped_print('Error encountered when trying to interpret JSON')
56
                print(e)
57
        elif in_content_type == 'raw':
58
            raw_interpreted_file = in_file_handler.read()
59
            self.fn_timestamped_print('I have read file entire content')
60
            return raw_interpreted_file
61
        else:
62
            self.fn_timestamped_print('Unknown content type provided, '
63
                                      + 'expected either "json" or "raw" but got '
64
                                      + in_content_type)
65
66
    def fn_get_file_statitics(self, file_to_evaluate):
67
        file_sha512 = hashlib.sha512(open(file_to_evaluate, 'r').read().encode()).hexdigest()
68
        file_dates = {
69
            'created': os.path.getctime(file_to_evaluate),
70
            'modified': os.path.getctime(file_to_evaluate),
71
        }
72
        file_info = {
73
            'date when created': date.strftime(datetime.fromtimestamp(file_dates['created']),
74
                                               '%Y-%m-%d %H:%M:%S.%f'),
75
            'date when last modified': date.strftime(datetime.fromtimestamp(file_dates['modified']),
76
                                                     '%Y-%m-%d %H:%M:%S.%f'),
77
            'size [bytes]': os.path.getsize(file_to_evaluate),
78
            'SHA512-Checksum': file_sha512,
79
        }
80
        return file_info
81
82
    def fn_load_configuration(self):
83
        relevant_file = os.path.join(os.path.dirname(__file__), 'config.json')
84
        self.cfg_dtls = self.fn_open_file_and_get_content(relevant_file)
85
        # adding a special case data type
86
        self.cfg_dtls['data_types']['str'] = ''
87
88
    def fn_open_file_and_get_content(self, input_file, content_type='json'):
89
        if os.path.isfile(input_file):
90
            with open(input_file, 'r') as file_handler:
91
                self.fn_timestamped_print('I have opened file: ' + input_file)
92
                return self.fn_get_file_content(file_handler, content_type)
93
        else:
94
            self.fn_timestamped_print('Given file ' + input_file
95
                                      + ' does not exist, please check your inputs!')
96
97
    def fn_optional_print(self, boolean_variable, string_to_print):
98
        if boolean_variable:
99
            self.fn_timestamped_print(string_to_print)
100
101
    def fn_store_file_statistics(self, local_logger, timmer, file_name, file_meaning):
102
        timmer.start()
103
        local_logger.info(file_meaning + ' file "' + file_name
104
                          + '" has the following characteristics: '
105
                          + str(self.fn_get_file_statitics(file_name)))
106
        timmer.stop()
107
108
    @staticmethod
109
    def fn_timestamped_print(string_to_print):
110
        print(datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S.%f %Z")
111
              + ' - ' + string_to_print)
112
113
    def fn_validate_single_value(self, value_to_validate, validation_type, name_meaning):
114
        is_fatal_error = False
115
        message = ''
116
        if validation_type == 'file':
117
            is_fatal_error = (not os.path.isfile(value_to_validate))
118
            message = 'Given ' + name_meaning + ' "' + value_to_validate \
119
                      + '" does not exist, please check your inputs!'
120
        elif validation_type == 'folder':
121
            is_fatal_error = (not os.path.isdir(value_to_validate))
122
            message = 'Given ' + name_meaning + ' "' + value_to_validate \
123
                      + '" does not exist, please check your inputs!'
124
        elif validation_type == 'url':
125
            url_reg_expression = 'https?://(?:www)?(?:[\\w-]{2,255}(?:\\.\\w{2,66}){1,2})'
126
            is_fatal_error = (not re.match(url_reg_expression, value_to_validate))
127
            message = 'Given ' + name_meaning + ' "' + value_to_validate \
128
                      + '" does not seem a valid one, please check your inputs!'
129
        if is_fatal_error:
130
            self.fn_timestamped_print(message)
131
            exit(1)
132