Skip to content

Commit

Permalink
Merge pull request #15 from MatrixEditor/fix/invalid-types
Browse files Browse the repository at this point in the history
[Fix] Documentation updates & error fixes
  • Loading branch information
MatrixEditor authored Dec 11, 2023
2 parents a8a7086 + 254c7ca commit 1f51ade
Show file tree
Hide file tree
Showing 16 changed files with 56 additions and 62 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,19 +210,19 @@ api = wrap(device)
friendly_name = api.friendly_name
# or manually
response = device.get(nodes / "netRemote.sys.info.friendlyName")
if response.status == FS_OK:
if response.success:
#_ Again, type(content) = nodes.BaseSysInfoFriendlyName
friendly_name = response.content.value

# Apply a new name via wrapper
api.friendly_name = "FooBar"
# or manually
device.put(nodes / "netRemote.sys.info.friendlyName", value="FooBar")
# Apply a new name via wrapper
api.friendly_name = "FooBar"
# or manually
device.put(nodes / "netRemote.sys.info.friendlyName", value="FooBar")

# get all elements of a list
valid_modes = api.ls_valid_modes()
# get a certain amount of elements beginning at index 3
valid_mpdes = api.ls_valid_modes(_pos=3, max_items=10)
valid_modes = api.ls_valid_modes(_pos=3, max_items=10)
```

## Software Update
Expand Down
2 changes: 1 addition & 1 deletion docs/api-examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ devices:
friendly_name = api.friendly_name
# or manually
response = device.get(nodes / "netRemote.sys.info.friendlyName")
if response.status == FS_OK:
if response.success:
#_ Again, type(content) = nodes.BaseSysInfoFriendlyName
friendly_name = response.content.value
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
project = 'fsapi-tools'
copyright = '2022, MatrixEditor'
author = 'MatrixEditor'
release = '2.0.1'
release = '2.0.2'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
2 changes: 1 addition & 1 deletion fsapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
>>> python3 -m fsapi --help
"""

__version__ = "2.0.1"
__version__ = "2.0.2"
__author__ = 'MatrixEditor'
2 changes: 1 addition & 1 deletion fsapi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from fsapi.netremote.cli import main
from fsapi.net.cli import main

if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion fsapi/isu/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def _run(argv, target: pathlib.Path, pp: DataclassPrinter):
# Don't include the data section if no explicitly activated
values["archive"].pop("data")

with open(str(out_path), "w") as fp:
with open(str(out_path), "w", encoding="utf-8") as fp:
json.dump(values, fp, cls=BytesJSONEncoder)
pp.print_msg(Fore.LIGHTBLACK_EX, "[out] JSON saved to", str(out_path))
else:
Expand Down
17 changes: 3 additions & 14 deletions fsapi/isu/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def is_compressed(self) -> bool:
@dataclass_struct
class ISUArchiveIndexDirectoryEntry:
entry_count: int = csfield(cs.Int8ul)
entries: list[ISUArchiveIndexEntry] = subcsfield(
entries: t.List[ISUArchiveIndexEntry] = subcsfield(
ISUArchiveIndexEntry, cs.Array(cs.this.entry_count, ISUArchiveIndexEntry.struct)
)

Expand All @@ -147,7 +147,7 @@ class ISUArchiveIndex:
length: int = csfield(cs.Int8ul)
name: bytes = csfield(cs.Bytes(cs.this.length)) # always 0
entry_count: int = csfield(cs.Int8ul)
entries: list[ISUArchiveIndexEntry] = subcsfield(
entries: t.List[ISUArchiveIndexEntry] = subcsfield(
ISUArchiveIndexEntry, cs.Array(cs.this.entry_count, ISUArchiveIndexEntry.struct)
)

Expand All @@ -162,17 +162,6 @@ class ISUArchive:
data: bytes = csfield(cs.Bytes(cs.this.size - cs.this.index_size - 4))


@dataclass_struct
class ISUDataField:
length: int = csfield(cs.Int16ul)
unknown_1: int = csfield(cs.Int16ul)
name_length: int = csfield(cs.Int16ul)
flags: int = csfield(cs.Int16ul)
name: str = csfield(cs.PaddedString(16, "utf-8"))
value: int | None = csfield(cs.If(cs.this.length == 32, cs.Int32ul))
unknown_2: int | None = csfield(cs.If(cs.this.length == 32, cs.Int32ul))


@dataclass_struct
class ISUDataSection:
magic: int = csfield(cs.Int8ul)
Expand Down Expand Up @@ -381,7 +370,7 @@ def __init__(self, isu: ISU) -> None:
self.isu = isu
self._fields = self._parse_fields()

def _parse_fields(self) -> list[ISUDataField]:
def _parse_fields(self) -> t.List[ISUDataField]:
index = self.isu.stream.find(b"DecompBuffer")
if index == -1:
# Rather return an empty list than raising an error
Expand Down
3 changes: 2 additions & 1 deletion fsapi/isu/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import dataclasses
import enum
import xml.etree.ElementTree as xmltree
import typing as t

from typing import Optional, Union
from fsapi.netconfig import FSNetConfiguration
Expand Down Expand Up @@ -153,7 +154,7 @@ class UpdateRequest:
"""

status: Union[UpdateStatus, int] = UpdateStatus.ERROR
updates: list[ISUSoftwareElement] = dataclasses.field(default_factory=list)
updates: t.List[ISUSoftwareElement] = dataclasses.field(default_factory=list)
error: Optional[Exception] = None

@property
Expand Down
10 changes: 6 additions & 4 deletions fsapi/net/_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import sys
import enum

from typing import Optional

class FSAlarmSource(enum.IntEnum):
BUZZER = 0
Expand Down Expand Up @@ -121,14 +122,15 @@ class FSEQPreset(enum.IntEnum):
NEWS = enum.auto()


def enum_value_name(value: int, enum: str) -> str | None:
member = get_enum(enum)
def enum_value_name(value: int, enum_: str) -> Optional[str]:
member = get_enum(enum_)
if member is None:
return None
return member._value2member_map_[value]

return getattr(member, "_value2member_map_")[value]

def get_enum(field_name: str, path: str = None) -> type | None:

def get_enum(field_name: str, path: str = None) -> Optional[type]:
module = sys.modules[__name__]
internal_name = f"FS_{field_name.upper()}"

Expand Down
2 changes: 1 addition & 1 deletion fsapi/net/_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
# ============================================================================


class netRemote_debug_incidentReport_lastCreatedKey_nt(NodeList):
class netRemote_debug_incidentReport_list_nt(NodeList):
class Meta:
path = "netRemote.debug.incidentReport.list"
name = "BaseDebugIncidentReportList"
Expand Down
17 changes: 8 additions & 9 deletions fsapi/net/_wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class APICall(t.Generic[_T]):
def __init__(self, node_path: str) -> None:
self.node_path = NodePath(node_path)

def __get__(self, __instance: t.Any, __owner: type | None = None) -> _T:
def __get__(self, __instance: t.Any, __owner: t.Optional[type] = None) -> _T:
return self.get(__instance)

def __set__(self, __instance: t.Any, __value: _T) -> None:
Expand Down Expand Up @@ -119,7 +119,7 @@ def put(self, wrapper: _Wrapper, value: _T) -> None:
wrapper.device.put(self.node_path, value=value)


class ListAPICall(APICall["list[NodeListItem]"]):
class ListAPICall(APICall[t.List[NodeListItem]]):
"""Representation for a list API call.
This class behaves differently compared to standard API call variables
Expand All @@ -137,22 +137,22 @@ def __init__(self, node_path: str) -> None:
super().__init__(node_path)
self.__instance = None

def __get__(self, __instance: t.Any, __owner: type | None = None) -> ListAPICall:
def __get__(self, __instance: t.Any, __owner: t.Optional[type] = None) -> ListAPICall:
self.__instance = __instance
return self

def __call__(self, _pos=-1, max_items=0xFFFF, **argv) -> list[NodeListItem] | None:
def __call__(self, _pos=-1, max_items=0xFFFF, **argv) -> t.List[NodeListItem]:
argv["_pos"] = _pos
argv["maxItems"] = max_items
return self.get(self.__instance, **argv)

def get(self, wrapper: _Wrapper, **argv) -> list[NodeListItem] | None:
def get(self, wrapper: _Wrapper, **argv) -> t.List[NodeListItem]:
"""Returns a list of items.
:param wrapper: the api wrapper instance
:type wrapper: _Wrapper
:return: the list returned by the device
:rtype: list[NodeListItem] | None
:rtype: t.List[NodeListItem]
"""
response = wrapper.device.list_get_next(self.node_path, **argv)
if response.status != Status.FS_OK:
Expand Down Expand Up @@ -226,13 +226,13 @@ def device(self) -> FSDevice:
return self.__device()
return self.__device

def get_field(self, name: str) -> APICall | ListAPICall:
def get_field(self, name: str) -> t.Union[APICall, ListAPICall]:
"""Returns a field of this instance named by the provided string.
:param name: the field's name
:type name: str
:return: the api call wrapper instance
:rtype: APICall | ListAPICall
:rtype: t.Union[APICall, ListAPICall]
"""
return getattr(self, name)

Expand Down Expand Up @@ -287,4 +287,3 @@ def get_field(self, name: str) -> APICall | ListAPICall:
ls_incident_reports: _lac = ListAPICall("netRemote.debug.incidentReport.list")
ls_clock_sources: _lac = ListAPICall("netRemote.sys.caps.clockSourceList")
ls_languages: _lac = ListAPICall("netRemote.sys.caps.validLang")
ls_: _lac = ListAPICall("netRemote.sys.caps.clockSourceList")
14 changes: 7 additions & 7 deletions fsapi/net/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def cacheable(cls) -> bool:
return cls._meta["cacheable"]

@property
def prototype(cls) -> list[Argument] | _Dynamic:
def prototype(cls) -> t.List[Argument] | _Dynamic:
"""Returns the prototype if this node."""
return cls._meta["prototype"]

Expand Down Expand Up @@ -512,11 +512,11 @@ def __eq__(self, __value: object) -> bool:
return super().__eq__(__value)

@property
def value(self) -> int | str | list[NodeListItem] | NodeValue:
def value(self) -> int | str | t.List[NodeListItem] | NodeValue:
"""The node's value
:return: the currently applied node value or None
:rtype: int | str | list[NodeListItem] | NodeValue
:rtype: int | str | t.List[NodeListItem] | NodeValue
"""
return self.__value

Expand Down Expand Up @@ -731,11 +731,11 @@ def __repr__(self) -> str:
return f"NodeListItem({repr(self.attrib)})"

@property
def fields(self) -> list[str]:
def fields(self) -> t.List[str]:
"""Returns a list of field names.
:return: all field names stored by this item.
:rtype: list[str]
:rtype: t.List[str]
"""
return list(self.attrib)

Expand Down Expand Up @@ -776,11 +776,11 @@ def __iter__(self) -> Iterator[NodeListItem]:
return iter(self.items)

@property
def items(self) -> list[NodeListItem]:
def items(self) -> t.List[NodeListItem]:
"""Returns the stored items as a list.
:return: the stored list items
:rtype: list[NodeListItem]
:rtype: t.List[NodeListItem]
"""
return self.value

Expand Down
4 changes: 2 additions & 2 deletions fsapi/net/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def View(value: str, search=False, disable_color=False, **kwds) -> None:
def Get(
host: str,
pin: str,
nodes: list[str],
nodes: t.List[str],
force_session=False,
disable_color=False,
simulate=False,
Expand Down Expand Up @@ -423,7 +423,7 @@ def Scan(
method = Method.GET
node_cls = (nodes / node).get_node_type()
if node_cls.is_list:
method = method.LIST_GET_NEXT
method = Method.LIST_GET_NEXT

if simulate:
pp.print_url(device.get_url(method, node))
Expand Down
25 changes: 14 additions & 11 deletions fsapi/net/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def __init__(
# The new value will be mapped automatically
self.new_session()

def get(self, *__nodes: t.Iterable[_NodeType]) -> FSResponse | list[FSResponse]:
def get(self, *__nodes: t.Iterable[_NodeType]) -> t.Union[FSResponse, t.List[FSResponse]]:
nodes = list(__nodes)
if len(nodes) == 1:
return self.node_request(Method.GET, nodes[0])
Expand All @@ -194,7 +194,7 @@ def list_get_next(self, node: _NodeType, **argv) -> FSResponse:
def list_get_prev(self, node: _NodeType, **argv) -> FSResponse:
return self.node_request(Method.LIST_GET_PREV, node, **argv)

def get_notifies(self) -> list[Node]:
def get_notifies(self) -> t.List[Node]:
if self.sid is None or self.sid == -1:
# NOTE: The unit will only execute this command if the user sends
# a valid Session ID
Expand Down Expand Up @@ -288,20 +288,20 @@ def node_request(
def node_request_multiple(
self,
method: Method,
nodes: list[_NodeType],
nodes: t.List[_NodeType],
config: FSNetConfiguration = None,
**argv,
) -> list[FSResponse]:
) -> t.List[FSResponse]:
"""Performs a multiple node request.
:param method: the API method
:type method: Method
:param nodes: the list of nodes to query
:type nodes: list[_NodeType]
:type nodes: t.List[_NodeType]
:param config: the network configuration, defaults to None
:type config: FSNetConfiguration, optional
:return: a list of response objects storing the de-serialized data.
:rtype: list[FSResponse]
:rtype: t.List[FSResponse]
"""
node_paths = list(map(self._to_node_path, nodes))
path_elements = ["fsapi", method.name]
Expand Down Expand Up @@ -387,18 +387,18 @@ def _create_url(self, path: str, parameters: dict) -> str:
def _build_parameters(self, parameters: dict) -> str:
# NOTE: These parameters must occur before any other custom
# parameter as GET_MULTIPLE would result in errors.
query_params = [f"pin={quote(self.pin)}"]
query_params = [f"pin={self._quote(self.pin)}"]
if self.sid is not None and self.sid != -1:
query_params.append(f"sid={quote(self.sid)}")
query_params.append(f"sid={self._quote(self.sid)}")

for key in parameters:
name = quote(key)
name = self._quote(key)
value = parameters[key]
if isinstance(value, list):
for list_element in value:
query_params.append(f"{name}={quote(str(list_element))}")
query_params.append(f"{name}={self._quote(list_element)}")
else:
query_params.append(f"{name}={quote(str(value))}")
query_params.append(f"{name}={self._quote(value)}")
return "&".join(query_params)

def _unmarshal(self, node_path: NodePath, tree: ElementTree.ElementTree) -> Node:
Expand Down Expand Up @@ -428,3 +428,6 @@ def _to_node_path(self, node: _NodeType) -> NodePath:
raise TypeError(f"Invalid node path type: {type(node)}")

return node_path

def _quote(self, obj: t.Any) -> str:
return quote(str(obj))
2 changes: 1 addition & 1 deletion nodes/fsapi_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def get_enum_class(java_class: str) -> str:
return content.replace("\n", "").replace(" ", "")


def get_list_prototype(java_class) -> list[str]:
def get_list_prototype(java_class) -> t.List[str]:
prototype = java_class[java_class.find("Prototype == null") :]
return prototype[prototype.find("{") + 1 : prototype.find("}")].split("\n")

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "fsapi-tools"
version = "2.0.1"
version = "2.0.2"
description="Frontier Smart Firmware Tools and FSAPI Implementation."
authors = [
{ name="MatrixEditor", email="not@supported.com" },
Expand Down

0 comments on commit 1f51ade

Please sign in to comment.