nano-wait 1.3__tar.gz → 3.0__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.
Potentially problematic release.
This version of nano-wait might be problematic. Click here for more details.
- {nano_wait-1.3 → nano_wait-3.0}/LICENSE +21 -21
- nano_wait-3.0/PKG-INFO +61 -0
- nano_wait-3.0/README.md +23 -0
- nano_wait-3.0/nano_wait/__init__.py +38 -0
- nano_wait-3.0/nano_wait/__main__.py +4 -0
- nano_wait-3.0/nano_wait/cli.py +58 -0
- nano_wait-3.0/nano_wait/core.py +68 -0
- nano_wait-3.0/nano_wait/nano_wait.py +32 -0
- nano_wait-3.0/nano_wait/utils.py +13 -0
- nano_wait-3.0/nano_wait/vision.py +111 -0
- nano_wait-3.0/nano_wait.egg-info/PKG-INFO +61 -0
- {nano_wait-1.3 → nano_wait-3.0}/nano_wait.egg-info/SOURCES.txt +6 -0
- nano_wait-3.0/nano_wait.egg-info/entry_points.txt +2 -0
- nano_wait-3.0/nano_wait.egg-info/requires.txt +9 -0
- {nano_wait-1.3 → nano_wait-3.0}/setup.cfg +4 -4
- nano_wait-3.0/setup.py +48 -0
- nano_wait-1.3/PKG-INFO +0 -388
- nano_wait-1.3/README.md +0 -375
- nano_wait-1.3/nano_wait/__init__.py +0 -1
- nano_wait-1.3/nano_wait/nano_wait.py +0 -76
- nano_wait-1.3/nano_wait.egg-info/PKG-INFO +0 -388
- nano_wait-1.3/nano_wait.egg-info/requires.txt +0 -2
- nano_wait-1.3/setup.py +0 -17
- {nano_wait-1.3 → nano_wait-3.0}/nano_wait.egg-info/dependency_links.txt +0 -0
- {nano_wait-1.3 → nano_wait-3.0}/nano_wait.egg-info/top_level.txt +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Luiz Filipe Seabra de marco
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Luiz Filipe Seabra de marco
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
nano_wait-3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nano_wait
|
|
3
|
+
Version: 3.0
|
|
4
|
+
Summary: Adaptive waiting and smart automation library — includes Wi-Fi, system context, and Vision Mode for screen-based decisions.
|
|
5
|
+
Author: Luiz Filipe Seabra de Marco
|
|
6
|
+
Author-email: luizfilipeseabra@icloud.com
|
|
7
|
+
License: MIT License
|
|
8
|
+
Keywords: automation automação wifi wait vision ocr screen adaptive ai
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
+
Classifier: Topic :: Utilities
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: psutil
|
|
19
|
+
Requires-Dist: pywifi
|
|
20
|
+
Provides-Extra: vision
|
|
21
|
+
Requires-Dist: pyautogui; extra == "vision"
|
|
22
|
+
Requires-Dist: pytesseract; extra == "vision"
|
|
23
|
+
Requires-Dist: pynput; extra == "vision"
|
|
24
|
+
Requires-Dist: opencv-python; extra == "vision"
|
|
25
|
+
Requires-Dist: numpy; extra == "vision"
|
|
26
|
+
Dynamic: author
|
|
27
|
+
Dynamic: author-email
|
|
28
|
+
Dynamic: classifier
|
|
29
|
+
Dynamic: description
|
|
30
|
+
Dynamic: description-content-type
|
|
31
|
+
Dynamic: keywords
|
|
32
|
+
Dynamic: license
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: provides-extra
|
|
35
|
+
Dynamic: requires-dist
|
|
36
|
+
Dynamic: requires-python
|
|
37
|
+
Dynamic: summary
|
|
38
|
+
|
|
39
|
+
# Nano-Wait Vision Module
|
|
40
|
+
|
|
41
|
+
Nano-Wait agora inclui um módulo de **Visão Inteligente**, capaz de ler números diretamente da tela e tomar decisões automáticas em aplicativos ou vídeos.
|
|
42
|
+
|
|
43
|
+
## Funcionalidades principais
|
|
44
|
+
|
|
45
|
+
- **Múltiplas regiões**: capture números de várias áreas da tela ao mesmo tempo.
|
|
46
|
+
- **Marcação interativa**: selecione regiões da tela facilmente usando o mouse com `mark_region()`.
|
|
47
|
+
- **Modos inteligentes**:
|
|
48
|
+
- `observe`: apenas lê e exibe números.
|
|
49
|
+
- `decision`: lê números e executa ações automáticas com base em valores.
|
|
50
|
+
- `learn`: registra padrões visuais para uso futuro.
|
|
51
|
+
- **Ações automatizadas**: clique duplo, pular itens, etc.
|
|
52
|
+
- Compatível com macOS, Windows e Linux.
|
|
53
|
+
|
|
54
|
+
## Instalação
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install -e .
|
|
58
|
+
# Dependências para o módulo de visão
|
|
59
|
+
pip install pyautogui pytesseract pynput opencv-python-headless
|
|
60
|
+
# macOS: instale o Tesseract OCR
|
|
61
|
+
brew install tesseract
|
nano_wait-3.0/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Nano-Wait Vision Module
|
|
2
|
+
|
|
3
|
+
Nano-Wait agora inclui um módulo de **Visão Inteligente**, capaz de ler números diretamente da tela e tomar decisões automáticas em aplicativos ou vídeos.
|
|
4
|
+
|
|
5
|
+
## Funcionalidades principais
|
|
6
|
+
|
|
7
|
+
- **Múltiplas regiões**: capture números de várias áreas da tela ao mesmo tempo.
|
|
8
|
+
- **Marcação interativa**: selecione regiões da tela facilmente usando o mouse com `mark_region()`.
|
|
9
|
+
- **Modos inteligentes**:
|
|
10
|
+
- `observe`: apenas lê e exibe números.
|
|
11
|
+
- `decision`: lê números e executa ações automáticas com base em valores.
|
|
12
|
+
- `learn`: registra padrões visuais para uso futuro.
|
|
13
|
+
- **Ações automatizadas**: clique duplo, pular itens, etc.
|
|
14
|
+
- Compatível com macOS, Windows e Linux.
|
|
15
|
+
|
|
16
|
+
## Instalação
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install -e .
|
|
20
|
+
# Dependências para o módulo de visão
|
|
21
|
+
pip install pyautogui pytesseract pynput opencv-python-headless
|
|
22
|
+
# macOS: instale o Tesseract OCR
|
|
23
|
+
brew install tesseract
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from .core import NanoWait
|
|
2
|
+
|
|
3
|
+
def wait(t: float, wifi: str = None, speed: float = 1.5, smart: bool = False, verbose: bool = False, log: bool = False):
|
|
4
|
+
"""
|
|
5
|
+
Main API function to wait adaptively.
|
|
6
|
+
|
|
7
|
+
Args:
|
|
8
|
+
t (float): Base wait time in seconds
|
|
9
|
+
wifi (str, optional): Wi-Fi SSID to consider
|
|
10
|
+
speed (float, optional): Speed factor (ignored if smart=True)
|
|
11
|
+
smart (bool, optional): Enable Smart Context Mode
|
|
12
|
+
verbose (bool): Print debug info
|
|
13
|
+
log (bool): Save log
|
|
14
|
+
"""
|
|
15
|
+
nw = NanoWait()
|
|
16
|
+
|
|
17
|
+
if smart:
|
|
18
|
+
pc_score = nw.get_pc_score()
|
|
19
|
+
wifi_score = nw.get_wifi_signal(wifi) if wifi else 5
|
|
20
|
+
risk_score = (pc_score + wifi_score) / 2
|
|
21
|
+
speed = max(0.5, min(5.0, risk_score))
|
|
22
|
+
if verbose:
|
|
23
|
+
print(f"[Smart Context] PC={pc_score:.2f}, Wi-Fi={wifi_score:.2f}, risk={risk_score:.2f}, speed={speed:.2f}")
|
|
24
|
+
|
|
25
|
+
if wifi:
|
|
26
|
+
wait_time = nw.wait_wifi(speed=speed, ssid=wifi)
|
|
27
|
+
else:
|
|
28
|
+
wait_time = nw.wait_n_wifi(speed=speed)
|
|
29
|
+
|
|
30
|
+
if verbose:
|
|
31
|
+
print(f"[NanoWait] PC+WiFi wait = {wait_time:.2f}s")
|
|
32
|
+
|
|
33
|
+
import time
|
|
34
|
+
time.sleep(wait_time)
|
|
35
|
+
|
|
36
|
+
if log:
|
|
37
|
+
with open("nano_wait.log", "a") as f:
|
|
38
|
+
f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - Waited {wait_time:.2f}s\n")
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from . import wait as nano_wait_func
|
|
3
|
+
from .core import NanoWait
|
|
4
|
+
|
|
5
|
+
# Presets tradicionais
|
|
6
|
+
SPEED_PRESETS = {
|
|
7
|
+
"slow": 0.5,
|
|
8
|
+
"normal": 1.5,
|
|
9
|
+
"fast": 3.0,
|
|
10
|
+
"ultra": 5.0
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
def main():
|
|
14
|
+
parser = argparse.ArgumentParser(
|
|
15
|
+
description="Nano-Wait — Adaptive smart wait for Python."
|
|
16
|
+
)
|
|
17
|
+
parser.add_argument("time", type=float, help="Base time in seconds (e.g. 2.5)")
|
|
18
|
+
parser.add_argument("--wifi", type=str, help="Wi-Fi SSID to use (optional)")
|
|
19
|
+
parser.add_argument(
|
|
20
|
+
"--speed",
|
|
21
|
+
type=str,
|
|
22
|
+
default="auto",
|
|
23
|
+
help="Speed preset (slow, normal, fast, ultra) or 'auto'"
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument("--smart", action="store_true", help="Enable Smart Context Mode")
|
|
26
|
+
parser.add_argument("--verbose", action="store_true", help="Show debug output")
|
|
27
|
+
parser.add_argument("--log", action="store_true", help="Write result to log file")
|
|
28
|
+
|
|
29
|
+
args = parser.parse_args()
|
|
30
|
+
|
|
31
|
+
nw = NanoWait()
|
|
32
|
+
|
|
33
|
+
# Determina o speed
|
|
34
|
+
if args.smart:
|
|
35
|
+
# Smart Context Mode
|
|
36
|
+
pc_score = nw.get_pc_score()
|
|
37
|
+
wifi_score = nw.get_wifi_signal(args.wifi) if args.wifi else 5
|
|
38
|
+
risk_score = (pc_score + wifi_score) / 2
|
|
39
|
+
# Quanto maior o risco (pior PC/Wi-Fi), menor o speed → espera maior
|
|
40
|
+
speed_value = max(0.5, min(5.0, risk_score))
|
|
41
|
+
if args.verbose:
|
|
42
|
+
print(f"[Smart Context] PC={pc_score:.2f}, Wi-Fi={wifi_score:.2f}, risk={risk_score:.2f}, speed={speed_value:.2f}")
|
|
43
|
+
elif args.speed.lower() == "auto":
|
|
44
|
+
# Auto-speed simples (sem Smart Context Mode)
|
|
45
|
+
speed_value = 1.5
|
|
46
|
+
else:
|
|
47
|
+
speed_value = SPEED_PRESETS.get(args.speed.lower(), 1.5)
|
|
48
|
+
|
|
49
|
+
nano_wait_func(
|
|
50
|
+
t=args.time,
|
|
51
|
+
wifi=args.wifi,
|
|
52
|
+
speed=speed_value,
|
|
53
|
+
verbose=args.verbose,
|
|
54
|
+
log=args.log
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
main()
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
class NanoWait:
|
|
2
|
+
def __init__(self):
|
|
3
|
+
import platform
|
|
4
|
+
self.system = platform.system().lower()
|
|
5
|
+
# Apenas Windows precisa de pywifi
|
|
6
|
+
if self.system == "windows":
|
|
7
|
+
import pywifi
|
|
8
|
+
self.wifi = pywifi.PyWiFi()
|
|
9
|
+
self.interface = self.wifi.interfaces()[0]
|
|
10
|
+
else:
|
|
11
|
+
self.wifi = None
|
|
12
|
+
self.interface = None
|
|
13
|
+
|
|
14
|
+
def get_pc_score(self):
|
|
15
|
+
import psutil
|
|
16
|
+
try:
|
|
17
|
+
cpu = psutil.cpu_percent(interval=1)
|
|
18
|
+
mem = psutil.virtual_memory().percent
|
|
19
|
+
return (max(0, min(10, 10 - cpu / 10)) + max(0, min(10, 10 - mem / 10))) / 2
|
|
20
|
+
except:
|
|
21
|
+
return 0
|
|
22
|
+
|
|
23
|
+
def get_wifi_signal(self, ssid=None):
|
|
24
|
+
# Retorna 0 se Wi-Fi não disponível
|
|
25
|
+
if self.system == "windows" and self.interface:
|
|
26
|
+
try:
|
|
27
|
+
self.interface.scan()
|
|
28
|
+
import time
|
|
29
|
+
time.sleep(2)
|
|
30
|
+
for net in self.interface.scan_results():
|
|
31
|
+
if ssid is None or net.ssid == ssid:
|
|
32
|
+
return max(0, min(10, (net.signal + 100) / 10))
|
|
33
|
+
except:
|
|
34
|
+
return 0
|
|
35
|
+
elif self.system == "darwin":
|
|
36
|
+
import subprocess
|
|
37
|
+
try:
|
|
38
|
+
out = subprocess.check_output([
|
|
39
|
+
"/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport",
|
|
40
|
+
"-I"
|
|
41
|
+
], text=True)
|
|
42
|
+
line = [l for l in out.split("\n") if "agrCtlRSSI" in l][0]
|
|
43
|
+
rssi = int(line.split(":")[1].strip())
|
|
44
|
+
return max(0, min(10, (rssi + 100) / 10))
|
|
45
|
+
except:
|
|
46
|
+
return 0
|
|
47
|
+
elif self.system == "linux":
|
|
48
|
+
import subprocess
|
|
49
|
+
try:
|
|
50
|
+
out = subprocess.check_output(["nmcli", "-t", "-f", "ACTIVE,SSID,SIGNAL", "dev", "wifi"], text=True)
|
|
51
|
+
for l in out.splitlines():
|
|
52
|
+
active, name, sig = l.split(":")
|
|
53
|
+
if active == "yes" or (ssid and name == ssid):
|
|
54
|
+
return max(0, min(10, int(sig)/10))
|
|
55
|
+
except:
|
|
56
|
+
return 0
|
|
57
|
+
return 0
|
|
58
|
+
|
|
59
|
+
def wait_wifi(self, speed=1.5, ssid=None):
|
|
60
|
+
"""Sempre disponível, mesmo sem pywifi"""
|
|
61
|
+
pc = self.get_pc_score()
|
|
62
|
+
wifi = self.get_wifi_signal(ssid)
|
|
63
|
+
risk = (pc + wifi) / 2
|
|
64
|
+
return max(0.2, (10 - risk)/speed)
|
|
65
|
+
|
|
66
|
+
def wait_n_wifi(self, speed=1.5):
|
|
67
|
+
pc = self.get_pc_score()
|
|
68
|
+
return max(0.2, (10 - pc)/speed)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from .core import NanoWait
|
|
2
|
+
from .utils import log_message, get_speed_value
|
|
3
|
+
|
|
4
|
+
def wait(t: float, wifi: str = None, speed: str | float = "normal", verbose=False, log=False) -> float:
|
|
5
|
+
"""
|
|
6
|
+
Adaptive smart wait — replaces time.sleep() with intelligence.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
t (float): Base wait time in seconds.
|
|
10
|
+
wifi (str, optional): Wi-Fi SSID to evaluate. Defaults to None.
|
|
11
|
+
speed (str|float): 'slow', 'normal', 'fast', 'ultra', or custom float.
|
|
12
|
+
verbose (bool): Print details. Defaults to False.
|
|
13
|
+
log (bool): Write log to file. Defaults to False.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
float: Wait time executed (seconds).
|
|
17
|
+
"""
|
|
18
|
+
speed_value = get_speed_value(speed)
|
|
19
|
+
nw = NanoWait()
|
|
20
|
+
|
|
21
|
+
factor = nw.wait_wifi(speed_value, wifi) if wifi else nw.wait_n_wifi(speed_value)
|
|
22
|
+
wait_time = round(max(0.05, min(t / factor, t)), 3)
|
|
23
|
+
|
|
24
|
+
if verbose:
|
|
25
|
+
print(f"[NanoWait] 🧠 speed={speed_value}, wait={wait_time:.3f}s")
|
|
26
|
+
|
|
27
|
+
if log:
|
|
28
|
+
log_message(f"Wait={wait_time:.3f}s | speed={speed_value}")
|
|
29
|
+
|
|
30
|
+
import time
|
|
31
|
+
time.sleep(wait_time)
|
|
32
|
+
return wait_time
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
def get_speed_value(speed):
|
|
4
|
+
"""Converts speed preset or numeric input to float."""
|
|
5
|
+
speed_map = {"slow": 0.8, "normal": 1.5, "fast": 3.0, "ultra": 6.0}
|
|
6
|
+
if isinstance(speed, str):
|
|
7
|
+
return speed_map.get(speed.lower(), 1.5)
|
|
8
|
+
return float(speed)
|
|
9
|
+
|
|
10
|
+
def log_message(text: str):
|
|
11
|
+
"""Saves messages to nano_wait.log."""
|
|
12
|
+
with open("nano_wait.log", "a") as f:
|
|
13
|
+
f.write(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {text}\n")
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import pytesseract
|
|
3
|
+
import pyautogui
|
|
4
|
+
from pynput.mouse import Controller, Button
|
|
5
|
+
from PIL import ImageGrab, ImageOps
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
class VisionMode:
|
|
9
|
+
"""
|
|
10
|
+
Classe para captura e interpretação visual da tela.
|
|
11
|
+
Modos disponíveis:
|
|
12
|
+
- "observe": apenas lê e exibe dados detectados.
|
|
13
|
+
- "decision": lê dados e toma decisões automáticas.
|
|
14
|
+
- "learn": registra padrões visuais para uso futuro.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, mode="observe"):
|
|
18
|
+
self.mode = mode
|
|
19
|
+
self.mouse = Controller()
|
|
20
|
+
print(f"🔍 VisionMode iniciado no modo '{self.mode}'")
|
|
21
|
+
|
|
22
|
+
def capture_numbers(self, regions=None):
|
|
23
|
+
results = {}
|
|
24
|
+
if not regions:
|
|
25
|
+
regions = [None]
|
|
26
|
+
|
|
27
|
+
for idx, region in enumerate(regions):
|
|
28
|
+
print(f"📸 Capturando região {idx + 1}...")
|
|
29
|
+
if region:
|
|
30
|
+
x, y, w, h = region
|
|
31
|
+
if w <= 0 or h <= 0:
|
|
32
|
+
raise ValueError("Largura e altura devem ser maiores que 0")
|
|
33
|
+
bbox = (x, y, x + w, y + h)
|
|
34
|
+
img = ImageGrab.grab(bbox=bbox)
|
|
35
|
+
else:
|
|
36
|
+
img = ImageGrab.grab()
|
|
37
|
+
|
|
38
|
+
img = ImageOps.grayscale(img)
|
|
39
|
+
text = pytesseract.image_to_string(img)
|
|
40
|
+
print(f"🧠 Texto detectado na região {idx + 1}: {text}")
|
|
41
|
+
|
|
42
|
+
match = re.findall(r'\d+', text)
|
|
43
|
+
numbers = [int(m) for m in match] if match else [0]
|
|
44
|
+
|
|
45
|
+
results[region or f"full_screen_{idx}"] = numbers
|
|
46
|
+
|
|
47
|
+
return results
|
|
48
|
+
|
|
49
|
+
def perform_action(self, action):
|
|
50
|
+
if action == "like_post":
|
|
51
|
+
self.mouse.click(Button.left, 2)
|
|
52
|
+
print("❤️ Ação: clique duplo executado.")
|
|
53
|
+
elif action == "skip_post":
|
|
54
|
+
self.mouse.move(100, 0)
|
|
55
|
+
print("⏭ Ação: pulando item.")
|
|
56
|
+
else:
|
|
57
|
+
print(f"⚙️ Ação desconhecida: {action}")
|
|
58
|
+
|
|
59
|
+
def run(self, regions=None):
|
|
60
|
+
numbers_per_region = self.capture_numbers(regions)
|
|
61
|
+
|
|
62
|
+
if self.mode == "observe":
|
|
63
|
+
for reg, nums in numbers_per_region.items():
|
|
64
|
+
print(f"👁 Região {reg}: números detectados = {nums}")
|
|
65
|
+
|
|
66
|
+
elif self.mode == "decision":
|
|
67
|
+
for reg, nums in numbers_per_region.items():
|
|
68
|
+
for number in nums:
|
|
69
|
+
if number > 1000:
|
|
70
|
+
self.perform_action("like_post")
|
|
71
|
+
else:
|
|
72
|
+
self.perform_action("skip_post")
|
|
73
|
+
|
|
74
|
+
elif self.mode == "learn":
|
|
75
|
+
print("📚 Modo aprendizado ativado: coletando dados...")
|
|
76
|
+
for _ in range(3):
|
|
77
|
+
self.capture_numbers(regions)
|
|
78
|
+
time.sleep(2)
|
|
79
|
+
else:
|
|
80
|
+
print(f"❌ Modo '{self.mode}' inválido.")
|
|
81
|
+
|
|
82
|
+
# ------------------------
|
|
83
|
+
# Nova função: mark_region
|
|
84
|
+
# ------------------------
|
|
85
|
+
@staticmethod
|
|
86
|
+
def mark_region():
|
|
87
|
+
"""
|
|
88
|
+
Captura região usando PyAutoGUI.
|
|
89
|
+
O usuário clica no canto superior esquerdo e inferior direito.
|
|
90
|
+
Retorna (x, y, largura, altura)
|
|
91
|
+
"""
|
|
92
|
+
print("📌 Marque a região desejada:")
|
|
93
|
+
print("Clique no canto superior esquerdo da área desejada e pressione Enter...")
|
|
94
|
+
input("Pressione Enter quando estiver pronto...")
|
|
95
|
+
x1, y1 = pyautogui.position()
|
|
96
|
+
print(f"📍 Ponto superior esquerdo: ({x1}, {y1})")
|
|
97
|
+
|
|
98
|
+
print("Clique no canto inferior direito da área desejada e pressione Enter...")
|
|
99
|
+
input("Pressione Enter quando estiver pronto...")
|
|
100
|
+
x2, y2 = pyautogui.position()
|
|
101
|
+
print(f"📍 Ponto inferior direito: ({x2}, {y2})")
|
|
102
|
+
|
|
103
|
+
x, y = min(x1, x2), min(y1, y2)
|
|
104
|
+
w, h = abs(x2 - x1), abs(y2 - y1)
|
|
105
|
+
|
|
106
|
+
if w == 0 or h == 0:
|
|
107
|
+
print("❌ Largura ou altura inválida. Tente novamente.")
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
print(f"✅ Região marcada: (x={x}, y={y}, largura={w}, altura={h})")
|
|
111
|
+
return (x, y, w, h)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nano_wait
|
|
3
|
+
Version: 3.0
|
|
4
|
+
Summary: Adaptive waiting and smart automation library — includes Wi-Fi, system context, and Vision Mode for screen-based decisions.
|
|
5
|
+
Author: Luiz Filipe Seabra de Marco
|
|
6
|
+
Author-email: luizfilipeseabra@icloud.com
|
|
7
|
+
License: MIT License
|
|
8
|
+
Keywords: automation automação wifi wait vision ocr screen adaptive ai
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
+
Classifier: Topic :: Utilities
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: psutil
|
|
19
|
+
Requires-Dist: pywifi
|
|
20
|
+
Provides-Extra: vision
|
|
21
|
+
Requires-Dist: pyautogui; extra == "vision"
|
|
22
|
+
Requires-Dist: pytesseract; extra == "vision"
|
|
23
|
+
Requires-Dist: pynput; extra == "vision"
|
|
24
|
+
Requires-Dist: opencv-python; extra == "vision"
|
|
25
|
+
Requires-Dist: numpy; extra == "vision"
|
|
26
|
+
Dynamic: author
|
|
27
|
+
Dynamic: author-email
|
|
28
|
+
Dynamic: classifier
|
|
29
|
+
Dynamic: description
|
|
30
|
+
Dynamic: description-content-type
|
|
31
|
+
Dynamic: keywords
|
|
32
|
+
Dynamic: license
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: provides-extra
|
|
35
|
+
Dynamic: requires-dist
|
|
36
|
+
Dynamic: requires-python
|
|
37
|
+
Dynamic: summary
|
|
38
|
+
|
|
39
|
+
# Nano-Wait Vision Module
|
|
40
|
+
|
|
41
|
+
Nano-Wait agora inclui um módulo de **Visão Inteligente**, capaz de ler números diretamente da tela e tomar decisões automáticas em aplicativos ou vídeos.
|
|
42
|
+
|
|
43
|
+
## Funcionalidades principais
|
|
44
|
+
|
|
45
|
+
- **Múltiplas regiões**: capture números de várias áreas da tela ao mesmo tempo.
|
|
46
|
+
- **Marcação interativa**: selecione regiões da tela facilmente usando o mouse com `mark_region()`.
|
|
47
|
+
- **Modos inteligentes**:
|
|
48
|
+
- `observe`: apenas lê e exibe números.
|
|
49
|
+
- `decision`: lê números e executa ações automáticas com base em valores.
|
|
50
|
+
- `learn`: registra padrões visuais para uso futuro.
|
|
51
|
+
- **Ações automatizadas**: clique duplo, pular itens, etc.
|
|
52
|
+
- Compatível com macOS, Windows e Linux.
|
|
53
|
+
|
|
54
|
+
## Instalação
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install -e .
|
|
58
|
+
# Dependências para o módulo de visão
|
|
59
|
+
pip install pyautogui pytesseract pynput opencv-python-headless
|
|
60
|
+
# macOS: instale o Tesseract OCR
|
|
61
|
+
brew install tesseract
|
|
@@ -2,9 +2,15 @@ LICENSE
|
|
|
2
2
|
README.md
|
|
3
3
|
setup.py
|
|
4
4
|
nano_wait/__init__.py
|
|
5
|
+
nano_wait/__main__.py
|
|
6
|
+
nano_wait/cli.py
|
|
7
|
+
nano_wait/core.py
|
|
5
8
|
nano_wait/nano_wait.py
|
|
9
|
+
nano_wait/utils.py
|
|
10
|
+
nano_wait/vision.py
|
|
6
11
|
nano_wait.egg-info/PKG-INFO
|
|
7
12
|
nano_wait.egg-info/SOURCES.txt
|
|
8
13
|
nano_wait.egg-info/dependency_links.txt
|
|
14
|
+
nano_wait.egg-info/entry_points.txt
|
|
9
15
|
nano_wait.egg-info/requires.txt
|
|
10
16
|
nano_wait.egg-info/top_level.txt
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[egg_info]
|
|
2
|
-
tag_build =
|
|
3
|
-
tag_date = 0
|
|
4
|
-
|
|
1
|
+
[egg_info]
|
|
2
|
+
tag_build =
|
|
3
|
+
tag_date = 0
|
|
4
|
+
|
nano_wait-3.0/setup.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as arq:
|
|
4
|
+
readme = arq.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name='nano_wait',
|
|
8
|
+
version='3.0',
|
|
9
|
+
license='MIT License',
|
|
10
|
+
author='Luiz Filipe Seabra de Marco',
|
|
11
|
+
author_email='luizfilipeseabra@icloud.com',
|
|
12
|
+
description=(
|
|
13
|
+
u'Adaptive waiting and smart automation library — '
|
|
14
|
+
u'includes Wi-Fi, system context, and Vision Mode for screen-based decisions.'
|
|
15
|
+
),
|
|
16
|
+
long_description=readme,
|
|
17
|
+
long_description_content_type="text/markdown",
|
|
18
|
+
keywords='automation automação wifi wait vision ocr screen adaptive ai',
|
|
19
|
+
packages=find_packages(),
|
|
20
|
+
install_requires=[
|
|
21
|
+
'psutil',
|
|
22
|
+
'pywifi'
|
|
23
|
+
],
|
|
24
|
+
extras_require={
|
|
25
|
+
"vision": [
|
|
26
|
+
"pyautogui",
|
|
27
|
+
"pytesseract",
|
|
28
|
+
"pynput",
|
|
29
|
+
"opencv-python",
|
|
30
|
+
"numpy"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
,
|
|
34
|
+
entry_points={
|
|
35
|
+
'console_scripts': [
|
|
36
|
+
'nano-wait = nano_wait.cli:main',
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
classifiers=[
|
|
40
|
+
"Programming Language :: Python :: 3",
|
|
41
|
+
"License :: OSI Approved :: MIT License",
|
|
42
|
+
"Operating System :: OS Independent",
|
|
43
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
44
|
+
"Topic :: Utilities",
|
|
45
|
+
"Intended Audience :: Developers",
|
|
46
|
+
],
|
|
47
|
+
python_requires='>=3.8',
|
|
48
|
+
)
|