import re
import sys
+import locale
revision = '$Revision$'
revision = re.sub( r'\$', '', revision )
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__":
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 )
'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):
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)
)
)
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
#------------------------------------------------------------