@camera.ui/server 2.0.3 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interface/assets/{404-4kT4tezJ.js → 404-DRRPa9Hr.js} +1 -1
- package/dist/interface/assets/About-Db5MifHo.js +1 -0
- package/dist/interface/assets/{Adminpanel-B38Z5X54.js → Adminpanel-ByDZ8Xpn.js} +1 -1
- package/dist/interface/assets/{Automation-BbX3-xf_.js → Automation-BqJ8PyPa.js} +2 -2
- package/dist/interface/assets/{AutomationImport-D5Ov1XoG.js → AutomationImport-BvuLSZcZ.js} +2 -2
- package/dist/interface/assets/{AutomationStore-CVQpLFae.js → AutomationStore-Ca07W8uH.js} +2 -2
- package/dist/interface/assets/{AutomationStoreDetail-NNXJ16cM.js → AutomationStoreDetail-DmFvT2az.js} +2 -2
- package/dist/interface/assets/{Automations-w8GvcQRP.js → Automations-Dr8K-cDz.js} +2 -2
- package/dist/interface/assets/{Camera-Bx-Fc8Rk.js → Camera-Bu1U8Oal.js} +2 -2
- package/dist/interface/assets/{CameraConsole-Br1Ot4HR.js → CameraConsole-BcvP76iJ.js} +1 -1
- package/dist/interface/assets/{Cameras-C-NQYdbQ.js → Cameras-Dwr5fbzg.js} +2 -2
- package/dist/interface/assets/{Camview-DWgaBueW.js → Camview-F0vVBWeZ.js} +1 -1
- package/dist/interface/assets/Config-CIAVylkc.js +2 -0
- package/dist/interface/assets/{ConfigActionCameraControl-Cvjyd2Rq.js → ConfigActionCameraControl-C1dsQnYF.js} +1 -1
- package/dist/interface/assets/{ConfigActionDelay-Rnxk--Qt.js → ConfigActionDelay-DTjjadCG.js} +1 -1
- package/dist/interface/assets/{ConfigActionHttp-BF8vrrHR.js → ConfigActionHttp-IFqZaHDZ.js} +1 -1
- package/dist/interface/assets/{ConfigActionImageInput-C8_H3ubM.js → ConfigActionImageInput-DY8RQJ2h.js} +1 -1
- package/dist/interface/assets/{ConfigActionNotification-T35A9o6f.js → ConfigActionNotification-CJL8uNR-.js} +1 -1
- package/dist/interface/assets/{ConfigActionOutput-CxB3eLLl.js → ConfigActionOutput-Butmz0jI.js} +1 -1
- package/dist/interface/assets/{ConfigActionPlugin-BHdyn9Te.js → ConfigActionPlugin-D5oE8oXm.js} +1 -1
- package/dist/interface/assets/{ConfigActionSensor-CMrg6h2b.js → ConfigActionSensor-CJ-mk6eS.js} +1 -1
- package/dist/interface/assets/{ConfigActionSnapshot-Dz6LdZsA.js → ConfigActionSnapshot-DCCiYu-s.js} +1 -1
- package/dist/interface/assets/{ConfigActionVariable-DIlUMHDy.js → ConfigActionVariable-F28sicqK.js} +1 -1
- package/dist/interface/assets/{ConfigConditionIfElse-0XRDQcTw.js → ConfigConditionIfElse-BJhRgP7t.js} +1 -1
- package/dist/interface/assets/{ConfigConditionSensorState-BzFQHkML.js → ConfigConditionSensorState-B6MdgPfo.js} +1 -1
- package/dist/interface/assets/{ConfigConditionSwitch-C7pp1EZI.js → ConfigConditionSwitch-BKToCaFK.js} +1 -1
- package/dist/interface/assets/{ConfigConditionTime-B0zctDc4.js → ConfigConditionTime-ChXeDbZB.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerDetection-DOS-gNhG.js → ConfigTriggerDetection-BWd3QqYf.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerGeofence-YggfZUFH.js → ConfigTriggerGeofence-BoT9t-8V.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerManual-BpBTh3CS.js → ConfigTriggerManual-Bt62nmi8.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerSchedule-DZG10NcA.js → ConfigTriggerSchedule-oBDIqAMo.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerSensor-Cu657NGX.js → ConfigTriggerSensor-BlTHlstZ.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerSystem-BfIHn9AZ.js → ConfigTriggerSystem--nEg_iQ0.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerWebhook-BKPOGAs3.js → ConfigTriggerWebhook-83rLUOjQ.js} +1 -1
- package/dist/interface/assets/{Console-C6A7MqYh.js → Console-2sHljg8h.js} +1 -1
- package/dist/interface/assets/{CuiActionButton-BSy6VaJ6.js → CuiActionButton-CNjL01gn.js} +1 -1
- package/dist/interface/assets/{CuiAvatar-BwAVgBUB.js → CuiAvatar-BDT9c-UI.js} +1 -1
- package/dist/interface/assets/{CuiBBoxPlayground-BUPzZ0sI.js → CuiBBoxPlayground-CMnBcPwI.js} +1 -1
- package/dist/interface/assets/CuiBottomSheet-WuxFsOrw.js +1 -0
- package/dist/interface/assets/{CuiBottomSheet-CxYeW_sq.js → CuiBottomSheet-h5sjwTf4.js} +1 -1
- package/dist/interface/assets/{CuiCameraCard-Ci09TTwg.js → CuiCameraCard-Bip9OIZO.js} +1 -1
- package/dist/interface/assets/{CuiCameraPipCard-fYyJQ9DL.js → CuiCameraPipCard-DElQvAB0.js} +1 -1
- package/dist/interface/assets/{CuiCameraRecordings-75jdIwEG.js → CuiCameraRecordings-Bf5IG7OM.js} +1 -1
- package/dist/interface/assets/{CuiCameraShares-C2HDYSGy.js → CuiCameraShares-Cw-Mffg8.js} +1 -1
- package/dist/interface/assets/{CuiCameraSnapshot-Cz8aYjoo.js → CuiCameraSnapshot-BS-_U34M.js} +1 -1
- package/dist/interface/assets/{CuiCameraTable-DrIhSgmU.js → CuiCameraTable-DY_unr4m.js} +1 -1
- package/dist/interface/assets/{CuiDataTable-DhnQRMXG.js → CuiDataTable-C5qi7zpz.js} +1 -1
- package/dist/interface/assets/{CuiFloatingButton-DRKyDsPh.js → CuiFloatingButton-Pmur2pAJ.js} +1 -1
- package/dist/interface/assets/{CuiImage-i_fTDsHd.js → CuiImage-DVoYtgtl.js} +1 -1
- package/dist/interface/assets/{CuiMenu-DSTlEsg9.js → CuiMenu-B7AhQbgB.js} +1 -1
- package/dist/interface/assets/{CuiPluginCard-XmOOko_4.js → CuiPluginCard-B5PhaGoF.js} +2 -2
- package/dist/interface/assets/{CuiPluginCategoryChip-BwL2qCTM.js → CuiPluginCategoryChip-nEwIiKiK.js} +1 -1
- package/dist/interface/assets/{CuiPluginOAuthButton-CmW7OY0L.js → CuiPluginOAuthButton-CJGsl-89.js} +2 -2
- package/dist/interface/assets/{CuiPluginTrustBadge-KcOasEJH.js → CuiPluginTrustBadge-DExKttfC.js} +1 -1
- package/dist/interface/assets/{CuiQRCode-DgaxwrkH.js → CuiQRCode-DkRZ5hfS.js} +1 -1
- package/dist/interface/assets/{CuiRecordingsGrid-BxoJSn6Z.js → CuiRecordingsGrid-mFXSsuG8.js} +1 -1
- package/dist/interface/assets/{CuiSchema-BDrsTIqf.js → CuiSchema-BSv1nUun.js} +1 -1
- package/dist/interface/assets/{CuiTopNavbarItem-DVwItfbG.js → CuiTopNavbarItem-w21c3xtQ.js} +1 -1
- package/dist/interface/assets/{CuiTopbarSlot-BT6XOANB.js → CuiTopbarSlot-CYPUqVPx.js} +1 -1
- package/dist/interface/assets/{Faces-DvYCASPC.js → Faces-DLpVsIkY.js} +1 -1
- package/dist/interface/assets/{FirstSteps-DAsmDJJE.js → FirstSteps-BDDy9x_6.js} +1 -1
- package/dist/interface/assets/{Instances-D4fzQrI3.js → Instances-FeIAnJix.js} +1 -1
- package/dist/interface/assets/{Logs-DYXtlueg.js → Logs-CIUyuGwj.js} +1 -1
- package/dist/interface/assets/{Menu-BcBthWK9.js → Menu-Gqs2UiSW.js} +1 -1
- package/dist/interface/assets/{OAuthDeviceFlow-C70vC26b.js → OAuthDeviceFlow-hNJ_UrdG.js} +1 -1
- package/dist/interface/assets/{Plugin-Ek8CJHb3.js → Plugin-BKItJas0.js} +1 -1
- package/dist/interface/assets/{PluginConsole-n1wMznj9.js → PluginConsole-Bwd5Mktk.js} +1 -1
- package/dist/interface/assets/PluginDetail-BBh5y9qU.js +2 -0
- package/dist/interface/assets/{PluginSchema-DDpK-w_q.js → PluginSchema-D92qcqf9.js} +1 -1
- package/dist/interface/assets/PluginSearch-BN3U3NY6.js +2 -0
- package/dist/interface/assets/PluginSearch-nHAFKMX0.js +1 -0
- package/dist/interface/assets/Plugins-gxyxkQ5i.js +1 -0
- package/dist/interface/assets/Recordings-B3Xw23vh.js +1 -0
- package/dist/interface/assets/{Settings-DqA1TU3I.js → Settings-D2LHMohy2.js} +1 -1
- package/dist/interface/assets/SettingsAccount-DUN1oTTn.js +1 -0
- package/dist/interface/assets/{SettingsAccount-BEVxkPFS.js → SettingsAccount-b4eVxI3M.js} +1 -1
- package/dist/interface/assets/{SettingsAppearance-B9KzFCdx.js → SettingsAppearance--Eidr-fz.js} +1 -1
- package/dist/interface/assets/SettingsAppearance-CLVMmnR_.js +1 -0
- package/dist/interface/assets/{SettingsBackup-j_z4sOId.js → SettingsBackup-DUYVdKjD.js} +1 -1
- package/dist/interface/assets/{SettingsNotifications-D2WgP9Pd.js → SettingsNotifications-xYOuLZsr.js} +1 -1
- package/dist/interface/assets/SettingsRecordings-BQDf4Zeg.js +1 -0
- package/dist/interface/assets/{SettingsRemote-C7wTY9EH.js → SettingsRemote-BXr1HLHm.js} +1 -1
- package/dist/interface/assets/SettingsSystem-DAjNwp4I.js +2 -0
- package/dist/interface/assets/{SettingsUsers-CdVrMc0h.js → SettingsUsers-DJ-eMMWe.js} +1 -1
- package/dist/interface/assets/{Terminal-pyMSi5jh.js → Terminal-P3yVGG8s.js} +1 -1
- package/dist/interface/assets/{VariableInput-DmE1m9Il.js → VariableInput-DdVw4SIR.js} +1 -1
- package/dist/interface/assets/{VariableSuggestions-eII-1Bd_.js → VariableSuggestions-SJPd5c8d.js} +1 -1
- package/dist/interface/assets/VersionsHandler-DcZ3RtHV.js +7 -0
- package/dist/interface/assets/{Workers-KL_fb-Ki.js → Workers-DWSJsRko.js} +1 -1
- package/dist/interface/assets/api-CKqAhmSC.css +2 -0
- package/dist/interface/assets/{api-DVDZCfaM.js → api-Cv3vt1pa.js} +1 -1
- package/dist/interface/assets/api-Ex2VUVD1.js +2 -0
- package/dist/interface/assets/{auth-pmpjgGBQ.js → auth-W-JA6GOD.js} +1 -1
- package/dist/interface/assets/{automations-xpnVYpRH.js → automations-d_B5L3sO.js} +1 -1
- package/dist/interface/assets/{automations-73X55Wxy.js → automations-irBgx9Ew.js} +1 -1
- package/dist/interface/assets/{backup-G0wpvhtl.js → backup-BT-P0duG.js} +1 -1
- package/dist/interface/assets/{cameras-CURX5SWn.js → cameras-DxjpuzW1.js} +1 -1
- package/dist/interface/assets/{cameras.schema-UcmqaqCT.js → cameras.schema-7ex1wBck.js} +1 -1
- package/dist/interface/assets/cloudHandoff-Cu1sRatW.js +1 -0
- package/dist/interface/assets/config-DwlSsbcP.js +1 -0
- package/dist/interface/assets/{deviceId-DRtZsFhF.js → deviceId-I24oaPe6.js} +1 -1
- package/dist/interface/assets/{hasPermission-DKf8cjsF.js → hasPermission-Cz0dkfyp.js} +1 -1
- package/dist/interface/assets/{instances-DvkGEhQ9.js → instances-D6wHW9_0.js} +1 -1
- package/dist/interface/assets/{main-D8ZyVvgT.css → main-BjuXWRyJ.css} +1 -1
- package/dist/interface/assets/main-C-WCGnJh.js +3 -0
- package/dist/interface/assets/{notifications-CThoWQfW.js → notifications-DLNUbEKC.js} +1 -1
- package/dist/interface/assets/{plugins-DN9592Gw.js → plugins-D-tGC0mr.js} +1 -1
- package/dist/interface/assets/{round-restart-alt-C6cWOig8.js → round-restart-alt-CaOjUTav.js} +1 -1
- package/dist/interface/assets/router-Cbt2STjH.js +2 -0
- package/dist/interface/assets/{routerState-DxipV4mY.js → routerState-_BXrxePY.js} +1 -1
- package/dist/interface/assets/{server-BaJ0ampx.js → server-ACfR-bOw.js} +1 -1
- package/dist/interface/assets/{shares-B6eaflmY.js → shares-Ut3rTZUx.js} +1 -1
- package/dist/interface/assets/{theme-Dbkvi1e_.js → theme-CDU91XW5.js} +1 -1
- package/dist/interface/assets/{types-CAW47AJe.js → types-Blh_1COV.js} +1 -1
- package/dist/interface/assets/ui-SZnjYe2F.js +1 -0
- package/dist/interface/assets/useAppVersion-Bo_n0OVQ.js +1 -0
- package/dist/interface/assets/{useBiometricCredentials-BJheacnv.js → useBiometricCredentials-XyEQbPBo.js} +1 -1
- package/dist/interface/assets/{useCameraOptions-r_TT2WJk.js → useCameraOptions-C3-ZVV2A.js} +1 -1
- package/dist/interface/assets/{useCuiCameraDrawer-DwlhaZ2i.js → useCuiCameraDrawer-CebQFNWX.js} +1 -1
- package/dist/interface/assets/useCuiDialog-ClphnG79.js +2 -0
- package/dist/interface/assets/{useFileDownload-BE32i7R1.js → useFileDownload-CdDprX3v.js} +1 -1
- package/dist/interface/assets/{useLogsSocket-CLSJzN6z.js → useLogsSocket-DKU0kKe_.js} +1 -1
- package/dist/interface/assets/{useServerRestart-DCJcb-IB.js → useServerRestart-CgCmTap7.js} +1 -1
- package/dist/interface/assets/{useSharedComposables-CWxbvFAw.js → useSharedComposables-BcUR_c17.js} +1 -1
- package/dist/interface/assets/{useStreamStatus-DH9KQ7aE.js → useStreamStatus-BTa-XXZJ.js} +1 -1
- package/dist/interface/assets/useUpdateChannel-WznJBL9L.js +1 -0
- package/dist/interface/assets/{useUserOptions-GzbPgMnC.js → useUserOptions-DffxmIf7.js} +1 -1
- package/dist/interface/assets/{users.schema-DKf9LQAY.js → users.schema-BcwArBbH.js} +1 -1
- package/dist/interface/assets/{vendor-cameraui-DhctzD3V.js → vendor-cameraui-zHth8Pa5.js} +2 -2
- package/dist/interface/assets/{vendor-chart-BjXPY6za.js → vendor-chart-CTk1N5fJ.js} +1 -1
- package/dist/interface/assets/{vendor-core-DnC_SdtD.js → vendor-core-_UeC1YMQ.js} +1 -1
- package/dist/interface/assets/{vendor-primevue-OV61z06m.js → vendor-primevue-BXMgwPEu.js} +1 -1
- package/dist/interface/assets/{view-grid-Y-11W6nc.js → view-grid-CX0RwdlE.js} +1 -1
- package/dist/interface/index.html +45 -44
- package/dist/interface/sw.js +1 -1
- package/dist/server/package.json +26 -16
- package/dist/server/requirements.txt +3 -2
- package/dist/server/src/_camera_ui_tools/camera_ui_common/common_utils/signal_handler.py +17 -9
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/detection.py +10 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/event_emitter.py +45 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/storage/__init__.py +47 -12
- package/dist/server/src/api/controllers/plugins.controller.js +11 -3
- package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
- package/dist/server/src/api/schemas/cameras.schema.d.ts +27 -0
- package/dist/server/src/api/schemas/cameras.schema.js +6 -0
- package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
- package/dist/server/src/api/schemas/config.schema.d.ts +2 -0
- package/dist/server/src/api/schemas/config.schema.js +1 -0
- package/dist/server/src/api/schemas/config.schema.js.map +1 -1
- package/dist/server/src/api/services/plugins.service.js +1 -1
- package/dist/server/src/api/services/plugins.service.js.map +1 -1
- package/dist/server/src/api/types/index.d.ts +1 -1
- package/dist/server/src/api.d.ts +1 -0
- package/dist/server/src/api.js +11 -3
- package/dist/server/src/api.js.map +1 -1
- package/dist/server/src/camera/decoder/ptz-autotracker.js +51 -78
- package/dist/server/src/camera/decoder/ptz-autotracker.js.map +1 -1
- package/dist/server/src/go2rtc/api/routes/streams.js +5 -6
- package/dist/server/src/go2rtc/api/routes/streams.js.map +1 -1
- package/dist/server/src/go2rtc/index.js +1 -0
- package/dist/server/src/go2rtc/index.js.map +1 -1
- package/dist/server/src/go2rtc/types.d.ts +3 -0
- package/dist/server/src/go2rtc/types.js.map +1 -1
- package/dist/server/src/main.js +1 -1
- package/dist/server/src/main.js.map +1 -1
- package/dist/server/src/manager/deviceManager.js +4 -1
- package/dist/server/src/manager/deviceManager.js.map +1 -1
- package/dist/server/src/manager/discoveryManager.d.ts +3 -2
- package/dist/server/src/manager/discoveryManager.js +58 -29
- package/dist/server/src/manager/discoveryManager.js.map +1 -1
- package/dist/server/src/plugins/config-store.d.ts +1 -1
- package/dist/server/src/plugins/config-store.js +17 -10
- package/dist/server/src/plugins/config-store.js.map +1 -1
- package/dist/server/src/plugins/index.d.ts +1 -0
- package/dist/server/src/plugins/index.js +38 -2
- package/dist/server/src/plugins/index.js.map +1 -1
- package/dist/server/src/plugins/runtime/base.js +10 -5
- package/dist/server/src/plugins/runtime/base.js.map +1 -1
- package/dist/server/src/plugins/runtime/go/index.js +1 -0
- package/dist/server/src/plugins/runtime/go/index.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/child.d.ts +1 -0
- package/dist/server/src/plugins/runtime/node/child.js +62 -19
- package/dist/server/src/plugins/runtime/node/child.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/configDb.d.ts +8 -0
- package/dist/server/src/plugins/runtime/node/configDb.js +15 -0
- package/dist/server/src/plugins/runtime/node/configDb.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/pluginApi.d.ts +4 -0
- package/dist/server/src/plugins/runtime/node/pluginApi.js +13 -5
- package/dist/server/src/plugins/runtime/node/pluginApi.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/cameraDevice.d.ts +1 -2
- package/dist/server/src/plugins/runtime/node/proxy/cameraDevice.js +2 -8
- package/dist/server/src/plugins/runtime/node/proxy/cameraDevice.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/coreManager.d.ts +3 -2
- package/dist/server/src/plugins/runtime/node/proxy/coreManager.js +9 -13
- package/dist/server/src/plugins/runtime/node/proxy/coreManager.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/deviceManager.d.ts +3 -2
- package/dist/server/src/plugins/runtime/node/proxy/deviceManager.js +14 -12
- package/dist/server/src/plugins/runtime/node/proxy/deviceManager.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/fileServe.js +4 -9
- package/dist/server/src/plugins/runtime/node/proxy/fileServe.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/notificationManager.js +3 -0
- package/dist/server/src/plugins/runtime/node/proxy/notificationManager.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/storage.d.ts +5 -2
- package/dist/server/src/plugins/runtime/node/storage.js +92 -67
- package/dist/server/src/plugins/runtime/node/storage.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/storageController.d.ts +2 -0
- package/dist/server/src/plugins/runtime/node/storageController.js +12 -4
- package/dist/server/src/plugins/runtime/node/storageController.js.map +1 -1
- package/dist/server/src/plugins/runtime/python/child.py +47 -38
- package/dist/server/src/plugins/runtime/python/config_db.py +28 -17
- package/dist/server/src/plugins/runtime/python/index.js +1 -0
- package/dist/server/src/plugins/runtime/python/index.js.map +1 -1
- package/dist/server/src/plugins/runtime/python/plugin_api.py +5 -5
- package/dist/server/src/plugins/runtime/python/proxy/camera_device.py +14 -13
- package/dist/server/src/plugins/runtime/python/proxy/core_manager.py +11 -14
- package/dist/server/src/plugins/runtime/python/proxy/device_manager.py +23 -18
- package/dist/server/src/plugins/runtime/python/remote_urls.py +3 -7
- package/dist/server/src/plugins/runtime/python/storage.py +157 -126
- package/dist/server/src/plugins/runtime/python/storage_controller.py +28 -13
- package/dist/server/src/plugins/runtime/python/store.py +513 -0
- package/dist/server/src/plugins/runtime/python/store_migrate.py +59 -0
- package/dist/server/src/plugins/store/coalescingWriter.d.ts +7 -0
- package/dist/server/src/plugins/store/coalescingWriter.js +52 -0
- package/dist/server/src/plugins/store/coalescingWriter.js.map +1 -0
- package/dist/server/src/plugins/store/envelope.d.ts +5 -0
- package/dist/server/src/plugins/store/envelope.js +40 -0
- package/dist/server/src/plugins/store/envelope.js.map +1 -0
- package/dist/server/src/plugins/store/layout.d.ts +2 -0
- package/dist/server/src/plugins/store/layout.js +60 -0
- package/dist/server/src/plugins/store/layout.js.map +1 -0
- package/dist/server/src/plugins/store/location.d.ts +14 -0
- package/dist/server/src/plugins/store/location.js +55 -0
- package/dist/server/src/plugins/store/location.js.map +1 -0
- package/dist/server/src/plugins/store/migrate.d.ts +1 -0
- package/dist/server/src/plugins/store/migrate.js +22 -0
- package/dist/server/src/plugins/store/migrate.js.map +1 -0
- package/dist/server/src/plugins/store/pluginStoreFile.d.ts +14 -0
- package/dist/server/src/plugins/store/pluginStoreFile.js +58 -0
- package/dist/server/src/plugins/store/pluginStoreFile.js.map +1 -0
- package/dist/server/src/plugins/store/storeFile.d.ts +5 -0
- package/dist/server/src/plugins/store/storeFile.js +112 -0
- package/dist/server/src/plugins/store/storeFile.js.map +1 -0
- package/dist/server/src/plugins/store/validate.d.ts +1 -0
- package/dist/server/src/plugins/store/validate.js +49 -0
- package/dist/server/src/plugins/store/validate.js.map +1 -0
- package/dist/server/src/plugins/worker.js +9 -8
- package/dist/server/src/plugins/worker.js.map +1 -1
- package/dist/server/src/remote/services/cloudflare-managed.js +2 -2
- package/dist/server/src/remote/services/cloudflare-managed.js.map +1 -1
- package/dist/server/src/remote/services/cloudflare.js +1 -0
- package/dist/server/src/remote/services/cloudflare.js.map +1 -1
- package/dist/server/src/remote/tunnel/client.js +1 -0
- package/dist/server/src/remote/tunnel/client.js.map +1 -1
- package/dist/server/src/rpc/server.js +12 -5
- package/dist/server/src/rpc/server.js.map +1 -1
- package/dist/server/src/services/config/defaults.js +1 -0
- package/dist/server/src/services/config/defaults.js.map +1 -1
- package/dist/server/src/services/config/types.d.ts +1 -0
- package/dist/server/src/utils/npm/index.d.ts +1 -1
- package/dist/server/src/utils/npm/index.js +7 -4
- package/dist/server/src/utils/npm/index.js.map +1 -1
- package/dist/server/src/workers/capabilities/plugin-host.js +1 -1
- package/dist/server/src/workers/capabilities/plugin-host.js.map +1 -1
- package/package.json +26 -16
- package/dist/interface/assets/About-CMxNy7no.js +0 -1
- package/dist/interface/assets/Config-CcQUpeLe.js +0 -2
- package/dist/interface/assets/CuiBottomSheet-CFGurpP0.js +0 -1
- package/dist/interface/assets/PluginDetail-COURDgOk.js +0 -2
- package/dist/interface/assets/PluginSearch-Czyt4or9.js +0 -2
- package/dist/interface/assets/PluginSearch-SpzDNe08.js +0 -1
- package/dist/interface/assets/Plugins-C0YqC8-O.js +0 -1
- package/dist/interface/assets/Recordings-CdJm5exh.js +0 -1
- package/dist/interface/assets/SettingsAccount-BZaLHEXI.js +0 -1
- package/dist/interface/assets/SettingsAppearance-DX4C4Xxw.js +0 -1
- package/dist/interface/assets/SettingsRecordings-DyMo9O0s.js +0 -1
- package/dist/interface/assets/SettingsSystem-CrrqIGPM.js +0 -2
- package/dist/interface/assets/VersionsHandler-C6NlIR5o.js +0 -7
- package/dist/interface/assets/api-BOvysXhM.js +0 -2
- package/dist/interface/assets/api-D7tGlI-z.css +0 -2
- package/dist/interface/assets/cloudHandoff-BFhzjzv4.js +0 -1
- package/dist/interface/assets/main-DL335xeQ.js +0 -3
- package/dist/interface/assets/router-UepCX3sI.js +0 -2
- package/dist/interface/assets/ui-CH55JEcY.js +0 -1
- package/dist/interface/assets/useCuiDialog-DSyAPuxQ.js +0 -2
- /package/dist/interface/assets/{logo-512-DLKVOU2S.png → error-256-DLKVOU2S.png} +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import truststore
|
|
2
4
|
|
|
3
5
|
truststore.inject_into_ssl()
|
|
4
6
|
|
|
5
7
|
import asyncio
|
|
6
8
|
import importlib.util
|
|
7
|
-
import json
|
|
8
9
|
import os
|
|
9
10
|
import sys
|
|
10
11
|
from contextlib import suppress
|
|
11
12
|
from pathlib import Path
|
|
12
13
|
from types import ModuleType
|
|
13
|
-
from typing import Any,
|
|
14
|
+
from typing import Any, cast
|
|
14
15
|
|
|
15
16
|
import setproctitle
|
|
16
|
-
from lmdbm import Lmdb
|
|
17
17
|
|
|
18
18
|
from _camera_ui_tools.camera_ui_common import (
|
|
19
19
|
LoggerOptions,
|
|
@@ -23,11 +23,18 @@ from _camera_ui_tools.camera_ui_common import (
|
|
|
23
23
|
from _camera_ui_tools.camera_ui_rpc import CloseHandler, RPCClient, create_rpc_client
|
|
24
24
|
from _camera_ui_tools.camera_ui_sdk import API_EVENT, BasePlugin, Camera
|
|
25
25
|
from _camera_ui_tools.camera_ui_sdk import CameraDevice as CameraDeviceInterface
|
|
26
|
-
from plugins.runtime.python.config_db import
|
|
26
|
+
from plugins.runtime.python.config_db import (
|
|
27
|
+
LocalPluginConfigDb,
|
|
28
|
+
PluginConfigDb,
|
|
29
|
+
PluginConfigStoreRPC,
|
|
30
|
+
RemotePluginConfigDb,
|
|
31
|
+
)
|
|
27
32
|
from plugins.runtime.python.namespaces import NamespaceManager
|
|
28
33
|
from plugins.runtime.python.plugin_api import PluginAPI
|
|
29
34
|
from plugins.runtime.python.proxy.camera_device import CameraDeviceProxy
|
|
30
35
|
from plugins.runtime.python.proxy.file_serve import PluginFileServer
|
|
36
|
+
from plugins.runtime.python.store import STORE_FILE_NAME, PluginStoreFile
|
|
37
|
+
from plugins.runtime.python.store_migrate import migrate_legacy_lmdbm, needs_lmdbm_migration
|
|
31
38
|
from plugins.runtime.python.typings import (
|
|
32
39
|
PLUGIN_COMMAND,
|
|
33
40
|
PLUGIN_STATUS,
|
|
@@ -40,20 +47,7 @@ from plugins.runtime.python.typings import (
|
|
|
40
47
|
process_name = sys.argv[2] if len(sys.argv) > 2 else sys.argv[1] if len(sys.argv) > 1 else "Plugin"
|
|
41
48
|
setproctitle.setproctitle(f"camera.ui - {process_name}")
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
class JsonLmdb(Lmdb[Literal["config"], dict[str, Any]]):
|
|
45
|
-
def _pre_key(self, key: Literal["config"]) -> bytes:
|
|
46
|
-
return key.encode("utf-8")
|
|
47
|
-
|
|
48
|
-
def _post_key(self, key: bytes) -> Literal["config"]:
|
|
49
|
-
_key: Any = key.decode("utf-8")
|
|
50
|
-
return _key
|
|
51
|
-
|
|
52
|
-
def _pre_value(self, value: dict[str, Any]) -> bytes:
|
|
53
|
-
return json.dumps(value).encode("utf-8")
|
|
54
|
-
|
|
55
|
-
def _post_value(self, value: bytes) -> dict[str, Any]:
|
|
56
|
-
return json.loads(value.decode("utf-8"))
|
|
50
|
+
RPC_TEARDOWN_TIMEOUT = 0.5
|
|
57
51
|
|
|
58
52
|
|
|
59
53
|
class PluginChild:
|
|
@@ -98,7 +92,7 @@ class PluginChild:
|
|
|
98
92
|
self.signal_handler = SignalHandler(
|
|
99
93
|
{
|
|
100
94
|
"display_name": "[Signal]",
|
|
101
|
-
"timeout_duration":
|
|
95
|
+
"timeout_duration": 2,
|
|
102
96
|
"logger": self.logger,
|
|
103
97
|
"close_function": self.stop_plugin,
|
|
104
98
|
}
|
|
@@ -125,7 +119,7 @@ class PluginChild:
|
|
|
125
119
|
|
|
126
120
|
async def start_plugin(self, data: ProcessLoadMessage) -> None:
|
|
127
121
|
try:
|
|
128
|
-
# Host-local writable dir
|
|
122
|
+
# Host-local writable dir — on a remote worker the master's path from
|
|
129
123
|
# the START message would point at the wrong machine.
|
|
130
124
|
storage_path = os.environ.get("PLUGIN_STORAGE_PATH") or data["storage"]["storagePath"]
|
|
131
125
|
plugin_info = data["plugin"]
|
|
@@ -145,7 +139,6 @@ class PluginChild:
|
|
|
145
139
|
plugin_storage = await self.api.storage_controller.createStorage("plugin")
|
|
146
140
|
self.plugin = cast(BasePlugin, plugin_constructor(self.logger, self.api, plugin_storage))
|
|
147
141
|
|
|
148
|
-
# Apply storage_schema if defined by plugin
|
|
149
142
|
if hasattr(self.plugin, "storage_schema") and self.plugin.storage_schema:
|
|
150
143
|
plugin_storage.defineSchemas(self.plugin.storage_schema)
|
|
151
144
|
|
|
@@ -154,11 +147,12 @@ class PluginChild:
|
|
|
154
147
|
namespaces.plugin_child_rpc, self.plugin, without_decorators=True
|
|
155
148
|
)
|
|
156
149
|
|
|
150
|
+
# Remote-hosted: serve this worker's files so the master can stream
|
|
151
|
+
# downloads/exports of them.
|
|
157
152
|
if os.environ.get("PLUGIN_REMOTE_MODE"):
|
|
158
153
|
self.file_server = PluginFileServer(self.proxy, plugin_info["id"])
|
|
159
154
|
await self.file_server.register()
|
|
160
155
|
|
|
161
|
-
# Set the plugin instance on device_manager for lifecycle callbacks
|
|
162
156
|
self.api.device_manager.set_plugin(self.plugin)
|
|
163
157
|
|
|
164
158
|
await self.api.device_manager.init()
|
|
@@ -180,15 +174,31 @@ class PluginChild:
|
|
|
180
174
|
self.stopped = True
|
|
181
175
|
|
|
182
176
|
if self.api:
|
|
183
|
-
self.api.
|
|
184
|
-
|
|
177
|
+
completed = await self.api.emit_and_wait(
|
|
178
|
+
API_EVENT.SHUTDOWN.value,
|
|
179
|
+
timeout=1.0,
|
|
180
|
+
on_error=lambda e: self.logger.error(f"Shutdown listener failed: {e}"),
|
|
181
|
+
)
|
|
182
|
+
if not completed:
|
|
183
|
+
self.logger.warn("Shutdown listeners still pending after 1s, continuing teardown")
|
|
184
|
+
|
|
185
|
+
await self.api.device_manager.close()
|
|
186
|
+
await self.api.core_manager.close()
|
|
187
|
+
await self.api.storage_controller.close()
|
|
188
|
+
|
|
185
189
|
self.api.cancel()
|
|
186
190
|
|
|
187
191
|
if self.plugin_db is not None:
|
|
188
192
|
with suppress(Exception):
|
|
189
|
-
self.plugin_db.close()
|
|
193
|
+
await self.plugin_db.close()
|
|
190
194
|
self.plugin_db = None
|
|
191
195
|
|
|
196
|
+
try:
|
|
197
|
+
await asyncio.wait_for(self._close_rpc(), timeout=RPC_TEARDOWN_TIMEOUT)
|
|
198
|
+
except TimeoutError:
|
|
199
|
+
self.logger.warn(f"RPC teardown still pending after {RPC_TEARDOWN_TIMEOUT}s, exiting anyway")
|
|
200
|
+
|
|
201
|
+
async def _close_rpc(self) -> None:
|
|
192
202
|
if self.channel:
|
|
193
203
|
with suppress(Exception):
|
|
194
204
|
await self.channel.close()
|
|
@@ -202,7 +212,8 @@ class PluginChild:
|
|
|
202
212
|
with suppress(Exception):
|
|
203
213
|
await self.close_proxy()
|
|
204
214
|
|
|
205
|
-
|
|
215
|
+
with suppress(Exception):
|
|
216
|
+
await self.proxy.disconnect()
|
|
206
217
|
|
|
207
218
|
async def send_message(self, message: ProcessResponse) -> None:
|
|
208
219
|
await self.channel.send(message)
|
|
@@ -224,25 +235,24 @@ class PluginChild:
|
|
|
224
235
|
pass
|
|
225
236
|
|
|
226
237
|
async def configure_plugin_db(self, storage_path: str, plugin_id: str) -> PluginConfigDb:
|
|
227
|
-
# Remote-hosted: config lives on the master (re-homing safe)
|
|
238
|
+
# Remote-hosted: config lives on the master (re-homing safe) — persist
|
|
228
239
|
# through its config store instead of a worker-local file.
|
|
229
240
|
if os.environ.get("PLUGIN_CONFIG_STORE_RPC"):
|
|
230
241
|
namespaces = NamespaceManager.plugin_namespaces(plugin_id)
|
|
231
|
-
|
|
232
|
-
remote_db = RemotePluginConfigDb(
|
|
242
|
+
store_rpc = self.proxy.create_proxy(namespaces.plugin_config_store_rpc, PluginConfigStoreRPC)
|
|
243
|
+
remote_db = RemotePluginConfigDb(store_rpc)
|
|
233
244
|
await remote_db.init()
|
|
234
245
|
return remote_db
|
|
235
246
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
plugin_db = cast(Lmdb[Literal["config"], dict[str, Any]], JsonLmdb.open(file=str(db_path), flag="c"))
|
|
240
|
-
config = cast(dict[str, Any] | None, plugin_db.get("config"))
|
|
247
|
+
volume_dir = Path(storage_path) / "volume"
|
|
248
|
+
store_path = volume_dir / STORE_FILE_NAME
|
|
241
249
|
|
|
242
|
-
if
|
|
243
|
-
|
|
250
|
+
if await asyncio.to_thread(needs_lmdbm_migration, volume_dir, store_path):
|
|
251
|
+
await migrate_legacy_lmdbm(volume_dir, store_path, self.logger)
|
|
244
252
|
|
|
245
|
-
|
|
253
|
+
store = PluginStoreFile(str(volume_dir), plugin_id, self.logger)
|
|
254
|
+
await store.open()
|
|
255
|
+
return LocalPluginConfigDb(store)
|
|
246
256
|
|
|
247
257
|
async def configure_cameras(self, api: PluginAPI, plugin_info: PluginInfo, cameras: list[Camera]) -> None:
|
|
248
258
|
cameras_devices: list[CameraDeviceProxy] = []
|
|
@@ -254,7 +264,6 @@ class PluginChild:
|
|
|
254
264
|
cameras_devices.append(
|
|
255
265
|
CameraDeviceProxy(
|
|
256
266
|
self.proxy,
|
|
257
|
-
api,
|
|
258
267
|
api.storage_controller,
|
|
259
268
|
camera,
|
|
260
269
|
plugin_info,
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Literal, Protocol
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from plugins.runtime.python.store import PluginStoreFile
|
|
3
7
|
|
|
4
8
|
|
|
5
9
|
class PluginConfigStoreRPC(Protocol):
|
|
@@ -9,11 +13,25 @@ class PluginConfigStoreRPC(Protocol):
|
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
class PluginConfigDb(Protocol):
|
|
12
|
-
def get(self, key: Literal["config"]) -> dict[str, Any] | None: ...
|
|
16
|
+
def get(self, key: Literal["config"], /) -> dict[str, Any] | None: ...
|
|
17
|
+
|
|
18
|
+
async def put(self, key: Literal["config"], value: dict[str, Any], /) -> None: ...
|
|
13
19
|
|
|
14
|
-
def
|
|
20
|
+
async def close(self) -> None: ...
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
|
|
23
|
+
class LocalPluginConfigDb:
|
|
24
|
+
def __init__(self, store: PluginStoreFile) -> None:
|
|
25
|
+
self._store = store
|
|
26
|
+
|
|
27
|
+
def get(self, key: Literal["config"], /) -> dict[str, Any]:
|
|
28
|
+
return self._store.get()
|
|
29
|
+
|
|
30
|
+
async def put(self, key: Literal["config"], value: dict[str, Any], /) -> None:
|
|
31
|
+
await self._store.put(value)
|
|
32
|
+
|
|
33
|
+
async def close(self) -> None:
|
|
34
|
+
await self._store.close()
|
|
17
35
|
|
|
18
36
|
|
|
19
37
|
class RemotePluginConfigDb:
|
|
@@ -24,19 +42,12 @@ class RemotePluginConfigDb:
|
|
|
24
42
|
async def init(self) -> None:
|
|
25
43
|
self._cache = (await self._store.get()) or {}
|
|
26
44
|
|
|
27
|
-
def get(self,
|
|
45
|
+
def get(self, key: Literal["config"], /) -> dict[str, Any]:
|
|
28
46
|
return self._cache
|
|
29
47
|
|
|
30
|
-
def
|
|
31
|
-
|
|
32
|
-
self.
|
|
33
|
-
# Lmdb-compatible sync signature — persistence is fire-and-forget; the
|
|
34
|
-
# cache is already current and errors only cost durability of this write.
|
|
35
|
-
task = asyncio.create_task(self._persist(dict(config)))
|
|
36
|
-
task.add_done_callback(lambda t: t.exception())
|
|
48
|
+
async def put(self, key: Literal["config"], value: dict[str, Any], /) -> None:
|
|
49
|
+
self._cache = value
|
|
50
|
+
await self._store.put(value)
|
|
37
51
|
|
|
38
|
-
def close(self) -> None:
|
|
52
|
+
async def close(self) -> None:
|
|
39
53
|
return None
|
|
40
|
-
|
|
41
|
-
async def _persist(self, config: dict[str, Any]) -> None:
|
|
42
|
-
await self._store.put(config)
|
|
@@ -29,6 +29,7 @@ export class PythonPluginRuntime extends BasePluginRuntime {
|
|
|
29
29
|
...this.getEnv(),
|
|
30
30
|
},
|
|
31
31
|
cwd: this.plugin.mainPath,
|
|
32
|
+
windowsHide: true,
|
|
32
33
|
});
|
|
33
34
|
this.worker.on('spawn', this.onSpawn.bind(this, this.worker.pid, command, args, processNames, resolve));
|
|
34
35
|
this.worker.on('error', this.onError.bind(this, reject));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/plugins/runtime/python/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI/C,MAAM,OAAO,mBAAoB,SAAQ,iBAAiB;IAChD,EAAE,CAAkB;IAE5B,YAAY,MAAqB;QAC/B,KAAK,CAAC,MAAM,CAAC,CAAC;QAEd,IAAI,CAAC,EAAE,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACxI,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAE1B,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,CAAC;YAEnI,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC;YACzC,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACvE,MAAM,IAAI,GAAa,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,YAAY,CAAC,CAAC;YAEjE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YAEhE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE,IAAI,EAAE;gBAClD,GAAG,EAAE;oBACH,gBAAgB,EAAE,GAAG;oBACrB,UAAU,EAAE,IAAI,CAAC,gBAAgB,EAAE;oBACnC,GAAG,IAAI,CAAC,MAAM,EAAE;iBACjB;gBACD,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/plugins/runtime/python/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
from typing import Any,
|
|
2
|
-
|
|
3
|
-
from plugins.runtime.python.config_db import PluginConfigDb
|
|
1
|
+
from typing import Any, cast
|
|
4
2
|
|
|
5
3
|
from _camera_ui_tools.camera_ui_common import LoggerService
|
|
6
4
|
from _camera_ui_tools.camera_ui_rpc import RPCClient
|
|
@@ -14,6 +12,7 @@ from _camera_ui_tools.camera_ui_sdk import (
|
|
|
14
12
|
)
|
|
15
13
|
from _camera_ui_tools.camera_ui_sdk import PluginAPI as PluginAPIInterface
|
|
16
14
|
from _camera_ui_tools.camera_ui_sdk.internal import AsyncEventEmitter
|
|
15
|
+
from plugins.runtime.python.config_db import PluginConfigDb
|
|
17
16
|
from plugins.runtime.python.proxy.core_manager import CoreManagerProxy
|
|
18
17
|
from plugins.runtime.python.proxy.device_manager import DeviceManagerProxy
|
|
19
18
|
from plugins.runtime.python.proxy.download_manager import DownloadManagerProxy
|
|
@@ -33,10 +32,11 @@ class PluginAPI(AsyncEventEmitter, PluginAPIInterface):
|
|
|
33
32
|
) -> None:
|
|
34
33
|
super().__init__()
|
|
35
34
|
|
|
35
|
+
self.logger = logger
|
|
36
36
|
self.storage_path = storage_path
|
|
37
37
|
self.storage_controller = StorageController(self, proxy, plugin, plugin_db)
|
|
38
|
-
self.core_manager = CoreManagerProxy(proxy,
|
|
39
|
-
self.device_manager = DeviceManagerProxy(proxy, self
|
|
38
|
+
self.core_manager = CoreManagerProxy(proxy, logger, plugin)
|
|
39
|
+
self.device_manager = DeviceManagerProxy(proxy, self.storage_controller, logger, plugin)
|
|
40
40
|
self.download_manager = DownloadManagerProxy(proxy)
|
|
41
41
|
self.notification_manager = NotificationManagerProxy(proxy, plugin)
|
|
42
42
|
|
|
@@ -9,7 +9,6 @@ from deepdiff.diff import DeepDiff
|
|
|
9
9
|
from _camera_ui_tools.camera_ui_common import Subscribed, TaskSet
|
|
10
10
|
from _camera_ui_tools.camera_ui_rpc import CloseHandler, RPCClient
|
|
11
11
|
from _camera_ui_tools.camera_ui_sdk import (
|
|
12
|
-
API_EVENT,
|
|
13
12
|
BehaviorSubject,
|
|
14
13
|
Camera,
|
|
15
14
|
CameraDetectionSettings,
|
|
@@ -53,7 +52,6 @@ from _camera_ui_tools.camera_ui_sdk import (
|
|
|
53
52
|
from _camera_ui_tools.camera_ui_sdk import CameraDevice as CameraDeviceInterface
|
|
54
53
|
from _camera_ui_tools.camera_ui_sdk.internal import SensorJSON
|
|
55
54
|
from plugins.runtime.python.camera.utils import build_snapshot_url, build_target_url
|
|
56
|
-
from plugins.runtime.python.remote_urls import rewrite_source_urls_for_remote
|
|
57
55
|
from plugins.runtime.python.namespaces import (
|
|
58
56
|
CameraNamespaces,
|
|
59
57
|
FrameWorkerDetectionNamespaces,
|
|
@@ -67,6 +65,7 @@ from plugins.runtime.python.proxy.sensor import (
|
|
|
67
65
|
SensorControllerInterface,
|
|
68
66
|
SensorProxy,
|
|
69
67
|
)
|
|
68
|
+
from plugins.runtime.python.remote_urls import rewrite_source_urls_for_remote
|
|
70
69
|
from plugins.runtime.python.typings import (
|
|
71
70
|
CameraEventMessage,
|
|
72
71
|
PluginInfo,
|
|
@@ -78,7 +77,6 @@ from plugins.runtime.python.typings import (
|
|
|
78
77
|
)
|
|
79
78
|
|
|
80
79
|
if TYPE_CHECKING:
|
|
81
|
-
from plugins.runtime.python.plugin_api import PluginAPI
|
|
82
80
|
from plugins.runtime.python.storage_controller import StorageController
|
|
83
81
|
|
|
84
82
|
|
|
@@ -99,7 +97,10 @@ class CameraControllerInterface(Protocol):
|
|
|
99
97
|
async def disconnect(self) -> None: ...
|
|
100
98
|
async def snapshot(self, source_id: str, force_new: bool | None = None) -> bytes | None: ...
|
|
101
99
|
async def probeStream(
|
|
102
|
-
self,
|
|
100
|
+
self,
|
|
101
|
+
source_id: str,
|
|
102
|
+
probe_config: ProbeConfig | None = None,
|
|
103
|
+
refresh: bool | None = False,
|
|
103
104
|
) -> ProbeStream | None: ...
|
|
104
105
|
async def refreshStates(self) -> dict[str, Any]: ...
|
|
105
106
|
async def registerSensor(self, sensor: SensorJSON, plugin_id: str) -> bool: ...
|
|
@@ -144,7 +145,6 @@ class CameraDeviceProxy(Subscribed, CameraDeviceInterface):
|
|
|
144
145
|
def __init__(
|
|
145
146
|
self,
|
|
146
147
|
proxy: RPCClient,
|
|
147
|
-
api: PluginAPI,
|
|
148
148
|
storage_controller: StorageController,
|
|
149
149
|
camera: Camera,
|
|
150
150
|
plugin: PluginInfo,
|
|
@@ -163,7 +163,6 @@ class CameraDeviceProxy(Subscribed, CameraDeviceInterface):
|
|
|
163
163
|
)
|
|
164
164
|
|
|
165
165
|
self._logger = logger
|
|
166
|
-
self._api: PluginAPI = api
|
|
167
166
|
self._proxy = proxy
|
|
168
167
|
self._plugin = plugin
|
|
169
168
|
self._contract: PluginContract = plugin["contract"]
|
|
@@ -199,8 +198,6 @@ class CameraDeviceProxy(Subscribed, CameraDeviceInterface):
|
|
|
199
198
|
NamespaceManager.frame_worker_detection_namespaces(self.id),
|
|
200
199
|
)
|
|
201
200
|
|
|
202
|
-
self._api.once(API_EVENT.SHUTDOWN.value, self.cleanup)
|
|
203
|
-
|
|
204
201
|
@property
|
|
205
202
|
def _cameraObject(self) -> Camera:
|
|
206
203
|
return deepcopy(self._camera_subject.value)
|
|
@@ -345,7 +342,7 @@ class CameraDeviceProxy(Subscribed, CameraDeviceInterface):
|
|
|
345
342
|
return self._proxy.create_proxy(self._namespaces[4].detection_rpc)
|
|
346
343
|
|
|
347
344
|
def getSourceById(self, id: str) -> CameraDeviceSource | None:
|
|
348
|
-
return next((s for s in self.sources if s._id == id), None)
|
|
345
|
+
return next((s for s in self.sources if s._id == id), None) # pyright: ignore[reportPrivateUsage]
|
|
349
346
|
|
|
350
347
|
def _can_access_sensor(self, sensor: StoredSensorData) -> bool:
|
|
351
348
|
# Own sensors are always accessible
|
|
@@ -609,7 +606,10 @@ class CameraDeviceProxy(Subscribed, CameraDeviceInterface):
|
|
|
609
606
|
return await self._camera_controller_proxy.snapshot(source_id, force_new)
|
|
610
607
|
|
|
611
608
|
async def _probe_stream(
|
|
612
|
-
self,
|
|
609
|
+
self,
|
|
610
|
+
source_id: str,
|
|
611
|
+
probe_config: ProbeConfig | None = None,
|
|
612
|
+
refresh: bool | None = False,
|
|
613
613
|
) -> ProbeStream | None:
|
|
614
614
|
return await self._camera_controller_proxy.probeStream(source_id, probe_config, refresh)
|
|
615
615
|
|
|
@@ -624,8 +624,6 @@ class CameraDeviceProxy(Subscribed, CameraDeviceInterface):
|
|
|
624
624
|
|
|
625
625
|
self.unsubscribe()
|
|
626
626
|
|
|
627
|
-
self._api.removeListener(API_EVENT.SHUTDOWN.value, self.cleanup)
|
|
628
|
-
|
|
629
627
|
self._tasks.remove_all()
|
|
630
628
|
|
|
631
629
|
if self._close_subscription:
|
|
@@ -772,7 +770,10 @@ class CameraDeviceProxy(Subscribed, CameraDeviceInterface):
|
|
|
772
770
|
self._sensors.pop(removed_data["sensorId"], None)
|
|
773
771
|
|
|
774
772
|
self._sensor_removed_subject.next(
|
|
775
|
-
{
|
|
773
|
+
{
|
|
774
|
+
"sensorId": removed_data["sensorId"],
|
|
775
|
+
"sensorType": removed_data["sensorType"],
|
|
776
|
+
}
|
|
776
777
|
)
|
|
777
778
|
|
|
778
779
|
elif event_type == "sensor:assignment:changed":
|
|
@@ -2,12 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import os
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Any, TypedDict
|
|
6
6
|
|
|
7
7
|
from _camera_ui_tools.camera_ui_common import LoggerService
|
|
8
8
|
from _camera_ui_tools.camera_ui_rpc import CloseHandler, RPCClient
|
|
9
9
|
from _camera_ui_tools.camera_ui_sdk import (
|
|
10
|
-
API_EVENT,
|
|
11
10
|
BasePlugin,
|
|
12
11
|
CoreManager,
|
|
13
12
|
CoreManagerEvent,
|
|
@@ -15,13 +14,14 @@ from _camera_ui_tools.camera_ui_sdk import (
|
|
|
15
14
|
PluginInterface,
|
|
16
15
|
Subject,
|
|
17
16
|
)
|
|
18
|
-
from plugins.runtime.python.namespaces import
|
|
17
|
+
from plugins.runtime.python.namespaces import (
|
|
18
|
+
CoreManagerNamespaces,
|
|
19
|
+
NamespaceManager,
|
|
20
|
+
PluginNamespaces,
|
|
21
|
+
)
|
|
19
22
|
from plugins.runtime.python.rpc.typings import CoreManagerInterface
|
|
20
23
|
from plugins.runtime.python.typings import PluginInfo
|
|
21
24
|
|
|
22
|
-
if TYPE_CHECKING:
|
|
23
|
-
from plugins.runtime.python.plugin_api import PluginAPI
|
|
24
|
-
|
|
25
25
|
|
|
26
26
|
class RPCConnection(TypedDict):
|
|
27
27
|
proxy: BasePlugin
|
|
@@ -32,13 +32,11 @@ class CoreManagerProxy(CoreManager):
|
|
|
32
32
|
def __init__(
|
|
33
33
|
self,
|
|
34
34
|
proxy: RPCClient,
|
|
35
|
-
api: PluginAPI,
|
|
36
35
|
logger: LoggerService,
|
|
37
36
|
plugin: PluginInfo,
|
|
38
37
|
):
|
|
39
38
|
self.__initialized = False
|
|
40
39
|
|
|
41
|
-
self.__api: PluginAPI = api
|
|
42
40
|
self.__proxy = proxy
|
|
43
41
|
self.__logger = logger
|
|
44
42
|
self.__plugin = plugin
|
|
@@ -52,8 +50,6 @@ class CoreManagerProxy(CoreManager):
|
|
|
52
50
|
self.__rpc_connections: dict[str, RPCConnection] = {}
|
|
53
51
|
self.__event_subject: Subject[CoreManagerEvent] = Subject()
|
|
54
52
|
|
|
55
|
-
self.__api.once(API_EVENT.SHUTDOWN.value, self.__close)
|
|
56
|
-
|
|
57
53
|
@property
|
|
58
54
|
def __core_manager_proxy(self) -> CoreManagerInterface:
|
|
59
55
|
return self.__proxy.create_proxy(
|
|
@@ -112,6 +108,11 @@ class CoreManagerProxy(CoreManager):
|
|
|
112
108
|
async def getPluginsByInterface(self, interfaceName: PluginInterface) -> list[PluginInfo]:
|
|
113
109
|
return await self.__core_manager_proxy.getPluginsByInterface(interfaceName)
|
|
114
110
|
|
|
111
|
+
async def close(self) -> None:
|
|
112
|
+
"""Internal method to close the core manager proxy."""
|
|
113
|
+
self.__initialized = False
|
|
114
|
+
self.__event_subject.complete()
|
|
115
|
+
|
|
115
116
|
async def __on_event_message(self, event: dict[str, Any]) -> None:
|
|
116
117
|
event_type = event.get("type")
|
|
117
118
|
if not event_type:
|
|
@@ -119,10 +120,6 @@ class CoreManagerProxy(CoreManager):
|
|
|
119
120
|
data = event.get("data")
|
|
120
121
|
self.__event_subject.next({"type": event_type, "data": data})
|
|
121
122
|
|
|
122
|
-
async def __close(self) -> None:
|
|
123
|
-
self.__initialized = False
|
|
124
|
-
self.__event_subject.complete()
|
|
125
|
-
self.__api.removeListener(API_EVENT.SHUTDOWN.value, self.__close)
|
|
126
123
|
if self.__close_subscription:
|
|
127
124
|
await self.__close_subscription()
|
|
128
125
|
self.__close_subscription = None
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Any
|
|
5
5
|
|
|
6
6
|
from _camera_ui_tools.camera_ui_common import (
|
|
7
7
|
LoggerService,
|
|
8
8
|
)
|
|
9
9
|
from _camera_ui_tools.camera_ui_rpc import CloseHandler, RPCClient
|
|
10
10
|
from _camera_ui_tools.camera_ui_sdk import (
|
|
11
|
-
API_EVENT,
|
|
12
11
|
BasePlugin,
|
|
13
12
|
Camera,
|
|
14
13
|
DeviceManager,
|
|
@@ -20,21 +19,20 @@ from plugins.runtime.python.namespaces import (
|
|
|
20
19
|
NamespaceManager,
|
|
21
20
|
PluginNamespaces,
|
|
22
21
|
)
|
|
23
|
-
from plugins.runtime.python.rpc.typings import
|
|
22
|
+
from plugins.runtime.python.rpc.typings import (
|
|
23
|
+
DeviceManagerInterface,
|
|
24
|
+
DiscoveryManagerInterface,
|
|
25
|
+
)
|
|
24
26
|
from plugins.runtime.python.storage_controller import StorageController
|
|
25
27
|
from plugins.runtime.python.typings import PluginInfo
|
|
26
28
|
|
|
27
29
|
from .camera_device import CameraDeviceProxy
|
|
28
30
|
|
|
29
|
-
if TYPE_CHECKING:
|
|
30
|
-
from plugins.runtime.python.plugin_api import PluginAPI
|
|
31
|
-
|
|
32
31
|
|
|
33
32
|
class DeviceManagerProxy(DeviceManager):
|
|
34
33
|
def __init__(
|
|
35
34
|
self,
|
|
36
35
|
proxy: RPCClient,
|
|
37
|
-
api: PluginAPI,
|
|
38
36
|
storage_controller: StorageController,
|
|
39
37
|
logger: LoggerService,
|
|
40
38
|
plugin: PluginInfo,
|
|
@@ -42,7 +40,6 @@ class DeviceManagerProxy(DeviceManager):
|
|
|
42
40
|
self.__initialized = False
|
|
43
41
|
self.__plugin_instance: BasePlugin | None = None
|
|
44
42
|
|
|
45
|
-
self.__api: PluginAPI = api
|
|
46
43
|
self.__proxy = proxy
|
|
47
44
|
self.__storage_controller = storage_controller
|
|
48
45
|
self.__logger = logger
|
|
@@ -56,8 +53,6 @@ class DeviceManagerProxy(DeviceManager):
|
|
|
56
53
|
NamespaceManager.discovery_manager_namespaces(),
|
|
57
54
|
)
|
|
58
55
|
|
|
59
|
-
self.__api.once(API_EVENT.SHUTDOWN.value, self.__close)
|
|
60
|
-
|
|
61
56
|
@property
|
|
62
57
|
def __device_manager_proxy(self) -> DeviceManagerInterface:
|
|
63
58
|
return self.__proxy.create_proxy(self.__namespaces[0].device_manager_rpc, DeviceManagerInterface)
|
|
@@ -97,6 +92,16 @@ class DeviceManagerProxy(DeviceManager):
|
|
|
97
92
|
async def configureCameras(self, camera_devices: list[CameraDeviceProxy]) -> None:
|
|
98
93
|
await asyncio.gather(*[self.__get_camera_device(camera_device) for camera_device in camera_devices])
|
|
99
94
|
|
|
95
|
+
async def close(self) -> None:
|
|
96
|
+
"""Internal method to close the device manager proxy and cleanup resources."""
|
|
97
|
+
self.__initialized = False
|
|
98
|
+
if self.__close_request:
|
|
99
|
+
await self.__close_request()
|
|
100
|
+
|
|
101
|
+
for device in self.__devices.values():
|
|
102
|
+
await device.cleanup()
|
|
103
|
+
self.__devices.clear()
|
|
104
|
+
|
|
100
105
|
async def __on_event_message(self, event: Any) -> None:
|
|
101
106
|
if not self.__plugin_instance:
|
|
102
107
|
self.__logger.warn("Plugin instance not set, cannot handle lifecycle event")
|
|
@@ -107,6 +112,9 @@ class DeviceManagerProxy(DeviceManager):
|
|
|
107
112
|
|
|
108
113
|
if event_type == "cameraAdded":
|
|
109
114
|
camera: Camera = data.get("camera")
|
|
115
|
+
if camera["_id"] in self.__devices:
|
|
116
|
+
return
|
|
117
|
+
|
|
110
118
|
camera_device = await self.__get_camera_device(camera)
|
|
111
119
|
|
|
112
120
|
if camera_device:
|
|
@@ -153,11 +161,14 @@ class DeviceManagerProxy(DeviceManager):
|
|
|
153
161
|
camera_device = self.__devices[camera["_id"]]
|
|
154
162
|
else:
|
|
155
163
|
camera_logger = self.__logger.create_logger(
|
|
156
|
-
{
|
|
164
|
+
{
|
|
165
|
+
"suffix": camera["name"],
|
|
166
|
+
"target_id": camera["_id"],
|
|
167
|
+
"target_type": "camera",
|
|
168
|
+
}
|
|
157
169
|
)
|
|
158
170
|
camera_device = CameraDeviceProxy(
|
|
159
171
|
self.__proxy,
|
|
160
|
-
self.__api,
|
|
161
172
|
self.__storage_controller,
|
|
162
173
|
camera,
|
|
163
174
|
self.__plugin,
|
|
@@ -177,9 +188,3 @@ class DeviceManagerProxy(DeviceManager):
|
|
|
177
188
|
|
|
178
189
|
async def __remove_camera_storage(self, camera_id: str) -> None:
|
|
179
190
|
await self.__storage_controller.removeStorage("camera", camera_id)
|
|
180
|
-
|
|
181
|
-
async def __close(self) -> None:
|
|
182
|
-
self.__initialized = False
|
|
183
|
-
self.__api.removeListener(API_EVENT.SHUTDOWN.value, self.__close)
|
|
184
|
-
if self.__close_request:
|
|
185
|
-
await self.__close_request()
|
|
@@ -8,11 +8,7 @@ _LOCALHOST = re.compile(r"127\.0\.0\.1|localhost")
|
|
|
8
8
|
def _rewrite_url(url: str, master: str, user: str | None, password: str | None) -> str:
|
|
9
9
|
rewritten = _LOCALHOST.sub(master, url)
|
|
10
10
|
|
|
11
|
-
if (
|
|
12
|
-
user
|
|
13
|
-
and rewritten.startswith("rtsp://")
|
|
14
|
-
and "@" not in rewritten[7:].split("/")[0]
|
|
15
|
-
):
|
|
11
|
+
if user and rewritten.startswith("rtsp://") and "@" not in rewritten[7:].split("/")[0]:
|
|
16
12
|
rewritten = rewritten.replace("rtsp://", f"rtsp://{user}:{password or ''}@", 1)
|
|
17
13
|
|
|
18
14
|
return rewritten
|
|
@@ -22,9 +18,9 @@ def _walk(value: Any, master: str, user: str | None, password: str | None) -> An
|
|
|
22
18
|
if isinstance(value, str):
|
|
23
19
|
return _rewrite_url(value, master, user, password)
|
|
24
20
|
if isinstance(value, list):
|
|
25
|
-
return [_walk(v, master, user, password) for v in value]
|
|
21
|
+
return [_walk(v, master, user, password) for v in value] # pyright: ignore[reportUnknownVariableType]
|
|
26
22
|
if isinstance(value, dict):
|
|
27
|
-
return {k: _walk(v, master, user, password) for k, v in value.items()}
|
|
23
|
+
return {k: _walk(v, master, user, password) for k, v in value.items()} # pyright: ignore[reportUnknownVariableType]
|
|
28
24
|
return value
|
|
29
25
|
|
|
30
26
|
|