Compare commits

..
27 Commits
Author SHA1 Message Date
Kevin FronczakandGitHub 4a4811bee2 Merge pull request #202 from fronzbot/release-0.14.2
Release 0.14.2
2019-10-12 14:38:35 -04:00
Kevin Fronczak ad7ece4d45 Fixed version.wq 2019-10-12 14:32:26 -04:00
Kevin Fronczak 17d1aa9690 Update changelog, bumped version 2019-10-12 14:31:20 -04:00
Kevin FronczakandGitHub b00839ecb3 Merge pull request #198 from 3ch01c/docker
Add Docker example files
2019-10-12 14:01:25 -04:00
Kevin Fronczak 4900ea8ba6 Add app to tox check 2019-10-12 13:41:57 -04:00
Kevin Fronczak 4fb16398e4 Restructured to allow for future expansion
- Removed docker_compose
2019-10-12 13:27:14 -04:00
Jack Miner a1fc0c5a2b Added TIMEDELTA environment variable to configure how far back to download videos. Wrapped long lines to make linter happy. 2019-09-22 11:43:22 -06:00
Jack Miner 6adb252cdd dockerized 2019-09-14 02:01:44 -06:00
Kevin FronczakandGitHub 3637bbad8d Merge pull request #196 from fronzbot/req
Update python slugify version, better versioning
2019-09-09 11:12:45 -04:00
Kevin FronczakandGitHub 694efe71f8 Update python slugify version, better versioning 2019-09-02 10:29:14 -04:00
Kevin FronczakandGitHub 315735bc2f Merge pull request #192 from fronzbot/dev-version-bump
Dev verison bump
2019-06-20 13:56:16 -04:00
Kevin Fronczak db6403b468 Dev verison bump 2019-06-20 13:44:11 -04:00
Kevin FronczakandGitHub 92dda40e84 Merge pull request #191 from fronzbot/0.14.1
0.14.1
2019-06-20 13:41:22 -04:00
Kevin Fronczak 6c8fc0abce Updated changes 2019-06-20 13:34:59 -04:00
Kevin Fronczak 2d74b12d43 Version bump 2019-06-20 13:32:46 -04:00
Kevin FronczakandGitHub 197695ee40 Merge pull request #190 from fronzbot/dev-version-bump
Dev version bump
2019-06-20 13:24:24 -04:00
Kevin Fronczak 490c42550d Dev version bump
- Added Py3.8 to supported versions
2019-06-20 12:42:01 -04:00
Kevin FronczakandGitHub 7367eb6e87 Merge pull request #187 from fronzbot/upgrade-login
Upgraded login urls to use rest-region subdomain
2019-06-18 10:55:32 -04:00
Kevin FronczakandGitHub 414b647dc8 Merge pull request #189 from fronzbot/timeout
Improved timeout, prevent blocking on startup when unable to login
2019-06-17 11:54:17 -04:00
Kevin FronczakandGitHub 57882bb811 Merge pull request #188 from fronzbot/remove-thumbnail-method
Remove thumbnail from homescreen method
2019-06-17 11:17:15 -04:00
Kevin Fronczak bb76f09f31 Fix dev version (will add to different PR) 2019-06-17 11:15:46 -04:00
Kevin Fronczak 741cf489c8 Fix tests for improved login routine 2019-06-17 11:11:07 -04:00
Kevin Fronczak 7ce332b3ca Improved timeout, prevent blocking on startup when unable to login 2019-06-17 11:07:16 -04:00
Kevin Fronczak 8b7a491c89 Remove thumbnail from homescreen method 2019-06-17 10:20:23 -04:00
Kevin Fronczak 604eebd1b7 Upgraded login urls to use rest-region subdomain 2019-06-17 10:04:34 -04:00
Kevin FronczakandGitHub c2f44b3dfd Merge pull request #183 from fronzbot/dev-version-bump
Dev version bump
2019-05-24 09:38:56 -04:00
Kevin Fronczak ccad3dcb0c Dev version bump 2019-05-23 16:53:02 -04:00
14 changed files with 124 additions and 79 deletions
+11
View File
@@ -3,6 +3,17 @@ Changelog
A list of changes between each release
0.14.2 (2019-10-12)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Update dependencies
- Dockerize `(@3ch01c <https://github.com/fronzbot/blinkpy/pull/198>__)`
0.14.1 (2019-06-20)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Fix timeout problems blocking blinkpy startup
- Updated login urls using ``rest-region`` subdomain
- Removed deprecated thumbanil recovery from homescreen
0.14.0 (2019-05-23)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Breaking Changes:**
+12
View File
@@ -0,0 +1,12 @@
FROM python:3.7-alpine
LABEL maintainer="Kevin Fronczak <kfronczak@gmail.com>"
VOLUME /media
RUN python -m pip install --upgrade pip
RUN pip3 install blinkpy
COPY app/ .
ENTRYPOINT ["python", "./app.py"]
CMD []
+1
View File
@@ -0,0 +1 @@
"""Python init file for app.py."""
+31
View File
@@ -0,0 +1,31 @@
"""Script to run blinkpy as an app."""
from os import environ
from datetime import datetime, timedelta
from blinkpy import blinkpy
USERNAME = environ.get('USERNAME')
PASSWORD = environ.get('PASSWORD')
TIMEDELTA = timedelta(environ.get('TIMEDELTA', 1))
def get_date():
"""Return now - timedelta for blinkpy."""
return (datetime.now() - TIMEDELTA).isoformat()
def download_videos(blink, save_dir='/media'):
"""Make request to download videos."""
blink.download_videos(save_dir, since=get_date())
def start():
"""Startup blink app."""
blink = blinkpy.Blink(username=USERNAME, password=PASSWORD)
blink.start()
return blink
if __name__ == '__main__':
BLINK = start()
download_videos(BLINK)
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
docker build -t fronzbot/blinkpy:latest ./
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
# bash run.sh [username] [password]
if [ "$#" -ne 2 ]; then
echo ""
echo "ERROR: Requries Blink username and password as arguments."
echo "bash run.sh [username] [password]"
echo ""
exit 1
fi
set -ex
USER=fronzbot
IMAGE=blinkpy
CONFIG=$HOME/blinkpy_media
USERNAME=$1
PASSWORD=$2
mkdir -p $CONFIG
result=$(docker images -q $IMAGE)
if [ $result ]; then
docker rm $IMAGE
fi
docker run -it --name ${IMAGE} \
-v $CONFIG:/media \
-e USERNAME=${USERNAME} \
-e PASSWORD=${PASSWORD} \
$USER/$IMAGE \
/bin/bash
+7 -7
View File
@@ -78,6 +78,7 @@ class Blink():
self.cameras = CaseInsensitiveDict({})
self.video_list = CaseInsensitiveDict({})
self._login_url = LOGIN_URL
self.login_urls = []
self.motion_interval = motion_interval
self.version = __version__
self.legacy = legacy_subdomain
@@ -131,9 +132,9 @@ class Blink():
if not isinstance(self._password, str):
raise BlinkAuthenticationException(ERROR.PASSWORD)
login_urls = [LOGIN_URL, OLD_LOGIN_URL, LOGIN_BACKUP_URL]
self.login_urls = [LOGIN_URL, OLD_LOGIN_URL, LOGIN_BACKUP_URL]
response = self.login_request(login_urls, is_retry=is_retry)
response = self.login_request(is_retry=is_retry)
if not response:
return False
@@ -148,10 +149,10 @@ class Blink():
return self._auth_header
def login_request(self, login_urls, is_retry=False):
def login_request(self, is_retry=False):
"""Make a login request."""
try:
login_url = login_urls.pop(0)
login_url = self.login_urls.pop(0)
except IndexError:
_LOGGER.error("Could not login to blink servers.")
return False
@@ -165,14 +166,13 @@ class Blink():
is_retry=is_retry)
try:
if response.status_code != 200:
response = self.login_request(login_urls)
response = self.login_request(is_retry=True)
response = response.json()
(self.region_id, self.region), = response['region'].items()
except AttributeError:
_LOGGER.error("Login API endpoint failed with response %s",
response,
exc_info=True)
response)
return False
except KeyError:
+5 -18
View File
@@ -117,13 +117,16 @@ class BlinkCamera():
_LOGGER.warning("Could not retrieve calibrated temperature.")
# Check if thumbnail exists in config, if not try to
# get it from the homescreen info in teh sync module
# get it from the homescreen info in the sync module
# otherwise set it to None and log an error
new_thumbnail = None
thumb_addr = None
if config['thumbnail']:
thumb_addr = config['thumbnail']
else:
thumb_addr = self.get_thumb_from_homescreen()
_LOGGER.warning("Could not find thumbnail for camera %s",
self.name,
exc_info=True)
if thumb_addr is not None:
new_thumbnail = "{}{}.jpg".format(self.sync.urls.base_url,
@@ -192,19 +195,3 @@ class BlinkCamera():
return
with open(path, 'wb') as vidfile:
copyfileobj(response.raw, vidfile)
def get_thumb_from_homescreen(self):
"""Retrieve thumbnail from homescreen."""
for device in self.sync.homescreen['devices']:
try:
device_type = device['device_type']
device_name = device['name']
device_thumb = device['thumbnail']
if device_type == 'camera' and device_name == self.name:
return device_thumb
except KeyError:
pass
_LOGGER.error("Could not find thumbnail for camera %s",
self.name,
exc_info=True)
return None
+4 -3
View File
@@ -4,7 +4,7 @@ import os
MAJOR_VERSION = 0
MINOR_VERSION = 14
PATCH_VERSION = 0
PATCH_VERSION = 2
__version__ = '{}.{}.{}'.format(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION)
@@ -33,6 +33,7 @@ PROJECT_CLASSIFIERS = [
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Topic :: Home Automation'
]
@@ -45,11 +46,11 @@ PYPI_URL = 'https://pypi.python.org/pypi/{}'.format(PROJECT_PACKAGE_NAME)
URLS
'''
BLINK_URL = 'immedia-semi.com'
DEFAULT_URL = "{}.{}".format('prod', BLINK_URL)
DEFAULT_URL = "{}.{}".format('rest-prod', BLINK_URL)
BASE_URL = "https://{}".format(DEFAULT_URL)
LOGIN_URL = "{}/api/v2/login".format(BASE_URL)
OLD_LOGIN_URL = "{}/login".format(BASE_URL)
LOGIN_BACKUP_URL = "https://{}.{}/login".format('rest.piri', BLINK_URL)
LOGIN_BACKUP_URL = "https://{}.{}/login".format('rest-piri', BLINK_URL)
'''
Dictionaries
+9 -3
View File
@@ -2,7 +2,7 @@
import logging
import time
from functools import wraps
from functools import partial, wraps
from requests import Request, Session, exceptions
from blinkpy.helpers.constants import BLINK_URL, TIMESTAMP_FORMAT
import blinkpy.helpers.errors as ERROR
@@ -28,8 +28,14 @@ def merge_dicts(dict_a, dict_b):
def create_session():
"""Create a session for blink communication."""
"""
Create a session for blink communication.
From @ericfrederich via
https://github.com/kennethreitz/requests/issues/2011
"""
sess = Session()
sess.get = partial(sess.get, timeout=5)
return sess
@@ -65,7 +71,7 @@ def http_req(blink, url='http://example.com', data=None, headers=None,
prepped = req.prepare()
try:
response = blink.session.send(prepped, stream=stream, timeout=10)
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.")
+3 -3
View File
@@ -1,4 +1,4 @@
python-dateutil==2.7.5
requests>=2.20.0
python-slugify==3.0.2
python-dateutil~=2.8.0
requests==2.22.0
python-slugify~=3.0.2
testtools==2.3.0
+4 -2
View File
@@ -69,7 +69,8 @@ class TestBlinkFunctions(unittest.TestCase):
bad_req,
new_req
]
self.blink.login_request(['test1', 'test2', 'test3'])
self.blink.login_urls = ['test1', 'test2', 'test3']
self.blink.login_request()
# pylint: disable=protected-access
self.assertEqual(self.blink._login_url, 'test3')
@@ -78,7 +79,8 @@ class TestBlinkFunctions(unittest.TestCase):
new_req,
bad_req
]
self.blink.login_request(['test1', 'test2', 'test3'])
self.blink.login_urls = ['test1', 'test2', 'test3']
self.blink.login_request()
# pylint: disable=protected-access
self.assertEqual(self.blink._login_url, 'test2')
+1 -40
View File
@@ -99,45 +99,6 @@ class TestBlinkCameraSetup(unittest.TestCase):
self.assertEqual(self.camera.image_from_cache, 'test')
self.assertEqual(self.camera.video_from_cache, 'foobar')
def test_thumbnail_not_in_info(self, mock_sess):
"""Test that we grab thumbanil if not in camera_info."""
mock_sess.side_effect = [
mresp.MockResponse({'temp': 71}, 200),
'foobar',
'barfoo'
]
self.camera.last_record = ['1']
self.camera.sync.last_record = {
'new': {
'clip': '/test.mp4',
'time': '1970-01-01T00:00:00'
}
}
config = {
'name': 'new',
'id': 1234,
'network_id': 5678,
'serial': '12345678',
'enabled': False,
'battery_voltage': 90,
'battery_state': 'ok',
'temperature': 68,
'wifi_strength': 4,
'thumbnail': '',
}
self.camera.sync.homescreen = {
'devices': [
{'foo': 'bar'},
{'device_type': 'foobar'},
{'device_type': 'camera',
'name': 'new',
'thumbnail': '/new/thumb'}
]
}
self.camera.update(config)
self.assertEqual(self.camera.thumbnail,
'https://rest-test.immedia-semi.com/new/thumb.jpg')
def test_no_thumbnails(self, mock_sess):
"""Tests that thumbnail is 'None' if none found."""
mock_sess.return_value = 'foobar'
@@ -167,7 +128,7 @@ class TestBlinkCameraSetup(unittest.TestCase):
logrecord.output,
[("WARNING:blinkpy.camera:Could not retrieve calibrated "
"temperature."),
("ERROR:blinkpy.camera:Could not find thumbnail for camera new"
("WARNING:blinkpy.camera:Could not find thumbnail for camera new"
"\nNoneType: None")]
)
+3 -3
View File
@@ -20,9 +20,9 @@ deps =
basepython = python3
ignore_errors = True
commands =
pylint --rcfile={toxinidir}/pylintrc blinkpy tests
flake8 blinkpy tests
pydocstyle blinkpy tests
pylint --rcfile={toxinidir}/pylintrc blinkpy tests app
flake8 blinkpy tests app
pydocstyle blinkpy tests app
rst-lint README.rst
rst-lint CHANGES.rst