Add isort and ruff linter (#6575)

* Add isort and ruff linter

Both linters are pretty common among modern python code bases.

The isort tool provides stable sorting and grouping, as well as pruning
of unused imports.

Ruff is a modern linter, that is very fast due to being written in rust.
It can detect many common issues in a python codebase.

Removes the pylint dev requirement, since ruff replaces it.

* treewide: fix issues detected by ruff

* treewide: fix bare except clauses

* .devcontainer: Set up isort

* treewide: optimize imports

* treewide: apply black

* treewide: make regex patterns raw strings

This is necessary for escape sequences to be properly recognized.
This commit is contained in:
Martin Weinelt 2023-05-29 12:31:17 +02:00 committed by GitHub
parent 1e17dbaa91
commit ab50d0b006
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 346 additions and 459 deletions

View File

@ -52,7 +52,8 @@
"mikestead.dotenv",
"csstools.postcss",
"blanu.vscode-styled-jsx",
"bradlc.vscode-tailwindcss"
"bradlc.vscode-tailwindcss",
"ms-python.isort"
],
"settings": {
"remote.autoForwardPorts": false,
@ -68,6 +69,9 @@
"python.testing.unittestArgs": ["-v", "-s", "./frigate/test"],
"files.trimTrailingWhitespace": true,
"eslint.workingDirectories": ["./web"],
"isort.args": [
"--settings-path=./pyproject.toml"
],
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true

View File

@ -70,11 +70,17 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Install requirements
run: |
pip install pip
pip install -r requirements-dev.txt
- name: Lint
python3 -m pip install -U pip
python3 -m pip install -r requirements-dev.txt
- name: Check black
run: |
python3 -m black frigate --check
black --check --diff frigate migrations docker *.py
- name: Check isort
run: |
isort --check --diff frigate migrations docker *.py
- name: Check ruff
run: |
ruff check frigate migrations docker *.py
python_tests:
runs-on: ubuntu-latest

View File

@ -1,11 +1,11 @@
import os
from statistics import mean
import multiprocessing as mp
import numpy as np
import datetime
import multiprocessing as mp
from statistics import mean
import numpy as np
from frigate.config import DetectorTypeEnum
from frigate.object_detection import (
LocalObjectDetector,
ObjectDetectProcess,
RemoteObjectDetector,
load_labels,
@ -53,7 +53,7 @@ def start(id, num_detections, detection_queue, event):
frame_times = []
for x in range(0, num_detections):
start_frame = datetime.datetime.now().timestamp()
detections = object_detector.detect(my_frame)
object_detector.detect(my_frame)
frame_times.append(datetime.datetime.now().timestamp() - start_frame)
duration = datetime.datetime.now().timestamp() - start

View File

@ -3,11 +3,14 @@
import json
import os
import sys
import yaml
sys.path.insert(0, "/opt/frigate")
from frigate.const import BIRDSEYE_PIPE, BTBN_PATH
from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode
from frigate.const import BIRDSEYE_PIPE, BTBN_PATH # noqa: E402
from frigate.ffmpeg_presets import ( # noqa: E402
parse_preset_hardware_acceleration_encode,
)
sys.path.remove("/opt/frigate")

View File

@ -1,13 +1,14 @@
import faulthandler
from flask import cli
faulthandler.enable()
import threading
threading.current_thread().name = "frigate"
from flask import cli
from frigate.app import FrigateApp
faulthandler.enable()
threading.current_thread().name = "frigate"
cli.show_server_banner = lambda *x: None
if __name__ == "__main__":

View File

@ -1,16 +1,16 @@
import logging
import multiprocessing as mp
from multiprocessing.queues import Queue
from multiprocessing.synchronize import Event as MpEvent
import os
import shutil
import signal
import sys
from typing import Optional
from types import FrameType
import psutil
import traceback
from multiprocessing.queues import Queue
from multiprocessing.synchronize import Event as MpEvent
from types import FrameType
from typing import Optional
import psutil
from peewee_migrate import Router
from playhouse.sqlite_ext import SqliteExtDatabase
from playhouse.sqliteq import SqliteQueueDatabase
@ -27,13 +27,13 @@ from frigate.const import (
MODEL_CACHE_DIR,
RECORD_DIR,
)
from frigate.object_detection import ObjectDetectProcess
from frigate.events.cleanup import EventCleanup
from frigate.events.external import ExternalEventProcessor
from frigate.events.maintainer import EventProcessor
from frigate.http import create_app
from frigate.log import log_process, root_configurer
from frigate.models import Event, Recordings, Timeline
from frigate.object_detection import ObjectDetectProcess
from frigate.object_processing import TrackedObjectProcessor
from frigate.output import output_frames
from frigate.plus import PlusApi
@ -42,10 +42,10 @@ from frigate.record.record import manage_recordings
from frigate.stats import StatsEmitter, stats_init
from frigate.storage import StorageMaintainer
from frigate.timeline import TimelineProcessor
from frigate.types import CameraMetricsTypes, RecordMetricsTypes
from frigate.version import VERSION
from frigate.video import capture_camera, track_camera
from frigate.watchdog import FrigateWatchdog
from frigate.types import CameraMetricsTypes, RecordMetricsTypes
logger = logging.getLogger(__name__)
@ -133,10 +133,10 @@ class FrigateApp:
for log, level in self.config.logger.logs.items():
logging.getLogger(log).setLevel(level.value.upper())
if not "werkzeug" in self.config.logger.logs:
if "werkzeug" not in self.config.logger.logs:
logging.getLogger("werkzeug").setLevel("ERROR")
if not "ws4py" in self.config.logger.logs:
if "ws4py" not in self.config.logger.logs:
logging.getLogger("ws4py").setLevel("ERROR")
def init_queues(self) -> None:
@ -294,7 +294,7 @@ class FrigateApp:
def start_video_output_processor(self) -> None:
output_processor = mp.Process(
target=output_frames,
name=f"output_processor",
name="output_processor",
args=(
self.config,
self.video_output_queue,
@ -467,7 +467,7 @@ class FrigateApp:
self.stop()
def stop(self) -> None:
logger.info(f"Stopping...")
logger.info("Stopping...")
self.stop_event.set()
for detector in self.detectors.values():

View File

@ -1,17 +1,14 @@
"""Handle communication between Frigate and other applications."""
import logging
from abc import ABC, abstractmethod
from typing import Any, Callable
from abc import ABC, abstractmethod
from frigate.config import FrigateConfig
from frigate.ptz import OnvifController, OnvifCommandEnum
from frigate.ptz import OnvifCommandEnum, OnvifController
from frigate.types import CameraMetricsTypes, RecordMetricsTypes
from frigate.util import restart_frigate
logger = logging.getLogger(__name__)
@ -72,7 +69,7 @@ class Dispatcher:
camera_name = topic.split("/")[-3]
command = topic.split("/")[-2]
self._camera_settings_handlers[command](camera_name, payload)
except IndexError as e:
except IndexError:
logger.error(f"Received invalid set command: {topic}")
return
elif topic.endswith("ptz"):
@ -80,7 +77,7 @@ class Dispatcher:
# example /cam_name/ptz payload=MOVE_UP|MOVE_DOWN|STOP...
camera_name = topic.split("/")[-2]
self._on_ptz_command(camera_name, payload)
except IndexError as e:
except IndexError:
logger.error(f"Received invalid ptz command: {topic}")
return
elif topic == "restart":
@ -128,7 +125,7 @@ class Dispatcher:
elif payload == "OFF":
if self.camera_metrics[camera_name]["detection_enabled"].value:
logger.error(
f"Turning off motion is not allowed when detection is enabled."
"Turning off motion is not allowed when detection is enabled."
)
return
@ -196,7 +193,7 @@ class Dispatcher:
if payload == "ON":
if not self.config.cameras[camera_name].record.enabled_in_config:
logger.error(
f"Recordings must be enabled in the config to be turned on via MQTT."
"Recordings must be enabled in the config to be turned on via MQTT."
)
return

View File

@ -1,6 +1,5 @@
import logging
import threading
from typing import Any, Callable
import paho.mqtt.client as mqtt
@ -8,7 +7,6 @@ import paho.mqtt.client as mqtt
from frigate.comms.dispatcher import Communicator
from frigate.config import FrigateConfig
logger = logging.getLogger(__name__)
@ -177,10 +175,10 @@ class MqttClient(Communicator): # type: ignore[misc]
f"{self.mqtt_config.topic_prefix}/restart", self.on_mqtt_command
)
if not self.mqtt_config.tls_ca_certs is None:
if self.mqtt_config.tls_ca_certs is not None:
if (
not self.mqtt_config.tls_client_cert is None
and not self.mqtt_config.tls_client_key is None
self.mqtt_config.tls_client_cert is not None
and self.mqtt_config.tls_client_key is not None
):
self.client.tls_set(
self.mqtt_config.tls_ca_certs,
@ -189,9 +187,9 @@ class MqttClient(Communicator): # type: ignore[misc]
)
else:
self.client.tls_set(self.mqtt_config.tls_ca_certs)
if not self.mqtt_config.tls_insecure is None:
if self.mqtt_config.tls_insecure is not None:
self.client.tls_insecure_set(self.mqtt_config.tls_insecure)
if not self.mqtt_config.user is None:
if self.mqtt_config.user is not None:
self.client.username_pw_set(
self.mqtt_config.user, password=self.mqtt_config.password
)

View File

@ -3,10 +3,9 @@
import json
import logging
import threading
from typing import Callable
from wsgiref.simple_server import make_server
from ws4py.server.wsgirefserver import (
WebSocketWSGIHandler,
WebSocketWSGIRequestHandler,
@ -18,7 +17,6 @@ from ws4py.websocket import WebSocket
from frigate.comms.dispatcher import Communicator
from frigate.config import FrigateConfig
logger = logging.getLogger(__name__)
@ -45,7 +43,7 @@ class WebSocketClient(Communicator): # type: ignore[misc]
"topic": json_message.get("topic"),
"payload": json_message.get("payload"),
}
except Exception as e:
except Exception:
logger.warning(
f"Unable to parse websocket message as valid json: {message.data.decode('utf-8')}"
)
@ -82,7 +80,7 @@ class WebSocketClient(Communicator): # type: ignore[misc]
"payload": payload,
}
)
except Exception as e:
except Exception:
# if the payload can't be decoded don't relay to clients
logger.debug(f"payload for {topic} wasn't text. Skipping...")
return

View File

@ -8,26 +8,14 @@ from typing import Dict, List, Optional, Tuple, Union
import matplotlib.pyplot as plt
import numpy as np
import yaml
from pydantic import BaseModel, Extra, Field, validator, parse_obj_as
from pydantic import BaseModel, Extra, Field, parse_obj_as, validator
from pydantic.fields import PrivateAttr
from frigate.const import (
CACHE_DIR,
DEFAULT_DB_PATH,
REGEX_CAMERA_NAME,
YAML_EXT,
)
from frigate.const import CACHE_DIR, DEFAULT_DB_PATH, REGEX_CAMERA_NAME, YAML_EXT
from frigate.detectors import DetectorConfig, ModelConfig
from frigate.detectors.detector_config import InputTensorEnum # noqa: F401
from frigate.detectors.detector_config import PixelFormatEnum # noqa: F401
from frigate.detectors.detector_config import BaseDetectorConfig
from frigate.plus import PlusApi
from frigate.util import (
create_mask,
deep_merge,
get_ffmpeg_arg_list,
escape_special_characters,
load_config_with_no_duplicates,
load_labels,
)
from frigate.ffmpeg_presets import (
parse_preset_hardware_acceleration_decode,
parse_preset_hardware_acceleration_scale,
@ -35,14 +23,14 @@ from frigate.ffmpeg_presets import (
parse_preset_output_record,
parse_preset_output_rtmp,
)
from frigate.detectors import (
PixelFormatEnum,
InputTensorEnum,
ModelConfig,
DetectorConfig,
from frigate.plus import PlusApi
from frigate.util import (
create_mask,
deep_merge,
escape_special_characters,
get_ffmpeg_arg_list,
load_config_with_no_duplicates,
)
from frigate.version import VERSION
logger = logging.getLogger(__name__)
@ -487,7 +475,7 @@ class CameraFfmpegConfig(FfmpegConfig):
if len(roles) > len(roles_set):
raise ValueError("Each input role may only be used once.")
if not "detect" in roles:
if "detect" not in roles:
raise ValueError("The detect role is required.")
return v
@ -776,12 +764,12 @@ def verify_config_roles(camera_config: CameraConfig) -> None:
set([r for i in camera_config.ffmpeg.inputs for r in i.roles])
)
if camera_config.record.enabled and not "record" in assigned_roles:
if camera_config.record.enabled and "record" not in assigned_roles:
raise ValueError(
f"Camera {camera_config.name} has record enabled, but record is not assigned to an input."
)
if camera_config.rtmp.enabled and not "rtmp" in assigned_roles:
if camera_config.rtmp.enabled and "rtmp" not in assigned_roles:
raise ValueError(
f"Camera {camera_config.name} has rtmp enabled, but rtmp is not assigned to an input."
)
@ -1062,7 +1050,7 @@ class FrigateConfig(FrigateBaseModel):
config.model.dict(exclude_unset=True),
)
if not "path" in merged_model:
if "path" not in merged_model:
if detector_config.type == "cpu":
merged_model["path"] = "/cpu_model.tflite"
elif detector_config.type == "edgetpu":

View File

@ -13,9 +13,9 @@ BTBN_PATH = "/usr/lib/btbn-ffmpeg"
# Regex Consts
REGEX_CAMERA_NAME = "^[a-zA-Z0-9_-]+$"
REGEX_RTSP_CAMERA_USER_PASS = ":\/\/[a-zA-Z0-9_-]+:[\S]+@"
REGEX_HTTP_CAMERA_USER_PASS = "user=[a-zA-Z0-9_-]+&password=[\S]+"
REGEX_CAMERA_NAME = r"^[a-zA-Z0-9_-]+$"
REGEX_RTSP_CAMERA_USER_PASS = r":\/\/[a-zA-Z0-9_-]+:[\S]+@"
REGEX_HTTP_CAMERA_USER_PASS = r"user=[a-zA-Z0-9_-]+&password=[\S]+"
# Known Driver Names

View File

@ -1,13 +1,7 @@
import logging
from .detection_api import DetectionApi
from .detector_config import (
PixelFormatEnum,
InputTensorEnum,
ModelConfig,
)
from .detector_types import DetectorTypeEnum, api_types, DetectorConfig
from .detector_config import InputTensorEnum, ModelConfig, PixelFormatEnum # noqa: F401
from .detector_types import DetectorConfig, DetectorTypeEnum, api_types # noqa: F401
logger = logging.getLogger(__name__)

View File

@ -1,7 +1,6 @@
import logging
from abc import ABC, abstractmethod
logger = logging.getLogger(__name__)

View File

@ -1,20 +1,18 @@
import hashlib
import json
import logging
from enum import Enum
import os
from typing import Dict, List, Optional, Tuple, Union, Literal
from enum import Enum
from typing import Dict, Optional, Tuple
import requests
import matplotlib.pyplot as plt
from pydantic import BaseModel, Extra, Field, validator
import requests
from pydantic import BaseModel, Extra, Field
from pydantic.fields import PrivateAttr
from frigate.plus import PlusApi
from frigate.util import load_labels
logger = logging.getLogger(__name__)

View File

@ -1,16 +1,16 @@
import logging
import importlib
import logging
import pkgutil
from typing import Union
from typing_extensions import Annotated
from enum import Enum
from typing import Union
from pydantic import Field
from typing_extensions import Annotated
from . import plugins
from .detection_api import DetectionApi
from .detector_config import BaseDetectorConfig
logger = logging.getLogger(__name__)

View File

@ -1,10 +1,11 @@
import logging
import numpy as np
from pydantic import Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
from typing_extensions import Literal
from pydantic import Extra, Field
try:
from tflite_runtime.interpreter import Interpreter

View File

@ -1,14 +1,14 @@
import io
import logging
import numpy as np
import requests
import io
from PIL import Image
from pydantic import Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
from typing_extensions import Literal
from pydantic import Extra, Field
from PIL import Image
logger = logging.getLogger(__name__)
@ -64,11 +64,11 @@ class DeepStack(DetectionApi):
for i, detection in enumerate(response_json.get("predictions")):
logger.debug(f"Response: {detection}")
if detection["confidence"] < 0.4:
logger.debug(f"Break due to confidence < 0.4")
logger.debug("Break due to confidence < 0.4")
break
label = self.get_label_index(detection["label"])
if label < 0:
logger.debug(f"Break due to unknown label")
logger.debug("Break due to unknown label")
break
detections[i] = [
label,

View File

@ -1,10 +1,11 @@
import logging
import numpy as np
from pydantic import Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
from typing_extensions import Literal
from pydantic import Extra, Field
try:
from tflite_runtime.interpreter import Interpreter, load_delegate

View File

@ -1,12 +1,12 @@
import logging
import numpy as np
import openvino.runtime as ov
from pydantic import Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum
from typing_extensions import Literal
from pydantic import Extra, Field
logger = logging.getLogger(__name__)
@ -41,7 +41,7 @@ class OvDetector(DetectionApi):
tensor_shape = self.interpreter.output(self.output_indexes).shape
logger.info(f"Model Output-{self.output_indexes} Shape: {tensor_shape}")
self.output_indexes += 1
except:
except Exception:
logger.info(f"Model has {self.output_indexes} Output Tensors")
break
if self.ov_model_type == ModelTypeEnum.yolox:

View File

@ -1,6 +1,6 @@
import ctypes
import logging
import ctypes
import numpy as np
try:
@ -8,13 +8,14 @@ try:
from cuda import cuda
TRT_SUPPORT = True
except ModuleNotFoundError as e:
except ModuleNotFoundError:
TRT_SUPPORT = False
from pydantic import Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
from typing_extensions import Literal
from pydantic import Field
logger = logging.getLogger(__name__)
@ -172,7 +173,7 @@ class TensorRtDetector(DetectionApi):
if not self.context.execute_async_v2(
bindings=self.bindings, stream_handle=self.stream
):
logger.warn(f"Execute returned false")
logger.warn("Execute returned false")
# Transfer predictions back from the GPU.
[

View File

@ -4,17 +4,13 @@ import datetime
import logging
import os
import threading
from multiprocessing.synchronize import Event as MpEvent
from pathlib import Path
from peewee import fn
from frigate.config import FrigateConfig
from frigate.const import CLIPS_DIR
from frigate.models import Event
from multiprocessing.synchronize import Event as MpEvent
logger = logging.getLogger(__name__)
@ -45,9 +41,9 @@ class EventCleanup(threading.Thread):
)
# loop over object types in db
for l in distinct_labels:
for event in distinct_labels:
# get expiration time for this label
expire_days = retain_config.objects.get(l.label, retain_config.default)
expire_days = retain_config.objects.get(event.label, retain_config.default)
expire_after = (
datetime.datetime.now() - datetime.timedelta(days=expire_days)
).timestamp()
@ -55,8 +51,8 @@ class EventCleanup(threading.Thread):
expired_events = Event.select().where(
Event.camera.not_in(self.camera_keys),
Event.start_time < expire_after,
Event.label == l.label,
Event.retain_indefinitely == False,
Event.label == event.label,
Event.retain_indefinitely is False,
)
# delete the media from disk
for event in expired_events:
@ -75,8 +71,8 @@ class EventCleanup(threading.Thread):
update_query = Event.update(update_params).where(
Event.camera.not_in(self.camera_keys),
Event.start_time < expire_after,
Event.label == l.label,
Event.retain_indefinitely == False,
Event.label == event.label,
Event.retain_indefinitely is False,
)
update_query.execute()
@ -92,9 +88,11 @@ class EventCleanup(threading.Thread):
)
# loop over object types in db
for l in distinct_labels:
for event in distinct_labels:
# get expiration time for this label
expire_days = retain_config.objects.get(l.label, retain_config.default)
expire_days = retain_config.objects.get(
event.label, retain_config.default
)
expire_after = (
datetime.datetime.now() - datetime.timedelta(days=expire_days)
).timestamp()
@ -102,8 +100,8 @@ class EventCleanup(threading.Thread):
expired_events = Event.select().where(
Event.camera == name,
Event.start_time < expire_after,
Event.label == l.label,
Event.retain_indefinitely == False,
Event.label == event.label,
Event.retain_indefinitely is False,
)
# delete the grabbed clips from disk
for event in expired_events:
@ -121,8 +119,8 @@ class EventCleanup(threading.Thread):
update_query = Event.update(update_params).where(
Event.camera == name,
Event.start_time < expire_after,
Event.label == l.label,
Event.retain_indefinitely == False,
Event.label == event.label,
Event.retain_indefinitely is False,
)
update_query.execute()
@ -131,9 +129,9 @@ class EventCleanup(threading.Thread):
select id,
label,
camera,
has_snapshot,
has_clip,
row_number() over (
has_snapshot,
has_clip,
row_number() over (
partition by label, camera, round(start_time/5,0)*5
order by end_time-start_time desc
) as copy_number
@ -169,8 +167,8 @@ class EventCleanup(threading.Thread):
# drop events from db where has_clip and has_snapshot are false
delete_query = Event.delete().where(
Event.has_clip == False, Event.has_snapshot == False
Event.has_clip is False, Event.has_snapshot is False
)
delete_query.execute()
logger.info(f"Exiting event cleanup...")
logger.info("Exiting event cleanup...")

View File

@ -1,17 +1,15 @@
"""Handle external events created by the user."""
import base64
import cv2
import datetime
import glob
import logging
import os
import random
import string
from multiprocessing.queues import Queue
from typing import Optional
from multiprocessing.queues import Queue
import cv2
from frigate.config import CameraConfig, FrigateConfig
from frigate.const import CLIPS_DIR

View File

@ -2,20 +2,16 @@ import datetime
import logging
import queue
import threading
from enum import Enum
from peewee import fn
from multiprocessing.queues import Queue
from multiprocessing.synchronize import Event as MpEvent
from typing import Dict
from frigate.config import EventsConfig, FrigateConfig
from frigate.models import Event
from frigate.types import CameraMetricsTypes
from frigate.util import to_relative_box
from multiprocessing.queues import Queue
from multiprocessing.synchronize import Event as MpEvent
from typing import Dict
logger = logging.getLogger(__name__)
@ -65,7 +61,7 @@ class EventProcessor(threading.Thread):
def run(self) -> None:
# set an end_time on events without an end_time on startup
Event.update(end_time=Event.start_time + 30).where(
Event.end_time == None
Event.end_time is None
).execute()
while not self.stop_event.is_set():
@ -99,9 +95,9 @@ class EventProcessor(threading.Thread):
# set an end_time on events without an end_time before exiting
Event.update(end_time=datetime.datetime.now().timestamp()).where(
Event.end_time == None
Event.end_time is None
).execute()
logger.info(f"Exiting event processor...")
logger.info("Exiting event processor...")
def handle_object_detection(
self,

View File

@ -2,13 +2,11 @@
import logging
import os
from typing import Any
from frigate.version import VERSION
from frigate.const import BTBN_PATH
from frigate.util import vainfo_hwaccel
from frigate.version import VERSION
logger = logging.getLogger(__name__)

View File

@ -1,23 +1,20 @@
import base64
from datetime import datetime, timedelta, timezone
import copy
import logging
import glob
import json
import logging
import os
import subprocess as sp
import pytz
import time
import traceback
from datetime import datetime, timedelta, timezone
from functools import reduce
from pathlib import Path
from tzlocal import get_localzone_name
from urllib.parse import unquote
import cv2
import numpy as np
import pytz
from flask import (
Blueprint,
Flask,
@ -27,26 +24,26 @@ from flask import (
make_response,
request,
)
from peewee import SqliteDatabase, operator, fn, DoesNotExist
from peewee import DoesNotExist, SqliteDatabase, fn, operator
from playhouse.shortcuts import model_to_dict
from tzlocal import get_localzone_name
from frigate.config import FrigateConfig
from frigate.const import CLIPS_DIR, MAX_SEGMENT_DURATION, RECORD_DIR
from frigate.models import Event, Recordings, Timeline
from frigate.events.external import ExternalEventProcessor
from frigate.models import Event, Recordings, Timeline
from frigate.object_processing import TrackedObject
from frigate.plus import PlusApi
from frigate.ptz import OnvifController
from frigate.stats import stats_snapshot
from frigate.storage import StorageMaintainer
from frigate.util import (
clean_camera_user_pass,
ffprobe_stream,
get_tz_modifiers,
restart_frigate,
vainfo_hwaccel,
get_tz_modifiers,
)
from frigate.storage import StorageMaintainer
from frigate.version import VERSION
logger = logging.getLogger(__name__)
@ -105,10 +102,10 @@ def events_summary():
clauses = []
if not has_clip is None:
if has_clip is not None:
clauses.append((Event.has_clip == has_clip))
if not has_snapshot is None:
if has_snapshot is not None:
clauses.append((Event.has_snapshot == has_snapshot))
if len(clauses) == 0:
@ -253,7 +250,7 @@ def send_to_plus(id):
event.plus_id = plus_id
event.save()
if not include_annotation is None:
if include_annotation is not None:
box = event.data["box"]
try:
@ -296,12 +293,12 @@ def false_positive(id):
# events from before the conversion to relative dimensions cant include annotations
if event.data.get("box") is None:
message = f"Events prior to 0.13 cannot be submitted as false positives"
message = "Events prior to 0.13 cannot be submitted as false positives"
logger.error(message)
return make_response(jsonify({"success": False, "message": message}), 400)
if event.false_positive:
message = f"False positive already submitted to Frigate+"
message = "False positive already submitted to Frigate+"
logger.error(message)
return make_response(jsonify({"success": False, "message": message}), 400)
@ -437,7 +434,7 @@ def get_sub_labels():
parts = label.split(",")
for part in parts:
if not (part.strip()) in sub_labels:
if part.strip() not in sub_labels:
sub_labels.append(part.strip())
sub_labels.sort()
@ -476,7 +473,7 @@ def event_thumbnail(id, max_cache_age=2592000):
event_complete = False
try:
event = Event.get(Event.id == id)
if not event.end_time is None:
if event.end_time is not None:
event_complete = True
thumbnail_bytes = base64.b64decode(event.thumbnail)
except DoesNotExist:
@ -486,9 +483,9 @@ def event_thumbnail(id, max_cache_age=2592000):
for camera_state in camera_states:
if id in camera_state.tracked_objects:
tracked_obj = camera_state.tracked_objects.get(id)
if not tracked_obj is None:
if tracked_obj is not None:
thumbnail_bytes = tracked_obj.get_thumbnail()
except:
except Exception:
return "Event not found", 404
if thumbnail_bytes is None:
@ -593,7 +590,7 @@ def event_snapshot(id):
event_complete = False
jpg_bytes = None
try:
event = Event.get(Event.id == id, Event.end_time != None)
event = Event.get(Event.id == id, Event.end_time is not None)
event_complete = True
if not event.has_snapshot:
return "Snapshot not available", 404
@ -609,7 +606,7 @@ def event_snapshot(id):
for camera_state in camera_states:
if id in camera_state.tracked_objects:
tracked_obj = camera_state.tracked_objects.get(id)
if not tracked_obj is None:
if tracked_obj is not None:
jpg_bytes = tracked_obj.get_jpg_bytes(
timestamp=request.args.get("timestamp", type=int),
bounding_box=request.args.get("bbox", type=int),
@ -617,9 +614,9 @@ def event_snapshot(id):
height=request.args.get("h", type=int),
quality=request.args.get("quality", default=70, type=int),
)
except:
except Exception:
return "Event not found", 404
except:
except Exception:
return "Event not found", 404
if jpg_bytes is None:
@ -645,7 +642,7 @@ def label_snapshot(camera_name, label):
event_query = (
Event.select()
.where(Event.camera == camera_name)
.where(Event.has_snapshot == True)
.where(Event.has_snapshot is True)
.order_by(Event.start_time.desc())
)
else:
@ -653,7 +650,7 @@ def label_snapshot(camera_name, label):
Event.select()
.where(Event.camera == camera_name)
.where(Event.label == label)
.where(Event.has_snapshot == True)
.where(Event.has_snapshot is True)
.order_by(Event.start_time.desc())
)
@ -820,13 +817,13 @@ def events():
if before:
clauses.append((Event.start_time < before))
if not has_clip is None:
if has_clip is not None:
clauses.append((Event.has_clip == has_clip))
if not has_snapshot is None:
if has_snapshot is not None:
clauses.append((Event.has_snapshot == has_snapshot))
if not in_progress is None:
if in_progress is not None:
clauses.append((Event.end_time.is_null(in_progress)))
if not include_thumbnails:
@ -894,12 +891,12 @@ def create_event(camera_name, label):
def end_event(event_id):
try:
current_app.external_processor.finish_manual_event(event_id)
except:
except Exception:
return jsonify(
{"success": False, "message": f"{event_id} must be set and valid."}, 404
)
return jsonify({"success": True, "message": f"Event successfully ended."}, 200)
return jsonify({"success": True, "message": "Event successfully ended."}, 200)
@bp.route("/config")
@ -959,9 +956,8 @@ def config_save():
# Validate the config schema
try:
new_yaml = FrigateConfig.parse_raw(new_config)
check_runtime = new_yaml.runtime_config
except Exception as e:
FrigateConfig.parse_raw(new_config)
except Exception:
return make_response(
jsonify(
{
@ -985,12 +981,12 @@ def config_save():
with open(config_file, "w") as f:
f.write(new_config)
f.close()
except Exception as e:
except Exception:
return make_response(
jsonify(
{
"success": False,
"message": f"Could not write config file, be sure that Frigate has write permission on the config file.",
"message": "Could not write config file, be sure that Frigate has write permission on the config file.",
}
),
400,
@ -1531,7 +1527,7 @@ def ffprobe():
if not path_param:
return jsonify(
{"success": False, "message": f"Path needs to be provided."}, "404"
{"success": False, "message": "Path needs to be provided."}, "404"
)
if path_param.startswith("camera"):

View File

@ -1,18 +1,17 @@
# adapted from https://medium.com/@jonathonbao/python3-logging-with-multiprocessing-f51f460b8778
import logging
import threading
import os
import signal
import queue
import multiprocessing as mp
from multiprocessing.queues import Queue
from logging import handlers
from typing import Optional
from types import FrameType
from setproctitle import setproctitle
from typing import Deque, Optional
from types import FrameType
import os
import queue
import signal
import threading
from collections import deque
from logging import handlers
from multiprocessing.queues import Queue
from types import FrameType
from typing import Deque, Optional
from setproctitle import setproctitle
from frigate.util import clean_camera_user_pass
@ -44,7 +43,7 @@ def root_configurer(queue: Queue) -> None:
def log_process(log_queue: Queue) -> None:
threading.current_thread().name = f"logger"
threading.current_thread().name = "logger"
setproctitle("frigate.logger")
listener_configurer()

View File

@ -1,12 +1,11 @@
from numpy import unique
from peewee import (
Model,
BooleanField,
CharField,
DateTimeField,
FloatField,
BooleanField,
TextField,
IntegerField,
Model,
TextField,
)
from playhouse.sqlite_ext import JSONField

View File

@ -1,6 +1,7 @@
import cv2
import imutils
import numpy as np
from frigate.config import MotionConfig

View File

@ -12,7 +12,6 @@ from setproctitle import setproctitle
from frigate.config import InputTensorEnum
from frigate.detectors import create_detector
from frigate.util import EventsPerSecond, SharedMemoryFrameManager, listen, load_labels
logger = logging.getLogger(__name__)
@ -161,7 +160,7 @@ class ObjectDetectProcess:
def start_or_restart(self):
self.detection_start.value = 0.0
if (not self.detect_process is None) and self.detect_process.is_alive():
if (self.detect_process is not None) and self.detect_process.is_alive():
self.stop()
self.detect_process = mp.Process(
target=run_detector,

View File

@ -15,10 +15,10 @@ import numpy as np
from frigate.comms.dispatcher import Dispatcher
from frigate.config import (
CameraConfig,
MqttConfig,
SnapshotsConfig,
RecordConfig,
FrigateConfig,
MqttConfig,
RecordConfig,
SnapshotsConfig,
)
from frigate.const import CLIPS_DIR
from frigate.events.maintainer import EventTypeEnum
@ -141,7 +141,7 @@ class TrackedObject:
# check each zone
for name, zone in self.camera_config.zones.items():
# if the zone is not for this object type, skip
if len(zone.objects) > 0 and not obj_data["label"] in zone.objects:
if len</