Skip to content

Commit

Permalink
refactor: use internal self._api inside the object (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Jun 11, 2024
1 parent 8deb6d1 commit c20e7a9
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 105 deletions.
2 changes: 1 addition & 1 deletion src/uiprotect/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,7 @@ async def get_devices(
objs: list[ProtectModel] = []

for obj_dict in await self.get_devices_raw(model_type):
obj = create_from_unifi_dict(obj_dict)
obj = create_from_unifi_dict(obj_dict, api=self)

if expected_type is not None and not isinstance(obj, expected_type):
raise NvrError(f"Unexpected model returned: {obj.model}")
Expand Down
39 changes: 22 additions & 17 deletions src/uiprotect/data/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class ProtectBaseObject(BaseModel):
* Provides `.unifi_dict` to convert object back into UFP JSON
"""

_api: ProtectApiClient | None = PrivateAttr(None)
_api: ProtectApiClient = PrivateAttr(...)

_protect_objs: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
_protect_lists: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
Expand All @@ -103,7 +103,8 @@ def __init__(self, api: ProtectApiClient | None = None, **data: Any) -> None:
Use the static method `.from_unifi_dict()` to create objects from UFP JSON data from then the main class constructor.
"""
super().__init__(**data)
self._api = api
if api is not None:
self._api = api

@classmethod
def from_unifi_dict(
Expand All @@ -125,7 +126,8 @@ def from_unifi_dict(
(cameras, users, etc.)
"""
data["api"] = api
if api is not None:
data["api"] = api
data = cls.unifi_dict_to_dict(data)

if is_debug():
Expand Down Expand Up @@ -161,7 +163,8 @@ def construct(cls, _fields_set: set[str] | None = None, **values: Any) -> Self:
}

obj = super().construct(_fields_set=_fields_set, **values)
obj._api = api
if api is not None:
obj._api = api

return obj

Expand Down Expand Up @@ -756,7 +759,9 @@ async def _save_device_changes(
if self.model is None:
raise BadRequest("Unknown model type")

if not self.api.bootstrap.auth_user.can(self.model, PermissionNode.WRITE, self):
if not self._api.bootstrap.auth_user.can(
self.model, PermissionNode.WRITE, self
):
if revert_on_fail:
self.revert_changes(data_before_changes)
raise NotAuthorized(f"Do not have write permission for obj: {self.id}")
Expand Down Expand Up @@ -811,11 +816,11 @@ async def emit_message(self, updated: dict[str, Any]) -> None:
data_frame.header = header
data_frame.data = updated

message = self.api.bootstrap.process_ws_packet(
message = self._api.bootstrap.process_ws_packet(
WSPacket(action_frame.packed + data_frame.packed),
)
if message is not None:
self.api.emit_message(message)
self._api.emit_message(message)


class ProtectDeviceModel(ProtectModelWithId):
Expand Down Expand Up @@ -977,7 +982,7 @@ def _get_unifi_remaps(cls) -> dict[str, str]:

async def _api_update(self, data: dict[str, Any]) -> None:
if self.model is not None:
return await self.api.update_device(self.model, self.id, data)
return await self._api.update_device(self.model, self.id, data)
return None

def unifi_dict(
Expand Down Expand Up @@ -1026,12 +1031,12 @@ def bridge(self) -> Bridge | None:
if self.bridge_id is None:
return None

return self.api.bootstrap.bridges[self.bridge_id]
return self._api.bootstrap.bridges[self.bridge_id]

@property
def protect_url(self) -> str:
"""UFP Web app URL for this device"""
return f"{self.api.base_url}/protect/devices/{self.id}"
return f"{self._api.base_url}/protect/devices/{self.id}"

@property
def is_adopted_by_us(self) -> bool:
Expand All @@ -1053,38 +1058,38 @@ def callback() -> None:
async def reboot(self) -> None:
"""Reboots an adopted device"""
if self.model is not None:
if not self.api.bootstrap.auth_user.can(
if not self._api.bootstrap.auth_user.can(
self.model,
PermissionNode.WRITE,
self,
):
raise NotAuthorized("Do not have permission to reboot device")
await self.api.reboot_device(self.model, self.id)
await self._api.reboot_device(self.model, self.id)

async def unadopt(self) -> None:
"""Unadopt/Unmanage adopted device"""
if not self.is_adopted_by_us:
raise BadRequest("Device is not adopted")

if self.model is not None:
if not self.api.bootstrap.auth_user.can(
if not self._api.bootstrap.auth_user.can(
self.model,
PermissionNode.DELETE,
self,
):
raise NotAuthorized("Do not have permission to unadopt devices")
await self.api.unadopt_device(self.model, self.id)
await self._api.unadopt_device(self.model, self.id)

async def adopt(self, name: str | None = None) -> None:
"""Adopts a device"""
if not self.can_adopt:
raise BadRequest("Device cannot be adopted")

if self.model is not None:
if not self.api.bootstrap.auth_user.can(self.model, PermissionNode.CREATE):
if not self._api.bootstrap.auth_user.can(self.model, PermissionNode.CREATE):
raise NotAuthorized("Do not have permission to adopt devices")

await self.api.adopt_device(self.model, self.id)
await self._api.adopt_device(self.model, self.id)
if name is not None:
await self.set_name(name)

Expand Down Expand Up @@ -1118,4 +1123,4 @@ def last_motion_event(self) -> Event | None:
if self.last_motion_event_id is None:
return None

return self.api.bootstrap.events.get(self.last_motion_event_id)
return self._api.bootstrap.events.get(self.last_motion_event_id)
8 changes: 4 additions & 4 deletions src/uiprotect/data/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def clear_ws_stats(self) -> None:

@property
def auth_user(self) -> User:
user: User = self.api.bootstrap.users[self.auth_user_id]
user: User = self._api.bootstrap.users[self.auth_user_id]
return user

@property
Expand Down Expand Up @@ -388,7 +388,7 @@ def _process_add_packet(
and obj.model.value in ModelType.bootstrap_models_set()
):
key = f"{obj.model.value}s"
if not self.api.ignore_unadopted or (
if not self._api.ignore_unadopted or (
obj.is_adopted and not obj.is_adopted_by_other
):
getattr(self, key)[obj.id] = obj
Expand Down Expand Up @@ -612,9 +612,9 @@ async def refresh_device(self, model_type: ModelType, device_id: str) -> None:
"""Refresh a device in the bootstrap."""
try:
if model_type == ModelType.NVR:
device: ProtectModelWithId = await self.api.get_nvr()
device: ProtectModelWithId = await self._api.get_nvr()
else:
device = await self.api.get_device(model_type, device_id)
device = await self._api.get_device(model_type, device_id)
except (
ValidationError,
TimeoutError,
Expand Down
Loading

0 comments on commit c20e7a9

Please sign in to comment.