Add duration parsing

This commit is contained in:
Ivan Habunek 2022-12-01 10:20:50 +01:00
parent 6ae2ed623a
commit 0e13914fce
No known key found for this signature in database
GPG Key ID: F5F0623FF5EBCB3D
2 changed files with 83 additions and 0 deletions

View File

@ -1,3 +1,7 @@
from argparse import ArgumentTypeError
import pytest
from toot.console import duration
from toot.wcstring import wc_wrap, trunc, pad, fit_text
@ -155,3 +159,45 @@ def test_wc_wrap_indented():
"dolores. Illo reiciendis nulla ea. Facilis nostrum",
"non qui inventore sit.",
]
def test_duration():
# Long hand
assert duration("1 second") == 1
assert duration("1 seconds") == 1
assert duration("100 second") == 100
assert duration("100 seconds") == 100
assert duration("5 minutes") == 5 * 60
assert duration("5 minutes 10 seconds") == 5 * 60 + 10
assert duration("1 hour 5 minutes") == 3600 + 5 * 60
assert duration("1 hour 5 minutes 1 second") == 3600 + 5 * 60 + 1
assert duration("5 days") == 5 * 86400
assert duration("5 days 3 minutes") == 5 * 86400 + 3 * 60
assert duration("5 days 10 hours 3 minutes 1 second") == 5 * 86400 + 10 * 3600 + 3 * 60 + 1
# Short hand
assert duration("1s") == 1
assert duration("100s") == 100
assert duration("5m") == 5 * 60
assert duration("5m10s") == 5 * 60 + 10
assert duration("5m 10s") == 5 * 60 + 10
assert duration("1h5m1s") == 3600 + 5 * 60 + 1
assert duration("1h 5m 1s") == 3600 + 5 * 60 + 1
assert duration("5d") == 5 * 86400
assert duration("5d3m") == 5 * 86400 + 3 * 60
assert duration("5d 3m") == 5 * 86400 + 3 * 60
assert duration("5d 10h 3m 1s") == 5 * 86400 + 10 * 3600 + 3 * 60 + 1
assert duration("5d10h3m1s") == 5 * 86400 + 10 * 3600 + 3 * 60 + 1
with pytest.raises(ArgumentTypeError):
duration("")
with pytest.raises(ArgumentTypeError):
duration("100")
# Wrong order
with pytest.raises(ArgumentTypeError):
duration("1m1d")
with pytest.raises(ArgumentTypeError):
duration("banana")

View File

@ -2,6 +2,7 @@
import logging
import os
import re
import shutil
import sys
@ -40,6 +41,42 @@ def timeline_count(value):
return n
DURATION_UNITS = {
"m": 60,
"h": 60 * 60,
"d": 60 * 60 * 24,
}
def duration(value: str):
match = re.match(r"""^
(([0-9]+)\s*(days|day|d))?\s*
(([0-9]+)\s*(hours|hour|h))?\s*
(([0-9]+)\s*(minutes|minute|m))?\s*
(([0-9]+)\s*(seconds|second|s))?\s*
$""", value, re.X)
if not match:
raise ArgumentTypeError(f"Invalid duration: {value}")
days = match.group(2)
hours = match.group(5)
minutes = match.group(8)
seconds = match.group(11)
days = int(match.group(2) or 0) * 60 * 60 * 24
hours = int(match.group(5) or 0) * 60 * 60
minutes = int(match.group(8) or 0) * 60
seconds = int(match.group(11) or 0)
duration = days + hours + minutes + seconds
if duration == 0:
raise ArgumentTypeError("Empty duration")
return duration
def editor(value):
if not value:
raise ArgumentTypeError(