• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

funilrys / PyFunceble / 10983538562

22 Sep 2024 06:42PM UTC coverage: 94.595% (-0.1%) from 94.723%
10983538562

Pull #380

github

funilrys
Introduction of a way to provide a configuration file from the CLI.

This patch fixes #377.

Contributors:
  * @spirillen
Pull Request #380: Introduction of a way to provide a configuration file from the CLI.

17 of 34 new or added lines in 2 files covered. (50.0%)

25 existing lines in 3 files now uncovered.

11341 of 11989 relevant lines covered (94.6%)

14.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.74
/PyFunceble/dataset/user_agent.py
1
"""
2
The tool to check the availability or syntax of domain, IP or URL.
3

4
::
5

6

7
    ██████╗ ██╗   ██╗███████╗██╗   ██╗███╗   ██╗ ██████╗███████╗██████╗ ██╗     ███████╗
8
    ██╔══██╗╚██╗ ██╔╝██╔════╝██║   ██║████╗  ██║██╔════╝██╔════╝██╔══██╗██║     ██╔════╝
9
    ██████╔╝ ╚████╔╝ █████╗  ██║   ██║██╔██╗ ██║██║     █████╗  ██████╔╝██║     █████╗
10
    ██╔═══╝   ╚██╔╝  ██╔══╝  ██║   ██║██║╚██╗██║██║     ██╔══╝  ██╔══██╗██║     ██╔══╝
11
    ██║        ██║   ██║     ╚██████╔╝██║ ╚████║╚██████╗███████╗██████╔╝███████╗███████╗
12
    ╚═╝        ╚═╝   ╚═╝      ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝╚══════╝╚═════╝ ╚══════╝╚══════╝
13

14
Provides an interface which let us interact with the Public Suffix List.
15

16
Author:
17
    Nissar Chababy, @funilrys, contactTATAfunilrysTODTODcom
18

19
Special thanks:
20
    https://pyfunceble.github.io/#/special-thanks
21

22
Contributors:
23
    https://pyfunceble.github.io/#/contributors
24

25
Project link:
26
    https://github.com/funilrys/PyFunceble
27

28
Project documentation:
29
    https://docs.pyfunceble.com
30

31
Project homepage:
32
    https://pyfunceble.github.io/
33

34
License:
35
::
36

37

38
    Copyright 2017, 2018, 2019, 2020, 2022, 2023, 2024 Nissar Chababy
39

40
    Licensed under the Apache License, Version 2.0 (the "License");
41
    you may not use this file except in compliance with the License.
42
    You may obtain a copy of the License at
43

44
        https://www.apache.org/licenses/LICENSE-2.0
45

46
    Unless required by applicable law or agreed to in writing, software
47
    distributed under the License is distributed on an "AS IS" BASIS,
48
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49
    See the License for the specific language governing permissions and
50
    limitations under the License.
51
"""
52

53
import os
15✔
54
import secrets
15✔
55
from typing import Any
15✔
56
from warnings import warn
15✔
57

58
import PyFunceble.storage
15✔
59
from PyFunceble.dataset.base import DatasetBase
15✔
60
from PyFunceble.downloader.user_agents import UserAgentsDownloader
15✔
61

62

63
class UserAgentDataset(DatasetBase):
15✔
64
    """
65
    Provides the dataset and infrastructure for the User Agent navigation
66
    """
67

68
    STORAGE_INDEX: str = "USER_AGENTS"
15✔
69
    DOWNLOADER: UserAgentsDownloader = UserAgentsDownloader()
15✔
70

71
    preferred_browser: str = "chrome"
15✔
72
    preferred_platform: str = "linux"
15✔
73

74
    def __init__(self) -> None:
75
        self.source_file = os.path.join(
76
            PyFunceble.storage.CONFIG_DIRECTORY,
77
            PyFunceble.storage.USER_AGENT_FILENAME,
78
        )
79

80
    def __contains__(self, value: Any) -> bool:
15✔
81
        content = self.get_content()
15✔
82

83
        if "@modern" in content:
15✔
84
            return value in self.get_content()["@modern"]
15✔
UNCOV
85
        return value in self.get_content()
×
86

87
    def __getattr__(self, value: Any) -> dict:
15✔
88
        if value in self:
15✔
89
            content = self.get_content()
15✔
90

91
            if "@modern" in content:
15✔
92
                return self.get_content()["@modern"][value]
15✔
UNCOV
93
            return self.get_content()[value]
×
94

95
        return dict()  # pylint: disable=use-dict-literal
15✔
96

97
    def __getitem__(self, value: Any) -> dict:
15✔
98
        return self.__getattr__(value)
15✔
99

100
    def set_preferred(
15✔
101
        self, browser_short_name: str, platform: str
102
    ) -> "UserAgentDataset":
103
        """
104
        Sets the preferred browser to work with.
105

106
        :param browser_short_name:
107
            The name of the browser to select.
108
        :pram platform:
109
            The name of the platform to select.
110

111
        :raise TypeError:
112
            When the given :code:`name` is not a :py:class:`str`.
113
        :raise ValueError:
114
            When the given :code:`value` is not supported.
115
        """
116

117
        if not self.is_supported(browser_short_name, platform):
15✔
118
            raise ValueError(
15✔
119
                f"The given name ({browser_short_name!r}) or platform "
120
                f"({platform!r}) is not supported."
121
            )
122

123
        self.preferred_browser = browser_short_name.lower()
15✔
124
        self.preferred_platform = platform.lower()
15✔
125

126
        return self
15✔
127

128
    # @deprecated("TODO: Soon we should be able to do this...")
129
    def set_prefered(
15✔
130
        self, browser_short_name: str, platform: str
131
    ) -> "UserAgentDataset":
132
        """
133
        Sets the preferred browser to work with.
134

135
        :param browser_short_name:
136
            The name of the browser to select.
137
        :pram platform:
138
            The name of the platform to select.
139

140
        :raise TypeError:
141
            When the given :code:`name` is not a :py:class:`str`.
142
        :raise ValueError:
143
            When the given :code:`value` is not supported.
144
        """
145

UNCOV
146
        warn(
×
147
            "The set_prefered() method is deprecated and will be removed in future "
148
            " releases. Please consider using the set_preferred() method instead.",
149
            DeprecationWarning,
150
            stacklevel=2,
151
        )
152

UNCOV
153
        return self.set_preferred(browser_short_name, platform)
×
154

155
    def is_supported_browser(self, browser_short_name: str) -> bool:
15✔
156
        """
157
        Checks if the given browser is supported.
158

159
        :raise TypeError:
160
            When :code:`browser_short_name` is not a :py:class:`str`.
161
        """
162

163
        if not isinstance(browser_short_name, str):
15✔
164
            raise TypeError(
15✔
165
                f"<browser_short_name> should be {str}, "
166
                f"{type(browser_short_name)} given."
167
            )
168

169
        return bool(browser_short_name.lower() in self) and bool(
15✔
170
            self[browser_short_name.lower()]
171
        )
172

173
    def is_supported(self, browser_short_name: str, platform: str) -> bool:
15✔
174
        """
175
        Checks if the given browser and platform is supported.
176

177
        :param browser_short_name:
178
            The short name of the browser.
179

180
        :param platform:
181
            The platform name.
182

183
        :raise TypeError:
184
            When :code:`browser_short_name` or :code:`platform` are not :py:class:`str`.
185
        """
186

187
        if not isinstance(browser_short_name, str):
15✔
188
            raise TypeError(
15✔
189
                f"<browser_short_name> should be {str}, "
190
                f"{type(browser_short_name)} given."
191
            )
192

193
        if not isinstance(platform, str):
15✔
194
            raise TypeError(f"<platform> should be {str}, {type(platform)} given.")
15✔
195

196
        return (
15✔
197
            self.is_supported_browser(browser_short_name)
198
            and bool(platform.lower() in self[browser_short_name.lower()])
199
            and bool(self[browser_short_name.lower()][platform.lower()])
200
        )
201

202
    def get_latest(self) -> str:
15✔
203
        """
204
        Provides the latest user agent for the given platform.
205

206
        Side Effect:
207
            It tries to get the platform and browser from the configuration
208
            (if exists).
209
        """
210

211
        if PyFunceble.storage.CONFIGURATION:
15✔
212
            if (
15✔
213
                PyFunceble.storage.CONFIGURATION.user_agent
214
                and PyFunceble.storage.CONFIGURATION.user_agent.custom
215
            ):
216
                return PyFunceble.storage.CONFIGURATION.user_agent.custom
15✔
217

218
            self.set_preferred(
15✔
219
                PyFunceble.storage.CONFIGURATION.user_agent.browser,
220
                PyFunceble.storage.CONFIGURATION.user_agent.platform,
221
            )
222

223
        result = self[self.preferred_browser][self.preferred_platform]
15✔
224

225
        if isinstance(result, (list, tuple)):
15✔
226
            return secrets.choice(result)
15✔
227

UNCOV
228
        return result
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc