Robustified and improved utils.str.format a bit; added a simple test.

This commit is contained in:
Jeremy Fincher 2005-01-28 15:23:18 +00:00
parent 1f1d85f249
commit a19a979499
3 changed files with 64 additions and 12 deletions

View File

@ -281,6 +281,11 @@ registerChannelValue(supybot.reply.format, 'time',
for human reading should be formatted. Refer to the Python documentation for human reading should be formatted. Refer to the Python documentation
for the time module to see valid formatting characters for time for the time module to see valid formatting characters for time
formats.""")) formats."""))
def timestamp(t):
t = time.localtime(t)
format = conf.get(supybot.reply.format.time, dynamic.channel)
return time.strftime(format, t)
utils.str.timestamp = timestamp
registerGroup(supybot.reply.format.time, 'elapsed') registerGroup(supybot.reply.format.time, 'elapsed')
registerChannelValue(supybot.reply.format.time.elapsed, 'short', registerChannelValue(supybot.reply.format.time.elapsed, 'short',

View File

@ -38,8 +38,9 @@ import textwrap
import supybot.structures as structures import supybot.structures as structures
curry = new.instancemethod from iter import all, any
curry = new.instancemethod
chars = string.maketrans('', '') chars = string.maketrans('', '')
def rsplit(s, sep=None, maxsplit=-1): def rsplit(s, sep=None, maxsplit=-1):
@ -327,29 +328,67 @@ def toBool(s):
else: else:
raise ValueError, 'Invalid string for toBool: %s' % quoted(s) raise ValueError, 'Invalid string for toBool: %s' % quoted(s)
# Replace me!
def timestamp(t):
return time.ctime(t)
_formatRe = re.compile('%([bfhiLnpqst%])')
def format(s, *args, **kwargs): def format(s, *args, **kwargs):
kwargs.setdefault('decimalSeparator', decimalSeparator) """w00t.
kwargs.setdefault('thousandsSeparator', thousandsSeparator)
%: literal %.
i: integer
s: string
f: float
b: form of the verb 'to be' (takes an int)
h: form of the verb 'to have' (takes an int)
L: commaAndify (takes a list of strings)
p: pluralize (takes a string)
q: quoted (takes a string)
n: nItems (takes a 2-tuple of (n, item) or a 3-tuple of (n, between, item))
t: time, formated (takes an int)
"""
args = list(args) args = list(args)
args.reverse() # For more efficiency popping. args.reverse() # For more efficient popping.
def sub(match): def sub(match):
char = match.group(1) char = match.group(1)
if char == 's': # Plain string. if char == 's':
return str(args.pop()) return str(args.pop())
elif char == 'i': # Integer elif char == 'i':
# XXX Improve me! # XXX Improve me!
return str(args.pop()) return str(args.pop())
elif char == 'f': # Float elif char == 'f':
# XXX Improve me! # XXX Improve me!
return str(args.pop()) return str(args.pop())
elif char == 'b': # form of the verb 'to be' elif char == 'b':
return be(args.pop()) return be(args.pop())
elif char == 'h': # form of the verb 'to have' elif char == 'h':
return has(args.pop()) return has(args.pop())
elif char == 'L': # commaAndify the list. elif char == 'L':
return commaAndify(args.pop()) return commaAndify(args.pop())
elif char == 'p':
return pluralize(args.pop())
elif char == 'q':
return quoted(args.pop())
elif char == 'n':
t = args.pop()
if not isinstance(t, (tuple, list)):
raise ValueError, 'Invalid value for %%n in format: %s' % t
if len(t) == 2:
return nItems(*t)
elif len(t) == 3:
return nItems(t[0], t[2], between=t[1])
else:
raise ValueError, 'Invalid value for %%n in format: %s' % t
elif char == 't':
return timestamp(args.pop())
elif char == '%':
return '%'
else: else:
assert False, 'Invalid char in sub (in format).' raise ValueError, 'Invalid char in sub (in format).'
return _formatRe.sub(sub, s) try:
return _formatRe.sub(sub, s)
except IndexError:
raise ValueError, 'Extra format chars in format spec: %r' % s
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

View File

@ -417,5 +417,13 @@ class WebTest(SupyTestCase):
url = 'http://slashdot.org/' url = 'http://slashdot.org/'
self.failUnless(len(utils.web.getUrl(url, 1024)) == 1024) self.failUnless(len(utils.web.getUrl(url, 1024)) == 1024)
class FormatTestCase(SupyTestCase):
def testNormal(self):
format = utils.str.format
self.assertEqual(format('I have %n of fruit: %L.', (3, 'kind'),
['apples', 'oranges', 'watermelon']),
'I have 3 kinds of fruit: '
'apples, oranges, and watermelon.')
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: