Passed
Branch master (0442a2)
by P.R.
02:00
created

HyperlinkNode.get_html_attributes()   A

Complexity

Conditions 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 3
1
"""
2
SDoc
3
4
Copyright 2016 Set Based IT Consultancy
5
6
Licence MIT
7
"""
8
# ----------------------------------------------------------------------------------------------------------------------
9
from urllib import request, error
10
import httplib2
0 ignored issues
show
Configuration introduced by
The import httplib2 could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
11
from sdoc.sdoc2 import node_store
12
from sdoc.sdoc2.node.Node import Node
13
14
15
class HyperlinkNode(Node):
16
    """
17
    SDoc2 node for hyperlinks.
18
    """
19
    # ------------------------------------------------------------------------------------------------------------------
20
    def __init__(self, options, argument):
21
        """
22
        Object constructor.
23
24
        :param dict[str,str] options: The options of the hyperlink.
25
        :param str argument: Not used.
26
        """
27
        super().__init__('hyperlink', options, argument)
28
29
    # ------------------------------------------------------------------------------------------------------------------
30
    def get_html_attributes(self):
31
        """
32
        Checks valid html attributes for hyperlinks and returns a list of attributes.
33
34
        :rtype: dict[str,str]
35
        """
36
        valid_html_attributes = ('href', 'class', 'id', 'download', 'hreflang', 'media', 'rel', 'target', 'type')
37
        attributes_dict = {}
38
39
        for key, value in self._options.items():
40
            if key in valid_html_attributes:
41
                attributes_dict[key] = value
42
43
        return attributes_dict
44
45
    # ------------------------------------------------------------------------------------------------------------------
46
    def prepare_content_tree(self):
47
        """
48
        Prepares the content of the node. Checks url of 'href' attribute. Sets if needed.
49
        """
50
        # Setting scheme if we haven't.
51
        if 'href' in self._options:
52
            self.set_scheme(self._options['href'])
53
        else:
54
            self.set_scheme(self._argument)
55
56
        # Trying to connect
57
        self.try_connect()
58
59
    # ------------------------------------------------------------------------------------------------------------------
60
    def set_scheme(self, url):
61
        """
62
        Checks if we haven't got a scheme. Sets scheme if needed.
63
64
        :param str url: The url address with scheme or without.
65
        """
66
        if not request.urlparse(url).scheme:
67
            if url.startswith('ftp.'):
68
                url = 'ftp://{0!s}'.format(url)
69
                self._options['href'] = url
70
            else:
71
                url = 'http://{0!s}'.format(url)
72
                self._options['href'] = url
73
74
    # ------------------------------------------------------------------------------------------------------------------
75
    def try_connect(self):
76
        """
77
        Tries to connect to url. If have connection, checks the redirect. If redirect to 'https' protocol and
78
        host is the same, reset scheme in 'href' attribute.
79
        """
80
        try:
81
            response = request.urlopen(self._options['href'])
82
83
            # Check if we can connect to host.
84
            if response.getcode() not in range(200, 400):
85
                print("Warning! - Cannot connect to: '{0!s}'".format(self._options['href']))
86
            else:
87
                # If we connected, check the redirect.
88
                url = self._options['href'].lstrip('(http://)|(https://)')
89
90
                connection = httplib2.HTTPConnectionWithTimeout(url)
91
                connection.request('HEAD', '/')
92
                response = connection.getresponse()
93
94
                if response.status in range(301, 304):
95
                    # If host of redirected is the same, reset 'href' option
96
                    if response.getheader('Location').startswith('https://' + url):
97
                        self._options['href'].replace('http://', 'https://')
98
99
        except error.URLError:
100
            print("Warning! - Invalid url address: '{0!s}'".format(self._options['href']))
101
102
    # ------------------------------------------------------------------------------------------------------------------
103
    def get_command(self):
104
        """
105
        Returns the command of this node, i.e. hyperlink.
106
107
        :rtype: str
108
        """
109
        return 'hyperlink'
110
111
    # ------------------------------------------------------------------------------------------------------------------
112
    def is_phrasing(self):
113
        """
114
        Returns True.
115
116
        :rtype: bool
117
        """
118
        return True
119
120
    # ------------------------------------------------------------------------------------------------------------------
121
    def is_inline_command(self):
122
        """
123
        Returns True.
124
125
        :rtype: bool
126
        """
127
        return True
128
129
    # ------------------------------------------------------------------------------------------------------------------
130
    def is_block_command(self):
131
        """
132
        Returns False.
133
134
        :rtype: bool
135
        """
136
        return False
137
138
139
# ----------------------------------------------------------------------------------------------------------------------
140
node_store.register_inline_command('hyperlink', HyperlinkNode)
141