aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore11
-rw-r--r--license.txt21
-rw-r--r--readme.rst24
-rwxr-xr-xscripts/fancy-sleep219
4 files changed, 275 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8b6a7ee
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+# safely ignore these filetypes/extensions
+*.pyo
+*.pyc
+*.log
+*.swp
+__pycache__
+*.jpg
+*.jpeg
+*.gif
+*.png
+*.svg
diff --git a/license.txt b/license.txt
new file mode 100644
index 0000000..d075b49
--- /dev/null
+++ b/license.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright © 2017 vg <vg@devys.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/readme.rst b/readme.rst
new file mode 100644
index 0000000..50c61ce
--- /dev/null
+++ b/readme.rst
@@ -0,0 +1,24 @@
+Description
+===========
+
+This repository contains little scripts not deserving their own repositories.
+
+License
+=======
+
+Unless specified otherwise, this project is licensed under the terms of the
+MIT license. You should have received a copy of the MIT License along with
+this program. If not, see <https://opensource.org/licenses/MIT>.
+
+SPDX-License-Identifier: MIT
+
+Copyright © 2017 vg <vg@devys.org>
+
+Contact
+=======
+
+developer
+ vg
+
+mail
+ vg@devys.org
diff --git a/scripts/fancy-sleep b/scripts/fancy-sleep
new file mode 100755
index 0000000..76cb04c
--- /dev/null
+++ b/scripts/fancy-sleep
@@ -0,0 +1,219 @@
+#!/usr/bin/env python3
+# Copyright 2017 vg@devys.org
+# SPDX-License-Identifier: MIT
+
+'''
+Simple and fancy sleep for console.
+
+Time can be precised as XX[h|m|s] [YY[m|s]] [ZZ[s]] or XX:YY[:ZZ].
+
+Usage: fancy-sleep [options] TIME...
+ fancy-sleep -h|--help
+
+Options:
+ -h, --help Display this help message
+'''
+
+
+import contextlib
+import datetime
+import sys
+import time
+import re
+
+import docopt
+
+
+_determine_delta_pattern = None
+
+
+# to avoid accidental trailing spaces removal, use another character and
+# replace.
+numbers = [i.replace('.', ' ') for i in (
+"""\
+ ██████
+ ██ ██
+ ██ ██
+ ██ ██
+ ██████
+""",
+"""\
+ ██
+ ██
+ ██
+ ██
+ ██
+""",
+"""\
+ ██████
+ ██
+ ██████
+ ██....
+ ██████
+""",
+"""\
+ ██████
+ ██
+ ██████
+ ██
+ ██████
+""",
+"""\
+ ██ ██
+ ██ ██
+ ██████
+ ██
+ ██
+""",
+"""\
+ ██████
+ ██....
+ ██████
+ ██
+ ██████
+""",
+"""\
+ ██████
+ ██....
+ ██████
+ ██ ██
+ ██████
+""",
+"""\
+ ██████
+ ██
+ ██
+ ██
+ ██
+""",
+"""\
+ ██████
+ ██ ██
+ ██████
+ ██ ██
+ ██████
+""",
+"""\
+ ██████
+ ██ ██
+ ██████
+ ██
+ ██████
+""",
+"""\
+ .
+ ██.
+ .
+ ██.
+ .
+""",
+)]
+
+
+def print_translated(string):
+ translated = []
+ for character in string:
+ index = 0
+ if '0' <= character and character <= '9':
+ index = ord(character) - ord('0')
+ elif character == ':':
+ index = 10
+ translated.append(numbers[index])
+ display_lines = ['', '', '', '', '', '']
+ for index in range(5):
+ for number in translated:
+ display_lines[index] += number.splitlines()[index]
+ print('\n'.join(display_lines), end='')
+
+
+def determine_delta(elements,
+ time_pattern=re.compile(r'^(\d+)([dhms]?)$')):
+ default = datetime.datetime.strptime('0', '%S')
+ timedelta = datetime.timedelta()
+ for element in elements:
+ groups = time_pattern.match(element)
+ if groups:
+ if groups.group(2) == 'd':
+ timedelta += datetime.timedelta(days=float(groups.group(1)))
+ elif groups.group(2) == 'h':
+ timedelta += datetime.timedelta(hours=float(groups.group(1)))
+ elif groups.group(2) == 'm':
+ timedelta += datetime.timedelta(minutes=float(groups.group(1)))
+ elif groups.group(2) == 's' or groups.group(2) == '':
+ timedelta += datetime.timedelta(seconds=float(groups.group(1)))
+
+
+ #with contextlib.suppress(ValueError):
+ # timedelta += datetime.datetime.strptime(element, '%dd') - default
+ #with contextlib.suppress(ValueError):
+ # timedelta += datetime.datetime.strptime(element, '%Hh') - default
+ #with contextlib.suppress(ValueError):
+ # timedelta += datetime.datetime.strptime(element, '%Mm') - default
+ #with contextlib.suppress(ValueError):
+ # timedelta += datetime.datetime.strptime(element, '%Ss') - default
+ #with contextlib.suppress(ValueError):
+ # timedelta += datetime.datetime.strptime(element, '%S') - default
+ else:
+ with contextlib.suppress(ValueError):
+ timedelta += datetime.datetime.strptime(element, '%H:%M') - default
+ with contextlib.suppress(ValueError):
+ timedelta += datetime.datetime.strptime(element, '%H:%M:%S') - default
+ return timedelta
+
+
+def determine_delta_tests():
+ assert(determine_delta('11'.split()) == datetime.timedelta(seconds=11))
+ assert(determine_delta('11s'.split()) == datetime.timedelta(seconds=11))
+ assert(determine_delta('11h 47m'.split()) == datetime.timedelta(hours=11, minutes=47))
+ assert(determine_delta('11h 47'.split()) == datetime.timedelta(hours=11, seconds=47))
+ assert(determine_delta('11h 47m 09'.split()) == datetime.timedelta(hours=11, minutes=47, seconds=9))
+ assert(determine_delta('09:53'.split()) == datetime.timedelta(hours=9, minutes=53))
+ assert(determine_delta('8:2 9'.split()) == datetime.timedelta(hours=8, minutes=2, seconds=9))
+ assert(determine_delta('8d 5:32 6s'.split()) == datetime.timedelta(days=8, hours=5, minutes=32, seconds=6))
+
+
+if __name__ == '__main__':
+ 'run fancy-sleep code: args parsing, display and sleeping logic'
+
+ # FIXME: can be done automatically with nose for example ?
+ determine_delta_tests()
+
+ args = docopt.docopt(__doc__)
+
+ curtime = datetime.datetime.now()
+ timedelta = determine_delta(args['TIME'])
+ target_time = curtime + timedelta
+
+ print('Launched at:', curtime.strftime('%F %T'))
+ print('Run until:', target_time.strftime('%F %T'))
+ sys.stdout.flush()
+
+ if sys.stdout.isatty():
+ print()
+
+ print('\n'*5, '\x1b[5A', sep='', end='')
+ print('\x1b[s', end='') # save cursor
+ try:
+ while True:
+ delta = target_time.timestamp() - time.time()
+ if delta <= 0:
+ break
+ hours = int(delta / 3600)
+ minutes = int(delta / 60) % 60
+ seconds = int(delta) % 60
+
+ print('\x1b[u', end='') # restore cursor
+ time_string = '%02d:%02d:%02d' % (hours, minutes, seconds)
+ #print('\rremainining time: %s' % time_string, end='')
+ print_translated(time_string)
+
+ time.sleep(1)
+ except KeyboardInterrupt:
+ sys.exit(130)
+ finally:
+ print()
+ else:
+ try:
+ time.sleep(target_time.timestamp() - time.time())
+ except KeyboardInterrupt:
+ sys.exit(130)