Miércoles, 14 de marzo del 2012
I-pdf v. 0.1 por fin viendo la luz
Pasaron los dÃas y por fin tengo algo "decente" para publicar, si no sabes a que me refiero serÃa bueno que veas ESTE POST ANTERIOR.
Ahora pasaré a hacer una explicación "más" detallada del programa y lo que hace.
El reto era tener una herramienta que leyera el texto un PDF y lo pasará a una base de datos para poder realizar consultas a los textos sin tener que abrir PDF x PDF lo cual es MUY PESADO, pero además las búsquedas tendrÃan que ser algo mucho más complejas que el simple buscar una palabra.
El programa está hecho en C++ con QT4.7 , simplemente la elección correcta porque la potencia de QT no tiene comparación en el mundo del software libre (lo siento GTK ya fuiste en mis preferencias), lo único malo es la documentación que no es muy amplia y menos fácil de entender cuando programas con C++, para el almacenamiento de los textos use PostgreSQL 9.1, por 2 motivos, 1 porque soy fan a muerte de PostgreSQL y 2 porque puedo almacenar la data en forma de texto plano y simple (un campo tipo TEXT) o puedo guardar vectores para búsquedas más complejas (tipo TSVECTOR), luego explicaré más sobre esto último.
Restricciones (pero no tantas en realidad) el programa funciona de forma local, osea busca tu DB en localhost, sin embargo es algo que se puede mejorar fácilmente con pequeños cambios, pero de momento la db y la app deben estar en la misma pc si es que quieres usar de frente el ejecutable.
El programa tiene una sola interface, muy sencilla por cierto, que tiene 2 tabs, el primero permite cargar los pdfs y el segundo hacer las búsquedas, el flujo es el siguiente:
Primero, se debe conectar a la DB, para eso encontrarás un botoncito en la parte superior derecha.
Segundo, debes subir PDFs a la aplicación, para eso hay un botón que dice "subir file", este lo que hace en realidad es "leer" el PDF y presentará el contenido en la ventana derecha.
* Tercero, bajar el contenido a la DB, para eso tienes 2 botones, uno si el contenido es en español y el otro si está en ingles, ¿porque esto?, bueno es simple en realidad, las búsquedas especiales por lexemas tienen esa caracterÃstica, dependiendo el idioma indexan los vectores y las búsquedas son más eficientes cuando tienes claro que idioma buscar.
Cuando tienes subidos los PDFs solo tienes que ir a el tab de Búsquedas y encontrarás 4 botones que explicaré luego.
En primer lugar si bien uso PostgreSQL 9.1 podrÃas usar 8.4 sin problemas, la base de datos se llama "indexadorpdf" y tengo una sola tabla donde almaceno todo el pdf (algo que hay que mejorar), la tabla se llama "tblpdf" y la estructura es asÃ:
indexadorpdf=# \d tblpdf
Table "public.tblpdf"
Column | Type | Modifiers
-------------+------------------------+-----------
nombre | character varying(250) |
tipo | character(3) |
texto | text |
textovector | tsvector |
Como verán es bastante simple, el campo "nombre" almacena el nombre y ruta del pdf (otra cosa a mejorar también), el campo "tipo" es para almacenar el tipo del documento, en este caso se pone pdf como texto duro, el campo "texto" tiene el contenido del PDF, todo completito, y el campo "textovector" tiene el contenido vectorizado por lexemas.
¿Que es un lexema?
No soy un experto en esto pero el tema es asÃ, cuando tu haces una búsqueda puedes buscar las palabras por su raÃz fonética, digamos la palabra "padre", la raÃz es "padr" y eso es lo que se guarda en un vector, entonces cuando uno busque con lexemas puede obtener resultados parecidos como padre, padrino, padrasto, etc. la idea es que uno haga búsquedas estilo "Google" donde puedo hasta escribir una palabra mal, por ejemplo sin acento y se puedan ubicar los textos que correspondan o se acerquen a ellos.
Ahora si pasemos a la pestaña de búsqueda, esta pantalla tiene un textbox donde puedes ingresar el contenido de tu búsqueda, en este textbox puedes ingresar el texto a buscar y los operadores, estos operadores responderán al tipo de búsqueda a utilizar.
Esta parte es para los no expertos en querys:
La búsqueda con LIKE busca palabras exactas, tal cual están escritas, por ejemplo si ponen "PAPA" se buscaran los textos con la palabra "PAPA" pero asà en mayúsculas, si se encuentra "papa" entonces no se tomará en cuenta, pero además si pone "PAPA" por si solo buscará solo un texto asÃ, si el texto tiene algo más como por ejemplo "PAPA AMARILLA" no se tomará en cuenta, para poder buscar más finamente puedes usar "PAPA%" y asà "PAPA AMARILLA" será tomado en cuenta ya que "%" indica que no importa lo que venga despues, pero "ME GUSTA LA PAPA AMARRILA" no aparecerá, ya que el texto no empieza con "PAPA" para que aparezca debes usar "%PAPA%", esto indica que se debe buscar cualquier texto que tenga la palabra "PAPA" dentro de si, incluso algo como esto "ME GUSTA EL PAPAPAN" aparecerÃa como encontrado.
La búsqueda con iLIKE funciona tal cual como la LIKE pero con la diferencia fundamental que no importará si el texto está en mayúsculas o minúsculas entonces si uds. buscan "PAPA" y el texto es "me gusta la papa amarilla" se mostrará como encontrado.
Ahora como verán esto no es muy eficiente en el sentido que buscar palabras sueltas o frases completas en una base de datos grande de pdf podrÃa ser casi imposible conseguir encontrar algo, generalmente uno busca palabras sueltas como por ejemplo "quiero buscar los textos que tengan la palabra casa, el nombre ernesto y la fecha 2011", tu búsqueda incluye: "casa", "ernesto" y "2011", eso se hace con los botones de lexemas.
Los 2 botones funcionan igual solo los diferencia si quieren utilizar la fonética castellana o inglesa, uno puede hacer una busqueda por ejemplo de la palabra "modulo" y aparecerán los textos que contengan la palabra "MODULO" y "módulo", luego podrÃan buscar las palabras del ejemplo bajo esta forma: "casa & ernesto & 2011", esto busca los textos que tengan las 3 palabras, pero podrÃamos hacer esto "casa | ernesto | 2011" donde pedimos los textos que tengan al menos una de las 3 palabras, en resumen & es el operador lógico "Y" y | es el operador lógico "O", también puedes hacer negaciones asÃ: "!casa & ernesto", eso quiere decir busca los textos que tengan la palabra "ernesto" pero no la palabra "casa".
¿Que necesitan para correr/compilar el programa?
el programa lo desarrollé utilizando QTCreator, asà que si lo tienen instalado no deberÃa haber problemas, si quieren solo ejecutarlo necesitan las librerias de QT, especialmente las de QtSql, y la de Poppler-QT (esta librerÃa es la que nos deja manipular los PDFs) aquà les pongo los includes:
QtGui
poppler-qt4.h
QtSql/QSqlDatabase
QtSql/QPSQLDriver
QtSql/QSqlQuery
QtSql/QSqlError
QtSql/QSqlRecord
QErrorMessage
QStandardItem
QStandardItemModel
¿Que hay que mejorar?
No pienso tocar el programa hasta nuevo aviso, no lo voy a subir a sourceforge, github, freshmeat o lo que sea de momento, si quieres apoyar me mandas un email con el proyecto cambiado (asà todo a lo bruto) o simplemente sacas tu fork, hay muchas cosas que mejorar, entre ellas:
1. La programación no está muy orientada a objetos que digamos, parece visual basic aplicado en C++, hay que crear clases para manipular el pdf por ejemplo y para las búsquedas, eso me parecerÃa muy adecuado.
2. Es necesario generar una rutina que lea archivos de configuración, especialmente la configuración de la db, de esa manera el programa no necesitarÃa funcionar solo con una db local sino con cualquier db externa y podrÃa ser compartido por muchos usuarios al mismo tiempo.
3. Para que pueda ser un proyecto totalmente cliente servidor el PDF tendrÃa que subirse a la DB también, de tal manera que cuando se realice la búsqueda se pueda descargar desde ahà y no guardar la ruta del file, eso ayudarÃa mucho, además no se está guardando el nombre del pdf en realidad lo cual es una desventaja terrible, como esto es una primera aproximación me he saltado varias cosas importantes.
4. Estandarizar nomenclaturas, todo esta un desorden.
5. Cambiar los mensajes, todo lo presento en un solo formato.
6. Hasta el momento no encuentro como cerrar adecuadamente la pantalla
Estos son los temas que de momento pienso trabajar para la versión 0.2 y tener algo más decente, de momento ya cumple su objetivo.
¿Qué se debe desarrollar a futuro?
Etapa 1:
1. El pdf no se debe poder guardar como "un todo" y página por página, asà cuando se busque un texto debe poder indicarme dentro de un pdf en que páginas han sido encontradas las coincidencias, o eventualmente buscar en el texto del todo yde ahà poder bajar a nivel de gina abriendo una nueva pantalla.
2. Filtros para búsquedas más complejas, habrÃa que pensar algo de ese estilo.
3. Leer todo un directorio de PDFs para subirlos, para no tener que hacerlo 1 x 1.
4. No depender de cargar el texto en la pantalla para subirlo, que se pueda tener la opción de subirlo directamente sin verlo, pero mantener la otra opción que sirvió de control de calidad para seleccionar que tanto vale la pena subir un pdf o no a la db dependiendo de como se hizo la lectura del mismo.
Etapa 2:
1. Renderizar el pdf desde la misma aplicación
2. Internacionalizar textos y mensajes, lo pensaba hacer en un archivo de configuración para que sea más facil y no meterme en N vueltas de programación
3. Compilar en monolÃtico, asà se podrÃa tener un aplicativo que tenga dentro de si todo lo necesario para ejecutarse sin tener que depender de tener las librerÃas, o sino crear un .DEB y un .RPM para la instalación.
Etapa 3:
1. Poder subir otros tipos de archivos como libre office o ms office y realizar el mismo trabajo de indexamiento del documento.
2. Poder subir gráficos con texto y por OCR poder obtener los mismos para indexarlos
Los interesados en apoyar me pueden escribir para organizarnos, los que quieran colaborar directo ya les comento que marzo y abril seguro ya no seguiré tocando el código, de todas maneras me escriben antes de tocar algo para poder comentarles si ya no estoy trabajando en eso.
Si se preguntan a estas alturas en que sistema operativo corre, es solo para Gnu/Linux, si se preguntan cuando correrá en Windows, solo pasará si alguien me paga por hacerlo para ajustarlo para esa plataforma.
Finalmente AQUI ESTA EL CODIGO y esto está probado y testeado en Gnu/Linux - Ubuntu v.11.10
Restricciones (pero no tantas en realidad) el programa funciona de forma local, osea busca tu DB en localhost, sin embargo es algo que se puede mejorar fácilmente con pequeños cambios, pero de momento la db y la app deben estar en la misma pc si es que quieres usar de frente el ejecutable.
El programa tiene una sola interface, muy sencilla por cierto, que tiene 2 tabs, el primero permite cargar los pdfs y el segundo hacer las búsquedas, el flujo es el siguiente:
Primero, se debe conectar a la DB, para eso encontrarás un botoncito en la parte superior derecha.
Segundo, debes subir PDFs a la aplicación, para eso hay un botón que dice "subir file", este lo que hace en realidad es "leer" el PDF y presentará el contenido en la ventana derecha.
* Tercero, bajar el contenido a la DB, para eso tienes 2 botones, uno si el contenido es en español y el otro si está en ingles, ¿porque esto?, bueno es simple en realidad, las búsquedas especiales por lexemas tienen esa caracterÃstica, dependiendo el idioma indexan los vectores y las búsquedas son más eficientes cuando tienes claro que idioma buscar.
Cuando tienes subidos los PDFs solo tienes que ir a el tab de Búsquedas y encontrarás 4 botones que explicaré luego.
En primer lugar si bien uso PostgreSQL 9.1 podrÃas usar 8.4 sin problemas, la base de datos se llama "indexadorpdf" y tengo una sola tabla donde almaceno todo el pdf (algo que hay que mejorar), la tabla se llama "tblpdf" y la estructura es asÃ:
indexadorpdf=# \d tblpdf
Table "public.tblpdf"
Column | Type | Modifiers
-------------+------------------------+-----------
nombre | character varying(250) |
tipo | character(3) |
texto | text |
textovector | tsvector |
Como verán es bastante simple, el campo "nombre" almacena el nombre y ruta del pdf (otra cosa a mejorar también), el campo "tipo" es para almacenar el tipo del documento, en este caso se pone pdf como texto duro, el campo "texto" tiene el contenido del PDF, todo completito, y el campo "textovector" tiene el contenido vectorizado por lexemas.
¿Que es un lexema?
No soy un experto en esto pero el tema es asÃ, cuando tu haces una búsqueda puedes buscar las palabras por su raÃz fonética, digamos la palabra "padre", la raÃz es "padr" y eso es lo que se guarda en un vector, entonces cuando uno busque con lexemas puede obtener resultados parecidos como padre, padrino, padrasto, etc. la idea es que uno haga búsquedas estilo "Google" donde puedo hasta escribir una palabra mal, por ejemplo sin acento y se puedan ubicar los textos que correspondan o se acerquen a ellos.
Ahora si pasemos a la pestaña de búsqueda, esta pantalla tiene un textbox donde puedes ingresar el contenido de tu búsqueda, en este textbox puedes ingresar el texto a buscar y los operadores, estos operadores responderán al tipo de búsqueda a utilizar.
Esta parte es para los no expertos en querys:
La búsqueda con LIKE busca palabras exactas, tal cual están escritas, por ejemplo si ponen "PAPA" se buscaran los textos con la palabra "PAPA" pero asà en mayúsculas, si se encuentra "papa" entonces no se tomará en cuenta, pero además si pone "PAPA" por si solo buscará solo un texto asÃ, si el texto tiene algo más como por ejemplo "PAPA AMARILLA" no se tomará en cuenta, para poder buscar más finamente puedes usar "PAPA%" y asà "PAPA AMARILLA" será tomado en cuenta ya que "%" indica que no importa lo que venga despues, pero "ME GUSTA LA PAPA AMARRILA" no aparecerá, ya que el texto no empieza con "PAPA" para que aparezca debes usar "%PAPA%", esto indica que se debe buscar cualquier texto que tenga la palabra "PAPA" dentro de si, incluso algo como esto "ME GUSTA EL PAPAPAN" aparecerÃa como encontrado.
La búsqueda con iLIKE funciona tal cual como la LIKE pero con la diferencia fundamental que no importará si el texto está en mayúsculas o minúsculas entonces si uds. buscan "PAPA" y el texto es "me gusta la papa amarilla" se mostrará como encontrado.
Ahora como verán esto no es muy eficiente en el sentido que buscar palabras sueltas o frases completas en una base de datos grande de pdf podrÃa ser casi imposible conseguir encontrar algo, generalmente uno busca palabras sueltas como por ejemplo "quiero buscar los textos que tengan la palabra casa, el nombre ernesto y la fecha 2011", tu búsqueda incluye: "casa", "ernesto" y "2011", eso se hace con los botones de lexemas.
Los 2 botones funcionan igual solo los diferencia si quieren utilizar la fonética castellana o inglesa, uno puede hacer una busqueda por ejemplo de la palabra "modulo" y aparecerán los textos que contengan la palabra "MODULO" y "módulo", luego podrÃan buscar las palabras del ejemplo bajo esta forma: "casa & ernesto & 2011", esto busca los textos que tengan las 3 palabras, pero podrÃamos hacer esto "casa | ernesto | 2011" donde pedimos los textos que tengan al menos una de las 3 palabras, en resumen & es el operador lógico "Y" y | es el operador lógico "O", también puedes hacer negaciones asÃ: "!casa & ernesto", eso quiere decir busca los textos que tengan la palabra "ernesto" pero no la palabra "casa".
¿Que necesitan para correr/compilar el programa?
el programa lo desarrollé utilizando QTCreator, asà que si lo tienen instalado no deberÃa haber problemas, si quieren solo ejecutarlo necesitan las librerias de QT, especialmente las de QtSql, y la de Poppler-QT (esta librerÃa es la que nos deja manipular los PDFs) aquà les pongo los includes:
QtGui
poppler-qt4.h
QtSql/QSqlDatabase
QtSql/QPSQLDriver
QtSql/QSqlQuery
QtSql/QSqlError
QtSql/QSqlRecord
QErrorMessage
QStandardItem
QStandardItemModel
¿Que hay que mejorar?
No pienso tocar el programa hasta nuevo aviso, no lo voy a subir a sourceforge, github, freshmeat o lo que sea de momento, si quieres apoyar me mandas un email con el proyecto cambiado (asà todo a lo bruto) o simplemente sacas tu fork, hay muchas cosas que mejorar, entre ellas:
1. La programación no está muy orientada a objetos que digamos, parece visual basic aplicado en C++, hay que crear clases para manipular el pdf por ejemplo y para las búsquedas, eso me parecerÃa muy adecuado.
2. Es necesario generar una rutina que lea archivos de configuración, especialmente la configuración de la db, de esa manera el programa no necesitarÃa funcionar solo con una db local sino con cualquier db externa y podrÃa ser compartido por muchos usuarios al mismo tiempo.
3. Para que pueda ser un proyecto totalmente cliente servidor el PDF tendrÃa que subirse a la DB también, de tal manera que cuando se realice la búsqueda se pueda descargar desde ahà y no guardar la ruta del file, eso ayudarÃa mucho, además no se está guardando el nombre del pdf en realidad lo cual es una desventaja terrible, como esto es una primera aproximación me he saltado varias cosas importantes.
4. Estandarizar nomenclaturas, todo esta un desorden.
5. Cambiar los mensajes, todo lo presento en un solo formato.
6. Hasta el momento no encuentro como cerrar adecuadamente la pantalla
Estos son los temas que de momento pienso trabajar para la versión 0.2 y tener algo más decente, de momento ya cumple su objetivo.
¿Qué se debe desarrollar a futuro?
Etapa 1:
1. El pdf no se debe poder guardar como "un todo" y página por página, asà cuando se busque un texto debe poder indicarme dentro de un pdf en que páginas han sido encontradas las coincidencias, o eventualmente buscar en el texto del todo yde ahà poder bajar a nivel de gina abriendo una nueva pantalla.
2. Filtros para búsquedas más complejas, habrÃa que pensar algo de ese estilo.
3. Leer todo un directorio de PDFs para subirlos, para no tener que hacerlo 1 x 1.
4. No depender de cargar el texto en la pantalla para subirlo, que se pueda tener la opción de subirlo directamente sin verlo, pero mantener la otra opción que sirvió de control de calidad para seleccionar que tanto vale la pena subir un pdf o no a la db dependiendo de como se hizo la lectura del mismo.
Etapa 2:
1. Renderizar el pdf desde la misma aplicación
2. Internacionalizar textos y mensajes, lo pensaba hacer en un archivo de configuración para que sea más facil y no meterme en N vueltas de programación
3. Compilar en monolÃtico, asà se podrÃa tener un aplicativo que tenga dentro de si todo lo necesario para ejecutarse sin tener que depender de tener las librerÃas, o sino crear un .DEB y un .RPM para la instalación.
Etapa 3:
1. Poder subir otros tipos de archivos como libre office o ms office y realizar el mismo trabajo de indexamiento del documento.
2. Poder subir gráficos con texto y por OCR poder obtener los mismos para indexarlos
Los interesados en apoyar me pueden escribir para organizarnos, los que quieran colaborar directo ya les comento que marzo y abril seguro ya no seguiré tocando el código, de todas maneras me escriben antes de tocar algo para poder comentarles si ya no estoy trabajando en eso.
Si se preguntan a estas alturas en que sistema operativo corre, es solo para Gnu/Linux, si se preguntan cuando correrá en Windows, solo pasará si alguien me paga por hacerlo para ajustarlo para esa plataforma.
Finalmente AQUI ESTA EL CODIGO y esto está probado y testeado en Gnu/Linux - Ubuntu v.11.10
Publicado por Ernesto Quiñones
en Informática, Software Libre
a las
10:48
| No hay comentarios
| No hay referencias
| Salidas (203)
Referencias
URI de referencia para esta entrada
No hay referencias






