Compare commits

..
1 Commits
Author SHA1 Message Date
Kevin FronczakandGitHub 1b66eddfb4 Merge pull request #340 from fronzbot/dev
0.16.0
2020-07-20 23:01:30 -04:00
13 changed files with 50 additions and 82 deletions
+1 -2
View File
@@ -33,9 +33,8 @@ jobs:
run: |
tox -r -e cov
- name: Codecov
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v1.0.6
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
file: ./coverage.xml
name: blinkpy
+2 -2
View File
@@ -8,12 +8,12 @@ repos:
- --quiet
files: ^((blinkpy|tests)/.+)?[^/]+\.py$
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.3
rev: 3.8.2
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings==1.5.0
- pydocstyle==5.1.1
- pydocstyle==5.0.2
files: ^(blinkpy|tests)/.+\.py$
- repo: https://github.com/Lucas-C/pre-commit-hooks-markup
rev: v1.0.0
-21
View File
@@ -4,27 +4,6 @@ Changelog
A list of changes between each release
0.16.3 (2020-08-02)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Add user-agent to all headers
0.16.2 (2020-08-01)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Add user-agent to header at login
- Remove extra data parameters at login (not-needed)
- Bump pytest to 6.0.1
0.16.1 (2020-07-29)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Unpin requirements, set minimum version instead
- Bump coverage to 5.2.1
- Bump pytest to 6.0.0
0.16.0 (2020-07-20)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1 -1
View File
@@ -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 ``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.
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.
Example usage, which downloads all videos recorded since July 4th, 2018 at 9:34am to the ``/home/blink`` directory:
+8 -9
View File
@@ -3,7 +3,7 @@
import logging
from json import dumps
from blinkpy.helpers.util import get_time, Throttle
from blinkpy.helpers.constants import DEFAULT_URL, TIMEOUT, DEFAULT_USER_AGENT
from blinkpy.helpers.constants import DEFAULT_URL, TIMEOUT
_LOGGER = logging.getLogger(__name__)
@@ -20,24 +20,21 @@ def request_login(
:param url: Login url.
:login_data: Dictionary containing blink login data.
"""
headers = {
"Host": DEFAULT_URL,
"Content-Type": "application/json",
"Accept": "/",
"user-agent": DEFAULT_USER_AGENT,
}
headers = {"Host": DEFAULT_URL, "Content-Type": "application/json"}
data = dumps(
{
"email": login_data["username"],
"password": login_data["password"],
"notification_key": login_data["notification_key"],
"unique_id": login_data["uid"],
"app_version": "6.0.7 (520300) #afb0be72a",
"device_identifier": login_data["device_id"],
"client_name": "Computer",
"client_type": "android",
"os_version": "5.1.1",
"reauth": "false",
}
)
return auth.query(
url=url,
headers=headers,
@@ -244,7 +241,9 @@ 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/v5/accounts/{blink.account_id}/networks/{network}/cameras/{camera_id}/liveview"
url = (
f"{blink.urls.base_url}/api/v3/networks/{network}/cameras/{camera_id}/liveview"
)
return http_post(blink, url)
+7 -16
View File
@@ -6,12 +6,7 @@ from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from blinkpy import api
from blinkpy.helpers import util
from blinkpy.helpers.constants import (
BLINK_URL,
DEFAULT_USER_AGENT,
LOGIN_ENDPOINT,
TIMEOUT,
)
from blinkpy.helpers.constants import BLINK_URL, LOGIN_ENDPOINT, TIMEOUT
_LOGGER = logging.getLogger(__name__)
@@ -58,7 +53,7 @@ class Auth:
"""Return authorization header."""
if self.token is None:
return None
return {"TOKEN_AUTH": self.token, "user-agent": DEFAULT_USER_AGENT}
return {"TOKEN_AUTH": self.token}
def create_session(self, opts=None):
"""Create a session for blink communication."""
@@ -113,7 +108,11 @@ class Auth:
try:
_LOGGER.info("Token expired, attempting automatic refresh.")
self.login_response = self.login()
self.extract_login_info()
self.region_id = self.login_response["region"]["tier"]
self.host = f"{self.region_id}.{BLINK_URL}"
self.token = self.login_response["authtoken"]["authtoken"]
self.client_id = self.login_response["client"]["id"]
self.account_id = self.login_response["account"]["id"]
self.is_errored = False
except LoginError:
_LOGGER.error("Login endpoint failed. Try again later.")
@@ -123,14 +122,6 @@ class Auth:
raise TokenRefreshFailed
return True
def extract_login_info(self):
"""Extract login info from login response."""
self.region_id = self.login_response["region"]["tier"]
self.host = f"{self.region_id}.{BLINK_URL}"
self.token = self.login_response["authtoken"]["authtoken"]
self.client_id = self.login_response["client"]["id"]
self.account_id = self.login_response["account"]["id"]
def startup(self):
"""Initialize tokens for communication."""
self.validate_login()
-1
View File
@@ -86,7 +86,6 @@ class Blink:
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)
+16 -14
View File
@@ -98,15 +98,6 @@ class BlinkCamera:
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)
@@ -189,10 +180,21 @@ class BlinkCamera:
update_cached_video = True
if new_thumbnail is not None and (update_cached_image or force_cache):
self._cached_image = self.get_media()
self._cached_image = api.http_get(
self.sync.blink,
url=self.thumbnail,
stream=True,
json=False,
timeout=TIMEOUT_MEDIA,
)
if clip_addr is not None and (update_cached_video or force_cache):
self._cached_video = self.get_media(media_type="video")
self._cached_video = api.http_get(
self.sync.blink,
url=self.clip,
stream=True,
json=False,
timeout=TIMEOUT_MEDIA,
)
def get_liveview(self):
"""Get livewview rtsps link."""
@@ -208,7 +210,7 @@ class BlinkCamera:
:param path: Path to write file
"""
_LOGGER.debug("Writing image from %s to %s", self.name, path)
response = self.get_media()
response = self._cached_image
if response.status_code == 200:
with open(path, "wb") as imgfile:
copyfileobj(response.raw, imgfile)
@@ -224,7 +226,7 @@ class BlinkCamera:
:param path: Path to write file
"""
_LOGGER.debug("Writing video from %s to %s", self.name, path)
response = self.get_media(media_type="video")
response = self._cached_video
if response is None:
_LOGGER.error("No saved video exist for %s.", self.name)
return
+1 -2
View File
@@ -4,7 +4,7 @@ import os
MAJOR_VERSION = 0
MINOR_VERSION = 16
PATCH_VERSION = "4-rc0"
PATCH_VERSION = 0
__version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}.{PATCH_VERSION}"
@@ -58,7 +58,6 @@ ONLINE = {"online": True, "offline": False}
"""
OTHER
"""
DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
DEVICE_ID = "Blinkpy"
TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S%z"
DEFAULT_MOTION_INTERVAL = 1
+4 -3
View File
@@ -1,3 +1,4 @@
python-dateutil>=2.8.1
requests>=2.24.0
python-slugify>=4.0.1
python-dateutil~=2.8.1
requests~=2.24.0
python-slugify~=4.0.1
testtools==2.4.0
+8 -9
View File
@@ -1,14 +1,13 @@
black==19.10b0
coverage==5.3
flake8==3.8.4
coverage==5.2
flake8==3.8.3
flake8-docstrings==1.5.0
pre-commit==2.7.1
pylint==2.6.0
pydocstyle==5.1.1
pytest==6.1.1
pytest-cov==2.10.1
pre-commit==2.6.0
pylint==2.5.3
pydocstyle==5.0.2
pytest==5.4.3
pytest-cov==2.10.0
pytest-sugar==0.9.4
pytest-timeout==1.4.2
restructuredtext-lint==1.3.1
pygments==2.7.1
testtools>=2.4.0
pygments==2.6.1
+1 -1
View File
@@ -128,7 +128,7 @@ class TestAuth(unittest.TestCase):
def test_header(self):
"""Test header data."""
self.auth.token = "bar"
expected_header = {"TOKEN_AUTH": "bar", "user-agent": const.DEFAULT_USER_AGENT}
expected_header = {"TOKEN_AUTH": "bar"}
self.assertDictEqual(self.auth.header, expected_header)
def test_header_no_token(self):
+1 -1
View File
@@ -68,7 +68,7 @@ class TestBlinkSetup(unittest.TestCase):
self.assertEqual(self.blink.last_refresh, None)
with mock.patch(
"blinkpy.sync_module.BlinkSyncModule.refresh", return_value=True
), mock.patch("blinkpy.blinkpy.Blink.get_homescreen", return_value=True):
):
self.blink.refresh()
self.assertEqual(self.blink.last_refresh, now)