mirror of
https://github.com/ep1cman/unifi-protect-backup.git
synced 2025-12-05 23:53:30 +00:00
mypy fixes
This commit is contained in:
@@ -19,9 +19,11 @@ repos:
|
|||||||
# Run the formatter.
|
# Run the formatter.
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v0.901
|
rev: v1.11.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
exclude: tests/
|
exclude: tests/
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- types-click
|
- types-pytz
|
||||||
|
- types-cryptography
|
||||||
|
- types-python-dateutil
|
||||||
|
|||||||
75
poetry.lock
generated
75
poetry.lock
generated
@@ -869,53 +869,60 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "0.900"
|
version = "1.11.1"
|
||||||
description = "Optional static typing for Python"
|
description = "Optional static typing for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy-0.900-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:07efc88486877d595cca7f7d237e6d04d1ba6f01dc8f74a81b716270f6770968"},
|
{file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"},
|
||||||
{file = "mypy-0.900-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:80c96f97de241ee7383cfe646bfc51113a48089d50c33275af0033b98dee3b1c"},
|
{file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"},
|
||||||
{file = "mypy-0.900-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:0e703c0afe36511746513d168e1d2a52f88e2a324169b87a6b6a58901c3afcf3"},
|
{file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"},
|
||||||
{file = "mypy-0.900-cp35-cp35m-win_amd64.whl", hash = "sha256:23100137579d718cd6f05d572574ca00701fa2bfc7b645ebc5130d93e2af3bee"},
|
{file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"},
|
||||||
{file = "mypy-0.900-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:468b3918b26f81d003e8e9b788c62160acb885487cf4d83a3f22ba9061cb49e2"},
|
{file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"},
|
||||||
{file = "mypy-0.900-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d90c296cd5cdef86e720a0994d41d72c06d6ff8ab8fc6aaaf0ee6c675835d596"},
|
{file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"},
|
||||||
{file = "mypy-0.900-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:42d66b3d716fe5e22b32915d1fa59e7183a0e02f00b337b834a596c1f5e37f01"},
|
{file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"},
|
||||||
{file = "mypy-0.900-cp36-cp36m-win_amd64.whl", hash = "sha256:a354613b4cc6e0e9f1ba7811083cd8f63ccee97333d1df7594c438399c83249a"},
|
{file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"},
|
||||||
{file = "mypy-0.900-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:22f97de97373dd6180c4abee90b20c60780820284d2cdc5579927c0e37854cf6"},
|
{file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"},
|
||||||
{file = "mypy-0.900-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e75f0c97cfe8d86da89b22ad7039f5af44b8f6b0af12bd2877791a92b4b9e987"},
|
{file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"},
|
||||||
{file = "mypy-0.900-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:41f082275a20e3eea48364915f7bc6ec5338be89db1ed8b2e570b9e3d12d4dc6"},
|
{file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"},
|
||||||
{file = "mypy-0.900-cp37-cp37m-win_amd64.whl", hash = "sha256:83adbf3f8c5023f4276557fbcb3b6306f9dce01783e8ac5f8c11fcb29f62e899"},
|
{file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"},
|
||||||
{file = "mypy-0.900-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2220f97804890f3e6da3f849f81f3e56e367a2027a51dde5ce3b7ebb2ad3342b"},
|
{file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"},
|
||||||
{file = "mypy-0.900-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:3f1d0601842c6b4248923963fc59a6fdd05dee0fddc8b07e30c508b6a269e68f"},
|
{file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"},
|
||||||
{file = "mypy-0.900-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c2f87505840c0f3557ea4aa5893f2459daf6516adac30b15d1d5cf567e0d7939"},
|
{file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"},
|
||||||
{file = "mypy-0.900-cp38-cp38-win_amd64.whl", hash = "sha256:a0461da00ed23d17fcb04940db2b72f920435cf79be943564b717e378ffeeddf"},
|
{file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"},
|
||||||
{file = "mypy-0.900-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9560b1f572cdaab43fdcdad5ef45138e89dc191729329db1b8ce5636f4cdeacf"},
|
{file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"},
|
||||||
{file = "mypy-0.900-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d794f10b9f28d21af7a93054e217872aaf9b9ad1bd354ae5e1a3a923d734b73f"},
|
{file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"},
|
||||||
{file = "mypy-0.900-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:68fd1c1c1fc9b405f0ed6cfcd00541de7e83f41007419a125c20fa5db3881cb1"},
|
{file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"},
|
||||||
{file = "mypy-0.900-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7eb1e5820deb71e313aa2b5a5220803a9b2e3efa43475537a71d0ffed7495e1e"},
|
{file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"},
|
||||||
{file = "mypy-0.900-cp39-cp39-win_amd64.whl", hash = "sha256:6598e39cd5aa1a09d454ad39687b89cf3f3fd7cf1f9c3f81a1a2775f6f6b16f8"},
|
{file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"},
|
||||||
{file = "mypy-0.900-py3-none-any.whl", hash = "sha256:3be7c68fab8b318a2d5bcfac8e028dc77b9096ea1ec5594e9866c8fb57ae0296"},
|
{file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"},
|
||||||
{file = "mypy-0.900.tar.gz", hash = "sha256:65c78570329c54fb40f956f7645e2359af5da9d8c54baa44f461cdc7f4984108"},
|
{file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"},
|
||||||
|
{file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"},
|
||||||
|
{file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"},
|
||||||
|
{file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"},
|
||||||
|
{file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
mypy-extensions = ">=0.4.3,<0.5.0"
|
mypy-extensions = ">=1.0.0"
|
||||||
toml = "*"
|
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||||
typing-extensions = ">=3.7.4"
|
typing-extensions = ">=4.6.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dmypy = ["psutil (>=4.0)"]
|
dmypy = ["psutil (>=4.0)"]
|
||||||
python2 = ["typed-ast (>=1.4.0,<1.5.0)"]
|
install-types = ["pip"]
|
||||||
|
mypyc = ["setuptools (>=50)"]
|
||||||
|
reports = ["lxml"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy-extensions"
|
name = "mypy-extensions"
|
||||||
version = "0.4.4"
|
version = "1.0.0"
|
||||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
description = "Type system extensions for programs checked with the mypy type checker."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7"
|
python-versions = ">=3.5"
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy_extensions-0.4.4.tar.gz", hash = "sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd"},
|
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||||
|
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1992,4 +1999,4 @@ multidict = ">=4.0"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.10.0,<4.0"
|
python-versions = ">=3.10.0,<4.0"
|
||||||
content-hash = "81ee0cdb5af9e498001e3e8239c0ba259d114e19a2099f133b2de9645f596788"
|
content-hash = "dea68a0cc11ccb56faf879210d124f44b2ee73a7a36205f1214dd8ab35451d1c"
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ uiprotect = "^5.4.0"
|
|||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
mypy = "^0.900"
|
mypy = "^1.11.1"
|
||||||
types-pytz = "^2021.3.5"
|
types-pytz = "^2021.3.5"
|
||||||
types-cryptography = "^3.3.18"
|
types-cryptography = "^3.3.18"
|
||||||
types-python-dateutil = "^2.8.19.10"
|
types-python-dateutil = "^2.8.19.10"
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ from .uploader import VideoUploader
|
|||||||
from .missing_event_checker import MissingEventChecker
|
from .missing_event_checker import MissingEventChecker
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
VideoDownloader,
|
"VideoDownloader",
|
||||||
VideoDownloaderExperimental,
|
"VideoDownloaderExperimental",
|
||||||
EventListener,
|
"EventListener",
|
||||||
Purge,
|
"Purge",
|
||||||
VideoUploader,
|
"VideoUploader",
|
||||||
MissingEventChecker,
|
"MissingEventChecker",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ class VideoDownloaderExperimental:
|
|||||||
else:
|
else:
|
||||||
self._has_ffprobe = False
|
self._has_ffprobe = False
|
||||||
|
|
||||||
|
raise RuntimeError("The `uiprotect` library is currently missing the features for this to work.")
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
"""Main loop."""
|
"""Main loop."""
|
||||||
self.logger.info("Starting Downloader")
|
self.logger.info("Starting Downloader")
|
||||||
@@ -149,7 +151,10 @@ class VideoDownloaderExperimental:
|
|||||||
self._failures[event.id] = 1
|
self._failures[event.id] = 1
|
||||||
else:
|
else:
|
||||||
self._failures[event.id] += 1
|
self._failures[event.id] += 1
|
||||||
self.logger.warning(f"Event failed download attempt {self._failures[event.id]}", exc_info=e)
|
self.logger.warning(
|
||||||
|
f"Event failed download attempt {self._failures[event.id]}",
|
||||||
|
exc_info=e,
|
||||||
|
)
|
||||||
|
|
||||||
if self._failures[event.id] >= 10:
|
if self._failures[event.id] >= 10:
|
||||||
self.logger.error(
|
self.logger.error(
|
||||||
@@ -171,7 +176,10 @@ class VideoDownloaderExperimental:
|
|||||||
self.current_event = None
|
self.current_event = None
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Unexpected exception occurred, abandoning event {event.id}:", exc_info=e)
|
self.logger.error(
|
||||||
|
f"Unexpected exception occurred, abandoning event {event.id}:",
|
||||||
|
exc_info=e,
|
||||||
|
)
|
||||||
|
|
||||||
async def _download(self, event: Event) -> Optional[bytes]:
|
async def _download(self, event: Event) -> Optional[bytes]:
|
||||||
"""Downloads the video clip for the given event."""
|
"""Downloads the video clip for the given event."""
|
||||||
@@ -181,8 +189,12 @@ class VideoDownloaderExperimental:
|
|||||||
assert isinstance(event.start, datetime)
|
assert isinstance(event.start, datetime)
|
||||||
assert isinstance(event.end, datetime)
|
assert isinstance(event.end, datetime)
|
||||||
try:
|
try:
|
||||||
prepared_video_file = await self._protect.prepare_camera_video(event.camera_id, event.start, event.end)
|
prepared_video_file = await self._protect.prepare_camera_video( # type: ignore
|
||||||
video = await self._protect.download_camera_video(event.camera_id, prepared_video_file["fileName"])
|
event.camera_id, event.start, event.end
|
||||||
|
)
|
||||||
|
video = await self._protect.download_camera_video( # type: ignore
|
||||||
|
event.camera_id, prepared_video_file["fileName"]
|
||||||
|
)
|
||||||
assert isinstance(video, bytes)
|
assert isinstance(video, bytes)
|
||||||
break
|
break
|
||||||
except (AssertionError, ClientPayloadError, TimeoutError) as e:
|
except (AssertionError, ClientPayloadError, TimeoutError) as e:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List
|
from typing import AsyncIterator, List
|
||||||
|
|
||||||
import aiosqlite
|
import aiosqlite
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
@@ -54,14 +54,14 @@ class MissingEventChecker:
|
|||||||
self.ignore_cameras: List[str] = ignore_cameras
|
self.ignore_cameras: List[str] = ignore_cameras
|
||||||
self.interval: int = interval
|
self.interval: int = interval
|
||||||
|
|
||||||
async def _get_missing_events(self) -> List[Event]:
|
async def _get_missing_events(self) -> AsyncIterator[Event]:
|
||||||
start_time = datetime.now() - self.retention
|
start_time = datetime.now() - self.retention
|
||||||
end_time = datetime.now()
|
end_time = datetime.now()
|
||||||
chunk_size = 500
|
chunk_size = 500
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Get list of events that need to be backed up from unifi protect
|
# Get list of events that need to be backed up from unifi protect
|
||||||
logger.extra_debug(f"Fetching events for interval: {start_time} - {end_time}")
|
logger.extra_debug(f"Fetching events for interval: {start_time} - {end_time}") # type: ignore
|
||||||
events_chunk = await self._protect.get_events(
|
events_chunk = await self._protect.get_events(
|
||||||
start=start_time,
|
start=start_time,
|
||||||
end=end_time,
|
end=end_time,
|
||||||
@@ -72,6 +72,7 @@ class MissingEventChecker:
|
|||||||
if not events_chunk:
|
if not events_chunk:
|
||||||
break # There were no events to backup
|
break # There were no events to backup
|
||||||
|
|
||||||
|
assert events_chunk[-1].end is not None
|
||||||
start_time = events_chunk[-1].end
|
start_time = events_chunk[-1].end
|
||||||
unifi_events = {event.id: event for event in events_chunk}
|
unifi_events = {event.id: event for event in events_chunk}
|
||||||
|
|
||||||
@@ -166,6 +167,9 @@ class MissingEventChecker:
|
|||||||
await self._download_queue.put(event)
|
await self._download_queue.put(event)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Unexpected exception occurred during missing event check:", exc_info=e)
|
logger.error(
|
||||||
|
"Unexpected exception occurred during missing event check:",
|
||||||
|
exc_info=e,
|
||||||
|
)
|
||||||
|
|
||||||
await asyncio.sleep(self.interval)
|
await asyncio.sleep(self.interval)
|
||||||
|
|||||||
@@ -21,7 +21,13 @@ from unifi_protect_backup import (
|
|||||||
VideoUploader,
|
VideoUploader,
|
||||||
notifications,
|
notifications,
|
||||||
)
|
)
|
||||||
from unifi_protect_backup.utils import SubprocessException, VideoQueue, human_readable_size, run_command, setup_logging
|
from unifi_protect_backup.utils import (
|
||||||
|
SubprocessException,
|
||||||
|
VideoQueue,
|
||||||
|
human_readable_size,
|
||||||
|
run_command,
|
||||||
|
setup_logging,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -67,7 +73,7 @@ class UnifiProtectBackup:
|
|||||||
max_event_length: int,
|
max_event_length: int,
|
||||||
sqlite_path: str = "events.sqlite",
|
sqlite_path: str = "events.sqlite",
|
||||||
color_logging: bool = False,
|
color_logging: bool = False,
|
||||||
download_rate_limit: float = None,
|
download_rate_limit: float | None = None,
|
||||||
port: int = 443,
|
port: int = 443,
|
||||||
use_experimental_downloader: bool = False,
|
use_experimental_downloader: bool = False,
|
||||||
):
|
):
|
||||||
@@ -196,7 +202,10 @@ class UnifiProtectBackup:
|
|||||||
await self._protect.update()
|
await self._protect.update()
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Failed to connect to UniFi Protect, retrying in {attempts}s...", exc_info=e)
|
logger.warning(
|
||||||
|
f"Failed to connect to UniFi Protect, retrying in {attempts}s...",
|
||||||
|
exc_info=e,
|
||||||
|
)
|
||||||
await asyncio.sleep(attempts)
|
await asyncio.sleep(attempts)
|
||||||
else:
|
else:
|
||||||
raise ConnectionError("Failed to connect to UniFi Protect after 10 attempts")
|
raise ConnectionError("Failed to connect to UniFi Protect after 10 attempts")
|
||||||
@@ -269,7 +278,11 @@ class UnifiProtectBackup:
|
|||||||
# Create purge task
|
# Create purge task
|
||||||
# This will, every midnight, purge old backups from the rclone remotes and database
|
# This will, every midnight, purge old backups from the rclone remotes and database
|
||||||
purge = Purge(
|
purge = Purge(
|
||||||
self._db, self.retention, self.rclone_destination, self._purge_interval, self.rclone_purge_args
|
self._db,
|
||||||
|
self.retention,
|
||||||
|
self.rclone_destination,
|
||||||
|
self._purge_interval,
|
||||||
|
self.rclone_purge_args,
|
||||||
)
|
)
|
||||||
tasks.append(purge.start())
|
tasks.append(purge.start())
|
||||||
|
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ async def get_camera_name(protect: ProtectApiClient, id: str):
|
|||||||
# Refresh cameras
|
# Refresh cameras
|
||||||
logger.debug(f"Unknown camera id: '{id}', checking API")
|
logger.debug(f"Unknown camera id: '{id}', checking API")
|
||||||
|
|
||||||
await protect.update(force=True)
|
await protect.update()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
name = protect.bootstrap.cameras[id].name
|
name = protect.bootstrap.cameras[id].name
|
||||||
@@ -377,7 +377,7 @@ class VideoQueue(asyncio.Queue):
|
|||||||
self._queue.append(item) # type: ignore
|
self._queue.append(item) # type: ignore
|
||||||
self._bytes_sum += len(item[1])
|
self._bytes_sum += len(item[1])
|
||||||
|
|
||||||
def full(self, item: tuple[Event, bytes] = None):
|
def full(self, item: tuple[Event, bytes] | None = None):
|
||||||
"""Return True if there are maxsize bytes in the queue.
|
"""Return True if there are maxsize bytes in the queue.
|
||||||
|
|
||||||
optionally if `item` is provided, it will return False if there is enough space to
|
optionally if `item` is provided, it will return False if there is enough space to
|
||||||
|
|||||||
Reference in New Issue
Block a user