Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add poetry #10

Merged
merged 4 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ repos:
- id: detect-private-key
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/python-poetry/poetry
rev: 1.8.0
hooks:
- id: poetry-check
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
args: ["--tab-width", "2"]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.5
hooks:
Expand Down
101 changes: 101 additions & 0 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

130 changes: 130 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
[tool.poetry]
name = "uvcclient"
version = "0.11.1"
description = "A remote control client for Ubiquiti's UVC NVR"
authors = ["Dan Smith <[email protected]>"]
readme = "README.rst"
repository = "https://github.com/uilibs/uvcclient"
classifiers = [
"Intended Audience :: Developers",
"Natural Language :: English",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Build Tools",
"Development Status :: 5 - Production/Stable",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)"
]
packages = [
{ include = "uvcclient", from = "src" },
]

[tool.poetry.urls]
"Bug Tracker" = "https://github.com/uilibs/uvcclient/issues"
"Changelog" = "https://github.com/uilibs/uvcclient/blob/main/CHANGELOG.md"

[tool.poetry.dependencies]
python = ">=3.10"

[tool.poetry.group.dev.dependencies]
pytest = ">=7,<9"

[tool.semantic_release]
version_toml = ["pyproject.toml:tool.poetry.version"]
version_variables = [
"src/uvcclient/__init__.py:__version__",
"docs/conf.py:release",
]
build_command = "pip install poetry && poetry build"

[tool.semantic_release.changelog]
exclude_commit_patterns = [
"chore*",
"ci*",
]

[tool.semantic_release.changelog.environment]
keep_trailing_newline = true

[tool.semantic_release.branches.main]
match = "main"

[tool.semantic_release.branches.noop]
match = "(?!main$)"
prerelease = true

[tool.pytest.ini_options]
addopts = "-v -Wdefault --cov=uvcclient --cov-report=term-missing:skip-covered -n=auto"
pythonpath = ["src"]

[tool.coverage.run]
branch = true

[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"@overload",
"if TYPE_CHECKING",
"raise NotImplementedError",
'if __name__ == "__main__":',
]

[tool.ruff]
target-version = "py310"
line-length = 88

[tool.ruff.lint]
ignore = [
"S101", # use of assert
"D203", # 1 blank line required before class docstring
"D212", # Multi-line docstring summary should start at the first line
"D100", # Missing docstring in public module
"D101", # Missing docstring in public module
"D102", # Missing docstring in public method
"D103", # Missing docstring in public module
"D104", # Missing docstring in public package
"D105", # Missing docstring in magic method
"D107", # Missing docstring in `__init__`
"D400", # First line should end with a period
"D401", # First line of docstring should be in imperative mood
"D205", # 1 blank line required between summary line and description
"D415", # First line should end with a period, question mark, or exclamation point
"D417", # Missing argument descriptions in the docstring
"E501", # Line too long
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
"B008", # Do not perform function call
"S110", # `try`-`except`-`pass` detected, consider logging the exception
"D106", # Missing docstring in public nested class
"UP031",
"B904",
"UP007", # typer needs Optional syntax
"UP038", # Use `X | Y` in `isinstance` is slower
"S603", # check for execution of untrusted input
]
select = [
"B", # flake8-bugbear
"D", # flake8-docstrings
"C4", # flake8-comprehensions
"S", # flake8-bandit
"F", # pyflake
"E", # pycodestyle
"W", # pycodestyle
"UP", # pyupgrade
"I", # isort
"RUF", # ruff specific
]

[tool.ruff.lint.per-file-ignores]
"tests/**/*" = [
"D100",
"D101",
"D102",
"D103",
"D104",
"S101",
]

[tool.ruff.lint.isort]
known-first-party = ["uvcclient", "tests"]
17 changes: 0 additions & 17 deletions setup.py

This file was deleted.

File renamed without changes.
8 changes: 4 additions & 4 deletions uvcclient/camera.py → src/uvcclient/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@

import json
import logging
import socket

# Python3 compatibility
try:
import httplib
except ImportError:
from http import client as httplib
try:
import urlparse
import urllib

import urlparse
except ImportError:
import urllib.parse as urlparse

Expand All @@ -37,7 +37,7 @@ class CameraAuthError(Exception):
pass


class UVCCameraClient(object):
class UVCCameraClient:
def __init__(self, host, username, password, port=80):
self._host = host
self._port = port
Expand All @@ -51,7 +51,7 @@ def _safe_request(self, *args, **kwargs):
conn = httplib.HTTPConnection(self._host, self._port)
conn.request(*args, **kwargs)
return conn.getresponse()
except (socket.error, OSError):
except OSError:
raise CameraConnectError("Unable to contact camera")
except httplib.HTTPException as ex:
raise CameraConnectError("Error connecting to camera: %s" % (str(ex)))
Expand Down
6 changes: 2 additions & 4 deletions uvcclient/main.py → src/uvcclient/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@
import optparse
import sys

from uvcclient import nvr
from uvcclient import camera
from uvcclient import store
from uvcclient.nvr import Invalid
from . import camera, nvr, store
from .nvr import Invalid

INFO_STORE = store.get_info_store()

Expand Down
19 changes: 10 additions & 9 deletions uvcclient/nvr.py → src/uvcclient/nvr.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@

import json
import logging
import pprint
import os
import pprint
import zlib


# Python3 compatibility
try:
import httplib
Expand Down Expand Up @@ -50,7 +49,7 @@ class CameraConnectionError(Exception):
pass


class UVCRemote(object):
class UVCRemote:
"""Remote control client for Ubiquiti Unifi Video NVR."""

CHANNEL_NAMES = ["high", "medium", "low"]
Expand Down Expand Up @@ -151,14 +150,14 @@ def dump(self, uuid):
pprint.pprint(data)

def set_recordmode(self, uuid, mode, chan=None):
"""Set the recording mode for a camera by UUID.
"""
Set the recording mode for a camera by UUID.

:param uuid: Camera UUID
:param mode: One of none, full, or motion
:param chan: One of the values from CHANNEL_NAMES
:returns: True if successful, False or None otherwise
"""

url = "/api/2.0/camera/%s" % uuid
data = self._uvc_request(url)
settings = data["data"][0]["recordingSettings"]
Expand Down Expand Up @@ -225,7 +224,8 @@ def list_zones(self, uuid):
return data["data"][0]["zones"]

def index(self):
"""Return an index of available cameras.
"""
Return an index of available cameras.

:returns: A list of dictionaries with keys of name, uuid
"""
Expand All @@ -243,7 +243,8 @@ def index(self):
]

def name_to_uuid(self, name):
"""Attempt to convert a camera name to its UUID.
"""
Attempt to convert a camera name to its UUID.

:param name: Camera name
:returns: The UUID of the first camera with the same name if found,
Expand All @@ -269,7 +270,8 @@ def get_snapshot(self, uuid):


def get_auth_from_env():
"""Attempt to get UVC NVR connection information from the environment.
"""
Attempt to get UVC NVR connection information from the environment.

Supports either a combined variable called UVC formatted like:

Expand All @@ -283,7 +285,6 @@ def get_auth_from_env():

:returns: A tuple like (host, port, apikey, path)
"""

combined = os.getenv("UVC")
if combined:
# http://192.168.1.1:7080/apikey
Expand Down
Loading