@scrypted/server 0.94.27 → 0.94.29

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.
@@ -0,0 +1,2 @@
1
+ export declare declare const version: string;
2
+ export declare async function installScryptedServerRequirements(version?: string, dest?: string);
@@ -0,0 +1,23 @@
1
+ const child_process = require('child_process');
2
+ const { PortablePython } = require('py')
3
+ const { once } = require('events');
4
+
5
+ module.exports = {
6
+ version: '3.11',
7
+ }
8
+
9
+ async function pipInstall(python, pkg) {
10
+ const cp = child_process.spawn(python, ['-m', 'pip', 'install', pkg], { stdio: 'inherit' });
11
+ const [exitCode] = await once(cp, 'exit');
12
+ if (exitCode)
13
+ throw new Error('non-zero exit code: ' + exitCode);
14
+ }
15
+
16
+ module.exports.installScryptedServerRequirements = async function installScryptedServerRequirements(version, dest) {
17
+ const py = new PortablePython(version || require('./packaged-python').version, dest);
18
+ await py.install();
19
+ let python = py.executablePath;
20
+
21
+ await pipInstall(python, 'debugpy');
22
+ await pipInstall(python, 'psutil').catch(() => { });
23
+ }
package/bin/postinstall CHANGED
@@ -1,24 +1,2 @@
1
1
  #!/usr/bin/env node
2
-
3
- const child_process = require('child_process');
4
- const { PortablePython } = require('py')
5
- const { once } = require('events');
6
- let python;
7
-
8
- async function pipInstall(pkg) {
9
- const cp = child_process.spawn(python, ['-m', 'pip', 'install', pkg], { stdio: 'inherit' });
10
- const [exitCode] = await once(cp, 'exit');
11
- if (exitCode)
12
- throw new Error('non-zero exit code: ' + exitCode);
13
- }
14
-
15
- async function installScryptedServerRequirements() {
16
- const py = new PortablePython("3.9");
17
- await py.install();
18
- python = py.executablePath;
19
-
20
- await pipInstall('debugpy');
21
- await pipInstall('psutil').catch(() => {});
22
- }
23
-
24
- installScryptedServerRequirements();
2
+ require('./packaged-python').installScryptedServerRequirements();
@@ -7,13 +7,12 @@ import child_process from 'child_process';
7
7
  import { RpcMessage, RpcPeer } from "../../rpc";
8
8
  export declare abstract class ChildProcessWorker extends EventEmitter implements RuntimeWorker {
9
9
  pluginId: string;
10
- worker: child_process.ChildProcess;
10
+ protected worker: child_process.ChildProcess;
11
11
  constructor(pluginId: string, options: RuntimeWorkerOptions);
12
12
  setupWorker(): void;
13
13
  get pid(): number;
14
14
  get stdout(): import("stream").Readable;
15
15
  get stderr(): import("stream").Readable;
16
- get killed(): boolean;
17
16
  kill(): void;
18
17
  abstract send(message: RpcMessage, reject?: (e: Error) => void): void;
19
18
  abstract setupRpcPeer(peer: RpcPeer): void;
@@ -25,9 +25,6 @@ class ChildProcessWorker extends ws_1.EventEmitter {
25
25
  get stderr() {
26
26
  return this.worker.stderr;
27
27
  }
28
- get killed() {
29
- return this.worker.killed;
30
- }
31
28
  kill() {
32
29
  if (!this.worker)
33
30
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"child-process-worker.js","sourceRoot":"","sources":["../../../src/plugin/runtime/child-process-worker.ts"],"names":[],"mappings":";;;AAAA,2BAAkC;AAKlC,MAAsB,kBAAmB,SAAQ,iBAAY;IAGtC;IAFnB,MAAM,CAA6B;IAEnC,YAAmB,QAAgB,EAAE,OAA6B;QAC9D,KAAK,EAAE,CAAC;QADO,aAAQ,GAAR,QAAQ,CAAQ;IAEnC,CAAC;IAED,WAAW;QACP,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC3B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,MAAM;YACZ,OAAO;QACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC;CAIJ;AA3CD,gDA2CC"}
1
+ {"version":3,"file":"child-process-worker.js","sourceRoot":"","sources":["../../../src/plugin/runtime/child-process-worker.ts"],"names":[],"mappings":";;;AAAA,2BAAkC;AAKlC,MAAsB,kBAAmB,SAAQ,iBAAY;IAGtC;IAFT,MAAM,CAA6B;IAE7C,YAAmB,QAAgB,EAAE,OAA6B;QAC9D,KAAK,EAAE,CAAC;QADO,aAAQ,GAAR,QAAQ,CAAQ;IAEnC,CAAC;IAED,WAAW;QACP,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC3B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,MAAM;YACZ,OAAO;QACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC;CAIJ;AAvCD,gDAuCC"}
@@ -13,7 +13,6 @@ export declare class NodeThreadWorker extends EventEmitter implements RuntimeWor
13
13
  get pid(): number;
14
14
  get stdout(): import("stream").Readable;
15
15
  get stderr(): import("stream").Readable;
16
- get killed(): boolean;
17
16
  kill(): void;
18
17
  send(message: RpcMessage, reject?: (e: Error) => void): void;
19
18
  setupRpcPeer(peer: RpcPeer): void;
@@ -39,9 +39,6 @@ class NodeThreadWorker extends ws_1.EventEmitter {
39
39
  get stderr() {
40
40
  return this.worker.stderr;
41
41
  }
42
- get killed() {
43
- return this.terminated;
44
- }
45
42
  kill() {
46
43
  if (!this.worker)
47
44
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"node-thread-worker.js","sourceRoot":"","sources":["../../../src/plugin/runtime/node-thread-worker.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,oEAA4C;AAC5C,2BAAkC;AAIlC,MAAa,gBAAiB,SAAQ,iBAAY;IAIL;IAHzC,UAAU,CAAU;IACpB,MAAM,CAAwB;IAE9B,YAAY,YAAoB,EAAS,QAAgB,EAAE,OAA6B;QACpF,KAAK,EAAE,CAAC;QAD6B,aAAQ,GAAR,QAAQ,CAAQ;QAErD,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;QAExB,IAAI,CAAC,MAAM,GAAG,IAAI,wBAAc,CAAC,MAAM,CAAC,YAAY,EAAE;YAClD,IAAI,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC;YACrC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE;YACxB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI,GAAG;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAChC,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,MAAM;YACZ,OAAO;QACX,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,OAAmB,EAAE,MAA2B;QACjD,IAAI,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,MAAM;gBACZ,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,CAAC,EAAE,CAAC;YACP,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACL,CAAC;IAED,YAAY,CAAC,IAAa;QACtB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,YAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;CACJ;AAjED,4CAiEC"}
1
+ {"version":3,"file":"node-thread-worker.js","sourceRoot":"","sources":["../../../src/plugin/runtime/node-thread-worker.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,oEAA4C;AAC5C,2BAAkC;AAIlC,MAAa,gBAAiB,SAAQ,iBAAY;IAIL;IAHzC,UAAU,CAAU;IACpB,MAAM,CAAwB;IAE9B,YAAY,YAAoB,EAAS,QAAgB,EAAE,OAA6B;QACpF,KAAK,EAAE,CAAC;QAD6B,aAAQ,GAAR,QAAQ,CAAQ;QAErD,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;QAExB,IAAI,CAAC,MAAM,GAAG,IAAI,wBAAc,CAAC,MAAM,CAAC,YAAY,EAAE;YAClD,IAAI,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC;YACrC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE;YACxB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI,GAAG;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAChC,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,MAAM;YACZ,OAAO;QACX,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,OAAmB,EAAE,MAA2B;QACjD,IAAI,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,MAAM;gBACZ,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,CAAC,EAAE,CAAC;YACP,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACL,CAAC;IAED,YAAY,CAAC,IAAa;QACtB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,YAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;CACJ;AA7DD,4CA6DC"}
@@ -1,9 +1,19 @@
1
+ /// <reference types="node" />
2
+ import { Readable, Writable, PassThrough } from 'stream';
1
3
  import { RpcMessage, RpcPeer } from "../../rpc";
2
4
  import { createRpcDuplexSerializer } from '../../rpc-serializer';
3
5
  import { ChildProcessWorker } from "./child-process-worker";
4
6
  import { RuntimeWorkerOptions } from "./runtime-worker";
5
7
  export declare class PythonRuntimeWorker extends ChildProcessWorker {
6
8
  serializer: ReturnType<typeof createRpcDuplexSerializer>;
9
+ peerin: Writable;
10
+ peerout: Readable;
11
+ _stdout: PassThrough;
12
+ _stderr: PassThrough;
13
+ pythonInstallationComplete: boolean;
14
+ get pid(): number;
15
+ get stdout(): PassThrough;
16
+ get stderr(): PassThrough;
7
17
  constructor(pluginId: string, options: RuntimeWorkerOptions);
8
18
  setupRpcPeer(peer: RpcPeer): void;
9
19
  send(message: RpcMessage, reject?: (e: Error) => void, serializationContext?: any): void;
@@ -8,14 +8,17 @@ const child_process_1 = __importDefault(require("child_process"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const os_1 = __importDefault(require("os"));
10
10
  const path_1 = __importDefault(require("path"));
11
+ const py_1 = require("py");
12
+ const stream_1 = require("stream");
13
+ const packaged_python_1 = require("../../../bin/packaged-python");
11
14
  const rpc_serializer_1 = require("../../rpc-serializer");
12
15
  const child_process_worker_1 = require("./child-process-worker");
13
16
  class PythonRuntimeWorker extends child_process_worker_1.ChildProcessWorker {
14
17
  static {
15
18
  try {
16
- const PortablePython = require('py').PortablePython;
17
- const py = new PortablePython("3.9");
19
+ const py = new py_1.PortablePython(packaged_python_1.version);
18
20
  const portablePython = py.executablePath;
21
+ // is this possible?
19
22
  if (fs_1.default.existsSync(portablePython))
20
23
  process.env.SCRYPTED_PYTHON_PATH = portablePython;
21
24
  }
@@ -23,6 +26,20 @@ class PythonRuntimeWorker extends child_process_worker_1.ChildProcessWorker {
23
26
  }
24
27
  }
25
28
  serializer;
29
+ peerin;
30
+ peerout;
31
+ _stdout = new stream_1.PassThrough();
32
+ _stderr = new stream_1.PassThrough();
33
+ pythonInstallationComplete = true;
34
+ get pid() {
35
+ return this.worker?.pid || -1;
36
+ }
37
+ get stdout() {
38
+ return this._stdout;
39
+ }
40
+ get stderr() {
41
+ return this._stderr;
42
+ }
26
43
  constructor(pluginId, options) {
27
44
  super(pluginId, options);
28
45
  const { env, pluginDebug } = options;
@@ -32,7 +49,7 @@ class PythonRuntimeWorker extends child_process_worker_1.ChildProcessWorker {
32
49
  if (pluginDebug) {
33
50
  args.push('-m', 'debugpy', '--listen', `0.0.0.0:${pluginDebug.inspectPort}`, '--wait-for-client');
34
51
  }
35
- args.push(path_1.default.join(__dirname, '../../../python', 'plugin_remote.py'));
52
+ args.push(path_1.default.join(__dirname, '../../../python', 'plugin_remote.py'), this.pluginId);
36
53
  const gstEnv = {};
37
54
  // hack to fix gst plugin search path on mac...
38
55
  if (os_1.default.platform() === 'darwin') {
@@ -52,53 +69,76 @@ class PythonRuntimeWorker extends child_process_worker_1.ChildProcessWorker {
52
69
  }
53
70
  let pythonPath = process.env.SCRYPTED_PYTHON_PATH;
54
71
  const pluginPythonVersion = options.packageJson.scrypted.pythonVersion?.[os_1.default.platform()]?.[os_1.default.arch()] || options.packageJson.scrypted.pythonVersion?.default;
55
- if (os_1.default.platform() === 'win32') {
56
- if (!pythonPath) {
72
+ if (!pythonPath) {
73
+ if (os_1.default.platform() === 'win32') {
57
74
  pythonPath = 'py.exe';
58
- const windowsPythonVersion = pluginPythonVersion || process.env.SCRYPTED_WINDOWS_PYTHON_VERSION;
59
- if (windowsPythonVersion)
60
- args.unshift(windowsPythonVersion);
75
+ }
76
+ else {
77
+ pythonPath = 'python3';
61
78
  }
62
79
  }
63
- else if (pluginPythonVersion) {
64
- pythonPath = `python${pluginPythonVersion}`;
80
+ const setup = () => {
81
+ const types = require.resolve('@scrypted/types');
82
+ const PYTHONPATH = types.substring(0, types.indexOf('types') + 'types'.length);
83
+ this.worker = child_process_1.default.spawn(pythonPath, args, {
84
+ // stdin, stdout, stderr, peer in, peer out
85
+ stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
86
+ env: Object.assign({
87
+ // rev this if the base python version or server characteristics change.
88
+ SCRYPTED_PYTHON_VERSION: '20240308.1',
89
+ PYTHONUNBUFFERED: '1',
90
+ PYTHONPATH,
91
+ }, gstEnv, process.env, env),
92
+ });
93
+ this.worker.stdout.pipe(this.stdout);
94
+ this.worker.stderr.pipe(this.stderr);
95
+ };
96
+ // if the plugin requests a specific python, then install it via portable python
97
+ if (pluginPythonVersion) {
98
+ const peerin = this.peerin = new stream_1.PassThrough();
99
+ const peerout = this.peerout = new stream_1.PassThrough();
100
+ const py = new py_1.PortablePython(pluginPythonVersion, path_1.default.dirname(options.unzippedPath));
101
+ this.pythonInstallationComplete = false;
102
+ py.install()
103
+ .then(() => {
104
+ pythonPath = py.executablePath;
105
+ // is this possible?
106
+ if (!fs_1.default.existsSync(pythonPath))
107
+ throw new Error('Installation failed. Portable python not found.');
108
+ setup();
109
+ peerin.pipe(this.worker.stdio[3]);
110
+ this.worker.stdio[4].pipe(peerout);
111
+ })
112
+ .catch(() => {
113
+ process.nextTick(() => {
114
+ this.emit('error', new Error('Failed to install portable python.'));
115
+ });
116
+ })
117
+ .finally(() => this.pythonInstallationComplete = true);
65
118
  }
66
119
  else {
67
- pythonPath ||= 'python3';
120
+ setup();
121
+ this.peerin = this.worker.stdio[3];
122
+ this.peerout = this.worker.stdio[4];
123
+ this.setupWorker();
68
124
  }
69
- args.push(this.pluginId);
70
- const types = require.resolve('@scrypted/types');
71
- const PYTHONPATH = types.substring(0, types.indexOf('types') + 'types'.length);
72
- this.worker = child_process_1.default.spawn(pythonPath, args, {
73
- // stdin, stdout, stderr, peer in, peer out
74
- stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
75
- env: Object.assign({
76
- // rev this if the base python version or server characterstics change.
77
- SCRYPTED_PYTHON_VERSION: '20240308.1',
78
- PYTHONUNBUFFERED: '1',
79
- PYTHONPATH,
80
- }, gstEnv, process.env, env),
81
- });
82
- this.setupWorker();
83
125
  }
84
126
  setupRpcPeer(peer) {
85
- const peerin = this.worker.stdio[3];
86
- const peerout = this.worker.stdio[4];
87
- const serializer = this.serializer = (0, rpc_serializer_1.createRpcDuplexSerializer)(peerin);
127
+ const serializer = this.serializer = (0, rpc_serializer_1.createRpcDuplexSerializer)(this.peerin);
88
128
  serializer.setupRpcPeer(peer);
89
- peerout.on('data', data => serializer.onData(data));
90
- peerin.on('error', e => {
129
+ this.peerout.on('data', data => serializer.onData(data));
130
+ this.peerin.on('error', e => {
91
131
  this.emit('error', e);
92
132
  serializer.onDisconnected();
93
133
  });
94
- peerout.on('error', e => {
134
+ this.peerout.on('error', e => {
95
135
  this.emit('error', e);
96
136
  serializer.onDisconnected();
97
137
  });
98
138
  }
99
139
  send(message, reject, serializationContext) {
100
140
  try {
101
- if (!this.worker)
141
+ if (this.pythonInstallationComplete && !this.worker)
102
142
  throw new Error('python worker has been killed');
103
143
  this.serializer.sendMessage(message, reject, serializationContext);
104
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"python-worker.js","sourceRoot":"","sources":["../../../src/plugin/runtime/python-worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"python-worker.js","sourceRoot":"","sources":["../../../src/plugin/runtime/python-worker.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,6 @@ export interface RuntimeWorker {
17
17
  pid: number;
18
18
  stdout: Readable;
19
19
  stderr: Readable;
20
- killed: boolean;
21
20
  kill(): void;
22
21
  on(event: 'rpc', listener: (message: any, sendHandle: net.Socket) => void): this;
23
22
  on(event: 'error', listener: (err: Error) => void): this;
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@scrypted/server",
3
- "version": "0.94.27",
3
+ "version": "0.94.29",
4
4
  "description": "",
5
5
  "dependencies": {
6
6
  "@mapbox/node-pre-gyp": "^1.0.11",
7
7
  "@scrypted/ffmpeg-static": "^6.1.0-build1",
8
8
  "@scrypted/types": "^0.3.17",
9
- "adm-zip": "^0.5.10",
9
+ "adm-zip": "^0.5.12",
10
10
  "body-parser": "^1.20.2",
11
11
  "cookie-parser": "^1.4.6",
12
12
  "engine.io": "^6.5.4",
13
13
  "express": "^4.18.3",
14
- "follow-redirects": "^1.15.5",
14
+ "follow-redirects": "^1.15.6",
15
15
  "http-auth": "^4.2.0",
16
16
  "ip": "^2.0.1",
17
17
  "level": "^8.0.1",
@@ -20,7 +20,7 @@
20
20
  "node-dijkstra": "^2.5.0",
21
21
  "node-forge": "^1.3.1",
22
22
  "node-gyp": "^10.0.1",
23
- "py": "npm:@bjia56/portable-python@^0.1.10",
23
+ "py": "npm:@bjia56/portable-python@^0.1.15",
24
24
  "router": "^1.3.8",
25
25
  "semver": "^7.6.0",
26
26
  "sharp": "^0.33.2",
@@ -38,7 +38,7 @@
38
38
  "@types/follow-redirects": "^1.14.4",
39
39
  "@types/http-auth": "^4.1.4",
40
40
  "@types/ip": "^1.1.3",
41
- "@types/lodash": "^4.14.202",
41
+ "@types/lodash": "^4.17.0",
42
42
  "@types/node-dijkstra": "^2.5.6",
43
43
  "@types/node-forge": "^1.3.11",
44
44
  "@types/semver": "^7.5.8",
@@ -4,7 +4,7 @@ import child_process from 'child_process';
4
4
  import { RpcMessage, RpcPeer } from "../../rpc";
5
5
 
6
6
  export abstract class ChildProcessWorker extends EventEmitter implements RuntimeWorker {
7
- worker: child_process.ChildProcess;
7
+ protected worker: child_process.ChildProcess;
8
8
 
9
9
  constructor(public pluginId: string, options: RuntimeWorkerOptions) {
10
10
  super();
@@ -30,10 +30,6 @@ export abstract class ChildProcessWorker extends EventEmitter implements Runtime
30
30
  return this.worker.stderr;
31
31
  }
32
32
 
33
- get killed() {
34
- return this.worker.killed;
35
- }
36
-
37
33
  kill(): void {
38
34
  if (!this.worker)
39
35
  return;
@@ -41,10 +41,6 @@ export class NodeThreadWorker extends EventEmitter implements RuntimeWorker {
41
41
  return this.worker.stderr;
42
42
  }
43
43
 
44
- get killed() {
45
- return this.terminated;
46
- }
47
-
48
44
  kill(): void {
49
45
  if (!this.worker)
50
46
  return;
@@ -2,8 +2,9 @@ import child_process from 'child_process';
2
2
  import fs from "fs";
3
3
  import os from "os";
4
4
  import path from 'path';
5
- import type { PortablePython as PortablePythonType } from 'py';
6
- import { Readable, Writable } from 'stream';
5
+ import { PortablePython } from 'py';
6
+ import { Readable, Writable, PassThrough } from 'stream';
7
+ import { version as packagedPythonVersion } from '../../../bin/packaged-python';
7
8
  import { RpcMessage, RpcPeer } from "../../rpc";
8
9
  import { createRpcDuplexSerializer } from '../../rpc-serializer';
9
10
  import { ChildProcessWorker } from "./child-process-worker";
@@ -12,9 +13,9 @@ import { RuntimeWorkerOptions } from "./runtime-worker";
12
13
  export class PythonRuntimeWorker extends ChildProcessWorker {
13
14
  static {
14
15
  try {
15
- const PortablePython = require('py').PortablePython as typeof PortablePythonType;
16
- const py = new PortablePython("3.9");
16
+ const py = new PortablePython(packagedPythonVersion);
17
17
  const portablePython = py.executablePath;
18
+ // is this possible?
18
19
  if (fs.existsSync(portablePython))
19
20
  process.env.SCRYPTED_PYTHON_PATH = portablePython;
20
21
  }
@@ -23,6 +24,23 @@ export class PythonRuntimeWorker extends ChildProcessWorker {
23
24
  }
24
25
 
25
26
  serializer: ReturnType<typeof createRpcDuplexSerializer>;
27
+ peerin: Writable;
28
+ peerout: Readable;
29
+ _stdout = new PassThrough();
30
+ _stderr = new PassThrough();
31
+ pythonInstallationComplete = true;
32
+
33
+ get pid() {
34
+ return this.worker?.pid || -1;
35
+ }
36
+
37
+ get stdout() {
38
+ return this._stdout;
39
+ }
40
+
41
+ get stderr() {
42
+ return this._stderr;
43
+ }
26
44
 
27
45
  constructor(pluginId: string, options: RuntimeWorkerOptions) {
28
46
  super(pluginId, options);
@@ -31,6 +49,7 @@ export class PythonRuntimeWorker extends ChildProcessWorker {
31
49
  const args: string[] = [
32
50
  '-u',
33
51
  ];
52
+
34
53
  if (pluginDebug) {
35
54
  args.push(
36
55
  '-m',
@@ -40,8 +59,10 @@ export class PythonRuntimeWorker extends ChildProcessWorker {
40
59
  '--wait-for-client',
41
60
  )
42
61
  }
62
+
43
63
  args.push(
44
64
  path.join(__dirname, '../../../python', 'plugin_remote.py'),
65
+ this.pluginId,
45
66
  )
46
67
 
47
68
  const gstEnv: NodeJS.ProcessEnv = {};
@@ -65,51 +86,76 @@ export class PythonRuntimeWorker extends ChildProcessWorker {
65
86
  let pythonPath = process.env.SCRYPTED_PYTHON_PATH;
66
87
  const pluginPythonVersion = options.packageJson.scrypted.pythonVersion?.[os.platform()]?.[os.arch()] || options.packageJson.scrypted.pythonVersion?.default;
67
88
 
68
- if (os.platform() === 'win32') {
69
- if (!pythonPath) {
89
+ if (!pythonPath) {
90
+ if (os.platform() === 'win32') {
70
91
  pythonPath = 'py.exe';
71
- const windowsPythonVersion = pluginPythonVersion || process.env.SCRYPTED_WINDOWS_PYTHON_VERSION;
72
- if (windowsPythonVersion)
73
- args.unshift(windowsPythonVersion)
92
+ }
93
+ else {
94
+ pythonPath = 'python3';
74
95
  }
75
96
  }
76
- else if (pluginPythonVersion) {
77
- pythonPath = `python${pluginPythonVersion}`;
97
+
98
+ const setup = () => {
99
+ const types = require.resolve('@scrypted/types');
100
+ const PYTHONPATH = types.substring(0, types.indexOf('types') + 'types'.length);
101
+ this.worker = child_process.spawn(pythonPath, args, {
102
+ // stdin, stdout, stderr, peer in, peer out
103
+ stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
104
+ env: Object.assign({
105
+ // rev this if the base python version or server characteristics change.
106
+ SCRYPTED_PYTHON_VERSION: '20240308.1',
107
+ PYTHONUNBUFFERED: '1',
108
+ PYTHONPATH,
109
+ }, gstEnv, process.env, env),
110
+ });
111
+
112
+ this.worker.stdout.pipe(this.stdout);
113
+ this.worker.stderr.pipe(this.stderr);
114
+ };
115
+
116
+
117
+ // if the plugin requests a specific python, then install it via portable python
118
+ if (pluginPythonVersion) {
119
+ const peerin = this.peerin = new PassThrough();
120
+ const peerout = this.peerout = new PassThrough();
121
+
122
+ const py = new PortablePython(pluginPythonVersion, path.dirname(options.unzippedPath));
123
+ this.pythonInstallationComplete = false;
124
+ py.install()
125
+ .then(() => {
126
+ pythonPath = py.executablePath;
127
+ // is this possible?
128
+ if (!fs.existsSync(pythonPath))
129
+ throw new Error('Installation failed. Portable python not found.');
130
+ setup();
131
+
132
+ peerin.pipe(this.worker.stdio[3] as Writable);
133
+ (this.worker.stdio[4] as Readable).pipe(peerout);
134
+ })
135
+ .catch(() => {
136
+ process.nextTick(() => {
137
+ this.emit('error', new Error('Failed to install portable python.'));
138
+ })
139
+ })
140
+ .finally(() => this.pythonInstallationComplete = true);
78
141
  }
79
142
  else {
80
- pythonPath ||= 'python3';
143
+ setup();
144
+ this.peerin = this.worker.stdio[3] as Writable;
145
+ this.peerout = this.worker.stdio[4] as Readable;
146
+ this.setupWorker();
81
147
  }
82
-
83
- args.push(this.pluginId);
84
-
85
- const types = require.resolve('@scrypted/types');
86
- const PYTHONPATH = types.substring(0, types.indexOf('types') + 'types'.length);
87
- this.worker = child_process.spawn(pythonPath, args, {
88
- // stdin, stdout, stderr, peer in, peer out
89
- stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
90
- env: Object.assign({
91
- // rev this if the base python version or server characterstics change.
92
- SCRYPTED_PYTHON_VERSION: '20240308.1',
93
- PYTHONUNBUFFERED: '1',
94
- PYTHONPATH,
95
- }, gstEnv, process.env, env),
96
- });
97
-
98
- this.setupWorker();
99
148
  }
100
149
 
101
150
  setupRpcPeer(peer: RpcPeer): void {
102
- const peerin = this.worker.stdio[3] as Writable;
103
- const peerout = this.worker.stdio[4] as Readable;
104
-
105
- const serializer = this.serializer = createRpcDuplexSerializer(peerin);
151
+ const serializer = this.serializer = createRpcDuplexSerializer(this.peerin);
106
152
  serializer.setupRpcPeer(peer);
107
- peerout.on('data', data => serializer.onData(data));
108
- peerin.on('error', e => {
153
+ this.peerout.on('data', data => serializer.onData(data));
154
+ this.peerin.on('error', e => {
109
155
  this.emit('error', e);
110
156
  serializer.onDisconnected();
111
157
  });
112
- peerout.on('error', e => {
158
+ this.peerout.on('error', e => {
113
159
  this.emit('error', e)
114
160
  serializer.onDisconnected();
115
161
  });
@@ -117,7 +163,7 @@ export class PythonRuntimeWorker extends ChildProcessWorker {
117
163
 
118
164
  send(message: RpcMessage, reject?: (e: Error) => void, serializationContext?: any): void {
119
165
  try {
120
- if (!this.worker)
166
+ if (this.pythonInstallationComplete && !this.worker)
121
167
  throw new Error('python worker has been killed');
122
168
  this.serializer.sendMessage(message, reject, serializationContext);
123
169
  }
@@ -16,7 +16,6 @@ export interface RuntimeWorker {
16
16
  pid: number;
17
17
  stdout: Readable;
18
18
  stderr: Readable;
19
- killed: boolean;
20
19
 
21
20
  kill(): void;
22
21