fb-tools 2.4.2__tar.gz → 2.5.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.4.2/lib/fb_tools.egg-info → fb_tools-2.5.0}/PKG-INFO +1 -1
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/__init__.py +3 -1
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/app.py +26 -17
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/cfg_app.py +28 -19
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/common.py +131 -2
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/ddns/__init__.py +190 -162
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/ddns/config.py +137 -83
- fb_tools-2.5.0/lib/fb_tools/ddns/errors.py +139 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/ddns/myip_app.py +7 -6
- fb_tools-2.5.0/lib/fb_tools/ddns/update_app.py +791 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/errors.py +170 -1
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/handling_obj.py +63 -18
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/local_version.py +1 -1
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/multi_config/__init__.py +4 -2
- {fb_tools-2.4.2 → fb_tools-2.5.0/lib/fb_tools.egg-info}/PKG-INFO +1 -1
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools.egg-info/SOURCES.txt +2 -0
- fb_tools-2.5.0/locale/de/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/locale/de/LC_MESSAGES/fb_tools.po +456 -286
- fb_tools-2.5.0/locale/en/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/locale/en/LC_MESSAGES/fb_tools.po +445 -273
- {fb_tools-2.4.2 → fb_tools-2.5.0}/locale/fb_tools.pot +442 -270
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_00_errors.py +19 -6
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_05_common.py +82 -11
- fb_tools-2.5.0/test/test_25_ddns_update_status.py +210 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_40_app_modules.py +22 -1
- fb_tools-2.4.2/lib/fb_tools/ddns/update_app.py +0 -426
- fb_tools-2.4.2/locale/de/LC_MESSAGES/fb_tools.mo +0 -0
- fb_tools-2.4.2/locale/en/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/LICENSE +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/MANIFEST.in +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/README.md +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/bin/get-file-to-remove +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/bin/myip +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/bin/update-ddns +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/argparse_actions.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/collections.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/config.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/get_file_rm_app.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/handler/__init__.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/handler/lock.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/mailaddress.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/merge.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/multi_config/files.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/multi_config/inits.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/multi_config/read.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/obj.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/pidfile.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools/xlate.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools.egg-info/dependency_links.txt +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools.egg-info/requires.txt +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/lib/fb_tools.egg-info/top_level.txt +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/setup.cfg +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/setup.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/call_script.sh +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/call_sleep.sh +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/do_sleep +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/general.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_10_base_object.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_13_collections.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_15_mailaddress.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_17_multicfg.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_18_pidfile.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_20_handling_object.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_30_base_handler.py +0 -0
- {fb_tools-2.4.2 → fb_tools-2.5.0}/test/test_33_lock.py +0 -0
|
@@ -12,8 +12,10 @@ DDNS_CFG_BASENAME = 'ddns.ini'
|
|
|
12
12
|
MAX_TIMEOUT = 3600
|
|
13
13
|
UTF8_ENCODING = 'utf-8'
|
|
14
14
|
DEFAULT_ENCODING = UTF8_ENCODING
|
|
15
|
+
DEFAULT_TERMINAL_WIDTH = 99
|
|
16
|
+
DEFAULT_TERMINAL_HEIGHT = 40
|
|
15
17
|
|
|
16
|
-
__version__ = '2.
|
|
18
|
+
__version__ = '2.5.0'
|
|
17
19
|
|
|
18
20
|
from .mailaddress import MailAddress, QualifiedMailAddress, MailAddressList # noqa
|
|
19
21
|
from .multi_config import BaseMultiConfig # noqa
|
|
@@ -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.2.
|
|
41
|
+
__version__ = '2.2.2'
|
|
42
42
|
LOG = logging.getLogger(__name__)
|
|
43
43
|
|
|
44
44
|
SIGNAL_NAMES = {
|
|
@@ -353,6 +353,30 @@ class BaseApplication(HandlingObject):
|
|
|
353
353
|
|
|
354
354
|
return res
|
|
355
355
|
|
|
356
|
+
# -------------------------------------------------------------------------
|
|
357
|
+
def _get_log_formatter(self, is_term=True):
|
|
358
|
+
|
|
359
|
+
# create formatter
|
|
360
|
+
if is_term:
|
|
361
|
+
format_str = ''
|
|
362
|
+
if self.verbose > 1:
|
|
363
|
+
format_str = '[%(asctime)s]: '
|
|
364
|
+
format_str += self.appname + ': '
|
|
365
|
+
else:
|
|
366
|
+
format_str = '[%(asctime)s]: ' + self.appname + ': '
|
|
367
|
+
if self.verbose:
|
|
368
|
+
if self.verbose > 1:
|
|
369
|
+
format_str += '%(name)s(%(lineno)d) %(funcName)s() '
|
|
370
|
+
else:
|
|
371
|
+
format_str += '%(name)s '
|
|
372
|
+
format_str += '%(levelname)s - %(message)s'
|
|
373
|
+
if is_term and self.terminal_has_colors:
|
|
374
|
+
formatter = ColoredFormatter(format_str)
|
|
375
|
+
else:
|
|
376
|
+
formatter = logging.Formatter(format_str)
|
|
377
|
+
|
|
378
|
+
return formatter
|
|
379
|
+
|
|
356
380
|
# -------------------------------------------------------------------------
|
|
357
381
|
def init_logging(self):
|
|
358
382
|
"""
|
|
@@ -376,22 +400,7 @@ class BaseApplication(HandlingObject):
|
|
|
376
400
|
root_logger = logging.getLogger()
|
|
377
401
|
root_logger.setLevel(root_loglevel)
|
|
378
402
|
|
|
379
|
-
|
|
380
|
-
format_str = ''
|
|
381
|
-
if self.verbose:
|
|
382
|
-
format_str = '[%(asctime)s]: '
|
|
383
|
-
format_str += self.appname + ': '
|
|
384
|
-
if self.verbose:
|
|
385
|
-
if self.verbose > 1:
|
|
386
|
-
format_str += '%(name)s(%(lineno)d) %(funcName)s() '
|
|
387
|
-
else:
|
|
388
|
-
format_str += '%(name)s '
|
|
389
|
-
format_str += '%(levelname)s - %(message)s'
|
|
390
|
-
formatter = None
|
|
391
|
-
if self.terminal_has_colors:
|
|
392
|
-
formatter = ColoredFormatter(format_str)
|
|
393
|
-
else:
|
|
394
|
-
formatter = logging.Formatter(format_str)
|
|
403
|
+
formatter = self._get_log_formatter()
|
|
395
404
|
|
|
396
405
|
# create log handler for console output
|
|
397
406
|
lh_console = logging.StreamHandler(sys.stderr)
|
|
@@ -27,11 +27,17 @@ from .argparse_actions import CfgFileOptionAction
|
|
|
27
27
|
from .argparse_actions import LogFileOptionAction
|
|
28
28
|
# from .error import FbCfgAppError
|
|
29
29
|
from .common import pp, to_bool
|
|
30
|
+
from .errors import CommonPathError
|
|
31
|
+
from .errors import DirectoryAccessError
|
|
32
|
+
from .errors import DirectoryNotDirError
|
|
33
|
+
from .errors import DirectoryNotExistsError
|
|
34
|
+
from .errors import FileAccessError
|
|
35
|
+
from .errors import FileNotRegularFileError
|
|
30
36
|
from .errors import MultiConfigError
|
|
31
37
|
from .multi_config import BaseMultiConfig
|
|
32
38
|
from .xlate import XLATOR
|
|
33
39
|
|
|
34
|
-
__version__ = '2.
|
|
40
|
+
__version__ = '2.3.1'
|
|
35
41
|
LOG = logging.getLogger(__name__)
|
|
36
42
|
|
|
37
43
|
|
|
@@ -42,6 +48,8 @@ _ = XLATOR.gettext
|
|
|
42
48
|
class FbConfigApplication(BaseApplication):
|
|
43
49
|
"""Class for configured application objects."""
|
|
44
50
|
|
|
51
|
+
default_logfile = None
|
|
52
|
+
|
|
45
53
|
# -------------------------------------------------------------------------
|
|
46
54
|
def __init__(
|
|
47
55
|
self, version=__pkg_version__, cfg_class=BaseMultiConfig, initialized=False,
|
|
@@ -58,7 +66,7 @@ class FbConfigApplication(BaseApplication):
|
|
|
58
66
|
self._use_chardet = True
|
|
59
67
|
self.use_chardet = use_chardet
|
|
60
68
|
self._additional_cfg_file = None
|
|
61
|
-
self._logfile =
|
|
69
|
+
self._logfile = self.default_logfile
|
|
62
70
|
self._cfg_class = cfg_class
|
|
63
71
|
self._append_appname_to_stems = append_appname_to_stems
|
|
64
72
|
self._config_dir = config_dir
|
|
@@ -139,10 +147,14 @@ class FbConfigApplication(BaseApplication):
|
|
|
139
147
|
help=_('Configuration files to use additional to the standard configuration files.'),
|
|
140
148
|
)
|
|
141
149
|
|
|
150
|
+
help_txt = _('A logfile for storing all logging output.')
|
|
151
|
+
if self.default_logfile:
|
|
152
|
+
help_txt += ' ' + _('Default: {!r}.').format(str(self.default_logfile))
|
|
153
|
+
|
|
142
154
|
cfg_options.add_argument(
|
|
143
155
|
'--logfile', '--log',
|
|
144
156
|
metavar=_('FILE'), dest='logfile', action=LogFileOptionAction,
|
|
145
|
-
help=
|
|
157
|
+
help=help_txt,
|
|
146
158
|
)
|
|
147
159
|
|
|
148
160
|
# -------------------------------------------------------------------------
|
|
@@ -201,7 +213,11 @@ class FbConfigApplication(BaseApplication):
|
|
|
201
213
|
self.logfile = self.cfg.logfile.resolve()
|
|
202
214
|
|
|
203
215
|
if self.logfile:
|
|
204
|
-
|
|
216
|
+
try:
|
|
217
|
+
self.init_file_logging()
|
|
218
|
+
except CommonPathError as e:
|
|
219
|
+
LOG.error(_('Got a {c}: {e}.').format(c=e.__class__.__name__, e=e))
|
|
220
|
+
self.exit(8)
|
|
205
221
|
|
|
206
222
|
# -------------------------------------------------------------------------
|
|
207
223
|
def init_file_logging(self):
|
|
@@ -209,33 +225,26 @@ class FbConfigApplication(BaseApplication):
|
|
|
209
225
|
if not self.logfile:
|
|
210
226
|
return
|
|
211
227
|
|
|
228
|
+
if not self.do_init_logging:
|
|
229
|
+
return
|
|
230
|
+
|
|
212
231
|
logdir = self.logfile.parent
|
|
213
232
|
|
|
214
233
|
# Checking the parent directory of the Logfile
|
|
215
234
|
if not logdir.exists():
|
|
216
|
-
|
|
217
|
-
LOG.error(msg)
|
|
218
|
-
self.exit(6)
|
|
235
|
+
raise DirectoryNotExistsError(logdir)
|
|
219
236
|
if not logdir.is_dir():
|
|
220
|
-
|
|
221
|
-
LOG.error(msg)
|
|
222
|
-
self.exit(6)
|
|
237
|
+
raise DirectoryNotDirError(logdir)
|
|
223
238
|
|
|
224
239
|
# Checking logfile, if it is already existing
|
|
225
240
|
if self.logfile.exists():
|
|
226
241
|
if not self.logfile.is_file():
|
|
227
|
-
|
|
228
|
-
LOG.error(msg)
|
|
229
|
-
self.exit(6)
|
|
242
|
+
raise FileNotRegularFileError(self.logfile)
|
|
230
243
|
if not os.access(self.logfile, os.W_OK):
|
|
231
|
-
|
|
232
|
-
LOG.error(msg)
|
|
233
|
-
self.exit(6)
|
|
244
|
+
raise FileAccessError(self.logfile, _('file is not writeable.'))
|
|
234
245
|
else:
|
|
235
246
|
if not os.access(logdir, os.W_OK):
|
|
236
|
-
|
|
237
|
-
LOG.error(msg)
|
|
238
|
-
self.exit(6)
|
|
247
|
+
raise DirectoryAccessError(logdir, _('no write access to directory.'))
|
|
239
248
|
|
|
240
249
|
LOG.debug(_('Start logging into file {!r} ...').format(str(self.logfile)))
|
|
241
250
|
|
|
@@ -34,10 +34,10 @@ except ImportError:
|
|
|
34
34
|
import six
|
|
35
35
|
|
|
36
36
|
# Own modules
|
|
37
|
-
|
|
37
|
+
from .errors import InvalidTimeIntervalError
|
|
38
38
|
from .xlate import XLATOR
|
|
39
39
|
|
|
40
|
-
__version__ = '2.0
|
|
40
|
+
__version__ = '2.1.0'
|
|
41
41
|
|
|
42
42
|
_ = XLATOR.gettext
|
|
43
43
|
|
|
@@ -91,6 +91,18 @@ RE_UNIT_EIBYTES = re.compile(r'^\s*Ei(?:B(?:yte)?)?\s*$', re.IGNORECASE)
|
|
|
91
91
|
RE_UNIT_ZBYTES = re.compile(r'^\s*Z(?:B(?:yte)?)?\s*$', re.IGNORECASE)
|
|
92
92
|
RE_UNIT_ZIBYTES = re.compile(r'^\s*Zi(?:B(?:yte)?)?\s*$', re.IGNORECASE)
|
|
93
93
|
|
|
94
|
+
DEBUG_TIMEINTERVAL2DELTA = False
|
|
95
|
+
|
|
96
|
+
RE_UNIT_TIME_SECOND = re.compile(
|
|
97
|
+
r'\s*(\d+(?:\.\d*)?)\s*(?:s(?:ec(?:onds?)?)?)?(?:\s*,)?', re.IGNORECASE)
|
|
98
|
+
RE_UNIT_TIME_MINUTE = re.compile(
|
|
99
|
+
r'\s*(\d+(?:\.\d*)?)\s*m(?:in(?:utes?)?)?(?:\s*,)?', re.IGNORECASE)
|
|
100
|
+
RE_UNIT_TIME_HOUR = re.compile(r'\s*(\d+(?:\.\d*)?)\s*h(?:ours?)?(?:\s*,)?', re.IGNORECASE)
|
|
101
|
+
RE_UNIT_TIME_DAY = re.compile(r'\s*(\d+(?:\.\d*)?)\s*d(?:ays?)?(?:\s*,)?', re.IGNORECASE)
|
|
102
|
+
RE_UNIT_TIME_WEEK = re.compile(r'\s*(\d+(?:\.\d*)?)\s*w(?:eeks?)?(?:\s*,)?', re.IGNORECASE)
|
|
103
|
+
RE_UNIT_TIME_MONTH = re.compile(r'\s*(\d+(?:\.\d*)?)\s*mon(?:ths?)?(?:\s*,)?', re.IGNORECASE)
|
|
104
|
+
RE_UNIT_TIME_YEAR = re.compile(r'\s*(\d+(?:\.\d*)?)\s*y(?:ears?)?(?:\s*,)?', re.IGNORECASE)
|
|
105
|
+
|
|
94
106
|
|
|
95
107
|
# =============================================================================
|
|
96
108
|
def pp(value, indent=4, width=99, depth=None):
|
|
@@ -842,6 +854,123 @@ def indent(text, prefix, initial_prefix=None, predicate=None):
|
|
|
842
854
|
|
|
843
855
|
return ''.join(lines)
|
|
844
856
|
|
|
857
|
+
# =============================================================================
|
|
858
|
+
def set_debug_timeinterval2delta(enable_debug=False):
|
|
859
|
+
"""Set the module property DEBUG_TIMEINTERVAL2DELTA to a boolean value."""
|
|
860
|
+
global DEBUG_TIMEINTERVAL2DELTA
|
|
861
|
+
|
|
862
|
+
if to_bool(enable_debug):
|
|
863
|
+
DEBUG_TIMEINTERVAL2DELTA = True
|
|
864
|
+
else:
|
|
865
|
+
DEBUG_TIMEINTERVAL2DELTA = False
|
|
866
|
+
|
|
867
|
+
# =============================================================================
|
|
868
|
+
def timeinterval2delta(interval):
|
|
869
|
+
"""
|
|
870
|
+
Try to convert the given textual time interval into a datetime.timeinterval object.
|
|
871
|
+
|
|
872
|
+
The interval may consists of tokens of float values with a measurement unit.
|
|
873
|
+
If a token is a float value without a measurement unit, then seconds are assumed.
|
|
874
|
+
Valid measurement units (as regular expressions) are:
|
|
875
|
+
* 's(ec(onds?)?)?'
|
|
876
|
+
* 'm(in(utes?)?)?' == 60 seconds
|
|
877
|
+
* 'h(ours?)*' == 3600 seconds
|
|
878
|
+
* 'd(ays?)?' == 3600 * 24 seconds
|
|
879
|
+
* 'w(eeks?)?' == 3600 * 24 * 7 seconds
|
|
880
|
+
* 'mon(ths?)?' == 3600 * 24 * 30 seconds
|
|
881
|
+
* 'y(ears?)?' == 3600 * 24 * 365 seconds
|
|
882
|
+
|
|
883
|
+
@raise InvalidTimeIntervalError: if the interval could not be interpreted
|
|
884
|
+
"""
|
|
885
|
+
if interval is None:
|
|
886
|
+
raise InvalidTimeIntervalError(None)
|
|
887
|
+
intrvl = str(interval).strip()
|
|
888
|
+
if intrvl == '':
|
|
889
|
+
raise InvalidTimeIntervalError(interval)
|
|
890
|
+
|
|
891
|
+
seconds = 0
|
|
892
|
+
|
|
893
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
894
|
+
LOG.debug('Start value: {!r}'.format(intrvl))
|
|
895
|
+
|
|
896
|
+
m = RE_UNIT_TIME_YEAR.search(intrvl)
|
|
897
|
+
if m:
|
|
898
|
+
years = float(m[1])
|
|
899
|
+
intrvl = RE_UNIT_TIME_YEAR.sub('', intrvl, 1)
|
|
900
|
+
seconds += years * 3600 * 24 * 365
|
|
901
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
902
|
+
LOG.debug(
|
|
903
|
+
'After year: match {m!r}, years {y!r}, new value {i!r}, new secs {s}.'.format(
|
|
904
|
+
m=m[1], y=years, i=intrvl, s=seconds))
|
|
905
|
+
|
|
906
|
+
m = RE_UNIT_TIME_MONTH.search(intrvl)
|
|
907
|
+
if m:
|
|
908
|
+
months = float(m[1])
|
|
909
|
+
intrvl = RE_UNIT_TIME_MONTH.sub('', intrvl, 1)
|
|
910
|
+
seconds += months * 3600 * 24 * 30
|
|
911
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
912
|
+
LOG.debug(
|
|
913
|
+
'After months: match {m!r}, months {mo!r}, new value {i!r}, new secs {s}.'.format(
|
|
914
|
+
m=m[1], mo=months, i=intrvl, s=seconds))
|
|
915
|
+
|
|
916
|
+
m = RE_UNIT_TIME_WEEK.search(intrvl)
|
|
917
|
+
if m:
|
|
918
|
+
weeks = float(m[1])
|
|
919
|
+
intrvl = RE_UNIT_TIME_WEEK.sub('', intrvl, 1)
|
|
920
|
+
seconds += weeks * 3600 * 24 * 7
|
|
921
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
922
|
+
LOG.debug(
|
|
923
|
+
'After weeks: match {m!r}, weeks {w!r}, new value {i!r}, new secs {s}.'.format(
|
|
924
|
+
m=m[1], w=weeks, i=intrvl, s=seconds))
|
|
925
|
+
|
|
926
|
+
m = RE_UNIT_TIME_DAY.search(intrvl)
|
|
927
|
+
if m:
|
|
928
|
+
days = float(m[1])
|
|
929
|
+
intrvl = RE_UNIT_TIME_DAY.sub('', intrvl, 1)
|
|
930
|
+
seconds += days * 3600 * 24
|
|
931
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
932
|
+
LOG.debug(
|
|
933
|
+
'After days: match {m!r}, days {d!r}, new value {i!r}, new secs {s}.'.format(
|
|
934
|
+
m=m[1], d=days, i=intrvl, s=seconds))
|
|
935
|
+
|
|
936
|
+
m = RE_UNIT_TIME_HOUR.search(intrvl)
|
|
937
|
+
if m:
|
|
938
|
+
hours = float(m[1])
|
|
939
|
+
intrvl = RE_UNIT_TIME_HOUR.sub('', intrvl, 1)
|
|
940
|
+
seconds += hours * 3600
|
|
941
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
942
|
+
LOG.debug(
|
|
943
|
+
'After hours: match {m!r}, hours {h!r}, new value {i!r}, new secs {s}.'.format(
|
|
944
|
+
m=m[1], h=hours, i=intrvl, s=seconds))
|
|
945
|
+
|
|
946
|
+
m = RE_UNIT_TIME_MINUTE.search(intrvl)
|
|
947
|
+
if m:
|
|
948
|
+
minutes = float(m[1])
|
|
949
|
+
intrvl = RE_UNIT_TIME_MINUTE.sub('', intrvl, 1)
|
|
950
|
+
seconds += minutes * 60
|
|
951
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
952
|
+
LOG.debug(
|
|
953
|
+
'After minutes: match {m!r}, minutes {mi!r}, new value {i!r}, '
|
|
954
|
+
'new secs {s}.'.format(m=m[1], mi=minutes, i=intrvl, s=seconds))
|
|
955
|
+
|
|
956
|
+
m = RE_UNIT_TIME_SECOND.search(intrvl)
|
|
957
|
+
if m:
|
|
958
|
+
secs = float(m[1])
|
|
959
|
+
intrvl = RE_UNIT_TIME_SECOND.sub('', intrvl, 1)
|
|
960
|
+
seconds += secs
|
|
961
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
962
|
+
LOG.debug(
|
|
963
|
+
'After seconds: match {m!r}, seconds {se!r}, new value {i!r}, '
|
|
964
|
+
'new secs {s}.'.format(m=m[1], se=secs, i=intrvl, s=seconds))
|
|
965
|
+
|
|
966
|
+
intrvl = intrvl.strip()
|
|
967
|
+
if DEBUG_TIMEINTERVAL2DELTA:
|
|
968
|
+
LOG.debug('Final value: {i!r}, seconds at last: {s}'.format(i=intrvl, s=seconds))
|
|
969
|
+
if intrvl != '':
|
|
970
|
+
raise InvalidTimeIntervalError(interval)
|
|
971
|
+
|
|
972
|
+
return datetime.timedelta(seconds=seconds)
|
|
973
|
+
|
|
845
974
|
|
|
846
975
|
# =============================================================================
|
|
847
976
|
|