summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Holtermann <info@markusholtermann.eu>2013-02-20 03:10:43 +0100
committerMarkus Holtermann <info@markusholtermann.eu>2013-02-20 03:43:16 +0100
commit0cfb6206440b0c30af6386032724a768d708f787 (patch)
treee60fb4f09931928a1732ebf72534a53b9a322fa8
parent5b6601f31b3e4d653336e484c044df3041c2b030 (diff)
downloadbvg-grabber-0cfb6206440b0c30af6386032724a768d708f787.tar.gz
bvg-grabber-0cfb6206440b0c30af6386032724a768d708f787.tar.bz2
bvg-grabber-0cfb6206440b0c30af6386032724a768d708f787.zip
Some cleanup and documentation
-rw-r--r--bvggrabber/api/__init__.py67
-rw-r--r--tests/test_api.py43
2 files changed, 74 insertions, 36 deletions
diff --git a/bvggrabber/api/__init__.py b/bvggrabber/api/__init__.py
index fe45879..d044dad 100644
--- a/bvggrabber/api/__init__.py
+++ b/bvggrabber/api/__init__.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
import datetime
-import json
import re
from functools import total_ordering
@@ -8,15 +7,32 @@ from math import floor
from dateutil.parser import parse
-from bvggrabber.utils.format import fullformat, timeformat
+from bvggrabber.utils.format import timeformat
from bvggrabber.utils.json import ObjectJSONEncoder
def compute_remaining(start, end):
+ """Compute the number of seconds between ``start`` and ``end`` and return
+ the number of seconds rounded down to entire minutes. That means:
+
+ * [0, 59] => 0
+ * [60, 119] => 60
+ * [120, 179] => 120
+ * [-59, -1] => -60
+ * [-119, -60] => -120
+
+ :param datetime.datetime start: The start to compute the remaining number
+ of minutes.
+ :param datetime.datetime end: The end of the interval
+ :raises: TypeError if either of ``start`` or ``end`` is not a
+ ``datetime.datetime``.
+ :return: The number of remaining seconds rounded to entire minutes
+ :rtype: int
+ """
if not isinstance(start, datetime.datetime):
- raise ValueError("start needs to be a datetime.datetime")
+ raise TypeError("start needs to be a datetime.datetime")
if not isinstance(end, datetime.datetime):
- raise ValueError("start needs to be a datetime.datetime")
+ raise TypeError("start needs to be a datetime.datetime")
seconds = (end - start).total_seconds()
return datetime.timedelta(minutes=floor(seconds / 60)).total_seconds()
@@ -27,6 +43,7 @@ class QueryApi(object):
pass
def call(self):
+ """Needs to be implemented by inheriting classes!"""
raise NotImplementedError("The inheriting class needs to implement "
"the call() method!")
@@ -41,9 +58,11 @@ class Response(object):
def merge(self, other):
if isinstance(other, Response):
if not other.state:
- raise ValueError("The response contains errors: " + str(other.error))
+ raise ValueError("The response contains errors: " +
+ str(other.error))
elif not self.state:
- raise ValueError("The response contains errors: " + str(self.error))
+ raise ValueError("The response contains errors: " +
+ str(self.error))
else:
self.departures.extend(other.departures)
else:
@@ -51,13 +70,13 @@ class Response(object):
@property
def to_json(self):
+ """
+ .. deprecated:: 0.0.1
+ Use :attr:`json` instead.
+ """
return ObjectJSONEncoder(ensure_ascii=False).encode(self.departures)
@property
- def state(self):
- return self._state
-
- @property
def departures(self):
return self._departures
@@ -65,11 +84,36 @@ class Response(object):
def error(self):
return self._error
+ @property
+ def json(self):
+ return ObjectJSONEncoder(ensure_ascii=False).encode(self.departures)
+
+ @property
+ def state(self):
+ return self._state
+
@total_ordering
class Departure(object):
- def __init__(self, start, end, when, line, since=None):
+ def __init__(self, start, end, when, line, since=None, no_add_day=False):
+ """
+ :param str start: The start station
+ :param str end: The end station
+ :param when: The leaving time of the public transport at the given
+ ``start`` station. Might be an :class:`int` (timestamp), a
+ :class:`datetime.datetime` instance or a :class:`str` accepted by
+ ``dateutil.parse()``. If ``when`` is smaller than ``since`` and the
+ difference between both times is larger than 12 hours (43200sec),
+ the API will add another day unless ``no_add_day`` is ``True``.
+ :param str line: The line of the public transport
+ :param since: Either ``None`` or :class:`datetime.datetime`. Defines
+ the temporal start for searching. ``None`` will internally be
+ resolved as :meth:`datetime.datetime.now`.
+ :param bool no_add_day: If true, there no additional day will be added
+ if ``when`` is smaller than ``since``. Default ``False``.
+ :raises: :exc:`TypeError` if ``when`` is invalid or cannot be parsed.
+ """
if since is None:
self.now = datetime.datetime.now()
else:
@@ -99,6 +143,7 @@ class Departure(object):
@property
def remaining(self):
+ """.. seealso:: bvggrabber.api.compute_remaining"""
return int(compute_remaining(self.now, self.when))
def __eq__(self, other):
diff --git a/tests/test_api.py b/tests/test_api.py
index 4c403a9..b96d6b8 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -34,33 +34,25 @@ class TestFunctions(unittest.TestCase):
fullformat(s), fullformat(e), t))
def test_compute_remaining_error(self):
- self.assertRaises(ValueError, compute_remaining,
+ self.assertRaises(TypeError, compute_remaining,
1357092240, datetime.datetime(2013, 1, 2, 3, 4, 1))
- self.assertRaises(ValueError, compute_remaining,
+ self.assertRaises(TypeError, compute_remaining,
datetime.datetime(2013, 1, 2, 3, 4, 0), 1357092241)
- self.assertRaises(ValueError, compute_remaining,
+ self.assertRaises(TypeError, compute_remaining,
1357092240, 1357092241)
class TestResponse(unittest.TestCase):
def test_merge(self):
- departures = [ Departure("ERP",
- "HBF",
- datetime.datetime(2013, 1, 2, 3, 4, 1),
- "U2"),
- Departure("HBF",
- "ERP",
- datetime.datetime(2013, 2, 1, 3, 4, 1),
- "U55")]
- departures2 = [ Departure("ERP",
- "HBF",
- datetime.datetime(2013, 1, 2, 3, 4, 1),
- "U6"),
- Departure("HBF",
- "ERP",
- datetime.datetime(2013, 2, 1, 3, 4, 1),
- "U9")]
+ departures = [Departure("ERP", "HBF",
+ datetime.datetime(2013, 1, 2, 3, 4, 1), "U2"),
+ Departure("HBF", "ERP",
+ datetime.datetime(2013, 2, 1, 3, 4, 1), "U55")]
+ departures2 = [Departure("ERP", "HBF",
+ datetime.datetime(2013, 1, 2, 3, 4, 1), "U6"),
+ Departure("HBF", "ERP",
+ datetime.datetime(2013, 2, 1, 3, 4, 1), "U9")]
allDepartures = [("Marchbrücke", departures),
("S Tiergarten", departures2)]
r1 = Response(True, "Marchbrücke", departures)
@@ -206,6 +198,7 @@ class TestDeparture(BaseTestDeparture):
self.assertRaises(TypeError, Departure, "from", "to", ["when"], "line")
self.assertIsInstance(Departure("from", "to", "16:15\n \t*", "line"),
Departure)
+
@unittest.skip("removed json from object")
def test_json(self):
json1 = {'start': "From My Station",
@@ -251,19 +244,19 @@ class TestDeparture(BaseTestDeparture):
mitday_current_day = datetime.datetime(2013, 1, 2, 11, 59, 0)
departure = Departure("From My Station", "To Your Station",
- mitday_current_day, "A Line", since=now)
+ mitday_current_day, "A Line", since=now)
self.assertEqual(departure.remaining, -43200)
departure = Departure("From My Station", "To Your Station",
- mitday_current_day, "A Line", since=now,
- no_add_day=True)
+ mitday_current_day, "A Line", since=now,
+ no_add_day=True)
mitday_next_day = datetime.datetime(2013, 1, 2, 11, 58, 59)
departure = Departure("From My Station", "To Your Station",
- mitday_next_day, "A Line", since=now)
+ mitday_next_day, "A Line", since=now)
self.assertEqual(departure.remaining, 43140)
departure = Departure("From My Station", "To Your Station",
- mitday_next_day, "A Line", since=now,
- no_add_day=True)
+ mitday_next_day, "A Line", since=now,
+ no_add_day=True)
self.assertEqual(departure.remaining, -43260)