Skip to content

Commit

Permalink
Réécris le templatetag 'minute_to_duration'
Browse files Browse the repository at this point in the history
Ce commit réécrit le templatetag 'minute_to_duration' en utilisant 'timesince' (de base dans Django), passant ainsi de 130 lignes à 15 et rendant l'internationalisation du résultat automatique.

Il déplace également les tests unitaires des templatetags dans le dossier approprié.
  • Loading branch information
rezemika authored and artragis committed Jan 8, 2018
1 parent a815bff commit 8969492
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 179 deletions.
2 changes: 1 addition & 1 deletion templates/tutorialv2/includes/tags_authors.part.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
<br/>
<span>
{% if online and reading_time and not is_part_or_chapter %}
{% trans "Temps de lecture estimé : " %}{{ reading_time | minute_to_duration:"long"}}
{% trans "Temps de lecture estimé : " %}{{ reading_time|minute_to_duration }}
{% elif online and not is_part_or_chapter %}
{% trans "Temps de lecture estimé à moins d’une minute." %}
{% endif %}
Expand Down
143 changes: 15 additions & 128 deletions zds/utils/templatetags/minute_to_duration.py
Original file line number Diff line number Diff line change
@@ -1,137 +1,24 @@
from django import template
from django.template import defaultfilters as filters
from django.utils.translation import ugettext as _
import math
import datetime

# Set register
register = template.Library()


# Register filter
@register.filter('minute_to_duration')
def minute_to_duration(value, duration_format=''):

def minute_to_duration(value):
"""
#######################################################
# #
# Minutes-to-Duration Template Tag #
# Inspired by Dan Ward 2009 (http://d-w.me) #
# Modified by Anto59290 for Zeste de Savoir #
# #
#######################################################
Usage: {{ VALUE|minute_to_duration[:"long"] }}
NOTE: Please read up 'Custom template tags and filters'
if you are unsure as to how the template tag is
implemented in your project.
Display a human-readable reading-time (or any other duration)
from a duration in minutes, with a granularity of 15 minutes.
"""

# Place seconds in to integer
secs = int(value * 60)

# If seconds are greater than 0
if secs > 0:

# Place durations of given units in to variables
daySecs = 86400
hourSecs = 3600
minSecs = 60
# To how many minutes we round up the result when input string is more than an hour
roundPrecision = 15

# If short string is enabled
if duration_format != 'long':

# Set short names
dayUnitName = ' jour'
hourUnitName = ' h'
minUnitName = ' min'

# Set short duration unit splitters
lastDurSplitter = ' '
nextDurSplitter = lastDurSplitter

# If short string is not provided or any other value
else:

# Set long names
dayUnitName = ' jour'
hourUnitName = ' heure'
minUnitName = ' minute'

# Set long duration unit splitters
lastDurSplitter = ' et '
nextDurSplitter = ', '

# Create string to hold outpout
durationString = ''

# Calculate number of days from seconds
days = int(math.floor(secs / int(daySecs)))

# Subtract days from seconds
secs = secs - (days * int(daySecs))

# Calculate number of hours from seconds (minus number of days)
hours = int(math.floor(secs / int(hourSecs)))

# Subtract hours from seconds
secs = secs - (hours * int(hourSecs))

# Calculate number of minutes from seconds (minus number of days and hours)
minutes = int(math.floor(secs / int(minSecs)))

# If duration is more than an hour we round up to avoid "5 hours and 7 minutes"
if hours > 1:
minutes = minutes - (minutes % roundPrecision)

# If number of days is greater than 0
if days > 0:

# Add multiple days to duration string
durationString += ' ' + str(days) + dayUnitName + (days > 1 and 's' or '')

# Determine if next string is to be shown
if hours > 0:

# If there are no more units after this
if minutes <= 0 and days != 0:

# Set hour splitter to last
hourSplitter = lastDurSplitter

# If there are unit after this
else:
# Set hour splitter to next
if (len(durationString) > 0 and nextDurSplitter):
hourSplitter = nextDurSplitter
else:
hourSplitter = ''

# If number of hours is greater than 0
if hours > 0:

# Add multiple days to duration string
durationString += hourSplitter + ' ' + str(hours) + hourUnitName + (hours > 1 and 's' or '')

# Determine if next string is to be shown
if minutes > 0 and hours > 0:
# Set minute splitter to last
minSplitter = lastDurSplitter
else:
minSplitter = ''

# If number of minutes is greater than 0
if minutes > 0:

# Add multiple days to duration string
durationString += minSplitter + ' ' + str(minutes) + minUnitName + (minutes > 1 and 's' or '')

# Return duration string
return durationString.strip()

# If seconds are not greater than 0
else:

# Provide 'No duration' message
return _('Inconnu')
now = datetime.datetime.now()
if value <= 0:
return ''
# Rounds value to avoid "1 hour, 2 minutes".
if 55 <= value <= 65:
value = 60
elif value > 65:
value = value - (value % 15)
delta = now - datetime.timedelta(minutes=value)
return filters.timesince(delta).replace(', ', _(' et '))
49 changes: 49 additions & 0 deletions zds/utils/templatetags/tests/tests_joinby.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from django.test import TestCase
from zds.utils.templatetags.joinby import joinby


class JoinByTest(TestCase):
def test_main(self):
self.assertEqual(joinby(()), '')

l = ['apple', 'banana', 'orange', 'clementine']
self.assertEqual(
joinby(l, final_separator=', '),
'apple, banana, orange, clementine'
)

l = ['apple', 'banana', 'orange', 'clementine']
self.assertEqual(
joinby(l, final_separator=' and '),
'apple, banana, orange and clementine'
)

l = ['apple', 'banana', 'orange', 'clementine']
self.assertEqual(
joinby(l, separator=';', final_separator=';'),
'apple;banana;orange;clementine'
)

l = [1, 2, 3, 4]
self.assertEqual(
joinby(l, separator=';', final_separator=';'),
'1;2;3;4'
)

l = ['Clem']
self.assertEqual(
joinby(l, final_separator=' and '),
'Clem'
)

l = ['Clem', 'Chuck Norris']
self.assertEqual(
joinby(l, final_separator=' and '),
'Clem and Chuck Norris'
)

l = ['Clem', 'Chuck Norris', 'Arnold Schwarzenegger']
self.assertEqual(
joinby(l, final_separator=' and '),
'Clem, Chuck Norris and Arnold Schwarzenegger'
)
40 changes: 40 additions & 0 deletions zds/utils/templatetags/tests/tests_minute_to_duration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django.test import TestCase
from zds.utils.templatetags.minute_to_duration import minute_to_duration


class TemplateTagsTest(TestCase):
def test_main(self):
self.assertEqual(minute_to_duration(0), '')
self.assertEqual(minute_to_duration(-1), '')
self.assertEqual(
minute_to_duration(1),
'1 minute'
)
self.assertEqual(
minute_to_duration(2),
'2 minutes'
)
self.assertEqual(
minute_to_duration(59),
'1 heure'
)
self.assertEqual(
minute_to_duration(60),
'1 heure'
)
self.assertEqual(
minute_to_duration(72),
'1 heure'
)
self.assertEqual(
minute_to_duration(90),
'1 heure et 30 minutes'
)
self.assertEqual(
minute_to_duration(105),
'1 heure et 45 minutes'
)
self.assertEqual(
minute_to_duration(110),
'1 heure et 45 minutes'
)
50 changes: 0 additions & 50 deletions zds/utils/tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from zds.utils.models import Alert
from zds.utils.templatetags.interventions import alerts_list
from zds.utils.templatetags.remove_url_scheme import remove_url_scheme
from zds.utils.templatetags.joinby import joinby


class Misc(TestCase):
Expand Down Expand Up @@ -55,53 +54,4 @@ def test_remove_url_scheme(self):

for element in oracle:
# as we are not in py3 we do not have subTest method. so we use a bare for loop.
self.assertEquals(remove_url_scheme(element.given), element.expected)
self.assertEqual(remove_url_scheme(element.given), element.expected)


class TemplateTagsTest(TestCase):
def test_joinby(self):
self.assertEqual(joinby([]), '')
self.assertEqual(joinby(()), '')

l = ['apple', 'banana', 'orange', 'clementine']
self.assertEqual(
joinby(l, final_separator=', '),
'apple, banana, orange, clementine'
)

l = ['apple', 'banana', 'orange', 'clementine']
self.assertEqual(
joinby(l, final_separator=' and '),
'apple, banana, orange and clementine'
)

l = ['apple', 'banana', 'orange', 'clementine']
self.assertEqual(
joinby(l, separator=';', final_separator=';'),
'apple;banana;orange;clementine'
)

l = [1, 2, 3, 4]
self.assertEqual(
joinby(l, separator=';', final_separator=';'),
'1;2;3;4'
)

l = ['Clem']
self.assertEqual(
joinby(l, final_separator=' and '),
'Clem'
)

l = ['Clem', 'Chuck Norris']
self.assertEqual(
joinby(l, final_separator=' and '),
'Clem and Chuck Norris'
)

l = ['Clem', 'Chuck Norris', 'Arnold Schwarzenegger']
self.assertEqual(
joinby(l, final_separator=' and '),
'Clem, Chuck Norris and Arnold Schwarzenegger'
)

0 comments on commit 8969492

Please sign in to comment.