mirror of
https://github.com/koush/scrypted.git
synced 2026-02-03 14:13:28 +00:00
sdk: Improve python generation (#931)
* Improve python generation * tweak * tweak * Move classes to other
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
__pycache__
|
__pycache__
|
||||||
|
venv
|
||||||
|
.venv
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import AbstractSet, Any, Callable
|
|
||||||
|
from enum import Enum
|
||||||
|
from typing import AbstractSet, Any, Callable, Literal
|
||||||
try:
|
try:
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
except:
|
except:
|
||||||
@@ -7,6 +9,7 @@ except:
|
|||||||
|
|
||||||
SettingValue = str
|
SettingValue = str
|
||||||
EventListener = Callable[[Any, Any, Any], None]
|
EventListener = Callable[[Any, Any, Any], None]
|
||||||
|
VibratePattern = int | list[int]
|
||||||
|
|
||||||
|
|
||||||
class Console:
|
class Console:
|
||||||
@@ -36,3 +39,51 @@ class MediaObject:
|
|||||||
|
|
||||||
class RTCSessionDescriptionInit(TypedDict):
|
class RTCSessionDescriptionInit(TypedDict):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationAction(TypedDict, total=False):
|
||||||
|
|
||||||
|
action: str
|
||||||
|
title: str
|
||||||
|
icon: str # optional
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationDirection(str, Enum):
|
||||||
|
|
||||||
|
auto = "auto"
|
||||||
|
ltr = "ltr"
|
||||||
|
rtl = "rtl"
|
||||||
|
|
||||||
|
|
||||||
|
class WebSocket:
|
||||||
|
|
||||||
|
CLOSED: int
|
||||||
|
CLOSING: int
|
||||||
|
CONNECTING: int
|
||||||
|
EventTarget: dict
|
||||||
|
OPEN: int
|
||||||
|
binaryType: Literal["blob", "arraybuffer"]
|
||||||
|
bufferedAmount: int
|
||||||
|
extensions: str
|
||||||
|
onclose: Callable[[dict], None]
|
||||||
|
onerror: Callable[[dict], None]
|
||||||
|
onmessage: Callable[[dict], None]
|
||||||
|
onopen: Callable[[dict], None]
|
||||||
|
protocol: str
|
||||||
|
readyState: int
|
||||||
|
url: str
|
||||||
|
|
||||||
|
def addEventListener(self, type: str, listener: Callable[[dict], None], options: dict = None) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def close(self, code: int = None, reason: str = None) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dispatchEvent(self, event: dict) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def removeEventListener(self, type: str, listener: Callable[[dict], None], options: dict = None) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def send(self, data: str | bytes | bytearray | int | float | bool) -> None:
|
||||||
|
pass
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -151,25 +151,63 @@ seen.add('RTCSignalingSession');
|
|||||||
seen.add('RTCSignalingChannel');
|
seen.add('RTCSignalingChannel');
|
||||||
seen.add('RTCSignalingClient');
|
seen.add('RTCSignalingClient');
|
||||||
|
|
||||||
|
function toDocstring(td: any, includePass: boolean = false) {
|
||||||
|
const suffix = includePass ? ` pass` : '';
|
||||||
|
const comments: any[] = ((td.comment ?? {}).summary ?? []).filter((item: any) => item.kind === "text");
|
||||||
|
if (comments.length === 0) {
|
||||||
|
if (includePass) {
|
||||||
|
return `pass`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (comments.length === 1) {
|
||||||
|
return ` """${comments[0].text.replaceAll('\n', ' ')}"""\n${suffix}`;
|
||||||
|
}
|
||||||
|
let text = ` """\n`;
|
||||||
|
for (const comment of comments) {
|
||||||
|
text += ` ${comment.text.replaceAll('\n', ' ')}\n\n`;
|
||||||
|
}
|
||||||
|
text = text.slice(0,text.length - 2)
|
||||||
|
text += ` """\n${suffix}`;
|
||||||
|
return text
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function toComment(td: any) {
|
||||||
|
const comments: any[] = ((td.comment ?? {}).summary ?? []).filter((item: any) => item.kind === "text");
|
||||||
|
if (comments.length === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (comments.length === 1) {
|
||||||
|
return ` # ${comments[0].text.replaceAll('\n', ' ')}`;
|
||||||
|
}
|
||||||
|
let text = ` # `;
|
||||||
|
for (const comment of comments) {
|
||||||
|
text += `${comment.text.replaceAll('\n', ' ')} `;
|
||||||
|
}
|
||||||
|
return text.slice(0,text.length - 1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function addNonDictionaryType(td: any) {
|
function addNonDictionaryType(td: any) {
|
||||||
seen.add(td.name);
|
seen.add(td.name);
|
||||||
python += `
|
python += `
|
||||||
class ${td.name}:
|
class ${td.name}:
|
||||||
|
${toDocstring(td)}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const properties = td.children.filter((child: any) => child.kindString === 'Property');
|
const properties = td.children.filter((child: any) => child.kindString === 'Property');
|
||||||
const methods = td.children.filter((child: any) => child.kindString === 'Method');
|
const methods = td.children.filter((child: any) => child.kindString === 'Method');
|
||||||
for (const property of properties) {
|
for (const property of properties) {
|
||||||
python += ` ${property.name}: ${toPythonType(property.type)}
|
python += ` ${property.name}: ${toPythonType(property.type)}${toComment(property)}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
for (const method of methods) {
|
for (const method of methods) {
|
||||||
python += ` ${toPythonMethodDeclaration(method)} ${method.name}(${selfSignature(method)}) -> ${toPythonReturnType(method.signatures[0].type)}:
|
python += ` ${toPythonMethodDeclaration(method)} ${method.name}(${selfSignature(method)}) -> ${toPythonReturnType(method.signatures[0].type)}:
|
||||||
pass
|
${toDocstring(method, true)}
|
||||||
|
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
python += ` pass
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const td of interfaces) {
|
for (const td of interfaces) {
|
||||||
@@ -181,7 +219,8 @@ for (const td of interfaces) {
|
|||||||
let pythonEnums = ''
|
let pythonEnums = ''
|
||||||
for (const e of enums) {
|
for (const e of enums) {
|
||||||
pythonEnums += `
|
pythonEnums += `
|
||||||
class ${e.name}(Enum):
|
class ${e.name}(str, Enum):
|
||||||
|
${toDocstring(e)}
|
||||||
`
|
`
|
||||||
for (const val of e.children) {
|
for (const val of e.children) {
|
||||||
pythonEnums += ` ${val.name} = "${val.type.value}"
|
pythonEnums += ` ${val.name} = "${val.type.value}"
|
||||||
@@ -190,7 +229,7 @@ class ${e.name}(Enum):
|
|||||||
}
|
}
|
||||||
|
|
||||||
python += `
|
python += `
|
||||||
class ScryptedInterfaceProperty(Enum):
|
class ScryptedInterfaceProperty(str, Enum):
|
||||||
`
|
`
|
||||||
for (const val of properties) {
|
for (const val of properties) {
|
||||||
python += ` ${val} = "${val}"
|
python += ` ${val} = "${val}"
|
||||||
@@ -198,7 +237,7 @@ for (const val of properties) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
python += `
|
python += `
|
||||||
class ScryptedInterfaceMethods(Enum):
|
class ScryptedInterfaceMethods(str, Enum):
|
||||||
`
|
`
|
||||||
for (const val of methods) {
|
for (const val of methods) {
|
||||||
python += ` ${val} = "${val}"
|
python += ` ${val} = "${val}"
|
||||||
@@ -207,10 +246,13 @@ for (const val of methods) {
|
|||||||
|
|
||||||
python += `
|
python += `
|
||||||
class DeviceState:
|
class DeviceState:
|
||||||
|
|
||||||
def getScryptedProperty(self, property: str) -> Any:
|
def getScryptedProperty(self, property: str) -> Any:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def setScryptedProperty(self, property: str, value: Any):
|
def setScryptedProperty(self, property: str, value: Any):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
`
|
`
|
||||||
for (const [val, type] of Object.entries(allProperties)) {
|
for (const [val, type] of Object.entries(allProperties)) {
|
||||||
if (val === 'nativeId')
|
if (val === 'nativeId')
|
||||||
@@ -219,6 +261,7 @@ for (const [val, type] of Object.entries(allProperties)) {
|
|||||||
@property
|
@property
|
||||||
def ${val}(self) -> ${toPythonType(type)}:
|
def ${val}(self) -> ${toPythonType(type)}:
|
||||||
return self.getScryptedProperty("${val}")
|
return self.getScryptedProperty("${val}")
|
||||||
|
|
||||||
@${val}.setter
|
@${val}.setter
|
||||||
def ${val}(self, value: ${toPythonType(type)}):
|
def ${val}(self, value: ${toPythonType(type)}):
|
||||||
self.setScryptedProperty("${val}", value)
|
self.setScryptedProperty("${val}", value)
|
||||||
@@ -249,15 +292,19 @@ while (discoveredTypes.size) {
|
|||||||
}
|
}
|
||||||
pythonUnknowns += `
|
pythonUnknowns += `
|
||||||
class ${td.name}(TypedDict):
|
class ${td.name}(TypedDict):
|
||||||
|
${toDocstring(td)}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const properties = td.children?.filter((child: any) => child.kindString === 'Property') || [];
|
const properties = td.children?.filter((child: any) => child.kindString === 'Property') || [];
|
||||||
for (const property of properties) {
|
for (const property of properties) {
|
||||||
pythonUnknowns += ` ${property.name}: ${toPythonType(property.type)}
|
pythonUnknowns += ` ${property.name}: ${toPythonType(property.type)}${toComment(property)}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
pythonUnknowns += ` pass
|
if (properties.length === 0) {
|
||||||
|
pythonUnknowns += ` pass
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
python = pythonUnknowns + python;
|
python = pythonUnknowns + python;
|
||||||
@@ -270,7 +317,7 @@ try:
|
|||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
except:
|
except:
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
from typing import Union, Any, Callable
|
from typing import Union, Any
|
||||||
|
|
||||||
from .other import *
|
from .other import *
|
||||||
|
|
||||||
|
|||||||
@@ -1855,7 +1855,7 @@ export interface HttpResponseOptions {
|
|||||||
headers?: object;
|
headers?: object;
|
||||||
}
|
}
|
||||||
export interface EngineIOHandler {
|
export interface EngineIOHandler {
|
||||||
onConnection(request: HttpRequest, webScoket: WebSocket): Promise<void>;
|
onConnection(request: HttpRequest, webSocket: WebSocket): Promise<void>;
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user