]> Frank Brehm's Git Trees - my-stuff/py-logrotate.git/commitdiff
check for period
authorFrank Brehm <frank@brehm-online.com>
Sat, 7 May 2011 21:07:29 +0000 (21:07 +0000)
committerFrank Brehm <frank@brehm-online.com>
Sat, 7 May 2011 21:07:29 +0000 (21:07 +0000)
git-svn-id: http://svn.brehm-online.com/svn/my-stuff/python/PyLogrotate/trunk@227 ec8d2aa5-1599-4edb-8739-2b3a1bc399aa

LogRotateCommon.py
LogRotateConfig.py
test/apache2

index 8490ee06bcd59b0d8fed173374d427b13876c0de..29c526d21cb9e8bda5a932523241486ce012a9ad 100755 (executable)
@@ -15,6 +15,7 @@
 
 import re
 import sys
+import locale
 
 revision = '$Revision$'
 revision = re.sub( r'\$', '', revision )
@@ -148,6 +149,157 @@ def email_valid(address):
 
     return True
 
+#------------------------------------------------------------------------
+
+def period2days(period, use_locale_radix = False, verbose = 0):
+    '''
+    Converts the given string of the form »5d 8h« in an amount of days.
+    It raises a ValueError on invalid values.
+
+    Special values of period:
+        - now (returns 0)
+        - never (returns float('inf'))
+
+    Valid units for periods are:
+        - »h[ours]«
+        - »d[ays]«   - default, if bare numbers are given
+        - »w[eeks]«  - == 7 days
+        - »m[onths]« - == 30 days
+        - »y[ears]«  - == 365 days
+
+    @param period:           the period to convert
+    @type period:            str
+    @param use_locale_radix: use the locale version of radix instead of the
+                             english decimal dot.
+    @type use_locale_radix:  bool
+    @param verbose:          level of verbosity
+    @type verbose:           int
+
+    @return: amount of days
+    @rtype:  float
+    '''
+
+    if period is None:
+        raise ValueError("Given period is »None«")
+
+    value = str(period).strip().lower()
+    if period == '':
+        raise ValueError("Given period was empty")
+
+    if verbose > 4:
+        sys.stderr.write("period2days() called with: »%s«\n" % (period))
+
+    if period == 'now':
+        return float(0)
+
+    # never - returns a positive infinite value
+    if period == 'never':
+        return float('inf')
+
+    days = float(0)
+    radix = '.'
+    if use_locale_radix:
+        radix = locale.RADIXCHAR
+    radix = re.escape(radix)
+    if verbose > 5:
+        sys.stderr.write("period2days(): using radix »%s«\n" % (radix))
+
+    # Search for hours in value
+    pattern = r'(\d+(?:' + radix + r'\d*)?)\s*h(?:ours?)?'
+    if verbose > 5:
+        sys.stderr.write("period2days(): pattern »%s«\n" % (pattern))
+    match = re.search(pattern, value, re.IGNORECASE)
+    if match:
+        hours_str = match.group(1)
+        if use_locale_radix:
+            hours_str = re.sub(radix, '.', hours_str, 1)
+        hours = float(hours_str)
+        days += (hours/24)
+        if verbose > 4:
+            sys.stderr.write("period2days(): found %f hours.\n" %(hours))
+        value = re.sub(pattern, '', value, re.IGNORECASE)
+    if verbose > 5:
+        sys.stderr.write("period2days(): rest after hours: »%s«\n" %(value))
+
+    # Search for weeks in value
+    pattern = r'(\d+(?:' + radix + r'\d*)?)\s*w(?:eeks?)?'
+    if verbose > 5:
+        sys.stderr.write("period2days(): pattern »%s«\n" % (pattern))
+    match = re.search(pattern, value, re.IGNORECASE)
+    if match:
+        weeks_str = match.group(1)
+        if use_locale_radix:
+            weeks_str = re.sub(radix, '.', weeks_str, 1)
+        weeks = float(weeks_str)
+        days += (weeks*7)
+        if verbose > 4:
+            sys.stderr.write("period2days(): found %f weeks.\n" %(weeks))
+        value = re.sub(pattern, '', value, re.IGNORECASE)
+    if verbose > 5:
+        sys.stderr.write("period2days(): rest after weeks: »%s«\n" %(value))
+
+    # Search for months in value
+    pattern = r'(\d+(?:' + radix + r'\d*)?)\s*m(?:onths?)?'
+    if verbose > 5:
+        sys.stderr.write("period2days(): pattern »%s«\n" % (pattern))
+    match = re.search(pattern, value, re.IGNORECASE)
+    if match:
+        months_str = match.group(1)
+        if use_locale_radix:
+            months_str = re.sub(radix, '.', months_str, 1)
+        months = float(months_str)
+        days += (months*30)
+        if verbose > 4:
+            sys.stderr.write("period2days(): found %f months.\n" %(months))
+        value = re.sub(pattern, '', value, re.IGNORECASE)
+    if verbose > 5:
+        sys.stderr.write("period2days(): rest after months: »%s«\n" %(value))
+
+    # Search for years in value
+    pattern = r'(\d+(?:' + radix + r'\d*)?)\s*y(?:ears?)?'
+    if verbose > 5:
+        sys.stderr.write("period2days(): pattern »%s«\n" % (pattern))
+    match = re.search(pattern, value, re.IGNORECASE)
+    if match:
+        years_str = match.group(1)
+        if use_locale_radix:
+            years_str = re.sub(radix, '.', years_str, 1)
+        years = float(years_str)
+        days += (years*365)
+        if verbose > 4:
+            sys.stderr.write("period2days(): found %f years.\n" %(years))
+        value = re.sub(pattern, '', value, re.IGNORECASE)
+    if verbose > 5:
+        sys.stderr.write("period2days(): rest after years: »%s«\n" %(value))
+
+    # At last search for days in value
+    pattern = r'(\d+(?:' + radix + r'\d*)?)\s*(?:d(?:ays?)?)?'
+    if verbose > 5:
+        sys.stderr.write("period2days(): pattern »%s«\n" % (pattern))
+    match = re.search(pattern, value, re.IGNORECASE)
+    if match:
+        days_str = match.group(1)
+        if use_locale_radix:
+            days_str = re.sub(radix, '.', days_str, 1)
+        days_float = float(days_str)
+        days += days_float
+        if verbose > 4:
+            sys.stderr.write("period2days(): found %f days.\n" %(days_float))
+        value = re.sub(pattern, '', value, re.IGNORECASE)
+    if verbose > 5:
+        sys.stderr.write("period2days(): rest after days: »%s«\n" %(value))
+
+    # warn, if there is a rest
+    if re.search(r'^\s*$', value) is None:
+        sys.stderr.write(
+            "period2days(): invalid content for a period: »%s«\n" %(value)
+        )
+
+    if verbose > 4:
+        sys.stderr.write("period2days(): total %f days found.\n" %(days))
+
+    return days
+
 #========================================================================
 
 if __name__ == "__main__":
index 3598821a49b557e37aa48bb3d93b5e687872998b..47e31950946e8bab63917ff9adbe940b18398336 100755 (executable)
@@ -20,7 +20,7 @@ import pprint
 import os
 import os.path
 
-from LogRotateCommon import split_parts, email_valid
+from LogRotateCommon import split_parts, email_valid, period2days
 
 revision = '$Revision$'
 revision = re.sub( r'\$', '', revision )
@@ -97,6 +97,23 @@ path_options = (
     'pidfile',
 )
 
+valid_periods = {
+  'hourly':   (1/24),
+  '2hourly':  (1/12),
+  '4hourly':  (1/6),
+  '6hourly':  (1/4),
+  '12hourly': (1/2),
+  'daily':    1,
+  '2daily':   2,
+  'weekly':   7,
+  'monthly':  30,
+  '2monthly': 60,
+  '4monthly': 120,
+  '6monthly': 182,
+  'yearly':   365,
+}
+
+
 #========================================================================
 
 class LogrotateConfigurationError(Exception):
@@ -1130,7 +1147,7 @@ class LogrotateConfigurationReader(object):
             if key in path_options:
                 if not os.path.abspath(val):
                     self.logger.warning(
-                        ( _("Value »%s« for option »%s« is not an absolute "
+                        ( _("Value »%s« for option »%s« is not "
                              + "an absolute path") % (val, key)
                         )
                     )
@@ -1144,6 +1161,45 @@ class LogrotateConfigurationReader(object):
             directive[key] = val
             return True
 
+        # Check for rotation period
+        pattern = r'^(' + '|'.join(valid_periods.keys()) + r'|period)$'
+        match = re.search(pattern, option, re.IGNORECASE)
+        if match:
+            key = match.group(1).lower()
+            if self.verbose > 4:
+                self.logger.debug(
+                    ( _("Checking »period«: key »%s«, value »%s«. "
+                        + "(file »%s«, line %s)")
+                      % (key, val, filename, linenr)
+                    )
+                )
+            option_value = 1
+            if key in valid_periods:
+                if (val is not None) and (re.search(r'^\s*$', val) is None):
+                    self.logger.warning(
+                        ( _("Option »%s« may not have a value (»%s«). "
+                            + "(file »%s«, line %s)")
+                            %(key, val, filename, linenr)
+                        )
+                    )
+                option_value = valid_periods[key]
+            else:
+                try:
+                    option_value = period2days(val, verbose = self.verbose)
+                except ValueError, e:
+                    self.logger.warning(
+                        ( _("Invalid period definition: »%s«") %(val) )
+                    )
+                    return False
+            if self.verbose > 4:
+                self.logger.debug(
+                    ( _("Setting »period« to %f days. (file »%s«, line %s)")
+                      % (option_value, filename, linenr)
+                    )
+                )
+            directive['period'] = option_value
+            return True
+
         return True
 
     #------------------------------------------------------------
index 1f24f145888d04f0deeff346a326099c59d421c8..fce39be2944a3f533f53ebd91bc244467cdb9e8c 100644 (file)
@@ -11,6 +11,7 @@
   rotate 10
   error bla
   weekly
+  #period 4.5days 2 hours 3.4y
   size 1m
   mail test@uhu-banane.de
   olddir /var/log/apache2/%Y-%m