IA PHP pós graduação Python
Chatbot no wordpress – Parte 2b

Neste fragmento criamos uma série de mudanças no plugin do wordpress para centralizar as operações do chatbot.

Git do projeto

https://github.com/marcelomaurin/chatbot-wordpress

Fiz esta modificação para facilitar a gestão dos itens.

Mudanças envolvidas

No plugin foram feitas diversas mudanças, entre elas. Criação de um menu de itens.

Plugin do wordpress

Temos um menu onde temos opções de Teste de funcionalidade do chatbot

Exemplo do chatbot

E o histórico, que mostra as perguntas realizadas, com opção de exclusão de lixo.

Histórico de Pesquisa

O projeto agregou um web service, que permite comunicação com o banco de dados, conforme o projeto historico.php.


<?php
/*phpinfo();*/
/*Registra webservice para processamento de jobs*/
ini_set('display_errors', 'Off');
error_reporting(E_ALL);

include "connectdb.php";

$typereq = $_SERVER['REQUEST_METHOD'];
//echo $typereq;

if ($typereq==='POST')
{
	//echo "POST";
    // The request is using the POST method
	$data = json_decode(file_get_contents("php://input"));
	if($data){
		$localguid = $dbhandle->real_escape_string($data->guid);
		$idhistorico = $dbhandle->real_escape_string($data->idhistorico);
		//echo var_dump(json_decode($foo, true));
	} else {
		$localguid = $dbhandle->real_escape_string($_POST['guid']);
		$idhistorico = $dbhandle->real_escape_string($_POST['idhistorico']);
		//echo "3";
	}
	//echo $localguid;
	//echo $idhistorico;
}

if ($typereq === 'GET') {
	//echo "GET";
    // The request is using the POST method
	$data = json_decode(file_get_contents("php://input"));
	if($data){
		$localguid = $dbhandle->real_escape_string($data->guid);
		$idhistorico = $dbhandle->real_escape_string($data->idhistorico);
	} else {
		$localguid = $dbhandle->real_escape_string($_GET['guid']);
		$idhistorico = $dbhandle->real_escape_string($_GET['idhistorico']);
	}
}

if ($typereq === 'DELETE')
{
	//echo $typereq;
	$data = json_decode(file_get_contents("php://input"));
	if($data){
		$localguid = $dbhandle->real_escape_string($data->guid);
		$idhistorico = $dbhandle->real_escape_string($data->idhistorico);
	} else {
		$localguid = $dbhandle->real_escape_string($_GET['guid']);
		$idhistorico = $dbhandle->real_escape_string($_GET['idhistorico']);
	}
	//$localguid = $data->guid;
	//$idhistorico = $data->idhistorico;
	$query = "delete from historico where idhistorico = ".$idhistorico;
	$dbhandle->query($query);
	//echo ($query);
}

if($localguid!=GUID)
{
	//echo $localguid;
	//echo "  - - ";
	//echo GUID;
	$strJSON =  '{';
	$strJSON = $strJSON . '"mensagem":"Acesso negado"';
	$strJSON = $strJSON . '}';
	echo $strJSON;
	exit();
}


if (($typereq === 'GET')||($typereq === 'POST')){
	if(($idhistorico)&&($idhistorico!='0'))
	{
		$query = "select idhistorico, pergunta from historico where (idhistorico = ".$idhistorico.");";
	} else {
		$query = "select idhistorico, pergunta from historico ;";
	}
	$rs = $dbhandle->query($query);

	$cont = 0;
	//echo $query;
	$strJSON =  '{"rs":[';
	//while($row=$rs->fetch_assoc())
	while($row=$rs->fetch_assoc())
	{

		if($cont!=0)
		{
			$strJSON = $strJSON . ',';
		}
		$strJSON = $strJSON . '{';
		$strJSON = $strJSON . '"idhistorico":'.$row['idhistorico'].',';
		$strJSON = $strJSON . '"pergunta":"'.$row['pergunta'].'"';
		$strJSON = $strJSON . '}';
		$cont ++;
	}
	$strJSON = $strJSON . ']}';
	if ($cont>0)
	{
		echo($strJSON);
	}
}
?>

No código acima, vemos que os verbos do HTML estão contemplados, apesar do sistema apenas usar o POST e DELETE.

O uso destes verbos será modelo para outros web services mais complexos.

Outra melhoria foi o uso de um GUID, que irá aumentar a segurança, restringindo o acesso ao web service, apenas a requisições com a chave correta.

Muitas mudanças ainda serão necessárias, porem estas garantem que nosso chatbot seja mais prático.

Muitas pessoas sabem que um chatbot não precisa deste tipo de melhoria, mas de fato, quando a intensão é o aprendizado, faze-lo de forma que fique mais fácil gerenciar as diversas ações de gestão do chatbot, ajudarão em um futuro próximo.

Há muito o que fazer, espero que acompanhem essa jornada.

Abraço.

IA PHP Python wordpress
Chatbot no wordpress – Parte 2

Agora que criei a página do Chatbot, vou comecar a preparar o recheio.

Definindo objetivo do Chatbot

A primeira coisa que precisamos saber é sobre o que devemos realizar nosso chatbot.

Bom irei falar sobre os projetos da maurinsoft.

Então o primeiro trabalho que irei precisar é criar simulados de perguntas, para facilitar isso, irei criar um conjunto de aplicações.

Neste post irei falar sobre o primeiro.

A melhor forma de criar um conjunto de perguntas é perguntando.

Então vou adicionar ao meu projeto uma tabela historico.

historico.sql

use maurinsoftdb;

create table historico (
  idhistorico int AUTO_INCREMENT PRIMARY KEY,
  pergunta varchar(200) not null,
  ip varchar(40),
  dtquest TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Agora que criei o espaço de armazenamento no banco, irei incluir no web service que processa a pergunta.

Fonte: runpy.php

<?php
    /*phpinfo();*/
	/*Registra webservice para processamento de jobs*/
	ini_set('display_errors', 'ON');
	error_reporting(E_ALL);

	header('Content-Type: application/json');  // <-- header declaration

	include "/var/www/html/python/connectdb.php";

	//header('Cache-Control: no-cache, must-revalidate');

$data = json_decode(file_get_contents("php://input"));

if($data){
		$pergunta = $dbhandle->real_escape_string($data->pergunta);
} else {
		$pergunta = $dbhandle->real_escape_string($_GET['pergunta']);
}

$ip = $_SERVER['REMOTE_ADDR']; /*Pega o ip do cliente*/

//echo "Inseriu";
$query= "INSERT into historico (pergunta, ip) values ( '". $pergunta. "', '".$ip."')";
$dbhandle->query($query); /*Executa*/

$json =  '{"rs":[';
if($pergunta){
  $command = escapeshellcmd('/var/www/html/python/nlp.py "'.$pergunta.'" > /var/log/proclog.log');
  $resposta = shell_exec($command);
  $resposta = str_replace (array("\r\n", "\n", "\r"), ' ', $resposta);

  if($resposta){
     $json = $json  . '{';
     $json = $json  .  '"pergunta":"'.$pergunta.'",';
     $json = $json  .  '"resposta":'.$resposta;
     $json = $json  .  '}';
  } else {
	 $json = $json  . '{';
	 $json = $json  .  '"pergunta":"'.$pergunta.'",';
     $json = $json  .  '"resposta":"'.'sem resposta'.'"';
	 $json = $json  .  '}';
  }
} else {
	$json = $json  . '{';
	$json = $json  .  '"pergunta":"'.$pergunta.'",';
    $json = $json  .  '"resposta":"'.'sem resposta'.'"';
	$json = $json  .  '}';
}
$json = $json  .  ']}';

echo $json
?>

Neste projeto que não irei falar muito, pois ja comentei sobre a maior parte em posts anteriores, fiz a inserção do código abaixo:

//echo "Inseriu";
$query= "INSERT into historico (pergunta, ip) values ( '". $pergunta. "', '".$ip."')";
$dbhandle->query($query); /*Executa*/	

Nela ao receber a pergunta armazenamos ela p pesquisa histórica.

Próximos passos

A seguir os próximos passos que iremos postar.

  • Iremos montar as questões que serão respondidas
  • Iremos cadastrar as respostas possíveis
  • Iremos associar as perguntas as respostas
  • Iremos gerar treinamento da nossa rede
  • Iremos codificar nosso código em python.
Blog C/C++
ISO8583

Este material esta sendo construído.

Objetivo

O objetivo deste artigo é apresentar uma visão geral sobre este protocolo.

Histórico

Criado em 1987 a ISO8583 descreve o intercâmbio entre requisições bancárias.

Funcionamento

Sem entrar muito no detalhe do funcionamento.

Basicamente a imagem abaixo, ilustra o funcionamento do protocolo em linhas gerais.

Visão geral do protocolo

De forma geral, o PDV ou POS solicita a operadora uma dada solicitação.

Por exemplo:

inicio de pagamento com cartão de crédito.

No corpo da solicitação, irão alguns dados identificadores da solicitação.

A operadora, pode conforme o tipo da solicitação, perguntar algumas coisas, como senha, tipo de cartão entre outras coisas.

Ou mesmo solicitar a visualização de outras.

A esta solicitação (chamamos de ação), que deve ser respondida pelo PDV ou POS.

A operadora pode realizar quantas perguntas forem necessárias para atendimento de suas necessidades.

Ao fim a operadora envia a resposta final, dando por encerrado a operação.

Em linhas bem gerais é assim que funciona o protocolo ISO 8583.

Estaremos entrando em detalhes, mais adiante.

Porem para entendimento geral, é um protocolo mestre/escravo, onde após a solicitação inicial, a operadora passa a solicitar informações, que devem ser respondidas.

Identificadores de tipo de mensagens

O identificador de tipo de mensagem é um campo numérico de 4 dígitos que especifica o tipo da mensagem que deve ser processado.

Formatação do cabeçalho da solicitação
  • V: número de versão da ISO 8583 (0 indica que é ISO 8583:1987; 1 indica ISO 8583:1992).
  • n: Classe da Mensagem conforme a tabela abaixo: | 0 Reserved for ISO use | 1 Authorization | 2 Financial | | 3 File action | 4 Reversal/Chargeback | 5 Reconciliation | | 6 Administration | 7 Fee collection | 8 Network management | | 9 Reserved for ISO use | | |
  • X: Função da Mensagem conforme tabela: | 0 Request | 1 Request response | 2 Advice | | 3 Advice response | 4 Notification | 5 – 9 Reserved for ISO use |
  • Y: Origem da Transação | 0 Acquirer | 1 Acquirer repeat | 2 Card issuer | | 3 Card issuer repeat | 4 Other | 5 Other repeat | | 6 –9 Reserved for ISO use | | |

Simulando PDV e Simulando Autorizadora

Eu vasculhando a internet achei o site da neapay, conforme referência.

Baixei um download simulator_ISSUER_ISO8583_host_auth_PRO.

A aplicação trabalha com JAVA, e é uma boa pedida quem deseja testar e aprender mais sobre o protocolo.

Simulação de ISO8583

Referências

C/C++
Threads para Raiz – Parte 2 – Programação C

Neste segundo artigo, utilizaremos o exemplo apresentado e iremos desenvolver nossa aplicação em C para linux.

Github

Para ilustrar nosso exemplo criei uma pasta C no nosso projeto git.

Threads para Raiz – Parte 1

Todos os itens deste artigos estão na pasta C.

Makefile

Para quem acompanha meu canal, o nosso bem amado Makefile é o contrutor da aplicação.

PROGRAMA=threads
PROGRAMA32=threads32

LIBS= -lpthread

CC=gcc

SOURCE= threads.c

all32: clean compile32


all: clean compile

clean:
	rm -f *.o
	rm -f $(PROGRAMA)

compile32:
	$(CC) -m32  $(SOURCE) $(LIBS) -o $(PROGRAMA32)

compile:
	$(CC) $(SOURCE) $(LIBS) -o $(PROGRAMA)

Aqui criamos um construtor para ambas as arquituras 32 e 64bits.

Por padrão iremos manter o uso em 64bits que é a plataforma nativa do meu linux.

Criando a base

O primeiro passo é criar a base do nosso chamador.

Para tanto iremos no main, inicializar as variáveis e chamar os chamadores das threads.

void main(void){
	int rstatus = 0;
	srand(time(NULL));
	pthread_t  pidRecepcao = 0;
	pthread_t  pidControlador = 0;
	pthread_t  pidExecutor = 0;
	//mutex = PTHREAD_MUTEX_INITIALIZER;

	printf("\nBem vindo ao programa das threads\n");
	printf("Este programa faz parte do artigo:\n");
	printf("http://maurinsoft.com.br/index.php/2022/07/02/threads-para-raiz-parte-1/\n\n");
	printf("Inicializando vetor\n\n");
	StartVetor();
	printf("Iniciando Recepcao\n");
	pidRecepcao = Start_Recepcao();
	printf("Iniciando Controlador\n");
	pidControlador = Start_Controlador();
	printf("Iniciando Executor\n");
	pidExecutor = Start_Executor();
	//bool flag = ((pidRecepcao!=0)||(pidControlador!=0)||(pidExecutor!=0));
	flgTerminou = false;
	while(!flgTerminou){
		printf("Status:");

		if(rstatus != 0)
		{
			printf ("Erro ao aguardar finalização do thread A.\n");

		}

		flgTerminou = flgTerminouRecepcao && flgTerminouExecucao;
		sleep(1);
	}
	printf("\n\nFila ordenada:");
	for(int cont = 0;cont<=MAXITEMS-1;cont++)
	{
	  printf("%i ",fila[cont]);
	}
	printf("\n\n");

	printf("\n\nFila executada:");
	for(int cont = 0;cont<=MAXITEMS-1;cont++)
	{
	  printf("%i ",executada[cont]);
	}
	printf("\n\n");

}

As funcoes Start_Recepcao, Start_Controlador, Start_Executor chamam as threads, que serão apresentadas em um próximo momento.

A variavel pidRecepcao , do tipo pthread_t que indica cada uma das threads criadas.

Inicialização de variáveis

A inicialização da fila é feita pela função StartVetor, conforme fonte abaixo:

void StartVetor(){
		for (int cont = 0;cont<=MAXITEMS;cont++)
		{
			fila[cont] = 0;
			executada[cont]=0;

		}
}

Temos também a variável executada, que será utilizada na marcação dos itens executados.

Sessão Crítica

O controle da sessão crítica é feita nas funções IniciaSessaoCritica e TerminaSessaoCritica, conforme fonte abaixo:


int IniciaSessaoCritica()
{
	int  rc;
	int cont = 0;
	while ( (rc = pthread_mutex_lock(&mutex))!=0)
	{
		usleep(100); /*Aguarda um pouco*/
		cont++;
		printf("Sessao critica não conseguida\n");
		if (cont>3) break;
	}
	return rc;


}

int TerminaSessaoCritica()
{
	int  rc;
	int cont = 0;
	while ( (rc = pthread_mutex_unlock(&mutex))!=0)
	{
		usleep(100); /*Aguarda um pouco*/
		cont++;
		printf("Sessao critica não liberada\n");
		if (cont>3) break;
	}
	return rc;


}

Ambas as funções controlam a sessão criada mutex, declarada, conforme fonte abaixo:

pthread_mutex_t    mutex = PTHREAD_MUTEX_INITIALIZER;

Para cada sessão critica, deve-se criar uma variável de controle. Como usaremos apenas a fila, como variável de troca de dados, utilizaremos uma única sessão critica.

Criando a thread da recepção

Agora iremos dar inicio a criação da thread da recepção, na qual incluiremos o inicio da thread.

pthread_t  Start_Recepcao()
{
	pthread_t  pid	= 0;
	int ret;
	ret=pthread_create(&pid,NULL,&threadRecepcao,NULL);

	return pid;
}

Neste segmento do código, podemos acompanhar que criamos a thread com pthread_create, passando o ponteiro da função que será criada a thread threadRecepcao. Desta forma a função threadRecepcao, não mais seguirá na thread pai. O ultimo parâmetro é utilizado para passagens de argumentos, no nosso caso, não será usado.

Por fim a função da thread

/*thread function definition*/
void* threadRecepcao(void* args)
{
	for(int cont = 0;cont<=MAXITEMS;cont++)
	{

		printf("Criando pacote nro %d\n",cont);
		if(IniciaSessaoCritica()==0)
		{
			int Valor = (rand()% 100);
			fila[cont] = Valor; /*Grava Valor na fila*/
			printf("Registrou na fila[%d] = %d\n",cont,Valor);
			TerminaSessaoCritica();
			usleep(1000);
		} else {
				printf("Falha na Recepcao nro:\n",cont);
		}

	}
	printf("Recepcao terminou atendimento\n");

}

Podemos observar que a threadRecepção requisita a sessão crítica para movimentar a fila, apenas depois alocando valor para ela. Também podemos perceber que após seu uso, o mesmo é descartado.

Criando o Controlador

O controlador, é executado, em seguida, ordenando as informações.

void ordenacao()
{
int i, x;
bool flgordenado = false;
while((!flgordenado)&&(!flgTerminou))
{
	//flgordenado = true;
	for (i=0; i<=MAXITEMS-1; i++)
	{
		if ((fila[i]!=0)&&(fila[i+1]!=0))
		{
		  if(fila[i]>fila[i+1])
		  {
		    x = fila[i];
            fila[i] = fila[i+1];
		    fila[i+1] = x;
		    flgordenado = false;
		    //printf("Ordenando os pacote nro %d\n",i);
		  }
		}	else {
			//printf("Posicao vazia %d\n",i);
			flgordenado = false;
		}
    }


  }
}

/*thread function definition*/
void* threadControlador(void* args)
{
  int oldValue, newValue;
  int flgOrdenado = false;
  printf("Iniciou o controlador\n");
  while(!flgTerminou) /*Faz enquanto nao terminar e nao ordenao*/
  {
	if(IniciaSessaoCritica()==0)
	{
		ordenacao();

		TerminaSessaoCritica();
		//usleep(200);

	}
  }

  printf("Terminou ordenação de todos os itens\n");
}

Neste bloco temos duas funções:

A thread em si é a threadControlador, que chama a função de ordenação ordenacao.

A ordenação só para quando for atendida duas condições:

Tiver terminado as demais threads, indicado pelo flag flgTerminou e quando tiver sido totalmente ordenado flgordenado.

Executor

A thread do Executor, pode ser vista conforme apresentado a seguir:

/*thread function definition*/
void* threadExecutor(void* args)
{
  int oldValue, newValue;
  bool flgExecutado = false;
  printf("Iniciou o controlador\n");
  int posicao = 0;
  //while(!flgExecutado)
  while((!flgExecutado)&&(!flgTerminou))
  {
    //printf("Pesquisando Posicao %d\n",posicao);

	//printf("Entrou na sessao critica\n");
	if  (fila[posicao]==0) /*Fila nao foi preenchida*/
	{
		printf("posicao vazia %d\n",posicao);
		posicao = posicao;

	} else
	{
	   executada[posicao] = fila[posicao];
	   printf("Executou[%d] = %d\n",posicao,fila[posicao]);
	   if(posicao==MAXITEMS-1)
	   {
		   printf("Chegou ao fim\n ");
		   flgExecutado= true; /*Finaliza executor*/
	   } else
	   {
		   posicao ++;
	   }

	}
	//printf("terminou while\n");
  }

  flgTerminouExecucao = true;

  printf("Terminou ordenação de todos os itens\n");

}

Ela irá rodar até que duas condições sejam satisfeitas:

  • flgExecutado – Controla a execução de todas as tarefas da lista
  • flgTerminou – Controla o fim de todas as demais threads do sistema

Testando programa

Compilando programa

A compilação em um Raspberry PI ocorreu com sucesso.

Executando o programa

root@raspberrypi:/home/mmm/projetos/Threads-para-Raiz/c# ./threads

Bem vindo ao programa das threads
Este programa faz parte do artigo:
http://maurinsoft.com.br/index.php/2022/07/02/threads-para-raiz-parte-1/

Inicializando vetor

Iniciando Recepcao
Iniciando Controlador
Registrou na fila[0] = 80
Registrou na fila[1] = 11
Registrou na fila[2] = 76
Registrou na fila[3] = 71
Registrou na fila[4] = 27
Registrou na fila[5] = 23
Registrou na fila[6] = 33
Registrou na fila[7] = 68
Registrou na fila[8] = 32
Registrou na fila[9] = 92
Recepcao terminou atendimento
Iniciou o controlador
Iniciando Executor
Status:Iniciou o controlador
Executou[0] = 11
Executou[1] = 23
Executou[2] = 27
Executou[3] = 32
Executou[4] = 33
Executou[5] = 68
Executou[6] = 71
Executou[7] = 76
Executou[8] = 80
Executou[9] = 92
Chegou ao fim
 Terminou ordenação de todos os itens
Status:Terminou ordenação de todos os itens


Fila ordenada:11 23 27 32 33 68 71 76 80 92



Fila executada:11 23 27 32 33 68 71 76 80 92

Como a execução ficou um pouco longa, resolvi jogar como código.

Foto da execução

Conclusão

Podemos perceber que a execução de threads pode ser facilitada com uso de flags externos, que facilitam a comunicação entre os processos. Pudemos ver tambem, que a programação em threads é de fato, um estado de arte da programação C, pois envolve alem de um algoritmo bem desenvolvido, a elaboração de estratégias pensando em que uma thread não sabe exatamente quando a outra irá cumprir suas atividades.

Desta forma cada thread tem que ser pensada em aguardar e esperar as informações das threads que colaboraram com esta.

Desta forma o controle interno das informações é bem mais complicado.

Pudemos ver por ultimo o uso dos sinalizadores, que visão identificar o uso de uma sessão crítica do sistema. Que nada mais é que um recurso compartilhado.

Espero que tenham gostado do artigo.

Em caso de dúvidas ou sugestões, fico a disposição como sempre.

marcelomaurinmartins@gmail.com

Bibliografia

C/C++ Delphi Java Python
Threads para Raiz – Parte 1

Neste primeiro artigo, iremos estabelecer um projeto, que iremos desenvolver nos demais artigos.

Objetivo

A intenção deste projeto é apresentar solução em diversos linguagens de controle de threads com compartilhamento de informações entre elas.

Proposta de projeto

Imagine que temos 3 funcionários em um departamento público.

  • Recepção de Protocolo – Ele recebe os protocolos de serviço dos clientes.
  • Controlador de Serviço – Ele recebe os protocolos da recepção, colocando em ordem numérica em uma fila de execução. Por controlar e ordenar, sua atividade demora tempo mediano.
  • Executor de Serviço – Ele pega o serviço, por executar o serviço é o mais demorado de todos.
Fluxo de execução

Tempo de execução

Ao analisarmos o departamento, fizemos a seguinte constatação:

  • A recepção de protocolo, é o departamento mais rápido.
  • O Controlador de Serviço tem um tempo médio que é o dobro da recepção.
  • Executor de Serviço – Demora o dobro do tempo do controlador de serviço.

Agora que temos o projeto, podemos no próximo artigo começar sua implementação.

Espero voces no próximo artigo 😉

wordpress
Chatbot no wordpress

[chatbot]

Objetivo

Neste tópico incluiremos o chatbot no wordpress, atraves de um shortcode.

Projeto GIT

O código deste projeto pode ser visto no git abaixo:

https://github.com/marcelomaurin/chatbot-wordpress

Ele permite criar um shortcode, que pode ser incluido nos posts.

Onde aparece uma pagina de chat, para que possa interagir.

[chatbot]

O chatbot pode ser incluído na página conforme o link acima.

O chatbot ja incluído nesta página

Nos próximos artigos iremos dar inicio ao código do chatbot, pois este esta apenas com a parte web atualmente.

Java
Java sem nutela no Ubuntu – Parte 3

Estarei neste tópico apresentando como integrar linux com JAVA, de forma que possamos utilizar recursos do sistema operacional de forma que possamos ganhar maior agilidade.

Porque usar o SO

É interessante criar rotinas integráveis para o sistema operacional para ganhar agilidade e performace.

Como utilizar?

Podemos chamar aplicações:

  • shell script– Quando queremos agregar operações em lote, exemplo copiar uma pasta.
  • aplicação terceira – Quando queremos aproveitar features especificas da linguagem, exemplo uso de python para IA.

Quando não utilizar o SO

Existem muitos motivos para usar, e outros motivos que rejeitam o uso.

O mais importante motivo que rejeita seu uso, é quando queremos criar aplicações que não dependem do SO, podendo ser desacoplada de qualquer plataforma.

Aplicações

Aplicações de infra, necessárias para criação de serviços ou recursos, associados a um dado SO.

Podemos utilizar um serviço por exemplo para criar ambientes automatizados, criando ambientes de forma rápida e automática, replicando o que um operador faria em processos manuais.

Exemplos:

  • Clonagem de banco de dados
  • Copiar arquivos
  • Montagem de Serviços
  • Gestão de recursos do SO
  • Manipulação de containers ou serviços.
  • Gestão de testes integrados, etc

Como chamar aplicações

	public static int ProgExt(String Param01, String Param02)  throws IOException {
		int Resultado = 0;
		System.out.println ("Chamando ProgExt... ");
		Runtime rt = Runtime.getRuntime();
        String[] commandAndArguments = {"/home/mmm/projetos/meuproj/scripts/ScripExt.sh",  Param01, Param02 };
		System.out.println(commandAndArguments);
        try {
			String s;
			System.out.println ("ProgExt- Exec commandAndArguments completo");
			Process p = rt.exec(commandAndArguments);
			p.waitFor();
			Resultado = p.exitValue();
            System.out.println ("ProgExt- exit: " + Resultado);

            p.destroy();
		} catch(Exception ex) {
            ex.printStackTrace();
        }

		return Resultado;
	}

Ao Realizar a chamada o ScriptExt.sh, passamos os parâmetros, conforme o script abaixo:

#!/bin/bash

ORIGEM=$1
DESTINO=$2

PATH=/home/mmm/projetos/meuproj/scripts


echo "Inicio de Log" >  $PATH/logbkp.log
echo "Iniciando copia de arquivo" >>  $PATH/logbkp.log

/usr/bin/cp -r $ORIGEM $DESTINO >>  $PATH/logbkp.log

O modelo deste script, permite capturar pela shell script os parâmetros recebidos do JAVA, realizando tarefas via scripts, permitindo aproveitar o que o JAVA teria maior dificuldade em realizar.

De fato a automação de cópia, não se enquadra em tarefa difícil, porem em um processo didático exemplifica sua prática.

Outro Exemplo seria copia de banco de dados:

#!/bin/bash

#exemplo de teste
#sh -x  ./clonabanco.sh bancoorigem bancodest

PATH=/home/mmm/projetos/meuproj/scripts

echo "Script de replicação de banco"

databaserep=$1

database=$2

output="output.sql"


echo "Log de execucao da operacao de clonagem de banco" >>  $PATH/logbkp.log

echo "Origem:$databaserep" >>  $PATH/logbkp.log
echo "Destino:$database" >>  $PATH/logbkp.log
echo "Data:`/usr/bin/date`" >>  $PATH/logbkp.log



echo "Iniciando criacao de backup " >>  $PATH/logbkp.log
echo `/usr/bin/mysqldump -uroot -pSENHA $databaserep -r $PATH/output.sql` >> $PATH/logbkp.log


echo "Escrevendo script de copia" >>  $PATH/logbkp.log

echo "CREATE DATABASE $database;"> $PATH/copy.sql
echo "use $database" >> $PATH/copy.sql
echo "SOURCE $PATH/output.sql" >> $PATH/copy.sql

echo "Criando a base destino" >>  $PATH/logbkp.log

echo `/usr/bin/mysql -uroot -pSENHA < $PATH/copy.sql` >> $PATH/logbkp.log

echo "Fim de execução " >>  $PATH/logbkp.log


Podemos ver neste script, o uso de técnica de clonagem do banco de dados, permitindo a integração simples com JAVA.

Com este ultimo artigo, encerramos a série de artigos Java sem Nutela no Ubuntu, espero que tenham gostado.

wordpress
Personalização do WordPress

Os templates tags são informações obtidas do wordpress, que facilitam a captura das informações pelo site.

A lista de templates é muito variada, e pode ser vista no site:

https://codex.wordpress.org/Template_Tags

Mas podemos destacar alguns:

  • the_tags – lista de tags marcados no post.
  • the_category – lista de categorias marcadas no post.

Rodando Querys

É possível rodar uma query incorporada, lendo informações do banco do wordpress, conforme exemplo:

global $wpdb;

$sql = "select * from $wpdb->posts where post_status = 'publish'");

$listagem = $wpdb->get_results($sql);

foreach ($listagem as $value){
    echo $value->post_title;
    echo $value->post_content;
}

Usando WP_QUERY

O WP_QUERY é um query modificado, permitindo fazer filtragens por parâmetros.

$posts = new WP_Query('posts_per_page=1&orderby=rand');

while($posts->have_posts()): $posts->the_post();
    echo the_title();
    echo the_content();
endwhile;

Estarei dando maior foco no WP_Query em outros posts.

Tornar um WORDPRESS restrito

Uma forma simples de restringir o conteúdo de um wordpress, é exigir autenticação.

Isso pode ser visto, se incluirmos no arquivo header.php o seguinte fragmento:

<?php
if (!is_user_logged_in() ){
Header( "location:wp-admin/" );
}
?>

HOOK – Ganchos

Add_Filter

O Add_filter permite interceptar um dado, antes da sua visualização na tela.

Ele utiliza um callback, que é chamado na ocorrência do evento.

Exemplo, exibição do titulo

<?php
add_filter('the_title','view_title', 10,2);

function view_title($value, $id){
  if ($value== "NOVO") {
    $value = "NEW";
  }
  return value;
}
?>

No exemplo toda vez que um Titulo vier com nome novo, ele será substituído por NEW.

Add_action

O add_action é um evento que ocorre no momento da execução do wordpress, que é disparado durante a execução de alguma etapa de montagem da página.

Exemplo, podemos chamar a função inicializa, no momento da inicialização da página.

<?php
add_action('init','inicializa');

function inicializa(){
  echo 'Inicializou';
}

Java
Java sem nutela no Ubuntu – Parte 2

Neste segundo artigo, Java sem nutela, vamos explicar como desenvolver uma aplicação na mão, sem IDE.

No primeiro artigo, expliquei como gerar um hello world, sem nada.

GIT

https://github.com/marcelomaurin/Java-Hello-World

Neste segundo artigo iremos incluir um arquivo de biblioteca JAR alem de explicar o conceito do JAR.

O JAR na verdade é um pacote contendo vários arquivos java, alem de outras informações referentes a criação de um pacote.

Usando um JAR

Primeiro irei explicar como usar o JAR.

O Arquivo JAR deve estar localizado em uma pasta onde os .JAR sejam encontrados, de forma geral, o linux ou qualquer outro sistema operacional, precisa visualizar a variável CLASSPATH

Para isso, iremos alterar o Makefile, incluindo o caminho da nossa lib

JCC=javac
SOURCE= \
	hello.java

TARGET= HelloWorld
PATHLIB=$CLASSPATH:/~/Java-Hello-World/libs

DEBUG= -g

all: compile run

lib:
	export CLASSPATH=$(PATHLIB)

compile:

	$(JCC) $(DEBUG) $(SOURCE)

run:
	java $(TARGET)

A lib só deve ser chamada um unica vez podendo ser incluída nos scripts de inicialização.

make lib

Pronto agora é só incluir seu jar na pasta que vc definiu no script e importar ele no seu código.

Criando seu JAR

A criação do JAR é bem simples, parte do meu artigo foi baseado no git https://github.com/macagua/example.java.helloworld

Meu GIT

https://github.com/marcelomaurin/hello-java

Nele podemos ver o Makefile

JCC=javac
SOURCE= \
	./HelloWorld/Hello.java

TARGET= HelloWorld

CLASS=Hello

DEBUG= -g

all: compile run

compile:
	$(JCC) $(DEBUG) $(SOURCE)

jar:
	jar cfm $(CLASS).jar Manifest.txt  $(TARGET)/$(CLASS).class


run:
	java -cp . $(TARGET).$(CLASS)

runjar:
	java -jar $(CLASS).jar

São dois pontos importantes para discusão.

A criação do jar pelo comando:

jar cfm $(CLASS).jar Manifest.txt $(TARGET)/$(CLASS).class

O jar é o pacote responsável pela criação dos pacotes jar.

No exemplo seguinte, vemos o pacote executado

java -jar $(CLASS).jar

onde o comando testa o pacote.

Criação do Pacote

Criação do Manifest.txt, é o arquivo responsável por dizer o que é.

Manifest-version: 1.0
Created-By: 1.0 (Maurinsoft)
Main-Class: HelloWorld.Hello

Nele encontramos apenas a descrição da classe que será criada (MAIN-CLASS)

Por ultimo os fontes Hello.java

package HelloWorld;

// Meu primeiro programa
class Hello {
	public static void main(String[] args) {
        	System.out.println("Hello, World!");
        }
}

Verificamos neste artigo, que o empacotamento, de fato é uma atividade bem simples e fácil de ser realizada manualmente.

en_USEnglish