Passed
Push — development/test ( 24302c...f5ca2a )
by Daniel
01:16
created

sources.common.FileOperations   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 114
dl 0
loc 140
rs 10
c 0
b 0
f 0
wmc 22

7 Methods

Rating   Name   Duplication   Size   Complexity  
A FileOperations.fn_store_file_statistics() 0 11 3
A FileOperations.fn_open_file_and_get_content() 0 9 3
A FileOperations.fn_build_relevant_file_list() 0 18 5
A FileOperations.fn_get_file_statistics() 0 25 2
A FileOperations.fn_move_files() 0 17 3
A FileOperations.build_file_list() 0 12 2
A FileOperations.fn_get_file_content() 0 20 4
1
"""
2
facilitates File Operations
3
"""
4
# package to handle date and times
5
from datetime import datetime
6
# package to use for checksum calculations (in this file)
7
import hashlib
8
# package to handle json files
9
import json
10
# package to facilitate operating system operations
11
import os
12
# package to facilitate os path manipulations
13
import pathlib
14
# package regular expressions
15
import re
16
17
18
class FileOperations:
19
    timestamp_format = '%Y-%m-%d %H:%M:%S.%f %Z'
20
21
    def build_file_list(self, local_logger, timmer, given_input_file):
22
        if re.search(r'(\*|\?)*', given_input_file):
23
            local_logger.debug('File pattern identified')
24
            parent_directory = os.path.dirname(given_input_file)
25
            # loading from a specific folder all files matching a given pattern into a file list
26
            relevant_files_list = self.fn_build_relevant_file_list(local_logger, timmer,
27
                                                                   parent_directory,
28
                                                                   given_input_file)
29
        else:
30
            local_logger.debug('Specific file name provided')
31
            relevant_files_list = [given_input_file]
32
        return relevant_files_list
33
34
    @staticmethod
35
    def fn_build_relevant_file_list(local_logger, timmer, in_folder, matching_pattern):
36
        timmer.start()
37
        local_logger.info('Listing all files within ' + in_folder
38
                          + ' folder looking for ' + matching_pattern + ' as matching pattern')
39
        list_files = []
40
        file_counter = 0
41
        if os.path.isdir(in_folder):
42
            working_path = pathlib.Path(in_folder)
43
            for current_file in working_path.iterdir():
44
                if current_file.is_file() and current_file.match(matching_pattern):
45
                    list_files.append(file_counter)
46
                    list_files[file_counter] = str(current_file.absolute())
47
                    local_logger.info(str(current_file.absolute()) + ' file identified')
48
                    file_counter = file_counter + 1
49
        local_logger.info(str(file_counter) + ' file(s) from ' + in_folder + ' folder identified!')
50
        timmer.stop()
51
        return list_files
52
53
    def fn_get_file_content(self, in_file_handler, in_content_type):
54
        if in_content_type == 'json':
55
            try:
56
                json_interpreted_details = json.load(in_file_handler)
57
                print(datetime.utcnow().strftime(self.timestamp_format) +
58
                      'I have interpreted JSON structure from given file')
59
                return json_interpreted_details
60
            except Exception as e:
61
                print(datetime.utcnow().strftime(self.timestamp_format) +
62
                      'Error encountered when trying to interpret JSON')
63
                print(e)
64
        elif in_content_type == 'raw':
65
            raw_interpreted_file = in_file_handler.read()
66
            print(datetime.utcnow().strftime(self.timestamp_format) +
67
                  'I have read file entire content')
68
            return raw_interpreted_file
69
        else:
70
            print(datetime.utcnow().strftime(self.timestamp_format) +
71
                  'Unknown content type provided, expected either "json" or "raw" but got '
72
                  + in_content_type)
73
74
    @staticmethod
75
    def fn_get_file_statistics(file_to_evaluate):
76
        try:
77
            file_handler = open(file=file_to_evaluate, mode='r', encoding='mbcs')
78
        except UnicodeDecodeError:
79
            file_handler = open(file=file_to_evaluate, mode='r', encoding='utf-8')
80
        file_content = file_handler.read().encode()
81
        file_handler.close()
82
        file_checksums = {
83
            'md5': hashlib.md5(file_content).hexdigest(),
84
            'sha1': hashlib.sha1(file_content).hexdigest(),
85
            'sha256': hashlib.sha256(file_content).hexdigest(),
86
            'sha512': hashlib.sha512(file_content).hexdigest(),
87
        }
88
        f_dts = {
89
            'created': datetime.fromtimestamp(os.path.getctime(file_to_evaluate)),
90
            'modified': datetime.fromtimestamp(os.path.getctime(file_to_evaluate)),
91
        }
92
        return {
93
            'date when created': datetime.strftime(f_dts['created'], '%Y-%m-%d %H:%M:%S.%f'),
94
            'date when last modified': datetime.strftime(f_dts['modified'], '%Y-%m-%d %H:%M:%S.%f'),
95
            'size [bytes]': os.path.getsize(file_to_evaluate),
96
            'MD5-Checksum': file_checksums['md5'],
97
            'SHA256-Checksum': file_checksums['sha256'],
98
            'SHA512-Checksum': file_checksums['sha512'],
99
        }
100
101
    @staticmethod
102
    def fn_move_files(local_logger, timmer, source_folder, file_names, destination_folder):
103
        timmer.start()
104
        resulted_files = []
105
        for current_file in file_names:
106
            new_file_name = current_file.replace(source_folder, destination_folder)
107
            if new_file_name.is_file():
108
                os.replace(current_file, new_file_name)
109
                local_logger.info('File ' + current_file
110
                                  + ' has just been been overwritten  as ' + new_file_name)
111
            else:
112
                os.rename(current_file, new_file_name)
113
                local_logger.info('File ' + current_file
114
                                  + ' has just been renamed as ' + new_file_name)
115
            resulted_files.append(new_file_name)
116
        timmer.stop()
117
        return resulted_files
118
119
    def fn_open_file_and_get_content(self, input_file, content_type='json'):
120
        if os.path.isfile(input_file):
121
            with open(input_file, 'r') as file_handler:
122
                print(datetime.utcnow().strftime(self.timestamp_format) +
123
                      'I have opened file: ' + input_file)
124
                return self.fn_get_file_content(file_handler, content_type)
125
        else:
126
            print(datetime.utcnow().strftime(self.timestamp_format) +
127
                  'Given file ' + input_file + ' does not exist, please check your inputs!')
128
129
    def fn_store_file_statistics(self, local_logger, timmer, file_name, file_meaning):
130
        timmer.start()
131
        file_name_variable_type = str(type(file_name))
132
        list_file_names = [file_name]
133
        if file_name_variable_type == "<class 'list'>":
134
            list_file_names = file_name
135
        for current_file_name in list_file_names:
136
            local_logger.info(file_meaning + ' file "' + current_file_name
137
                              + '" has the following characteristics: '
138
                              + str(self.fn_get_file_statistics(current_file_name)))
139
        timmer.stop()
140