server/util: add date time parser
This commit is contained in:
parent
60a677edf4
commit
d44bcdf3da
4 changed files with 106 additions and 1 deletions
|
@ -100,6 +100,15 @@ user@host:szuru/server$ source python_modules/bin/activate # enters the sandbox
|
|||
`alembic` should have been installed during installation of `szurubooru`'s
|
||||
dependencies.
|
||||
|
||||
4. Run the tests:
|
||||
|
||||
```console
|
||||
(python_modules) user@host:szuru/server$ green
|
||||
```
|
||||
|
||||
`green` should have been installed during installation of `szurubooru`'s
|
||||
dependencies.
|
||||
|
||||
It is recommended to rebuild the frontend after each change to configuration.
|
||||
|
||||
|
||||
|
|
|
@ -3,3 +3,4 @@ configobj>=5.0.6
|
|||
falcon>=0.3.0
|
||||
psycopg2>=2.6.1
|
||||
SQLAlchemy>=1.0.12
|
||||
green>=2.4.0
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
''' Exports dotdict. '''
|
||||
''' Exports miscellaneous functions and data structures. '''
|
||||
|
||||
import datetime
|
||||
import re
|
||||
from szurubooru.errors import ValidationError
|
||||
|
||||
class dotdict(dict): # pylint: disable=invalid-name
|
||||
'''dot.notation access to dictionary attributes'''
|
||||
|
@ -6,3 +10,52 @@ class dotdict(dict): # pylint: disable=invalid-name
|
|||
return self.get(attr)
|
||||
__setattr__ = dict.__setitem__
|
||||
__delattr__ = dict.__delitem__
|
||||
|
||||
def parse_time_range(value, timezone=datetime.timezone(datetime.timedelta())):
|
||||
''' Returns tuple containing min/max time for given text representation. '''
|
||||
one_day = datetime.timedelta(days=1)
|
||||
one_second = datetime.timedelta(seconds=1)
|
||||
|
||||
value = value.lower()
|
||||
if not value:
|
||||
raise ValidationError('Empty date format.')
|
||||
|
||||
if value == 'today':
|
||||
now = datetime.datetime.now(tz=timezone)
|
||||
return (
|
||||
datetime.datetime(now.year, now.month, now.day, 0, 0, 0),
|
||||
datetime.datetime(now.year, now.month, now.day, 0, 0, 0)
|
||||
+ one_day - one_second)
|
||||
|
||||
if value == 'yesterday':
|
||||
now = datetime.datetime.now(tz=timezone)
|
||||
return (
|
||||
datetime.datetime(now.year, now.month, now.day, 0, 0, 0) - one_day,
|
||||
datetime.datetime(now.year, now.month, now.day, 0, 0, 0)
|
||||
- one_second)
|
||||
|
||||
match = re.match('^(\d{4})$', value)
|
||||
if match:
|
||||
year = int(match.group(1))
|
||||
return (
|
||||
datetime.datetime(year, 1, 1),
|
||||
datetime.datetime(year + 1, 1, 1) - one_second)
|
||||
|
||||
match = re.match('^(\d{4})-(\d{1,2})$', value)
|
||||
if match:
|
||||
year = int(match.group(1))
|
||||
month = int(match.group(2))
|
||||
return (
|
||||
datetime.datetime(year, month, 1),
|
||||
datetime.datetime(year, month + 1, 1) - one_second)
|
||||
|
||||
match = re.match('^(\d{4})-(\d{1,2})-(\d{1,2})$', value)
|
||||
if match:
|
||||
year = int(match.group(1))
|
||||
month = int(match.group(2))
|
||||
day = int(match.group(3))
|
||||
return (
|
||||
datetime.datetime(year, month, day),
|
||||
datetime.datetime(year, month, day + 1) - one_second)
|
||||
|
||||
raise ValidationError('Invalid date format: %r.' % value)
|
||||
|
|
42
server/tests/test_util.py
Normal file
42
server/tests/test_util.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
import unittest
|
||||
from datetime import datetime
|
||||
import szurubooru.util
|
||||
from szurubooru.util import parse_time_range
|
||||
from szurubooru.errors import ValidationError
|
||||
|
||||
class FakeDatetime(datetime):
|
||||
def now(tz=None):
|
||||
return datetime(1997, 1, 2, 3, 4, 5, tzinfo=tz)
|
||||
|
||||
class TestParseTime(unittest.TestCase):
|
||||
def test_empty(self):
|
||||
self.assertRaises(ValidationError, parse_time_range, '')
|
||||
|
||||
def test_today(self):
|
||||
szurubooru.util.datetime.datetime = FakeDatetime
|
||||
date_min, date_max = parse_time_range('today')
|
||||
self.assertEquals(date_min, datetime(1997, 1, 2, 0, 0, 0))
|
||||
self.assertEquals(date_max, datetime(1997, 1, 2, 23, 59, 59))
|
||||
|
||||
def test_yesterday(self):
|
||||
szurubooru.util.datetime.datetime = FakeDatetime
|
||||
date_min, date_max = parse_time_range('yesterday')
|
||||
self.assertEquals(date_min, datetime(1997, 1, 1, 0, 0, 0))
|
||||
self.assertEquals(date_max, datetime(1997, 1, 1, 23, 59, 59))
|
||||
|
||||
def test_year(self):
|
||||
date_min, date_max = parse_time_range('1999')
|
||||
self.assertEquals(date_min, datetime(1999, 1, 1, 0, 0, 0))
|
||||
self.assertEquals(date_max, datetime(1999, 12, 31, 23, 59, 59))
|
||||
|
||||
def test_month(self):
|
||||
for text in ['1999-2', '1999-02']:
|
||||
date_min, date_max = parse_time_range(text)
|
||||
self.assertEquals(date_min, datetime(1999, 2, 1, 0, 0, 0))
|
||||
self.assertEquals(date_max, datetime(1999, 2, 28, 23, 59, 59))
|
||||
|
||||
def test_day(self):
|
||||
for text in ['1999-2-6', '1999-02-6', '1999-2-06', '1999-02-06']:
|
||||
date_min, date_max = parse_time_range(text)
|
||||
self.assertEquals(date_min, datetime(1999, 2, 6, 0, 0, 0))
|
||||
self.assertEquals(date_max, datetime(1999, 2, 6, 23, 59, 59))
|
Loading…
Reference in a new issue