fb-tools 2.6.3__tar.gz → 2.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fb_tools-2.6.3/lib/fb_tools.egg-info → fb_tools-2.8.0}/PKG-INFO +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/bin/get-file-to-remove +3 -3
- {fb_tools-2.6.3 → fb_tools-2.8.0}/bin/myip +1 -1
- fb_tools-2.8.0/bin/show-spinner +78 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/bin/update-ddns +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/__init__.py +2 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/app.py +82 -44
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/cfg_app.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/colcts.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/collections.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/common.py +4 -2
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/config.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/ddns/__init__.py +41 -3
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/ddns/myip_app.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/ddns/update_app.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/errors.py +57 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/get_file_rm_app.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/handler/__init__.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/handler/lock.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/handling_obj.py +157 -26
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/local_version.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/merge.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/multi_config/__init__.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/multi_config/files.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/multi_config/inits.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/multi_config/read.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/obj.py +24 -28
- fb_tools-2.8.0/lib/fb_tools/show_spinner_app.py +300 -0
- fb_tools-2.8.0/lib/fb_tools/socket_obj/__init__.py +668 -0
- fb_tools-2.8.0/lib/fb_tools/socket_obj/tcp.py +493 -0
- fb_tools-2.8.0/lib/fb_tools/socket_obj/unix.py +531 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/xlate.py +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0/lib/fb_tools.egg-info}/PKG-INFO +1 -1
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools.egg-info/SOURCES.txt +9 -0
- fb_tools-2.8.0/locale/de/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/locale/de/LC_MESSAGES/fb_tools.po +471 -144
- fb_tools-2.8.0/locale/en/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/locale/en/LC_MESSAGES/fb_tools.po +460 -143
- {fb_tools-2.6.3 → fb_tools-2.8.0}/locale/fb_tools.pot +460 -144
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/general.py +4 -1
- fb_tools-2.8.0/test/listener_thread.py +103 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_15_mailaddress.py +2 -2
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_20_handling_object.py +48 -1
- fb_tools-2.8.0/test/test_35_sockets.py +178 -0
- fb_tools-2.8.0/test/test_36_unixsocket.py +172 -0
- fb_tools-2.8.0/test/test_37_tcpsocket.py +151 -0
- fb_tools-2.6.3/locale/de/LC_MESSAGES/fb_tools.mo +0 -0
- fb_tools-2.6.3/locale/en/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/LICENSE +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/MANIFEST.in +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/README.md +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/argparse_actions.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/ddns/config.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/ddns/errors.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/mailaddress.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/pidfile.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools/spinner.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools.egg-info/dependency_links.txt +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools.egg-info/requires.txt +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/lib/fb_tools.egg-info/top_level.txt +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/setup.cfg +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/setup.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/call_script.sh +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/call_sleep.sh +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/do_sleep +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_00_errors.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_05_common.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_10_base_object.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_13_colcts.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_17_multicfg.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_18_pidfile.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_25_ddns_update_status.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_30_base_handler.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_33_lock.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_40_app_modules.py +0 -0
- {fb_tools-2.6.3 → fb_tools-2.8.0}/test/test_50_spinner.py +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: Print a newline separated list of files generated from file globbing patterns.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import print_function
|
|
@@ -58,8 +58,8 @@ from fb_tools.xlate import XLATOR
|
|
|
58
58
|
|
|
59
59
|
_ = XLATOR.gettext
|
|
60
60
|
|
|
61
|
-
__author__ = 'Frank Brehm <frank
|
|
62
|
-
__copyright__ = '(C) 2024 by Frank Brehm,
|
|
61
|
+
__author__ = 'Frank Brehm <frank@brehm-online.com>'
|
|
62
|
+
__copyright__ = '(C) 2024 by Frank Brehm, Berlin'
|
|
63
63
|
|
|
64
64
|
appname = my_path.name
|
|
65
65
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: Prints the public NAT IPv4 address and/or the automatic assigned IPv6 address.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import print_function
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
@summary: Print a newline separated list of files generated from file globbing patterns.
|
|
5
|
+
|
|
6
|
+
@author: Frank Brehm
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
|
+
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import print_function
|
|
11
|
+
|
|
12
|
+
# Standard modules
|
|
13
|
+
import locale
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
except ImportError:
|
|
19
|
+
from pathlib2 import Path
|
|
20
|
+
|
|
21
|
+
__exp_py_version_major__ = 3
|
|
22
|
+
__min_py_version_minor__ = 6
|
|
23
|
+
|
|
24
|
+
if sys.version_info[0] != __exp_py_version_major__:
|
|
25
|
+
print('This script is intended to use with Python {}.'.format(
|
|
26
|
+
__exp_py_version_major__), file=sys.stderr)
|
|
27
|
+
print('You are using Python: {0}.{1}.{2}-{3}-{4}.'.format(
|
|
28
|
+
*sys.version_info) + '\n', file=sys.stderr)
|
|
29
|
+
sys.exit(1)
|
|
30
|
+
|
|
31
|
+
if sys.version_info[1] < __min_py_version_minor__:
|
|
32
|
+
print('A minimal Python version of {maj}.{min} is necessary to execute this script.'.format(
|
|
33
|
+
maj=__exp_py_version_major__, min=__min_py_version_minor__), file=sys.stderr)
|
|
34
|
+
print('You are using Python: {0}.{1}.{2}-{3}-{4}.'.format(
|
|
35
|
+
*sys.version_info) + '\n', file=sys.stderr)
|
|
36
|
+
sys.exit(1)
|
|
37
|
+
|
|
38
|
+
my_path = Path(__file__)
|
|
39
|
+
my_real_path = my_path.resolve()
|
|
40
|
+
bin_path = my_real_path.parent
|
|
41
|
+
base_dir = bin_path.parent
|
|
42
|
+
lib_dir = base_dir.joinpath('lib')
|
|
43
|
+
module_dir = lib_dir.joinpath('fb_tools')
|
|
44
|
+
|
|
45
|
+
# print("My path: {!r}".format(str(my_path)))
|
|
46
|
+
# print("My real path: {!r}".format(str(my_real_path)))
|
|
47
|
+
# print("Bin path: {!r}".format(str(bin_path)))
|
|
48
|
+
# print("Base dir: {!r}".format(str(base_dir)))
|
|
49
|
+
# print("Lib dir: {!r}".format(str(lib_dir)))
|
|
50
|
+
# print("Module dir: {!r}".format(str(module_dir)))
|
|
51
|
+
|
|
52
|
+
if module_dir.exists():
|
|
53
|
+
sys.path.insert(0, str(lib_dir))
|
|
54
|
+
|
|
55
|
+
# own modules:
|
|
56
|
+
from fb_tools.show_spinner_app import ShowSpinnerApplication
|
|
57
|
+
from fb_tools.xlate import XLATOR
|
|
58
|
+
|
|
59
|
+
_ = XLATOR.gettext
|
|
60
|
+
|
|
61
|
+
__author__ = 'Frank Brehm <frank@brehm-online.com>'
|
|
62
|
+
__copyright__ = '(C) 2024 by Frank Brehm, Berlin'
|
|
63
|
+
|
|
64
|
+
appname = my_path.name
|
|
65
|
+
|
|
66
|
+
locale.setlocale(locale.LC_ALL, '')
|
|
67
|
+
|
|
68
|
+
app = ShowSpinnerApplication(appname=appname, base_dir=base_dir)
|
|
69
|
+
app.initialized = True
|
|
70
|
+
|
|
71
|
+
if app.verbose > 2:
|
|
72
|
+
print(_('{c}-Object:\n{a}').format(c=app.__class__.__name__, a=app), file=sys.stderr)
|
|
73
|
+
|
|
74
|
+
app()
|
|
75
|
+
|
|
76
|
+
sys.exit(0)
|
|
77
|
+
|
|
78
|
+
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: Update the A and/or AAAA record at ddns.de with the current IP address.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import print_function
|
|
@@ -13,6 +13,7 @@ UTF8_ENCODING = 'utf-8'
|
|
|
13
13
|
|
|
14
14
|
DDNS_CFG_BASENAME = 'ddns.ini'
|
|
15
15
|
MAX_TIMEOUT = 3600
|
|
16
|
+
MAX_PORT_NUMBER = (2 ** 16) - 1
|
|
16
17
|
DEFAULT_ENCODING = UTF8_ENCODING
|
|
17
18
|
DEFAULT_TERMINAL_WIDTH = 99
|
|
18
19
|
DEFAULT_TERMINAL_HEIGHT = 40
|
|
@@ -22,6 +23,6 @@ DEFAULT_TERMINAL_HEIGHT = 40
|
|
|
22
23
|
from .mailaddress import MailAddress, MailAddressList, QualifiedMailAddress # noqa: F401
|
|
23
24
|
from .multi_config import BaseMultiConfig # noqa: F401
|
|
24
25
|
|
|
25
|
-
__version__ = '2.
|
|
26
|
+
__version__ = '2.8.0'
|
|
26
27
|
|
|
27
28
|
# vim: ts=4 et list
|
|
@@ -38,7 +38,7 @@ from .xlate import __lib_dir__ as __xlate_lib_dir__
|
|
|
38
38
|
from .xlate import __mo_file__ as __xlate_mo_file__
|
|
39
39
|
from .xlate import __module_dir__ as __xlate_module_dir__
|
|
40
40
|
|
|
41
|
-
__version__ = '2.
|
|
41
|
+
__version__ = '2.3.0'
|
|
42
42
|
LOG = logging.getLogger(__name__)
|
|
43
43
|
|
|
44
44
|
SIGNAL_NAMES = {
|
|
@@ -57,7 +57,40 @@ _ = XLATOR.gettext
|
|
|
57
57
|
|
|
58
58
|
# =============================================================================
|
|
59
59
|
class BaseApplication(HandlingObject):
|
|
60
|
-
"""
|
|
60
|
+
"""
|
|
61
|
+
Class for the base application objects.
|
|
62
|
+
|
|
63
|
+
Properties:
|
|
64
|
+
* address_family (str or int - rw) (inherited from HandlingObject)
|
|
65
|
+
* appname (str - rw) (inherited from FbBaseObject)
|
|
66
|
+
* argparse_epilog (None or str - ro)
|
|
67
|
+
* argparse_prefix_chars (str - ro)
|
|
68
|
+
* assumed_answer (None or bool - rw) (inherited from HandlingObject)
|
|
69
|
+
* base_dir (pathlib.Path - rw) (inherited from FbBaseObject)
|
|
70
|
+
* description (str - ro)
|
|
71
|
+
* exit_value (int - rw)
|
|
72
|
+
* exitvalue (int - rw)
|
|
73
|
+
* force (bool - rw) (inherited from HandlingObject)
|
|
74
|
+
* force_desc_msg (None or str - ro)
|
|
75
|
+
* initialized (bool - rw) (inherited from FbBaseObject)
|
|
76
|
+
* interrupted (bool - rw) (inherited from HandlingObject)
|
|
77
|
+
* is_venv (bool - ro) (inherited from HandlingObject)
|
|
78
|
+
* prompt_timeout (int - rw) (inherited from HandlingObject)
|
|
79
|
+
* quiet (bool - rw) (inherited from HandlingObject)
|
|
80
|
+
* simulate (bool - rw) (inherited from HandlingObject)
|
|
81
|
+
* testing_args (array od str - ro)
|
|
82
|
+
* usage (str - ro)
|
|
83
|
+
* usage_term None or int - ro)
|
|
84
|
+
* verbose (int - rw) (inherited from FbBaseObject)
|
|
85
|
+
* version (str - ro) (inherited from FbBaseObject)
|
|
86
|
+
|
|
87
|
+
Public attributes:
|
|
88
|
+
* add_search_paths Array of pathlib.Path (inherited from HandlingObject)
|
|
89
|
+
* arg_parser argparse.ArgumentParser
|
|
90
|
+
* args Namespace
|
|
91
|
+
* env Dict
|
|
92
|
+
* signals_dont_interrupt Array of int (inherited from HandlingObject)
|
|
93
|
+
"""
|
|
61
94
|
|
|
62
95
|
re_prefix = re.compile(r'^[a-z0-9][a-z0-9_]*$', re.IGNORECASE)
|
|
63
96
|
re_anum = re.compile(r'[^A-Z0-9_]+', re.IGNORECASE)
|
|
@@ -77,72 +110,77 @@ class BaseApplication(HandlingObject):
|
|
|
77
110
|
self, version=__pkg_version__, usage=None, description=None, testing_args=None,
|
|
78
111
|
argparse_epilog=None, argparse_prefix_chars='-', env_prefix=None,
|
|
79
112
|
initialized=None, *args, **kwargs):
|
|
80
|
-
"""Initialise a BaseApplication object."""
|
|
81
|
-
self.arg_parser = None
|
|
82
|
-
"""
|
|
83
|
-
@ivar: argparser object to parse commandline parameters
|
|
84
|
-
@type: argparse.ArgumentParser
|
|
85
|
-
"""
|
|
86
|
-
|
|
87
|
-
self.args = None
|
|
88
|
-
"""
|
|
89
|
-
@ivar: an object containing all commandline parameters
|
|
90
|
-
after parsing them
|
|
91
|
-
@type: Namespace
|
|
92
113
|
"""
|
|
114
|
+
Initialise a BaseApplication object.
|
|
93
115
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
@
|
|
116
|
+
@param appname: name of the current running application
|
|
117
|
+
@type: str
|
|
118
|
+
@param argparse_epilog: an epilog displayed at the end of the argparse help screen
|
|
119
|
+
@type: str
|
|
120
|
+
@param argparse_prefix_chars: The set of characters that prefix optional arguments.
|
|
121
|
+
@type: str
|
|
122
|
+
@param assumed_answer: The assumed answer to all yes/no questions
|
|
123
|
+
@type: bool or None
|
|
124
|
+
@param base_dir: base directory used for different purposes
|
|
125
|
+
@type: str or pathlib.Path
|
|
126
|
+
@param description: a short text describing the application
|
|
127
|
+
@type: str
|
|
128
|
+
@param env_prefix: a prefix for environment variables to detect them and to assign
|
|
129
|
+
@type: None or str
|
|
130
|
+
@param force: Forced execution of something
|
|
131
|
+
@type: bool
|
|
132
|
+
@param initialized: initialisation of this object is complete after init
|
|
133
|
+
@type: bool
|
|
134
|
+
@param quiet: Quiet execution
|
|
135
|
+
@type: bool
|
|
136
|
+
@param simulate: actions with changing a state are not executed
|
|
137
|
+
@type: bool
|
|
138
|
+
@param terminal_has_colors: has the current terminal colored output
|
|
139
|
+
@type: bool
|
|
140
|
+
@param testing_args: Command line arguments to use for testing purposes.
|
|
141
|
+
@type: None or list of strings
|
|
142
|
+
@param verbose: verbosity level (0 - 9)
|
|
97
143
|
@type: int
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
self._usage = usage
|
|
101
|
-
"""
|
|
102
|
-
@ivar: usage text used on argparse
|
|
144
|
+
@type: usage: usage text used on argparse
|
|
103
145
|
@type: str
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
self._description = description
|
|
107
|
-
"""
|
|
108
|
-
@ivar: a short text describing the application
|
|
146
|
+
@param version: version string of the current object or application
|
|
109
147
|
@type: str
|
|
110
148
|
"""
|
|
111
|
-
|
|
149
|
+
self._usage = usage
|
|
150
|
+
self._description = description
|
|
112
151
|
self._testing_args = testing_args
|
|
152
|
+
self._argparse_epilog = argparse_epilog
|
|
153
|
+
self._argparse_prefix_chars = argparse_prefix_chars
|
|
154
|
+
self._env_prefix = None
|
|
155
|
+
|
|
156
|
+
self._exit_value = 0
|
|
113
157
|
"""
|
|
114
|
-
@ivar:
|
|
115
|
-
@type:
|
|
158
|
+
@ivar: return value of the application for exiting with sys.exit().
|
|
159
|
+
@type: int
|
|
116
160
|
"""
|
|
117
161
|
|
|
118
|
-
self.
|
|
162
|
+
self.arg_parser = None
|
|
119
163
|
"""
|
|
120
|
-
@ivar:
|
|
121
|
-
@type:
|
|
164
|
+
@ivar: argparser object to parse commandline parameters
|
|
165
|
+
@type: argparse.ArgumentParser
|
|
122
166
|
"""
|
|
123
167
|
|
|
124
|
-
self.
|
|
168
|
+
self.args = None
|
|
125
169
|
"""
|
|
126
|
-
@ivar:
|
|
127
|
-
|
|
170
|
+
@ivar: an object containing all commandline parameters
|
|
171
|
+
after parsing them
|
|
172
|
+
@type: Namespace
|
|
128
173
|
"""
|
|
129
174
|
|
|
130
175
|
self.env = {}
|
|
131
176
|
"""
|
|
132
|
-
@ivar: a dictionary with all application
|
|
177
|
+
@ivar: a dictionary with all application specific environment variables,
|
|
133
178
|
they will detected by the env_prefix property of this object,
|
|
134
179
|
and their names will transformed before saving their values in
|
|
135
180
|
self.env by removing the env_prefix from the variable name.
|
|
136
181
|
@type: dict
|
|
137
182
|
"""
|
|
138
183
|
|
|
139
|
-
self._env_prefix = None
|
|
140
|
-
"""
|
|
141
|
-
@ivar: a prefix for environment variables to detect them and to assign
|
|
142
|
-
their transformed names and their values in self.env
|
|
143
|
-
@type: str
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
184
|
super(BaseApplication, self).__init__(
|
|
147
185
|
version=version,
|
|
148
186
|
initialized=False,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: The module for the application object with support for configuration files.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import absolute_import
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
They are providing alternatives to Python's general purpose built-in frozen_set, set and dict.
|
|
7
7
|
|
|
8
8
|
@author: Frank Brehm
|
|
9
|
-
@contact: frank
|
|
9
|
+
@contact: frank@brehm-online.com
|
|
10
10
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
11
11
|
"""
|
|
12
12
|
from __future__ import absolute_import
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
They are providing alternatives to Python's general purpose built-in frozen_set, set and dict.
|
|
7
7
|
|
|
8
8
|
@author: Frank Brehm
|
|
9
|
-
@contact: frank
|
|
9
|
+
@contact: frank@brehm-online.com
|
|
10
10
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
11
11
|
"""
|
|
12
12
|
from __future__ import absolute_import
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: The module for common used functions.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
|
|
@@ -37,7 +37,7 @@ import six
|
|
|
37
37
|
from .errors import InvalidTimeIntervalError
|
|
38
38
|
from .xlate import XLATOR
|
|
39
39
|
|
|
40
|
-
__version__ = '2.1.
|
|
40
|
+
__version__ = '2.1.1'
|
|
41
41
|
|
|
42
42
|
_ = XLATOR.gettext
|
|
43
43
|
|
|
@@ -64,6 +64,8 @@ RE_FQDN = re.compile(
|
|
|
64
64
|
r'(?=^.{4,253}$)(^((?!-)[a-z0-9-]{1,63}(?<!-)\.)+[a-z]{2,63}\.?$)',
|
|
65
65
|
re.IGNORECASE)
|
|
66
66
|
|
|
67
|
+
RE_FIRST_LINE = re.compile(r'^([^\n]*)(\r?\n)')
|
|
68
|
+
|
|
67
69
|
CUR_RADIX = locale.nl_langinfo(locale.RADIXCHAR)
|
|
68
70
|
CUR_THOUSEP = locale.nl_langinfo(locale.THOUSEP)
|
|
69
71
|
H2MB_PAT = r'^\s*\+?(\d+(?:' + re.escape(CUR_THOUSEP) + r'\d+)*(?:'
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: The base module for all DDNS related classes.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import absolute_import, print_function
|
|
@@ -46,10 +46,11 @@ from .. import __version__ as GLOBAL_VERSION
|
|
|
46
46
|
from ..argparse_actions import DirectoryOptionAction
|
|
47
47
|
from ..cfg_app import FbConfigApplication
|
|
48
48
|
from ..common import pp
|
|
49
|
+
from ..common import to_bool
|
|
49
50
|
from ..errors import IoTimeoutError
|
|
50
51
|
from ..xlate import XLATOR, format_list
|
|
51
52
|
|
|
52
|
-
__version__ = '2.
|
|
53
|
+
__version__ = '2.3.0'
|
|
53
54
|
LOG = logging.getLogger(__name__)
|
|
54
55
|
|
|
55
56
|
_ = XLATOR.gettext
|
|
@@ -65,6 +66,8 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
65
66
|
work_directory_must_exists = False
|
|
66
67
|
work_directory_must_be_writeable = False
|
|
67
68
|
|
|
69
|
+
default_verify_server_cert = True
|
|
70
|
+
|
|
68
71
|
# -------------------------------------------------------------------------
|
|
69
72
|
def __init__(
|
|
70
73
|
self, appname=None, verbose=0, version=GLOBAL_VERSION, base_dir=None,
|
|
@@ -76,6 +79,7 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
76
79
|
description = _('This is a base DDNS related application.')
|
|
77
80
|
|
|
78
81
|
self._user_agent = '{}/{}'.format(self.library_name, GLOBAL_VERSION)
|
|
82
|
+
self._verify_server_cert = self.default_verify_server_cert
|
|
79
83
|
|
|
80
84
|
super(BaseDdnsApplication, self).__init__(
|
|
81
85
|
appname=appname, verbose=verbose, version=version, base_dir=base_dir,
|
|
@@ -99,6 +103,19 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
99
103
|
raise DdnsAppError(_('Invalid user agent {!r} given.').format(value))
|
|
100
104
|
self._user_agent = str(value).strip()
|
|
101
105
|
|
|
106
|
+
# -----------------------------------------------------------
|
|
107
|
+
@property
|
|
108
|
+
def verify_server_cert(self):
|
|
109
|
+
"""Return whether to verify the SSL certificate of the requested server."""
|
|
110
|
+
return self._verify_server_cert
|
|
111
|
+
|
|
112
|
+
@verify_server_cert.setter
|
|
113
|
+
def verify_server_cert(self, value):
|
|
114
|
+
if value is None:
|
|
115
|
+
self._verify_server_cert = self.default_verify_server_cert
|
|
116
|
+
return
|
|
117
|
+
self._verify_server_cert = to_bool(value)
|
|
118
|
+
|
|
102
119
|
# -------------------------------------------------------------------------
|
|
103
120
|
@property
|
|
104
121
|
def has_dns_module(self):
|
|
@@ -119,6 +136,7 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
119
136
|
res = super(BaseDdnsApplication, self).as_dict(short=short)
|
|
120
137
|
res['has_dns_module'] = self.has_dns_module
|
|
121
138
|
res['user_agent'] = self.user_agent
|
|
139
|
+
res['verify_server_cert'] = self.verify_server_cert
|
|
122
140
|
|
|
123
141
|
return res
|
|
124
142
|
|
|
@@ -176,6 +194,14 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
176
194
|
DdnsConfiguration.default_timeout),
|
|
177
195
|
)
|
|
178
196
|
|
|
197
|
+
ddns_group.add_argument(
|
|
198
|
+
'-k', '--insecure', dest='insecure', action='store_true',
|
|
199
|
+
help=_(
|
|
200
|
+
'By default, every secure connection {app} makes is verified to be secure before '
|
|
201
|
+
'the request takes place. This option makes {app} skip the verification step and '
|
|
202
|
+
'proceed without checking.').format(app=self.appname),
|
|
203
|
+
)
|
|
204
|
+
|
|
179
205
|
super(BaseDdnsApplication, self).init_arg_parser()
|
|
180
206
|
|
|
181
207
|
# -------------------------------------------------------------------------
|
|
@@ -225,6 +251,9 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
225
251
|
logging.getLogger('requests').setLevel(logging.WARNING)
|
|
226
252
|
self.loglevel_requests_set = True
|
|
227
253
|
|
|
254
|
+
if self.args.insecure:
|
|
255
|
+
self.verify_server_cert = False
|
|
256
|
+
|
|
228
257
|
self.initialized = True
|
|
229
258
|
|
|
230
259
|
# -------------------------------------------------------------------------
|
|
@@ -251,6 +280,15 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
251
280
|
self, url, method='GET', data=None, headers=None, may_simulate=False,
|
|
252
281
|
return_json=True):
|
|
253
282
|
"""Perform the underlying Web request."""
|
|
283
|
+
verify = None
|
|
284
|
+
if url.startswith('https://'):
|
|
285
|
+
if self.verify_server_cert:
|
|
286
|
+
verify = True
|
|
287
|
+
else:
|
|
288
|
+
verify = False
|
|
289
|
+
urllib3.disable_warnings()
|
|
290
|
+
LOG.debug(f'Verifying remote server certificate: {verify!r}.')
|
|
291
|
+
|
|
254
292
|
if headers is None:
|
|
255
293
|
headers = {}
|
|
256
294
|
|
|
@@ -282,7 +320,7 @@ class BaseDdnsApplication(FbConfigApplication):
|
|
|
282
320
|
|
|
283
321
|
session = requests.Session()
|
|
284
322
|
response = session.request(
|
|
285
|
-
method, url, data=data, headers=headers, timeout=self.cfg.timeout)
|
|
323
|
+
method, url, data=data, headers=headers, timeout=self.cfg.timeout, verify=verify)
|
|
286
324
|
|
|
287
325
|
except (
|
|
288
326
|
socket.timeout, urllib3.exceptions.ConnectTimeoutError,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: The module for the classes of the myip application.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import absolute_import, print_function
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: The module for the classes of the update-ddns application.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import absolute_import, print_function
|
|
@@ -14,7 +14,7 @@ import signal
|
|
|
14
14
|
# Own modules
|
|
15
15
|
from .xlate import XLATOR
|
|
16
16
|
|
|
17
|
-
__version__ = '2.
|
|
17
|
+
__version__ = '2.5.1'
|
|
18
18
|
|
|
19
19
|
_ = XLATOR.gettext
|
|
20
20
|
ngettext = XLATOR.ngettext
|
|
@@ -150,6 +150,13 @@ class AbortAppError(FbAppError):
|
|
|
150
150
|
pass
|
|
151
151
|
|
|
152
152
|
|
|
153
|
+
# =============================================================================
|
|
154
|
+
class ExitAppError(FbAppError):
|
|
155
|
+
"""Special exception class exiting the application."""
|
|
156
|
+
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
|
|
153
160
|
# =============================================================================
|
|
154
161
|
class FbCfgAppError(FbAppError):
|
|
155
162
|
"""Generic exception class for all configured application classes."""
|
|
@@ -572,6 +579,55 @@ class FileAccessError(CommonFileError, PermissionError):
|
|
|
572
579
|
return msg
|
|
573
580
|
|
|
574
581
|
|
|
582
|
+
# =============================================================================
|
|
583
|
+
class GenericSocketError(FbError):
|
|
584
|
+
"""Base error class for all special exceptions raised in a socket module."""
|
|
585
|
+
|
|
586
|
+
pass
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
# =============================================================================
|
|
590
|
+
class SocketReadTimeoutError(IoTimeoutError, GenericSocketError):
|
|
591
|
+
"""Special error class indicating a timout error on a read operation on a socket."""
|
|
592
|
+
|
|
593
|
+
# -------------------------------------------------------------------------
|
|
594
|
+
def __init__(self, timeout, filename=None):
|
|
595
|
+
"""
|
|
596
|
+
Initialise an SocketReadTimeoutError exception.
|
|
597
|
+
|
|
598
|
+
@param timeout: the timout in seconds leading to the error
|
|
599
|
+
@type timeout: float
|
|
600
|
+
@param filename: the filename of the socket leading to the error
|
|
601
|
+
@type filename: str
|
|
602
|
+
"""
|
|
603
|
+
strerror = _('Timeout error on reading from socket')
|
|
604
|
+
fn = None
|
|
605
|
+
if filename is not None:
|
|
606
|
+
fn = str(filename)
|
|
607
|
+
super(SocketReadTimeoutError, self).__init__(strerror, timeout, fn)
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
# =============================================================================
|
|
611
|
+
class SocketWriteTimeoutError(IoTimeoutError, GenericSocketError):
|
|
612
|
+
"""Special error class indicating a timout error on a write operation on a socket."""
|
|
613
|
+
|
|
614
|
+
# -------------------------------------------------------------------------
|
|
615
|
+
def __init__(self, timeout, filename=None):
|
|
616
|
+
"""
|
|
617
|
+
Initialise an SocketWriteTimeoutError exception.
|
|
618
|
+
|
|
619
|
+
@param timeout: the timout in seconds leading to the error
|
|
620
|
+
@type timeout: float
|
|
621
|
+
@param filename: the filename of the socket leading to the error
|
|
622
|
+
@type filename: str
|
|
623
|
+
"""
|
|
624
|
+
strerror = _('Timeout error on writing to socket')
|
|
625
|
+
fn = None
|
|
626
|
+
if filename is not None:
|
|
627
|
+
fn = str(filename)
|
|
628
|
+
super(SocketWriteTimeoutError, self).__init__(strerror, timeout, fn)
|
|
629
|
+
|
|
630
|
+
|
|
575
631
|
# =============================================================================
|
|
576
632
|
|
|
577
633
|
if __name__ == '__main__':
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@summary: Module for a extended handler module, which has additional methods for locking.
|
|
5
5
|
|
|
6
6
|
@author: Frank Brehm
|
|
7
|
-
@contact: frank
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
8
|
@copyright: © 2024 by Frank Brehm, Berlin
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import absolute_import
|