difonlib 0.2.2a1__tar.gz → 0.2.3__tar.gz
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.
- {difonlib-0.2.2a1 → difonlib-0.2.3}/PKG-INFO +1 -1
- {difonlib-0.2.2a1 → difonlib-0.2.3}/pyproject.toml +4 -4
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/input_devs.py +33 -1
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib.egg-info/PKG-INFO +1 -1
- {difonlib-0.2.2a1 → difonlib-0.2.3}/tests/test_bt_utils.py +2 -1
- difonlib-0.2.3/tests/test_utils.py +103 -0
- difonlib-0.2.2a1/tests/test_utils.py +0 -6
- {difonlib-0.2.2a1 → difonlib-0.2.3}/README.md +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/setup.cfg +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/__init__.py +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/bt_utils.py +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/ng_lib.py +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/py.typed +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/remctrl.py +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/tuya_devs.py +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib/utils.py +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib.egg-info/SOURCES.txt +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib.egg-info/dependency_links.txt +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib.egg-info/requires.txt +0 -0
- {difonlib-0.2.2a1 → difonlib-0.2.3}/src/difonlib.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "difonlib"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
description = "python libraries"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -36,9 +36,9 @@ warn_return_any = true
|
|
|
36
36
|
mypy_path = ["src"]
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
[tool.pytest.ini_options]
|
|
40
|
-
addopts = "-v"
|
|
41
|
-
testpaths = ["tests"]
|
|
39
|
+
# [tool.pytest.ini_options]
|
|
40
|
+
# addopts = "-v"
|
|
41
|
+
# testpaths = ["tests"]
|
|
42
42
|
|
|
43
43
|
[dependency-groups]
|
|
44
44
|
dev = [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
from evdev import InputDevice, categorize
|
|
2
|
+
from evdev import InputDevice, categorize, ecodes, list_devices
|
|
3
3
|
from evdev.events import KeyEvent
|
|
4
4
|
from typing import Dict, Any, List, Optional
|
|
5
5
|
from difonlib.utils import logdbg
|
|
@@ -31,6 +31,38 @@ class IDevKbdKey:
|
|
|
31
31
|
keycode: str | tuple = ""
|
|
32
32
|
|
|
33
33
|
|
|
34
|
+
def idev_get_connected_devs() -> List[InputDevice]:
|
|
35
|
+
return [InputDevice(p) for p in list_devices()]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def is_remote_ctrl(dev: InputDevice) -> bool:
|
|
39
|
+
caps = dev.capabilities()
|
|
40
|
+
if ecodes.EV_KEY not in caps:
|
|
41
|
+
return False
|
|
42
|
+
keys = set(caps[ecodes.EV_KEY])
|
|
43
|
+
remote_keys = {
|
|
44
|
+
ecodes.KEY_UP,
|
|
45
|
+
ecodes.KEY_DOWN,
|
|
46
|
+
ecodes.KEY_LEFT,
|
|
47
|
+
ecodes.KEY_RIGHT,
|
|
48
|
+
ecodes.KEY_OK,
|
|
49
|
+
ecodes.KEY_SELECT,
|
|
50
|
+
ecodes.KEY_BACK,
|
|
51
|
+
ecodes.KEY_PLAYPAUSE,
|
|
52
|
+
ecodes.KEY_VOLUMEUP,
|
|
53
|
+
ecodes.KEY_VOLUMEDOWN,
|
|
54
|
+
ecodes.KEY_HOME,
|
|
55
|
+
ecodes.KEY_MENU,
|
|
56
|
+
}
|
|
57
|
+
return bool(remote_keys & keys)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def idev_get_dev_by_uniq(uniq: str) -> Optional[InputDevice]:
|
|
61
|
+
devs = idev_get_connected_devs()
|
|
62
|
+
matched = [dev for dev in devs if dev.uniq == uniq and is_remote_ctrl(dev)]
|
|
63
|
+
return matched[0] if matched else None
|
|
64
|
+
|
|
65
|
+
|
|
34
66
|
def get_connected_input_devices() -> List[Dict[str, Any]]:
|
|
35
67
|
path = Path("/proc/bus/input/devices")
|
|
36
68
|
devices: List[Dict[str, Any]] = []
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from difonlib.utils import logdbg
|
|
2
2
|
from difonlib.bt_utils import bt_hid_conn_devs, get_connected_input_devices
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import pytest
|
|
5
5
|
|
|
6
6
|
dbg = logdbg
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
@pytest.mark.slow
|
|
9
10
|
def test_bt_utils():
|
|
10
11
|
assert type(bt_hid_conn_devs()) is list, "Return value type is not list"
|
|
11
12
|
assert type(get_connected_input_devices()) is list, "Return value type is not list"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import pytest
|
|
3
|
+
from difonlib.utils import (
|
|
4
|
+
logdbg,
|
|
5
|
+
is_mac_address,
|
|
6
|
+
# is_mac_address2,
|
|
7
|
+
mac_format,
|
|
8
|
+
UtilsError,
|
|
9
|
+
to_signed,
|
|
10
|
+
swap16,
|
|
11
|
+
swap32,
|
|
12
|
+
fs_remove_dir_content,
|
|
13
|
+
file_get_latest,
|
|
14
|
+
YamlConfig,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.mark.parametrize(
|
|
19
|
+
"mac",
|
|
20
|
+
[
|
|
21
|
+
"AA:BB:CC:DD:EE:FF",
|
|
22
|
+
"aa:bb:cc:dd:ee:ff",
|
|
23
|
+
"01:23:45:67:89:aB",
|
|
24
|
+
],
|
|
25
|
+
)
|
|
26
|
+
def test_is_mac_address_valid(mac):
|
|
27
|
+
assert is_mac_address(mac)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.mark.parametrize(
|
|
31
|
+
"mac",
|
|
32
|
+
[
|
|
33
|
+
"AA-BB-CC-DD-EE-FF",
|
|
34
|
+
"AABBCCDDEEFF",
|
|
35
|
+
"GG:HH:II:JJ:KK:LL",
|
|
36
|
+
],
|
|
37
|
+
)
|
|
38
|
+
def test_is_mac_address_invalid(mac):
|
|
39
|
+
assert not is_mac_address(mac)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_mac_format_ok():
|
|
43
|
+
assert mac_format("112233445566") == "11:22:33:44:55:66"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_mac_format_invalid():
|
|
47
|
+
with pytest.raises(UtilsError):
|
|
48
|
+
mac_format("1234")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_to_signed_positive():
|
|
52
|
+
assert to_signed(10, 8) == 10
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_to_signed_negative():
|
|
56
|
+
assert to_signed(0b11111111, 8) == -1
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_swap16():
|
|
60
|
+
assert swap16(0x1234) == 0x3412
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_swap32():
|
|
64
|
+
assert swap32(0x11223344) == 0x44332211
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_fs_remove_dir_content(tmp_dir: Path):
|
|
68
|
+
f = tmp_dir / "a.txt"
|
|
69
|
+
f.write_text("hello")
|
|
70
|
+
|
|
71
|
+
fs_remove_dir_content(str(tmp_dir))
|
|
72
|
+
|
|
73
|
+
assert list(tmp_dir.iterdir()) == []
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_file_get_latest(tmp_dir: Path):
|
|
77
|
+
f1 = tmp_dir / "a.txt"
|
|
78
|
+
f2 = tmp_dir / "b.txt"
|
|
79
|
+
f1.write_text("1")
|
|
80
|
+
f2.write_text("2")
|
|
81
|
+
|
|
82
|
+
latest = file_get_latest(str(tmp_dir), "*.txt")
|
|
83
|
+
if latest:
|
|
84
|
+
assert latest.endswith("b.txt")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_yaml_config_create_and_save(yaml_config_path):
|
|
88
|
+
cfg = YamlConfig(str(yaml_config_path))
|
|
89
|
+
cfg.config["a"] = 1
|
|
90
|
+
cfg.save()
|
|
91
|
+
|
|
92
|
+
cfg2 = YamlConfig(str(yaml_config_path))
|
|
93
|
+
assert cfg2.config["a"] == 1
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_log_dbg():
|
|
97
|
+
logdbg("hello 12345")
|
|
98
|
+
assert True
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_show_tmp(tmp_path):
|
|
102
|
+
# Show value of tmp_path fixture
|
|
103
|
+
print(f"Show value of tmp_path fixture: {tmp_path}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|