mirror of https://github.com/fail2ban/fail2ban
				
				
				
			code review and few new test cases
							parent
							
								
									db5ee0842a
								
							
						
					
					
						commit
						d23d103f96
					
				| 
						 | 
				
			
			@ -167,6 +167,7 @@ class Actions(JailThread, Mapping):
 | 
			
		|||
	# @param value the time
 | 
			
		||||
	
 | 
			
		||||
	def setBanTime(self, value):
 | 
			
		||||
		value = MyTime.str2seconds(value)
 | 
			
		||||
		self.__banManager.setBanTime(value)
 | 
			
		||||
		logSys.info("Set banTime = %s" % value)
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,32 +98,34 @@ class MyTime:
 | 
			
		|||
		else:
 | 
			
		||||
			return time.localtime(MyTime.myTime)
 | 
			
		||||
 | 
			
		||||
	## 
 | 
			
		||||
	# Wraps string expression like "1h 2m 3s" into number contains seconds (3723).
 | 
			
		||||
	# The string expression will be evaluated as mathematical expression, spaces between each groups 
 | 
			
		||||
	#   will be wrapped to "+" operand (only if any operand does not specified between).
 | 
			
		||||
	# Because of case insensitivity and overwriting with minutes ("m" or "mm"), the short replacement for month
 | 
			
		||||
	#   are "mo" or "mon" (like %b by date formating).
 | 
			
		||||
	# Ex: 1hour+30min = 5400
 | 
			
		||||
	#     0d 1h 30m   = 5400
 | 
			
		||||
	#     1year-6mo   = 15778800
 | 
			
		||||
	#     6 months    = 15778800
 | 
			
		||||
	# warn: month is not 30 days, it is a year in seconds / 12, the leap years will be respected also:
 | 
			
		||||
	#       >>>> float(Test.str2seconds("1month")) / 60 / 60 / 24
 | 
			
		||||
	#       30.4375
 | 
			
		||||
	#       >>>> float(Test.str2seconds("1year")) / 60 / 60 / 24
 | 
			
		||||
	#       365.25	
 | 
			
		||||
	#
 | 
			
		||||
	# @returns number (calculated seconds from expression "val")
 | 
			
		||||
 | 
			
		||||
	@staticmethod
 | 
			
		||||
	def str2seconds(val):
 | 
			
		||||
		"""Wraps string expression like "1h 2m 3s" into number contains seconds (3723).
 | 
			
		||||
		The string expression will be evaluated as mathematical expression, spaces between each groups 
 | 
			
		||||
		  will be wrapped to "+" operand (only if any operand does not specified between).
 | 
			
		||||
		Because of case insensitivity and overwriting with minutes ("m" or "mm"), the short replacement for month
 | 
			
		||||
		  are "mo" or "mon".
 | 
			
		||||
		Ex: 1hour+30min = 5400
 | 
			
		||||
		    0d 1h 30m   = 5400
 | 
			
		||||
		    1year-6mo   = 15778800
 | 
			
		||||
		    6 months    = 15778800
 | 
			
		||||
		warn: month is not 30 days, it is a year in seconds / 12, the leap years will be respected also:
 | 
			
		||||
		      >>>> float(str2seconds("1month")) / 60 / 60 / 24
 | 
			
		||||
		      30.4375
 | 
			
		||||
		      >>>> float(str2seconds("1year")) / 60 / 60 / 24
 | 
			
		||||
		      365.25	
 | 
			
		||||
		
 | 
			
		||||
		@returns number (calculated seconds from expression "val")
 | 
			
		||||
		"""
 | 
			
		||||
		if isinstance(val, (int, long, float, complex)):
 | 
			
		||||
			return val
 | 
			
		||||
		# replace together standing abbreviations, example '1d12h' -> '1d 12h':
 | 
			
		||||
		val = re.sub(r"(?i)(?<=[a-z])(\d)", r" \1", val)
 | 
			
		||||
		# replace abbreviation with expression:
 | 
			
		||||
		for rexp, rpl in (
 | 
			
		||||
			(r"days?|da|dd?", 24*60*60), (r"week?|wee?|ww?", 7*24*60*60), (r"months?|mon?", (365*3+366)*24*60*60/4/12), (r"years?|yea?|yy?", (365*3+366)*24*60*60/4), 
 | 
			
		||||
			(r"seconds?|sec?|ss?", 1), (r"minutes?|min?|mm?", 60), (r"hours?|ho|hh?", 60*60),
 | 
			
		||||
			(r"days?|da|dd?", 24*60*60), (r"weeks?|wee?|ww?", 7*24*60*60), (r"months?|mon?", (365*3+366)*24*60*60/4/12), 
 | 
			
		||||
			(r"years?|yea?|yy?", (365*3+366)*24*60*60/4), 
 | 
			
		||||
			(r"seconds?|sec?|ss?", 1), (r"minutes?|min?|mm?", 60), (r"hours?|hou?|hh?", 60*60),
 | 
			
		||||
		):
 | 
			
		||||
			val = re.sub(r"(?i)(?<=[\d\s])(%s)\b" % rexp, "*"+str(rpl), val)
 | 
			
		||||
		val = re.sub(r"(\d)\s+(\d)", r"\1+\2", val);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@ from StringIO import StringIO
 | 
			
		|||
from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack, getLogger
 | 
			
		||||
from ..helpers import splitcommaspace
 | 
			
		||||
from ..server.datetemplate import DatePatternRegex
 | 
			
		||||
from ..server.mytime import MyTime
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HelpersTest(unittest.TestCase):
 | 
			
		||||
| 
						 | 
				
			
			@ -229,3 +230,20 @@ class CustomDateFormatsTest(unittest.TestCase):
 | 
			
		|||
		self.assertEqual(
 | 
			
		||||
			date,
 | 
			
		||||
			datetime.datetime(2007, 1, 25, 16, 0))
 | 
			
		||||
 | 
			
		||||
class MyTimeTest(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
	def testStr2Seconds(self):
 | 
			
		||||
		# several formats / write styles:
 | 
			
		||||
		str2sec = MyTime.str2seconds
 | 
			
		||||
		self.assertEqual(str2sec('1y6mo30w15d12h35m25s'), 66821725)
 | 
			
		||||
		self.assertEqual(str2sec('2yy 3mo 4ww 10dd 5hh 30mm 20ss'), 74307620)
 | 
			
		||||
		self.assertEqual(str2sec('2 years 3 months 4 weeks 10 days 5 hours 30 minutes 20 seconds'), 74307620)
 | 
			
		||||
		self.assertEqual(str2sec('1 year + 1 month - 1 week + 1 day'), 33669000)
 | 
			
		||||
		self.assertEqual(str2sec('2 * 0.5 yea + 1*1 mon - 3*1/3 wee + 2/2 day - (2*12 hou 3*20 min 80 sec) '), 33578920.0)
 | 
			
		||||
		self.assertEqual(str2sec('2*.5y+1*1mo-3*1/3w+2/2d-(2*12h3*20m80s) '), 33578920.0)
 | 
			
		||||
		self.assertEqual(str2sec('1ye -2mo -3we -4da -5ho -6mi -7se'), 24119633)
 | 
			
		||||
		# month and year in days :
 | 
			
		||||
		self.assertEqual(float(str2sec("1 month")) / 60 / 60 / 24, 30.4375)
 | 
			
		||||
		self.assertEqual(float(str2sec("1 year")) / 60 / 60 / 24, 365.25)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,6 +133,7 @@ def gatherTests(regexps=None, no_network=False):
 | 
			
		|||
	tests.addTest(unittest.makeSuite(misctestcase.SetupTest))
 | 
			
		||||
	tests.addTest(unittest.makeSuite(misctestcase.TestsUtilsTest))
 | 
			
		||||
	tests.addTest(unittest.makeSuite(misctestcase.CustomDateFormatsTest))
 | 
			
		||||
	tests.addTest(unittest.makeSuite(misctestcase.MyTimeTest))
 | 
			
		||||
	# Database
 | 
			
		||||
	tests.addTest(unittest.makeSuite(databasetestcase.DatabaseTest))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -300,4 +301,4 @@ else:
 | 
			
		|||
			kernel32.CloseHandle(process)
 | 
			
		||||
			return True
 | 
			
		||||
		else:
 | 
			
		||||
			return False
 | 
			
		||||
			return False
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue