miércoles, 3 de abril de 2013

Eliminar caracteres especiales con PostgreSQL

aqui les dejo un query que me envio un amigo, la consulta elimina los caracteres especiales y solo deja letras a-zA-Z y numeros 0-9 usando expresiones regulares. ejecuten la consulta y vean el resultado!
select regexp_replace
('$wan<>tó&or-+,;emove#speci#%&al~\¡?\{[]}''''chars123…..789', '[^a-zA-Z0-9]', '', 'g')
y listo!

miércoles, 27 de marzo de 2013

Gammu y mensajeria de texto (sms) masiva

Wammu es un programa para manejar los datos en el teléfono celular como los contactos, calendario y mensajes. Está creado sobre la biblioteca Gammu, que provee una capa de abstracción para trabajar con diferentes teléfonos celulares de diferentes proveedores (incluyendo Nokia, Sony-Ericsson, Motorola, Samsung, Siemens, Huawei y otros). puedes ir a la pagina oficial y obtener mas informacion http://es.wammu.eu/ instalando
# aptitude install gammu gammu-doc gammu-smsd libgammu7 libgsmsd7
comando para identificar el dispositivo
# gammu -c /etc/gammu-smsdrc --identify
respuesta:
Dispositivo : /dev/ttyUSB0
Fabricante : Huawei
Modelo : unknown (E173)
Firmware : 11.126.85.00.197
IMEI : 352214041427007
IMSI SIM : 734048700255917

NOTA: para las pruebas estoy utilizando un mdoem usb Huawei E173 con un chip de telefono movistar, en la pagina oficial de gammu (http://es.wammu.eu/) puedes ubicar los telefonos y modems soportados ademas del tipo de conexion, para la prueba se utilizo connection = at19200 verificar los puertos del dispositivo que reconoce la pc
# ls -l /dev/tty*
resultado:
crw-rw---- 1 root dialout 188, 0 2013-03-25 14:22 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 2013-03-25 14:22 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2 2013-03-25 14:23 /dev/ttyUSB2
crw-rw---- 1 root dialout 188, 3 2013-03-25 14:23 /dev/ttyUSB3
crw-rw---- 1 root dialout 188, 4 2013-03-25 14:23 /dev/ttyUSB4
crw-rw---- 1 root dialout 188, 5 2013-03-25 14:23 /dev/ttyUSB5

Algunos casos solo reconoce ttyUSB0 al ttyUSB3
El archivo de configuracion por modem conectado, si existen multiples modem es necesario crear un archivo por cada modem. Adicional es necesario identificar por cual puerto salen y entran los sms para el caso de la prueba donde se reconocen 6 puertos se utiliza port = /dev/ttyUSB0 si reconoce 4 puertos el puerto de salida es otro, solo queda probar.
# vim /etc/gammu-smsdrc
[gammu]
port = /dev/ttyUSB0
model =
logformat = textalldate
connection = at19200
synchronizetime = yes
use_locking =
gammuloc =

[smsd]
#Para el demonio SMSD
logfile = /home/usuario/smsdlog
debuglevel = 1
commtimeout = 0
sendtimeout = 10
receivefrequency = 60
phoneid = modem1
#Para la Base de Datos
service = sql
driver = native_pgsql
host = 192.168.1.3
pin = 1234
user = u_test
password = pass_server
database = sms4
guardar y salir :wq el parametro phoneid = modem1 cambia por cada dispositivo conectado, asi identificas cada modem; al igual que puedes crear diferentes archivos para los logs de cada dispositivo para probar el modem conectado puedes utilizar el comando:
# echo "prueba" | gammu -c /etc/gammu-smsdrc --sendsms TEXT 04141111111 -> aqui el nuemero al que envias el sms
Como se observa en el archivo de configuracion existe una BD asociada al proceso database = sms4, es donde se registran los mensajes entrantes y salientes, para crear esta bd utiliza el archivo .sql propio para la instalacion de gammu La estructura de la bd para gammu se encuentra en:
/usr/share/doc/gammu/examples/sql/pgsql.sql
Solo queda crear la bd desde el archivo pgsql.sql
# su - postgres
$ psql 
postgres=# create database sms4 with owner u_fmnh;
postgres=# \q

$ psql sms4 u_fmnh -h localhost < /usr/share/doc/gammu/examples/sql/pgsql.sql

para ejecutar el envio de sms automatico solo hay q levantar el proceso
# gammu-smsd -c /etc/gammu-smsdrc
Si existen mas modems conectados y configurados el parametro -c recibe la ruta de cada configuracion Si deseas probar si todo funciona inserta en la bd creada en la tabla outbox query format sms flash
INSERT INTO outbox("DestinationNumber", "TextDecoded", "CreatorID", "Class")
 VALUES ('04141111111', 'prueba', 'Gammu', '0')

query format sms normal
INSERT INTO outbox("DestinationNumber", "TextDecoded", "CreatorID", "Class")
 VALUES ('04141111111', 'prueba', 'Gammu', '-1')
Si tienes multiples dispositivos conectados y quieres enviar sms por cada uno de ellos debes señalar en el insert a cual modem envias utilizando el parametro de configuracion phoneid en los campos SenderID CreatorID
INSERT INTO outbox ("DestinationNumber", "TextDecoded", "SenderID", "CreatorID", "Coding","Class") 
VALUES ('04141111111','prueba modem1','modem1','modem1',''Default_No_Compression'',0)' 


INSERT INTO outbox ("DestinationNumber", "TextDecoded", "SenderID", "CreatorID", "Coding","Class") 
VALUES ('04141111111','prueba modem1','modem2','modem2',''Default_No_Compression'',0)' 
...y listo!!
Solo queda departe de tu codigo controlar la carga por cada modem, debe existir una mejor forma de balancear la carga del envio de sms, pero aun no lo se.. adicional, reiniciar el servicio si falla...

comenten al respecto.. gracias!

Curl PHP

PHP soporta libcurl, una biblioteca creada por Daniel Stenberg que permite conectarse y comunicarse con diferentes tipos de servidores y diferentes tipos de protocolos. Actualmente, libcurl admite los protocolos http, https, ftp, gopher, telnet, dict, file y ldap. libcurl también admite certificados HTTPS, HTTP, POST, HTTP PUT, subidas mediante FTP (también se puede hacer con la extensión FTP de PHP), subidas basadas en formularios HTTP, proxies, cookies, y autenticación usuario+contraseña. ver toda la info en http://php.net/manual/es/book.curl.php ahora vamos a instalar
# aptitude install php5-curl
luego verifique su configuracion de php con un de momento mostrare un codigo que uso en symfony para obtener la info del CNE a partir de una cedula.. luego usteder jugaran con este y otros codigos como quieran.. paso 1 crear una carpeta functions en proy/lib
$ mkdir /var/www/proy/lib/functions
y dentro de eso creo una clase que contendra un metodo para invocar esta funcion proy/lib/functions/functions.class.php
class functions {
public static function getDatosCne($ci){
        $url="http://www.cne.gov.ve/web/registro_electoral/ce.php?nacionalidad=V&cedula=$ci";
        $curl = curl_init();
        curl_setopt ($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // almacene en una variable
        curl_setopt($curl, CURLOPT_HEADER, true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $cne='';

        if(curl_exec($curl) === false){
            echo 'Curl error: ' . curl_error($curl);
        }else
        {
            $cne = curl_exec($curl);
            $inicio = stripos($cne, '');
            if($inicio){
                $cne_datos = substr($cne,$inicio);

                $fin = stripos($cne_datos, '
'); $cne_datos = substr($cne_datos,0,$fin+8); $cne = $cne_datos; } else{ $cne = false; } } curl_close($curl); return $cne; } }
y luego en mi action uso este metodo para obtener los datos del CNE de una persona en particular..
$cne = functions::getDatosCne($persona->getCi());
y si necesito algun dato en particular de la informacion que estoy recibiendo simplemente hago un explode de la cadena
foreach($personas as $persona){
 $persona_cne = new PersonaCne();
 $persona_cne->setPersonaId($persona->getId());
 $cne = functions::getDatosCne($persona->getCi());
 if($cne){
  $persona_cne->setCne($cne);
  $cne = strip_tags(htmlspecialchars_decode($cne));
  $ci = explode('Nombre:',$cne);
  $n_ci = explode(':',$ci[0]);
  $persona_cne->setCneCi(trim($n_ci[1]));
  $nombre = explode('Estado:',$ci[1]);
  $persona_cne->setCneNombre(trim($nombre[0]));
  $estado = explode('Municipio:',$nombre[1]);
  $persona_cne->setCneEstado(trim($estado[0])); 
  $municipio = explode('Parroquia:',$estado[1]);
  $persona_cne->setCneMunicipio(trim($municipio[0]));
  $parroquia = explode('Centro:',$municipio[1]);
  $persona_cne->setCneParroquia(trim($parroquia[0]));
  $centro = explode('Direccion:',$parroquia[1]);
  $persona_cne->setCneCentro(trim($centro[0])); 
 }
 $persona_cne->save();
}
y listo..