Skip to content

Commit

Permalink
Merge pull request #951 from fronzbot/dev
Browse files Browse the repository at this point in the history
0.23.0
  • Loading branch information
fronzbot authored Jun 19, 2024
2 parents ae0e26f + bb0adb6 commit 098d43b
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 40 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: build

on:
push:
branches: [ master, dev ]
pull_request:
branches: [ master, dev ]

jobs:
build:
runs-on: ${{ matrix.platform }}
strategy:
matrix:
platform:
- ubuntu-latest
python-version: ['3.11']
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements_test.txt
pip install tox
- name: Build Wheel
run: |
tox -r -e build
49 changes: 32 additions & 17 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@ on:

jobs:
coverage:
runs-on: ${{ matrix.platform }}
runs-on: ubuntu-latest
strategy:
max-parallel: 1
matrix:
platform:
- ubuntu-latest
python-version: ['3.11']

steps:
- uses: actions/checkout@v4
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -28,16 +25,34 @@ jobs:
pip install -r requirements.txt
pip install -r requirements_test.txt
pip install tox
pip install codecov
- name: Test
- name: Run Coverage
run: |
tox -r -e cov
- name: Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Upload coverage
uses: actions/upload-artifact@v4.3.3
with:
flags: unittests
file: ./coverage.xml
name: blinkpy
fail_ci_if_error: true
name: coverage-${{ matrix.python-version }}
path: coverage.xml
overwrite: true
upload-coverage:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11']
needs:
- coverage
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.7
with:
name: coverage-${{ matrix.python-version }}
path: coverage.xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4.4.1
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
name: blinkpy
15 changes: 10 additions & 5 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ on:
branches: [ master, dev ]
pull_request:
branches: [ master, dev ]

jobs:
lint:
runs-on: ubuntu-latest
strategy:
max-parallel: 2
matrix:
python-version: [3.11]
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v4
Expand All @@ -27,7 +27,12 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements_test.txt
pip install tox
- name: Lint
- name: Ruff
run: |
ruff check blinkpy tests blinkapp
- name: Black
run: |
black --check --color --diff blinkpy tests blinkapp
- name: RST-Lint
run: |
tox -r -e lint
rst-lint README.rst CHANGES.rst CONTRIBUTING.rst
16 changes: 10 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: build
name: tests

on:
push:
Expand All @@ -7,17 +7,17 @@ on:
branches: [ master, dev ]

jobs:
build:
pytest:
runs-on: ${{ matrix.platform }}
strategy:
max-parallel: 4
matrix:
platform:
- ubuntu-latest
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v3
- name: Check out code from GitHub
uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
Expand All @@ -27,7 +27,11 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements_test.txt
pip install tox
pip install .
- name: Tests
run: |
tox -r
python -m pytest \
--timeout=30 \
--durations=10 \
--cov=blinkpy \
--cov-report term-missing
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ Changelog

A list of changes between each release

0.23.0 (2024-06-19)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

See release notes: (`0.23.0 <https://github.com/fronzbot/blinkpy/releases/tag/v0.23.0>`__)


0.22.7 (2024-04-15)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
37 changes: 35 additions & 2 deletions blinkpy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ async def request_login(
async def request_verify(auth, blink, verify_key):
"""Send verification key to blink servers."""
url = (
f"{blink.urls.base_url}/api/v4/account/{blink.account_id}"
f"/client/{blink.client_id}/pin/verify"
f"{blink.urls.base_url}/api/v5/accounts/{blink.account_id}"
f"/users/{blink.auth.user_id}"
f"/clients/{blink.client_id}/client_verification/pin/verify"
)
data = dumps({"pin": verify_key})
return await auth.query(
Expand Down Expand Up @@ -165,6 +166,38 @@ async def request_system_disarm(blink, network, **kwargs):
return response


async def request_notification_flags(blink, **kwargs):
"""
Get system notification flags.
:param blink: Blink instance.
"""
url = (
f"{blink.urls.base_url}/api/v1/accounts/{blink.account_id}"
"/notifications/configuration"
)
response = await http_get(blink, url)
await wait_for_command(blink, response)
return response


async def request_set_notification_flag(blink, data_dict):
"""
Set a system notification flag.
:param blink: Blink instance.
:param data_dict: Dictionary of notifications to set.
"""
url = (
f"{blink.urls.base_url}/api/v1/accounts/{blink.account_id}"
"/notifications/configuration"
)
data = dumps({"notifications": data_dict})
response = await http_post(blink, url, data=data, json=False)
await wait_for_command(blink, response)
return response


async def request_command_status(blink, network, command_id):
"""
Request command status.
Expand Down
3 changes: 3 additions & 0 deletions blinkpy/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(
self.region_id = login_data.get("region_id", None)
self.client_id = login_data.get("client_id", None)
self.account_id = login_data.get("account_id", None)
self.user_id = login_data.get("user_id", None)
self.login_response = None
self.is_errored = False
self.no_prompt = no_prompt
Expand All @@ -64,6 +65,7 @@ def login_attributes(self):
self.data["region_id"] = self.region_id
self.data["client_id"] = self.client_id
self.data["account_id"] = self.account_id
self.data["user_id"] = self.user_id
return self.data

@property
Expand Down Expand Up @@ -130,6 +132,7 @@ def extract_login_info(self):
self.token = self.login_response["auth"]["token"]
self.client_id = self.login_response["account"]["client_id"]
self.account_id = self.login_response["account"]["account_id"]
self.user_id = self.login_response["account"].get("user_id", None)

async def startup(self):
"""Initialize tokens for communication."""
Expand Down
22 changes: 20 additions & 2 deletions blinkpy/blinkpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import logging
import datetime
import aiofiles
import aiofiles.ospath
from requests.structures import CaseInsensitiveDict
from dateutil.parser import parse
from slugify import slugify
Expand Down Expand Up @@ -143,6 +144,8 @@ async def setup_prompt_2fa(self):
async def setup_post_verify(self):
"""Initialize blink system after verification."""
try:
if not self.homescreen:
await self.get_homescreen()
await self.setup_networks()
networks = self.setup_network_ids()
cameras = await self.setup_camera_list()
Expand Down Expand Up @@ -191,7 +194,7 @@ async def setup_owls(self):
network_list.append(str(network_id))
self.sync[name] = BlinkOwl(self, name, network_id, owl)
await self.sync[name].start()
except KeyError:
except (KeyError, TypeError):
# No sync-less devices found
pass

Expand Down Expand Up @@ -221,7 +224,7 @@ async def setup_lotus(self):
network_list.append(str(network_id))
self.sync[name] = BlinkLotus(self, name, network_id, lotus)
await self.sync[name].start()
except KeyError:
except (KeyError, TypeError):
# No sync-less devices found
pass

Expand Down Expand Up @@ -317,6 +320,21 @@ async def save(self, file_name):
"""Save login data to file."""
await util.json_save(self.auth.login_attributes, file_name)

async def get_status(self):
"""Get the blink system notification status."""
response = await api.request_notification_flags(self)
return response.get("notifications", response)

async def set_status(self, data_dict={}):
"""
Set the blink system notification status.
:param data_dict: Dictionary of notification keys to modify.
Example: {'low_battery': False, 'motion': False}
"""
response = await api.request_set_notification_flag(self, data_dict)
return response

async def download_videos(
self, path, since=None, camera="all", stop=10, delay=1, debug=False
):
Expand Down
23 changes: 23 additions & 0 deletions blinkpy/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,17 @@ async def async_arm(self, value):
await api.wait_for_command(self.sync.blink, response)
return response

async def record(self):
"""Initiate clip recording for a blink mini camera."""
url = (
f"{self.sync.urls.base_url}/api/v1/accounts/"
f"{self.sync.blink.account_id}/networks/"
f"{self.network_id}/owls/{self.camera_id}/clip"
)
response = await api.http_post(self.sync.blink, url)
await api.wait_for_command(self.sync.blink, response)
return response

async def snap_picture(self):
"""Snap picture for a blink mini camera."""
url = (
Expand Down Expand Up @@ -575,6 +586,18 @@ async def async_arm(self, value):
await api.wait_for_command(self.sync.blink, response)
return response

async def record(self):
"""Initiate clip recording for a blink doorbell camera."""
url = (
f"{self.sync.urls.base_url}/api/v1/accounts/"
f"{self.sync.blink.account_id}/networks/"
f"{self.sync.network_id}/doorbells/{self.camera_id}/clip"
)

response = await api.http_post(self.sync.blink, url)
await api.wait_for_command(self.sync.blink, response)
return response

async def snap_picture(self):
"""Snap picture for a blink doorbell camera."""
url = (
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "blinkpy"
version = "0.22.7"
version = "0.23.0"
license = {text = "MIT"}
description = "A Blink camera Python Library."
readme = "README.rst"
Expand Down
10 changes: 5 additions & 5 deletions requirements_test.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
ruff==0.3.7
black==24.3.0
ruff==0.4.9
black==24.4.2
build==1.2.1
coverage==7.4.4
pytest==8.1.1
coverage==7.5.3
pytest==8.2.2
pytest-cov==5.0.0
pytest-sugar==1.0.0
pytest-timeout==2.3.1
restructuredtext-lint==1.4.0
pygments==2.17.2
pygments==2.18.0
testtools>=2.4.0
sortedcontainers~=2.4.0
pytest-asyncio>=0.21.0
Loading

0 comments on commit 098d43b

Please sign in to comment.