diff --git a/CHANGES.rst b/CHANGES.rst index d5234d74..0636d7cd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,6 +3,14 @@ Changelog A list of changes between each release +0.10.3 (2018-11-18) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Use networks endpoint rather than homecreen to retrieve arm/disarm status (`@md-reddevil `__) +- Fix incorrect command status endpoint (`@md-reddevil `__) +- Add extra debug logging +- Remove error prior to re-authorization (only log error when re-auth failed) + + 0.10.2 (2018-10-30) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Set minimum required version of the requests library to 2.20.0 due to vulnerability in earlier releases. @@ -11,19 +19,19 @@ A list of changes between each release 0.10.1 (2018-10-18) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Fix re-authorization bug (fixes `#101 `_) +- Fix re-authorization bug (fixes `#101 `__) - Log an error if saving video that doesn't exist 0.10.0 (2018-10-16) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Moved all API calls to own module for easier maintainability - Added network ids to sync module and cameras to allow for multi-network use -- Removed dependency on video existance prior to camera setup (fixes `#93 `_) +- Removed dependency on video existance prior to camera setup (fixes `#93 `__) - Camera wifi_strength now reported in wifi "bars" rather than dBm due to API endpoint change - Use homescreen thumbnail as fallback in case it's not in the camera endpoint - Removed "armed" and "status" attributes from camera (status of camera only reported by "motion_enabled" now) - Added serial number attributes to sync module and cameras -- Check network_id from login response and verify that network is onboarded (fixes `#90 `_) +- Check network_id from login response and verify that network is onboarded (fixes `#90 `__) - Check if retrieved clip is "None" prior to storing in cache 0.9.0 (2018-09-27) @@ -55,26 +63,26 @@ A list of changes between each release 0.8.0 (2018-05-21) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Added support for battery voltage level (fixes `#64 `_) +- Added support for battery voltage level (fixes `#64 `__) - Added motion detection per camera - Added fully accessible camera configuration dict -- Added celcius property to camera (fixes `#60 `_) +- Added celcius property to camera (fixes `#60 `__) 0.7.1 (2018-05-09) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Fixed pip 10 import issue during setup (`@fronzbot `_) +- Fixed pip 10 import issue during setup (`@fronzbot `__) 0.7.0 (2018-02-08) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed style errors for bumped pydocstring and pylint versions -- Changed Blink.cameras dictionary to be case-insensitive (fixes `#35 `_) -- Changed api endpoint for video extraction (fixes `#35 `_ and `#41 `_) +- Changed Blink.cameras dictionary to be case-insensitive (fixes `#35 `__) +- Changed api endpoint for video extraction (fixes `#35 `__ and `#41 `__) - Removed last_motion() function from Blink class - Refactored code for better organization - Moved some request calls out of @property methods (enables future CLI support) - Renamed get_summary() method to summary and changed to @property - Added ability to download most recent video clip -- Improved camera arm/disarm handling (`@b10m `_) +- Improved camera arm/disarm handling (`@b10m `__) - Added authentication to ``login()`` function and deprecated ``setup_system()`` in favor of ``start()`` - Added ``attributes`` dictionary to camera object @@ -83,7 +91,7 @@ A list of changes between each release - Removed redundent properties that only called hidden variables - Revised request wrapper function to be more intelligent - Added tests to ensure exceptions are caught and handled (100% coverage!) -- Added auto-reauthorization (token refresh) when a request fails due to an expired token (`@tySwift93 `_) +- Added auto-reauthorization (token refresh) when a request fails due to an expired token (`@tySwift93 `__) - Added battery level string to reduce confusion with the way Blink reports battery level as integer from 0 to 3 0.5.2 (2017-03-12) diff --git a/blinkpy/api.py b/blinkpy/api.py index df0772c6..f9db8df8 100644 --- a/blinkpy/api.py +++ b/blinkpy/api.py @@ -25,11 +25,17 @@ def request_login(blink, url, username, password): def request_networks(blink): - """Request network information.""" + """Request all networks information.""" url = "{}/networks".format(blink.urls.base_url) return http_get(blink, url) +def request_network_status(blink, network): + """Request network information.""" + url = "{}/network/{}".format(blink.urls.base_url, network) + return http_get(blink, url) + + def request_syncmodule(blink, network): """Request sync module info.""" url = "{}/network/{}/syncmodules".format(blink.urls.base_url, network) @@ -50,9 +56,9 @@ def request_system_disarm(blink, network): def request_command_status(blink, network, command_id): """Request command status.""" - url = "{}/network/{}/command_id/{}".format(blink.urls.base_url, - network, - command_id) + url = "{}/network/{}/command/{}".format(blink.urls.base_url, + network, + command_id) return http_get(blink, url) @@ -144,6 +150,7 @@ def http_get(blink, url, stream=False, json=True): """ if blink.auth_header is None: raise BlinkException(ERROR.AUTH_TOKEN) + _LOGGER.debug("Making GET request to %s", url) return http_req(blink, url=url, headers=blink.auth_header, reqtype='get', stream=stream, json_resp=json) @@ -156,4 +163,5 @@ def http_post(blink, url): """ if blink.auth_header is None: raise BlinkException(ERROR.AUTH_TOKEN) + _LOGGER.debug("Making POST request to %s", url) return http_req(blink, url=url, headers=blink.auth_header, reqtype='post') diff --git a/blinkpy/helpers/constants.py b/blinkpy/helpers/constants.py index db5d0077..67b6f5a6 100644 --- a/blinkpy/helpers/constants.py +++ b/blinkpy/helpers/constants.py @@ -4,7 +4,7 @@ MAJOR_VERSION = 0 MINOR_VERSION = 10 -PATCH_VERSION = 2 +PATCH_VERSION = 3 __version__ = '{}.{}.{}'.format(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION) diff --git a/blinkpy/helpers/util.py b/blinkpy/helpers/util.py index 253220e2..710f7bb0 100644 --- a/blinkpy/helpers/util.py +++ b/blinkpy/helpers/util.py @@ -2,7 +2,7 @@ import logging from requests import Request, Session, exceptions -from blinkpy.helpers.constants import BLINK_URL, PROJECT_URL +from blinkpy.helpers.constants import BLINK_URL import blinkpy.helpers.errors as ERROR @@ -50,8 +50,7 @@ def http_req(blink, url='http://example.com', data=None, headers=None, response = blink.session.send(prepped, stream=stream) if json_resp and 'code' in response.json(): if is_retry: - _LOGGER.error(("Cannot obtain new token for server auth. " - "Please report this issue on %s"), PROJECT_URL) + _LOGGER.error("Cannot obtain new token for server auth.") return None else: headers = attempt_reauthorization(blink) @@ -59,13 +58,14 @@ def http_req(blink, url='http://example.com', data=None, headers=None, reqtype=reqtype, stream=stream, json_resp=json_resp, is_retry=True) except (exceptions.ConnectionError, exceptions.Timeout): - _LOGGER.error("Cannot connect to server with url %s.", url) + _LOGGER.info("Cannot connect to server with url %s.", url) if not is_retry: headers = attempt_reauthorization(blink) return http_req(blink, url=url, data=data, headers=headers, reqtype=reqtype, stream=stream, json_resp=json_resp, is_retry=True) - _LOGGER.error("Possible issue with Blink servers.") + _LOGGER.error("Endpoint %s failed. Possible issue with Blink servers.", + url) return None if json_resp: diff --git a/blinkpy/sync_module.py b/blinkpy/sync_module.py index d1fa668e..ce4611cf 100644 --- a/blinkpy/sync_module.py +++ b/blinkpy/sync_module.py @@ -31,6 +31,7 @@ def __init__(self, blink): self.host = None self.summary = None self.homescreen = None + self.network_info = None self.record_dates = {} self.videos = {} self.events = [] @@ -64,7 +65,7 @@ def online(self): @property def arm(self): """Return status of sync module: armed/disarmed.""" - return self.homescreen['network']['armed'] + return self.network_info['network']['armed'] @arm.setter def arm(self, value): @@ -88,6 +89,9 @@ def start(self): self.homescreen = api.request_homescreen(self.blink) + self.network_info = api.request_network_status(self.blink, + self.network_id) + camera_info = self.get_camera_info() for camera_config in camera_info: name = camera_config['name'] @@ -114,6 +118,8 @@ def refresh(self, force_cache=False): self.events = self.get_events() self.videos = self.get_videos() self.homescreen = api.request_homescreen(self.blink) + self.network_info = api.request_network_status(self.blink, + self.network_id) camera_info = self.get_camera_info() for camera_config in camera_info: name = camera_config['name'] @@ -135,9 +141,10 @@ def get_videos(self, start_page=0, end_page=1): if not this_page: break videos.append(this_page) - + _LOGGER.debug("Getting videos from page %s through %s", + start_page, + end_page) for page in videos: - _LOGGER.debug("Retrieved video page %s", page) for entry in page: camera_name = entry['camera_name'] clip_addr = entry['address'] @@ -168,5 +175,5 @@ def get_videos(self, start_page=0, end_page=1): } ] self.record_dates = all_dates - + _LOGGER.debug("Retrieved a total of %s records", len(all_dates)) return self.videos diff --git a/tests/test_api.py b/tests/test_api.py index 103367d8..e5f73996 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -25,13 +25,14 @@ def tearDown(self): def test_http_req_connect_error(self, mock_auth): """Test http_get error condition.""" mock_auth.return_value = {'foo': 'bar'} - firstlog = ("ERROR:blinkpy.helpers.util:" - "Cannot connect to server with url {}").format( - 'http://notreal.fake.') + firstlog = ("INFO:blinkpy.helpers.util:" + "Cannot connect to server with url {}.").format( + 'http://notreal.fake') nextlog = ("INFO:blinkpy.helpers.util:" "Auth token expired, attempting reauthorization.") lastlog = ("ERROR:blinkpy.helpers.util:" - "Possible issue with Blink servers.") + "Endpoint {} failed. Possible issue with " + "Blink servers.").format('http://notreal.fake') expected = [firstlog, nextlog, firstlog, lastlog] with self.assertLogs() as getlog: api.http_get(self.blink, 'http://notreal.fake') diff --git a/tests/test_blinkpy.py b/tests/test_blinkpy.py index 577d177c..444581c2 100644 --- a/tests/test_blinkpy.py +++ b/tests/test_blinkpy.py @@ -14,7 +14,6 @@ from blinkpy.helpers.util import ( http_req, create_session, BlinkAuthenticationException, BlinkException, BlinkURLHandler) -from blinkpy.helpers.constants import PROJECT_URL import tests.mock_responses as mresp USERNAME = 'foobar' @@ -79,8 +78,7 @@ def test_bad_request(self, mock_sess): """Check that we raise an Exception with a bad request.""" self.blink.session = create_session() explog = ("ERROR:blinkpy.helpers.util:" - "Cannot obtain new token for server auth. " - "Please report this issue on {}").format(PROJECT_URL) + "Cannot obtain new token for server auth.") with self.assertRaises(BlinkException): http_req(self.blink, reqtype='bad') diff --git a/tests/test_sync_module.py b/tests/test_sync_module.py index bda50fa3..07d654fa 100644 --- a/tests/test_sync_module.py +++ b/tests/test_sync_module.py @@ -88,6 +88,7 @@ def test_sync_start(self, mock_resp): 'status': 'foobar'}}, {'event': True}, {}, + {}, {'devicestatus': {}}, None, None