diff options
author | Markus Holtermann <info@markusholtermann.eu> | 2013-02-20 03:10:43 +0100 |
---|---|---|
committer | Markus Holtermann <info@markusholtermann.eu> | 2013-02-20 03:43:16 +0100 |
commit | 0cfb6206440b0c30af6386032724a768d708f787 (patch) | |
tree | e60fb4f09931928a1732ebf72534a53b9a322fa8 | |
parent | 5b6601f31b3e4d653336e484c044df3041c2b030 (diff) | |
download | bvg-grabber-0cfb6206440b0c30af6386032724a768d708f787.tar.gz bvg-grabber-0cfb6206440b0c30af6386032724a768d708f787.tar.bz2 bvg-grabber-0cfb6206440b0c30af6386032724a768d708f787.zip |
Some cleanup and documentation
-rw-r--r-- | bvggrabber/api/__init__.py | 67 | ||||
-rw-r--r-- | tests/test_api.py | 43 |
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) |