Mostrando entradas con la etiqueta software libre. Mostrar todas las entradas
Mostrando entradas con la etiqueta software libre. Mostrar todas las entradas

martes, septiembre 24, 2013

Developing a jGnash plugin

jGnash is a personal financial software, available as Free Libre Open Source Software (FLOSS). I've been using it since some years, and i can say that is a great software. It has many functionalities, PDF reports and charts, to register and control your incomes and expenses. It just lack of some analysis reports, so i decided to build my own.

It's possible to create plug-ins for jGnash. So you can add a new functionality or a new report, without recompile the whole software. There's a folder in jGnash installation directory called "plugins", in this folder you can add a JAR file containing the new plug-in and next time you start jGnash, it will load your plug-in.

Requirements to build a new plug-in

For build a new plug-in you will need Java programing knowledge, and some specifics thing depending on the kind of functionalities that you are trying to extend. For building new graph charts or reports, I will suggest experience related to: Java Swing, JFreeChart, DynamicJasper and JasperReports. There is not good documentation about packages and source code of jGnash, but you can download the source code and will find is not hard to read, also you will find help on email lists.

According to jGnash help menu, these are the external libraries they use, so could be good also know a little bit about them: args4j, db4o, JasperReports, DynamicJasper, JFreeChart, JGoodies Animation, JGoodies Forms, JGoodies Looks, Apache MINA, XStream and SwingX.

I like Eclipse IDE, so I will use it, but any Java IDE should be good.

Of course, you must have installed jGnash, to link the jars files to your new plugin project.

Architecture

jGnash provides a plug-in system that is easy to understand. The jgnash2.jar provides a interface called: jgnash.plugin.Plugin and a abstract class called: jgnash.plugin.AbstractEnabledAction, to create a new plugin, inside the new plugin jar, just implement the Plugin interface and extend the AbstractEnabledAction.


Also it will be needed to write a couple of lines inside the jar MANIFEST file.

Steps to create a basic plugin

1- Start a new Java Project, this is a normal Java project in Eclipse IDE.

2-In the Java Build Path of the project (Right click on the project, Properties, Java Build Path, Libraries) add the External Jar: jgnash2.jar from your jGnash installation path.


3- Inside the project, create a new file called: MANIFEST.MF

This file must contain something similar to this:

Manifest-Version: 1.0
Plugin-Activator: myplugin.mypackage.MyPlugin
Plugin-Version: 1.0

Where "Plugin-Activator:" points to the class that implements the jgnash.plugin.Plugin interface.

4- Create the Plugin implementation class, that indicate, which menus will be added to the user interface and which actions will be executed. This is a simple example:

package myplugin.mypackage;

import javax.swing.JMenuItem;
import javax.swing.JPanel;

import jgnash.plugin.Plugin;

public class MyPlugin implements Plugin{

    @Override
    public JMenuItem[] getMenuItems() {
        JMenuItem menuItem = new JMenuItem();

        menuItem.putClientProperty(Plugin.PRECEDINGMENUIDREF, "new-command");
        menuItem.setAction(new MyAction());

        return new JMenuItem[] { menuItem };
    }

    @Override
    public String getName() {
        return "My Plugin";
    }

    @Override
    public JPanel getOptionsPanel() {
        return null;
    }

    @Override
    public void start() {
    }

    @Override
    public void stop() {  
    }
}

The line menuItem.putClientProperty(Plugin.PRECEDINGMENUIDREF, "new-command"); will tell to jGnash where to add the new menuItem, the preceding code, indicate before New Command menuItem. Other places you can choose are listed in the source code of jGnash, check this file:

/jgnash2/jgnash-resources/src/main/resources/jgnash/resource/main-frame-actions.xml

Another important line is: menuItem.setAction(new MyAction()); it says, when user clicks this menuItem execute the code inside MyAction class, that we must create later.

5- Implementing AbstractEnabledAction.

package myplugin.mypackage;

import java.awt.event.ActionEvent;

import javax.swing.Action;
import javax.swing.JOptionPane;

import jgnash.ui.actions.AbstractEnabledAction;

public class MyAction extends AbstractEnabledAction {

    public MyAction(){
        putValue(NAME, "Title");
        putValue(Action.SHORT_DESCRIPTION, "Description");
    }
  
    @Override
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(null, "Hello World");
    }
}

It's important to set the "NAME" and "Action.SHORT_DESCRIPTION" values, they will be shown as the title and tool tip text of the menuItem.

The actionPerformed method will be executed when the menuItem is clicked by the user, in this example will show a simple dialog window saying "Hello World".

6- Creating the jar file. In Eclipse, right click over your project, select Export, and then Jar File.


After that, follow the instructions, and take care when "Jar Manifest Specification" windows appear, select the option: "Use existing manifest from workspace", and choose the "MANIFEST.MF" file that we have created before.


7- Copy the generated jar file inside "plugins" folder of jGnash, run jGnash and you will see the message "Hello World" when you click the new menu "Title" inside "File" menu.



Thanks to jGnash developers for this great software. My hope is that lots of jGnash plug-ins come alive to make it a better software for all.

sábado, agosto 27, 2011

Sistema de Comunicación para Redes Internas (SISCORI) hecho en Java

Sistema de Comunicación para Redes Internas (SISCORI) hecho en Java


En Febrero del 2009 publiqué un artículo sobre un proyectito de java hecho en para una materia en la universidad: Simulador del procesador DLX (jbz) hecho en Java, resultando ser uno de los temas más leídos del foro, entonces aquí les va otro proyecto java del tiempo de la universidad: SISCORI.

Prácticamente, SISCORI, es un sistema de mensajería instantánea hecho en java (tipo jabber, pero muy, muy simple), con un protocolo de comunicación simple basado en texto, la interfaz de usuario es awt, allá por el 2004 estaba aprendiendo java, casi no habían libros al respecto y aún no tenía documentación de swing, de hecho usamos un IDE que ya no existe, se llamaba Bluette. SISCORI se compone de dos grupos de programas, los servidores y los clientes, se usa el API estándar de Socketes de java para la transmisión y recepción de datos.

La segunda versión de SISCORI si está hecha en swing, en el tiempo en que JBuilder era lo último!, mucho antes que NetBeans. Esta segunda versión usa el java sound API para capturar el audio del sistema y luego transmitir los bytes de audio sobre una red IP y permitir comunicación oral entre dos personas.

Los proyectos a futuro era integrar ambos programas y hacer una tercera versión que permitiera transmitir video, pero eso nunca sucedió, otros proyectos personales y académicos llegaron a ser prioridad.

Aquí hay más información, he desempolvado el viejo sitio que hicimos para aquel proyecto, también a partir de ahora queda liberado como software libre conforme la GPL v3.


Este es un resumen de una presentación en una feria de tecnología del CONICYT y AIN en el hotel Crowne Plaza en Nicaragua, donde como miembros de ANETIC (Asociación de Estudiantes TIC) presentamos a SISCORI, en el video se puede ver a Janet Wheelock (QEPD) quien era la presidenta de ANETIC en esa fecha.











sábado, julio 03, 2010

¡Soy Libre!

¡Soy Libre!


Hace ya casi un año atrás, a inicios de septiembre se me dio la oportunidad de realizar "Un nuevo reto: estudiar un Máster de Software libre". Ahora, gracias a Dios después de defender el proyecto final del máster ya ¡Soy Libre!.
Soy libre en el aspecto de haber aprendido muchas cosas sobre el software libre y el software de código abierto, pero sobre todo porque ya tengo tiempo libre nuevamente, "que alegre!", "que alegre!"... a descansar un tiempo uff!...





Así finalizó mi ruta por las clases obligatorias y opcionales:


Más allá de lo académico, la experiencia fue excelente, sobre todo por conocer nuevas personas de distintos lugares, con quienes compartía los objetivos de conocer más sobre el software libre, y mucho más aún por encontrar a otro nicaraguense que ha cursado satisfactoriamenbte el master mi nuevo amigo Lenin Silva Colomer, felicidades a él también.

domingo, octubre 18, 2009

Un nuevo reto: Máster oficial de Software libre

Un nuevo reto: Máster oficial de Software libre

Gracias a una beca de la Fundación Carolina (http://www.fundacioncarolina.es) tengo la oportunidad de aumentar, mejorar y formalizar mis conocimientos en el ámbito del software libre, al haber sido uno de los beneficiados para cursar el Máster oficial de Software Libre de la Universitat Oberta de Catalunya (UOC) de España.

La modalidad de enseñanza de la universidad es a distancia, mediante lo que se conoce como e-learning usando la plataforma Web de la UOC. Como sucedía con los antiguos cursos por correspondencia, que ya existían antes de la aparición de Internet, he recibido el primero grupo de documentos físicos y discos para las clases que actualmente me corresponden cursar:
  • Aspectos económicos y modelos de negocio del software libre
  • Desarrollo de aplicaciones Web
  • Implantación de sistemas de software libre
  • Introducción al software libre
  • Sistema operativo GNU/Linux básico
  • Utilidades y herramientas de software libre

Descripción del Máster

"Nace fruto de la necesidad de formar personal cualificado en el ámbito del software libre. La Unión Europea ha recomendado la realización de estudios sobre este ámbito porque, según alega, el habitual desconocimiento del código fuente no permite auditar el funcionamiento real, hecho que puede comprometer seriamente la seguridad de algunos países y la deja en manos de las empresas que crean programas de propiedad.

Basándose en esta realidad mundial, nace este máster oficial que ofrece a los estudiantes diferentes posibilidades dependiendo de su perfil profesional (administrador de redes y sistemas operativos, administrador web y sistemas de comercio electrónico, experto en desarrollo de aplicaciones y dirección de sistemas operativos en entornos de software libre) y de sus intereses.

Este máster oficial nace para dar respuesta a la necesidad del personal cualificado en este segmento, ya que el software libre atrae la atención de empresas y administraciones públicas de todo el mundo.

Países como Brasil, México, Alemania o China fomentan su uso y desarrollo y muchas grandes compañías tecnológicas, como IBM, Apple, SUN Microsystems y Netscape, dan apoyo al movimiento del software libre y de código abierto, tanto liberando algunos de sus productos estrella, como Mozilla y OpenOffice, como participando en el desarrollo de programas como Eclipse y MacOS X, entre otros."

http://www.uoc.edu/estudios/mofs/software_libre/presentacion/index.html

El plan de estudios

Sobre la Universitat Oberta de Catalunya (UOC) en la Wikipedia

http://es.wikipedia.org/wiki/UOC

Dios permita que supere este nuevo reto!.

lunes, octubre 12, 2009

Microsoft afirma que el Open Source Software es una solución para las necesidades de los gobiernos.

Microsoft afirma que el Open Source Software es una solución para las necesidades de los gobiernos.


En una entrevista de CNN por Gabriela Frías, este pasado 11 de octubre, el vicepresidente de Microsoft Latinoamérica, Hernan Rincón, ha admitido que el Software de Código abierto es una alternativa que resuelve las necesidades de los gobiernos de américa latina.

Aparentemente la participación del señor Hernan en CNN era principalmente para hablar del lanzamiento de su nuevo sistema operativo para móviles: Windows Mobile 6.5, como parte de la respuesta de Microsoft al sistema operativo y entornos de desarrollo del IPhone de Apple y Android de Google, pero como todos los periodistas que preguntan sobre temas más polémicos o difíciles para el entrevistado, la señora Frías, aprovechó el momento para previamente hablar de los sistemas de Código Abierto y los gobiernos, a lo cual el señor Hernan comentó:

"Todos los gobiernos tienen como parte de su estrategía la tecnología de OSS (Open Source Software) y la tecnología de Microsoft y lo apropiado hoy en día es buscar la mejor solución para las necesidades específicas del gobierno, y si ello es nuestra tecnología o la tecnología de OSS que así sea, lo importante es que haya opciones en el mercado y nosotros siempre respetamos y convivimos e interoperamos con la tecnología de OSS." - La economía y la tecnología, Hernan Rincón (vicepresidente de Microsoft Latinoamérica) opina sobre el impacto de la tecnología en la región. Entrevista de CNN por Gabriela Frías (11 de octubre).



En la Web de CNN se puede ver la entrevista completa (6 minutos aproximadamente).

http://edition.cnn.com/video/?/video/spanish/2009/10/11/WEBtec.cnn

domingo, febrero 15, 2009

Simulador del procesador DLX (jbz) hecho en Java


Ordenando directorios viejos en mi disco duro, me encontré con un proyecto viejo de cuando estaba en la universidad llevando la clase de Arquitectura de Máquinas III, y me pareció interesante compartirlo, ya que quizás sea de utilidad para alguien, por lo cual dedico este artículo a dicho proyectito, en general este artículo es un estracto del trabajo entregado para dicha clase mencionada anteriormente, aquí se puede descargar el documento completo en PDF:

http://sites.google.com/site/denisjtorresg/simulador_dlx_jbz.pdf

Descargar

Dicho proyectito fue realizado como parte de una clase en la universidad, por lo cual probablemente puede ser mejorado, en esta URL se puede descargar el código fuente y la documentación del proyecto.

http://sites.google.com/site/denisjtorresg/dlxjbz.zip

Introducción ¿Qué es DLX (jbz)?
DLX (jbz) es un simulador del procesador DLX segmentado. Es un programa hecho en JAVA lo cual permite su portabilidad a múltiples arquitecturas de sistemas de cómputo (ver Requerimientos del Sistema).
El simulador DLX (jbz) después de leer un archivo conteniendo código DLX, muestra información importante sobre el CPU (pipeline, registros, memoria, ...) mientras se ejecuta el código paso a paso o continuamente. DLX (jbz) ofrece estadísticas sobre el comportamiento del cause a lo largo del tiempo.
La segmentación encausada es una técnica de implementación que consiste en solapar la ejecución de múltiples instrucciones en el tiempo, en los procesadores que implementan esta técnica la ejecución de una instrucción se divide en diferentes fases y el procesador se organiza en unidades o secciones de ejecución relativamente independientes llamadas segmentos o etapas. El objetivo de la segmentación es conseguir una instrucción por ciclo, aunque cada instrucción por separado ocupe varios ciclos (CPI>1).


Diseño del Simulador

Estructura Lógica del Simulador DLX (jbz):

El simulador DLX (jbz) cuenta con 32 registros enteros de propósito general, nombrados de R0 a R31. Está segmentado en 5 etapas, las cuales son: BUS, D/L, ALU, MEM, y ESC.
Etapa Descripción
BUS Etapa de búsqueda o fetch de la instrucción e incremento del PC
D/L Decodificación/Carga de operandos (registros) en ALU
ALU Ejecución de operaciones y cálculo de direcciones efectivas de datos
MEM Acceso a memoria para lectura (M->R) o para escritura (R->M)
ESC Escritura de resultados en los registros
Cuenta con una memoria de 100 casillas, numeradas de 000 a 099. En la memoria se almacena el código fuente que se ejecuta en el simulador, así como valores enteros resultado de operaciones de escritura en memoria.

Formato de instrucciones del DLX (jbz):

El formato de instrucción del DLX (jbz) es el siguiente:
Cálculo OP RD,RF1,RF2 RD = RF1 OP RF2
Acceso a Memoria LW RD,DB(RF) RD = M[RF + DB]
Escritura en Memoria SW DB(RF1),RF2 M[RF1 + DB] = RF2
Significado de simbología:
Símbolo Descripción
OP Indica un tipo de operación
RD Registro destino
RF1 Registro fuente primero
RF2 Registro fuente segundo
DB Dirección de memoria base
RF Registro Fuente

Juego de instrucciones del DLX (jbz):

Cada instrucción cargada en el simulador DLX (jbz) ocupa una casilla de memoria. En el código fuente del programa las MAYUSCULAS y minúsculas se tratan por igual.
Instrucción Ejemplo Descripción
ADDI ADDI R1,R0,7 Suma el Registro Fuente con una Constante y el resultado se almacena en el Registro Destino.
SUBI SUBI R1,R0,7 Resta el Registro Fuente de una Constante y el resultado se almacena en el Registro Destino.
ORI ORI R1,R0,7 Aplica la operación OR a nivel de bits, entre el Registro Fuente con una Constante y el resultado se almacena en el Registro Destino.
ANDI ANDI R1,R0,7 Aplica la operación AND a nivel de bits, entre el Registro Fuente con una Constante y el resultado se almacena en el Registro Destino.
XORI XORI R1,R0,7 Aplica la operación XOR a nivel de bits, entre el Registro Fuente con una Constante y el resultado se almacena en el Registro Destino.
ADD ADD R3,R1,R2 Suma el Registro Fuente 1 con el Registro Fuente 2 y el resultado se almacena en el Registro Destino.
SUB SUB R3,R1,R2 Resta el Registro Fuente 1 del Registro Fuente 2 y el resultado se almacena en el Registro Destino.
MULT MULT R3,R1,R2 Multiplica el Registro Fuente 1 con el Registro Fuente 2 y el resultado se almacena en el Registro Destino.
DIV DIV R3,R1,R2 Divide el Registro Fuente 1 entre el Registro Fuente 2 y el resultado se almacena en el Registro Destino.
OR OR R3,R1,R2 Aplica la operación OR a nivel de bits, entre el Registro Fuente 1 con el Registro Fuente 2 y el resultado se almacena en el Registro Destino.
AND AND R3,R1,R2 Aplica la operación AND a nivel de bits, entre el Registro Fuente 1 con el Registro Fuente 2 y el resultado se almacena en el Registro Destino.
XOR XOR R3,R1,R2 Aplica la operación XOR a nivel de bits, entre el Registro Fuente 1 con el Registro Fuente 2 y el resultado se almacena en el Registro Destino.
LW LW R3,0(R1) Carga en el Registro Destino el valor ocupado en la celda de memoria cuya dirección es: la suma de la Dirección Base más el valor del Registro Fuente.
SW SW 0(R1),R2 Guarda el valor del Registro Fuente 2 en la celda de memoria cuya dirección es: la suma de la Dirección Base más el valor del Registro Fuente 1.
NOP NOP Operación de relleno. No realiza ninguna operación.
TRAP TRAP Indica al simulador que el programa ha terminado
; ;comentario Todo texto a la derecha del símbolo punto y coma será omitido por el simulador
Diagrama de Clases del fuente del Simulador DLX (jbz):


Clase Descripción
Principal.java Contiene el método Main y es el dlx en si.
Presentacion.java Clase JFrame usada al inicio para mostrar pantalla de bienvenida.
Instrucciones.java Contiene métodos y constantes para manipular, leer y procesar las

instrucciones válidas para el simulador.
InstDecode.java Clase para contener la estructura decodificada de cada instrucción, usada

para buscar dependencias.
jFrmDependencias.java Clase tipo Ventana encargada de encontrar y mostrar mostrar las

dependencias en un código.
DlxFiltro.java Clase usada para filtrar los archivos con extensión .dlx cuando se muestra la

ventana Abrir.
frameAyuda.java Clase tipo Ventana para mostrar la ayuda.
jFrmCodigo.java Clase tipo Ventana para mostrar el código cargado en memoria.
jFrmEstadisticas.java Clase tipo Ventana para mostrar las estadísticas
iFrmPipeline.java Clase tipo Ventana para mostrar el pipeline
jFrmRegistros.java Clase tipo Ventana para mostrar los registros

Uso del simulador

Requerimientos del simulador DLX (jbz):

Software:
Es necesario para la ejecución del simulador DLX (jbz) la previa instalación de la plataforma Java 2 Standard Edition. Sistema operativo: cualquiera soportado por java.
Espacio de disco duro: Menos de 1 MB. Memoria RAM: Mínimo de 32 MB. Procesador: Mínimo de 133 MHZ.

Instalación:

Copie la carpeta “dlxjbz” a su disco duro.

Ejecución del simulador:

En una consola de comandos (la ventana de MS-DOS en Windows) ubicarse en el directorio “dlxjbz/bin” y escribir:
java -jar dlxjbz.jar
Nota para usuarios de Windows: en el directorio “dlxjbz/bin” se incluye un archivo por lotes con el nombre de: “run.bat” el cual puede ejecutar la aplicación con sólo ser picado dos veces.
Referencia rápida a los menús:
Menú Submenú Acceso Rápido Descripción
Archivo



Reset Ctrl + R Reinicia el Simulador

Abrir Ctrl + A Abrir un archivo dlx para ejecutar

Salir Ctrl + S Salir del simulador
Ejecutar



Un Ciclo F5 Ejecuta un ciclo (un paso)

Múltiples Ciclos F6 Ejecuta una cantidad de ciclos según se especifique

Correr F7 Corre por completo todo el programa
Configurar



Instrucciones en el Pipeline Ctrl + I Establece la cantidad de instrucciones que pueden estar en el pipeline
Ventana



Registros Ctrl + 1 Muestra la ventana Registros

Código Ctrl + 2 Muestra la ventana Código

Pipeline Ctrl + 3 Muestra la ventana Pipeline

Estadísticas Ctrl + 4 Muestra la ventana Estadísticas

Dependencias Ctrl + 5 Muestra la ventana Dependencias
Ayuda



Contenido F1 Muestra la ayuda

Acerca de Ctrl + F1 Muestra información sobre los autores del simulador

Ejemplo 1 de código fuente para el DLX (jbz):

;Ejemplo de código para DLX (jbz)
;Programa que suma 8+9 y guarda el resultado en R3
;Asegurar que el valor de R0 sea 0
XOR R0,R0,R0
;Cargar 8 en R1
ADDI R1,R0,8
;Cargar 9 en R2
ADDI R2,R0,9
;Sumar R1+R2 y guardar en R3
ADD R3,R1,R2
;Final del programa
TRAP
El objetivo de la prueba es comprobar el correcto funcionamiento del simulador DLX (jbz) con un código sencillo.
Resultados obtenidos mediante el simulador:
Valores finales de los Registros
R0 = 0
R1 = 8
R2 = 9
R3 = 17
Dependencias
(0) XOR R0,R0,R0
(1) ADDI R1,R0,8 RAW0
(2) ADDI R2,R0,9 RAW0
(3) ADD R3,R1,R2 RAW1 RAW2
Variable Valor
Numero de Instrucciones Total 5
Ciclos Ejecutados 9
Instrucciones Ejecutadas 4
CPI 2.25
ILP 0.44
Instrucciones en el Pipeline 1
Dependencias RAW 4
Dependencias WAR 0
Dependencias WAW 0
Instrucciones Simultaneas en el Pipe Line 5
Ejemplo 2 de código fuente para el DLX (jbz):


; Ejemplo DLX (jbz)
; Carga y lectura de valores en memoria
XOR R0,R0,R0 ; Asegurar 0 en R0
ADDI R1,R0,15 ; Cargar 15 en R1
ADDI R2,R0,4 ; Cargar 4 en R2
; Escritura en memoria
SW 0(R1),R2 ; M[15]=4 en la casilla 15 escribir 4
SW 1(R1),R2 ; M[15+1]=4 en la casilla 15+1 escribir 4
; Lectura de memoria
LW R3,0(R1) ; r3 = M[15]
LW R4,1(R1) ; r4 = M[15+1]
ADD R4,R2,R3 ; r4 = r4+r3
;FIN
TRAP

El objetivo de la prueba es comprobar el correcto funcionamiento del simulador DLX (jbz) con instrucciones de acceso a memoria.
Resultados obtenidos mediante el simulador:
Valores finales de los Registros
R0 = 0
R1 = 15
R2 = 4
R3 = 4
R4 = 8
Valores finales de la Memoria
M[015] = 4
M[016] = 4
Dependencias
(0) XOR R0,R0,R0
(1) ADDI R1,R0,15 RAW0
(2) ADDI R2,R0,4 RAW0
(3) SW 0(R1),R2 RAW1 RAW2
(4) SW 1(R1),R2 RAW1 RAW2
(5) LW R3,0(R1) RAW1
(6) LW R4,1(R1) RAW1
(7) ADD R4,R2,R3 RAW2 RAW5 WAW6
Estadísticas
Variable Valor
Numero de Instrucciones Total 9
Ciclos Ejecutados 13
Instrucciones Ejecutadas 8
CPI 1.62
ILP 0.62
Instrucciones en el Pipeline 1
Dependencias RAW 10
Dependencias WAR 0
Dependencias WAW 1
Instrucciones Simultaneas en el Pipe Line 5

Conclusiones

Desde un punto de vista general: el uso de un simulador del procesador DLX, con la capacidad de poder realizar distintas pruebas, con distintos códigos, y ejecuciones paso a paso, ayuda grandemente a comprender los conceptos de segmentación encausada o pipeline.
En nuestra experiencia: de los datos obtenidos en las distintas pruebas que realizamos con nuestro simulador, encontramos que: mientras más instrucciones a la vez hay en el pipeline la cantidad de ciclos necesarios para ejecutar todo el programa disminuye, lo cual también significa que el CPI disminuye y el ILP aumenta, lo cual se traduce en un aumento del rendimiento del procesador.

Bibliografía

  • Segmentación Encausada Prof. José L. Díaz Chow Depto. de Arquitectura y Sistemas, Universidad Nacional de Ingeniería de Nicaragua (UNI).
  • WinDLX DLX-Pipeline Simulator TU Vienna, Inst. fr Technische Informatik

martes, octubre 28, 2008

¿Qué antivirus uso? ¡Prometo decir la verdad!

¿Qué antivirus uso? ¡Prometo decir la verdad!

Nota: de aqui en adelante voy a usar la palabra virus para referirme a virus, gusanos, troyanos, spyware, etc. de manera indistina.

"Denis, ¿Qué antivirus usas?, ¿Qué antivirus me recomiendas?, ¿Cuál es el mejor antivirus?...", muchas veces me han hecho estas preguntas o algunas parecidas (¡como que si yo tengo la respuesta!), incluso este tipo de temas es de amplia discusión en toda la Red. Como todo linuxero (usuario de linux) presumido mi respuesta siempre había sido:

"No uso antivirus, ¿para qué quiero uno?, yo uso GNU/Linux y en GNU/Linux no hay ataques de virus... (seguido de toda la explicación sobre el software libre)",

pero hoy quiero confesar que mi respuesta no ha sido del todo sincera, por lo que en este artículo quiero decir la verdad a la pregunta ¿Qué antivirus uso YO?.

Primero: quiero destacar que tengo la confianza de que GNU/Linux es un sistema muy seguro, hasta el momento no he tenido (y estoy seguro que no tendré) ningún problema de virus, pero ojo tener cuidado más adelante relato una anécdota que me sucedió con wine. Si desea saber más sobre linux y los virus puede ver estos enlaces:

Segundo: (aquí es donde venía la parte poco sincera), SI tengo instalado un antivirus en GNU/Linux Debian, se llama ClamAV, y para los que no sabían viene en los discos oficiales y está en los repositorios de paquetes oficiales.

ClamAV (Clam AntiVirus) es un anti virus y anti spyware open source (GPL), gratis para UNIX, está diseñado especialmente para el escaneo de correo electrónico en servidores de correo, aunque también provee de un escáner desde línea de comandos, cuenta con actualizaciones periódicas (manuales o automáticas) de su base de datos de definiciones de virus (la cual crece casi diario), es multi plataforma, hay una versión para MS Windows llamada ClamWin que se puede integrar con MS Office Outlook Express.

Estas son las URL de ambos:

¿Porqué tengo un antivirus instalado en GNU/Linux?

No tengo ningún servidor de correo, mis razones para tener instalado un antivirus en GNU/Linux son:
  1. Mi memoria USB la uso en diferentes lugares (casa, trabajo, amigos, cyber, etc.), en ocasiones algunos de estos lugares me infectan con los viruses recidentes, aunque no afectan mi GNU/Linux Debian no me gusta andar basura en la memoria y no me gustaría que por mi memoria se infesten otros.
  2. En la casa, la PC de mi hermana tiene Windows (ha sido difícil convercerla al cambio), en muchas ocasiones dicha computadora adquiere algún virus, y adivinen a quién le toca quitarlo...
Eliminar los virus de una memoria USB

En el caso de mi memoria hice lo siguiente: primero instalé ClamAV (apt-get install clamav), y luego he creado en la raíz de mi memoria un script llamado antivisrus.sh con el siguiente contenido:

#!/bin/sh

clamscan --remove -r -l clamscan.log .

Esto lo que hará cuando se ejecute, será escanear el contenido del directorio actual (la raíz de mi memoria) de forma recursiva pasando por todos los subdirectorios y borrando todo archivo que clamav considere infectado, todo lo que clamav haga quedará registrado en un archivo llamado clamscan.log en la misa raíz de mi memoria.

Cuando quiero revisar/limpiar la memoria tan solo ejecuto en una consola:

$sh /media/DENISTORRES/antivisrus.sh

Ojo, yo soy imprudente, si se fijan yo ejecuto clamscan con la opción --remove, algo más prudente puede ser, crear un directorio cuarentena donde se mande todo archivo infectado, para su examinación previo a su borrado:

#!/bin/sh

clamscan --move=/home/denis/cuarentena -r -l clamscan.log .

Eliminar los virus de Windows desde GNU/Linux (sin arrancar Windows)
El otro caso que les mencioné por el cual uso clamAV es para limpiar el Windows de la computadora de mi hermana, al principio se me había ocurrido encender la PC de mi hermana, compartir la particion de Windows, montarla con samba en mi PC y proceder a escanearla. ClamAV empezó a realizar su trabajo, detectó los virus, pero como el virus ya estaba residente y ejecutándose en la computadora con Windows, no dejaba borrar los archivos infectados, e incluso como Windows estaba ejecutándose algunos archivos del sistema operativo no se dejaban escanear.

/home/denis/blanca_pc/WINDOWS/SYSTEM32/RVHOST.exe: Worm.Sohanad-130 FOUND
ERROR: Can't unlink '/home/denis/blanca_pc/WINDOWS/SYSTEM32/RVHOST.exe': Permission denied
WARNING: Can't open file /home/denis/blanca_pc/pagefile.sys
WARNING: Can't open file /home/denis/blanca_pc/WINDOWS/SYSTEM32/config/system.LOG
WARNING: Can't open file /home/denis/blanca_pc/WINDOWS/SYSTEM32/config/software.LOG
WARNING: Can't open file /home/denis/blanca_pc/WINDOWS/SYSTEM32/config/default.LOG
WARNING: Can't open file /home/denis/blanca_pc/WINDOWS/SYSTEM32/config/SECURITY
WARNING: Can't open file /home/denis/blanca_pc/WINDOWS/SYSTEM32/config/SAM
WARNING: Can't open file /home/denis/blanca_pc/WINDOWS/SYSTEM32/config/SAM.LOG
WARNING: Can't open file /home/denis/blanca_pc/WINDOWS/SYSTEM32/config/SECURITY.LOG


Esto me llevó a la utilización de otra estrategia (la cual uso actualmente), como la PC de mi hermana no tiene instalado ningún Linux, entonces utilicé mi Knoppix Live CD para arrancar linux en dicha PC, y luego escanearla con ClamAV.

Con Knoppix en ejecución es muy fácil montar la partición de Windows. En el Desktop aparece un icono para cada partición, es fácil montarla tan sólo es necesario darle clic al icono de la partición, luego hacer con clic con el botón derecho desde el menú emergente, y cambiar a modo de escritura la partición (para que podamos borrar los virus).

Knoppix trae instalado ClamAV, por lo cual es posible proceder despúes de arrancar Knoppix el escaneo de los directorios necesarios, pero si Knoppix es muy viejo la versión del engine de clamscan y la base de datos de definiciones de virus pueden estar muy desactualizadas, por lo cual es bueno previo al escaneo instalar una versión reciente de ClamAV y actualizar las definiciones de virus.

Las actualizaciones de definiciones de virus de ClamAV son gratis, en realidad se tratan de 2 archivos main.cvd y daily.cvs los cuales pueden ser descargados desde el sitio oficial de ClamAV:
Para actualizar el engine de ClamAV en mi Debian Etch yo ya habia descargado con anterioridad desde Backports (http://www.backports.org/) los deb de ClamAV, y como Knoppix está basado en Debian entonces los mismos deb pueden ser utilizados.

Una vez con estos archivos es posible actualizar ClamAV en Knoppix así:

knoppix@1[~]$ cd ~/clamav
knoppix@1[clamav]$ ls
daily.cvd  deb  main.cvd
knoppix@1[clamav]$ cd deb/
knoppix@1[deb]$ su

root@1[deb]# dpkg -l | grep clam
ii  clamav             0.88.2-1    antivirus scanner for Unix
ii  clamav-base        0.88.2-1    base package for clamav, an anti-virus utility
ii  clamav-freshclam   0.88.2-1    downloads clamav virus databases from the Inte
ii  libclamav1         0.88.2-1    virus scanner library


root@1[deb]# ls
clamav_0.93.1.dfsg-volatile1_i386.deb
clamav-base_0.93.1.dfsg-volatile1_all.deb
libclamav4_0.93.1.dfsg-volatile1_i386.deb

root@1[deb]# dpkg -i *
(Leyendo la base de datos ...
103700 ficheros y directorios instalados actualmente.)
Preparando para reemplazar clamav 0.88.2-1 (usando clamav_0.93.1.dfsg-volatile1_i386.deb) ...
Desempaquetando el reemplazo de clamav ...
Preparando para reemplazar clamav-base 0.88.2-1 (usando clamav-base_0.93.1.dfsg-volatile1_all.deb) ...
Desempaquetando el reemplazo de clamav-base ...
Seleccionando el paquete libclamav4 previamente no seleccionado.
Desempaquetando libclamav4 (de libclamav4_0.93.1.dfsg-volatile1_i386.deb) ...
Configurando clamav-base (0.93.1.dfsg-volatile1) ...
Replacing config file /etc/clamav/clamd.conf with new version

Configurando libclamav4 (0.93.1.dfsg-volatile1) ...

root@2[deb]# cd ..
root@2[clamav]# ls -lh
total 18M
-rwx------ 1 knoppix knoppix 1,3M 2008-10-23 20:22 daily.cvd
drwxr-xr-x 2 knoppix knoppix  120 2008-10-23 20:23 deb
-rwx------ 1 knoppix knoppix  17M 2008-10-23 20:22 main.cvd
root@2[clamav]# ls -lh /var/lib/clamav/
total 15M
-rwxr-xr-x 1 clamav root 2,0M 2008-10-23 20:34 daily.cvd
-rwxr-xr-x 1 clamav root  13M 2008-10-23 20:34 main.cvd

root@2[clamav]# cp *cvd /var/lib/clamav/
cp: ¿sobreescribir «/var/lib/clamav/daily.cvd»? (s/n) s
cp: ¿sobreescribir «/var/lib/clamav/main.cvd»? (s/n) s
root@2[clamav]# ls -lh /var/lib/clamav/
total 18M
-rwxr-xr-x 1 clamav root 1,3M 2008-10-23 20:43 daily.cvd
-rwxr-xr-x 1 clamav root  17M 2008-10-23 20:43 main.cvd


root@2[clamav]# cd /mnt/sda1/antivirus/
root@2[antivirus]# ls
antivisrus.sh

root@2[antivirus]# cat antivisrus.sh
#!/bin/sh

clamscan --remove -r -l clamscan.log /media/sda1/ > clamscan_full.log


poweroff

root@2[antivirus]#
root@2[antivirus]# clamscan --version
ClamAV 0.93.1/8468/Wed Oct 22 14:35:20 2008

root@2[antivirus]# sh antivisrus.sh
LibClamAV Warning: ***********************************************************
LibClamAV Warning: ***  This version of the ClamAV engine is outdated.     ***
LibClamAV Warning: *** DON'T PANIC! Read http://www.clamav.net/support/faq ***
LibClamAV Warning: ***********************************************************
LibClamAV Warning: ***********************************************************
LibClamAV Warning: ***  This version of the ClamAV engine is outdated.     ***
LibClamAV Warning: *** DON'T PANIC! Read http://www.clamav.net/support/faq ***
LibClamAV Warning: ***********************************************************

Cuidado con Wine

Por seguridad si tienen instalado wine les recomiendo que no asocien por defecto los archivos .exe para ser ejecutados con wine (en cualquier entorno gráfico gnome o kde) ya que hace algún tiempo me pasó lo siguiente:

El ipod de mi prima tenía el famoso virus "Nueva Carpera.exe" se lo íbamos a borrar desde linux, pero por error después de seleccionarlo presioné la tecla Enter y se empezó a ejecutar (sin que me percata de eso).

Procedí a borrar los archivos “Nueva Carpeta.exe” de los subdirectorios del ipod, pero noté que en la raíz no se había borrado y que cada vez que lo borraba volvía a aparecer, “jejejeje, está cómico esto, tengo un virus en linux!” pensé, deduje que se estaba ejecutando lo busque en los procesos, y allí había un wine corriendo, maté el proceso, y después pude borrar el archivo sin ningún problema.

(ojo en mi sistema de archivos ext3 no pasó nada malo, revisé mi home y el fake_windows de winw y todo estaba bien, el virus sólo se copiaba en la memoria del ipod).

Algunos virus/troyanos/espías/gusanos que ClamAV me ha detectado según el log de los escaneos:

./RECYCLER/S-1-5-21-1482476501-1644491937-682003330-1013/stcvhost.exe: Worm.Autorun-1617 FOUND
./RECYCLER/S-1-5-21-1482476501-1644491937-682003330-1013/stcvhost.exe: Removed

... otro log ...

/media/hda1/Archivos de programa/EA GAMES/MOHAA/main/Pak1.pk3: Oversized.Zip FOUND
/media/hda1/Archivos de programa/EA GAMES/MOHAA/main/Pak1.pk3: Removed

... otro log ...

./mon/mon.exe: Worm.Sohanad-130 FOUND
./mon/mon.exe: Removed
./carpeta.exe: Trojan.Downloader-53377 FOUND
./carpeta.exe: Removed

... otro log ...

/mnt/guin/c/Documents and Settings/kathy/Escritorio/Sin.wcp: Unknown error code
/mnt/guin/c/RECYCLER/S-1-5-21-1482476501-1644491937-682003330-1013/stcvhost.exe: Worm.Autorun-1617 FOUND

... otro log ...
./RECYCLER/S-1-5-21-1482476501-1644491937-682003330-1013/isi32.exe: Worm.Autorun-826 FOUND
./RECYCLER/S-1-5-21-1482476501-1644491937-682003330-1013/isi32.exe: Removed

... otro log ...
/home/denis/blanca_pc/WINDOWS/MEMORY.DMP: Trojan.KillCMOS FOUND

... la memoria de mi papá ....

./ntde1ect.com: Trojan.Spy-6766 FOUND
./n1deiect.com: Trojan.Spy-17753 FOUND
./g2pfnid.com: Trojan.Spy-48682 FOUND
./e.com: Trojan.Vundo-7458 FOUND
./autorun.inf: Inf.Suspect-2 FOUND
./nideiect.com: Trojan.Bagle-283 FOUND
./RECYCLER/S-1-5-21-1482476501-1644491937-682003330-1013/sic32.exe: Trojan.Small-8279 FOUND
./RECYCLER/S-1-5-21-3318671052-061502871-8581524341-500/~WRL0258.tmp: Trojan.Autorun-160 FOUND
./MSOCache/doWTP_RESTORE_0.exe: Trojan.Delf-1727 FOUND


Así que esa es la verdad, la verdad ... usar Linux es el mejor antivirus que existe :-)
-

Artículos Relacionados

Usando ClamAV 0.95.1 en Ubuntu Jaunty con clamtk como GUI (http://josegjimenez.wordpress.com/2009/04/25/clamav-0951/)

viernes, agosto 08, 2008

Diagramando con Dia - Secuencia de Escape

El fuente de este gráfico es de dominio público, aquí puede descargarlo, está hecho con DIA. Si no conoces sobre DIA aquí tienes una breve descripción (tomada de la Wikipedia) sobre este excelente software libre:

"Dia es una aplicación gráfica de propósito general para la creación de diagramas, desarrollada como parte del proyecto GNOME. Está concebido de forma modular, con diferentes paquetes de formas para diferentes necesidades... Actualmente se incluyen diagramas entidad-relación, diagramas UML, diagramas de flujo, diagramas de redes, diagramas de circuitos eléctricos... El formato para leer y almacenar gráficos es XML (comprimido con gzip, para ahorrar espacio). Puede producir salida en los formatos EPS, SVG y PNG."


Considero que es importante destacar que es un software muy liviano y fácil de usar, en su sitio Web http://live.gnome.org/Dia podrás descargarlo de forma gratuita, este software es multiplataforma o sea también puede ser ejecutado en Windows.
Software Libre para asistencia en el aprendizaje de las matemáticas: Maxima, xMaxima



Introducción

Hace algunos días un amigo (@LeX), me mandó (y a otro montón de personas al mismo tiempo) uno de esos correos tipo "cadena de socialización" (así les llamo yo), que decía lo siguiente:


"Sólo gente inteligente puede abrir este archivo, PERO INTENTENLO.....Y SI ACIERTAN, ANOTEN SU NOMBRE Y REENVIENLO, UNA BONITA PRUEBA..... Una vez que abras el archivo verás la lista de personas que pudieron abrirlo... ahora es tu turno. Te he considerado entre la gente inteligente que puede resolverlo. Un hombre quería entrar a su trabajo pero olvidó su PIN. Sin embargo, se acordaba de ciertas pistas para recordarlo. Estas son las 5 pistas.
  • El quinto número más el tercero equivalen a 14
  • El cuarto número es uno más que el segundo número.
  • El primer número es uno menos que dos veces el segundo número.
  • El segundo número más el tercer número equivalen a 10.
  • La suma de todos los números es 30.
"

El autor del correo adjuntaba este archivo Hoja de Cálculo de MS Excel, la cual al quererla abrir solicita una contraseña, según el correo la contraseña coincide con las 5 pistas dadas en el correo.



Recordé que cuando estudié computación en la UNI, las clases de Cálculo, se acompañaban de un software llamado: "Wolfram Mathematica", en el cual podíamos resolver, graficar y programar, desde sencillos cálculos matemáticos hasta resolver complejas integrales múltiples, por medio de este software se pueden resolver sistemas de ecuaciones como el planteado el correo de @LeX, al instante apareció en mi mente la idea de buscar un software libre equivalente a "Wolfram Mathematica", buscando un poquito en Google me encontré con este software disponible para GNU/Linux Debian: Maxima.

Maxima

La wikipedia dice lo siguiente sobre Maxima:

"El sistema de álgebra computacional Maxima es un motor de cálculo simbólico escrito en lenguaje Lisp publicado bajo licencia GNU GPL. Cuenta con un amplio conjunto de funciones para hacer manipulación simbólica de polinomios, matrices, funciones racionales, integración, derivación, manejo de gráficos en 2D y 3D, manejo de números de coma flotante muy grandes, expansión en series de potencias y de Fourier, entre otras funcionalidades. Además tiene un depurador a nivel de fuente para el código de Maxima. Maxima está basado en el sistema original de Macsyma desarrollado por MIT en los años 70. Es bastante fiable, tiene un buen recolector de basura, por lo que no desperdicia memoria."

La Web oficial de Maxima es: http://maxima.sourceforge.net/

Maxima es un software de modo texto, pero existe un complemento llamado xMaxima, el cual provee de una interfaz gráfica para facilitar el uso de Maxima.

Resolver sistemas de ecuaciones con Maxima y xMaxima

Una vez que se ha planteado el sistema de ecuaciones (en este caso de 5 variables), según lo indicado en el correo:

x5 + x3 = 14
x4 = x2 + 1
x1 = (2 * x2) - 1
x2 + x3 = 10
x1 + x2 + x3 + x4 + x5 = 30

Haciendo uso de la función solve de Maxima e indicando cada una de las ecuaciones se obtiene el valor de cada variable casi al instante (después de escribir el código pulsar Enter):

(%i1) solve([
x5 + x3 = 14,
x4 = x2 + 1,
x1 = (2 * x2) - 1,
x2 + x3 = 10,
x1 + x2 +x3 + x4 + x5 = 30
],
[x1,x2,x3,x4,x5]
);
(%o1) [[x1 = 7, x2 = 4, x3 = 6, x4 = 5, x5 = 8]]
(%i2)

x1 = 7
x2 = 4
x3 = 6
x4 = 5
x5 = 8


Maxima es capaz de realizar muchas operaciones matemáticas, la parte inferior de xMaxima muestra por defecto una ayuda bastante intuitiva con múltiples ejemplos.

Software libre como este, es de gran ventaja para asistir al aprendizaje de las matemáticas, pues a como se observa en este simple ejemplo, Maxima no resuelve el ejercicio por si sola, es necesario que de previo el estudiante haga un análisis del problema, y plantee correctamente el sistema de ecuaciones, si el estudiante no lo hace, Maxima no le puede ayudar, Maxima no puede interpretar el lenguaje humano, Maxima debe recibir instrucciones claras y datos correctos de lo que se pretende resolver, o sea que Maxima no te hace la tarea, tan sólo te ayuda.

Interesante (otro asunto)!

Es interesante como estos correos cadenas viajan por todo el mundo, despúes de resolver el sistema de ecuaciones com xMaxima y entrar al archivo se puede ver cuanta gente se ha anotado, diciendo ser de paises como:

  • Pakistan
  • India
  • Palestine
  • Philippines
  • Lebanon
  • UAE
  • Iraq
  • Philippines
  • Jordan
  • United Arab Emirates
  • Palestine
  • Qatat
  • Palestine
  • Egyptian
  • Scottish
  • mexican
  • mexicano
  • TICA
  • Costa Rica
  • Nicaragua

miércoles, abril 30, 2008

Instalar tsearsh2 en PostgreSQL con soporte español con ispell

Introducción

Este pequeño manual trata sobre la instalación, configuración y realización de una pequeña prueba del motor de búsqueda para texto[4] Tsearch2[3] usado en PostgreSQL[1][2] con soporte para diccionario Español usando ispell y codificación de caracteres iso-8859-1, este manual se basa en mi experiencia personal usando Tsearch2, como parte del proyecto de software libre HelpDesk fantASTIC[9]. Es importante destacar que actualmente (20 Abril 2008) Tsearch2 está integrado en PostgreSQL 8.3, por lo cual este gran parte de este manual será válido sólo para versiones inferiores a PostgreSQL 8.3, en mi caso he usado Tsearch2 usando ispell con idioma español con PostgreSQL 8.1 y supongo que este manual funcionaría perfectamente bien con PostgreSQL 8.0, al mismo tiempo estoy seguro que con PostgreSQL 8.2 presentará un problema, provocado por un bug presente en un paquete llamado snowball[5] usado por Tsearch2.

El ejemplo aquí descrito ha sido realizado en GNU / Linux Debian Etch 4.0 r0, pero no implica que no pueda ser posible su implementación en otras distribuciones de GNU / Linux o en otros sistemas operativos soportados por PostgreSQL (como en MS Windows).

Se recomienda leer un poco (aunque no es necesario para completar la realización de este ejemplo) el manual de Tsearch2 ubicado en: http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/docs/tsearch-V2-intro.html

Instalar PostgreSQL en Debian Etch GNU/Linux

Aquí no hay mucho que decir:


#apt-get install postgresql-8.1 postgresql-contrib-8.1 postgresql-client-8.1



Importante: no olvidar instalar el paquete postgresql-contrib, pues es allí donde viene Tsearch2.

Descripción de Ejemplo

Como parte de esta explicación, expongo un pequeño ejemplo, el cual se trata del almacenamiento de "artículos" los cuales constan de un "nombre" y del "contenido" del artículo, el objetivo es poder hacer búsquedas por aproximación entre todos los artículos registrados (usando Tsearch2 y PostgreSQL).

Crear Base de Datos de Prueba

Una vez instalado PostgreSQL se ha creado en nuestro sistema un usuario llamado "postgres", el cual es el administrador del RDBMS, para crear la nueva base de datos, que se llamará: "articulos" es posible hacer:


#su postgres
$createdb articulos


Nota: De aquí en adelante voy a suponer que usted sabe usar alguna herramienta cliente básica de PostgreSQL, en este manual usaré psql, cabe destacar que también es posible utilizar las herramientas gráficas, como por ejemplo pgAdmin3.

Definir un nuevo lenguaje procedural en la Base de Datos

Para este ejemplo crearemos algunos scripts en PL/pgSQL, para lo cual es necesario que nuestra base de datos "articulos" tenga soporte para este lenguaje procedural.

Para instalar plpgsql, ejecutar desde una consola, estando siempre como usuario postgres (o cualquier usuario con los privilegios suficientes):


$createlang plpgsql articulos


También es posible hacer esto mismo desde una consola SQL dentro de PostgreSQL:


CREATE PROCEDURAL LANGUAGE plpgsql;


Diseño de Estructura de la Base de Datos (mi ejemplo)

Para ejemplo necesitamos sólo una tabla, la cual se llamará "articulo" y tendrá esta estructura:


Para hacer uso de Tsearch2, necesitamos crear un campo más en la tabla "articulo", este campo debe ser de tipo "tsvector" (este tipo de dato "tsvector" se instalará en nuestra base de datos cuando instalemos Tsearch2, algo que se describe más adelante). Tsearch2 usará este campo extra con el fin de crear una "especie" de índice de busqueda (no es un índice como tal a nivel de base de datos).

Nota: Mi proyecto HelpDesk fantASTIC[9], utiliza PEAR MDB2[6] como capa de abstracción de base de datos, MDB2 hace una especie de reconocimiento o revisión de los tipos de datos de los campos de las tablas que se acceden por medio de él, el tipo de dato "tsvector" no es reconocido por PEAR MDB2[6], lo cual genera un error al intentar acceder por medio de este a tablas que contengan campos con este tipo de datos, razón por la cual sugiero crear una tabla extra para almacenar los índices de Tsearch2, y mediante un trigger mantener ambas tablas sincronizadas, en lugar de crear un campo extra dentro de la tabla.

Supongo que este problema (el no reconocimiento de los tipos de datos especiales como "tsvector") también se podría presentar al usar cualquier otro framework de acceso a base de datos, que revise los tipos de datos de los campos y no tenga soporte para el tipo "tsvector", en caso contrario (ya sea que el tipo de datos de los campos no sea de importancia o de que sí exista soporte, para el tipo de datos "tsvector") este modelo seguiría siendo siempre funcional.

A continuación se presenta el modelo DER versión 2 a utilizar en este ejemplo:




La tabla "pg_ts_articulo" almacenará el índice "tsvector", para cada artículo en el campo "articulo_tsearch_idx" de tipo "tsvector".

Cada ves que un artículo se cree, modifique o borre en la tabla "articulo" un trigger se disparará y hará los cambos pertinentes en la tabla "pg_ts_articulo", para que el índice siempre esté actualizado.

Instalar Tsearch2 en la Base de Datos "articulos"

Para instalar Tsearch2 en nuestra base de datos, utilizamos el archivo sql provisto por el paquete "postgresql-contrib", el cual se encuentra en la siguiente ruta:

/usr/share/postgresql/<'version'>/contrib/tsearch2.sql

En mi caso estoy usando PostgreSQL 8.1, por lo cual ejecuto como usuario con privilegios sobre la base de datos "articulos":


$psql -d articulos -f /usr/share/postgresql/8.1/contrib/tsearch2.sql


Aparecerán mensajes como este:


SET
BEGIN
psql:/usr/share/postgresql/8.1/contrib/tsearch2.sql:13: NOTICE: CREATE TABLE / PRIMARY KEY creará el índice implícito «pg_ts_dict_pkey» para la tabla «pg_ts_dict»
CREATE TABLE
CREATE FUNCTION
CREATE FUNCTION
...
CREATE OPERATOR
CREATE OPERATOR
CREATE OPERATOR CLASS
COMMIT


Si todo sale bien, se han agregado las siguientes tablas a la base de datos "articulos":

pg_ts_cfg
pg_ts_cfgmap
pg_ts_dict
pg_ts_parser



Estas tablas son usadas para configurar y parametrizar Tsearch2.

Instalar soporte a lenguaje español de Tsearch2 con ispell usando codificación iso-8859-1

En la página Web de Tsearch2[3] podrá encontrar el archivo tsearch2_espanol.tar.bz2 el cual contiene lo necesario para que Tsearch2 soporte el lenguaje español mediante ispell usando codificiación iso-8859-1. En la página Web de Tsearch2 busque:

tsearch2_espanol.tar.bz2 - spanish ispell dictionary in iso-8859-1 encoding (Denis Torres) [10]

Descargue el archivo y descomprímalo, encontrará los siguientes archivos:

"espanol.aff", fichero de afijos, si desea conocer más sobre estos archivos puede visitar aquí [7].
"espanol.dict", diccionario de palabras en español, si desea conocer más sobre estos archivos puede visitar [7].
"espanol.stop", lista de palabras que no serán indizadas por Tsearch2.[8]
"default_spanish.sql", script sql que parametriza las opciones correspondientes en las tablas de configuración de Tsearch2, para agregar una nueva configuración de diccionario para Tsearch2 llamada "default_spanish".

Copie los siguientes archivos en /usr/local/pgsql/share/contrib/, (si la ruta no existe puede crearla):

espanol.aff
espanol.dict
espanol.stop

Nota: en debian no sería la mejor opción instalar estos archivos en la ruta /usr/local/pgsql/share/contrib/, si usted desea puede copiar estos archivos en otro lugar, pero asegúrese de ajustar el archivo "default_spanish.sql" antes de ejecutarlo.

Luego ejecute el script "default_spanish.sql", en la base de datos "articulos"


$psql -d articulos -f {ruta_al_script}/default_spanish.sql


Crear estructura de datos Diseñada

Aquí no hay mucho que explicar, supongo que el lector sabe crear tablas en SQL. En otras palabras crear las tablas "articulo" y "pg_ts_articulo".


CREATE TABLE articulo(
id_articulo serial NOT NULL,
nombre text NOT NULL,
contenido text,
primary key (id_articulo)
);

CREATE TABLE pg_ts_articulo (
id_articulo integer NOT NULL,
articulo_tsearch_idx tsvector,
PRIMARY KEY (id_articulo)
);

CREATE INDEX idx_articulo_tsearch
ON pg_ts_articulo USING gist (articulo_tsearch_idx);

ALTER TABLE pg_ts_articulo ADD FOREIGN KEY (id_articulo) REFERENCES articulo (id_articulo) ON UPDATE RESTRICT ON DELETE CASCADE;


Es importante hacer notar:

1- Se ha creado para el campo "articulo_tsearch_idx" un índice a nivel de base de datos de tipo: "gist". (Leer el manual de Tsearch2 para obtener detalles sobre los indices GIST).
2- Se ha agregado una relación entre los campos "id_articulo" desde la tabla "articulo" hacia "pg_ts_articulo" con la restricción: ON DELETE CASCADE para que al momento de borrar un "articulo" se borre también su registro relacionado en "pg_ts_articulo".

Crear trigger para la sincronización de los artículos con campo de índice de Tsearch2

Cada vez que se actualice la tabla "articulo" debería actualizarse el índice de Tsearch2 en la tabla "pg_ts_articulo", este trabajo lo hará el siguiente trigger:


CREATE OR REPLACE FUNCTION actualizar_indice_tsearch2() RETURNS "trigger" AS $$
BEGIN

DELETE FROM pg_ts_articulo WHERE pg_ts_articulo.id_articulo = NEW.id_articulo;
INSERT INTO pg_ts_articulo
VALUES (NEW.id_articulo, to_tsvector('default_spanish', coalesce(NEW.nombre) || ' ' || coalesce(NEW.contenido)));

RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';


CREATE TRIGGER tsvectorupdate AFTER UPDATE OR INSERT ON articulo
FOR EACH ROW EXECUTE PROCEDURE actualizar_indice_tsearch2();


Nota: El indice insertado en "pg_ts_articulo" abarca no sólo el "contenido" sino también el "nombre" del "articulo" para que al momento de realizar una búsqueda se evalúen ambos campos[coalesce(NEW.nombre) || ' ' || coalesce(NEW.contenido)].

Introducir algunos datos de pruebas


INSERT INTO articulo (nombre,contenido) VALUES ('Función echo', 'Muestra todos sus parámetros por la salida definida. echo() no es realmente una función (es una sentencia del lenguaje) de modo que no se requiere el uso de los paréntesis. De hecho, si se indica más de un parámetro, no se pueden incluir los paréntesis.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función sin', 'Devuelve el seno de arg en radianes.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función print_r', 'print_r -- Imprime información legible para humanos sobre una variable.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función print', 'Muestra el valor de cadena por la salida definida. Siempre devuelve el valor 1. print() no es realmente una función (es una sentencia del lenguaje) de modo que no se requiere el uso de los paréntesis.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función array_pop', 'array_pop() extrae y devuelve el último valor de la matriz, acortando la matriz en un elemento. Si matriz está vacía (o no es una matriz), se regresará NULL.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función array', ' Devuelve una matriz con los parámetros que se le pasan. A dichos parámetros se les puede dar un índice usando el operador =>. Lea la sección sobre los tipos de matrices para más información sobre matrices. Nota: array() es una construcción del lenguaje que se utiliza para representar matrices literales, no una función regular. La forma "índice => valor" separada por comas, define índices y valores. el índice puede ser de tipo cadena o numérico. Cuando el índice es omitido, se genera automáticamente un índice numérico, empezando en cero. Si el índice es un entero, el siguiente índice generado será igual al índice con número mayor + 1. Note que cuando se definen dos índices idénticos, el último sobre escribe al primero.Tener una coma después del último elemento de la matriz, aunque inusual, es sintácticamente valido. El siguiente ejemplo demuestra cómo crear una matriz bidimensional, cómo especificar claves para matrices asociativas, y cómo especificar índices no consecutivos en matrices normales.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función cos', 'cos() devuelve el coseno del parámetro arg. El parámetro arg está en radianes.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función tan', 'Devuelve la tangente de arg en radianes.');
INSERT INTO articulo (nombre,contenido) VALUES ('Función array_rand', 'array_rand() es bastante útil cuando desea elegir una o más entradas aleatorias de una matriz. Recibe una matriz de entrada y un argumento opcional num_req que especifica cuántas entradas desea seleccionar; si no se precisa éste argumento, recibe un valor por defecto de 1. Si está eligiendo únicamente una entrada, array_rand() devuelve la clave de una entrada al azar. De lo contrario, devuelve una matriz de claves para las entradas aleatorias. Esto se ha hecho de esta forma para que usted pueda elegir claves al igual que valores al azar de la matriz. ');


Probar actualizaciones en ambas tablas

Primero:

SELECT * FROM articulo;


Luego:


SELECT * FROM pg_ts_articulo;


Ambas tablas deben contener datos.

Crear función plpgsql para realizar las búsquedas


CREATE TYPE respuesta_buscar_articulo AS (id_articulo int, nombre text,contenido text, puntaje real);

CREATE OR REPLACE FUNCTION buscar_articulo(text) RETURNS SETOF respuesta_buscar_articulo AS $$
DECLARE
AGUJA ALIAS FOR $1;
RESPUESTA RECORD;
BEGIN

FOR RESPUESTA IN (
SELECT
articulo.id_articulo,
headline('default_spanish',articulo.nombre,tsq) AS nombre,
headline('default_spanish',articulo.contenido,tsq) AS contenido,
rank(articulo_tsearch_idx,tsq) as puntaje
FROM
pg_ts_articulo,
to_tsquery('default_spanish',AGUJA) tsq,
articulo
WHERE
articulo.id_articulo = pg_ts_articulo.id_articulo
AND
articulo_tsearch_idx @@ tsq
ORDER BY puntaje DESC )
LOOP
RETURN NEXT RESPUESTA;
END LOOP;

RETURN;
END;
$$
LANGUAGE plpgsql;


Hacer búsquedas de prueba

A continuación sólo debemos hacer algunas pruebas:

1- Coincidir sólo una palabra:


select * from buscar_articulo('función');


2- Coincidir 2 (ambas a la vez) palabras:


select * from buscar_articulo('función & matriz');


3- Coincidir cualquiera de 2 palabras:


select * from buscar_articulo('función | seno');






Notar que en esta última búsqueda los artículos que involucran ambas palabras "función" y "seno" tienen mayor puntaje.

Enlaces
[1] http://www.postgresql.org
[2] http://es.wikipedia.org/wiki/Postgresql
[3] http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/
[4] http://en.wikipedia.org/wiki/Full_text_search
[5] http://archives.postgresql.org/pgsql-general/2007-09/msg00794.php
[6] http://pear.php.net/package/MDB2
[7] http://www.datsi.fi.upm.es/%7Ecoes/espell_leame/espell_leame.html
[8] Se agradece a las personas que colaboraron para la elaboración de esta lista de palabras: https://lists.ubuntu.com/archives/ubuntu-ni/2007-August/001921.html
[9] http://sourceforge.net/projects/fantastic/
[10] http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/dicts/ispell/tsearch2_espanol.tar.bz2