Completed
Push — master ( b1e450...5ca4d8 )
by
unknown
17s queued 10s
created

gvmtools.pyshell.main()   D

Complexity

Conditions 12

Size

Total Lines 86
Code Lines 60

Duplication

Lines 13
Ratio 15.12 %

Importance

Changes 0
Metric Value
eloc 60
dl 13
loc 86
rs 4.6689
c 0
b 0
f 0
cc 12
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gvmtools.pyshell.main() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2018 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
import code
20
import logging
21
import os
22
import sys
23
24
from argparse import Namespace
25
26
from gvm import get_version as get_gvm_version
27
from gvm.protocols.latest import Gmp, Osp
28
from gvm.transforms import EtreeCheckCommandTransform
29
30
from gvmtools import get_version
31
from gvmtools.helper import authenticate, run_script
32
from gvmtools.parser import create_parser, create_connection, PROTOCOL_OSP
33
34
__version__ = get_version()
35
__api_version__ = get_gvm_version()
36
37
logger = logging.getLogger(__name__)
38
39
HELP_TEXT = """
40
    Command line tool to access services via GMP (Greenbone Management
41
    Protocol) and OSP (Open Scanner Protocol)
42
43
    gvm-pyshell provides an interactive shell for GMP and OSP services.
44
45
    Example:
46
        >>> tasks = gmp.get_tasks()
47
        >>> task_names = tasks.xpath('task/name/text()')
48
        >>> print(task_names)
49
        ['Scan Task']
50
51
    The interactive shell can be exited with:
52
        Ctrl + D on Linux  or
53
        Ctrl + Z on Windows
54
55
    The protocol specifications for GMP and OSP are available at:
56
      https://docs.greenbone.net/index.html#api_documentation"""
57
58
59
class Help(object):
60
    """Help class to overwrite the help function from python itself.
61
    """
62
63
    def __call__(self):
64
        return print(HELP_TEXT)
65
66
    def __repr__(self):
67
        # do pwd command
68
        return HELP_TEXT
69
70
71
def main():
72
    parser = create_parser(
73
        description=HELP_TEXT, logfilename='gvm-pyshell.log')
74
75
    parser.add_protocol_argument()
76
77
    parser.add_argument(
78
        '-i', '--interactive', action='store_true', default=False,
79
        help='Start an interactive Python shell')
80
81
    parser.add_argument(
82
        'scriptname', nargs='?', metavar="SCRIPT",
83
        help='Path to script to be preloaded (example: myscript.gmp)')
84
    parser.add_argument(
85
        'scriptargs', nargs='*', metavar="ARG",
86
        help='Arguments for preloaded script')
87
88
    args = parser.parse_args()
89
90
    if 'socket' in args.connection_type and args.sockpath:
91
        print('The --sockpath parameter has been deprecated. Please use '
92
              '--socketpath instead', file=sys.stderr)
93
94
    connection = create_connection(**vars(args))
95
96
    transform = EtreeCheckCommandTransform()
97
98
    global_vars = {
99
        'help': Help(),
100
        '__version__': __version__,
101
        '__api_version__': __api_version__,
102
    }
103
104
    username = None
105
    password = None
106
107 View Code Duplication
    if args.protocol == PROTOCOL_OSP:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
108
        protocol = Osp(connection, transform=transform)
109
        global_vars['osp'] = protocol
110
        global_vars['__name__'] = '__osp__'
111
    else:
112
        protocol = Gmp(connection, transform=transform)
113
        global_vars['gmp'] = protocol
114
        global_vars['__name__'] = '__gmp__'
115
116
        if args.gmp_username:
117
            (username, password) = authenticate(
118
                protocol, username=args.gmp_username,
119
                password=args.gmp_password)
120
121
    shell_args = Namespace(
122
        username=username, password=password)
123
124
    global_vars['args'] = shell_args
125
126
    with_script = args.scriptname and len(args.scriptname) > 0
127
128
    if with_script:
129
        argv = [os.path.abspath(args.scriptname), *args.scriptargs]
130
        shell_args.argv = argv
131
        # for backwards compatibility we add script here
132
        shell_args.script = argv
133
134
    no_script_no_interactive = not args.interactive and not with_script
135
    script_and_interactive = args.interactive and with_script
136
    only_interactive = not with_script and args.interactive
137
    only_script = not args.interactive and with_script
138
139
    if only_interactive or no_script_no_interactive:
140
        enter_interactive_mode(global_vars)
141
142
    if script_and_interactive or only_script:
143
        if only_script:
144
            print(
145
                'Using gvm-pyshell for running scripts only is deprecated. '
146
                'Please use gvm-script instead',
147
                file=sys.stderr,
148
            )
149
150
        script_name = args.scriptname
151
        run_script(script_name, global_vars)
152
153
        if not only_script:
154
            enter_interactive_mode(global_vars)
155
156
    protocol.disconnect()
157
158
159
def enter_interactive_mode(global_vars):
160
    code.interact(
161
        banner='GVM Interactive Console. Type "help" to get information \
162
about functionality.',
163
        local=dict(global_vars))
164
165
166
if __name__ == '__main__':
167
    main()
168