Author: jezdez Date: 2011-04-22 05:02:47 -0700 (Fri, 22 Apr 2011) New Revision: 16071
Modified: django/trunk/django/contrib/humanize/templatetags/humanize.py django/trunk/docs/ref/contrib/humanize.txt django/trunk/tests/regressiontests/humanize/tests.py Log: Fixed #12771 -- Added naturaltime filter to humanize contrib app. Thanks, phinpho, djansoft and xtrqt. Modified: django/trunk/django/contrib/humanize/templatetags/humanize.py =================================================================== --- django/trunk/django/contrib/humanize/templatetags/humanize.py 2011-04-22 12:02:38 UTC (rev 16070) +++ django/trunk/django/contrib/humanize/templatetags/humanize.py 2011-04-22 12:02:47 UTC (rev 16071) @@ -2,7 +2,7 @@ from django.utils.encoding import force_unicode from django import template from django.template import defaultfilters -from datetime import date +from datetime import date, datetime import re register = template.Library() @@ -83,7 +83,7 @@ present day returns representing string. Otherwise, returns a string formatted according to settings.DATE_FORMAT. """ - try: + try: value = date(value.year, value.month, value.day) except AttributeError: # Passed value wasn't a date object @@ -100,3 +100,35 @@ return _(u'yesterday') return defaultfilters.date(value, arg) register.filter(naturalday) + +def naturaltime(value, arg=None): + """ + For date and time values shows how many seconds, minutes or hours ago compared to + current timestamp returns representing string. Otherwise, returns a string + formatted according to settings.DATE_FORMAT + """ + try: + value = datetime(value.year, value.month, value.day, value.hour, value.minute, value.second) + except AttributeError: + return value + except ValueError: + return value + + delta = datetime.now() - value + if delta.days != 0: + value = date(value.year, value.month, value.day) + return naturalday(value, arg) + elif delta.seconds == 0: + return _(u'now') + elif delta.seconds < 60: + return _(u'%s seconds ago' % (delta.seconds)) + elif delta.seconds / 60 < 2: + return _(r'a minute ago') + elif delta.seconds / 60 < 60: + return _(u'%s minutes ago' % (delta.seconds/60)) + elif delta.seconds / 60 / 60 < 2: + return _(u'an hour ago') + elif delta.seconds / 60 / 60 < 24: + return _(u'%s hours ago' % (delta.seconds/60/60)) + return naturalday(value, arg) +register.filter(naturaltime) Modified: django/trunk/docs/ref/contrib/humanize.txt =================================================================== --- django/trunk/docs/ref/contrib/humanize.txt 2011-04-22 12:02:38 UTC (rev 16070) +++ django/trunk/docs/ref/contrib/humanize.txt 2011-04-22 12:02:47 UTC (rev 16071) @@ -82,6 +82,31 @@ * Any other day is formatted according to given argument or the :setting:`DATE_FORMAT` setting if no argument is given. +.. templatefilter:: naturaltime + +naturaltime +----------- + +.. versionadded:: 1.4 + +For date and time values shows how many seconds, minutes or hours ago compared +to current timestamp returns representing string. Otherwise, it behaves like +:tfilter:`naturaldate`, so it can also take string argument for date formating. + +**Argument:** Date formatting string as described in the :tfilter:`date` tag. + +Examples (when 'now' is 17 Feb 2007 16:30:00): + + * ``17 Feb 2007 16:30:00`` becomes ``now``. + * ``17 Feb 2007 16:29:31`` becomes ``29 seconds ago``. + * ``17 Feb 2007 16:29:00`` becomes ``a minute ago``. + * ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``. + * ``17 Feb 2007 15:30:29`` becomes ``an hours ago``. + * ``17 Feb 2007 13:31:29`` becomes ``2 hours ago``. + * ``16 Feb 2007 13:31:29`` becomes ``yesterday``. + * Any other day is formatted according to given argument or the + :setting:`DATE_FORMAT` setting if no argument is given. + .. templatefilter:: ordinal ordinal Modified: django/trunk/tests/regressiontests/humanize/tests.py =================================================================== --- django/trunk/tests/regressiontests/humanize/tests.py 2011-04-22 12:02:38 UTC (rev 16070) +++ django/trunk/tests/regressiontests/humanize/tests.py 2011-04-22 12:02:47 UTC (rev 16071) @@ -1,4 +1,4 @@ -from datetime import timedelta, date +from datetime import timedelta, date, datetime from django.template import Template, Context, add_to_builtins from django.utils import unittest @@ -72,6 +72,32 @@ someday_result, u"I'm not a date value", None) self.humanize_tester(test_list, result_list, 'naturalday') + def test_naturaltime(self): + from django.template import defaultfilters + now = datetime.now() + seconds_ago = now - timedelta(seconds=30) + a_minute_ago = now - timedelta(minutes=1, seconds=30) + minutes_ago = now - timedelta(minutes=2) + an_hour_ago = now - timedelta(hours=1, minutes=30, seconds=30) + hours_ago = now - timedelta(hours=23, minutes=50, seconds=50) + + test_list = (now, a_minute_ago, an_hour_ago) + result_list = (_(u'now'), _(u'a minute ago'), _(u'an hour ago')) + self.humanize_tester(test_list, result_list, 'naturaltime') + + t = Template('{{ seconds_ago|%s }}' % 'naturaltime') + rendered = t.render(Context(locals())).strip() + self.assertTrue(u' seconds ago' in rendered) + + t = Template('{{ minutes_ago|%s }}' % 'naturaltime') + rendered = t.render(Context(locals())).strip() + self.assertTrue(u' minutes ago' in rendered) + + t = Template('{{ hours_ago|%s }}' % 'naturaltime') + rendered = t.render(Context(locals())).strip() + self.assertTrue(u' hours ago' in rendered) + + if __name__ == '__main__': unittest.main() -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-updates@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.