Passed
Push — master ( 24a582...ab5396 )
by Jan
05:47 queued 03:29
created

oval_graph.client.Client._get_part()   A

Complexity

Conditions 2

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 2
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
13
14 1
class Client():
15 1
    def __init__(self, args):
16 1
        self.parser = None
17 1
        self.MESSAGES = self._get_message()
18 1
        self.arg = self.parse_arguments(args)
19 1
        self.hide_passing_tests = self.arg.hide_passing_tests
20 1
        self.source_filename = self.arg.source_filename
21 1
        self.rule_name = self.arg.rule_id
22 1
        self.out = self.arg.output
23 1
        self.all_rules = self.arg.all
24 1
        self.isatty = sys.stdout.isatty()
25 1
        self.show_failed_rules = False
26 1
        self.show_not_selected_rules = False
27 1
        self.xml_parser = XmlParser(
28
            self.source_filename)
29 1
        self.parts = self.get_src('parts')
30
31 1
    def _get_message(self):
32 1
        MESSAGES = {
33
            'description': '',
34
            '--output': '',
35
            'source_filename': '',
36
        }
37 1
        return MESSAGES
38
39 1
    def print_red_text(self, text):
40
        CRED = '\033[91m'
41
        CEND = '\033[0m'
42
        print(CRED + str(text) + CEND)
43
44 1
    def run_gui_and_return_answers(self):
45 1
        if self.isatty:
46 1
            if self.all_rules:
47
                return {'rules': self.search_rules_id()}
48
            else:
49 1
                try:
50 1
                    import inquirer
51
                    return inquirer.prompt(self.get_questions())
52 1
                except ImportError:
53 1
                    print(self.get_selection_rules())
54 1
                    return None
55
        else:
56
            return {'rules': self.search_rules_id()}
57
58 1
    def get_list_of_matched_rules(self):
59 1
        rules = self.search_rules_id()
60 1
        if self.show_failed_rules:
61 1
            rules = self._get_only_fail_rule(rules)
62 1
        return rules
63
64 1
    def get_list_of_lines(self):
65 1
        lines = ['== The Rule IDs ==']
66 1
        for rule in self.get_list_of_matched_rules():
67 1
            lines.append("'" + rule + r'\b' + "'")
68 1
        if self.show_not_selected_rules:
69 1
            for line in self.get_lines_of_wanted_not_selected_rules():
70 1
                lines.append(line)
71 1
        lines.append(
72
            "You haven't got installed inquirer lib. "
73
            "Please copy id rule with you want use and put it in command")
74 1
        return lines
75
76 1
    def get_selection_rules(self):
77 1
        return "\n".join(self.get_list_of_lines())
78
79 1
    def get_lines_of_wanted_not_selected_rules(self):
80 1
        out = []
81 1
        out.append('== The not selected rule IDs ==')
82 1
        for rule in self._get_wanted_rules_from_array_of_IDs(
83
                self.xml_parser.notselected_rules):
84 1
            out.append(rule + '(Not selected)')
85 1
        return out
86
87 1
    def get_choices(self):
88 1
        rules = self.search_rules_id()
89 1
        if self.show_failed_rules:
90 1
            rules = self._get_only_fail_rule(rules)
91 1
        choices = rules
92 1
        if self.show_not_selected_rules:
93 1
            print("\n".join(self.get_lines_of_wanted_not_selected_rules()))
94 1
        return choices
95
96 1
    def get_questions(self):
97 1
        choices = self.get_choices()
98 1
        from inquirer.questions import Checkbox as checkbox
99 1
        questions = [
100
            checkbox(
101
                'rules',
102
                message=(
103
                    "= The Rules IDs = (move - UP and DOWN arrows,"
104
                    " select - SPACE or LEFT and RIGHT arrows, submit - ENTER)"),
105
                choices=choices,
106
            ),
107
        ]
108 1
        return questions
109
110 1
    def _get_only_fail_rule(self, rules):
111 1
        return list(
112
            filter(
113
                lambda rule: self.xml_parser.used_rules[rule]['result'] == 'fail',
114
                rules))
115
116 1
    def _get_wanted_rules_from_array_of_IDs(self, rules):
117 1
        return [
118
            x for x in rules if re.search(
119
                self.rule_name, x)]
120
121 1
    def search_rules_id(self):
122 1
        rules = self._get_wanted_rules_from_array_of_IDs(
123
            self.xml_parser.used_rules.keys())
124 1
        notselected_rules = self._get_wanted_rules_from_array_of_IDs(
125
            self.xml_parser.notselected_rules)
126 1
        return self._check_rules_id(rules, notselected_rules)
127
128 1
    def _check_rules_id(self, rules, notselected_rules):
129 1
        if len(notselected_rules) and not rules:
130 1
            raise ValueError(
131
                ('Rule(s) "{}" was not selected, '
132
                 "so there are no results. The rule is"
133
                 ' "notselected" because it'
134
                 " wasn't a part of the executed profile"
135
                 " and therefore it wasn't evaluated "
136
                 "during the scan.")
137
                .format(notselected_rules))
138 1
        elif not notselected_rules and not rules:
139 1
            raise ValueError('404 rule "{}" not found!'.format(self.rule_name))
140
        else:
141 1
            return rules
142
143 1
    def save_html_and_open_html(self, oval_tree_dict, src, rule, out):
144 1
        self.save_html_report(oval_tree_dict, src)
145 1
        print('Rule "{}" done!'.format(rule))
146 1
        out.append(src)
147 1
        self.open_web_browser(src)
148
149 1
    def open_web_browser(self, src):
150 1
        if not self.off_webbrowser:
151
            try:
152
                webbrowser.get('firefox').open_new_tab(src)
153
            except BaseException:
154
                webbrowser.open_new_tab(src)
155
156 1
    def get_src(self, src):
157 1
        _dir = os.path.dirname(os.path.realpath(__file__))
158 1
        FIXTURE_DIR = os.path.join(_dir, src)
159 1
        return str(FIXTURE_DIR)
160
161 1
    def get_save_src(self, rule):
162 1
        date = str(datetime.now().strftime("-%d_%m_%Y-%H_%M_%S"))
163 1
        if self.out is not None:
164 1
            os.makedirs(self.out, exist_ok=True)
165 1
            return os.path.join(
166
                self.out,
167
                'graph-of-' + rule + date + '.html')
168 1
        return os.path.join(
169
            os.getcwd(),
170
            'graph-of-' + rule + date + '.html')
171
172 1
    def _get_part(self, part):
173 1
        with open(os.path.join(self.parts, part), "r") as data_file:
174 1
            return data_file.readlines()
175
176 1
    def _merge_report_parts(self, data):
177 1
        head = self._get_part('head.html')
178 1
        body = self._get_part('body.html')
179 1
        script = self._get_part('script.js')
180 1
        footer = ['</script>', '</body>', '</html>']
181 1
        return [*head, data, *body, *script, *footer]
182
183 1
    def save_html_report(self, dict_, src):
184 1
        data = "var data_of_tree =" + str(
185
            json.dumps(dict_, sort_keys=False, indent=4) + ";")
186 1
        with open(src, "w+") as data_file:
187 1
            data_file.writelines(self._merge_report_parts(data))
188
189 1
    def parse_arguments(self, args):
190 1
        self.prepare_parser()
191 1
        args = self.parser.parse_args(args)
192 1
        return 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