File: v5.py

package info (click to toggle)
python-hole 0.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 128 kB
  • sloc: python: 680; makefile: 3
file content (220 lines) | stat: -rw-r--r-- 7,402 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
"""*hole API Python client."""

import asyncio
import logging
import socket

import aiohttp
import sys

if sys.version_info >= (3, 11):
    import asyncio as async_timeout
else:
    import async_timeout

from . import exceptions

_LOGGER = logging.getLogger(__name__)
_INSTANCE = "{schema}://{host}/{location}/api.php"


class HoleV5(object):
    """A class for handling connections with a *hole instance."""

    def __init__(
        self,
        host,
        session,
        location="admin",
        tls=False,
        verify_tls=True,
        api_token=None,
    ):
        """Initialize the connection to a *hole instance."""
        self._session = session
        self.tls = tls
        self.verify_tls = verify_tls
        self.schema = "https" if self.tls else "http"
        self.host = host
        self.location = location
        self.api_token = api_token
        self.data = {}
        self.versions = {}
        self.base_url = _INSTANCE.format(
            schema=self.schema, host=self.host, location=self.location
        )

    async def get_data(self):
        """Get details of a *hole instance."""
        params = "summaryRaw&auth={}".format(self.api_token)
        try:
            async with async_timeout.timeout(5):
                response = await self._session.get(self.base_url, params=params)

            _LOGGER.debug("Response from *hole: %s", response.status)
            self.data = await response.json()
            _LOGGER.debug(self.data)

        except (asyncio.TimeoutError, aiohttp.ClientError, socket.gaierror):
            msg = "Can not load data from *hole: {}".format(self.host)
            _LOGGER.error(msg)
            raise exceptions.HoleConnectionError(msg)

    async def get_versions(self):
        """Get version information of a *hole instance."""
        params = "versions"
        try:
            async with async_timeout.timeout(5):
                response = await self._session.get(self.base_url, params=params)

            _LOGGER.debug("Response from *hole: %s", response.status)
            self.versions = await response.json()
            _LOGGER.debug(self.versions)

        except (asyncio.TimeoutError, aiohttp.ClientError, socket.gaierror):
            msg = "Can not load data from *hole: {}".format(self.host)
            _LOGGER.error(msg)
            raise exceptions.HoleConnectionError(msg)

    async def enable(self):
        """Enable DNS blocking on a *hole instance."""
        if self.api_token is None:
            _LOGGER.error("You need to supply an api_token to use this")
            return
        params = "enable=True&auth={}".format(self.api_token)
        try:
            async with async_timeout.timeout(5):
                response = await self._session.get(self.base_url, params=params)
                _LOGGER.debug("Response from *hole: %s", response.status)

                while self.status != "enabled":
                    _LOGGER.debug("Awaiting status to be enabled")
                    await self.get_data()
                    await asyncio.sleep(0.01)

            data = self.status
            _LOGGER.debug(data)

        except (asyncio.TimeoutError, aiohttp.ClientError, socket.gaierror):
            msg = "Can not load data from *hole: {}".format(self.host)
            _LOGGER.error(msg)
            raise exceptions.HoleConnectionError(msg)

    async def disable(self, duration=True):
        """Disable DNS blocking on a *hole instance."""
        if self.api_token is None:
            _LOGGER.error("You need to supply an api_token to use this")
            return
        params = "disable={}&auth={}".format(duration, self.api_token)
        try:
            async with async_timeout.timeout(5):
                response = await self._session.get(self.base_url, params=params)
                _LOGGER.debug("Response from *hole: %s", response.status)

                while self.status != "disabled":
                    _LOGGER.debug("Awaiting status to be disabled")
                    await self.get_data()
                    await asyncio.sleep(0.01)

            data = self.status
            _LOGGER.debug(data)

        except (asyncio.TimeoutError, aiohttp.ClientError, socket.gaierror):
            msg = "Can not load data from *hole: {}".format(self.host)
            _LOGGER.error(msg)
            raise exceptions.HoleConnectionError(msg)

    @property
    def status(self):
        """Return the status of the *hole instance."""
        return self.data["status"]

    @property
    def unique_clients(self):
        """Return the unique clients of the *hole instance."""
        return self.data["unique_clients"]

    @property
    def unique_domains(self):
        """Return the unique domains of the *hole instance."""
        return self.data["unique_domains"]

    @property
    def ads_blocked_today(self):
        """Return the ads blocked today of the *hole instance."""
        return self.data["ads_blocked_today"]

    @property
    def ads_percentage_today(self):
        """Return the ads percentage today of the *hole instance."""
        return self.data["ads_percentage_today"]

    @property
    def clients_ever_seen(self):
        """Return the clients_ever_seen of the *hole instance."""
        return self.data["clients_ever_seen"]

    @property
    def dns_queries_today(self):
        """Return the dns queries today of the *hole instance."""
        return self.data["dns_queries_today"]

    @property
    def domains_being_blocked(self):
        """Return the domains being blocked of the *hole instance."""
        return self.data["domains_being_blocked"]

    @property
    def queries_cached(self):
        """Return the queries cached of the *hole instance."""
        return self.data["queries_cached"]

    @property
    def queries_forwarded(self):
        """Return the queries forwarded of the *hole instance."""
        return self.data["queries_forwarded"]

    @property
    def ftl_current(self):
        """Return the current version of FTL of the *hole instance."""
        return self.versions["FTL_current"]

    @property
    def ftl_latest(self):
        """Return the latest version of FTL of the *hole instance."""
        return self.versions["FTL_latest"]

    @property
    def ftl_update(self):
        """Return wether an update of FTL of the *hole instance is available."""
        return self.versions["FTL_update"]

    @property
    def core_current(self):
        """Return the current version of the *hole instance."""
        return self.versions["core_current"]

    @property
    def core_latest(self):
        """Return the latest version of the *hole instance."""
        return self.versions["core_latest"]

    @property
    def core_update(self):
        """Return wether an update of the *hole instance is available."""
        return self.versions["core_update"]

    @property
    def web_current(self):
        """Return the current version of the web interface of the *hole instance."""
        return self.versions["web_current"]

    @property
    def web_latest(self):
        """Return the latest version of the web interface of the *hole instance."""
        return self.versions["web_latest"]

    @property
    def web_update(self):
        """Return wether an update of web interface of the *hole instance is available."""
        return self.versions["web_update"]