summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrr- <rr-@sakuya.pl>2016-04-02 14:13:26 +0200
committerrr- <rr-@sakuya.pl>2016-04-03 12:12:57 +0200
commitd44bcdf3da0ee90be69b62c3124d9b93e674baba (patch)
treeb09ae78cea4cc283cfa043531d1c18b201313356
parent60a677edf4b905fd70f86ce3fcf4d4901a440e72 (diff)
server/util: add date time parser
-rw-r--r--INSTALL.md9
-rw-r--r--server/requirements.txt1
-rw-r--r--server/szurubooru/util.py55
-rw-r--r--server/tests/test_util.py42
4 files changed, 106 insertions, 1 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 3a99f4d..820b4a1 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -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.
diff --git a/server/requirements.txt b/server/requirements.txt
index 0122fa6..614cf9c 100644
--- a/server/requirements.txt
+++ b/server/requirements.txt
@@ -3,3 +3,4 @@ configobj>=5.0.6
falcon>=0.3.0
psycopg2>=2.6.1
SQLAlchemy>=1.0.12
+green>=2.4.0
diff --git a/server/szurubooru/util.py b/server/szurubooru/util.py
index 929957d..90677d2 100644
--- a/server/szurubooru/util.py
+++ b/server/szurubooru/util.py
@@ -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)
diff --git a/server/tests/test_util.py b/server/tests/test_util.py
new file mode 100644
index 0000000..bfa5218
--- /dev/null
+++ b/server/tests/test_util.py
@@ -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))