Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1eba2aea9e |
+99
-19
@@ -1,6 +1,8 @@
|
|||||||
|
from asyncio.windows_events import NULL
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
import urllib
|
||||||
|
|
||||||
class AntiCaptcha:
|
class AntiCaptcha:
|
||||||
"""
|
"""
|
||||||
@@ -11,28 +13,106 @@ class AntiCaptcha:
|
|||||||
|
|
||||||
ep: str = ""
|
ep: str = ""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self):
|
||||||
self.ep = "https://localhost:8443"
|
self.ep = "https://localhost:8443"
|
||||||
|
|
||||||
def __request_json_post__ (self, path: str, object: dict):
|
def __request_json_post__(self, path: str, object: dict):
|
||||||
"""
|
|
||||||
## HTTP JSON POST
|
|
||||||
---
|
|
||||||
Este método é responsável por realizar requisições HTTP do tipo POST para objetos JSON.
|
|
||||||
|
|
||||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
"""
|
||||||
"""
|
## HTTP JSON POST
|
||||||
|
---
|
||||||
|
Este método é responsável por realizar requisições HTTP do tipo POST para objetos JSON.
|
||||||
|
|
||||||
url = self.ep + path
|
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
||||||
print("Calling: " + url)
|
"""
|
||||||
|
|
||||||
|
url = self.ep + path
|
||||||
|
print("Calling: " + url)
|
||||||
|
|
||||||
|
apikey = os.environ.get('REPLAY_APIKEY')
|
||||||
|
headers = {"X-API-KEY": apikey}
|
||||||
|
res = requests.post(url, json = object, headers = headers, verify = False)
|
||||||
|
|
||||||
|
if res.status_code >= 400:
|
||||||
|
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
||||||
|
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
||||||
|
return json.loads(res.text)
|
||||||
|
else:
|
||||||
|
return res.text
|
||||||
|
|
||||||
apikey = os.environ.get('REPLAY_APIKEY')
|
def recaptcha_v2 (self, site: str, data_sitekey: str):
|
||||||
headers = {"X-API-KEY": apikey}
|
"""
|
||||||
res = requests.post(url, json = object, headers = headers, verify = False)
|
## Recaptcha V2
|
||||||
|
Este método realiza a quebra de Captchas do tipo V2.
|
||||||
|
|
||||||
if res.status_code >= 400:
|
- Exemplo de site com Captcha V2: https://2captcha.com/demo/recaptcha-v2
|
||||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
---
|
||||||
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
#### Parâmetros:
|
||||||
return json.loads(res.text)
|
- site: Endereço (url) do site que se quer quebrar o Captcha
|
||||||
else:
|
- data_sitekey: Atributo data-sitekey presente no Captcha da página
|
||||||
return res.text
|
- Para encontrar este atributo, é possível utilizar a função Eval do Chrome com o comando:
|
||||||
|
|
||||||
|
'document.getElementById("g-recaptcha").getAttribute("data-sitekey")'
|
||||||
|
|
||||||
|
---
|
||||||
|
#### Retorna:
|
||||||
|
-> Solução do Captcha. Deve ser inserido no campo oculto do captcha na página.
|
||||||
|
- Para encontrar o campo oculto, pode-se utilizar o comando:
|
||||||
|
|
||||||
|
'document.getElementById("g-recaptcha-response")'
|
||||||
|
"""
|
||||||
|
|
||||||
|
site = urllib.parse.quote (site, "")
|
||||||
|
|
||||||
|
object = {
|
||||||
|
"Site": site,
|
||||||
|
"Data": data_sitekey,
|
||||||
|
"Img": "",
|
||||||
|
"To": 300
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.__request_json_post__ ("/ipc/anticaptcha/recaptchav2", object)
|
||||||
|
|
||||||
|
def image2text (self, site: str, img_b64: str):
|
||||||
|
"""
|
||||||
|
## Image to text
|
||||||
|
Este método realiza a quebra de Captchas de imagem.
|
||||||
|
|
||||||
|
- Exemplo de site com Captcha de Imagem: https://seguro.cesgranrio.org.br/login.aspx
|
||||||
|
---
|
||||||
|
#### Parâmetros:
|
||||||
|
- site: Endereço (url) do site que se quer quebrar o Captcha
|
||||||
|
- img_b64: Imagem contendo o Captcha codificada em Base64. Não há forma simples e bem definida para conseguir isso, mas o código DOM JS abaixo talvez ajude:
|
||||||
|
|
||||||
|
'let img = document.getElementById("ImgCapcha1");
|
||||||
|
|
||||||
|
var canvas = document.createElement('CANVAS');
|
||||||
|
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
var dataURL;
|
||||||
|
|
||||||
|
canvas.height = img.naturalHeight;
|
||||||
|
|
||||||
|
canvas.width = img.naturalWidth;
|
||||||
|
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
|
||||||
|
dataURL = canvas.toDataURL();
|
||||||
|
|
||||||
|
dataURL.split(",")[1]'
|
||||||
|
|
||||||
|
---
|
||||||
|
#### Retorna:
|
||||||
|
-> Solução do Captcha. Deve ser inserido no campo de resposta do Captcha para prosseguir.
|
||||||
|
"""
|
||||||
|
|
||||||
|
site = urllib.parse.quote (site, "")
|
||||||
|
|
||||||
|
object = {
|
||||||
|
"Site": site,
|
||||||
|
"Img": img_b64,
|
||||||
|
"To": 300
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.__request_json_post__ ("/ipc/anticaptcha/image2text", object)
|
||||||
|
|||||||
@@ -1,576 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
from time import time
|
|
||||||
import requests
|
|
||||||
import urllib
|
|
||||||
|
|
||||||
class Replay:
|
|
||||||
"""
|
|
||||||
## Replay
|
|
||||||
---
|
|
||||||
Esta classe é utilizada para fazer manipulações com o Replay instalado na máquina. Ela concede acesso às diferentes funcionalidades que o mesmo apresenta na interface do Console, sem que o programador precise realizar WebScraping para acessá-lo.
|
|
||||||
|
|
||||||
Permite por exemplo a extração de configurações definidas para certos repositórios, registro de Logs, manipulação de banco de dados (SQLite), entre várias outras coisas.
|
|
||||||
"""
|
|
||||||
|
|
||||||
ep: str = ""
|
|
||||||
|
|
||||||
def __init__ (self):
|
|
||||||
self.ep = "https://localhost:8443"
|
|
||||||
|
|
||||||
def __request_get__ (self, data: str):
|
|
||||||
|
|
||||||
"""
|
|
||||||
## HTTP GET
|
|
||||||
---
|
|
||||||
Este método é responsável por realizar requisições HTTP do tipo GET.
|
|
||||||
|
|
||||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url = self.ep + data
|
|
||||||
print("Calling: " + url)
|
|
||||||
|
|
||||||
apikey = os.environ.get('REPLAY_APIKEY')
|
|
||||||
headers = {"X-API-KEY": apikey}
|
|
||||||
res = requests.get(url, headers=headers, verify=False)
|
|
||||||
|
|
||||||
if res.status_code >= 400:
|
|
||||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
|
||||||
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
|
||||||
return json.loads(res.text)
|
|
||||||
else:
|
|
||||||
return res.text
|
|
||||||
|
|
||||||
def __request_json_post__ (self, path: str, object: dict):
|
|
||||||
|
|
||||||
"""
|
|
||||||
## HTTP JSON POST
|
|
||||||
---
|
|
||||||
Este método é responsável por realizar requisições HTTP do tipo POST para objetos JSON.
|
|
||||||
|
|
||||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url = self.ep + path
|
|
||||||
print("Calling: " + url)
|
|
||||||
|
|
||||||
apikey = os.environ.get('REPLAY_APIKEY')
|
|
||||||
headers = {"X-API-KEY": apikey}
|
|
||||||
res = requests.post(url, json = object, headers = headers, verify = False)
|
|
||||||
|
|
||||||
if res.status_code >= 400:
|
|
||||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
|
||||||
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
|
||||||
return json.loads(res.text)
|
|
||||||
else:
|
|
||||||
return res.text
|
|
||||||
|
|
||||||
def __request_raw_post__ (self, path: str, data: str):
|
|
||||||
|
|
||||||
"""
|
|
||||||
## HTTP RAW POST
|
|
||||||
---
|
|
||||||
Este método é responsável por realizar requisições HTTP do tipo POST para objetos RAW.
|
|
||||||
|
|
||||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url = self.ep + path
|
|
||||||
print("Calling: " + url)
|
|
||||||
|
|
||||||
apikey = os.environ.get('REPLAY_APIKEY')
|
|
||||||
headers = {"X-API-KEY": apikey}
|
|
||||||
res = requests.post(url, data = data, headers = headers, verify = False)
|
|
||||||
|
|
||||||
if res.status_code >= 400:
|
|
||||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
|
||||||
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
|
||||||
return json.loads(res.text)
|
|
||||||
else:
|
|
||||||
return res.text
|
|
||||||
|
|
||||||
def replay_env_queue_id (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Queue ID
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_QUEUEID", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_QUEUEID")
|
|
||||||
|
|
||||||
def replay_env_alias (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Alias
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_ALIAS", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_ALIAS")
|
|
||||||
|
|
||||||
def replay_env_feature_dir (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Feature Directory
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_FEATUREDIR", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_FEATUREDIR")
|
|
||||||
|
|
||||||
def replay_env_root (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Root
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_ROOT", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_ROOT")
|
|
||||||
|
|
||||||
def replay_env_addr (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Address
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_ADDR", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_ADDR")
|
|
||||||
|
|
||||||
def replay_env_home_dir (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Home Directory
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_HOMEDIR", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_HOMEDIR")
|
|
||||||
|
|
||||||
def replay_env_repo (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Repository
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_REPO", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_REPO")
|
|
||||||
|
|
||||||
def replay_env_ver (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Version
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_VER", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_VER")
|
|
||||||
|
|
||||||
def replay_env_repo_dir (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Repository Directory
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_REPODIR", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_REPODIR")
|
|
||||||
|
|
||||||
def replay_env_data_dir (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Data Directory
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_DATADIR", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_DATADIR")
|
|
||||||
|
|
||||||
def replay_env_instance_alias (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment Instance Alias
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_INSTANCE_ALIAS", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_INSTANCE_ALIAS")
|
|
||||||
|
|
||||||
def replay_env_api_key (self):
|
|
||||||
"""
|
|
||||||
## Replay Environment API Key
|
|
||||||
---
|
|
||||||
Esta função retorna o valor atribuído à variável de ambiente "REPLAY_APIKEY", caso exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return os.environ.get ("REPLAY_APIKEY")
|
|
||||||
|
|
||||||
def sql (self, command:str):
|
|
||||||
"""
|
|
||||||
## SQL Commands Executer
|
|
||||||
Este método faz um requisição SQL no Replay na aba "Banco de Dados"
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- command: Comando SQL que se deseja executar.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> Qualquer que seja o retorno do comando executado.
|
|
||||||
"""
|
|
||||||
|
|
||||||
sql = {
|
|
||||||
"Sql": command
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.__request_json_post__("/api/v1/sql", sql)
|
|
||||||
|
|
||||||
def new_log (self):
|
|
||||||
"""
|
|
||||||
## New Log
|
|
||||||
Este método faz a instanciação de um objeto do tipo "Log" para que ele possa ser registrado no Replay.
|
|
||||||
"""
|
|
||||||
log = {
|
|
||||||
"Alias": str (self.replay_env_alias()),
|
|
||||||
"Dtlog": datetime.now().isoformat() + "Z"
|
|
||||||
}
|
|
||||||
|
|
||||||
return log
|
|
||||||
|
|
||||||
def log (self, log: dict):
|
|
||||||
"""
|
|
||||||
## Log
|
|
||||||
Esta função realiza a postagem de um Log na base de dados do replay, podendo ser visualizado pelo Console.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- log: Este parâmetro é uma instância da classe Logs que deve ser criada a partir do método "new_logs".
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
---
|
|
||||||
"""
|
|
||||||
log["Dtlogend"] = datetime.now().isoformat() + "Z"
|
|
||||||
|
|
||||||
return self.__request_json_post__ ("/api/v1/log/add", log)
|
|
||||||
|
|
||||||
def config_get (self, config_name: str):
|
|
||||||
"""
|
|
||||||
## Configuration Getter
|
|
||||||
Este método busca a configuração associada ao nome recebido no repositório atual.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- config_name: Nome da configuração que se quer procurar o valor.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> O valor associado à configuração procurada.
|
|
||||||
"""
|
|
||||||
|
|
||||||
config_name = urllib.parse.quote(config_name, "")
|
|
||||||
|
|
||||||
return self.__request_get__(f"/api/v1/config/byrepo/{int(os.path.basename(os.getcwd()))}/{config_name}")
|
|
||||||
|
|
||||||
def config_get_global (self, config_name: str):
|
|
||||||
"""
|
|
||||||
## Global Configuration Getter
|
|
||||||
Este método procura entre as configurações globais, uma correspondência ao nome de configuração recebido.
|
|
||||||
|
|
||||||
---
|
|
||||||
### Obs:
|
|
||||||
Uma configuração global é definida diretamente na aba de Configurações do Console do Replay.
|
|
||||||
|
|
||||||
Deve-se clicar em "Adicionar" e digitar o nome da configuração, depois editar o nome da mesma.
|
|
||||||
|
|
||||||
Se uma configuração não está associada a nenhum repositório em específico, isso quer dizer que ela é global.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- config_name: Nome da configuração global que se quer saber o valor.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> O valor da configuração encontrada.
|
|
||||||
-> "" caso a configuração não exista.
|
|
||||||
"""
|
|
||||||
|
|
||||||
config_name = urllib.parse.quote(config_name, "")
|
|
||||||
|
|
||||||
return self.__request_get__("/api/v1/config/global/"+config_name)
|
|
||||||
|
|
||||||
def config_get_all (self):
|
|
||||||
"""
|
|
||||||
## All Configuration Getter
|
|
||||||
Este método busca por todas as configurações contidas no repositório atual.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> Uma lista de dicionários contendo todas as configs e informações sobre elas. Por exemplo:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": número associado a config na base de dados do replay,
|
|
||||||
|
|
||||||
"k": nome associado à config na base de dados do replay,
|
|
||||||
|
|
||||||
"v" valor atribuído à config,
|
|
||||||
|
|
||||||
"t": tipo da config em questão (que pode ser 't', 'p' ou 'json'),
|
|
||||||
|
|
||||||
"repo": repositório ao qual a configuração está associada
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.__request_get__(f"/api/v1/config/byrepo/{int(os.path.basename(os.getcwd()))}")
|
|
||||||
|
|
||||||
def config_get_map (self) -> dict[str, dict]:
|
|
||||||
"""
|
|
||||||
## Configuration Getter Mapper
|
|
||||||
Este método executa o método "config_get_all" para conseguir todas as configurações alocadas para o reposiório do projeto atual. Após isso, cria um dicionário de strings para outros dicionários contendo as configurações recebidas. As strings do primeiro dicionário são o nome associado à configuração.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> Dicionário de strings (nome da configuração) para dicionários (todas as propriedades da configuração).
|
|
||||||
"""
|
|
||||||
|
|
||||||
dict_configs = {}
|
|
||||||
configs = self.config_get_all()
|
|
||||||
|
|
||||||
for config in configs:
|
|
||||||
dict_configs[config["k"]] = config
|
|
||||||
|
|
||||||
return dict_configs
|
|
||||||
|
|
||||||
def open_app (self, id: int):
|
|
||||||
"""
|
|
||||||
## Open Apps
|
|
||||||
Este método realiza a execução de um aplicativo cujo ID foi recebido.
|
|
||||||
|
|
||||||
---
|
|
||||||
### Obs:
|
|
||||||
É importante ressaltar que a execução do aplicativo lançado é síncrona, ou seja, o código não terá sua execução completada antes da finalização do aplicativo.
|
|
||||||
|
|
||||||
Para alguns casos de uso, a execução síncrona é bastante útil, mas para outros, pode dificultar bastante o processo de desenvolvimento.
|
|
||||||
|
|
||||||
Sendo assim, é possível utilizar o recurso de multiThreading do python para que o aplicativo seja executado assíncronamente. Isso é feito através da biblioteca "threading", que não é nativa. Deve-se instalá-la e utilizar de acordo com a necessidade.
|
|
||||||
|
|
||||||
Para maiores informações sobre a biblioteca threading, visite o site:
|
|
||||||
http://pymotw.com/2/threading/
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- id: Identificador do aplicativo que se deseja executar.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
---
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.__request_get__(f"/api/v1/app/run/{id}")
|
|
||||||
|
|
||||||
def cron_reload (self):
|
|
||||||
"""
|
|
||||||
## Cronometer Reload
|
|
||||||
Este método está ligado à página de Agendamentos no Console do Replay. Ele recarrega esta funcionalidade para atualizar os registros de agendamento.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> ???
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.__request_get__("/ipc/cron/reload")
|
|
||||||
|
|
||||||
def menu_get_all_enabled (self):
|
|
||||||
"""
|
|
||||||
Get All Enabled Menus
|
|
||||||
Este método está relacionado à aba de "Menus" do Console do Replay. Todos os menus cadastrados naquela aba e que tenham a checkbox do lado esquerdo marcada deverão ser buscados por este método.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> Lista de dicionários, onde os dicionários são os dados/informações dos menus encontrados.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.__request_get__("/api/v1/menu/enabled")
|
|
||||||
|
|
||||||
def service_stop_all (self):
|
|
||||||
"""
|
|
||||||
## Stop All Services
|
|
||||||
Este método realiza a parada forçada de todos os serviços que estiverem ativos. É possível visualizar quais serviços estão ativos pela aba "Serviços" do Console do Replay. Todos cujo PID tenha um valor diferente de -1 e 0 são serviços que estão, atualmente, ativos.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> "ok" caso o método tenha sido executado corretamente
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.__request_get__("/api/v1/service/op/stopall")
|
|
||||||
|
|
||||||
def exit (self):
|
|
||||||
"""
|
|
||||||
## Exit
|
|
||||||
Finaliza a sessão do Replay. Equivalente a clicar no ícone e depois em "Quit".
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> "ok" caso o método tenha sido executado corretamente.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.__request_get__("/api/v1/exit")
|
|
||||||
except:
|
|
||||||
return "ok"
|
|
||||||
|
|
||||||
def queue_add (self, job_id: int, params: dict = {}):
|
|
||||||
"""
|
|
||||||
## Queue Add
|
|
||||||
Este método adiciona um novo "job" à fila de execução. É possível ver o resultado na aba "Fila" presente na interface do Console do Replay.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- job_id: Identificador do robô, aplicativo ou serviço que se deve adicionar à fila de execução.
|
|
||||||
- params: Parâmetros de execução do robô. Ao rodar um robô pela interface do Replay, é aberto um editor de Objetos JSON. Esse parâmetro é basicamente o editor. Deve ser passado um dicionário contendo todos os parâmetros que se quer informar para a execução do robô.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> "ok" caso a adição à fila tenha ocorrido com sucesso.
|
|
||||||
"""
|
|
||||||
|
|
||||||
object = json.dumps(params)
|
|
||||||
|
|
||||||
return self.__request_raw_post__(f"/api/v1/queue/add/{job_id}", object)
|
|
||||||
|
|
||||||
def queue_get_data (self, queue_id: int):
|
|
||||||
"""
|
|
||||||
## Queue Get Data
|
|
||||||
Este método busca informações sobre um "job" presente na fila.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- queue_id: Identificador do robô na fila que se quer obter os dados. Para obter esta informação, você pode utilizar o método "replay_env_queue_id()".
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> String emulando um objeto JSON com todos os dados passados ao robô no momento da execução (Editor de Objetos JSON).
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.__request_get__(f"/api/v1/queue/getrequest/{queue_id}")
|
|
||||||
|
|
||||||
def queue_get_my_data (self):
|
|
||||||
"""
|
|
||||||
## Queue Get My Data
|
|
||||||
Este método é uma extensão do método "queue_get_data". Ele elimina a necessidade de se adicionar o identificador do robô na fila, já que a variável de ambiente é buscada dentro do método. Além disso, é interessante ressaltar que este método faz a busca de informações sobre o robô que está atualmente rodando.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> String emulando um objeto JSON com todos os dados passados ao robô no momento da execução (Editor de Objetos JSON).
|
|
||||||
"""
|
|
||||||
|
|
||||||
my_data = self.replay_env_queue_id()
|
|
||||||
return self.queue_get_data (my_data)
|
|
||||||
|
|
||||||
def queue_get_my_json (self):
|
|
||||||
"""
|
|
||||||
## Queue Get My JSON
|
|
||||||
Este método é uma extensão do método "queue_get_my_data", mas ele faz com que o objeto seja um dicionário ao invés de uma string. Além disso, é interessante ressaltar que este método faz a busca de informações sobre o robô que está atualmente rodando.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
#### Retorna:
|
|
||||||
-> Dicionário emulando um objeto JSON com todos os dados passados ao robô no momento da execução (Editor de Objetos JSON).
|
|
||||||
"""
|
|
||||||
|
|
||||||
str_obj = self.queue_get_my_data()
|
|
||||||
|
|
||||||
return json.loads(str_obj)
|
|
||||||
|
|
||||||
def queue_abort (self):
|
|
||||||
"""
|
|
||||||
## Queue Abort
|
|
||||||
Este método é utilizado para abortar o processo atual que está sendo executado na fila. É equivalente ao botão "Abortar" presente na aba de "Fila" no Console do Replay.
|
|
||||||
|
|
||||||
É possível abortar mais de um executável na fila. Basta adicioná-lo, esperar que seja executado e então utilizar o método abort.
|
|
||||||
|
|
||||||
#### Lembre-se sempre que este método somente surte efeito no processo ATUAL executado pela fila.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
- "ok": caso tudo tenha ocorrido corretamente e o método tenha abortado um elemento da fila.
|
|
||||||
- None: caso o método tenha sido executado e não haja mais nenhum robô na fila sendo executado atualmente.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.__request_get__("/api/v1/queue/abort")
|
|
||||||
except:
|
|
||||||
return "ok"
|
|
||||||
|
|
||||||
def queue_enqueue (self, job_id: int):
|
|
||||||
"""
|
|
||||||
## Queue Enqueue
|
|
||||||
Este método adiciona a fila um robô cujo ID tenha sido passado como parâmetro.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- job_id: Identificador do robô que se quer adicionar à fila na base de dados do replay.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
-> "ok" caso o robô tenha sido adicionado à fila corretamente.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.__request_get__(f"/api/v1/robots/op/enqueue/{job_id}")
|
|
||||||
|
|
||||||
def error (self, err_msg: str, desc: str):
|
|
||||||
"""
|
|
||||||
## Error
|
|
||||||
Este método é utilizado para postar erros relacionados ao programa, não às APIs, na base de dados do Replay.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Parâmetros:
|
|
||||||
- err_msg: Mensagem de erro que será registrada. Pense nela como um título, deve ser curto e direto ao ponto.
|
|
||||||
- desc: Descrição do erro ocorrido. Aqui devem ser dados mais detalhes acerca do que ocorreu de errado.
|
|
||||||
|
|
||||||
---
|
|
||||||
#### Retorna:
|
|
||||||
- ?
|
|
||||||
"""
|
|
||||||
|
|
||||||
robot_data = self.queue_get_my_data ()
|
|
||||||
|
|
||||||
error = {
|
|
||||||
"Feature": self.replay_env_alias (),
|
|
||||||
"Err": err_msg,
|
|
||||||
"When": datetime.now().isoformat() + "Z",
|
|
||||||
"Stack": "",
|
|
||||||
"InputData": robot_data,
|
|
||||||
"Details": desc
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.__request_json_post__("/api/v1/err", error)
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
Feature: The Replay API client
|
|
||||||
|
|
||||||
Scenario: Testing every environment variable getter
|
|
||||||
Given the Replay client
|
|
||||||
When each one of the getters is called
|
|
||||||
Then all of the returns must be either of the type string or the type None
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: Testing the process of creating and registering a Log
|
|
||||||
Given the Replay client
|
|
||||||
And a Log created
|
|
||||||
When the log method is called
|
|
||||||
Then this new log must be registered in the Replay Data Base
|
|
||||||
|
|
||||||
|
|
||||||
# Since this is a remote repository, it is impossible to test the config getters methods.
|
|
||||||
# They have to be runned inside a local repository wich contains Replay, so, unfortunatelly, they will not be tested, at least not for now.
|
|
||||||
|
|
||||||
|
|
||||||
#It is also not possible to test the open_app method for the same reasons as above.
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: Testing the menu_get_all_enabled method.
|
|
||||||
Given the Replay client
|
|
||||||
When the menu_get_all_enabled method is called
|
|
||||||
Then there must be a list as a return
|
|
||||||
|
|
||||||
|
|
||||||
# Given the fact that the methods "service_stop_all" and "exit" will break the tests chain, they cannot be tested.
|
|
||||||
|
|
||||||
|
|
||||||
# The same from above goes for the "exit" method.
|
|
||||||
|
|
||||||
|
|
||||||
# The queue methods needs some parameters, wich cannot be given, since this test is not made to be launched through Replay and there is no way to know wich are the "job_id"s or "queue_id"s from the tester machine.
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: Testing queue_abort method
|
|
||||||
Given the Replay client
|
|
||||||
When the queue_abort method is called
|
|
||||||
Then there must be None as return, since this test was not runned by Replay
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
from behave import *
|
|
||||||
from cli import Replay
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
# ============================= ENVIRONMENT VARIABLES GETTERS =============================
|
|
||||||
@given(u'the Replay client')
|
|
||||||
def step_impl (context):
|
|
||||||
context.client = Replay ()
|
|
||||||
|
|
||||||
@when(u'each one of the getters is called')
|
|
||||||
def step_impl(context):
|
|
||||||
context.returns = {context.client.replay_env_queue_id(): "context.client.replay_env_queue_id()", context.client.replay_env_alias(): "context.client.replay_env_alias()", context.client.replay_env_feature_dir(): "context.client.replay_env_feature_dir()", context.client.replay_env_root(): "context.client.replay_env_root()", context.client.replay_env_addr(): "context.client.replay_env_addr()", context.client.replay_env_home_dir(): "context.client.replay_env_home_dir()", context.client.replay_env_repo(): "context.client.replay_env_repo()", context.client.replay_env_ver(): "context.client.replay_env_ver()", context.client.replay_env_repo_dir(): "context.client.replay_env_repo_dir()", context.client.replay_env_data_dir(): "context.client.replay_env_data_dir()", context.client.replay_env_instance_alias(): "context.client.replay_env_instance_alias()", context.client.replay_env_api_key(): "context.client.replay_env_api_key()"}
|
|
||||||
|
|
||||||
@then(u'all of the returns must be either of the type string or the type None')
|
|
||||||
def step_impl(context):
|
|
||||||
for ret in context.returns.keys():
|
|
||||||
assert ( type(ret) == type(None) or type(ret) == type("") ), f'Something went wrong with the {context.returns[ret]} variable getter.'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ============================= LOG REGISTERS =============================
|
|
||||||
@given(u'a Log created')
|
|
||||||
def step_impl(context):
|
|
||||||
context.log = context.client.new_log()
|
|
||||||
|
|
||||||
@when(u'the log method is called')
|
|
||||||
def step_impl(context):
|
|
||||||
context.dt_log_end = datetime.now().isoformat() + "Z"
|
|
||||||
context.log_return = context.client.log(context.log)
|
|
||||||
|
|
||||||
@then(u'this new log must be registered in the Replay Data Base')
|
|
||||||
def step_impl(context):
|
|
||||||
assert (context.client.sql("select * from logs")["data"][-1]["dtlogend"] == context.dt_log_end and context.log_return == "ok")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ============================= CONFIGURATION GETTERS =============================
|
|
||||||
# Since this is a remote repository, it is impossible to test the config getters methods.
|
|
||||||
# They have to be runned inside a local repository wich contains Replay, so, unfortunatelly, they will not be tested, at least not for now.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ============================= OPEN APP =============================
|
|
||||||
#It is also not possible to test the open_app method for the same reasons as above.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ============================= GET ALL ENABLED MENUS =============================
|
|
||||||
@when(u'the menu_get_all_enabled method is called')
|
|
||||||
def step_impl(context):
|
|
||||||
context.all_menus_return = context.client.menu_get_all_enabled()
|
|
||||||
|
|
||||||
@then(u'there must be a list as a return')
|
|
||||||
def step_impl(context):
|
|
||||||
assert type(context.all_menus_return) == type([]), "Something went wrong getting the enabled menus."
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Given the fact that the methods "service_stop_all" and "exit" will break the tests chain, they cannot be tested.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The same from above goes for the "exit" method.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The queue methods needs some parameters, wich cannot be given, since this test is not made to be launched through Replay and there is no way to know wich are the "job_id"s or "queue_id"s from the tester machine.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ============================= QUEUE ABORT =============================
|
|
||||||
@when(u'the queue_abort method is called')
|
|
||||||
def step_impl(context):
|
|
||||||
context.queue_abort_return = context.client.queue_abort()
|
|
||||||
|
|
||||||
@then(u'there must be None as return, since this test was not runned by Replay')
|
|
||||||
def step_impl(context):
|
|
||||||
assert (context.queue_abort_return == None), 'Something went wrong with queue_abort.'
|
|
||||||
Reference in New Issue
Block a user