mirror of
https://github.com/koush/scrypted.git
synced 2026-02-03 14:13:28 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fb0c01e7e | ||
|
|
014d7b35ac | ||
|
|
b08267dab0 | ||
|
|
97d78516f2 | ||
|
|
360c2437c1 | ||
|
|
0b230bfc74 | ||
|
|
d25dc8d266 | ||
|
|
5f4d1e99cd | ||
|
|
ee38ef7817 | ||
|
|
80af38d3e1 | ||
|
|
2f19866f05 | ||
|
|
cf1c500e9d | ||
|
|
9a770e9dc9 | ||
|
|
6dbb8863a0 | ||
|
|
5eac8d0ab9 | ||
|
|
272bad8f29 | ||
|
|
83a3352862 | ||
|
|
4d5a693208 | ||
|
|
70e7f944c0 | ||
|
|
5a52c03a3d | ||
|
|
f9f597ef01 | ||
|
|
2e07788c0c | ||
|
|
9c0fbc1cb6 | ||
|
|
239d49899d | ||
|
|
2d3589b5a3 | ||
|
|
96ec465a38 | ||
|
|
5bb6b87c7d | ||
|
|
fcfedccaf8 | ||
|
|
98373833fd |
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -13,11 +13,11 @@ Before opening an issue, view the device's Console logs in the Scrypted Manageme
|
||||
|
||||
**DO NOT OPEN ISSUES FOR ANY OF THE FOLLOWING:**
|
||||
|
||||
* Server setup assistance. Use Discord, Reddit, or Github Discussions.
|
||||
* Hardware setup assistance. Use Discord, Reddit, or Github Discussions.
|
||||
* Server or hardware setup assistance. Use Discord, Reddit, or Github Discussions.
|
||||
* Feature Requests. Use Discord, Reddit, or Github Discussions.
|
||||
* Packet loss in your camera logs. This is wifi/network congestion.
|
||||
* HomeKit weirdness. See HomeKit troubleshooting guide.
|
||||
* Release schedules or timelines. Releases are rolled out unevenly across the different server platforms.
|
||||
|
||||
However, if something **was working**, and is now **no longer working**, you may create a Github issue.
|
||||
Created issues that do not meet these requirements or are improperly filled out will be immediately closed.
|
||||
|
||||
@@ -70,7 +70,7 @@ async function getAuth(options: AuthFetchOptions, url: string | URL, method: str
|
||||
|
||||
export function createAuthFetch<B, M>(
|
||||
h: fetcher<B, M>,
|
||||
parser: (body: M, responseType: HttpFetchResponseType) => Promise<any>
|
||||
parser: (body: M, responseType: HttpFetchResponseType | undefined) => Promise<any>
|
||||
) {
|
||||
const authHttpFetch = async <T extends HttpFetchOptions<B>>(options: T & AuthFetchOptions): ReturnType<typeof h<T>> => {
|
||||
const method = getFetchMethod(options);
|
||||
@@ -99,7 +99,7 @@ export function createAuthFetch<B, M>(
|
||||
};
|
||||
}
|
||||
|
||||
let authenticateHeaders: string | string[] = initialResponse.headers.get('www-authenticate');
|
||||
let authenticateHeaders: string | string[] | null = initialResponse.headers.get('www-authenticate');
|
||||
if (!authenticateHeaders)
|
||||
throw new Error('Did not find WWW-Authenticate header.');
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"inlineSources": true,
|
||||
"declaration": true,
|
||||
"resolveJsonModule": true,
|
||||
"strict": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
|
||||
14
packages/cli/package-lock.json
generated
14
packages/cli/package-lock.json
generated
@@ -10,7 +10,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/client": "^1.3.3",
|
||||
"@scrypted/types": "^0.2.99",
|
||||
"@scrypted/types": "^0.3.30",
|
||||
"engine.io-client": "^6.5.3",
|
||||
"readline-sync": "^1.4.10",
|
||||
"semver": "^7.5.4",
|
||||
@@ -101,15 +101,11 @@
|
||||
"rimraf": "^5.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/client/node_modules/@scrypted/types": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.3.4.tgz",
|
||||
"integrity": "sha512-k/YMx8lIWOkePgXfKW9POr12mb+erFU2JKxO7TW92GyW8ojUWw9VOc0PK6O9bybi0vhsEnvMFkO6pO6bAonsVA=="
|
||||
},
|
||||
"node_modules/@scrypted/types": {
|
||||
"version": "0.2.99",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.2.99.tgz",
|
||||
"integrity": "sha512-2J1FH7tpAW5X3rgA70gJ+z0HFM90c/tBA+JXdP1vI1d/0yVmh9TSxnHoCuADN4R2NQXHmoZ6Nbds9kKAQ/25XQ=="
|
||||
"version": "0.3.30",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.3.30.tgz",
|
||||
"integrity": "sha512-1k+JVSR6WSNmE/5mLdqfrTmV3uRbvZp0OwKb8ikNi39ysBuC000tQGcEdXZqhYqRgWdhDTWtxXe9XsYoAZGKmA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@scrypted/client": "^1.3.3",
|
||||
"@scrypted/types": "^0.2.99",
|
||||
"@scrypted/types": "^0.3.30",
|
||||
"engine.io-client": "^6.5.3",
|
||||
"readline-sync": "^1.4.10",
|
||||
"semver": "^7.5.4",
|
||||
|
||||
@@ -160,11 +160,11 @@ async function main() {
|
||||
const ffmpegInput = await sdk.mediaManager.convertMediaObjectToJSON<FFmpegInput>(await pendingResult, ScryptedMimeTypes.FFmpegInput);
|
||||
if (ffmpegInput.url && ffmpegInput.urls?.[0]) {
|
||||
const url = new URL(ffmpegInput.url);
|
||||
if (url.hostname === '127.0.0.1' && ffmpegInput.urls?.[0]) {
|
||||
ffmpegInput.inputArguments = ffmpegInput.inputArguments.map(i => i === ffmpegInput.url ? ffmpegInput.urls?.[0] : i);
|
||||
if (url.hostname === '127.0.0.1' && ffmpegInput.urls?.[0] && ffmpegInput.inputArguments) {
|
||||
ffmpegInput.inputArguments = ffmpegInput.inputArguments.map(i => i === ffmpegInput.url && ffmpegInput.urls ? ffmpegInput.urls?.[0] : i);
|
||||
}
|
||||
}
|
||||
const args = [...ffmpegInput.inputArguments];
|
||||
const args = ffmpegInput.inputArguments ? [...ffmpegInput.inputArguments] : [];
|
||||
if (ffmpegInput.h264FilterArguments)
|
||||
args.push(...ffmpegInput.h264FilterArguments);
|
||||
console.log('ffplay', ...args);
|
||||
|
||||
@@ -90,7 +90,13 @@ export async function installServe(installVersion: string, ignoreError?: boolean
|
||||
const installJson = path.join(installDir, 'install.json');
|
||||
try {
|
||||
const { version } = JSON.parse(fs.readFileSync(installJson).toString());
|
||||
if (semver.parse(process.version).major !== semver.parse(version).major)
|
||||
const processSemver = semver.parse(process.version);
|
||||
if (!processSemver)
|
||||
throw new Error('error parsing process version');
|
||||
const installSemver = semver.parse(version);
|
||||
if (!installSemver)
|
||||
throw new Error('error parsing install.json version');
|
||||
if (processSemver.major !== installSemver.major)
|
||||
throw new Error('mismatch');
|
||||
}
|
||||
catch (e) {
|
||||
@@ -111,16 +117,32 @@ export async function installServe(installVersion: string, ignoreError?: boolean
|
||||
}
|
||||
|
||||
export async function serveMain(installVersion?: string) {
|
||||
let install = !!installVersion;
|
||||
const options = ((): { install: true; version: string } | { install: false } => {
|
||||
if (installVersion) {
|
||||
console.log(`Installing @scrypted/server@${installVersion}`);
|
||||
return {
|
||||
install: true,
|
||||
version: installVersion
|
||||
};
|
||||
}
|
||||
|
||||
if (!fs.existsSync('node_modules/@scrypted/server')) {
|
||||
console.log('Package @scrypted/server not found. Installing.');
|
||||
return {
|
||||
install: true,
|
||||
version: 'latest',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
install: false,
|
||||
}
|
||||
})();
|
||||
|
||||
const { installDir, volume } = cwdInstallDir();
|
||||
if (!fs.existsSync('node_modules/@scrypted/server')) {
|
||||
install = true;
|
||||
installVersion ||= 'latest';
|
||||
console.log('Package @scrypted/server not found. Installing.');
|
||||
}
|
||||
if (install) {
|
||||
await installServe(installVersion, true);
|
||||
|
||||
if (options.install) {
|
||||
await installServe(options.version, true);
|
||||
}
|
||||
|
||||
// todo: remove at some point after core lxc updater rolls out.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"inlineSources": true,
|
||||
"declaration": true,
|
||||
"moduleResolution": "Node16",
|
||||
"strict": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
|
||||
4
plugins/core/package-lock.json
generated
4
plugins/core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.3.25",
|
||||
"version": "0.3.26",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.3.25",
|
||||
"version": "0.3.26",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.3.25",
|
||||
"version": "0.3.26",
|
||||
"description": "Scrypted Core plugin. Provides the UI, websocket, and engine.io APIs.",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -161,10 +161,10 @@ export default {
|
||||
let t = ``;
|
||||
let toffset = 0;
|
||||
if (detection.score && detection.className !== 'motion') {
|
||||
t += `<tspan x='${x}' dy='${toffset}em'>${Math.round(detection.score * 100) / 100}</tspan>`
|
||||
t += `<tspan x='${x}' dy='${toffset}em'>${Math.round((detection.labelScore || detection.score) * 100) / 100}</tspan>`
|
||||
toffset -= 1.2;
|
||||
}
|
||||
const tname = detection.className + (detection.id ? `: ${detection.id}` : '')
|
||||
const tname = (detection.label || detection.className) + (detection.id ? `: ${detection.id}` : '')
|
||||
t += `<tspan x='${x}' dy='${toffset}em'>${tname}</tspan>`
|
||||
|
||||
const fs = 20;
|
||||
|
||||
4
plugins/coreml/package-lock.json
generated
4
plugins/coreml/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/coreml",
|
||||
"version": "0.1.53",
|
||||
"version": "0.1.57",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/coreml",
|
||||
"version": "0.1.53",
|
||||
"version": "0.1.57",
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"version": "0.1.53"
|
||||
"version": "0.1.57"
|
||||
}
|
||||
|
||||
@@ -26,17 +26,14 @@ predictExecutor = concurrent.futures.ThreadPoolExecutor(1, "CoreML-Predict")
|
||||
|
||||
availableModels = [
|
||||
"Default",
|
||||
"scrypted_yolov10m_320",
|
||||
"scrypted_yolov10n_320",
|
||||
"scrypted_yolov10n",
|
||||
"scrypted_yolo_nas_s_320",
|
||||
"scrypted_yolov9e_320",
|
||||
"scrypted_yolov9c_320",
|
||||
"scrypted_yolov9c",
|
||||
"scrypted_yolov6n_320",
|
||||
"scrypted_yolov6n",
|
||||
"scrypted_yolov6s_320",
|
||||
"scrypted_yolov6s",
|
||||
"scrypted_yolov8n_320",
|
||||
"scrypted_yolov8n",
|
||||
"ssdlite_mobilenet_v2",
|
||||
"yolov4-tiny",
|
||||
]
|
||||
@@ -80,7 +77,7 @@ class CoreMLPlugin(PredictPlugin, scrypted_sdk.Settings, scrypted_sdk.DeviceProv
|
||||
self.storage.setItem("model", "Default")
|
||||
model = "scrypted_yolov9c_320"
|
||||
self.yolo = "yolo" in model
|
||||
self.scrypted_yolov10n = "scrypted_yolov10n" in model
|
||||
self.scrypted_yolov10n = "scrypted_yolov10" in model
|
||||
self.scrypted_yolo_nas = "scrypted_yolo_nas" in model
|
||||
self.scrypted_yolo = "scrypted_yolo" in model
|
||||
self.scrypted_model = "scrypted" in model
|
||||
|
||||
@@ -1 +1 @@
|
||||
opencv-python
|
||||
opencv-python==4.9.0.80
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
# 2024-04-23 - modify timestamp to force pip reinstall
|
||||
coremltools==7.1
|
||||
Pillow>=5.4.1
|
||||
|
||||
4
plugins/onnx/package-lock.json
generated
4
plugins/onnx/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/openvino",
|
||||
"version": "0.1.92",
|
||||
"version": "0.1.95",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/openvino",
|
||||
"version": "0.1.92",
|
||||
"version": "0.1.95",
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"version": "0.1.92"
|
||||
"version": "0.1.95"
|
||||
}
|
||||
|
||||
@@ -29,17 +29,13 @@ except:
|
||||
|
||||
availableModels = [
|
||||
"Default",
|
||||
"scrypted_yolov10m_320",
|
||||
"scrypted_yolov10n_320",
|
||||
"scrypted_yolov10n",
|
||||
"scrypted_yolo_nas_s_320",
|
||||
"scrypted_yolov6n_320",
|
||||
"scrypted_yolov6n",
|
||||
"scrypted_yolov6s_320",
|
||||
"scrypted_yolov6s",
|
||||
"scrypted_yolov9c_320",
|
||||
"scrypted_yolov9c",
|
||||
"scrypted_yolov8n_320",
|
||||
"scrypted_yolov8n",
|
||||
]
|
||||
|
||||
def parse_labels(names):
|
||||
@@ -59,7 +55,7 @@ class ONNXPlugin(
|
||||
if model == "Default" or model not in availableModels:
|
||||
if model != "Default":
|
||||
self.storage.setItem("model", "Default")
|
||||
model = "scrypted_yolov8n_320"
|
||||
model = "scrypted_yolov10m_320"
|
||||
self.yolo = "yolo" in model
|
||||
self.scrypted_yolov10 = "scrypted_yolov10" in model
|
||||
self.scrypted_yolo_nas = "scrypted_yolo_nas" in model
|
||||
@@ -72,7 +68,7 @@ class ONNXPlugin(
|
||||
|
||||
model_version = "v2"
|
||||
onnxfile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/onnx-models/main/{model}/{onnxmodel}.onnx",
|
||||
f"https://github.com/koush/onnx-models/raw/main/{model}/{onnxmodel}.onnx",
|
||||
f"{model_version}/{model}/{onnxmodel}.onnx",
|
||||
)
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class ONNXFaceRecognition(FaceRecognizeDetection):
|
||||
onnxmodel = "best" if "scrypted" in model else model
|
||||
model_version = "v1"
|
||||
onnxfile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/onnx-models/main/{model}/{onnxmodel}.onnx",
|
||||
f"https://github.com/koush/onnx-models/raw/main/{model}/{onnxmodel}.onnx",
|
||||
f"{model_version}/{model}/{onnxmodel}.onnx",
|
||||
)
|
||||
print(onnxfile)
|
||||
|
||||
@@ -23,7 +23,7 @@ class ONNXTextRecognition(TextRecognition):
|
||||
onnxmodel = model
|
||||
model_version = "v3"
|
||||
onnxfile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/onnx-models/main/{model}/{onnxmodel}.onnx",
|
||||
f"https://github.com/koush/onnx-models/raw/main/{model}/{onnxmodel}.onnx",
|
||||
f"{model_version}/{model}/{onnxmodel}.onnx",
|
||||
)
|
||||
print(onnxfile)
|
||||
|
||||
@@ -1 +1 @@
|
||||
opencv-python
|
||||
opencv-python==4.9.0.80
|
||||
|
||||
4
plugins/openvino/package-lock.json
generated
4
plugins/openvino/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/openvino",
|
||||
"version": "0.1.88",
|
||||
"version": "0.1.96",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/openvino",
|
||||
"version": "0.1.88",
|
||||
"version": "0.1.96",
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"version": "0.1.88"
|
||||
"version": "0.1.96"
|
||||
}
|
||||
|
||||
@@ -30,17 +30,14 @@ prepareExecutor = concurrent.futures.ThreadPoolExecutor(1, "OpenVINO-Prepare")
|
||||
|
||||
availableModels = [
|
||||
"Default",
|
||||
"scrypted_yolov10m_320",
|
||||
"scrypted_yolov10s_320",
|
||||
"scrypted_yolov10n_320",
|
||||
"scrypted_yolov10n",
|
||||
"scrypted_yolo_nas_s_320",
|
||||
"scrypted_yolov6n_320",
|
||||
"scrypted_yolov6n",
|
||||
"scrypted_yolov6s_320",
|
||||
"scrypted_yolov6s",
|
||||
"scrypted_yolov9c_320",
|
||||
"scrypted_yolov9c",
|
||||
"scrypted_yolov8n_320",
|
||||
"scrypted_yolov8n",
|
||||
"ssd_mobilenet_v1_coco",
|
||||
"ssdlite_mobilenet_v2",
|
||||
"yolo-v3-tiny-tf",
|
||||
@@ -138,7 +135,7 @@ class OpenVINOPlugin(
|
||||
if model == "Default" or model not in availableModels:
|
||||
if model != "Default":
|
||||
self.storage.setItem("model", "Default")
|
||||
model = "scrypted_yolov8n_320"
|
||||
model = "scrypted_yolov10n_320"
|
||||
self.yolo = "yolo" in model
|
||||
self.scrypted_yolov10 = "scrypted_yolov10" in model
|
||||
self.scrypted_yolo_nas = "scrypted_yolo_nas" in model
|
||||
@@ -152,31 +149,31 @@ class OpenVINOPlugin(
|
||||
|
||||
model_version = "v5"
|
||||
xmlFile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/openvino-models/main/{model}/{precision}/{ovmodel}.xml",
|
||||
f"https://github.com/koush/openvino-models/raw/main/{model}/{precision}/{ovmodel}.xml",
|
||||
f"{model_version}/{model}/{precision}/{ovmodel}.xml",
|
||||
)
|
||||
binFile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/openvino-models/main/{model}/{precision}/{ovmodel}.bin",
|
||||
f"https://github.com/koush/openvino-models/raw/main/{model}/{precision}/{ovmodel}.bin",
|
||||
f"{model_version}/{model}/{precision}/{ovmodel}.bin",
|
||||
)
|
||||
if self.scrypted_yolo_nas:
|
||||
labelsFile = self.downloadFile(
|
||||
"https://raw.githubusercontent.com/koush/openvino-models/main/scrypted_nas_labels.txt",
|
||||
"https://github.com/koush/openvino-models/raw/main/scrypted_nas_labels.txt",
|
||||
"scrypted_nas_labels.txt",
|
||||
)
|
||||
elif self.scrypted_model:
|
||||
labelsFile = self.downloadFile(
|
||||
"https://raw.githubusercontent.com/koush/openvino-models/main/scrypted_labels.txt",
|
||||
"https://github.com/koush/openvino-models/raw/main/scrypted_labels.txt",
|
||||
"scrypted_labels.txt",
|
||||
)
|
||||
elif self.yolo:
|
||||
labelsFile = self.downloadFile(
|
||||
"https://raw.githubusercontent.com/koush/openvino-models/main/coco_80cl.txt",
|
||||
"https://github.com/koush/openvino-models/raw/main/coco_80cl.txt",
|
||||
"coco_80cl.txt",
|
||||
)
|
||||
else:
|
||||
labelsFile = self.downloadFile(
|
||||
"https://raw.githubusercontent.com/koush/openvino-models/main/coco_labels.txt",
|
||||
"https://github.com/koush/openvino-models/raw/main/coco_labels.txt",
|
||||
"coco_labels.txt",
|
||||
)
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@ class OpenVINOFaceRecognition(FaceRecognizeDetection):
|
||||
precision = self.plugin.precision
|
||||
model_version = "v5"
|
||||
xmlFile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/openvino-models/main/{model}/{precision}/{ovmodel}.xml",
|
||||
f"https://github.com/koush/openvino-models/raw/main/{model}/{precision}/{ovmodel}.xml",
|
||||
f"{model_version}/{model}/{precision}/{ovmodel}.xml",
|
||||
)
|
||||
binFile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/openvino-models/main/{model}/{precision}/{ovmodel}.bin",
|
||||
f"https://github.com/koush/openvino-models/raw/main/{model}/{precision}/{ovmodel}.bin",
|
||||
f"{model_version}/{model}/{precision}/{ovmodel}.bin",
|
||||
)
|
||||
print(xmlFile, binFile)
|
||||
|
||||
@@ -25,11 +25,11 @@ class OpenVINOTextRecognition(TextRecognition):
|
||||
precision = self.plugin.precision
|
||||
model_version = "v5"
|
||||
xmlFile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/openvino-models/main/{model}/{precision}/{ovmodel}.xml",
|
||||
f"https://github.com/koush/openvino-models/raw/main/{model}/{precision}/{ovmodel}.xml",
|
||||
f"{model_version}/{model}/{precision}/{ovmodel}.xml",
|
||||
)
|
||||
binFile = self.downloadFile(
|
||||
f"https://raw.githubusercontent.com/koush/openvino-models/main/{model}/{precision}/{ovmodel}.bin",
|
||||
f"https://github.com/koush/openvino-models/raw/main/{model}/{precision}/{ovmodel}.bin",
|
||||
f"{model_version}/{model}/{precision}/{ovmodel}.bin",
|
||||
)
|
||||
print(xmlFile, binFile)
|
||||
|
||||
@@ -1 +1 @@
|
||||
opencv-python
|
||||
opencv-python==4.9.0.80
|
||||
|
||||
@@ -38,6 +38,7 @@ def getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text,
|
||||
nLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(text_score_comb.astype(np.uint8), connectivity=4)
|
||||
|
||||
det = []
|
||||
scores = []
|
||||
mapper = []
|
||||
for k in range(1,nLabels):
|
||||
# size filtering
|
||||
@@ -45,7 +46,8 @@ def getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text,
|
||||
if size < 10: continue
|
||||
|
||||
# thresholding
|
||||
if np.max(textmap[labels==k]) < text_threshold: continue
|
||||
score = np.max(textmap[labels==k])
|
||||
if score < text_threshold: continue
|
||||
|
||||
# make segmentation map
|
||||
segmap = np.zeros(textmap.shape, dtype=np.uint8)
|
||||
@@ -89,8 +91,9 @@ def getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text,
|
||||
box = np.array(box)
|
||||
|
||||
det.append(box)
|
||||
scores.append(score)
|
||||
|
||||
return det, labels, mapper
|
||||
return det, labels, mapper, scores
|
||||
|
||||
def getPoly_core(boxes, labels, mapper, linkmap):
|
||||
# configs
|
||||
@@ -241,14 +244,14 @@ def getPoly_core(boxes, labels, mapper, linkmap):
|
||||
def getDetBoxes(textmap, linkmap, text_threshold, link_threshold, low_text, poly=False, estimate_num_chars=False):
|
||||
if poly and estimate_num_chars:
|
||||
raise Exception("Estimating the number of characters not currently supported with poly.")
|
||||
boxes, labels, mapper = getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text, estimate_num_chars)
|
||||
boxes, labels, mapper, scores = getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text, estimate_num_chars)
|
||||
|
||||
if poly:
|
||||
polys = getPoly_core(boxes, labels, mapper, linkmap)
|
||||
else:
|
||||
polys = [None] * len(boxes)
|
||||
|
||||
return boxes, polys, mapper
|
||||
return boxes, polys, mapper, scores
|
||||
|
||||
def adjustResultCoordinates(polys, ratio_w, ratio_h, ratio_net = 2):
|
||||
if len(polys) > 0:
|
||||
|
||||
@@ -20,18 +20,16 @@ class FaceRecognizeDetection(PredictPlugin):
|
||||
def __init__(self, nativeId: str | None = None):
|
||||
super().__init__(nativeId=nativeId)
|
||||
|
||||
self.inputheight = 320
|
||||
self.inputwidth = 320
|
||||
self.inputheight = 640
|
||||
self.inputwidth = 640
|
||||
|
||||
self.labels = {
|
||||
0: "face",
|
||||
1: "plate",
|
||||
2: "text",
|
||||
}
|
||||
self.loop = asyncio.get_event_loop()
|
||||
self.minThreshold = 0.7
|
||||
self.minThreshold = 0.2
|
||||
|
||||
self.detectModel = self.downloadModel("scrypted_yolov8n_flt_320")
|
||||
self.detectModel = self.downloadModel("scrypted_yolov10n_face")
|
||||
self.faceModel = self.downloadModel("inception_resnet_v1")
|
||||
|
||||
def downloadModel(self, model: str):
|
||||
@@ -49,7 +47,7 @@ class FaceRecognizeDetection(PredictPlugin):
|
||||
|
||||
async def detect_once(self, input: Image.Image, settings: Any, src_size, cvss):
|
||||
results = await self.predictDetectModel(input)
|
||||
objs = yolo.parse_yolov9(results)
|
||||
objs = yolo.parse_yolov10(results)
|
||||
ret = self.create_detection_result(objs, src_size, cvss)
|
||||
return ret
|
||||
|
||||
|
||||
@@ -65,14 +65,14 @@ class TextRecognition(PredictPlugin):
|
||||
low_text = 0.4
|
||||
poly = False
|
||||
|
||||
boxes_list, polys_list = [], []
|
||||
boxes_list, polys_list, scores_list = [], [], []
|
||||
for out in y:
|
||||
# make score and link map
|
||||
score_text = out[:, :, 0]
|
||||
score_link = out[:, :, 1]
|
||||
|
||||
# Post-processing
|
||||
boxes, polys, mapper = getDetBoxes(
|
||||
boxes, polys, mapper, scores = getDetBoxes(
|
||||
score_text,
|
||||
score_link,
|
||||
text_threshold,
|
||||
@@ -96,18 +96,19 @@ class TextRecognition(PredictPlugin):
|
||||
if polys[k] is None:
|
||||
polys[k] = boxes[k]
|
||||
boxes_list.append(boxes)
|
||||
scores_list.append(scores)
|
||||
polys_list.append(polys)
|
||||
|
||||
preds: List[Prediction] = []
|
||||
for boxes in boxes_list:
|
||||
for box in boxes:
|
||||
for boxes, scores in zip(boxes_list, scores_list):
|
||||
for box, score in zip(boxes, scores):
|
||||
tl, tr, br, bl = box
|
||||
l = min(tl[0], bl[0])
|
||||
t = min(tl[1], tr[1])
|
||||
r = max(tr[0], br[0])
|
||||
b = max(bl[1], br[1])
|
||||
|
||||
pred = Prediction(0, 1, Rectangle(l, t, r, b))
|
||||
pred = Prediction(0, float(score), Rectangle(l, t, r, b))
|
||||
preds.append(pred)
|
||||
|
||||
return self.create_detection_result(preds, src_size, cvss)
|
||||
@@ -121,18 +122,19 @@ class TextRecognition(PredictPlugin):
|
||||
|
||||
futures: List[Future] = []
|
||||
|
||||
boundingBoxes = [d["boundingBox"] for d in detections]
|
||||
boundingBoxes, scores = [d["boundingBox"] for d in detections], [d["score"] for d in detections]
|
||||
if not len(boundingBoxes):
|
||||
return ret
|
||||
|
||||
text_groups = find_adjacent_groups(boundingBoxes)
|
||||
text_groups = find_adjacent_groups(boundingBoxes, scores)
|
||||
|
||||
detections = []
|
||||
for group in text_groups:
|
||||
boundingBox = group["union"]
|
||||
score = group["score"]
|
||||
d: ObjectDetectionResult = {
|
||||
"boundingBox": boundingBox,
|
||||
"score": 1,
|
||||
"score": score,
|
||||
"className": "text",
|
||||
}
|
||||
futures.append(
|
||||
|
||||
@@ -43,30 +43,31 @@ def are_boxes_adjacent(box1: BoundingBox, box2: BoundingBox):
|
||||
return False
|
||||
|
||||
|
||||
def find_adjacent_groups(boxes: List[BoundingBox]) -> List[dict]:
|
||||
def find_adjacent_groups(boxes: List[BoundingBox], scores: List[float]) -> List[dict]:
|
||||
groups = []
|
||||
|
||||
# sort boxes left to right
|
||||
boxes = sorted(boxes, key=lambda box: box[0])
|
||||
|
||||
for box in boxes:
|
||||
for index, box in enumerate(boxes):
|
||||
added_to_group = False
|
||||
for group in groups:
|
||||
for other_box in group["boxes"]:
|
||||
if are_boxes_adjacent(box, other_box):
|
||||
group["boxes"].append(box)
|
||||
group["scores"].append(scores[index])
|
||||
added_to_group = True
|
||||
break
|
||||
if added_to_group:
|
||||
break
|
||||
if not added_to_group:
|
||||
groups.append({"boxes": [box], "skew_angle": 0})
|
||||
groups.append({"boxes": [box], "scores": [scores[index]], "skew_angle": 0})
|
||||
|
||||
# Calculate the skew angle of each group
|
||||
for group in groups:
|
||||
boxes = group["boxes"]
|
||||
group["union"] = union_boxes(boxes)
|
||||
if len(boxes) -1 :
|
||||
if len(boxes) - 1:
|
||||
lm = (boxes[0][1] + boxes[0][3]) / 2
|
||||
rm = (boxes[-1][1] + boxes[-1][3]) / 2
|
||||
dx = (boxes[-1][0]) - (boxes[0][0] + boxes[0][2])
|
||||
@@ -78,7 +79,10 @@ def find_adjacent_groups(boxes: List[BoundingBox]) -> List[dict]:
|
||||
group['skew_angle'] = math.atan2(rm - lm, dx) * 2
|
||||
# pad this box by a few pixels
|
||||
group['union'] = (group['union'][0] - pad_height, group['union'][1] - pad_height, group['union'][2] + pad_height * 2, group['union'][3] + pad_height * 2)
|
||||
# average the scores
|
||||
group['score'] = sum(group['scores']) / len(group['scores'])
|
||||
else:
|
||||
group['skew_angle'] = 0
|
||||
group['score'] = group['scores'][0]
|
||||
|
||||
return groups
|
||||
|
||||
26
plugins/unifi-protect/package-lock.json
generated
26
plugins/unifi-protect/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/unifi-protect",
|
||||
"version": "0.0.146",
|
||||
"version": "0.0.149",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/unifi-protect",
|
||||
"version": "0.0.146",
|
||||
"version": "0.0.149",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@koush/unifi-protect": "file:../../external/unifi-protect",
|
||||
@@ -27,12 +27,12 @@
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"http-auth-utils": "^3.0.2",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"typescript": "^4.4.3"
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.9.0"
|
||||
"@types/node": "^20.11.0",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../../external/unifi-protect": {
|
||||
@@ -61,12 +61,12 @@
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.2.103",
|
||||
"version": "0.3.31",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"axios": "^1.6.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
@@ -260,10 +260,10 @@
|
||||
"requires": {
|
||||
"@scrypted/sdk": "file:../sdk",
|
||||
"@scrypted/server": "file:../server",
|
||||
"@types/node": "^16.9.0",
|
||||
"http-auth-utils": "^3.0.2",
|
||||
"node-fetch-commonjs": "^3.1.1",
|
||||
"typescript": "^4.4.3"
|
||||
"@types/node": "^20.11.0",
|
||||
"http-auth-utils": "^5.0.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
},
|
||||
"@scrypted/sdk": {
|
||||
@@ -273,7 +273,7 @@
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"axios": "^1.6.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.15.9",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/unifi-protect",
|
||||
"version": "0.0.146",
|
||||
"version": "0.0.149",
|
||||
"description": "Unifi Protect Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
|
||||
@@ -157,10 +157,11 @@ export class UnifiProtect extends ScryptedDeviceBase implements Settings, Device
|
||||
const payload = updatePacket.payload as ProtectNvrUpdatePayloadEventAdd;
|
||||
if (!payload.camera)
|
||||
return;
|
||||
const unifiCamera = this.cameras.get(payload.camera);
|
||||
const nativeId = this.getNativeId({ id: payload.camera }, false);
|
||||
const unifiCamera = this.cameras.get(nativeId);
|
||||
|
||||
if (!unifiCamera) {
|
||||
this.console.log('unknown device event, sync needed?', payload.camera);
|
||||
this.console.log('unknown device event, sync needed?', payload);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,7 +196,7 @@ export class UnifiProtect extends ScryptedDeviceBase implements Settings, Device
|
||||
// id: '661d86bf03e69c03e408d62a',
|
||||
// modelKey: 'event'
|
||||
// }
|
||||
|
||||
|
||||
if (payload.type === 'smartDetectZone' || payload.type === 'smartDetectLine') {
|
||||
unifiCamera.resetDetectionTimeout();
|
||||
|
||||
@@ -602,7 +603,7 @@ export class UnifiProtect extends ScryptedDeviceBase implements Settings, Device
|
||||
return this.storageSettings.values.idMaps.nativeId?.[nativeId] || nativeId;
|
||||
}
|
||||
|
||||
getNativeId(device: any, update: boolean) {
|
||||
getNativeId(device: { id?: string, mac?: string; anonymousDeviceId?: string }, update: boolean) {
|
||||
const { id, mac, anonymousDeviceId } = device;
|
||||
const idMaps = this.storageSettings.values.idMaps;
|
||||
|
||||
|
||||
253
server/package-lock.json
generated
253
server/package-lock.json
generated
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"name": "@scrypted/server",
|
||||
"version": "0.105.0",
|
||||
"version": "0.110.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/server",
|
||||
"version": "0.105.0",
|
||||
"version": "0.110.4",
|
||||
"hasInstallScript": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
"@scrypted/ffmpeg-static": "^6.1.0-build1",
|
||||
"@scrypted/node-pty": "^1.0.10",
|
||||
"@scrypted/types": "^0.3.28",
|
||||
"adm-zip": "^0.5.12",
|
||||
"@scrypted/node-pty": "^1.0.14",
|
||||
"@scrypted/types": "^0.3.30",
|
||||
"adm-zip": "^0.5.14",
|
||||
"body-parser": "^1.20.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"dotenv": "^16.4.5",
|
||||
@@ -29,13 +29,13 @@
|
||||
"node-dijkstra": "^2.5.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-gyp": "^10.1.0",
|
||||
"py": "npm:@bjia56/portable-python@^0.1.31",
|
||||
"py": "npm:@bjia56/portable-python@^0.1.51",
|
||||
"router": "^1.3.8",
|
||||
"semver": "^7.6.2",
|
||||
"sharp": "^0.33.3",
|
||||
"sharp": "^0.33.4",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tar": "^7.1.0",
|
||||
"tslib": "^2.6.2",
|
||||
"tar": "^7.2.0",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.4.5",
|
||||
"whatwg-mimetype": "^4.0.0",
|
||||
"ws": "^8.17.0"
|
||||
@@ -50,7 +50,7 @@
|
||||
"@types/follow-redirects": "^1.14.4",
|
||||
"@types/http-auth": "^4.1.4",
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/lodash": "^4.17.1",
|
||||
"@types/lodash": "^4.17.4",
|
||||
"@types/node-dijkstra": "^2.5.6",
|
||||
"@types/node-forge": "^1.3.11",
|
||||
"@types/semver": "^7.5.8",
|
||||
@@ -60,18 +60,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.1.1.tgz",
|
||||
"integrity": "sha512-3bfqkzuR1KLx57nZfjr2NLnFOobvyS0aTszaEGCGqmYMVDRaGvgIZbjGSV/MHSSmLgQ/b9JFHQ5xm5WRZYd+XQ==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz",
|
||||
"integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-arm64": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.3.tgz",
|
||||
"integrity": "sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz",
|
||||
"integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -94,9 +94,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-x64": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.3.tgz",
|
||||
"integrity": "sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -287,9 +287,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.3.tgz",
|
||||
"integrity": "sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz",
|
||||
"integrity": "sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -312,9 +312,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm64": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.3.tgz",
|
||||
"integrity": "sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz",
|
||||
"integrity": "sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -337,9 +337,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-s390x": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.3.tgz",
|
||||
"integrity": "sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz",
|
||||
"integrity": "sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -348,7 +348,7 @@
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.28",
|
||||
"glibc": ">=2.31",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
@@ -362,9 +362,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-x64": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.3.tgz",
|
||||
"integrity": "sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -387,9 +387,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-arm64": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.3.tgz",
|
||||
"integrity": "sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz",
|
||||
"integrity": "sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -412,9 +412,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-x64": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.3.tgz",
|
||||
"integrity": "sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -437,15 +437,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-wasm32": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.3.tgz",
|
||||
"integrity": "sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz",
|
||||
"integrity": "sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/runtime": "^1.1.0"
|
||||
"@emnapi/runtime": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
@@ -458,9 +458,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-ia32": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.3.tgz",
|
||||
"integrity": "sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz",
|
||||
"integrity": "sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -479,9 +479,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-x64": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.3.tgz",
|
||||
"integrity": "sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -702,18 +702,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/node-pty": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/node-pty/-/node-pty-1.0.10.tgz",
|
||||
"integrity": "sha512-JmcfpDyRuQ5UCCYaG4aaoH7BPfJuc4HzMimYBZOCwy8cmryfHj9vssp6x3XLDoc5WQS/Yp7Uil+qSMdWzAIM6w==",
|
||||
"version": "1.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/node-pty/-/node-pty-1.0.14.tgz",
|
||||
"integrity": "sha512-jqWXmvEgK1TH9GDod2mLYcL97sC5mw4+YdMz0EzCvdz4QyILHNTVyB98cfWdfPz33mZC0YOASh9BFrGk3cBzaA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"prebuild-install": "^7.1.2"
|
||||
"prebuild-install": "npm:@scrypted/prebuild-install@^7.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/types": {
|
||||
"version": "0.3.28",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.3.28.tgz",
|
||||
"integrity": "sha512-58oF+fIAG6cwxIBvciwHu7cbENxa8y0fwN4IuhhC+JRq3Xqun8TnWDjKOLmah5gfdqfaI3wHTLuZWuOwOEJC5A=="
|
||||
"version": "0.3.30",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.3.30.tgz",
|
||||
"integrity": "sha512-1k+JVSR6WSNmE/5mLdqfrTmV3uRbvZp0OwKb8ikNi39ysBuC000tQGcEdXZqhYqRgWdhDTWtxXe9XsYoAZGKmA=="
|
||||
},
|
||||
"node_modules/@types/adm-zip": {
|
||||
"version": "0.5.5",
|
||||
@@ -817,9 +817,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.1.tgz",
|
||||
"integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==",
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
@@ -951,11 +951,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/adm-zip": {
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.12.tgz",
|
||||
"integrity": "sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ==",
|
||||
"version": "0.5.14",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.14.tgz",
|
||||
"integrity": "sha512-DnyqqifT4Jrcvb8USYjp6FHtBpEIz1mnXu6pTRHZ0RL69LbQYiO+0lDFg5+OKA7U29oWSs3a/i8fhn8ZcceIWg==",
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
"node": ">=12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
@@ -1555,20 +1555,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"dependencies": {
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
@@ -2392,17 +2378,6 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
@@ -2613,9 +2588,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.56.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz",
|
||||
"integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==",
|
||||
"version": "3.63.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.63.0.tgz",
|
||||
"integrity": "sha512-vAszCsOUrUxjGAmdnM/pq7gUgie0IRteCQMX6d4A534fQCR93EJU5qgzBvU6EkFfK27s0T3HEV3BOyJIr7OMYw==",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
@@ -2915,12 +2890,14 @@
|
||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz",
|
||||
"integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==",
|
||||
"name": "@scrypted/prebuild-install",
|
||||
"version": "7.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/prebuild-install/-/prebuild-install-7.1.8.tgz",
|
||||
"integrity": "sha512-ghmvo7gRUUyTUtjBGEcZfL7fizBNdzFFLnMRiNh3+lL25t8Rjv4EDBEKmDT6C4/wKVfdtzAnITBBc9r9DhVqRg==",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.0",
|
||||
"expand-template": "^2.0.3",
|
||||
"follow-redirects": "^1.15.6",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
@@ -2928,7 +2905,6 @@
|
||||
"node-abi": "^3.3.0",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^4.0.0",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
@@ -2982,9 +2958,9 @@
|
||||
},
|
||||
"node_modules/py": {
|
||||
"name": "@bjia56/portable-python",
|
||||
"version": "0.1.31",
|
||||
"resolved": "https://registry.npmjs.org/@bjia56/portable-python/-/portable-python-0.1.31.tgz",
|
||||
"integrity": "sha512-dgJUIWz7pY/IYzrMhyWBuSpUE+pYyL/DomlaOS69tH/YJ4blAA73ORTu3mt6zB5IrgcxABECD6y9DZ5PwN+KtQ==",
|
||||
"version": "0.1.51",
|
||||
"resolved": "https://registry.npmjs.org/@bjia56/portable-python/-/portable-python-0.1.51.tgz",
|
||||
"integrity": "sha512-Ug+TBsoD+H0/jknw0lZ0oxGEPwQPCk5B6TEyX24QM2mX9w1FHhD0oNbhW3biRw31KjWK0uyJux01tcaRUpUtRQ==",
|
||||
"dependencies": {
|
||||
"adm-zip": "^0.5.10"
|
||||
}
|
||||
@@ -3262,9 +3238,9 @@
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
},
|
||||
"node_modules/sharp": {
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.3.tgz",
|
||||
"integrity": "sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==",
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz",
|
||||
"integrity": "sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"color": "^4.2.3",
|
||||
@@ -3279,8 +3255,8 @@
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "0.33.3",
|
||||
"@img/sharp-darwin-x64": "0.33.3",
|
||||
"@img/sharp-darwin-arm64": "0.33.4",
|
||||
"@img/sharp-darwin-x64": "0.33.4",
|
||||
"@img/sharp-libvips-darwin-arm64": "1.0.2",
|
||||
"@img/sharp-libvips-darwin-x64": "1.0.2",
|
||||
"@img/sharp-libvips-linux-arm": "1.0.2",
|
||||
@@ -3289,15 +3265,15 @@
|
||||
"@img/sharp-libvips-linux-x64": "1.0.2",
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.0.2",
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.0.2",
|
||||
"@img/sharp-linux-arm": "0.33.3",
|
||||
"@img/sharp-linux-arm64": "0.33.3",
|
||||
"@img/sharp-linux-s390x": "0.33.3",
|
||||
"@img/sharp-linux-x64": "0.33.3",
|
||||
"@img/sharp-linuxmusl-arm64": "0.33.3",
|
||||
"@img/sharp-linuxmusl-x64": "0.33.3",
|
||||
"@img/sharp-wasm32": "0.33.3",
|
||||
"@img/sharp-win32-ia32": "0.33.3",
|
||||
"@img/sharp-win32-x64": "0.33.3"
|
||||
"@img/sharp-linux-arm": "0.33.4",
|
||||
"@img/sharp-linux-arm64": "0.33.4",
|
||||
"@img/sharp-linux-s390x": "0.33.4",
|
||||
"@img/sharp-linux-x64": "0.33.4",
|
||||
"@img/sharp-linuxmusl-arm64": "0.33.4",
|
||||
"@img/sharp-linuxmusl-x64": "0.33.4",
|
||||
"@img/sharp-wasm32": "0.33.4",
|
||||
"@img/sharp-win32-ia32": "0.33.4",
|
||||
"@img/sharp-win32-x64": "0.33.4"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
@@ -3337,49 +3313,6 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"node_modules/simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/simple-get": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
|
||||
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"decompress-response": "^6.0.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
@@ -3537,9 +3470,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.1.0.tgz",
|
||||
"integrity": "sha512-ENhg4W6BmjYxl8GTaE7/h99f0aXiSWv4kikRZ9n2/JRxypZniE84ILZqimAhxxX7Zb8Px6pFdheW3EeHfhnXQQ==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.2.0.tgz",
|
||||
"integrity": "sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==",
|
||||
"dependencies": {
|
||||
"@isaacs/fs-minipass": "^4.0.0",
|
||||
"chownr": "^3.0.0",
|
||||
@@ -3677,9 +3610,9 @@
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "@scrypted/server",
|
||||
"version": "0.106.0",
|
||||
"version": "0.110.5",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
"@scrypted/ffmpeg-static": "^6.1.0-build1",
|
||||
"@scrypted/node-pty": "^1.0.10",
|
||||
"@scrypted/types": "^0.3.28",
|
||||
"adm-zip": "^0.5.12",
|
||||
"@scrypted/node-pty": "^1.0.14",
|
||||
"@scrypted/types": "^0.3.30",
|
||||
"adm-zip": "^0.5.14",
|
||||
"body-parser": "^1.20.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"dotenv": "^16.4.5",
|
||||
@@ -22,13 +22,13 @@
|
||||
"node-dijkstra": "^2.5.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-gyp": "^10.1.0",
|
||||
"py": "npm:@bjia56/portable-python@^0.1.31",
|
||||
"py": "npm:@bjia56/portable-python@^0.1.51",
|
||||
"router": "^1.3.8",
|
||||
"semver": "^7.6.2",
|
||||
"sharp": "^0.33.3",
|
||||
"sharp": "^0.33.4",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tar": "^7.1.0",
|
||||
"tslib": "^2.6.2",
|
||||
"tar": "^7.2.0",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.4.5",
|
||||
"whatwg-mimetype": "^4.0.0",
|
||||
"ws": "^8.17.0"
|
||||
@@ -40,7 +40,7 @@
|
||||
"@types/follow-redirects": "^1.14.4",
|
||||
"@types/http-auth": "^4.1.4",
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/lodash": "^4.17.1",
|
||||
"@types/lodash": "^4.17.4",
|
||||
"@types/node-dijkstra": "^2.5.6",
|
||||
"@types/node-forge": "^1.3.11",
|
||||
"@types/semver": "^7.5.8",
|
||||
|
||||
@@ -41,7 +41,7 @@ const StreamParser: FetchParser<IncomingMessage> = {
|
||||
}
|
||||
}
|
||||
|
||||
export function getHttpFetchParser(responseType: HttpFetchResponseType) {
|
||||
export function getHttpFetchParser(responseType: HttpFetchResponseType | undefined) {
|
||||
switch (responseType) {
|
||||
case 'json':
|
||||
return JSONParser;
|
||||
@@ -53,7 +53,7 @@ export function getHttpFetchParser(responseType: HttpFetchResponseType) {
|
||||
return BufferParser;
|
||||
}
|
||||
|
||||
export function httpFetchParseIncomingMessage(readable: IncomingMessage, responseType: HttpFetchResponseType) {
|
||||
export function httpFetchParseIncomingMessage(readable: IncomingMessage, responseType: HttpFetchResponseType | undefined) {
|
||||
return getHttpFetchParser(responseType).parse(readable);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export type fetcher<B, M> = <T extends HttpFetchOptions<B>>(options: T) => Promi
|
||||
>>;
|
||||
|
||||
|
||||
export function getHttpFetchAccept(responseType: HttpFetchResponseType) {
|
||||
export function getHttpFetchAccept(responseType: HttpFetchResponseType | undefined) {
|
||||
switch (responseType) {
|
||||
case 'json':
|
||||
return 'application/json';
|
||||
@@ -89,7 +89,7 @@ export function setHeader(headers: [string, string][], key: string, value: strin
|
||||
headers.push([key, value]);
|
||||
}
|
||||
|
||||
export function setDefaultHttpFetchAccept(headers: [string, string][], responseType: HttpFetchResponseType) {
|
||||
export function setDefaultHttpFetchAccept(headers: [string, string][], responseType: HttpFetchResponseType | undefined) {
|
||||
if (hasHeader(headers, 'Accept'))
|
||||
return;
|
||||
const accept = getHttpFetchAccept(responseType);
|
||||
@@ -97,7 +97,7 @@ export function setDefaultHttpFetchAccept(headers: [string, string][], responseT
|
||||
setHeader(headers, 'Accept', accept);
|
||||
}
|
||||
|
||||
export function createHeadersArray(headers: HeadersInit): [string, string][] {
|
||||
export function createHeadersArray(headers: HeadersInit | undefined): [string, string][] {
|
||||
const headersArray: [string, string][] = [];
|
||||
if (!headers)
|
||||
return headersArray;
|
||||
@@ -144,7 +144,7 @@ export function createStringOrBufferBody(headers: [string, string][], body: any)
|
||||
return body;
|
||||
}
|
||||
|
||||
export async function domFetchParseIncomingMessage(response: Response, responseType: HttpFetchResponseType) {
|
||||
export async function domFetchParseIncomingMessage(response: Response, responseType: HttpFetchResponseType | undefined) {
|
||||
switch (responseType) {
|
||||
case 'json':
|
||||
return response.json();
|
||||
|
||||
@@ -13,7 +13,7 @@ export async function listenZero(server: net.Server, hostname?: string) {
|
||||
return (server.address() as net.AddressInfo).port;
|
||||
}
|
||||
|
||||
export async function listenZeroSingleClient(hostname?: string, options?: net.ServerOpts) {
|
||||
export async function listenZeroSingleClient(hostname?: string, options?: net.ServerOpts, listenTimeout = 30000) {
|
||||
const server = new net.Server(options);
|
||||
const port = await listenZero(server, hostname);
|
||||
|
||||
@@ -22,7 +22,7 @@ export async function listenZeroSingleClient(hostname?: string, options?: net.Se
|
||||
const timeout = setTimeout(() => {
|
||||
server.close();
|
||||
reject(new ListenZeroSingleClientTimeoutError());
|
||||
}, 30000);
|
||||
}, listenTimeout);
|
||||
cancel = () => {
|
||||
clearTimeout(timeout);
|
||||
server.close();
|
||||
|
||||
@@ -28,6 +28,12 @@ import { RuntimeWorker } from './runtime/runtime-worker';
|
||||
|
||||
const serverVersion = require('../../package.json').version;
|
||||
|
||||
export class UnsupportedRuntimeError extends Error {
|
||||
constructor(runtime: string) {
|
||||
super(`Unsupported runtime: ${runtime}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class PluginHost {
|
||||
worker: RuntimeWorker;
|
||||
peer: RpcPeer;
|
||||
@@ -281,7 +287,7 @@ export class PluginHost {
|
||||
|
||||
const workerHost = this.scrypted.pluginHosts.get(runtime);
|
||||
if (!workerHost)
|
||||
throw new Error(`Unsupported Scrypted runtime: ${this.packageJson.scrypted.runtime}`);
|
||||
throw new UnsupportedRuntimeError(this.packageJson.scrypted.runtime);
|
||||
|
||||
this.worker = workerHost(this.scrypted.mainFilename, this.pluginId, {
|
||||
packageJson: this.packageJson,
|
||||
|
||||
@@ -12,7 +12,6 @@ import net from 'net';
|
||||
import path from 'path';
|
||||
import { ParsedQs } from 'qs';
|
||||
import semver from 'semver';
|
||||
import { PassThrough } from 'stream';
|
||||
import { Parser as TarParser } from 'tar';
|
||||
import { URL } from "url";
|
||||
import WebSocket, { Server as WebSocketServer } from "ws";
|
||||
@@ -29,10 +28,11 @@ import { getMixins, hasMixinCycle } from './mixin/mixin-cycle';
|
||||
import { AccessControls } from './plugin/acl';
|
||||
import { PluginDebug } from './plugin/plugin-debug';
|
||||
import { PluginDeviceProxyHandler } from './plugin/plugin-device';
|
||||
import { PluginHost } from './plugin/plugin-host';
|
||||
import { PluginHost, UnsupportedRuntimeError } from './plugin/plugin-host';
|
||||
import { isConnectionUpgrade, PluginHttp } from './plugin/plugin-http';
|
||||
import { WebSocketConnection } from './plugin/plugin-remote-websocket';
|
||||
import { getPluginVolume } from './plugin/plugin-volume';
|
||||
import { CustomRuntimeWorker } from './plugin/runtime/custom-worker';
|
||||
import { NodeForkWorker } from './plugin/runtime/node-fork-worker';
|
||||
import { PythonRuntimeWorker } from './plugin/runtime/python-worker';
|
||||
import { RuntimeWorker, RuntimeWorkerOptions } from './plugin/runtime/runtime-worker';
|
||||
@@ -46,7 +46,6 @@ import { getNpmPackageInfo, PluginComponent } from './services/plugin';
|
||||
import { ServiceControl } from './services/service-control';
|
||||
import { UsersService } from './services/users';
|
||||
import { getState, ScryptedStateManager, setState } from './state';
|
||||
import { CustomRuntimeWorker } from './plugin/runtime/custom-worker';
|
||||
|
||||
interface DeviceProxyPair {
|
||||
handler: PluginDeviceProxyHandler;
|
||||
@@ -630,8 +629,8 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
|
||||
return this.runPlugin(plugin, pluginDebug);
|
||||
}
|
||||
|
||||
setupPluginHostAutoRestart(pluginHost: PluginHost) {
|
||||
const logger = this.getDeviceLogger(this.findPluginDevice(pluginHost.pluginId));
|
||||
setupPluginHostAutoRestart(pluginId: string, pluginHost?: PluginHost) {
|
||||
const logger = this.getDeviceLogger(this.findPluginDevice(pluginId));
|
||||
|
||||
let timeout: NodeJS.Timeout;
|
||||
|
||||
@@ -640,20 +639,20 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
|
||||
return;
|
||||
|
||||
const t = 60000;
|
||||
pluginHost.kill();
|
||||
logger.log('e', `plugin ${pluginHost.pluginId} unexpectedly exited, restarting in ${t}ms`);
|
||||
pluginHost?.kill();
|
||||
logger.log('e', `plugin ${pluginId} unexpectedly exited, restarting in ${t}ms`);
|
||||
|
||||
timeout = setTimeout(async () => {
|
||||
timeout = undefined;
|
||||
const plugin = await this.datastore.tryGet(Plugin, pluginHost.pluginId);
|
||||
const plugin = await this.datastore.tryGet(Plugin, pluginId);
|
||||
if (!plugin) {
|
||||
logger.log('w', `scheduled plugin restart cancelled, plugin no longer exists ${pluginHost.pluginId}`);
|
||||
logger.log('w', `scheduled plugin restart cancelled, plugin no longer exists ${pluginId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const existing = this.plugins[pluginHost.pluginId];
|
||||
if (existing && existing !== pluginHost && !existing.killed) {
|
||||
logger.log('w', `scheduled plugin restart cancelled, plugin was restarted by user ${pluginHost.pluginId}`);
|
||||
const existing = this.plugins[pluginId];
|
||||
if (existing && pluginHost && existing !== pluginHost && !existing.killed) {
|
||||
logger.log('w', `scheduled plugin restart cancelled, plugin was restarted by user ${pluginId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -661,32 +660,52 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
|
||||
this.runPlugin(plugin);
|
||||
}
|
||||
catch (e) {
|
||||
logger.log('e', `error restarting plugin ${pluginHost.pluginId}`);
|
||||
logger.log('e', `error restarting plugin ${pluginId}`);
|
||||
logger.log('e', e.toString());
|
||||
restart();
|
||||
}
|
||||
}, t);
|
||||
};
|
||||
|
||||
pluginHost.worker.once('error', restart);
|
||||
pluginHost.worker.once('exit', restart);
|
||||
pluginHost.worker.once('close', restart);
|
||||
1
|
||||
if (pluginHost) {
|
||||
pluginHost.worker.once('error', restart);
|
||||
pluginHost.worker.once('exit', restart);
|
||||
pluginHost.worker.once('close', restart);
|
||||
}
|
||||
else {
|
||||
restart();
|
||||
}
|
||||
}
|
||||
|
||||
loadPlugin(plugin: Plugin, pluginDebug?: PluginDebug) {
|
||||
const pluginId = plugin._id;
|
||||
this.killPlugin(pluginId);
|
||||
try {
|
||||
this.killPlugin(pluginId);
|
||||
|
||||
const pluginDevices = this.findPluginDevices(pluginId);
|
||||
for (const pluginDevice of pluginDevices) {
|
||||
this.invalidatePluginDevice(pluginDevice._id);
|
||||
const pluginDevices = this.findPluginDevices(pluginId);
|
||||
for (const pluginDevice of pluginDevices) {
|
||||
this.invalidatePluginDevice(pluginDevice._id);
|
||||
}
|
||||
|
||||
const pluginHost = new PluginHost(this, plugin, pluginDebug);
|
||||
this.plugins[pluginId] = pluginHost;
|
||||
this.setupPluginHostAutoRestart(pluginId, pluginHost);
|
||||
|
||||
return pluginHost;
|
||||
}
|
||||
catch (e) {
|
||||
const logger = this.getDeviceLogger(this.findPluginDevice(pluginId));
|
||||
if (e instanceof UnsupportedRuntimeError) {
|
||||
logger.log('e', 'error loading plugin (not retrying)');
|
||||
logger.log('e', e.toString());
|
||||
throw e;
|
||||
}
|
||||
|
||||
const pluginHost = new PluginHost(this, plugin, pluginDebug);
|
||||
this.setupPluginHostAutoRestart(pluginHost);
|
||||
this.plugins[pluginId] = pluginHost;
|
||||
|
||||
return pluginHost;
|
||||
logger.log('e', 'error loading plugin (retrying...)');
|
||||
logger.log('e', e.toString());
|
||||
this.setupPluginHostAutoRestart(pluginId);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
probePluginDevices(plugin: Plugin) {
|
||||
|
||||
Reference in New Issue
Block a user