Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.16.4 #402

Merged
merged 38 commits into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ed44507
Dev bump
fronzbot Aug 2, 2020
141fea5
Bump pytest-cov from 2.10.0 to 2.10.1
dependabot-preview[bot] Aug 17, 2020
e00600c
Bump coverage from 5.2.1 to 5.3
dependabot-preview[bot] Sep 14, 2020
9a95016
Bump pygments from 2.6.1 to 2.7.1
dependabot-preview[bot] Sep 18, 2020
a374009
Fix readme param and spelling
rohitsud Sep 27, 2020
75dbd1e
Merge pull request #368 from fronzbot/dependabot/pip/pytest-cov-2.10.1
fronzbot Sep 28, 2020
cd97921
Merge pull request #377 from fronzbot/dependabot/pip/coverage-5.3
fronzbot Sep 28, 2020
dae2413
Merge pull request #381 from rohitsud/patch-1
fronzbot Sep 28, 2020
8c23087
Bump pre-commit from 2.6.0 to 2.7.1
dependabot-preview[bot] Sep 28, 2020
1b1c30b
Add codecov token to workflow to fix upload issue
fronzbot Oct 5, 2020
721a3ad
Merge pull request #386 from fronzbot/add-codecov-token
fronzbot Oct 5, 2020
7aef857
Bump pylint from 2.5.3 to 2.6.0
dependabot-preview[bot] Oct 5, 2020
190cef8
Attempt to fix coverage
fronzbot Oct 5, 2020
7140895
Merge pull request #370 from fronzbot/dependabot/pip/pylint-2.6.0
fronzbot Oct 5, 2020
69aaee3
Merge branch 'dev' into dependabot/pip/pre-commit-2.7.1
fronzbot Oct 5, 2020
f619b20
Bump flake8 from 3.8.3 to 3.8.4
dependabot-preview[bot] Oct 5, 2020
bdcb3f6
Bump pydocstyle from 5.0.2 to 5.1.1
dependabot-preview[bot] Oct 5, 2020
f27df12
Merge pull request #379 from fronzbot/dependabot/pip/pygments-2.7.1
fronzbot Oct 5, 2020
cbab673
Merge pull request #384 from fronzbot/dependabot/pip/flake8-3.8.4
fronzbot Oct 5, 2020
80e3984
Merge pull request #375 from fronzbot/dependabot/pip/pydocstyle-5.1.1
fronzbot Oct 5, 2020
59ef398
Bump pytest from 6.0.1 to 6.1.1
dependabot-preview[bot] Oct 5, 2020
e8e9d4e
Update .pre-commit-config.yaml
fronzbot Oct 5, 2020
fcce28c
Merge pull request #385 from fronzbot/dependabot/pip/pytest-6.1.1
fronzbot Oct 5, 2020
f13d177
Merge pull request #371 from fronzbot/dependabot/pip/pre-commit-2.7.1
fronzbot Oct 5, 2020
b0fed67
Move testtools to requirements_test.txt
fronzbot Oct 5, 2020
828b411
Merge pull request #387 from fronzbot/move-testtools
fronzbot Oct 5, 2020
b5b7498
Generalized image/video download, fixed non-updating image for minis
fronzbot Oct 6, 2020
eb1fbe9
Updated liveview endpoint
fronzbot Oct 6, 2020
a94f59e
Merge pull request #388 from fronzbot/fix-mini-thumb-refresh
fronzbot Oct 6, 2020
469b0c2
Merge pull request #389 from fronzbot/fix-liveview-endpoint
fronzbot Oct 6, 2020
8898436
Update constants.py
fronzbot Oct 6, 2020
f09a66c
Fix malformatted stream url for blink mini
fronzbot Oct 25, 2020
0842739
Merge pull request #395 from fronzbot/fix-stream-format
fronzbot Oct 25, 2020
92a2cc2
Added test to catch NoneType error on refresh, fixed offending code
fronzbot Nov 23, 2020
ba3c2e3
Merge pull request #401 from fronzbot/fix-exception-on-refresh
fronzbot Nov 23, 2020
ab38afa
dev version bump
fronzbot Nov 23, 2020
c01a6ce
dev version bump
fronzbot Nov 23, 2020
a2555a6
Update for 0.16.4
fronzbot Nov 23, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ jobs:
run: |
tox -r -e cov
- name: Codecov
uses: codecov/codecov-action@v1.0.6
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
file: ./coverage.xml
name: blinkpy
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ repos:
- --quiet
files: ^((blinkpy|tests)/.+)?[^/]+\.py$
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.2
rev: 3.8.3
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings==1.5.0
- pydocstyle==5.0.2
- pydocstyle==5.1.1
files: ^(blinkpy|tests)/.+\.py$
- repo: https://github.com/Lucas-C/pre-commit-hooks-markup
rev: v1.0.0
Expand Down
25 changes: 25 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,31 @@ Changelog

A list of changes between each release

0.16.4 (2020-11-22)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Bugfixes:**

- Updated liveview endpoint (`#389 <https://github.com/fronzbot/blinkpy/pull/389>`__)
- Fixed mini thumbnail not updating (`#388 <https://github.com/fronzbot/blinkpy/pull/388>`__)
- Add exception catch to prevent NoneType error on refresh, added test to check behavior as well (`#401 <https://github.com/fronzbot/blinkpy/pull/401>`__)
- Unrelated: had to add two force methods to refresh for testing purposes. Should not change normal usage.
- Fix malformed stream url (`#395 <https://github.com/fronzbot/blinkpy/pull/395>`__)

**All:**

- Moved testtools to requirements_test.txt (`#387 <https://github.com/fronzbot/blinkpy/pull/387>`__)
- Bumped pytest to 6.1.1
- Bumped flake8 to 3.8.4
- Fixed README spelling ((`#381 <https://github.com/fronzbot/blinkpy/pull/381>`__) via @rohitsud)
- Bumped pygments to 2.7.1
- Bumped coverage to 5.3
- Bumped pydocstyle to 5.1.1
- Bumped pre-commit to 2.7.1
- Bumped pylint to 2.6.0
- Bumped pytest-cov to 2.10.1


0.16.3 (2020-08-02)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ Similar methods exist for individual cameras:

Download videos
----------------
You can also use this library to download all videos from the server. In order to do this, you must specify a ``path``. You may also specifiy a how far back in time to go to retrieve videos via the ``since=`` variable (a simple string such as ``"2017/09/21"`` is sufficient), as well as how many pages to traverse via the ``page=`` variable. Note that by default, the library will search the first ten pages which is sufficient in most use cases. Additionally, you can specidy one or more cameras via the ``camera=`` property. This can be a single string indicating the name of the camera, or a list of camera names. By default, it is set to the string ``'all'`` to grab videos from all cameras.
You can also use this library to download all videos from the server. In order to do this, you must specify a ``path``. You may also specifiy a how far back in time to go to retrieve videos via the ``since=`` variable (a simple string such as ``"2017/09/21"`` is sufficient), as well as how many pages to traverse via the ``stop=`` variable. Note that by default, the library will search the first ten pages which is sufficient in most use cases. Additionally, you can specify one or more cameras via the ``camera=`` property. This can be a single string indicating the name of the camera, or a list of camera names. By default, it is set to the string ``'all'`` to grab videos from all cameras.

Example usage, which downloads all videos recorded since July 4th, 2018 at 9:34am to the ``/home/blink`` directory:

Expand Down
4 changes: 1 addition & 3 deletions blinkpy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,7 @@ def request_camera_liveview(blink, network, camera_id):
:param network: Sync module network id.
:param camera_id: Camera ID of camera to request liveview from.
"""
url = (
f"{blink.urls.base_url}/api/v3/networks/{network}/cameras/{camera_id}/liveview"
)
url = f"{blink.urls.base_url}/api/v5/accounts/{blink.account_id}/networks/{network}/cameras/{camera_id}/liveview"
return http_post(blink, url)


Expand Down
12 changes: 7 additions & 5 deletions blinkpy/blinkpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,22 @@ def __init__(
self.no_owls = no_owls

@util.Throttle(seconds=MIN_THROTTLE_TIME)
def refresh(self, force=False):
def refresh(self, force=False, force_cache=False):
"""
Perform a system refresh.

:param force: Force an update of the camera data
:param force: Used to override throttle, resets refresh
:param force_cache: Used to force update without overriding throttle
"""
if self.check_if_ok_to_update() or force:
if self.check_if_ok_to_update() or force or force_cache:
if not self.available:
self.setup_post_verify()

self.get_homescreen()
for sync_name, sync_module in self.sync.items():
_LOGGER.debug("Attempting refresh of sync %s", sync_name)
sync_module.refresh(force_cache=force)
if not force:
sync_module.refresh(force_cache=(force or force_cache))
if not force_cache:
# Prevents rapid clearing of motion detect property
self.last_refresh = int(time.time())
return True
Expand Down
32 changes: 15 additions & 17 deletions blinkpy/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ def arm(self, value):
self.sync.blink, self.network_id, self.camera_id
)

def get_media(self, media_type="image"):
"""Download media (image or video)."""
url = self.thumbnail
if media_type.lower() == "video":
url = self.clip
return api.http_get(
self.sync.blink, url=url, stream=True, json=False, timeout=TIMEOUT_MEDIA,
)

def snap_picture(self):
"""Take a picture with camera to create a new thumbnail."""
return api.request_new_image(self.sync.blink, self.network_id, self.camera_id)
Expand Down Expand Up @@ -180,21 +189,10 @@ def update_images(self, config, force_cache=False):
update_cached_video = True

if new_thumbnail is not None and (update_cached_image or force_cache):
self._cached_image = api.http_get(
self.sync.blink,
url=self.thumbnail,
stream=True,
json=False,
timeout=TIMEOUT_MEDIA,
)
self._cached_image = self.get_media()

if clip_addr is not None and (update_cached_video or force_cache):
self._cached_video = api.http_get(
self.sync.blink,
url=self.clip,
stream=True,
json=False,
timeout=TIMEOUT_MEDIA,
)
self._cached_video = self.get_media(media_type="video")

def get_liveview(self):
"""Get livewview rtsps link."""
Expand All @@ -210,7 +208,7 @@ def image_to_file(self, path):
:param path: Path to write file
"""
_LOGGER.debug("Writing image from %s to %s", self.name, path)
response = self._cached_image
response = self.get_media()
if response.status_code == 200:
with open(path, "wb") as imgfile:
copyfileobj(response.raw, imgfile)
Expand All @@ -226,7 +224,7 @@ def video_to_file(self, path):
:param path: Path to write file
"""
_LOGGER.debug("Writing video from %s to %s", self.name, path)
response = self._cached_video
response = self.get_media(media_type="video")
if response is None:
_LOGGER.error("No saved video exist for %s.", self.name)
return
Expand Down Expand Up @@ -268,6 +266,6 @@ def get_liveview(self):
response = api.http_post(self.sync.blink, url)
server = response["server"]
server_split = server.split(":")
server_split[0] = "rtsps"
server_split[0] = "rtsps:"
link = "".join(server_split)
return link
2 changes: 1 addition & 1 deletion blinkpy/helpers/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

MAJOR_VERSION = 0
MINOR_VERSION = 16
PATCH_VERSION = 3
PATCH_VERSION = 4

__version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}.{PATCH_VERSION}"

Expand Down
4 changes: 2 additions & 2 deletions blinkpy/sync_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def get_owl_info(self, name):
for owl in self.blink.homescreen["owls"]:
if owl["name"] == name:
return owl
except KeyError:
except (TypeError, KeyError):
pass
return None

Expand Down Expand Up @@ -270,7 +270,7 @@ def get_camera_info(self, camera_id, **kwargs):
if owl["name"] == self.name:
self.status = owl["enabled"]
return owl
except KeyError:
except (TypeError, KeyError):
pass
return None

Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
python-dateutil>=2.8.1
requests>=2.24.0
python-slugify>=4.0.1
testtools>=2.4.0
17 changes: 9 additions & 8 deletions requirements_test.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
black==19.10b0
coverage==5.2.1
flake8==3.8.3
coverage==5.3
flake8==3.8.4
flake8-docstrings==1.5.0
pre-commit==2.6.0
pylint==2.5.3
pydocstyle==5.0.2
pytest==6.0.1
pytest-cov==2.10.0
pre-commit==2.7.1
pylint==2.6.0
pydocstyle==5.1.1
pytest==6.1.1
pytest-cov==2.10.1
pytest-sugar==0.9.4
pytest-timeout==1.4.2
restructuredtext-lint==1.3.1
pygments==2.6.1
pygments==2.7.1
testtools>=2.4.0
39 changes: 23 additions & 16 deletions tests/test_blink_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,23 @@

from blinkpy import blinkpy
from blinkpy.sync_module import BlinkSyncModule
from blinkpy.camera import BlinkCamera
from blinkpy.helpers.util import get_time, BlinkURLHandler


class MockSyncModule(BlinkSyncModule):
"""Mock http requests from sync module."""
"""Mock blink sync module object."""

def __init__(self, blink, header):
"""Create mock sync module instance."""
super().__init__(blink, header, network_id=None, camera_list=None)
self.blink = blink
self.header = header
self.return_value = None
self.return_value2 = None
def get_network_info(self):
"""Mock network info method."""
return True

def http_get(self, url, stream=False, json=True):
"""Mock get request."""
if stream and self.return_value2 is not None:
return self.return_value2
return self.return_value

def http_post(self, url):
"""Mock post request."""
return self.return_value
class MockCamera(BlinkCamera):
"""Mock blink camera object."""

def update(self, config, force_cache=False, **kwargs):
"""Mock camera update method."""


class TestBlinkFunctions(unittest.TestCase):
Expand Down Expand Up @@ -121,3 +115,16 @@ def test_parse_camera_not_in_list(self, mock_req):
with self.assertLogs() as dl_log:
blink.download_videos("/tmp", camera="bar", stop=2)
self.assertEqual(dl_log.output, expected_log)

@mock.patch("blinkpy.blinkpy.api.request_network_update")
@mock.patch("blinkpy.auth.Auth.query")
def test_refresh(self, mock_req, mock_update):
"""Test ability to refresh system."""
mock_update.return_value = {"network": {"sync_module_error": False}}
mock_req.return_value = None
self.blink.last_refresh = 0
self.blink.available = True
self.blink.sync["foo"] = MockSyncModule(self.blink, "foo", 1, [])
self.blink.cameras = {"bar": MockCamera(self.blink.sync)}
self.blink.sync["foo"].cameras = self.blink.cameras
self.assertTrue(self.blink.refresh())
4 changes: 2 additions & 2 deletions tests/test_blinkpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def test_throttle(self, mock_time):
self.assertEqual(self.blink.last_refresh, None)
with mock.patch(
"blinkpy.sync_module.BlinkSyncModule.refresh", return_value=True
):
self.blink.refresh()
), mock.patch("blinkpy.blinkpy.Blink.get_homescreen", return_value=True):
self.blink.refresh(force=True)

self.assertEqual(self.blink.last_refresh, now)
self.assertEqual(self.blink.check_if_ok_to_update(), False)
Expand Down
7 changes: 7 additions & 0 deletions tests/test_cameras.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,10 @@ def test_mini_missing_attributes(self, mock_resp):
attr = camera.attributes
for key in attr:
self.assertEqual(attr[key], None)

def test_camera_stream(self, mock_resp):
"""Test that camera stream returns correct url."""
mock_resp.return_value = {"server": "rtsps://foo.bar"}
mini_camera = BlinkCameraMini(self.blink.sync["test"])
self.assertEqual(self.camera.get_liveview(), "rtsps://foo.bar")
self.assertEqual(mini_camera.get_liveview(), "rtsps://foo.bar")