fb-tools 2.6.1__tar.gz → 2.6.2__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.1/lib/fb_tools.egg-info → fb_tools-2.6.2}/PKG-INFO +1 -1
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/__init__.py +1 -1
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/local_version.py +1 -1
- fb_tools-2.6.2/lib/fb_tools/spinner.py +587 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2/lib/fb_tools.egg-info}/PKG-INFO +1 -1
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools.egg-info/SOURCES.txt +3 -1
- fb_tools-2.6.2/test/test_50_spinner.py +126 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/LICENSE +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/MANIFEST.in +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/README.md +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/bin/get-file-to-remove +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/bin/myip +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/bin/update-ddns +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/app.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/argparse_actions.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/cfg_app.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/colcts.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/collections.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/common.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/config.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/ddns/__init__.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/ddns/config.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/ddns/errors.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/ddns/myip_app.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/ddns/update_app.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/errors.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/get_file_rm_app.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/handler/__init__.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/handler/lock.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/handling_obj.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/mailaddress.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/merge.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/multi_config/__init__.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/multi_config/files.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/multi_config/inits.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/multi_config/read.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/obj.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/pidfile.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools/xlate.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools.egg-info/dependency_links.txt +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools.egg-info/requires.txt +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/lib/fb_tools.egg-info/top_level.txt +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/locale/de/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/locale/de/LC_MESSAGES/fb_tools.po +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/locale/en/LC_MESSAGES/fb_tools.mo +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/locale/en/LC_MESSAGES/fb_tools.po +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/locale/fb_tools.pot +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/setup.cfg +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/setup.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/call_script.sh +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/call_sleep.sh +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/do_sleep +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/general.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_00_errors.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_05_common.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_10_base_object.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_13_colcts.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_15_mailaddress.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_17_multicfg.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_18_pidfile.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_20_handling_object.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_25_ddns_update_status.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_30_base_handler.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_33_lock.py +0 -0
- {fb_tools-2.6.1 → fb_tools-2.6.2}/test/test_40_app_modules.py +0 -0
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
__author__ = 'Frank Brehm <frank@brehm-online.com>'
|
|
12
12
|
__copyright__ = '(C) 2024 by Frank Brehm, Berlin'
|
|
13
13
|
__contact__ = 'frank@brehm-online.com'
|
|
14
|
-
__version__ = '2.6.
|
|
14
|
+
__version__ = '2.6.2'
|
|
15
15
|
__license__ = 'LGPL3+'
|
|
16
16
|
|
|
17
17
|
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
@summary: Module for for a Spinner class.
|
|
5
|
+
|
|
6
|
+
A Spinner object is displaying on console a rotating or somehow
|
|
7
|
+
other animated character during its existence.
|
|
8
|
+
|
|
9
|
+
This class was taken from https://github.com/Tagar/stuff
|
|
10
|
+
|
|
11
|
+
Example usage:
|
|
12
|
+
|
|
13
|
+
from fb_tools.spinner import Spinner
|
|
14
|
+
|
|
15
|
+
with Spinner("just waiting a bit.. "):
|
|
16
|
+
time.sleep(3)
|
|
17
|
+
|
|
18
|
+
@author: Frank Brehm
|
|
19
|
+
@contact: frank@brehm-online.com
|
|
20
|
+
@copyright: © 2024 by Frank Brehm, Berlin
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import itertools
|
|
24
|
+
import logging
|
|
25
|
+
import sys
|
|
26
|
+
import threading
|
|
27
|
+
import time
|
|
28
|
+
# from collections import namedtuple
|
|
29
|
+
|
|
30
|
+
# Own modules
|
|
31
|
+
# from .common import to_bytes
|
|
32
|
+
from .xlate import XLATOR
|
|
33
|
+
|
|
34
|
+
__version__ = '2.1.0'
|
|
35
|
+
|
|
36
|
+
_ = XLATOR.gettext
|
|
37
|
+
|
|
38
|
+
LOG = logging.getLogger(__name__)
|
|
39
|
+
|
|
40
|
+
CycleList = {
|
|
41
|
+
'dots': {'delay': 80, 'frames': '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'},
|
|
42
|
+
'dots2': {'delay': 80, 'frames': '⣾⣽⣻⢿⡿⣟⣯⣷'},
|
|
43
|
+
'dots3': {'delay': 80, 'frames': '⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓'},
|
|
44
|
+
'dots4': {'delay': 80, 'frames': '⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆'},
|
|
45
|
+
'dots5': {'delay': 80, 'frames': '⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋'},
|
|
46
|
+
'dots6': {'delay': 80, 'frames': '⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁'},
|
|
47
|
+
'dots7': {'delay': 80, 'frames': '⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈'},
|
|
48
|
+
'dots8': {'delay': 80, 'frames': '⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈'},
|
|
49
|
+
'dots9': {'delay': 80, 'frames': '⢹⢺⢼⣸⣇⡧⡗⡏'},
|
|
50
|
+
'dots10': {'delay': 80, 'frames': '⢄⢂⢁⡁⡈⡐⡠'},
|
|
51
|
+
'dots11': {'delay': 100, 'frames': '⠁⠂⠄⡀⢀⠠⠐⠈'},
|
|
52
|
+
'dots12': {
|
|
53
|
+
'delay': 80,
|
|
54
|
+
'frames': [
|
|
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
|
+
'dots8Bit': {
|
|
114
|
+
'delay': 80,
|
|
115
|
+
'frames': '⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙'
|
|
116
|
+
'⡚⡛⡜⡝⡞⡟⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻'
|
|
117
|
+
'⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕'
|
|
118
|
+
'⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷'
|
|
119
|
+
'⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿',
|
|
120
|
+
},
|
|
121
|
+
'line': {'delay': 130, 'frames': ['-', '\\', '|', '/']},
|
|
122
|
+
'line1': {'delay': 100, 'frames': ['-', '/', '|', '\\']},
|
|
123
|
+
'line2': {'delay': 100, 'frames': '⠂-–—–-'},
|
|
124
|
+
'pipe': {'delay': 100, 'frames': '┤┘┴└├┌┬┐'},
|
|
125
|
+
'simpleDots': {'delay': 400, 'frames': ['. ', '.. ', '...', ' ']},
|
|
126
|
+
'simpleDotsScrolling': {'delay': 200, 'frames': ['. ', '.. ', '...', ' ..', ' .', ' ']},
|
|
127
|
+
'star': {'delay': 70, 'frames': '✶✸✹✺✹✷'},
|
|
128
|
+
'star2': {'delay': 80, 'frames': '+x*'},
|
|
129
|
+
'flip': {'delay': 70, 'frames': "___-``'´-___"},
|
|
130
|
+
'hamburger': {'delay': 100, 'frames': '☱☲☴'},
|
|
131
|
+
'growVertical': {'delay': 120, 'frames': '▁▃▄▅▆▇▆▅▄▃'},
|
|
132
|
+
'growHorizontal': {'delay': 120, 'frames': '▏▎▍▌▋▊▉▊▋▌▍▎'},
|
|
133
|
+
'balloon': {'delay': 140, 'frames': ' .oO@* '},
|
|
134
|
+
'balloon2': {'delay': 120, 'frames': '.oO°Oo.'},
|
|
135
|
+
'noise': {'delay': 100, 'frames': '▓▒░'},
|
|
136
|
+
'bounce': {'delay': 120, 'frames': '⠁⠂⠄⠂'},
|
|
137
|
+
'boxBounce': {'delay': 120, 'frames': '▖▘▝▗'},
|
|
138
|
+
'boxBounce2': {'delay': 100, 'frames': '▌▀▐▄'},
|
|
139
|
+
'triangle': {'delay': 50, 'frames': '◢◣◤◥'},
|
|
140
|
+
'arc': {'delay': 100, 'frames': '◜◠◝◞◡◟'},
|
|
141
|
+
'circle': {'delay': 120, 'frames': '◡⊙◠'},
|
|
142
|
+
'squareCorners': {'delay': 180, 'frames': '◰◳◲◱'},
|
|
143
|
+
'circleQuarters': {'delay': 120, 'frames': '◴◷◶◵'},
|
|
144
|
+
'circleHalves': {'delay': 50, 'frames': '◐◓◑◒'},
|
|
145
|
+
'squish': {'delay': 100, 'frames': '╫╪'},
|
|
146
|
+
'toggle': {'delay': 250, 'frames': '⊶⊷'},
|
|
147
|
+
'toggle2': {'delay': 80, 'frames': '▫▪'},
|
|
148
|
+
'toggle3': {'delay': 120, 'frames': '□■'},
|
|
149
|
+
'toggle4': {'delay': 100, 'frames': '■□▪▫'},
|
|
150
|
+
'toggle5': {'delay': 100, 'frames': '▮▯'},
|
|
151
|
+
'toggle7': {'delay': 80, 'frames': '⦾⦿'},
|
|
152
|
+
'toggle8': {'delay': 100, 'frames': '◍◌'},
|
|
153
|
+
'toggle9': {'delay': 100, 'frames': '◉◎'},
|
|
154
|
+
'toggle10': {'delay': 100, 'length': 2, 'frames': '㊂㊀㊁'},
|
|
155
|
+
'toggle12': {'delay': 120, 'frames': '☗☖'},
|
|
156
|
+
'toggle13': {'delay': 80, 'frames': '=*-'},
|
|
157
|
+
'arrow': {'delay': 100, 'frames': '←↖↑↗→↘↓↙'},
|
|
158
|
+
'arrow2': {
|
|
159
|
+
'delay': 80,
|
|
160
|
+
'length': 2,
|
|
161
|
+
'frames': ['⬆️ ', '↗️ ', '➡️ ', '↘️ ', '⬇️ ', '↙️ ', '⬅️ ', '↖️ '],
|
|
162
|
+
},
|
|
163
|
+
'arrow3': {
|
|
164
|
+
'delay': 120,
|
|
165
|
+
'frames': ['▹▹▹▹▹', '▸▹▹▹▹', '▹▸▹▹▹', '▹▹▸▹▹', '▹▹▹▸▹', '▹▹▹▹▸'],
|
|
166
|
+
},
|
|
167
|
+
'bouncingBar': {
|
|
168
|
+
'delay': 80,
|
|
169
|
+
'frames': [
|
|
170
|
+
'[ ]',
|
|
171
|
+
'[= ]',
|
|
172
|
+
'[== ]',
|
|
173
|
+
'[=== ]',
|
|
174
|
+
'[ ===]',
|
|
175
|
+
'[ ==]',
|
|
176
|
+
'[ =]',
|
|
177
|
+
'[ ]',
|
|
178
|
+
'[ =]',
|
|
179
|
+
'[ ==]',
|
|
180
|
+
'[ ===]',
|
|
181
|
+
'[====]',
|
|
182
|
+
'[=== ]',
|
|
183
|
+
'[== ]',
|
|
184
|
+
'[= ]',
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
'bouncingBall': {
|
|
188
|
+
'delay': 80,
|
|
189
|
+
'frames': [
|
|
190
|
+
'( ● )',
|
|
191
|
+
'( ● )',
|
|
192
|
+
'( ● )',
|
|
193
|
+
'( ● )',
|
|
194
|
+
'( ●)',
|
|
195
|
+
'( ● )',
|
|
196
|
+
'( ● )',
|
|
197
|
+
'( ● )',
|
|
198
|
+
'( ● )',
|
|
199
|
+
'(● )',
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
'smiley': {'delay': 200, 'length': 2, 'frames': ['😄', '😝']},
|
|
203
|
+
'monkey': {'delay': 300, 'length': 2, 'frames': ['🙈', '🙈', '🙉', '🙊']},
|
|
204
|
+
'hearts': {'delay': 100, 'length': 2, 'frames': ['💛', '💙', '💜', '💚', '❤️ ']},
|
|
205
|
+
'clock': {
|
|
206
|
+
'delay': 100,
|
|
207
|
+
'length': 2,
|
|
208
|
+
'frames': [
|
|
209
|
+
'🕛',
|
|
210
|
+
'🕐',
|
|
211
|
+
'🕑',
|
|
212
|
+
'🕒',
|
|
213
|
+
'🕓',
|
|
214
|
+
'🕔',
|
|
215
|
+
'🕕',
|
|
216
|
+
'🕖',
|
|
217
|
+
'🕗',
|
|
218
|
+
'🕘',
|
|
219
|
+
'🕙',
|
|
220
|
+
'🕚',
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
'earth': {'delay': 180, 'length': 2, 'frames': ['🌍', '🌎', '🌏']},
|
|
224
|
+
'material': {
|
|
225
|
+
'delay': 17,
|
|
226
|
+
'frames': [
|
|
227
|
+
'█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
228
|
+
'██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
229
|
+
'███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
230
|
+
'████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
231
|
+
'██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
232
|
+
'██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
233
|
+
'███████▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
234
|
+
'████████▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
235
|
+
'█████████▁▁▁▁▁▁▁▁▁▁▁',
|
|
236
|
+
'█████████▁▁▁▁▁▁▁▁▁▁▁',
|
|
237
|
+
'██████████▁▁▁▁▁▁▁▁▁▁',
|
|
238
|
+
'███████████▁▁▁▁▁▁▁▁▁',
|
|
239
|
+
'█████████████▁▁▁▁▁▁▁',
|
|
240
|
+
'██████████████▁▁▁▁▁▁',
|
|
241
|
+
'██████████████▁▁▁▁▁▁',
|
|
242
|
+
'▁██████████████▁▁▁▁▁',
|
|
243
|
+
'▁██████████████▁▁▁▁▁',
|
|
244
|
+
'▁██████████████▁▁▁▁▁',
|
|
245
|
+
'▁▁██████████████▁▁▁▁',
|
|
246
|
+
'▁▁▁██████████████▁▁▁',
|
|
247
|
+
'▁▁▁▁█████████████▁▁▁',
|
|
248
|
+
'▁▁▁▁██████████████▁▁',
|
|
249
|
+
'▁▁▁▁██████████████▁▁',
|
|
250
|
+
'▁▁▁▁▁██████████████▁',
|
|
251
|
+
'▁▁▁▁▁██████████████▁',
|
|
252
|
+
'▁▁▁▁▁██████████████▁',
|
|
253
|
+
'▁▁▁▁▁▁██████████████',
|
|
254
|
+
'▁▁▁▁▁▁██████████████',
|
|
255
|
+
'▁▁▁▁▁▁▁█████████████',
|
|
256
|
+
'▁▁▁▁▁▁▁█████████████',
|
|
257
|
+
'▁▁▁▁▁▁▁▁████████████',
|
|
258
|
+
'▁▁▁▁▁▁▁▁████████████',
|
|
259
|
+
'▁▁▁▁▁▁▁▁▁███████████',
|
|
260
|
+
'▁▁▁▁▁▁▁▁▁███████████',
|
|
261
|
+
'▁▁▁▁▁▁▁▁▁▁██████████',
|
|
262
|
+
'▁▁▁▁▁▁▁▁▁▁██████████',
|
|
263
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁████████',
|
|
264
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁███████',
|
|
265
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████',
|
|
266
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████',
|
|
267
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████',
|
|
268
|
+
'█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████',
|
|
269
|
+
'██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███',
|
|
270
|
+
'██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███',
|
|
271
|
+
'███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███',
|
|
272
|
+
'████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██',
|
|
273
|
+
'█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█',
|
|
274
|
+
'█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█',
|
|
275
|
+
'██████▁▁▁▁▁▁▁▁▁▁▁▁▁█',
|
|
276
|
+
'████████▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
277
|
+
'█████████▁▁▁▁▁▁▁▁▁▁▁',
|
|
278
|
+
'█████████▁▁▁▁▁▁▁▁▁▁▁',
|
|
279
|
+
'█████████▁▁▁▁▁▁▁▁▁▁▁',
|
|
280
|
+
'█████████▁▁▁▁▁▁▁▁▁▁▁',
|
|
281
|
+
'███████████▁▁▁▁▁▁▁▁▁',
|
|
282
|
+
'████████████▁▁▁▁▁▁▁▁',
|
|
283
|
+
'████████████▁▁▁▁▁▁▁▁',
|
|
284
|
+
'██████████████▁▁▁▁▁▁',
|
|
285
|
+
'██████████████▁▁▁▁▁▁',
|
|
286
|
+
'▁██████████████▁▁▁▁▁',
|
|
287
|
+
'▁██████████████▁▁▁▁▁',
|
|
288
|
+
'▁▁▁█████████████▁▁▁▁',
|
|
289
|
+
'▁▁▁▁▁████████████▁▁▁',
|
|
290
|
+
'▁▁▁▁▁████████████▁▁▁',
|
|
291
|
+
'▁▁▁▁▁▁███████████▁▁▁',
|
|
292
|
+
'▁▁▁▁▁▁▁▁█████████▁▁▁',
|
|
293
|
+
'▁▁▁▁▁▁▁▁█████████▁▁▁',
|
|
294
|
+
'▁▁▁▁▁▁▁▁▁█████████▁▁',
|
|
295
|
+
'▁▁▁▁▁▁▁▁▁█████████▁▁',
|
|
296
|
+
'▁▁▁▁▁▁▁▁▁▁█████████▁',
|
|
297
|
+
'▁▁▁▁▁▁▁▁▁▁▁████████▁',
|
|
298
|
+
'▁▁▁▁▁▁▁▁▁▁▁████████▁',
|
|
299
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁███████▁',
|
|
300
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁███████▁',
|
|
301
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁███████',
|
|
302
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁███████',
|
|
303
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████',
|
|
304
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████',
|
|
305
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████',
|
|
306
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████',
|
|
307
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███',
|
|
308
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███',
|
|
309
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██',
|
|
310
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██',
|
|
311
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██',
|
|
312
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█',
|
|
313
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█',
|
|
314
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█',
|
|
315
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
316
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
317
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
318
|
+
'▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁',
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
'moon': {
|
|
322
|
+
'delay': 80,
|
|
323
|
+
'length': 2,
|
|
324
|
+
'frames': ['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘'],
|
|
325
|
+
},
|
|
326
|
+
'runner': {'delay': 140, 'length': 2, 'frames': ['🚶', '🏃']},
|
|
327
|
+
'pong': {
|
|
328
|
+
'delay': 80,
|
|
329
|
+
'frames': [
|
|
330
|
+
'▐⠂ ▌',
|
|
331
|
+
'▐⠈ ▌',
|
|
332
|
+
'▐ ⠂ ▌',
|
|
333
|
+
'▐ ⠠ ▌',
|
|
334
|
+
'▐ ⡀ ▌',
|
|
335
|
+
'▐ ⠠ ▌',
|
|
336
|
+
'▐ ⠂ ▌',
|
|
337
|
+
'▐ ⠈ ▌',
|
|
338
|
+
'▐ ⠂ ▌',
|
|
339
|
+
'▐ ⠠ ▌',
|
|
340
|
+
'▐ ⡀ ▌',
|
|
341
|
+
'▐ ⠠ ▌',
|
|
342
|
+
'▐ ⠂ ▌',
|
|
343
|
+
'▐ ⠈ ▌',
|
|
344
|
+
'▐ ⠂▌',
|
|
345
|
+
'▐ ⠠▌',
|
|
346
|
+
'▐ ⡀▌',
|
|
347
|
+
'▐ ⠠ ▌',
|
|
348
|
+
'▐ ⠂ ▌',
|
|
349
|
+
'▐ ⠈ ▌',
|
|
350
|
+
'▐ ⠂ ▌',
|
|
351
|
+
'▐ ⠠ ▌',
|
|
352
|
+
'▐ ⡀ ▌',
|
|
353
|
+
'▐ ⠠ ▌',
|
|
354
|
+
'▐ ⠂ ▌',
|
|
355
|
+
'▐ ⠈ ▌',
|
|
356
|
+
'▐ ⠂ ▌',
|
|
357
|
+
'▐ ⠠ ▌',
|
|
358
|
+
'▐ ⡀ ▌',
|
|
359
|
+
'▐⠠ ▌',
|
|
360
|
+
],
|
|
361
|
+
},
|
|
362
|
+
'shark': {
|
|
363
|
+
'delay': 120,
|
|
364
|
+
'frames': [
|
|
365
|
+
'▐|\\____________▌',
|
|
366
|
+
'▐_|\\___________▌',
|
|
367
|
+
'▐__|\\__________▌',
|
|
368
|
+
'▐___|\\_________▌',
|
|
369
|
+
'▐____|\\________▌',
|
|
370
|
+
'▐_____|\\_______▌',
|
|
371
|
+
'▐______|\\______▌',
|
|
372
|
+
'▐_______|\\_____▌',
|
|
373
|
+
'▐________|\\____▌',
|
|
374
|
+
'▐_________|\\___▌',
|
|
375
|
+
'▐__________|\\__▌',
|
|
376
|
+
'▐___________|\\_▌',
|
|
377
|
+
'▐____________|\\▌',
|
|
378
|
+
'▐____________/|▌',
|
|
379
|
+
'▐___________/|_▌',
|
|
380
|
+
'▐__________/|__▌',
|
|
381
|
+
'▐_________/|___▌',
|
|
382
|
+
'▐________/|____▌',
|
|
383
|
+
'▐_______/|_____▌',
|
|
384
|
+
'▐______/|______▌',
|
|
385
|
+
'▐_____/|_______▌',
|
|
386
|
+
'▐____/|________▌',
|
|
387
|
+
'▐___/|_________▌',
|
|
388
|
+
'▐__/|__________▌',
|
|
389
|
+
'▐_/|___________▌',
|
|
390
|
+
'▐/|____________▌',
|
|
391
|
+
],
|
|
392
|
+
},
|
|
393
|
+
'dqpb': {'delay': 100, 'frames': 'dqpb'},
|
|
394
|
+
'weather': {
|
|
395
|
+
'delay': 100,
|
|
396
|
+
'length': 2,
|
|
397
|
+
'frames': [
|
|
398
|
+
'☀️ ',
|
|
399
|
+
'☀️ ',
|
|
400
|
+
'☀️ ',
|
|
401
|
+
'🌤 ',
|
|
402
|
+
'⛅️',
|
|
403
|
+
'🌥 ',
|
|
404
|
+
'☁️ ',
|
|
405
|
+
'🌧 ',
|
|
406
|
+
'🌨 ',
|
|
407
|
+
'🌧 ',
|
|
408
|
+
'🌨 ',
|
|
409
|
+
'🌧 ',
|
|
410
|
+
'🌨 ',
|
|
411
|
+
'⛈ ',
|
|
412
|
+
'🌨 ',
|
|
413
|
+
'🌧 ',
|
|
414
|
+
'🌨 ',
|
|
415
|
+
'☁️ ',
|
|
416
|
+
'🌥 ',
|
|
417
|
+
'⛅️',
|
|
418
|
+
'🌤 ',
|
|
419
|
+
'☀️ ',
|
|
420
|
+
'☀️ ',
|
|
421
|
+
],
|
|
422
|
+
},
|
|
423
|
+
'christmas': {'delay': 400, 'length': 2, 'frames': '🌲🎄'},
|
|
424
|
+
'grenade': {
|
|
425
|
+
'delay': 80,
|
|
426
|
+
'length': 3,
|
|
427
|
+
'frames': [
|
|
428
|
+
'، ',
|
|
429
|
+
'′ ',
|
|
430
|
+
' ´ ',
|
|
431
|
+
' ‾ ',
|
|
432
|
+
' ⸌',
|
|
433
|
+
' ⸊',
|
|
434
|
+
' |',
|
|
435
|
+
' ⁎',
|
|
436
|
+
' ⁕',
|
|
437
|
+
' ෴ ',
|
|
438
|
+
' ⁓',
|
|
439
|
+
' ',
|
|
440
|
+
' ',
|
|
441
|
+
' ',
|
|
442
|
+
],
|
|
443
|
+
},
|
|
444
|
+
'point': {'delay': 125, 'frames': ['∙∙∙', '●∙∙', '∙●∙', '∙∙●', '∙∙∙']},
|
|
445
|
+
'layer': {'delay': 150, 'frames': '-=≡'},
|
|
446
|
+
'betaWave': {
|
|
447
|
+
'delay': 80,
|
|
448
|
+
'frames': [
|
|
449
|
+
'ρββββββ',
|
|
450
|
+
'βρβββββ',
|
|
451
|
+
'ββρββββ',
|
|
452
|
+
'βββρβββ',
|
|
453
|
+
'ββββρββ',
|
|
454
|
+
'βββββρβ',
|
|
455
|
+
'ββββββρ',
|
|
456
|
+
],
|
|
457
|
+
},
|
|
458
|
+
'aesthetic': {
|
|
459
|
+
'delay': 80,
|
|
460
|
+
'frames': [
|
|
461
|
+
'▰▱▱▱▱▱▱',
|
|
462
|
+
'▰▰▱▱▱▱▱',
|
|
463
|
+
'▰▰▰▱▱▱▱',
|
|
464
|
+
'▰▰▰▰▱▱▱',
|
|
465
|
+
'▰▰▰▰▰▱▱',
|
|
466
|
+
'▰▰▰▰▰▰▱',
|
|
467
|
+
'▰▰▰▰▰▰▰',
|
|
468
|
+
'▰▱▱▱▱▱▱',
|
|
469
|
+
],
|
|
470
|
+
},
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
# =============================================================================
|
|
474
|
+
class Spinner(object):
|
|
475
|
+
"""Displaying on console a rotating or somehow other animated character."""
|
|
476
|
+
|
|
477
|
+
default_cycle_name = 'line1'
|
|
478
|
+
default_delay = 100
|
|
479
|
+
|
|
480
|
+
# -------------------------------------------------------------------------
|
|
481
|
+
def __init__(self, message, cycle_name=None, frames=None, delay=None):
|
|
482
|
+
"""Initialize a Spinner object."""
|
|
483
|
+
self.cycle_name = cycle_name
|
|
484
|
+
if not self.cycle_name:
|
|
485
|
+
self.cycle_name = self.default_cycle_name
|
|
486
|
+
|
|
487
|
+
self.frames = None
|
|
488
|
+
self.delay = self.default_delay
|
|
489
|
+
self.characters = 1
|
|
490
|
+
length = None
|
|
491
|
+
|
|
492
|
+
if frames:
|
|
493
|
+
self.frames = frames
|
|
494
|
+
else:
|
|
495
|
+
if self.cycle_name not in CycleList:
|
|
496
|
+
msg = _('Spinner {!r} not found.').format(self.cycle_name)
|
|
497
|
+
raise KeyError(msg)
|
|
498
|
+
|
|
499
|
+
self.frames = CycleList[self.cycle_name]['frames']
|
|
500
|
+
self.delay = CycleList[self.cycle_name]['delay']
|
|
501
|
+
if 'length' in CycleList[self.cycle_name]:
|
|
502
|
+
length = CycleList[self.cycle_name]['length']
|
|
503
|
+
|
|
504
|
+
self.spinner = itertools.cycle(self.frames)
|
|
505
|
+
|
|
506
|
+
if length:
|
|
507
|
+
self.characters = length
|
|
508
|
+
else:
|
|
509
|
+
self.characters = len(self.frames[0])
|
|
510
|
+
if delay:
|
|
511
|
+
self.delay = delay
|
|
512
|
+
|
|
513
|
+
# LOG.debug('First frame is of type {!r}.'.format(self.frames[0].__class__.__name__))
|
|
514
|
+
# LOG.debug('Frames has {c} characters, delay is {d} milliseconds.'.format(
|
|
515
|
+
# c=self.characters, d=self.delay))
|
|
516
|
+
# len_in_codeunits = len(self.frames[0].encode('utf-16-le')) // 2
|
|
517
|
+
# LOG.debug('len_in_codeunits: {}'.format(len_in_codeunits))
|
|
518
|
+
# LOG.debug('len: {}'.format(len(self.frames[0].encode('utf-8'))))
|
|
519
|
+
# LOG.debug('str: {}'.format(self.frames[0]))
|
|
520
|
+
# LOG.debug('bytes: {}'.format(to_bytes(self.frames[0])))
|
|
521
|
+
|
|
522
|
+
self.busy = False
|
|
523
|
+
self.spinner_visible = False
|
|
524
|
+
sys.stdout.write(message)
|
|
525
|
+
|
|
526
|
+
# -------------------------------------------------------------------------
|
|
527
|
+
def write_next(self):
|
|
528
|
+
"""Write the next character from the cycle array on the current screen position."""
|
|
529
|
+
with self._screen_lock:
|
|
530
|
+
if not self.spinner_visible:
|
|
531
|
+
sys.stdout.write(next(self.spinner) + ' ')
|
|
532
|
+
self.spinner_visible = True
|
|
533
|
+
sys.stdout.flush()
|
|
534
|
+
|
|
535
|
+
# -------------------------------------------------------------------------
|
|
536
|
+
def remove_spinner(self, cleanup=False):
|
|
537
|
+
"""
|
|
538
|
+
Remove the last visible cycle character from screen.
|
|
539
|
+
|
|
540
|
+
If the parameter cleanup is true, then the screen cursor will be mnoved to the next line.
|
|
541
|
+
"""
|
|
542
|
+
with self._screen_lock:
|
|
543
|
+
if self.spinner_visible:
|
|
544
|
+
sys.stdout.write('\b' * (self.characters + 1))
|
|
545
|
+
self.spinner_visible = False
|
|
546
|
+
if cleanup:
|
|
547
|
+
sys.stdout.write(' ' * self.characters) # overwrite spinner with blank
|
|
548
|
+
sys.stdout.write('\r') # move to next line
|
|
549
|
+
sys.stdout.flush()
|
|
550
|
+
|
|
551
|
+
# -------------------------------------------------------------------------
|
|
552
|
+
def spinner_task(self):
|
|
553
|
+
"""Entry point of the Thread. It is an infinite loop."""
|
|
554
|
+
delay = float(self.delay) / 1000.0
|
|
555
|
+
|
|
556
|
+
while self.busy:
|
|
557
|
+
self.write_next()
|
|
558
|
+
time.sleep(delay)
|
|
559
|
+
self.remove_spinner()
|
|
560
|
+
|
|
561
|
+
# -------------------------------------------------------------------------
|
|
562
|
+
def __enter__(self):
|
|
563
|
+
"""Execute this ction, when this object will be created for the with-block."""
|
|
564
|
+
if sys.stdout.isatty():
|
|
565
|
+
self._screen_lock = threading.Lock()
|
|
566
|
+
self.busy = True
|
|
567
|
+
self.thread = threading.Thread(target=self.spinner_task)
|
|
568
|
+
self.thread.start()
|
|
569
|
+
|
|
570
|
+
# -------------------------------------------------------------------------
|
|
571
|
+
def __exit__(self, exc_type, exc_val, exc_traceback):
|
|
572
|
+
"""Exit action at the end of the with-block."""
|
|
573
|
+
if sys.stdout.isatty():
|
|
574
|
+
self.busy = False
|
|
575
|
+
self.remove_spinner(cleanup=True)
|
|
576
|
+
else:
|
|
577
|
+
sys.stdout.write('\r')
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
# =============================================================================
|
|
581
|
+
if __name__ == '__main__':
|
|
582
|
+
|
|
583
|
+
pass
|
|
584
|
+
|
|
585
|
+
# =============================================================================
|
|
586
|
+
|
|
587
|
+
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list
|
|
@@ -22,6 +22,7 @@ lib/fb_tools/mailaddress.py
|
|
|
22
22
|
lib/fb_tools/merge.py
|
|
23
23
|
lib/fb_tools/obj.py
|
|
24
24
|
lib/fb_tools/pidfile.py
|
|
25
|
+
lib/fb_tools/spinner.py
|
|
25
26
|
lib/fb_tools/xlate.py
|
|
26
27
|
lib/fb_tools.egg-info/PKG-INFO
|
|
27
28
|
lib/fb_tools.egg-info/SOURCES.txt
|
|
@@ -59,4 +60,5 @@ test/test_20_handling_object.py
|
|
|
59
60
|
test/test_25_ddns_update_status.py
|
|
60
61
|
test/test_30_base_handler.py
|
|
61
62
|
test/test_33_lock.py
|
|
62
|
-
test/test_40_app_modules.py
|
|
63
|
+
test/test_40_app_modules.py
|
|
64
|
+
test/test_50_spinner.py
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
@summary: Test script (and module) for unit tests on spinner module and Spinner objects.
|
|
5
|
+
|
|
6
|
+
@author: Frank Brehm
|
|
7
|
+
@contact: frank@brehm-online.com
|
|
8
|
+
@license: GPL3
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
import time
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import unittest2 as unittest
|
|
18
|
+
except ImportError:
|
|
19
|
+
import unittest
|
|
20
|
+
|
|
21
|
+
libdir = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..', 'lib'))
|
|
22
|
+
sys.path.insert(0, libdir)
|
|
23
|
+
|
|
24
|
+
from fb_tools.common import to_bool
|
|
25
|
+
|
|
26
|
+
from general import FbToolsTestcase, get_arg_verbose, init_root_logger
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
APPNAME = 'test_spinner'
|
|
30
|
+
|
|
31
|
+
LOG = logging.getLogger(APPNAME)
|
|
32
|
+
|
|
33
|
+
EXEC_LONG_TESTS = False
|
|
34
|
+
if 'EXEC_LONG_TESTS' in os.environ and os.environ['EXEC_LONG_TESTS'] != '':
|
|
35
|
+
EXEC_LONG_TESTS = to_bool(os.environ['EXEC_LONG_TESTS'])
|
|
36
|
+
|
|
37
|
+
SPINNER_TO_TEST = 'line'
|
|
38
|
+
if 'SPINNER_TO_TEST' in os.environ:
|
|
39
|
+
SPINNER_TO_TEST = os.environ['SPINNER_TO_TEST'].strip()
|
|
40
|
+
if not SPINNER_TO_TEST:
|
|
41
|
+
SPINNER_TO_TEST = None
|
|
42
|
+
|
|
43
|
+
# =============================================================================
|
|
44
|
+
class TestSpinner(FbToolsTestcase):
|
|
45
|
+
"""Testcase for unit tests on module fb_tools.spinner."""
|
|
46
|
+
|
|
47
|
+
# -------------------------------------------------------------------------
|
|
48
|
+
def setUp(self):
|
|
49
|
+
"""Execute this on setting up before calling each particular test method."""
|
|
50
|
+
if self.verbose >= 1:
|
|
51
|
+
print()
|
|
52
|
+
|
|
53
|
+
# -------------------------------------------------------------------------
|
|
54
|
+
def tearDown(self):
|
|
55
|
+
"""Tear down routine for calling each particular test method."""
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
# -------------------------------------------------------------------------
|
|
59
|
+
def test_import(self):
|
|
60
|
+
"""Test import of pp_admintools.spinner."""
|
|
61
|
+
LOG.info(self.get_method_doc())
|
|
62
|
+
|
|
63
|
+
import fb_tools.spinner
|
|
64
|
+
LOG.debug('Version of module fb_tools.spinner: {!r}.'.format(
|
|
65
|
+
fb_tools.spinner.__version__))
|
|
66
|
+
|
|
67
|
+
# -------------------------------------------------------------------------
|
|
68
|
+
@unittest.skipUnless(SPINNER_TO_TEST, 'No spinner to test selected.')
|
|
69
|
+
def test_particular_spinner(self):
|
|
70
|
+
"""Test execution of a particular spinner."""
|
|
71
|
+
LOG.info(self.get_method_doc())
|
|
72
|
+
|
|
73
|
+
from fb_tools.spinner import Spinner
|
|
74
|
+
|
|
75
|
+
seconds_per_spinner = 10
|
|
76
|
+
|
|
77
|
+
msg = 'Testing spinner {!r}: '.format(SPINNER_TO_TEST)
|
|
78
|
+
with Spinner(msg, SPINNER_TO_TEST):
|
|
79
|
+
time.sleep(seconds_per_spinner)
|
|
80
|
+
print()
|
|
81
|
+
print('Continue ...')
|
|
82
|
+
|
|
83
|
+
# -------------------------------------------------------------------------
|
|
84
|
+
@unittest.skipUnless(EXEC_LONG_TESTS, 'Long terming tests are not executed.')
|
|
85
|
+
def test_all_spinners(self):
|
|
86
|
+
"""Test execution of all spinners."""
|
|
87
|
+
LOG.info(self.get_method_doc())
|
|
88
|
+
|
|
89
|
+
import fb_tools.spinner
|
|
90
|
+
from fb_tools.spinner import Spinner
|
|
91
|
+
|
|
92
|
+
seconds_per_spinner = 6
|
|
93
|
+
|
|
94
|
+
for cycle_name in fb_tools.spinner.CycleList.keys():
|
|
95
|
+
|
|
96
|
+
msg = 'Testing spinner {!r}: '.format(cycle_name)
|
|
97
|
+
with Spinner(msg, cycle_name):
|
|
98
|
+
time.sleep(seconds_per_spinner)
|
|
99
|
+
print()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# =============================================================================
|
|
103
|
+
if __name__ == '__main__':
|
|
104
|
+
|
|
105
|
+
verbose = get_arg_verbose()
|
|
106
|
+
if verbose is None:
|
|
107
|
+
verbose = 0
|
|
108
|
+
init_root_logger(verbose)
|
|
109
|
+
|
|
110
|
+
LOG.info('Starting tests ...')
|
|
111
|
+
|
|
112
|
+
loader = unittest.TestLoader()
|
|
113
|
+
suite = unittest.TestSuite()
|
|
114
|
+
|
|
115
|
+
suite.addTest(TestSpinner('test_import', verbose))
|
|
116
|
+
suite.addTest(TestSpinner('test_particular_spinner', verbose))
|
|
117
|
+
suite.addTest(TestSpinner('test_all_spinners', verbose))
|
|
118
|
+
|
|
119
|
+
runner = unittest.TextTestRunner(verbosity=verbose)
|
|
120
|
+
|
|
121
|
+
result = runner.run(suite)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# =============================================================================
|
|
125
|
+
|
|
126
|
+
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|