From b002786055797307a9b2c4f3068df509a8e1c893 Mon Sep 17 00:00:00 2001 From: Martin Riedel Date: Sat, 25 Jan 2020 13:23:58 -0500 Subject: [PATCH 1/6] Updated production pypi key. Changed condition to deploy python 3.7 and 2.7 to pypi. --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index ffb2dad..2bd0943 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,19 +35,19 @@ deploy: password: secure: m/iNGZX8iIdta1ko/0yTZ994hM6aJqiLcgen1Au/DwgFYAbh2AWCFyQNeghqn4KwG1+LSb4TQdpGWgrx3lB2dFnHIVrkSYC25OBelg+1gmCO+7VUOM3Ysyxy2Av/fjR2N0xqxCwepr2xl5hUc4wdm+hKkKj13vhClQuQkp8quz2iagAuOsIHja1uDmoVM4IPQg+KBtQA1HpQp1f2v/O/qW4bfJKHqbhEzVXS5LMoN7LUh3iBjwwolPsuGE/3MwB9YgGZvdSIAsS/Wyam/7i7pSg8HgnXnRH3jucNZ84fh/1bVunpmyP8ebO+lhrryukkRRap82Vb7oQLN82SGqwFiBZZ+2LqCD4z/UOg67+6ZvTx0R06aK1WMpIwSd+sY5ohBHPIDR645m9m/z5N7JHY5ydeUi6NxRVTJjkfTRzjowV427r9UFgGFP/qXBRcgxB36FhXMw8q8tsNnKkB3wvmxPN7RbCUyQG7In2TxBuXCHiHXAGAM6B70ktHc3wK0dtRZF0hqSIQIqUlKiHjjL/IkwdYo5Fg/26HszczqlD0ZSD0uJq4BxJjQQ5di7vcgyu9BcP9rDHIenFZXW+ccMSVx0GD6bAUCJT/+RwWa3YARPojDoaDv+FcKeMBTIQFeOsi7lYwxqFL28YiGfSjQnkFsVmeH91YG0dW7u7l+GBZGsk= server: https://test.pypi.org/legacy/ - distributions: "sdist bdist_wheel" skip_existing: true on: - python: 3.7 - repo: rado0x54/python-carson-living branch: develop - # Prod PYPI + condition: $TRAVIS_PYTHON_VERSION = 3.7 || $TRAVIS_PYTHON_VERSION == 2.7 + repo: rado0x54/python-carson-living + # Prod PYPI 3.7 - provider: pypi user: __token__ password: - secure: p8maUDwhdIKEM6rbQnv3X4MNHu/ZNxUWVzDPgaMyoulUL+3itj6f1l1paPseSE+KJt/zbcByIB60EYP/k8NaklwmR/YpLrK2L6DU5E3v68YPcg1XaKBwG/7Wnx0w9QsWn39xR3/lE7RiLTLqPx/sqv7DY7QoT90LD4fufroR1/9sQVx0ociTIytcGE3J+K3iI/QimRZAskr75cgYpi0mQR6t4l0IEF6LEkr3y5vMcD5n2nVTW6XQXHdQvy2JhXiVHkHXWWfafERsuTUTm6h6z0/f/02O68W3yJvD/BFOnqTs3RAamff07Sf5Mb6jJj9Qi05aArRHuCkSqskiklTpgwEsOTrTaJb+wnVUJYiM2bqJCki8O0S7e67fA6I8wMXADjXeH4Y3pFDl7hltUupGgee+cnUIf87zXxczTz9Gweqh1pW2faMoXIiQ8tCdcx3V6B/CMIStlrLsTwDK+4MJIIkjkd1DwnBdN8K5OdX3HCdciPzAnkUm85OfgT75GgHlh4BWGJr0PnWnhd+PqyQvSymzVjiWXY/jiQgHVGRmA1vcoNeYlThvgXwtIbQ2cjukqqFGcgfStVaCVZAJO0kp6pfXCjR/BDuXKHvilL6s5cPN/UJO3Jr+TboTqxkuJFPrp4H4uQY3Imad9xRY49wXthHbspK5CutYHiIv/Co++vM= + secure: Pu0F/Zd3vAkyLSAmtrQdgM8wEDy68UHH8hBoMWj8e3/jq0BjKBdcLRSFj9GnV7BM0zBCk0CmcX9/sXSWo1kkprvEmS+57zRcuXCLfk/oT1J9TRmbDPCEObBsrvNzQroXHwqX/OWqKJcaTv+NYE1bGzvoKUMGvd+1d9CdNbfD/pnxtrA7UkZUJargBvEYCKM/Yd/aYsluzobzZMcZ0tSUEvpRoXYBCCFv4/B+rfUECrxCiXnu7uhQg2MTAwgJBcu6qG0gd/1aKgCyD89Q20/vEFvHQv6dU2j6G2dQr41q+ek7OxUx52LHtbAz4a7QiNvceeFD2O1Q1wDBz04983StpAsxqAKg5PAD+dJdAIBc76r4gqckIYf5RSvpiwU+7pYXLDqt3d4lxtJpK9+6BRdEUqVzrPgGUi3Z6BK7QcTSxdT9r96gWUoI4VOZOHvjHTzSUI/Ymie894Inpn7I2ugfa+SpVam6sCon4QBwKJIu65OIpmH1uNYPU4IqWqhhf/5+8BqRZ6H7uK1d6fUClViRAynj14JjiaW5Cb1jlWrOnli1jnvTH6kZ8tcZhsagDxUDwD+BtaUQOaW/E9sv1bl9z7D1lKc5Lg9Udp09WMVFczaXWm56NBGUju6jQf+P7p6e1G7xVKEPOf9dI5rNf32RazoVEJsyW5jSEShKb32Eg5g=" distributions: "sdist bdist_wheel" + skip_existing: true on: tags: true - python: 3.7 + condition: $TRAVIS_PYTHON_VERSION = 3.7 || $TRAVIS_PYTHON_VERSION == 2.7 repo: rado0x54/python-carson-living From f9166c1f1ff39ea287d558af970dd54072eeaa72 Mon Sep 17 00:00:00 2001 From: Martin Riedel Date: Sat, 25 Jan 2020 14:38:43 -0500 Subject: [PATCH 2/6] Made conditions to conform with POSIX. --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2bd0943..7e4c8bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,8 @@ cache: pip # Coverall and Lint only in 3.7 after_success: - - if [ "$TRAVIS_PYTHON_VERSION" == "3.7" ]; then tox -e lint; fi - - if [ "$TRAVIS_PYTHON_VERSION" == "3.7" ]; then coveralls; fi + - if [ $TRAVIS_PYTHON_VERSION = 3.7 ]; then tox -e lint; fi + - if [ $TRAVIS_PYTHON_VERSION = 3.7 ]; then coveralls; fi deploy: # Test PYPI @@ -35,10 +35,11 @@ deploy: password: secure: m/iNGZX8iIdta1ko/0yTZ994hM6aJqiLcgen1Au/DwgFYAbh2AWCFyQNeghqn4KwG1+LSb4TQdpGWgrx3lB2dFnHIVrkSYC25OBelg+1gmCO+7VUOM3Ysyxy2Av/fjR2N0xqxCwepr2xl5hUc4wdm+hKkKj13vhClQuQkp8quz2iagAuOsIHja1uDmoVM4IPQg+KBtQA1HpQp1f2v/O/qW4bfJKHqbhEzVXS5LMoN7LUh3iBjwwolPsuGE/3MwB9YgGZvdSIAsS/Wyam/7i7pSg8HgnXnRH3jucNZ84fh/1bVunpmyP8ebO+lhrryukkRRap82Vb7oQLN82SGqwFiBZZ+2LqCD4z/UOg67+6ZvTx0R06aK1WMpIwSd+sY5ohBHPIDR645m9m/z5N7JHY5ydeUi6NxRVTJjkfTRzjowV427r9UFgGFP/qXBRcgxB36FhXMw8q8tsNnKkB3wvmxPN7RbCUyQG7In2TxBuXCHiHXAGAM6B70ktHc3wK0dtRZF0hqSIQIqUlKiHjjL/IkwdYo5Fg/26HszczqlD0ZSD0uJq4BxJjQQ5di7vcgyu9BcP9rDHIenFZXW+ccMSVx0GD6bAUCJT/+RwWa3YARPojDoaDv+FcKeMBTIQFeOsi7lYwxqFL28YiGfSjQnkFsVmeH91YG0dW7u7l+GBZGsk= server: https://test.pypi.org/legacy/ + distributions: "sdist bdist_wheel" skip_existing: true on: branch: develop - condition: $TRAVIS_PYTHON_VERSION = 3.7 || $TRAVIS_PYTHON_VERSION == 2.7 + condition: $TRAVIS_PYTHON_VERSION = 3.7 -o $TRAVIS_PYTHON_VERSION = 2.7 repo: rado0x54/python-carson-living # Prod PYPI 3.7 - provider: pypi @@ -49,5 +50,5 @@ deploy: skip_existing: true on: tags: true - condition: $TRAVIS_PYTHON_VERSION = 3.7 || $TRAVIS_PYTHON_VERSION == 2.7 + condition: $TRAVIS_PYTHON_VERSION = 3.7 -o $TRAVIS_PYTHON_VERSION = 2.7 repo: rado0x54/python-carson-living From c80029ce1d8b853cb699281c74382cd8a9daf206 Mon Sep 17 00:00:00 2001 From: Martin Riedel Date: Sat, 25 Jan 2020 14:57:09 -0500 Subject: [PATCH 3/6] changed if to test. Trying to fix broken condition. "travis_run_after_success: command not found" --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7e4c8bc..884daee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,8 @@ cache: pip # Coverall and Lint only in 3.7 after_success: - - if [ $TRAVIS_PYTHON_VERSION = 3.7 ]; then tox -e lint; fi - - if [ $TRAVIS_PYTHON_VERSION = 3.7 ]; then coveralls; fi + - test $TRAVIS_PYTHON_VERSION = 3.7 && tox -e lint + - test $TRAVIS_PYTHON_VERSION = 3.7 && coveralls deploy: # Test PYPI From 40f9e1b237793a7a9961915f4d22e8711afbfff0 Mon Sep 17 00:00:00 2001 From: Martin Riedel Date: Sat, 25 Jan 2020 15:09:23 -0500 Subject: [PATCH 4/6] moved condition in deploy back to bash, since this seems required. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 884daee..e539d47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ deploy: skip_existing: true on: branch: develop - condition: $TRAVIS_PYTHON_VERSION = 3.7 -o $TRAVIS_PYTHON_VERSION = 2.7 + condition: $TRAVIS_PYTHON_VERSION == 3.7 || $TRAVIS_PYTHON_VERSION == 2.7 repo: rado0x54/python-carson-living # Prod PYPI 3.7 - provider: pypi @@ -50,5 +50,5 @@ deploy: skip_existing: true on: tags: true - condition: $TRAVIS_PYTHON_VERSION = 3.7 -o $TRAVIS_PYTHON_VERSION = 2.7 + condition: $TRAVIS_PYTHON_VERSION == 3.7 || $TRAVIS_PYTHON_VERSION == 2.7 repo: rado0x54/python-carson-living From 49d04bd846049189901a9e2fa56dc5c749ae825a Mon Sep 17 00:00:00 2001 From: Martin Riedel Date: Sat, 25 Jan 2020 16:27:48 -0500 Subject: [PATCH 5/6] Updated Readme. Exposed function to update auth_key in eagle eye manually. --- README.rst | 51 +++++++++++++++++++++++++++++++++------ carson_living/eagleeye.py | 4 +-- scripts/carsoncli.py | 21 +++++++++++++--- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/README.rst b/README.rst index 0200f28..c3d89da 100644 --- a/README.rst +++ b/README.rst @@ -2,6 +2,9 @@ Carson Living Python API ======================== +.. image:: https://badge.fury.io/py/carson-living.svg + :target: https://badge.fury.io/py/carson-living + .. image:: https://travis-ci.org/rado0x54/python-carson-living.svg?branch=master :target: https://travis-ci.org/rado0x54/python-carson-living @@ -11,6 +14,9 @@ Carson Living Python API .. image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg :target: https://opensource.org/licenses/Apache-2.0 +.. image:: https://img.shields.io/pypi/pyversions/carson-living.svg + :target: https://pypi.python.org/pypi/carson-living + Python Carson Living is a library written in Python that exposes the carson.live devices as Python objects. Please note, that `Carson `_ does not provide an official API documentation, therefore this project @@ -25,8 +31,8 @@ Carson Living Python should work against **Python 2.x >= 2.7** and **Python 3.x .. code-block:: - # Installing from PyPi (TODO / Unsupported) - $ pip install carson_living + # Installing from PyPi + $ pip install carson-living # Installing latest development $ pip install \ @@ -84,7 +90,7 @@ Eagle Eye cameras can produce live images and videos but also allow access to pa or just pass a generated url with an eagle_eye auth key ``A=c000....``. Please note, that the url can only be accessed as long as the ``auth_key`` is valid. Therefore it may make sense to force the eagle eye api to refresh the auth key before generating a image or video url. -1. Directly save a live image: +- Directly save a live image: .. code-block:: python @@ -92,7 +98,7 @@ force the eagle eye api to refresh the auth key before generating a image or vid with open('image_{}.jpeg'.format(camera.entity_id), 'wb') as file: camera.get_image(file) -2. Directly save a live video of 10s: +- Directly save a live video of 10s: .. code-block:: python @@ -100,7 +106,7 @@ force the eagle eye api to refresh the auth key before generating a image or vid with open('video_{}.flv'.format(camera.entity_id), 'wb') as file: camera.get_video(file, timedelta(seconds=10)) -3. Directly download a image from a timestamp: +- Directly download a image from a timestamp: .. code-block:: python @@ -110,9 +116,40 @@ force the eagle eye api to refresh the auth key before generating a image or vid with open('image_{}.jpeg'.format(camera.entity_id), 'wb') as file: camera.get_image(file, three_hours_ago) -4. Directly download a historic image from a timestamp: +- Directly download a recorded video from a timestamp: + +.. code-block:: python + + three_days_ago = datetime.utcnow() - timedelta(days=3) + # download all videos from 3 days ago + for cam in building.cameras: + with open('video_{}.flv'.format(cam.entity_id), 'wb') as file: + cam.get_video(file, timedelta(seconds=5), three_days_ago) + +- The Carson API is also able to produce authenticated URLs that can be handled externally. + Please not, that the ``auth_key`` has a limited lifetime. Therefore it makes sense to update + the ``auth_key`` manually before retrieving predefined URLs. Note, the Eagle Eye API in Carson + is associated with a building, so it is sufficient to update it once for all cameras in the same + building. The function signature of the the ``_url`` function is identical to the previous ones + (minus the file object). + +.. code-block:: python -TODO. + # Update Session Auth Key of Eagle Eye once in a while if using + # generated authenticated URLs. + # Note, this is not needed for get_image() or get_video() + building.eagleeye_api.update_session_auth_key() + for cam in building.cameras: + img_url = cam.get_image_url(three_days_ago) + print(img_url) + # >> https://cXXX.eagleeyenetworks.com/asset/prev/image.jpeg?id=c0×tamp=20200122211442.575&asset_class=pre&A=c000~... + response = requests.get(img_url) + with open('image_{}_with_url.jpeg'.format(cam.entity_id), 'wb') as file: + file.write(response.content) + # do only 1 cam. + break + +Use ``cam.get_video_url()`` the same way. CLI Tool ~~~~~~~~ diff --git a/carson_living/eagleeye.py b/carson_living/eagleeye.py index 3872d39..b0c31ec 100644 --- a/carson_living/eagleeye.py +++ b/carson_living/eagleeye.py @@ -60,7 +60,7 @@ def get_camera(self, ee_id): """ return self._cameras.get(ee_id) - def _update_session_auth_key(self): + def update_session_auth_key(self): """Updates the internal session state via session_callback Raises: @@ -104,7 +104,7 @@ def authenticated_query(self, url, method='get', params=None, """ if not self._session_auth_key \ or not self._session_brand_subdomain: - self._update_session_auth_key() + self.update_session_auth_key() headers = {'Cookie': 'auth_key={}'.format(self._session_auth_key)} headers.update(BASE_HEADERS) diff --git a/scripts/carsoncli.py b/scripts/carsoncli.py index 985f523..329f64e 100755 --- a/scripts/carsoncli.py +++ b/scripts/carsoncli.py @@ -7,6 +7,8 @@ from datetime import timedelta, datetime +import requests + from carson_living import Carson, CarsonAPIError @@ -112,16 +114,27 @@ def main(): print(door) _bar() - three_hours_ago = datetime.utcnow() - timedelta(hours=3) + three_days_ago = datetime.utcnow() - timedelta(days=3) # download all images from 3 hours ago + + # Update Session Auth Key of Eagle Eye once in a while if using + # generated authenticated URLs. + # Note, this is not needed for get_image() or get_video() + building.eagleeye_api.update_session_auth_key() for cam in building.cameras: - with open('image_{}.jpeg'.format(cam.entity_id), 'wb') as file: - cam.get_image(file, three_hours_ago) + img_url = cam.get_image_url(three_days_ago) + print(img_url) + response = requests.get(img_url) + with open('image_{}_with_url.jpeg'.format( + cam.entity_id), 'wb') as file: + file.write(response.content) + # do only 1 cam. + break try: for cam in building.cameras: with open('video_{}.flv'.format(cam.entity_id), 'wb') as file: - cam.get_video(file, timedelta(seconds=5), three_hours_ago) + cam.get_video(file, timedelta(seconds=5), three_days_ago) except CarsonAPIError as error: # Somehow historic videos currently return # 422 Client Error: Error generating keyframes. From 3af76ae8b7ab3e88646e02514a0227beeb0c3017 Mon Sep 17 00:00:00 2001 From: Martin Riedel Date: Sat, 25 Jan 2020 16:34:01 -0500 Subject: [PATCH 6/6] Release 0.0.2 identifier --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b7a9baa..3ef6080 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ """Python Carson Living setup script.""" from setuptools import setup -_VERSION = '0.0.1' +_VERSION = '0.0.2' def readme():