Passed
Branch master (5f3343)
by Konrad
01:49
created

lighthouse_garden.lighthouse.database   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 39
eloc 101
dl 0
loc 201
rs 9.28
c 0
b 0
f 0

11 Functions

Rating   Name   Duplication   Size   Complexity  
A get_data() 0 13 3
A get_average_by_attribute() 0 9 1
A get_history_by_attribute() 0 11 2
A add_value_to_history() 0 13 2
A get_last_results() 0 11 4
A sort_by_average() 0 4 2
A get_average_peak() 0 14 2
A get_last_value() 0 3 1
A set_data() 0 11 2
A get_target_by_attribute() 0 5 3
F get_result_by_report_file() 0 73 17
1
#!/usr/bin/env python3
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
# -*- coding: future_fstrings -*-
3
4
import datetime
5
import json
6
import os
7
import sys
8
from collections import defaultdict
9
10
from lighthouse_garden.utility import output, system
11
from lighthouse_garden.lighthouse import utility
12
13
14
def get_result_by_report_file(target, file_name):
15
    """
16
17
    :param target: Dict
18
    :param file_name: String
19
    :return:
20
    """
21
    output.println(f'{output.Subject.INFO} Processing result of report', verbose_only=True)
22
    _report_path = f'{utility.get_data_dir()}{file_name}.report.json'
23
    _report = None
24
25
    if os.path.isfile(_report_path):
26
        with open(_report_path, 'r') as read_file:
27
            _report = json.load(read_file)
28
    else:
29
        sys.exit(f'{output.Subject.ERROR} Report file not found: {_report_path}')
30
31
    if not isinstance(_report, dict):
32
        sys.exit(f'{output.Subject.ERROR} Report not readable')
33
34
    if _report['categories']['performance']['score']:
35
        _performance = int(round(_report['categories']['performance']['score'] * 100))
36
    else:
37
        return None
38
39
    _result = defaultdict(dict)
40
    _result = {
41
        'title': target['title'],
42
        'url': target['url'],
43
        'performance': {
44
            'value': _performance
45
        },
46
        'report': f'{utility.get_data_dir(absolute_path=False)}{file_name}.report.html',
47
        'date': '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())
48
    }
49
50
    # audits
51
    if _report['audits']['first-contentful-paint']:
52
        _result['performance']['first-contentful-paint'] = _report['audits']['first-contentful-paint']['displayValue']
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (118/100).

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

Loading history...
53
54
    if _report['audits']['largest-contentful-paint']:
55
        _result['performance']['largest-contentful-paint'] = _report['audits']['largest-contentful-paint']['displayValue']
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (122/100).

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

Loading history...
56
57
    if _report['audits']['speed-index']:
58
        _result['performance']['speed-index'] = _report['audits']['speed-index']['displayValue']
59
60
    if _report['audits']['total-blocking-time']:
61
        _result['performance']['total-blocking-time'] = _report['audits']['total-blocking-time']['displayValue']
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (112/100).

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

Loading history...
62
63
    if _report['audits']['interactive']:
64
        _result['performance']['interactive'] = _report['audits']['interactive']['displayValue']
65
66
    if _report['audits']['cumulative-layout-shift']:
67
        _result['performance']['cumulative-layout-shift'] = _report['audits']['cumulative-layout-shift']['displayValue']
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (120/100).

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

Loading history...
68
69
    # average
70
    _result['average'] = {
71
        'value': get_average_by_attribute(target, 'performance', _performance),
0 ignored issues
show
Bug introduced by
There seem to be too many positional arguments for this function call.
Loading history...
72
        'min': get_average_peak(target, 'performance', _performance, True),
0 ignored issues
show
Bug introduced by
There seem to be too many positional arguments for this function call.
Loading history...
73
        'max': get_average_peak(target, 'performance', _performance, False)
0 ignored issues
show
Bug introduced by
There seem to be too many positional arguments for this function call.
Loading history...
74
    }
75
76
    # additional metrics
77
    if 'accessibility' in _report['categories'] and _report['categories']['accessibility']['score']:
78
        _result['accessibility']['value'] = int(round(_report['categories']['accessibility']['score'] * 100))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/100).

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

Loading history...
79
80
    if 'best-practices' in _report['categories'] and _report['categories']['best-practices']['score']:
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (102/100).

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

Loading history...
81
        _result['best-practices']['value'] = int(round(_report['categories']['best-practices']['score'] * 100))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (111/100).

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

Loading history...
82
83
    if 'seo' in _report['categories'] and _report['categories']['seo']['score']:
84
        _result['seo']['value'] = int(round(_report['categories']['seo']['score'] * 100))
85
86
    return _result
87
88
89
def get_data(target, file_suffix=''):
90
    """
91
92
    :param target:
93
    :param file_suffix:
94
    :return:
95
    """
96
    data_file = f'{utility.get_data_dir()}_{target["identifier"]}{file_suffix}.json'
97
    if os.path.isfile(data_file):
98
        with open(data_file, 'r') as read_file:
99
            return json.load(read_file)
100
    else:
101
        return []
102
103
104
def set_data(target, data, file_suffix=''):
105
    """
106
107
    :param target:
108
    :param data:
109
    :param file_suffix:
110
    :return:
111
    """
112
    data_file = f'{utility.get_data_dir()}_{target["identifier"]}{file_suffix}.json'
113
    with open(data_file, 'w') as write_file:
114
        json.dump(data, write_file)
115
116
117
def add_value_to_history(target, result):
118
    """
119
120
    :param target:
121
    :param result:
122
    :return:
123
    """
124
    _data = get_data(target, '.history')
125
    while len(_data) > system.config['keep_history']:
126
        utility.remove_file(f'{utility.get_export_dir()}{_data[0]["report"]}')
127
        del _data[0]
128
    _data.append(result)
129
    set_data(target, _data, '.history')
130
131
132
def get_average_by_attribute(target, attribute):
133
    """
134
135
    :param target:
136
    :param attribute:
137
    :return:
138
    """
139
    history_data = get_history_by_attribute(target, attribute)
140
    return sum(history_data) / float(len(history_data))
141
142
143
def get_average_peak(target, attribute, min_max=True):
144
    """
145
146
    :param target:
147
    :param attribute:
148
    :param min_max:
149
    :return:
150
    """
151
    history_data = get_history_by_attribute(target, attribute)
152
153
    if min_max:
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
154
        return min(history_data)
155
    else:
156
        return max(history_data)
157
158
159
def get_history_by_attribute(target, attribute):
160
    """
161
162
    :param target:
163
    :param attribute:
164
    :return:
165
    """
166
    history_data = []
167
    for history in get_data(target, '.history'):
168
        history_data.append(history[attribute])
169
    return history_data
170
171
172
def get_target_by_attribute(value, attribute):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
173
    for target in system.config['targets']:
174
        if target[attribute] == value:
175
            return target
176
    return None
177
178
179
def get_last_results():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
180
    results = []
181
    for target in system.config['targets']:
182
        _result = get_data(target)
183
        if _result:
184
            results.append(_result)
185
186
    # sort by performance
187
    results.sort(key=lambda x: x['performance'], reverse=True)
188
189
    return results
190
191
192
def get_last_value(target, attribute):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
193
    _result = get_data(target, '.history')
194
    return _result[-1][attribute]
195
196
197
def sort_by_average(results):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
198
    # sort by average
199
    results.sort(key=lambda x: x['average']['value'], reverse=True)
200
    return results
201