"Fossies" - the Fresh Open Source Software Archive

Member "fail2ban-0.11.1/fail2ban/server/mytime.py" (11 Jan 2020, 5558 Bytes) of package /linux/misc/fail2ban-0.11.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "mytime.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.10.5_vs_0.11.1.

    1 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
    2 # vi: set ft=python sts=4 ts=4 sw=4 noet :
    3 
    4 # This file is part of Fail2Ban.
    5 #
    6 # Fail2Ban is free software; you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation; either version 2 of the License, or
    9 # (at your option) any later version.
   10 #
   11 # Fail2Ban is distributed in the hope that it will be useful,
   12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 # GNU General Public License for more details.
   15 #
   16 # You should have received a copy of the GNU General Public License
   17 # along with Fail2Ban; if not, write to the Free Software
   18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   19 
   20 __author__ = "Cyril Jaquier"
   21 __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
   22 __license__ = "GPL"
   23 
   24 import datetime
   25 import re
   26 import time
   27 
   28 
   29 ##
   30 # MyTime class.
   31 #
   32 
   33 class MyTime:
   34     """A wrapper around time module primarily for testing purposes
   35 
   36     This class is a wrapper around time.time()  and time.gmtime(). When
   37     performing unit test, it is very useful to get a fixed value from
   38     these functions.  Thus, time.time() and time.gmtime() should never
   39     be called directly.  This wrapper should be called instead. The API
   40     are equivalent.
   41     """
   42 
   43     myTime = None
   44     alternateNowTime = None
   45     alternateNow = None
   46 
   47     @staticmethod
   48     def setAlternateNow(t):
   49         """Set current time.
   50 
   51         Use None in order to always get the real current time.
   52 
   53         @param t the time to set or None
   54         """
   55 
   56         MyTime.alternateNowTime = t
   57         MyTime.alternateNow = \
   58             datetime.datetime.fromtimestamp(t) if t is not None else None
   59 
   60     @staticmethod
   61     def setTime(t):
   62         """Set current time.
   63 
   64         Use None in order to always get the real current time.
   65 
   66         @param t the time to set or None
   67         """
   68 
   69         MyTime.myTime = t
   70 
   71     @staticmethod
   72     def time():
   73         """Decorate time.time() for the purpose of testing mocking
   74 
   75         @return time.time() if setTime was called with None
   76         """
   77 
   78         if MyTime.myTime is None:
   79             return time.time()
   80         else:
   81             return MyTime.myTime
   82 
   83     @staticmethod
   84     def gmtime():
   85         """Decorate time.gmtime() for the purpose of testing mocking
   86 
   87         @return time.gmtime() if setTime was called with None
   88         """
   89         if MyTime.myTime is None:
   90             return time.gmtime()
   91         else:
   92             return time.gmtime(MyTime.myTime)
   93 
   94     @staticmethod
   95     def now():
   96         """Decorate datetime.now() for the purpose of testing mocking
   97 
   98         @return datetime.now() if setTime was called with None
   99         """
  100         if MyTime.myTime is None:
  101             return datetime.datetime.now()
  102         if MyTime.myTime == MyTime.alternateNowTime:
  103             return MyTime.alternateNow
  104         return datetime.datetime.fromtimestamp(MyTime.myTime)
  105 
  106     @staticmethod
  107     def localtime(x=None):
  108         """Decorate time.localtime() for the purpose of testing mocking
  109 
  110         @return time.localtime() if setTime was called with None
  111         """
  112         if MyTime.myTime is None or x is not None:
  113             return time.localtime(x)
  114         else:
  115             return time.localtime(MyTime.myTime)
  116     
  117     @staticmethod
  118     def time2str(unixTime, format="%Y-%m-%d %H:%M:%S"):
  119         """Convert time to a string representing as date and time using given format.
  120         Default format is ISO 8601, YYYY-MM-DD HH:MM:SS without microseconds.
  121 
  122         @return ISO-capable string representation of given unixTime
  123         """
  124         return datetime.datetime.fromtimestamp(
  125             unixTime).replace(microsecond=0).strftime(format)
  126 
  127     ## precreate/precompile primitives used in str2seconds:
  128 
  129     ## preparing expression:
  130     _str2sec_prep = re.compile(r"(?i)(?<=[a-z])(\d)")
  131     ## finally expression:
  132     _str2sec_fini = re.compile(r"(\d)\s+(\d)")
  133     ## wrapper for each sub part:
  134     _str2sec_subpart = r"(?i)(?<=[\d\s])(%s)\b"
  135     ## parts to be replaced - pair of (regexp x replacement):
  136     _str2sec_parts = (
  137         (re.compile(_str2sec_subpart % r"days?|da|dd?"),      "*"+str(24*60*60)),
  138         (re.compile(_str2sec_subpart % r"weeks?|wee?|ww?"),   "*"+str(7*24*60*60)),
  139         (re.compile(_str2sec_subpart % r"months?|mon?"),      "*"+str((365*3+366)*24*60*60/4/12)),
  140         (re.compile(_str2sec_subpart % r"years?|yea?|yy?"),   "*"+str((365*3+366)*24*60*60/4)),
  141         (re.compile(_str2sec_subpart % r"seconds?|sec?|ss?"), "*"+str(1)),
  142         (re.compile(_str2sec_subpart % r"minutes?|min?|mm?"), "*"+str(60)),
  143         (re.compile(_str2sec_subpart % r"hours?|hou?|hh?"),   "*"+str(60*60)),
  144     )
  145 
  146     @staticmethod
  147     def str2seconds(val):
  148         """Wraps string expression like "1h 2m 3s" into number contains seconds (3723).
  149         The string expression will be evaluated as mathematical expression, spaces between each groups 
  150           will be wrapped to "+" operand (only if any operand does not specified between).
  151         Because of case insensitivity and overwriting with minutes ("m" or "mm"), the short replacement for month
  152           are "mo" or "mon".
  153         Ex: 1hour+30min = 5400
  154             0d 1h 30m   = 5400
  155             1year-6mo   = 15778800
  156             6 months    = 15778800
  157         warn: month is not 30 days, it is a year in seconds / 12, the leap years will be respected also:
  158               >>>> float(str2seconds("1month")) / 60 / 60 / 24
  159               30.4375
  160               >>>> float(str2seconds("1year")) / 60 / 60 / 24
  161               365.25    
  162         
  163         @returns number (calculated seconds from expression "val")
  164         """
  165         if isinstance(val, (int, long, float, complex)):
  166             return val
  167         # replace together standing abbreviations, example '1d12h' -> '1d 12h':
  168         val = MyTime._str2sec_prep.sub(r" \1", val)
  169         # replace abbreviation with expression:
  170         for rexp, rpl in MyTime._str2sec_parts:
  171             val = rexp.sub(rpl, val)
  172         val = MyTime._str2sec_fini.sub(r"\1+\2", val)
  173         return eval(val)