]> Frank Brehm's Git Trees - pixelpark/admin-tools.git/commitdiff
Adding bin/pp-duration and its appp module
authorFrank Brehm <frank@brehm-online.com>
Tue, 2 Feb 2021 10:49:08 +0000 (11:49 +0100)
committerFrank Brehm <frank@brehm-online.com>
Tue, 2 Feb 2021 10:49:08 +0000 (11:49 +0100)
bin/pp-duration [new file with mode: 0755]
lib/pp_lib/pp_duration_app.py [new file with mode: 0644]

diff --git a/bin/pp-duration b/bin/pp-duration
new file mode 100755 (executable)
index 0000000..59a3e8c
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+from __future__ import print_function
+
+# Standard modules
+import sys
+
+__exp_py_version_major__ = 3
+__min_py_version_minor__ = 4
+
+if sys.version_info[0] != __exp_py_version_major__:
+    print("This script is intended to use with Python {}.".format(
+            __exp_py_version_major__), file=sys.stderr)
+    print("You are using Python: {0}.{1}.{2}-{3}-{4}.".format(
+        *sys.version_info) + "\n", file=sys.stderr)
+    sys.exit(1)
+
+if sys.version_info[1] < __min_py_version_minor__:
+    print("A minimal Python version of {maj}.{min} is necessary to execute this script.".format(
+        maj=__exp_py_version_major__, min=__min_py_version_minor__), file=sys.stderr)
+    print("You are using Python: {0}.{1}.{2}-{3}-{4}.".format(
+        *sys.version_info) + "\n", file=sys.stderr)
+    sys.exit(1)
+
+# Standard modules
+import os
+import locale
+
+try:
+    import pathlib
+    from pathlib import Path
+except ImportError:
+    from pathlib2 import Path
+    import pathlib2 as pathlib
+
+# own modules:
+
+my_path = Path(__file__)
+my_real_path = my_path.resolve()
+bin_path = my_real_path.parent
+base_dir = bin_path.parent
+lib_dir = base_dir.joinpath('lib')
+module_dir = lib_dir.joinpath('pp_lib')
+
+if module_dir.exists():
+    sys.path.insert(0, str(lib_dir))
+
+from pp_lib.pp_duration_app import PpDurationApp
+
+__author__ = 'Frank Brehm <frank.brehm@pixelpark.com>'
+__copyright__ = '(C) 2021 by Frank Brehm, Pixelpark GmbH, Berlin'
+
+appname = os.path.basename(sys.argv[0])
+
+# locale.setlocale(locale.LC_ALL, '')
+
+app = PpDurationApp(appname=appname)
+
+if app.verbose > 2:
+    print("{c}-Object:\n{a}".format(c=app.__class__.__name__, a=app))
+
+app()
+
+sys.exit(0)
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/lib/pp_lib/pp_duration_app.py b/lib/pp_lib/pp_duration_app.py
new file mode 100644 (file)
index 0000000..95a76d1
--- /dev/null
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2021 by Frank Brehm, Berlin
+@summary: The module for the application object.
+"""
+from __future__ import absolute_import
+
+# Standard modules
+import logging
+import textwrap
+import datetime
+import time
+
+# Third party modules
+import six
+
+from babel.numbers import format_decimal
+
+# Own modules
+from fb_tools.common import pp
+from fb_tools.app import BaseApplication
+from fb_tools.xlate import format_list
+
+try:
+    from .local_version import __version__ as my_version
+except ImportError:
+    from .global_version import __version__ as my_version
+
+__version__ = '0.1.0'
+LOG = logging.getLogger(__name__)
+
+
+# =============================================================================
+class PpDurationApp(BaseApplication):
+    """
+    Application class for displaying a duration in a human readable format.
+    """
+
+    # -------------------------------------------------------------------------
+    def __init__(
+            self, appname=None, verbose=0, version=my_version, *arg, **kwargs):
+
+        indent = ' ' * self.usage_term_len
+
+        usage = textwrap.dedent("""\
+        %(prog)s [--color [{{yes,no,auto}}]] [-v] <START_TIMESTAMP> [END_TIMESTAMP]
+
+        {i}%(prog)s --usage
+        {i}%(prog)s -h|--help
+        {i}%(prog)s -V|--version
+        """).strip().format(i=indent)
+
+        desc = """Display the duration between two UNIX timestamps in a human readable format."""
+
+        self.start_ts = None
+        self.end_ts = None
+
+        super(PpDurationApp, self).__init__(
+            description=desc,
+            appname=appname,
+            verbose=verbose,
+            version=version,
+            *arg, **kwargs
+        )
+
+        self.post_init()
+        self.initialized = True
+
+    # -------------------------------------------------------------------------
+    def init_arg_parser(self):
+        """
+        Method to initiate the argument parser.
+        """
+
+        super(PpDurationApp, self).init_arg_parser()
+
+        self.arg_parser.add_argument(
+            'start_ts',
+            metavar='START_TIMESTAMP', type=float,
+            help=(
+                'The UNIX timestamp of the beginning of the duration. Mandatory argument.'),
+        )
+
+        self.arg_parser.add_argument(
+            'end_ts',
+            metavar='END_TIMESTAMP', type=float, nargs='?',
+            help=(
+                'The UNIX timestamp of the end of the duration. '
+                'The current timestamp will be used, if not given.'),
+        )
+
+    # -------------------------------------------------------------------------
+    def perform_arg_parser(self):
+        """
+        Public available method to execute some actions after parsing
+        the command line parameters.
+
+        Descendant classes may override this method.
+        """
+
+        if self.args.start_ts is not None:
+            self.start_ts = self.args.start_ts
+
+        if self.args.end_ts is not None:
+            self.end_ts = self.args.end_ts
+        else:
+            self.end_ts = time.time()
+
+    # -------------------------------------------------------------------------
+    def _run(self):
+        """The underlaying startpoint of the application."""
+
+        start_dt = datetime.datetime.utcfromtimestamp(self.start_ts)
+        end_dt = datetime.datetime.utcfromtimestamp(self.end_ts)
+
+        tdiff = end_dt - start_dt
+
+        seconds_total = float(int((tdiff.total_seconds() * 100) + 0.5)) / 100
+
+        minutes_total = seconds_total // 60
+        seconds_left = seconds_total - (minutes_total * 60)
+
+        hours_total = minutes_total // 60
+        minutes_left = minutes_total - (hours_total * 60)
+
+        days_total = hours_total // 24
+        hours_left = hours_total - (days_total * 24)
+
+        months_total = days_total // 30
+        days_left = days_total - (months_total * 30)
+
+        years = 0
+        months_left = months_total
+        if days_total > 365:
+            years = days_total // 365
+            months_left = months_total - (years * 12)
+
+        output_list = []
+        if years:
+            if years == 1:
+                output_list.append('one year')
+            else:
+                output_list.append('{:.0f} years'.format(years))
+        if output_list or months_left:
+            if months_left == 1:
+                output_list.append('one month')
+            else:
+                output_list.append('{:.0f} months'.format(months_left))
+
+        if output_list or days_left:
+            if days_left == 1:
+                output_list.append('one day')
+            else:
+                output_list.append('{:.0f} days'.format(days_left))
+
+        if output_list or hours_left:
+            if hours_left == 1:
+                output_list.append('one hour')
+            else:
+                output_list.append('{:.0f} hours'.format(hours_left))
+
+        if output_list or minutes_left:
+            if minutes_left == 1:
+                output_list.append('one minute')
+            else:
+                output_list.append('{:.0f} minutes'.format(minutes_left))
+
+        secs_out = format_decimal(seconds_left, locale='en_US')
+        output_list.append('{} seconds'.format(secs_out))
+
+        secs_out = format_decimal(seconds_total, locale='en_US')
+        output = "Duration was {} seconds".format(secs_out)
+        if len(output_list) > 1:
+            output += ' == ' + format_list(output_list, locale='en_US')
+        output += '.'
+
+        print(output)
+
+
+# =============================================================================
+
+if __name__ == "__main__":
+
+    pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list