rpa-suite 1.4.2__py3-none-any.whl → 1.4.6__py3-none-any.whl

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.
rpa_suite/__init__.py CHANGED
@@ -26,6 +26,7 @@
26
26
  ``printer``: Functions for formatted output
27
27
  ``regex``: Operations with regular expressions
28
28
  ``validate``: Data validation functions
29
+ ``Browser``: Object Browser automation functions (neeeds Selenium and Webdriver_Manager)
29
30
 
30
31
  pt-br
31
32
  -----
@@ -55,6 +56,8 @@
55
56
  ``printer``: Funções para output formatado
56
57
  ``regex``: Operações com expressões regulares
57
58
  ``validate``: Funções de validação de dados
59
+ ``Browser``: Objeto de Automação de Navegadores (necessario Selenium e Webdriver_Manager)
58
60
  """
59
61
 
60
- from .suite import Suite as rpa
62
+ from .suite import rpa
63
+ rpa
@@ -3,9 +3,12 @@
3
3
  """
4
4
  The Core module is where we can import all Sub-Objects used by the rpa_suite module separately, categorized by their respective classes based on functionality. However, we can also use them through the main rpa object using the following syntax:
5
5
  >>> from rpa_suite import rpa
6
- >>> rpa.clock.wait_for_exec()
6
+ >>> rpa.clock.wait_for_exec(foo)
7
7
  >>> rpa.file.screen_shot() ...
8
- among others.
8
+ or
9
+ >>> from rpa_suite.core.clock import Clock
10
+ >>> clock = Clock()
11
+ >>> clock.wait_for_exec()
9
12
 
10
13
  pt-br
11
14
  ----------
@@ -13,9 +16,13 @@ O módulo Core é de onde podemos importar todos os Sub-Objetos usados pelo mód
13
16
  >>> from rpa_suite import rpa
14
17
  >>> rpa.clock.wait_for_exec()
15
18
  >>> rpa.file.screen_shot() ...
16
- entre outros.
19
+ ou
20
+ >>> from rpa_suite.core.clock import Clock
21
+ >>> clock = Clock()
22
+ >>> clock.wait_for_exec(foo)
17
23
 
18
24
  """
25
+
19
26
  from .clock import Clock
20
27
  from .date import Date
21
28
  from .dir import Directory
@@ -25,3 +32,13 @@ from .log import Log
25
32
  from .print import Print
26
33
  from .regex import Regex
27
34
  from .validate import Validate
35
+
36
+
37
+
38
+ # On this case, we are importing the Browser class only if the selenium and webdriver_manager modules are installed.
39
+ # This is useful to avoid unnecessary imports and dependencies if the user does not need the Browser functionality.
40
+ import importlib.util
41
+
42
+ # from .browser import Browser
43
+ if importlib.util.find_spec("selenium") and importlib.util.find_spec("webdriver_manager"):
44
+ from .browser import Browser
@@ -0,0 +1,299 @@
1
+ # default import
2
+ import os, requests
3
+
4
+ # imports
5
+ from rpa_suite.functions._printer import error_print, alert_print, success_print
6
+
7
+ from selenium import webdriver
8
+ from selenium.webdriver.common.by import By
9
+ from selenium.webdriver.chrome.options import Options
10
+ from selenium.webdriver.support.ui import WebDriverWait
11
+ from selenium.webdriver.support import expected_conditions as EC
12
+ from webdriver_manager.chrome import ChromeDriverManager
13
+ from time import sleep
14
+
15
+
16
+ class Browser():
17
+
18
+ """
19
+ Browser Object for Automation (Work in Progress)
20
+ This class provides an interface for automating browser interactions using
21
+ Google Chrome with a debugging port. It includes methods for starting,
22
+ configuring, navigating, and interacting with the browser. The implementation
23
+ is still under development and may require further enhancements.
24
+
25
+ Attributes:
26
+ driver: The WebDriver instance used to control the browser.
27
+ port (int): The debugging port used to connect to the browser. Default is 9393.
28
+ path_driver (str): The path to the ChromeDriver executable.
29
+
30
+ Methods:
31
+ __init__(port: int = 9393, close_all_chrome_on_this_port: bool = False):
32
+ Initializes the Browser object with the specified debugging port and
33
+ optionally closes all Chrome instances running on the same port.
34
+ configure_browser() -> None:
35
+ Configures the browser with debugging options and initializes the WebDriver.
36
+ start_browser(close_chrome_on_this_port: bool = True, display_message: bool = False):
37
+ Starts the Chrome browser with the specified debugging port and initializes
38
+ the WebDriver.
39
+ find_ele(value, by=By.XPATH, timeout=12, display_message=True):
40
+ Finds a single element on the page using the specified locator strategy.
41
+ get(url: str, display_message: bool = False):
42
+ Navigates the browser to the specified URL.
43
+ _close_all_chrome():
44
+ Closes all Chrome processes forcefully.
45
+ close_browser(display_message: bool = False):
46
+ Closes the browser instance and terminates the associated Chrome processes.
47
+
48
+ pt-br
49
+ ----------
50
+ Objeto Browser para Automação (Em Desenvolvimento)
51
+ Esta classe fornece uma interface para automação de interações com o navegador
52
+ Google Chrome utilizando uma porta de depuração. Inclui métodos para iniciar,
53
+ configurar, navegar e interagir com o navegador. A implementação ainda está em
54
+ desenvolvimento e pode requerer melhorias adicionais.
55
+
56
+ Atributos:
57
+ driver: A instância do WebDriver usada para controlar o navegador.
58
+ port (int): A porta de depuração usada para conectar ao navegador. O padrão é 9393.
59
+ path_driver (str): O caminho para o executável do ChromeDriver.
60
+
61
+ Métodos:
62
+ __init__(port: int = 9393, close_all_chrome_on_this_port: bool = False):
63
+ Inicializa o objeto Browser com a porta de depuração especificada e,
64
+ opcionalmente, fecha todas as instâncias do Chrome que estão sendo executadas
65
+ na mesma porta.
66
+ configure_browser() -> None:
67
+ Configura o navegador com opções de depuração e inicializa o WebDriver.
68
+ start_browser(close_chrome_on_this_port: bool = True, display_message: bool = False):
69
+ Inicia o navegador Chrome com a porta de depuração especificada e inicializa
70
+ o WebDriver.
71
+ find_ele(value, by=By.XPATH, timeout=12, display_message=True):
72
+ Localiza um único elemento na página usando a estratégia de localização especificada.
73
+ get(url: str, display_message: bool = False):
74
+ Navega o navegador para a URL especificada.
75
+ _close_all_chrome():
76
+ Fecha todos os processos do Chrome de forma forçada.
77
+ close_browser(display_message: bool = False):
78
+ Fecha a instância do navegador e termina os processos associados do Chrome.
79
+ """
80
+
81
+ driver: None
82
+ port: int = None
83
+ path_driver = None
84
+
85
+ def __init__(self, port: int = 9393, close_all_chrome_on_this_port: bool = False):
86
+ self.port = port
87
+ self.path_driver = ChromeDriverManager().install()
88
+
89
+ if close_all_chrome_on_this_port: self._close_all_chrome()
90
+ ...
91
+
92
+ def configure_browser(self) -> None:
93
+ """
94
+ Configures the browser instance with specified options and initializes the WebDriver.
95
+ This method sets up the browser with debugging options, maximized window, and disables notifications.
96
+ It also verifies the existence of the ChromeDriver executable at the specified path before creating
97
+ the WebDriver instance.
98
+ Raises:
99
+ FileNotFoundError: If the specified path to the ChromeDriver executable does not exist.
100
+ Exception: For any other errors encountered during the browser configuration process.
101
+ """
102
+
103
+ try:
104
+ # Use the absolute path from comment
105
+
106
+ options = Options()
107
+ options.add_experimental_option("debuggerAddress",
108
+ f"127.0.0.1:{str(self.port)}")
109
+
110
+ # Additional configs
111
+ options.add_argument("--start-maximized")
112
+ options.add_argument("--disable-notifications")
113
+
114
+ # Verifica se o caminho do driver está correto
115
+ if not os.path.exists(self.path_driver):
116
+ raise FileNotFoundError(f'O caminho do driver não foi encontrado: {self.path_driver}')
117
+
118
+ # Create driver with options and chromedriver path
119
+ self.driver = webdriver.Chrome(
120
+ #service=self.path_driver,
121
+ options=options,
122
+ keep_alive=True
123
+ )
124
+
125
+ except Exception as e:
126
+ error_print(f'Erro durante a função: {self.configure_browser.__name__}! Error: {str(e)}.')
127
+
128
+ def start_browser(self, close_chrome_on_this_port: bool = True, display_message: bool = False):
129
+ """
130
+ Starts a Chrome browser instance with remote debugging enabled.
131
+ Args:
132
+ close_chrome_on_this_port (bool): If True, closes any existing Chrome instance using the specified debugging port before starting a new one. Defaults to True.
133
+ display_message (bool): If True, displays a success message upon successfully starting the browser. Defaults to False.
134
+ Raises:
135
+ Exception: If an error occurs while starting the browser or connecting to the debugging port.
136
+ Behavior:
137
+ - Closes any existing Chrome instance on the specified debugging port if `close_chrome_on_this_port` is True.
138
+ - Launches Chrome with the specified debugging port and user data directory.
139
+ - Waits until Chrome is fully initialized and accessible via the debugging port.
140
+ - Configures the browser instance using the `configure_browser` method.
141
+ - Optionally displays a success message if `display_message` is True.
142
+ """
143
+
144
+ try:
145
+ if close_chrome_on_this_port: self.close_browser()
146
+
147
+ # Inicia o Chrome com debugging port
148
+ os.system(f'start chrome.exe --remote-debugging-port={str(self.port)} --user-data-dir="C:/temp/chrome_profile"')
149
+
150
+ # Aguardar até que o Chrome esteja realmente aberto
151
+ while True:
152
+ try:
153
+ # Tenta conectar ao Chrome na porta de depuração
154
+ response = requests.get(f'http://127.0.0.1:{self.port}/json')
155
+ if response.status_code == 200:
156
+ break # O Chrome está aberto
157
+ except requests.ConnectionError:
158
+ sleep(1) # Espera um segundo antes de tentar novamente
159
+
160
+ # Inicializa o Chrome com as opções
161
+ self.configure_browser()
162
+
163
+ if display_message: success_print(f'Browser: Iniciado com sucesso!')
164
+
165
+ except Exception as e:
166
+ error_print(f'Erro ao iniciar navegador: {str(e)}.')
167
+
168
+
169
+ def find_ele(self, value, by=By.XPATH, timeout=12, display_message=True):
170
+ """
171
+ Locate and return a web element on the page using the specified locator strategy.
172
+ Args:
173
+ value (str): The locator value to identify the web element.
174
+ by (selenium.webdriver.common.by.By, optional): The locator strategy to use.
175
+ Defaults to By.XPATH.
176
+ timeout (int, optional): The maximum time to wait for the element to appear, in seconds.
177
+ Defaults to 12.
178
+ display_message (bool, optional): Whether to display an error message if the element
179
+ is not found. Defaults to True.
180
+ Returns:
181
+ selenium.webdriver.remote.webelement.WebElement: The located web element if found.
182
+ None: If the element is not found or an exception occurs.
183
+ Raises:
184
+ Exception: Propagates any exception encountered during the element search if
185
+ `display_message` is set to False.
186
+ """
187
+
188
+ try:
189
+ sleep(2)
190
+ element = WebDriverWait(self.driver, timeout).until(
191
+ EC.presence_of_element_located((by, value))
192
+ ); return element
193
+
194
+ except Exception as e:
195
+
196
+ if display_message:
197
+ error_print(f'Erro durante a função: {self.find_ele.__name__}! Error: {str(e)}.')
198
+ return None
199
+ else: return None
200
+
201
+ # find elements (needs implementation)
202
+ ...
203
+
204
+ # navigate
205
+ def get(self, url: str, display_message: bool = False):
206
+ """
207
+ Navigates the browser to the specified URL.
208
+ Args:
209
+ url (str): The URL to navigate to.
210
+ display_message (bool, optional): If True, displays a success message upon navigation. Defaults to False.
211
+ Raises:
212
+ Exception: If an error occurs while navigating to the URL, it logs the error message.
213
+ """
214
+
215
+ try:
216
+ self.driver.get(url)
217
+ if display_message: success_print(f'Browser: Navegando para: {url}')
218
+
219
+ except Exception as e:
220
+ error_print(f'Erro ao navegar para a URL: {url}. Error: {str(e)}.')
221
+
222
+
223
+ def _close_all_browsers(self):
224
+ """
225
+ Forcefully closes all instances of Google Chrome running on the system.
226
+ This method uses the `taskkill` command to terminate all processes with the name
227
+ "chrome.exe". Any errors during the execution of the command are silently ignored.
228
+ Note:
229
+ This method is specific to Windows operating systems and will not work on other platforms.
230
+ """
231
+
232
+ try:
233
+ os.system('taskkill /F /IM chrome.exe >nul 2>&1')
234
+ except:
235
+ pass
236
+
237
+
238
+ def close_browser(self, display_message: bool = False):
239
+ """
240
+ Fecha o navegador controlado pelo Selenium e encerra os processos relacionados ao Chrome.
241
+ Este método tenta fechar o navegador de forma ordenada utilizando os métodos `close` e `quit` do Selenium.
242
+ Caso esses métodos falhem, ele força o encerramento do processo do Chrome associado à porta de depuração remota.
243
+ Em último caso, pode encerrar todos os processos do Chrome relacionados à porta especificada.
244
+ Args:
245
+ display_message (bool): Indica se mensagens de status devem ser exibidas durante o processo de fechamento.
246
+ Comportamento:
247
+ - Tenta fechar o navegador utilizando `self.driver.close()` e `self.driver.quit()`.
248
+ - Aguarda um momento para liberar o processo.
249
+ - Força o encerramento do processo do Chrome associado à porta de depuração remota.
250
+ - Verifica se o processo foi encerrado e tenta métodos mais agressivos, se necessário.
251
+ - Em caso de falha crítica, tenta encerrar todos os processos do Chrome relacionados à porta especificada.
252
+ Exceções:
253
+ - Captura e exibe mensagens de erro caso ocorra falha ao fechar o navegador.
254
+ Observação:
255
+ Use com cautela, especialmente o encerramento extremo, pois pode afetar outros processos do Chrome em execução.
256
+ """
257
+
258
+ try:
259
+ # Primeiro tenta fechar todas as janelas via Selenium
260
+ try:
261
+ self.driver.close()
262
+ except:
263
+ pass
264
+
265
+ # Depois tenta encerrar a sessão
266
+ try:
267
+ self.driver.quit()
268
+ except:
269
+ pass
270
+
271
+ # Aguarda um momento para o processo ser liberado
272
+ sleep(1)
273
+
274
+ # Força o fechamento do processo específico do Chrome
275
+ os.system(f'taskkill /f /im chrome.exe /fi "commandline like *--remote-debugging-port={str(self.port)}*" >nul 2>&1')
276
+
277
+ # Verifica se o processo foi realmente terminado
278
+ check = os.system(f'tasklist /fi "imagename eq chrome.exe" /fi "commandline like *--remote-debugging-port={str(self.port)}*" >nul 2>&1')
279
+
280
+ if check == 0:
281
+ # Processo ainda existe, tenta método mais agressivo
282
+ os.system(f'taskkill /f /im chrome.exe /fi "commandline like *--remote-debugging-port={str(self.port)}*" /t >nul 2>&1')
283
+ if display_message: alert_print(f'Browser: Fechado via força!')
284
+
285
+ else:
286
+ if display_message: success_print(f'Browser: Fechado com sucesso!')
287
+
288
+ except Exception as e:
289
+
290
+
291
+ try:
292
+ if display_message: alert_print(f'Erro ao fechar navegador: {str(e)}, Tentando meio mais forte!')
293
+
294
+ # Último recurso - mata todos os processos do Chrome (use com cautela)
295
+ os.system(f'taskkill /f /im chrome.exe /fi "commandline like *--remote-debugging-port={str(self.port)}*" /t >nul 2>&1')
296
+ if display_message: alert_print(f'Browser: Fechado via força extrema!')
297
+
298
+ except Exception as error_ultimate:
299
+ if display_message: error_print(f'Falha crítica ao tentar fechar o navegador! Error: {str(error_ultimate)}!')
rpa_suite/core/clock.py CHANGED
@@ -42,7 +42,7 @@ class Clock():
42
42
 
43
43
  def __init__(self):
44
44
  ...
45
-
45
+
46
46
  def exec_at_hour(self,
47
47
  hour_to_exec: str | None,
48
48
  fn_to_exec: Callable[..., Any],
rpa_suite/core/file.py CHANGED
@@ -170,7 +170,7 @@ class File():
170
170
  full_path_with_name = fr'{path_to_create}/{name_file}'
171
171
 
172
172
  with open(full_path_with_name, 'w', encoding='utf-8') as file:
173
- file.write('[T-BOT Crédit Simulation] running in realtime, waiting finish to new execution')
173
+ file.write('[RPA Suite] - Running Flag File')
174
174
  if display_message: success_print("Flag file created.")
175
175
 
176
176
  except Exception as e: