lighthouse_garden.utility.system.clear_data()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 13
rs 10
c 0
b 0
f 0
cc 2
nop 0
1
#!/usr/bin/env python3
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
# -*- coding: future_fstrings -*-
3
4
import json
5
import os
6
import shutil
7
import subprocess
8
import sys
9
10
from lighthouse_garden.utility import output
11
from lighthouse_garden.lighthouse import utility
12
13
config = {
14
    'verbose': False,
15
    'mute': False,
16
    'run': 1,
17
    'export': False,
18
    'export_path': None,
19
    'config_file_path': None,
20
    'data_dir': 'd/',
21
    'keep_history': 0,
22
    'title': 'Lighthouse Garden',
23
    'description': 'Monitoring performance data by Google Lighthouse',
24
    'lighthouse': {
25
        'chrome_flags': '--no-sandbox --headless --disable-gpu --ignore-certificate-errors --disable-dev-shm-usage',
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (116/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
26
        'options': '--quiet --no-enable-error-reporting --preset=desktop --disable-storage-reset'
27
    }
28
}
29
30
31
def check_args(config_file=None,
32
               verbose=False):
33
    """
34
    Check the input arguments
35
    :param config_file:
36
    :param verbose:
37
    :return:
38
    """
39
    global config
0 ignored issues
show
Coding Style Naming introduced by
Constant name "config" doesn't conform to UPPER_CASE naming style ('([^\\W\\da-z][^\\Wa-z]*|__.*__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
Usage of the global statement should be avoided.

Usage of global can make code hard to read and test, its usage is generally not recommended unless you are dealing with legacy code.

Loading history...
40
41
    config['verbose'] = verbose
42
43
    if not config_file is None:
44
        config['config_file_path'] = config_file
45
46
47
def check_config(additional_config={}):
0 ignored issues
show
Bug Best Practice introduced by
The default value {} might cause unintended side-effects.

Objects as default values are only created once in Python and not on each invocation of the function. If the default object is modified, this modification is carried over to the next invocation of the method.

# Bad:
# If array_param is modified inside the function, the next invocation will
# receive the modified object.
def some_function(array_param=[]):
    # ...

# Better: Create an array on each invocation
def some_function(array_param=None):
    array_param = array_param or []
    # ...
Loading history...
48
    """
49
    Checking configuration information by file or dictionary
50
    :param additional_config: Dictionary
51
    :return:
52
    """
53
    global config
0 ignored issues
show
Coding Style Naming introduced by
Constant name "config" doesn't conform to UPPER_CASE naming style ('([^\\W\\da-z][^\\Wa-z]*|__.*__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
Usage of the global statement should be avoided.

Usage of global can make code hard to read and test, its usage is generally not recommended unless you are dealing with legacy code.

Loading history...
54
55
    if config['config_file_path'] is None and additional_config == {}:
56
        sys.exit(f'{output.Subject.ERROR} Configuration is missing')
57
58
    if additional_config:
59
        config.update(additional_config)
60
61
    _config_file_path = config['config_file_path']
62
    if not _config_file_path is None:
63
        if os.path.isfile(_config_file_path):
64
            with open(_config_file_path, 'r') as read_file:
65
                config.update(json.load(read_file))
66
                output.println(
67
                    f'{output.Subject.INFO} Loading host configuration {output.CliFormat.BLACK}{_config_file_path}{output.CliFormat.ENDC}', verbose_only=True)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (158/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
68
        else:
69
            sys.exit(f'{output.Subject.ERROR} Local configuration not found: {config["config_file_path"]}')
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
70
71
72
def run_command(command, return_output=False, allow_fail=False):
73
    """
74
    Run local command
75
    :param command: String Shell command
76
    :param return_output: Boolean Return shell command output
77
    :param allow_fail: Boolean
78
    :return:
79
    """
80
    output.println(
81
        f'{output.Subject.DEBUG}{output.Subject.CMD} {output.CliFormat.BLACK}{command}{output.CliFormat.ENDC}', verbose_only=True)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (130/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
82
83
    res = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
84
85
    out, err = res.communicate()
86
87
    if res.wait() != 0 and err.decode() != '':
88
        _error_message = f'{output.Subject.ERROR} {err.decode()}'
89
        if allow_fail:
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
90
            output.println(_error_message)
91
            return False
92
        else:
93
            sys.exit(_error_message)
94
95
    if return_output:
96
        return out.decode()
97
98
    return True
99
100
101
def check_lighthouse_version():
102
    """
103
    Check sshpass version
104
    :return:
105
    """
106
    _version = run_command('lighthouse --version', return_output=True)
107
108
    if _version:
109
        output.println(
110
            f'{output.Subject.INFO} lighthouse version {_version}',
111
            verbose_only=True
112
        )
113
        config['lighthouse']['version'] = _version
114
115
116
def check_path(path):
117
    """
118
    Create a path on the system if not exists
119
    :param path: String Directory path
120
    :return:
121
    """
122
    run_command(
123
        f'[ ! -d "{path}" ] && mkdir -p "{path}"'
124
    )
125
126
127
def clear_data():
128
    """
129
    Clear the performance data and the lighthouse garden dashboard
130
    :return:
131
    """
132
    output.println(f'{output.Subject.INFO} Clear data')
133
    _file_path = f'{config["export_path"]}index.html'
134
    _dir_path = utility.get_data_dir()
135
136
    if os.path.isfile(_file_path):
137
        os.remove(_file_path)
138
139
    shutil.rmtree(_dir_path)
140