Skip to content

Commit

Permalink
Merge pull request #5 from rado0x54/develop
Browse files Browse the repository at this point in the history
Release 0.0.2
  • Loading branch information
rado0x54 authored Jan 25, 2020
2 parents 89b7948 + a9bb4f6 commit b2f740d
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 21 deletions.
15 changes: 8 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -38,16 +38,17 @@ deploy:
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
51 changes: 44 additions & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 <https://carson.live>`_ does not provide an official API documentation, therefore this project
Expand All @@ -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 \
Expand Down Expand Up @@ -84,23 +90,23 @@ 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
for camera in building.cameras:
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
for camera in building.cameras:
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
Expand All @@ -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&timestamp=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
~~~~~~~~
Expand Down
4 changes: 2 additions & 2 deletions carson_living/eagleeye.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
21 changes: 17 additions & 4 deletions scripts/carsoncli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from datetime import timedelta, datetime

import requests

from carson_living import Carson, CarsonAPIError


Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""Python Carson Living setup script."""
from setuptools import setup

_VERSION = '0.0.1'
_VERSION = '0.0.2'


def readme():
Expand Down

0 comments on commit b2f740d

Please sign in to comment.