Passed
Push — master ( 8e9b8f...82f349 )
by Jan
04:12 queued 11s
created

oval_graph.client.Client._get_html_body()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 10
nop 2
dl 0
loc 12
ccs 2
cts 2
cp 1
crap 1
rs 9.9
c 0
b 0
f 0
1 1
import re
2 1
import argparse
3 1
import tempfile
4 1
import os
5 1
import webbrowser
6 1
import json
7 1
import shutil
8 1
from datetime import datetime
9 1
import sys
10
11 1
from .xml_parser import XmlParser
12 1
from .exceptions import NotChecked
13 1
from ._builder_html_graph import BuilderHtmlGraph
14
15
16 1
class Client():
17 1
    def __init__(self, args):
18 1
        self.parser = None
19 1
        self.MESSAGES = self._get_message()
20 1
        self.arg = self.parse_arguments(args)
21 1
        self.hide_passing_tests = self.arg.hide_passing_tests
22 1
        self.source_filename = self.arg.source_filename
23 1
        self.rule_name = self.arg.rule_id
24 1
        self.out = self.arg.output
25 1
        self.all_rules = self.arg.all
26 1
        self.all_in_one = None
27 1
        self.off_webbrowser = None
28 1
        self.isatty = sys.stdout.isatty()
29 1
        self.show_failed_rules = False
30 1
        self.show_not_selected_rules = False
31 1
        self.xml_parser = XmlParser(
32
            self.source_filename)
33 1
        self.parts = self.get_src('parts')
34 1
        self.START_OF_FILE_NAME = 'graph-of-'
35 1
        self.date = str(datetime.now().strftime("-%d_%m_%Y-%H_%M_%S"))
36
37 1
    def _get_message(self):
38 1
        MESSAGES = {
39
            'description': '',
40
            '--output': '',
41
            'source_filename': '',
42
        }
43 1
        return MESSAGES
44
45 1
    def print_red_text(self, text):
46
        CRED = '\033[91m'
47
        CEND = '\033[0m'
48
        print(CRED + str(text) + CEND)
49
50 1
    def run_gui_and_return_answers(self):
51 1
        if self.isatty:
52 1
            if self.all_rules:
53
                return self._get_rules()
54
            else:
55 1
                try:
56 1
                    import inquirer
57 1
                    return inquirer.prompt(self.get_questions())
58 1
                except ImportError:
59 1
                    print(self.get_selection_rules())
60 1
                    return None
61
        else:
62 1
            return self._get_rules()
63
64 1
    def _get_rules(self):
65 1
        return {
66
            'rules': self._get_only_fail_rule(
67
                self.search_rules_id())} if self.show_failed_rules else {
68
            'rules': self.search_rules_id()}
69
70 1
    def get_list_of_matched_rules(self):
71 1
        return self._get_only_fail_rule(
72
            self.search_rules_id()) if self.show_failed_rules else self.search_rules_id()
73
74 1
    def get_list_of_lines(self):
75 1
        lines = ['== The Rule IDs ==']
76 1
        for rule in self.get_list_of_matched_rules():
77 1
            lines.append("'" + rule + r'\b' + "'")
78 1
        if self.show_not_selected_rules:
79 1
            for line in self.get_lines_of_wanted_not_selected_rules():
80 1
                lines.append(line)
81 1
        lines.append(
82
            "You haven't got installed inquirer lib. "
83
            "Please copy id rule with you want use and put it in command")
84 1
        return lines
85
86 1
    def get_selection_rules(self):
87 1
        return "\n".join(self.get_list_of_lines())
88
89 1
    def get_lines_of_wanted_not_selected_rules(self):
90 1
        out = []
91 1
        out.append('== The not selected rule IDs ==')
92 1
        for rule in self._get_wanted_rules_from_array_of_IDs(
93
                self.xml_parser.notselected_rules):
94 1
            out.append(rule + '(Not selected)')
95 1
        return out
96
97 1
    def get_choices(self):
98 1
        if self.show_not_selected_rules:
99 1
            print("\n".join(self.get_lines_of_wanted_not_selected_rules()))
100 1
        return self.get_list_of_matched_rules()
101
102 1
    def get_questions(self):
103 1
        choices = self.get_choices()
104 1
        from inquirer.questions import Checkbox as checkbox
105 1
        questions = [
106
            checkbox(
107
                'rules',
108
                message=(
109
                    "= The Rules IDs = (move - UP and DOWN arrows,"
110
                    " select - SPACE or LEFT and RIGHT arrows, submit - ENTER)"),
111
                choices=choices,
112
            ),
113
        ]
114 1
        return questions
115
116 1
    def _get_only_fail_rule(self, rules):
117 1
        return list(
118
            filter(
119
                lambda rule: self.xml_parser.used_rules[rule]['result'] == 'fail',
120
                rules))
121
122 1
    def _get_wanted_rules_from_array_of_IDs(self, rules):
123 1
        return [
124
            x for x in rules if re.search(
125
                self.rule_name, x)]
126
127 1
    def search_rules_id(self):
128 1
        return self._check_rules_id(
129
            self._get_wanted_rules_from_array_of_IDs(
130
                self.xml_parser.used_rules.keys()),
131
            self._get_wanted_rules_from_array_of_IDs(
132
                self.xml_parser.notselected_rules))
133
134 1
    def _check_rules_id(self, rules, notselected_rules):
135 1
        if len(notselected_rules) and not rules:
136 1
            raise ValueError(
137
                ('Rule(s) "{}" was not selected, '
138
                 "so there are no results. The rule is"
139
                 ' "notselected" because it'
140
                 " wasn't a part of the executed profile"
141
                 " and therefore it wasn't evaluated "
142
                 "during the scan.")
143
                .format(notselected_rules))
144 1
        elif not notselected_rules and not rules:
145 1
            raise ValueError('404 rule "{}" not found!'.format(self.rule_name))
146
        else:
147 1
            return rules
148
149 1
    def get_save_src(self, rule):
150 1
        if self.out is not None:
151 1
            os.makedirs(self.out, exist_ok=True)
152 1
            return os.path.join(
153
                self.out,
154
                self.START_OF_FILE_NAME + rule + '.html')
155 1
        return os.path.join(
156
            os.getcwd(),
157
            self.START_OF_FILE_NAME + rule + '.html')
158
159 1
    def get_src(self, src):
160 1
        _dir = os.path.dirname(os.path.realpath(__file__))
161 1
        return str(os.path.join(_dir, src))
162
163 1
    def _build_and_save_html(self, dict_oval_trees, src, rules, out):
164 1
        builder = BuilderHtmlGraph(self.parts, self.off_webbrowser)
165 1
        builder.save_html_and_open_html(dict_oval_trees, src, rules, out)
166
167 1
    def _prepare_data(self, rules, dict_oval_trees, out):
168 1
        for rule in rules['rules']:
169 1
            try:
170 1
                self._put_to_dict_oval_trees(dict_oval_trees, rule)
171 1
                if not self.all_in_one:
172 1
                    self._build_and_save_html(
173
                        dict_oval_trees, self._get_src_for_one_graph(
174
                            rule), dict(
175
                            rules=[rule]), out)
176 1
                    dict_oval_trees = {}
177 1
            except NotChecked as error:
178
                self.print_red_text(error)
179 1
        if self.all_in_one:
180
            self._build_and_save_html(
181
                dict_oval_trees, self.get_save_src(
182
                    'rules' + self.date), rules, out)
183 1
        return out
184
185 1
    def prepare_data(self, rules):
186 1
        out = []
187 1
        oval_tree_dict = dict()
188 1
        return self._prepare_data(rules, oval_tree_dict, out)
189
190 1
    def parse_arguments(self, args):
191 1
        self.prepare_parser()
192 1
        return self.parser.parse_args(args)
193
194 1
    def prepare_parser(self):
195 1
        self.parser = argparse.ArgumentParser(
196
            description=self.MESSAGES.get('description'))
197 1
        self.parser.add_argument(
198
            '--all',
199
            action="store_true",
200
            default=False,
201
            help="Process all matched rules.")
202 1
        self.parser.add_argument(
203
            '--hide-passing-tests',
204
            action="store_true",
205
            default=False,
206
            help=(
207
                "Do not display passing tests for better orientation in"
208
                " graphs that contain a large amount of nodes.(Not implemented)"))
209 1
        self.parser.add_argument(
210
            '-o',
211
            '--output',
212
            action="store",
213
            default=None,
214
            help=self.MESSAGES.get('--output'))
215 1
        self.parser.add_argument(
216
            "source_filename",
217
            help=self.MESSAGES.get('source_filename'))
218 1
        self.parser.add_argument(
219
            "rule_id", help=(
220
                "Rule ID to be visualized. A part from the full rule ID"
221
                " a part of the ID or a regular expression can be used."
222
                " If brackets are used in the regular expression "
223
                "the regular expression must be quoted."))
224