Está en la página 1de 205

DEPARTAMENTO DE INGENIERA

DE SISTEMAS Y AUTOMTICA
ESCUELA TCNICA SUPERIOR DE INGENIEROS E.S.I.
UNIVERSIDAD DE SEVILLA
PROYECTO FIN DE CARRERA

SISTEMA

GESTIN DOCUMENTAL
TRAVS DE INTERNET
DE

INGENIERA DE TELECOMUNICACIN

AUTOR: CARLOS ALBERTO GARCA LVAREZ


TUTOR: EDUARDO FERNNDEZ CAMACHO

SEVILLA, FEBRERO DE 2007

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

NDICE

DEL

PROYECTO "SISTEMA

GESTIN DOCUMENTAL A TRAVS DE


INTERNET "
DE

1. Anlisis de Antecedentes............................................................................................. 6
1.1. Bases de Datos..................................................................................................... 6
1.1.1. MySQL........................................................................................................... 6
1.1.2. PHP............................................................................................................... 9
1.1.3. HTML.......................................................................................................... 10
1.2. Mtodos Educativos........................................................................................... 11
1.2.1. Matlab......................................................................................................... 12
1.2.2. Microsoft Visual Studio .NET.................................................................... 18
2. Anlisis de Factibilidad............................................................................................ 21
3. Objetivos del Proyecto.............................................................................................. 22
3.1. Actualizacin Automtica de Bases de Datos.................................................. 22
3.2. Requisitos Previos para la Actualizacin Automtica.................................... 22
3.2.1. MySQL Server............................................................................................ 23
3.2.2. MySQL Control Center.............................................................................. 26
3.2.3. Apache Web Server.................................................................................... 27
3.2.4. PHP............................................................................................................ 29
3.2.5. Groupweb................................................................................................... 33
3.2.5.1. Copia Local del Sitio Web................................................................... 34
3.2.5.2. Restauracin de la Base de Datos..................................................... 34
3.2.5.2.1. Introduccin al Comando "mysqldump".................................... 34
3.2.5.2.2. Restauracin de la Base de Datos a Travs de Mysqldump..... 38
3.2.5.3. Estructura del Sitio Web.................................................................... 40
3.2.5.4. Relacin entre las Tablas de la Base de Datos..................................40
3.3. Control Remoto de Procesos en Tiempo Real Mediante Matlab/Tcp/Ip........45
3.4. Requisitos Previos para el Control Remoto..................................................... 45
3.4.1. Microsoft Visual .NET................................................................................ 45
3.4.2. Matlab 6.5.................................................................................................. 46
4. Metodologa.............................................................................................................. 47
4.1. Actualizacin Automtica de Bases de Datos................................................... 47
4.1.1. Paso 1 Validacin.................................................................................... 49
4.1.2. Paso 2 Seleccin de ficheros e Insercin de Rutas................................. 50
4.1.3. Paso 3 Seleccin de Campos de la Actualizacin................................... 53
4.1.4. Paso 4 Complecin de Entradas para Actualizacin............................ 55
4.1.5. Fichero de Inclusin General..................................................................... 60
4.2. Control Remoto de Procesos en Tiempo Real mediante Matlab/TCP/IP....... 61
4.2.1. Estructura General del Sistema de Control Remoto................................ 63
4.2.2. Servigar..................................................................................................... 64
4.2.2.1. Interfaz Web....................................................................................... 64
4.2.2.2. Aplicacin Servidor en Servigar........................................................ 67
4.2.3. Neoxite....................................................................................................... 69
4.2.3.1. Bloque Tunning (S-Function)............................................................. 69
4.2.3.2. Aplicacin Matlab............................................................................... 71
3

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


4.2.3.3. Aplicacin Cliente............................................................................... 72
4.2.3.4. Aplicacin Servidor............................................................................ 74
4.2.4. Ubicacin y Puesta a Punto de los Programas......................................... 75
4.2.5. Ejemplo Completo de Control Remoto...................................................... 77
5. Resultados Experimentales...................................................................................... 86
5.1. Sistema de Actualizacin de Bases de Datos.................................................... 86
5.2. Control Remoto de Una Planta a Travs de Una Interfaz Web Usando
Matlab...................................................................................................................... 87
6. Concordancia Entre Resultados y Objetivos........................................................... 88
6.1. Sistema de Actualizacin de Bases de Datos.................................................... 88
6.2. Control Remoto de Planta Mediante Matlab/TCP/IP.................................... 88
7. Conclusiones............................................................................................................. 89
7.1. Actualizacin Automtica de Base de Datos.................................................... 89
7.2. Control Remoto de Sistemas mediante Matlab/Simulink............................... 90
8. Futuras Mejoras (Lneas de Investigacin)............................................................. 91
9. Bibliografa............................................................................................................... 93
10. Anexos..................................................................................................................... 94
10.1. Contenidos del CD-Rom.................................................................................. 94
10.2. Manual de Uso: Sistema de Actualizacin de Bases de Datos...................... 96
10.2.1. Instalacin................................................................................................ 96
10.2.2. Usando el Sistema de Actualizacin de Bases de Datos......................... 96
10.2.2.1. Actualizar Base de Datos.................................................................. 97
10.2.2.2. Editar Fichero de Definicin de Publicaciones............................... 98
10.2.2.3. Crear Copia de Seguridad de la Base de Datos...............................99
10.2.2.4. Restaurar Copia de Seguridad de la Base de Datos....................... 99
10.3. Manual de Uso: Sistema de Control Remoto............................................... 100
10.3.1. Instalacin.............................................................................................. 100
10.3.2. Usando el Control Remoto..................................................................... 101
10.4. Cdigo Fuente................................................................................................ 103
10.4.1. Sistema de Actualizacin de Bases de Datos......................................... 103
10.4.1.1. Update.html..................................................................................... 103
10.4.1.2. Paso1.php......................................................................................... 105
10.4.1.3. Paso2.php........................................................................................ 106
10.4.1.4. Paso3.php......................................................................................... 111
10.4.1.5. Proc_files.php.................................................................................. 127
10.4.1.6. Backup.php...................................................................................... 130
10.4.1.7. Pubs_editor.php.............................................................................. 135
10.4.1.8. Functions.inc.php............................................................................ 137
10.4.1.9. Functions.step3.php........................................................................ 146
10.4.1.10. Help.html....................................................................................... 167
10.4.2. Control Remoto de Procesos mediante Matlab/TCP/IP.......................170
10.4.2.1. Tunning.aspx.cs.............................................................................. 170
10.4.2.2. cp_server_servigar........................................................................ 176
10.4.2.3. Tunning.c........................................................................................ 185
10.4.2.4. Sendtoservigar.m............................................................................ 191
10.4.2.5. cp_client_neoxite............................................................................ 193
10.4.2.6. cp_server_neoxite.......................................................................... 198

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

1 A NLISIS
1.1 B ASES

DE

DE

A NTECEDENTES .

D ATOS .

Hoy en da las bases de datos son la base de muchos sistemas de almacenamiento de


informacin. Sin ellas, la informacin de que se dispone se encontrara desperdigada,
ilocalizable en las situaciones de necesidad, con las consiguientes repercusiones que ello
tiene en una sociedad de la informacin como es aquella en la que nos encontramos.
Una posible definicin de "base de datos" es "conjunto de datos que pertenecen al
mismo contexto almacenados semnticamente para su posterior uso". Las bases de datos
permiten, por tanto, almacenar y clasificar los datos de forma ordenada. Es por ello que se
antojan una herramienta necesaria y de uso obligado en la mayora de sistemas actuales.
El inconveniente que presentan es su mantenimiento. El tiempo de mantenimiento de
una base de datos aumenta exponencialmente con el volumen de datos a actualizar.
Este inconveniente se agrava si con la misma informacin hay que actualizar distintas
bases de datos. Es inevitable tener que actualizar una base de datos, pero el problema de
actualizar varias con la misma informacin (o con informacin similar) se paliara en gran
medida si se dispusiera de un sistema con cierta inteligencia que realizara el trasvase de
informacin de una base de datos a las dems.
Dicho sistema inteligente debe emplear tecnologas especficas que soporten el manejo
de bases de datos. Entre ellas se encuentran MySQL, PHP o HTML, cuyas caractersticas
se abordan en los siguientes apartados.

1.1.1 M YSQL.
MySQL es un sistema de gestin de base de datos, multihilo y multiusuario.
MySQL es un sistema de administracin de bases de datos. Una base de datos es una
coleccin estructurada de datos. Esta puede ser desde una simple lista de compras a una
galera de pinturas hasta el vasto volumen de informacin en un red corporativa. Para
agregar, acceder a y procesar datos guardados en un computador, se necesita un
administrador como MySQL Server. Dado que los ordenadores son muy buenos manejando

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


grandes cantidades de informacin, los administradores de bases de datos juegan un papel
central en computacin, como aplicaciones independientes o como parte de otras
aplicaciones.
SQL (Standard Query Language) es un lenguaje estandarizado de base de datos
relacionantes, el cual nos permite realizar tablas y obtener datos de ella de manera muy
sencilla. Gracias a l podemos realizar diversos tipos de operaciones sobre una base de
datos.
SQL trabaja con una estructura de dos capas, o sea, con una estructura cliente/servidor.
El cliente comienza el proceso mediante el envo de una consulta, el servidor la recibe, la
procesa y devuelve un resultado. El cliente es el que realiza la mayor parte de la tarea ya
que se encarga de mostrar los datos por pantalla, presentar informes tabulados, imprimir,
guardar, etc, dejando al servidor libre para otras tareas.
MySQL es un sistema de administracin relacional de bases de datos. Una base de
datos relacional archiva datos en tablas separadas en vez de colocar todos los datos en un
gran archivo. Esto permite velocidad y flexibilidad. Las tablas estn conectadas por
relaciones definidas que hacen posible combinar datos de diferentes tablas sobre pedido.
MySQL es software de cdigo abierto (open source). Fuente abierta significa que es
posible para cualquier persona usarlo y modificarlo. Cualquier persona puede bajar el cdigo
fuente de MySQL y usarlo sin pagar. Cualquier interesado puede estudiar el cdigo fuente y
ajustarlo a sus necesidades. MySQL usa el GPL (GNU General Public License) para definir
qu puede hacer y qu no puede hacer con el software en diferentes situaciones.
Un aspecto importante en el diseo de una base de datos reside en la eleccin de los
ndices y evitando hacer escaneos completos de las tablas.
Los ndices son usados para encontrar rpidamente los registros que tengan un
determinado valor en alguna de sus columnas. Sin un ndice, MySQL tiene que iniciar la
bsqueda con el primer registro y leer a travs de toda la tabla para encontrar los registros
relevantes. An en tablas pequeas, de unos 1000 registros, es por lo menos 100 veces
ms rpido leer los datos usando un ndice que haciendo una lectura secuencial.
Cuando MySQL trata de responder una consulta, examina una variedad de estadsticas
acerca de los datos, y decide cmo buscar los que deseamos de la manera ms rpida. Sin
embargo, como se acaba de mencionar, cuando en una tabla no existen ndices en los
cuales pueda auxiliarse MySQL para resolver una consulta, se tendrn que leer todos los
registros de la tabla de manera secuencial. Esto es comnmente llamado un escaneo

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


completo de una tabla, y es muchas veces algo que se debe evitar.
En particular, se deben evitar las escaneos completos de tablas por las siguientes
razones:

Sobrecarga de CPU: El proceso de comprobar cada uno de los registros en una

tabla es insignificante cuando se tienen pocos datos, pero puede convertirse en un


problema a medida que va aumentando la cantidad de registros en nuestra tabla.
Existe una relacion proporcional entre el numero de registros que tiene una tabla y la
cantidad de tiempo que le toma a MySQL revisarla completamente.

Concurrencia: Mientras MySQL est leyendo los datos de una tabla, ste la

bloquea, de tal manera que nadie ms puede escribir en ella, aunque s pueden
leerla. Cuando MySQL est actualizando o eliminando filas de una tabla, ste la
bloquea, y por lo tanto nadie puede al menos leerla.

Sobrecarga de disco: En una tabla muy grande, un escaneo completo consume

una

gran

cantidad

de

entrada/salida

en

el

disco.

Esto

puede

alentar

significativamente el servidor de bases de datos, especialmente si se tiene un disco


IDE algo antiguo.
En resumen, lo mejor es intentar que los escaneos completos de tablas sean minimos
(especialmente si la aplicacin necesita escalabilidad en tamao, nmero de usuarios, o
ambos).
Es en estos casos donde la indexacin puede ayudar. De manera simple, un ndice le
permite a MySQL determinar si un valor dado coincide con cualquier fila en una tabla.
Cuando se indexa una columna en particular, MySQL crea otra estructura de datos (un
ndice) que usa para almacenar informacin extra acerca de los valores en la columna
indexada. Los valores indexados son llamados frecuentemente claves. Aunque sta es la
manera simple de explicar los ndices, realmente es un poco mas complejo, ya que MySQL
almacena todas las claves del ndice en una estructura de datos de rbol. Esta estructura de
datos de rbol le permite a MySQL encontrar claves muy rpidamente.
Cuando MySQL determine la existencia de un ndice en una columna, lo usar en vez de
hacer un escaneo completo de la tabla. Esto reduce de manera importante los tiempos de
CPU y las operaciones de entrada/salida en disco, a su vez que se mejora la concurrencia
porque MySQL bloquear la tabla nicamente para obtener las filas que necesite (en base a
lo que encontr en el ndice). Cuando tenemos grandes cantidades de datos en nuestras
tablas, la mejora en la obtencion de los datos puede ser muy significativa.

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

1.1.2 PHP.
PHP es un lenguaje de programacin usado generalmente para la creacin de
contenidos de sitios web. El nombre es el acrnimo recursivo de "PHP: Hypertext
Preprocessor" (inicialmente "PHP Tools" o "Personal Home Page Tools") y se trata de un
lenguaje interpretado usado para la creacin de aplicaciones para servidores, o creacin de
contenido dinmico para sitios web.
La interpretacin del cdigo en lenguaje PHP y su ejecucin se da en el servidor, en el
cual se encuentra almacenado el script, y el cliente slo recibe el resultado de la ejecucin.
Cuando el cliente hace una peticin al servidor para que le enve una pgina web, generada
por un script PHP, el servidor ejecuta el intrprete de PHP, el cual procesa el script
solicitado que generar el contenido de manera dinmica, pudiendo modificar el contenido a
enviar, y regresa el resultado al servidor, el cual se encarga de regresrselo al cliente.
PHP permite la conexin a diferentes tipos de servidores de bases de datos, entre ellos
el que interesa para el presente proyecto (MySQL).
PHP tambin tiene la capacidad de ser ejecutado en distintos sistemas operativos, entre
los que se incluyen Windows y Linux (los dos sistemas operativos sobre los que se prueba
el script realizado aqu).
Los principales usos de PHP son los siguientes:

Programacin de pginas web dinmicas, habitualmente en combinacin con el


motor de bases de datos MySQL, aunque cuenta con soporte nativo para otros
motores, incluyendo el estndar ODBC, lo que ampla en gran medida sus
posibilidades de conexin.

Programacin en consola, al estilo de Perl o Shell scripting.

Creacin de aplicaciones grficas independientes del navegador, por medio de la


combinacin de PHP y GTK (Gimp Tool Kit), lo que permite desarrollar aplicaciones
de escritorio en los sistemas operativos en que est soportado.

Las ventajes de PHP son que se trata de un lenguaje multiplataforma, posee capacidad
de conexin con la mayora de los manejadores de bases de datos que se utilizan en la
actualidad, permite leer y manipular datos desde diversas fuentes (incluyendo los datos que
pueden ingresar los usuarios desde formularios HTML), posee capacidad de expandir su
potencial utilizando la enorme cantidad de mdulos (tambin conocidos como "extensiones")

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


de que dispone, es libre, se encuentra muy bien documentado y por ltimo nos permite crear
formularios web.
La mayora de estas ventajas sern explotadas para la realizacin del script de
actualizacin de la pgina web.

1.1.3 HTML.
HTML (acrnimo ingls de "HyperText Markup Language") es un lenguaje de marcacin
diseado para estructurar textos y presentarlos en forma de hipertexto, que es el formato
estndar de las pginas web. Gracias a Internet y a los navegadores del tipo Internet
Explorer, Opera, Firefox o Netscape, el HTML se ha convertido en uno de los formatos ms
populares que existen para la construccin de documentos y tambin de los ms fciles de
aprender.
HTML es una aplicacin de SGML conforme al estndar internacional ISO 8879. XHTML
es una reformulacin de HTML 4 como aplicacin XML 1.0, y que supone la base para la
evolucin estable de este lenguaje. Adems, XHTML permite la compatibilidad con los
agentes de usuario que ya admitan HTML 4 siguiendo un conjunto de reglas.
El lenguaje HTML puede ser creado y editado con cualquier editor de textos bsico,
como puede ser el Bloc de Notas de Windows (o Notepad), o cualquier otro editor que
admita texto sin formato como GNU Emacs, Microsoft Wordpad, TextPad, Vim, Notepad++,
etc.
Existen adems, otros programas para la realizacin de sitios Web o edicin de cdigo
HTML, como por ejemplo Microsoft FrontPage, el cual tiene un formato bsico parecido al
resto de los programas de Office. Tambin existe el famoso software de Macromedia (que
adquiri la empresa Adobe) llamado Dreamweaver, siendo uno de los ms utilizados en el
mbito de diseo y programacin Web. Estos programas se les conoce como editores
WYSIWYG o What You See Is What You Get (en espaol: lo que ves es lo que obtienes).
Esto significa que son editores que van mostrando el resultado de lo que se est editando
en tiempo real a medida que se va desarrollando el documento. Ahora bien, esto no significa
una manera distinta de realizar sitios web, sino que una forma un tanto ms simple ya que
estos programas, adems de tener la opcin de trabajar con la vista preliminar, tiene su
propia seccin HTML la cual va generando todo el cdigo a medida que se va trabajando.
Combinar estos dos mtodos resulta muy interesante, ya que de alguna manera se

10

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


ayudan entre s. Por ejemplo; si se est editando todo en HTML y de pronto se olvida algn
cdigo o etiqueta, simplemente hay que dirigirse al editor visual o WYSIWYG y continuar ah
la edicin, o viceversa, ya que hay casos en que es ms rpido y fcil escribir directamente
el cdigo de alguna caracterstica que se quiera adherirle al sitio, que buscar la opcin en el
programa mismo.
HTML utiliza etiquetas o marcas, que consisten en breves instrucciones de comienzo y
final, mediante las cuales se determinan la forma en la que debe aparecer en el navegador
el texto, as como tambin las imgenes y los dems elementos, en la pantalla del
ordenador.
Toda etiqueta se identifica porque est encerrada entre los signos menor que y mayor
que (< y >, respectivamente), y algunas tienen atributos que pueden tomar algn valor. En
general las etiquetas se aplicarn de dos formas especiales:

Se abren y se cierran, como por ejemplo: <b>negrita</b> que se vera en el

navegador como negrita.

No pueden abrirse y cerrarse, como <hr> que se vera en su navegador como una

lnea horizontal (aunque en el nuevo estndar XHTML 1.0 se escribe de la forma <hr
/>, cerrndose de forma correcta en este nuevo estndar, es decir, que para cerrar
una etiqueta que no tiene cierre en HTML, se antepone una barra inclinada al signo
mayor que).

Otras que pueden abrirse y cerrarse, como por ejemplo <p>.

1.2 M TODOS E DUCATIVOS .


Hoy por hoy, las prcticas de laboratorio son un cuello de botella en cualquier carrera de
ingeniera. La escasez de recursos y la limitacin del uso de stos debido a la gran cantidad
de alumnos que llenan las aulas constituyen un grave impedimento para el aprendizaje de
los alumnos.
Una posible ayuda ante este problema sera poner esta tecnologa al alcance del alumno
en cualquier momento y desde cualquier sitio. Las tecnologas de la informacin que
proporciona internet permiten esto.
El acceso a travs de una web al material disponible en los laboratorios permitira el
acceso a los recursos de forma ordenada y con una mayor eficiencia.
Las ventajas que este tipo de acceso traeran consigo podran verse reflejadas en, por

11

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


ejemplo, prcticas de control sobre sistemas fsicos disponibles en un laboratorio. Los
controladores pueden implementarse en programas especficos de control como pueden ser
LabView o Matlab (a travs de Simulink). Conectando de alguna forma estos programas con
una interfaz web que permitiera a los usuarios conectarse desde sus propios hogares
mediante un nombre de usuario y una contrasea, stos podran realizar el control de forma
alternativa a la asistencia a clase.
Las ventajas son obvias: si a un alumno le faltase tiempo para realizar las prcticas en el
tiempo asignado en laboratorio, siempre podra ampliar el tiempo disponible realizando
dichas prcticas a travs de una interfaz web desde su propia casa.
No obstante, las desventajas tampoco son inexistentes: por una parte, hay que crear
dicha interfaz, aadirle las restricciones necesarias

para que los

controladores

implementados no produzcan malfuncionamientos en el sistema de pruebas, crear un


sistema de validacin de usuarios, etc.
Las tecnologas ms comunes para el control de procesos o mquinas en los
laboratorios son Matlab y LabView. Matlab, a travs de su herramienta Simulink, permite
implementar controladores para simulacin o para pruebas en tiempo real a travs del
paquete Real Time Workshop, y es el programa en el que se centrar el presente proyecto.
Por otra parte, puesto que es necesaria la programacin de una interfaz, se ha elegido el
paquete de programacin Microsoft Visual Studio .NET para la consecucin de una interfaz
web basada en ASP que implemente validacin de usuarios y permite el control remoto.

1.2.1 M ATLAB .
Matlab es la abreviatura de "Matrix Laboratory" (laboratorio de matrices). Es un programa
de matemticas creado por "The MathWorks" en 1984. Est disponible para las plataformas
Unix, Windows y Mac.
Es un software muy usado en universidades, centros de investigacin y por ingenieros.
En los ltimos aos ha incluido muchas ms capacidades, como la de programar
directamente procesadores digitales de seales, crear cdigo VHDL y otras.
Matlab es un programa de clculo numrico, orientado a matrices y vectores. Por tanto,
desde el principio hay que pensar que todo lo que se pretenda hacer con l, ser mucho
ms rpido y efectivo si se piensa en trminos de matrices y vectores.
Posee una interfaz fcil de usar: su ventana principal se divide en tres partes principales:

12

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


el historial de comandos (todos los comandos insertados en la ventana de comandos
ordenados cronolgicamente por orden de insercin), el espacio de trabajo (que muestra
todas las variables creadas en el entorno de trabajo de Matlab, as como el espacio ocupado
por las mismas y sus valores) y la ventana de comandos, que es la parte ms interesante
para el usuario, ya que es en ella donde se ejecutan las rdenes deseadas y se invocan las
funciones necesarias para realizar los clculos deseados.
Las capacidades de Matlab se pueden ampliar toolboxes. Cada uno de los toolboxes (o
cajas de herramientas) se han creado con una finalidad concreta. Estos toolboxes son
paquetes de funciones especializadas. As, se encuentran los siguientes toolboxes:

Control

System

Toolbox:

este

paquete

proporciona

herramientas

para

sistemticamente analizar, disear y afinar (sintonizar) sistemas de control lineales.


Se puede especificar el modelo lineal del sistema, representar sus respuestas
temporal y frecuencial para entender el comportamiento del sistema, sintonizar los
parmetros del controlador utilizando tcnicas automatizadas e interactivas, y
verificar los requisitos de rendimiento, tales como tiempo de subida y mrgenes de
ganancia/fase. Un conjunto de interfaces grficas de usuario basadas en flujo de
trabajo (workflow) guan al usuario en cada paso del proceso de diseo y anlisis.

Robust Control Toolbox: la caja de herramientas de control robusto es una

coleccin de funciones y herramientas que ayudan al usuario a analizar y disear


sistemas de control con varias entradas y salidas (MIMO o MultiInput-MultiOutput)
con elementos inciertos. Se pueden construir modelos de sistemas LTI inciertos
que contengan tanto parmetros como dinmicas inciertas. Se pueden conseguir
herramientas para analizar los mrgenes de estabilidad de sistemas MIMO y el
rendimiento en el peor caso posible.
Este toolbox incluye una seleccin de herramientas de sntesis de control que
computa controladores que optimizan el rendimiento en el peor caso y que identifica
los valores de los parmetros para el peor caso. Permite simplificar y reducir el orden
los modelos complejos con herramientas de reduccin de modelos que minimizan los
lmites de error aditivo y multiplicativo. Proporciona herramientas para implementar
mtodos de control avanzados como H, H2, desigualdades de matrices lineales (LMI
o Linear Matrix Inequalities),...

Frequency Domain System Identification Toolbox: el toolbox de identificacin de

sistemas en el dominio de la frecuencia (FDIDENT) proporciona herramientas


especializadas para identificar sistemas SISO (single-input/single-output) de

13

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


dinmica lineal a partir de respuestas temporales o medidas de la respuesta
frecuencial del sistema. Los mtodos del dominio frecuencial sostienen el modelado
en tiempo continuo, que puede ser un fuerte complemento y altamente preciso para
los mtodos de tiempo discreto ms comnmente usados. Los mtodos del toolbox
se pueden aplicar a problemas tales como el modelado de sistemas electrnicos,
mecnicos y acsticos.
La caja de herramientas de identificacin de sistemas en el dominio frecuencial
est construida completamente en Matlab, y todas las funciones se encuentran
disponibles en la ventana de comandos o a travs de interfaces grficas de usuario.

Fuzzy Logic Toolbox: la caja de herramientas de lgica difusa es una coleccin de

funciones construidas en el entorno de clculo numrico Matlab. Proporciona


herramientas para crear y editar sistemas borrosos en el marco de Matlab, o si se
prefiere, integrar el sistemas borrosos en simulaciones con Simulink. Pueden incluso
construirse programas C autnomos que llamen a sistemas borrosos construidos con
Matlab. Este toolbox se basa en herramientas de interfaz grfica de usuario (GUI)
para ayudar a realizar las tareas, aunque tambin se puede trabajar desde la lnea
de comandos, esto ya es a eleccin del usuario.

Higher Order Spectral Analisys Toolbox: se trata de un conjunto de ficheros M que

implementan una variedad de algoritmos de procesamiento de seal avanzados para


la estimacin de espectros, olyespectros, bicoherencia, cross-cumulants y autocumulants (incluyendo correlaciones), y clculo de distribuciones temporalfrecuenciales. Basados en estos, tambin implementa algoritmos para identificacin
de sistemas ciegos paramtricos y no paramtricos, estimacin de tiempos de
retardo, recuperacin de armnicos, enganche de fase, estimacin de la direccin de
llegada, estimacin de parmetros de modelos no lineales de Volterra y prediccin
lineal adaptativa.

Image Processing Toolbox: este toolbox proporciona un extenso conjunto de

algoritmos estndares de referencia y herramientas grficas para procesamiento,


anlisis, y visualizacin de imgenes, y para desarrollo de algoritmos. Se pueden
restaurar imgenes degradadas o con ruido, mejorar imgenes para una mayor
comprensin, extraer caractersticas, analizar formas y texturas, ... La mayora de
funciones de esta caja de herramientas estn escritas en el lenguaje abierto de
Matlab.

Model Predective Control Toolbox: esta caja de herramientas permite disear,

14

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


analizar y simular modelos de controladores predictivos que estn basados en
modelos de plantas creados en Matlab o deducidos de un modelo linealizado de
Simulink. Los modelos de controladores predictivos ayudan a optimizar el
rendimiento de sistemas de control MIMO (varias entradas y varias salidas) que
estn sujetos a restricciones en las entradas y las salidas.

Mu Analisis and Synthesis Toolbox: coleccin de funciones (comandos)

desarrollados principalmente para el anlisis y sntesis de sistemas de control, con


nfasis en la cuantificar los efectos de la incertidumbre. Las -Tools porporcionan un
conjunto consistente de estructuras de datos para el tratamiento unificado de
sistemas ya sea en el dominio del tiempo, en el dominio de la frecuencia o en el
espacio de estados. Las -Tools tambin dan a los usuarios de Matlab acceso a
desarrollos recientes en teora de control, a saber, control ptimo H y tcnicas de
anlisis y sntesis m. Este paquete permite sofisticados resultados de perturbacin
de matricesy tcnicas de control ptimo para solventar problemas de diseo de
control. El software de diseo de control, tal como las -Tools, proporciona un
vnculo entre la teora de control y la ingeniera de control.

NAG Foundation Toolbox: la NAG Foundation Toolbox consta de ms de 240

ficheros .M que cubren muchos temas, entre los que se incluyen optimizacin,
ecuaciones diferenciales ordinarias y parciales, cuadratura y estadstica. Esta
'toolbox' tambin incorpora nueva funciones de gran inters para tareas especficas
como resolucin de problemas de valores de contorno, realizacin de cuadraturas
adaptativas unidimensional y multidimensional, ajuste de curvas y superficies y
acceder directamente a los algoritmos LAPACK para resolucin de ecuaciones
lineales.

Neural Network Toolbox: la caja de herramientas de redes neuronales extiende

Matlab con herramientas para disear, implementar, visualizar y simular redes


neuronales. Las redes neuronales son inestimables para las aplicaciones donde el
anlisis formal sera difcil o imposible, tales como el reconocimiento de patrones o el
control e identificacin de sistemas no lineales. Este toolbox proporciona un
exhaustivo soporte para muchos paradigmas comprobados de redes, as como
interfaces grficas que posibilitan el diseo y la gestin de las redes. El diseo
extensible, abierto y modular del toolbox simplifica la creacin de redes y funciones
personalizadas.

Nonlinear Control Design Toolbox: permite optimizar el comportamiento de los

15

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


sistemas modelados en Simulink personalizando los parmetros de diseo por medio
de optimizaciones numricas. Se puede optimizar el rendimiento en bucle cerrado de
sistemas de control, desde controladores PID hasta arquitecturas multi-bucle. Se
pueden expresar fcilmente los requisitos de diseo en trminos de tiempo de
subida, tiempo de establecimiento, lmites de saturacin, rizado,... Permite modificar
los coeficientes de los algoritmos de procesamiento de seal y de comunicacin, y
alcanzar caractersticas de comportamiento tales como consumo del pico de
potencia, rango de movimiento mecnico o prdida de paquetes de datos.
En conjuncin con Simulink, puede usarse para poner a punto sistemas de control
lineales multi-bucle. Se pueden especificar diversos requisitos en el dominio del
tiempo y la frecuencia (incluyendo ganancia y mrgenes de fase) en las grficas de
respuesta del bucle abierto (y cerrado), y optimizar los parmetros del sistema de
control para hacer cumplir estos requisitos.

Optimization Toolbox: el toolbox de optimizacin extiende el entorno de clculo

tcnico de Matlab con herramientas y algoritmos ampliamente utilizados para


optimizacin estndar y a gran escala. Estos algoritmos resuelven problemas
continuos y discretos con y sin restricciones. Esta caja de herramientas incluye
funciones para programacin lineal, programacin cuadrtica, optimizacin no lineal,
mnimos cuadrados no lineales, ecuaciones no lineales, optimizacin multi-objetivo y
programacin entera binaria.

Signal Processing Toolbox: este paquete es una coleccin de algoritmos

estndares de la industria para procesamiento de seales analgicas y digitales.


Proporciona una interfaz grfica de usuario para diseo y anlisis interactivo y
funciones en lnea de comandos para desarrollo de algoritmos avanzados.

SIMULINK: Simulink es una plataforma para simulacin multidominio y diseo

basado en modelo para sistemas dinmicos. Proporciona un entorno grfico


interactivo y un conjunto personalizable de bloques de libreras, y puede extenderse
para aplicaciones ms especficas.

SIMULINK Real Time Workshop: Real Time Workshop es una extensin de las

capacidades de Simulink y Matlab que automticamente genera paquetes y compila


cdigo fuente de modelos de Simulink para crear aplicaciones software en tiempo
real sobre una variedad de sistemas. Proporcionando un entorno de generacin de
cdigo para conseguir prototipos y desarrollos rpidos, Real Time Workshop es el
fundamento para las capacidades de generacin de produccin de cdigo. Junto con

16

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


otras herramientas y componentes, RTW (Real Time Workshop) proporciona:

Generacin de cdigo automtica adaptada para diversas plataformas destino.

Un camino rpido y directo del diseo del sistema a la implementacin.

Integracin con Matlab y Simulink.

Una intefaz de usuario grfica simple.

Una arquitectura abierta y un proceso de construccin extensible.

Spline Toolbox: se trata de una coleccin de funciones para ajuste, interpolacin,

extrapolacin y visualizacin de datos. Los splines son polinomios suaves a trozos


que pueden ser usados para representar funciones en grandes intervalos, donde no
sera prctico una polinomio de aproximacin simple.

Statistics Toolbox: proporciona a los ingenieros, cientficos, investigadores,

analistas financieros y estadsticos un extenso conjunto de herramientas para


evaluar y comprender sus datos. Incluye funciones y herramienta interactivas para
analizar datos histricos, datos de modelado, sistemas simulados, desarrollo de
algoritmos estadsticos, y estadstica para aprender y ensear.

Symbolic Math Toolbox: esta caja de herramientas combina las matemticas

simblicas y las capacidades aritmticas de precisin variable del motor simblico de


Maple con las capacidades numricas y de visualizacin de Matlab. Con este
toolbox, pueden usarse la sintaxis y el lenguaje de Matlab para realizar clculos
simblicos. Este toolbox ofrece ms de 100 funciones simblicas para realizar
operaciones de transformacin de integrales, de clculo y algebraicas.

System Identification Toolbox: el toolbox de identificacin de sistema permite

construir y evaluar modelos lineales de sistemas dinmicos a partir de datos de


mediciones entrada-salida. Se pueden usar tcnicas en el dominio del tiempo o la
frecuencia para ajustar modelos a datos mono o multi-canales. Esta caja de
herramientas es til para modelar sistemas dinmicos que no sean fcilmente
representados por los principios bsicos, incluyendo subsistemas de motor,
dinmicas de vuelo, procesos de termo-fluidos y sistemas electromecnicos.
Estos conjuntos de herramientas son muy tiles, y como se desprenden de las
caractersticas y descripciones anteriores, la mayora estn orientados al control de sistemas
y diseo de controladores, que es la razn principal del desarrollo de este proyecto.

17

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

1.2.2 M ICROSOFT VISUAL S TUDIO .NET.


Visual Studio .NET es un IDE (Integrated Development Environment) o entorno integrado
de desarrollo desarrollado por Microsoft. Es para el sistema operativo Microsoft Windows y
est pensado, principal pero no exclusivamente, para desarrollar para plataformas Win32.
Un entorno de desarrollo integrado es un programa compuesto por un conjunto de
herramientas para un programador. Puede dedicarse en exclusiva a un slo lenguaje de
programacin o bien, puede utilizarse para varios.
Un IDE es un entorno de programacin que ha sido empaquetado como un programa de
aplicacin, es decir, consiste en un editor de cdigo, un compilador, un depurador y un
constructor de interfaz grfica GUI. Los IDEs pueden ser aplicaciones por si solas o pueden
ser parte de aplicaciones existentes. El leguaje Basic por ejemplo puede ser usado dentro
de las aplicaciones de Microsoft Office, lo que hace posible escribir sentencias Basic en
forma de macros para Word.
Los IDEs proveen un marco de trabajo amigable para la mayora de los lenguajes de
programacin tales como C++, Java, C#, Basic, Object Pascal, Velneo, etc.
En este caso, Visual Studio .NET proporciona soporte para los lenguajes de
programacin Basic, C++, C# y J#. Adems, puede utilizarse para construir aplicaciones
dirigidas a Windows (utilizando Windows Forms), Web (usando ASP.NET y Servicios Web) y
dispositivos porttiles (utilizando .NET Compact Framework).
Visual Studio .NET 2003 incluye una completa gama de funciones, desde modeladores
que ayudan a componer visualmente las aplicaciones empresariales ms complejas hasta la
implementacin de una aplicacin en el ms pequeo de los dispositivos. Visual Studio .NET
y la plataforma .NET Framework de Microsoft Windows proporcionan una completa
herramienta para disear, desarrollar, depurar e implementar aplicaciones seguras para
Windows y Web.
Los cuatro lenguajes de programacin soportados por esta herramienta de programacin
se describen someramente a continuacin:

C#: es un lenguaje de programacin orientado a objetos desarrollado y

estandarizado por Microsoft como parte de su plataforma .NET, que despus fue
aprobado como un estndar por la ECMA e ISO.
Su sintaxis bsica deriva de C/C++ y utiliza el modelo de objetos de la plataforma
.NET, el cual es similar al de Java aunque incluye mejoras derivadas de otros
lenguajes (ms notablemente de Delphi y Java). C# fue diseado para combinar el

18

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


control a bajo nivel de lenguajes como C y la velocidad de programacin de
lenguajes como Visual Basic.
Aunque C# forma parte de la plataforma .NET, sta es una interfaz de
programacin de aplicaciones; mientras que C# es un lenguaje de programacin
independiente diseado para generar programas sobre dicha plataforma. Aunque
an no existen, es posible implementar compiladores que no generen programas
para dicha plataforma, sino para una plataforma diferente como Win32 o UNIX.

Visual Basic.NET (VB.NET): es una versin de Visual Basic enfocada al desarrollo

de aplicaciones .NET. El lenguaje de programacin es Visual Basic, que apareci en


el ao 1991 como una evolucin del QuickBasic que fabricaba Microsoft.
Es un lenguaje de programacin orientado a objetos(POO), y como novedades
ms importantes en la versin .NET, podemos citar la posibilidad de definir mbitos
de tipo, clases que pueden derivarse de otras mediante herencia, sobrecarga de
mtodos, nuevo control estructurado de excepciones o la creacin de aplicaciones
con mltiples hilos de ejecucin, adems de contar con la extensa librera de .NET,
con la que es posible desarrollar tanto Windows Applications y Web Forms, as como
un extenso nmero de clientes para bases de datos. Gracias a estas mejoras en lo
que vendra siendo Visual Basic 7.0 los programadores de este lenguaje pueden
desarrollar aplicaciones ms robustas que en el pasado con una base slida
orientada a objetos.

Visual C++: es el nombre de una herramienta y un lenguaje de programacin. La

herramienta forma parte de la suite de programacin de Microsoft Visual Studio, que


en su ltima versin est disponible para su descarga gratuita en la pgina de
Microsoft para uso no profesional.
El lenguaje de programacin utilizado por esta herramienta, de igual nombre est
basado en C++, y es compatible en la mayor parte de su cdigo con este lenguaje, a
la vez que su sintaxis es exactamente igual. En algunas ocasiones esta
incompatibilidad impide que otros compiladores, sobre todo en otros sistemas
operativos, funcionen bien con cdigo desarrollado en este lenguaje.

Visual J# .NET: es una herramienta para programadores en lenguaje Java que

deseen crear aplicaciones y servicios en Microsoft Windows .NET Framework.


El lenguaje de programacin J# es un lenguaje transicional para programadores
del lenguaje de programacin Java y del lenguaje J++ de Microsoft, creado con la

19

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


intencin de que ambos puedan usar sus conocimientos actuales para crear
aplicaciones en la plataforma .NET de Microsoft. J# se supone compatible con Java,
tanto a nivel cdigo fuente, como binario. En teora, J# puede ser usado para
transicionar aplicaciones que usan bibliotecas de terceros, an cuando el cdigo de
stas no este disponible.
La utilidad de esta suite de programacin reside en sus capacidades de programacin
web y la facilidad de integrar ASP con cdigo Visual C#. sta ha sido la combinacin
escogida para el desarrollo de la interfaz web del sistema de control remoto.
El cdigo ASP permite utilizar las etiquetas comunes HTML y adems permite
implementar consultas a bases de datos del tipo SQL y realizar consultas al servidor.
Aunque esta opcin no se ha explotado en el proyecto, siempre permite una futura mejora y
ampliacin de posibilidades (escalabilidad).
El cdigo C# permite dotar al sistema de una mayor funcionalidad que no permite el
lenguaje ASP. Por un lado, proporciona una mayor facilidad, debido principalmente al
soporte de ayuda disponible con Microsoft Visual Studio .NET, ya que ste incluye las
denominadas libreras MSDN, que suponen el pilar de la programacin para este paquete.
Las libreras MSDN constituyen la referencia de la programacin en este entorno, y puesto
que se trata de un lenguaje de muy alto nivel, ya se encuentran creadas una gran cantidad
de funciones que en conjuncin con el lenguaje de programacin web ASP permite dotar a
la aplicacin de control remoto de una mayor funcionalidad.
Por otra parte, este entorno incluye la mayora de los lenguajes de programacin
ampliamente utilizados en ingeniera. No es de extraar, por tanto, pensar en la combinacin
de Microsoft Visual Studio con Matlab, ya que Matlab posee unas herramientas
denominadas funciones-S que permiten al usuario la programacin de sus propias
funciones y bloques funcionales en Simulink mediante programacin tradicional en lenguaje
C. Por tanto, esto permite el desarrollo de libreras con Microsoft Visual Studio .NET para su
posterior uso con Matlab, con todas las ventajas que esto conlleva. No obstante, hay que ser
cautos en el uso de funciones avanzadas de Visual C# de cara a la construccin de libreras
para Matlab, ya que entonces hay que personalizar el proceso de compilado y construccin
de ejecutables y libreras, para que no se produzcan errores en el proceso de linkado y
generacin de ficheros objeto.

20

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

2 A NLISIS

DE

FACTIBILIDAD .

En la parte referente a la actualizacin automtica de un sistema de bases de datos, la


factibilidad sera reducida o muy limitada en el caso de un sistema genrico capaz de
actualizar cualquier sistema de bases de datos ante mltiples entradas y de distinta ndole.
No es este el caso presente. Se pretende disear un sistema de actualizacin de bases de
datos orientado a una base de datos concreta, la del grupo de control predictivo de la
Universidad de Sevilla. En lo concerniente al apartado de las entradas del sistema, cabe
mencionar que se limitan a ficheros de texto plano con patrones constantes de definicin de
campos (esto es, cada campo se encuentra separado del anterior de forma unvoca y
constante para todas las nuevas entradas de la base de datos) y de entradas de la base de
datos (cada entrada se encuentra separada de la anterior de forma unvoca y constante, de
forma similar al caso anterior), as como direcciones de internet que complementen la
informacin de dichos ficheros y directorios para la bsqueda de documentos del tipo pdf
(Portable Document Format) que contengan informacin relevante acerca de las entradas de
la base de datos.
Esta base de datos tiene unas caractersticas concretas, que junto con las
especificaciones concisas de las posibles entradas existentes, posibilita la realizacin de
esta parte del proyecto.

En la parte referente al control remoto de una planta a travs de internet mediante el uso
de Matlab y una interfaz web, la factilidad es limitada, ya que Matlab no permite el
establecimiento de sockets de forma sencilla. Si se intenta abrir un socket con Java, el hilo
principal del programa queda bloqueado, impidiendo el correcto control de la planta. Si se
intenta utilizar Matlab Server, entonces se permiten conexiones sobre la planta a travs de
internet, pero cada conexin se realiza en un hilo distinto del programa, lo que implicara que
el control no se estara llevando a cabo realmente. No obstante, haciendo uso de las
funciones S, que permiten el uso de funciones programadas en C puede encontrarse una
solucin viable, haciendo posible la factibilidad de la otra parte del presente proyecto.

21

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

3 O BJETIVOS

DEL

3.1 A CTUALIZACIN A UTOMTICA

DE

P ROYECTO .

B ASES

DE

D ATOS .

El objetivo a conseguir con las bases de datos es claro: simplificar el proceso de


actualizacin de una base de datos a partir de informacin disponible en otras fuentes (entre
ellas, otra base de datos).
Se ha realizado un sistema con cierta "inteligencia" para la actualizacin de bases de
datos a partir de distintos elementos de entrada:

Ficheros de texto con la informacin de otras bases de datos: normalmente la

correspondencia entre los datos contenidos en estos ficheros y la estructura de la


base de datos destino no es exactamente la misma, por lo que el sistema debe
generar los campos alternativos que sean necesarios y que se puedan obtener a
partir de los facilitados.

Direcciones web: ofrecen ms informacin para la actualizacin, complementando

los campos de los ficheros de texto.

Directorios de ficheros: tiles si la base de datos contiene un registro de ficheros,

como pueden ser los artculos publicados en una determinada revista.


A partir de estos elementos se proceder a la actualizacin de la base de datos,
tenindose en cuenta todos ellos para una mejor complecin de la misma.
Otro objetivo colateral de este proyecto es realizar un sistema de actualizacin flexible,
que permita adaptar el sistema a cualquier otro sistema de bases de datos de forma fcil y
directa. Con esto se ofrece la posibilidad de reusar cdigo y ahorrar tiempo de
programacin.

3.2 R EQUISITOS P REVIOS

PARA LA

A CTUALIZACIN A UTOMTICA .

El sistema de pruebas para el script de actualizacin es la pgina web del grupo de


control predictivo de la Universidad de Sevilla. Para la gestin de la base de datos y las
posteriores comprobaciones del script, es necesario instalar una determinada batera de
programas, cada uno de ellos con una funcionalidad distinta:

22

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

MySQL Server: gestor de bases de datos open source.

MySQL Administrator: herramienta de mantenimiento y gestin de bases de datos

SQL.

Apache Web Server: servidor web para poder visualizar la pgina web bajo

pruebas.

PHP: lenguaje de programacin que permite la ejecucin de cdigo en un servidor

web.

3.2.1 M YSQL S ERVER .


MySQL es un gestor de bases de datos open source (o de otra forma, software libre). Es
la herramienta utilizada en el servidor Nyquist para gestionar las bases de datos, y por ello
aqu se explicar someramente una instalacin bsica, que ser suficiente para los objetivos
del proyecto.
La versin aqu utilizada es la estndar 4.1.16, para procesadores x86. El nombre del
fichero necesario para esta instalacin es:
mysql-standard-4.1.16-pc-linux-gnu-i686-glibc23.tar.gz

El

usuario

puede

instalar

cualquier

otra

versin.

La

instalacin

no

variar

significativamente, salvo en los nmeros de la versin utilizada y en el tipo de sta (max o


standard, generalmente).
Los pasos a seguir para instalacin de MySQL Standard Edition a travs de un terminal
son los siguientes:
1. Crear un usuario y un grupo para ejecutar MySQL:
# groupadd mysql
# useradd -g mysql mysql

2. Descomprimir el archivo que contiene MySQL en el directorio "/usr/local/":


# cd /usr/local
# tar -xzf /directorio/mysql-standard-4.1.16-pc-linux-gnu-i686-glibc23.tar.gz

NOTA: "/directorio/" hace referencia a la ubicacin en la que se encuentre el


fichero

.tar.gz

de MySQL. El usuario deber cambiarlo por el directorio

apropiado.
3. Realizar un enlace simblico al directorio creado por la descompresin del punto
2:

23

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


# ln -s mysql-standard-4.1.16-pc-linux-gnu-i686-glibc23/ mysql

NOTA: con esto se podr acceder al directorio donde se ha descomprimido el


fichero simplemente mediante la ruta "/usr/local/mysql/".
4. Ejecutar el script de instalacin:
# cd mysql
# scripts/mysql_install_db

NOTA: durante el proceso de instalacin se mostrarn en el terminal diversos


mensajes informativos. Uno de ellos es de especial importancia: el referente
al cambio de la contrasea del usuario "root", que es el administrador de la
base de datos. En dicho mensaje se recomienda el cambio de la contrasea,
que inicialmente se establece a una contrasea vaca (es decir, ninguna), a
una contrasea particular del usuario. Ms adelante se har una resea a
este inciso.
5. Cambiar el usuario y grupo de los ficheros:
# chown -R root .
# chown -R mysql data
# chgrp -R mysql .

NOTA: Estos comandos pueden variar dependiendo de la versin de Linux


utilizada. En el desarrollo de esta beca se utiliz Debian Sarge 3.1, y estos
comandos se ejecutaron satisfactoriamente. Hay que asegurarse de que se
establece la asociacin de los grupos bien, puesto que en caso contrario, al
ejecutar MySQL como se indica en el punto 6 se obtendr un error de
escritura en el directorio "data".
6. Ejecutar MySQL:
# bin/mysqld_safe --user=mysql &

NOTA: dependiendo de la versin a instalar de MySQL, habr que utilizar


"mysql_safe" o "mysqld_safe". En la facilitada, hay que usar "mysqld_safe". Adems,
la utilizacin del ampersand (&) al final tiene su base en que de esta forma no
se bloquea el terminal y se permite seguir ejecutando comandos.
NOTA 2: otra forma de arrancar el servidor y pararlo, respectivamente, se
consigue con los siguientes comandos:
# /usr/local/mysql/support-files/mysql.server start
# /usr/local/mysql/support-files/mysql.server stop

7. Ahora que ya se est ejecutando MySQL es un buen momento para cambiar la


contrasea del usuario "root". Se facilitan aqu los comandos especficos para este

24

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


fin:
# ./bin/mysqladmin -u root password 'nuevo-password'
# ./bin/mysqladmin -u root -h debian password 'nuevo-password'

Ahora lo que se va a hacer es automatizar el arranque del servidor con el arranque del
sistema. Para ello, se copiar el script de manejo del servidor en la ubicacin donde se
encuentren los ficheros de arranque del sistema. Esto se consigue con la siguiente orden:
# cp /usr/local/mysql/support-files/mysql.server /etc/init.d

Este script se puede utilizar tanto para arrancar el servidor en el inicio del sistema como
para pararlo al apagar el ordenador. Para ello, se ultimarn estas dos operaciones creando
unos enlaces simblicos, necesarios para el script:
# cd /etc/rc2.d
# ln -s /etc/init.d/mysql.server S20mysql
# cd /etc/rc0.d
# ln -s /etc/init.d/mysql.server K20mysql

Es conveniente ejecutar el script de inicio y apagado del servidor como el usuario "mysql"
y no como el usuario "root" por razones de seguridad. A tal efecto, se modificar el fichero
"mysql.server" que se ha copiado en "/etc/init.d/". Se ha de buscar la siguiente lnea:
$bindir/mysqld_safe --datadir=$datadir --pid-file=$pid_file &

y se sustituir por esta otra:


$bindir/mysqld_safe --datadir=$datadir --pid-file=$pid_file --user=mysql &

NOTA: en el fichero de la distribucin facilitada, esta lnea era la lnea 199.

Si la instalacin bsica descrita aqu no proporciona los resultados deseados, se


recomienda consultar el fichero "INSTALL-BINARY" que se encuentra en el directorio creado en
el paso 2 (carpeta de descompresin).
La instalacin para el sistema Windows es ms sencilla, en tanto que simplemente
dispone de un ejecutable. Para instalarlo, descomprimir el fichero mysql-4.1.18-win32.zip
y hacer doble click sobre el instalador setup.exe. No se entrar en detalles de la instalacin
porque es similar a la instalacin para Linux. En todo caso, puede que se altere el orden de
alguno de los pasos, que la mayora de ellos se realicen de forma grfica en forma de
ventanas y que otros no tengan sentido (como el hecho de realizar enlaces simblicos o
programar el autoarranque con el sistema, puesto que se ofrece al usuario la posibilidad de
arrancar el servidor MySQL como un servicio del sistema.

25

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

3.2.2 M YSQL C ONTROL C ENTER .


MySQL Control Center es una herramienta de bastante ayuda en el mantenimiento y
gestin de la base de datos SQL. Permite, entre otras cosas, crear nuevos usuarios,
modificar las tablas existentes y aadir/crear nuevas bases de datos.
La versin aqu utilizada es la 0.9.4, para procesadores x86. El nombre del fichero
necesario para esta instalacin es:
mysqlcc-0.9.4-linux-glibc23.tar.gz

El

usuario

puede

instalar

cualquier

otra

versin.

La

instalacin

no

variar

significativamente.
Los pasos a seguir para instalacin de MySQL Control Center a travs de un terminal
son los siguientes:
1. Descomprimir el archivo que contiene MySQL Control Center en el directorio
"/usr/local/":
# cd /usr/local
# tar -xzf /directorio/mysqlcc-0.9.4-linux-glibc23.tar.gz

NOTA: "/directorio/" hace referencia a la ubicacin en la que se encuentre el


fichero

.tar.gz

de MySQL Control Center. El usuario deber cambiarlo por el

directorio apropiado.
2. Realizar un enlace simblico al directorio creado por la descompresin del punto
2:
# ln -s mysqlcc-0.9.4-linux-glibc23/ mysqlcc

NOTA: con esto se podr acceder al directorio donde se ha descomprimido el


fichero simplemente mediante la ruta "/usr/local/mysqlcc/".
3. Ejecutar MySQL Control Center:
# cd mysqlcc
# ./mysqlcc

4. Aparecer una ventana con el ttulo "MySQLCC Register Server". En primera instancia,
nos bastar rellenar los campos existentes con los siguientes datos:

Name localhost
NOTA: Aqu se debe poner el nombre que se quiere dar a la conexin.

Host name localhost


NOTA: Aqu se debe poner el nombre de la mquina donde est el
servidor MySQL. Localhost indica al programa que se usar la misma

26

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


computadora donde se est instalando el programa como servidor de
bases de datos, de forma que se conecte a sta de forma local.

User name root


NOTA: Aqu se debe especificar el nombre del usuario de MySQL para
conectar con el servidor.

Password Aqu se debe especificar la contrasea del usuario del campo


anterior. Si se especific como nombre de usuario "root", entonces caben dos
opciones: 1) dejar en blanco si no se ejecut el paso 7 en la instalacin de
MySQL 2) rellenar este campo con la contrasea establecida.

5. Pulsar el botn "Add" (o "Aadir"). Acto seguido, aparecer una ventana, que es la
ventana principal de MySQL Control Center. En la parte izquierda aparece un men
titulado "MySQL Servers". En su interior, aparece "localhost", que es la conexin actual. Si
se despliega, aparecern tres submens, a saber: "Databases", "Server

Administration"

"User Administration". El primero, "Databases", al desplegarse muestra las bases de datos


existentes; el segundo, "Server
Administration",

Administration"

no nos interesa; y el tercero, "User

sirve para administrar los usuarios que tendrn acceso al servidor

MySQL. Tanto los mens "Databases" como "User

Administration"

sern tiles ms

adelante, en la configuracin de la pgina web.

Si la instalacin bsica descrita aqu no proporciona los resultados deseados, se


recomienda consultar el fichero "INSTALL.txt" que se encuentra en el directorio creado en el
paso 1 (carpeta de descompresin).
Para la instalacin en el sistema Windows se propone otro programa, denominado
MySQL Administrator. Se trata de una evolucin de MySQL Control Center, y posee ms
posibilidades de modificacin y mayor cantidad de opciones que el anterior. Su instalacin
tambin es ms sencilla, en tanto que simplemente dispone de un ejecutable. Para
instalarlo, hacer doble click sobre el instalador mysql-administrator-1.1.9-win.msi.

3.2.3 A PACHE WEB S ERVER .


Apache es un servidor gratuito y software libre adems. ste ser el que permitir las
conexiones remotas desde otras mquinas y a su vez permitir al programador ver las

27

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


pginas en proceso de modificacin a travs del navegador.
La versin aqu utilizada es la 2.0.55, para procesadores x86. El nombre del fichero
necesario para esta instalacin es:
httpd-2.0.55.tar.gz

El

usuario

puede

instalar

cualquier

otra

versin.

La

instalacin

no

variar

significativamente. En este caso se tendrn que compilar las fuentes del servidor Apache.
Los pasos a seguir para instalacin de Apache Server a travs de un terminal son los
siguientes:
1. Descomprimir el archivo que contiene Apache Server en el directorio
"/usr/local/src/":
# cd /usr/local/src
# tar -zxf /directorio/httpd-2.0.55.tar.gz

NOTA: "/directorio/" hace referencia a la ubicacin en la que se encuentre el


fichero

.tar.gz

de Apache Server. El usuario deber cambiarlo por el directorio

apropiado.
2. Configurar los fuentes para que la compilacin se adapte al sistema y las
necesidades:
# cd httpd-2.0.55
# ./configure --prefix=/usr/local/apache2 --enable-so --with-mpm=prefork

NOTA: con esto se compila Apache Server con las opciones por defecto. La
opcin "prefix" indica dnde se va a instalar el servidor Apache. La opcin
"enable-so" sirve para realizar la carga dinmica de mdulos. Es importante
poner esta opcin para despus cargar dinmicamente php. "with-mpm" es una
opcin necesaria para un correcto funcionamiento con php.
3. Compilar los fuentes:
# make

4. Instalar Apache Server:


# make install

5. Arrancar Apache Server:


# cd /usr/local/apache2/bin
# .apachectl start

6. Esto no es un paso de la instalacin en s, sino una comprobacin de que


funciona correctamente Apache Server en el sistema. Abrir desde el navegador web
la url:

28

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


http:/localhost/

Si la instalacin ha tenido xito, debera mostrarse una pgina con el siguiente texto al
comienzo:
"If you can see this, it means that the installation of the Apache web server software on this system was successful.
You may now add content to this directory and replace this page."

Para proseguir con la siguiente instalacin, que corresponde a php, es conveniente parar
el servidor con la siguiente orden:
# ./apachectl stop

donde se ha supuesto que seguimos en el directorio "/usr/local/apache2/bin/".


A continuacin se realizar una automatizacin similar a la que se llev a cabo con el
servidor MySQL para automatizar el arranque y parada del servidor Apache Server al
encender y apagar el ordenador. Para ello, se debe copiar el script " apachectl" al sitio donde
se encuentran los ficheros de arranque del sistema:
# cp /usr/local/apache2/bin/apachectl /etc/init.d

Este script se puede utilizar tanto para arrancar el servidor en el inicio del sistema como
para pararlo al apagar el ordenador. Para ello, se ultimarn estas dos operaciones, creando
unos enlaces simblicos necesarios para el script:
# cd /etc/rc2.d
# ln -s /etc/init.d/apachectl S20apachectl
# cd /etc/rc0.d
# ln -s /etc/init.d/apachectl K20apachectl

Si la instalacin bsica descrita aqu no proporciona los resultados deseados, se


recomienda consultar el fichero "INSTALL" que se encuentra en el directorio creado en el paso
1 (carpeta de descompresin).
La versin para Windows se encuentra en el fichero apache_2.0.55-win32-x86no_ssl.msi.

Para instalar Apache para Windows simplemente se ha de hacer doble click

sobre el instalador anterior y proceder con todos los pasos que vaya solicitando el mismo.
Se ofrecer, al igual que pasaba con MySQL Server iniciar este servidor como un servicio
del sistema. sta es la opcin recomendada.

3.2.4 PHP.
PHP es un lenguaje de programacin de pginas web que permite dotarlas de
dinamismo. Este lenguaje permite la comunicacin entre los navegadores y los servidores
que alojan las pginas web, permitiendo que aqullos soliciten determinados datos,
devolvindoselos ste.

29

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


La versin aqu utilizada es la 4.4.2, para procesadores x86. El nombre del fichero
necesario para esta instalacin es:
php-4.4.2.tar.gz

El

usuario

puede

instalar

cualquier

otra

versin.

La

instalacin

no

variar

significativamente.
Los pasos a seguir para instalacin de php a travs de un terminal son los siguientes:
1. Descomprimir el archivo que contiene php en el directorio "/usr/local/src/":
# cd /usr/local/src
# tar -zxf /directorio/php-4.4.2.tar.gz

NOTA: "/directorio/" hace referencia a la ubicacin en la que se encuentre el


fichero

.tar.gz

de Apache Server. El usuario deber cambiarlo por el directorio

apropiado.
2. Configurar las fuentes para su posterior instalacin:
# cd php-4.4.2
#./configure

--prefix=/usr/local/php4

--with-mysql=/usr/local/mysql

--with-

apxs2=/usr/local/apache2/bin/apxs --with-gettext[=DIR]

NOTA: con estas opciones se compilar php con las opciones por defecto.
"with-mysql" incluye el soporte para MySQL, por lo que se le indica el directorio
donde est instalado dicho servidor; "with-apxs2" compila el mdulo para
Apache Server 2, por lo que se le indica el directorio donde est instalado
dicha utilidad. Por ltimo, se indica tambin "with-gettext" porque la pgina del
grupo de control predictivo hace uso de este mdulo, por lo que, o bien se
incluye ahora, o bien se recompilara php ms adelante de nuevo.
3. Compilar php:
# make

4. Instalar php:
# make install

5. Copiar el fichero de configuracin de php donde php espera encontrarlo. Este


directorio es el que se indic en el paso 2 con la opcin prefix aandindole el
subdirectorio "/lib/", es decir:
# cp php.ini-dist /usr/local/php4/lib/php.ini

6. Hacer que Apache Server reconozca los ficheros con extensin .php. Para ello,
aadir en el fichero "/usr/local/apache2/conf/httpd.conf" la siguiente lnea:

30

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


AddType application/x-httpd-php .php

NOTA: en la versin facilitada, la lnea se deba aadir en la lnea 838.


7. Comprobar que la instalacin y configuracin de php ha sido correcta. Para ello,
abrir un editor de textos (i.e., "gedit") y crear un fichero llamado "prueba.php":
# cd /usr/local/apache2/htdocs/
# gedit prueba.php

NOTA: el directorio "/usr/local/apache2/htdocs/" es el directorio en el que busca


Apache Server las pginas del host cuando se indican mediante "localhost".
Por tanto, para referirnos despus a ella, habr que copiar en este directorio
el fichero de prueba, con la finalidad de poder verlo despus.
8. Aadir las siguientes lneas al fichero:
<?php
phpinfo();
?>

9. Abrir un navegador web e indicar la siguiente url:


http://localhost/prueba.php

10. Se debera ver una pgina mostrando distintas caractersticas e informacin


acerca del sistema.
NOTA: si no se ve esta pgina, probar a reiniciar el ordenador y volver a cargar la
pgina. Debido a que Apache Server se encuentra iniciado, puede que no tenga
en cuenta las modificaciones al fichero "httpd.conf" de forma inmediata.
11. Por ltimo, tambin sera conveniente realizar una pequea comprobacin de que
todo lo anteriormente instalado funciona conjuntamente, es decir, crear una pgina
que mediante funciones php se conecte al servidor MySQL para obtener una
determinada informacin a travs del servidor Apache. Para ello, editar el fichero
"prueba.php" creado anteriormente e insertar el siguiente contenido:

31

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


<?php
// Ejemplo de acceso a base de datos MySQL.
// Conseguimos la conexin.
$link = @mysql_connect('localhost', 'root', 'root_password');
if (!$link) {
exit('<b>Error</b>: No se puede conectar con la base de datos. '.mysql_error());
}
$ddbb = 'mysql';
if (!@mysql_select_db($ddbb)) {
exit("<b>Error</b>: No se encuentra la base de datos '$ddbb'.");
}
// Ejecutamos una consulta.
$sql = 'SELECT * FROM help_keyword';
$res = @mysql_query($sql);
if (!$res) {
exit("<b>Error</b>: La consulta '$sql' ha fallado. ".mysql_error());
}
// Mostramos el metadata de la tabla.
echo '<table border="1">';
echo '<tr> <th>Nombre</th> <th>Tipo</th> <th>Permite NULL</th> </tr>';
$numFields = mysql_num_fields($res);
for ($i = 0; $i < $numFields; $i ++) {
$meta = mysql_fetch_field($res, $i);
echo '<tr>';
echo "<td>$meta->name</td>";
echo "<td>$meta->type</td>";
echo "<td>$meta->not_null</td>";
echo '</tr>';
}
echo '</table>';
echo '<br>';
// Mostramos el contenido de la tabla.
echo '<table border="1">';
echo '<tr>';
for ($i = 0; $i < $numFields; $i ++) {
$meta = mysql_fetch_field($res, $i);
echo "<th>$meta->name</th>";
}
echo '</tr>';
while ($row = mysql_fetch_row($res)) {
echo '<tr>';
foreach ($row as $col) {
echo "<td>$col</td>";
}
echo '</tr>';
}
echo '</table>';
// Liberamos los recursos y cerramos la conexin.
mysql_free_result($res);
mysql_close($link);
?>

NOTA: en la lnea que contiene la funcin "@mysql_connect('localhost',


'root_password')"

'root',

se debe sustituir "root_password" por la contrasea del

32

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


administrador ("root") del servidor MySQL.
12. Si todo ha ido bien, se deberan mostrar algunas tablas.

Si la instalacin bsica descrita aqu no proporciona los resultados deseados, se


recomienda consultar el fichero "INSTALL" que se encuentra en el directorio creado en el paso
1 (carpeta de descompresin).
Con esto ya se encuentra configurado el servidor web al completo. Faltan por pulir
algunos pequeos detalles, pero esto ya depende de las pretensiones del proyecto, de
modo que las modificaciones a realizar se comentarn cuando se estime conveniente.
Para instalar PHP en cualquier versin de Windows se puede hacer mediante el fichero
comprimido php-5.1.2-Win32.zip. Esta versin es ms moderna que la indicada para
Linux, pero para el sitio empleado para el presente proyecto basta con la versin de Linux.
No obstante, se ha elegido una versin ms moderna para Windows. Para instalar PHP en
Windows se ha de descomprimir el fichero anterior y seguir las notas de instalacin
indicadas en el fichero install.txt que aparece en la carpeta resultante de la
descompresin. Puesto que la versin de Apache instalada es la 2.0.55 el apartado a seguir
es el 2. Installation on Windows systems, subapartado Apache 2.0.x on Microsoft
Windows.

3.2.5 G ROUPWEB .
La primera de las tareas a realizar es el mantenimiento, actualizacin y modificacin del
sitio web del grupo de control predictivo del departamento de sistemas y automtica de la
Escuela Superior de Ingenieros de Sevilla. Esta pgina es accesible desde la url:
http://nyquist.us.es/groupweb/index.php
Lo primero que se hizo fue una copia de la pgina web, ya que por razones de seguridad
no era conveniente la modificacin "in situ" de la pgina en el propio servidor. Esto se realiz
mediante una transferencia ftp. Posteriormente, hubo que configurar la pgina web para su
correcta visualizacin en el servidor configurado en el apartado 2 de la presente memoria.
El sitio web se encuentra comprimido en el siguiente fichero:
groupweb.rar

33

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

3.2.5.1 C OPIA L OCAL

DEL

S ITIO WEB .

En primer lugar, para ser coherentes con las rutas utilizadas por el creador original del
sitio web, se crearon los siguientes directorios:
# mkdir var
# cd var
# mkdir www
# rar x groupweb.rar

Este sitio web hace uso de unas libreras de libre distribucin denominadas "phphtmllib".
Por ello, hay que realizar un enlace simblico al directorio "phphtmllib-2.4.1" que se encuentra
dentro del directorio creado en la descompresin anterior. Para ello, tecleamos lo siguiente:
# cd groupweb
# ln -s phphtmllib-2.4.1/ phphtmlib

Este paso es un requisito de una instalacin previa de dichas libreras, una especie de
variable de entorno sin la cual no funcionara correctamente la pgina web.
Otro paso a realizar es cambiar el directorio en el que Apache Server busca las pginas
web almacenadas. Por defecto, esta ruta es "/usr/local/apache2/htdocs/", y se debe cambiar a
"/var/www/". Para ello, se debe teclear lo siguiente:
# cd /usr/local/apache2/conf
# gedit httpd.conf

Buscamos

en

este

"/usr/local/apache2/htdocs""

fichero

la

lnea

que

contiene

el

texto

"DocumentRoot

y la cambiamos por "DocumentRoot "/var/www""

Ntese que al cambiar el fichero de configuracin de Apache Server, ser necesario


reiniciar el sistema (o reiniciar el servidor Apache) para que los cambios surtan efecto.

3.2.5.2 R ESTAURACIN

3.2.5.2.1 INTRODUCCIN

DE LA

AL

B ASE

DE

D ATOS .

C OMANDO " MYSQLDUMP ".

Para realizar una copia de seguridad de la base de datos existen varios comandos
especficos. Estos comandos son:

34

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

mysqlimport
mysqlhotcopy
mysqldump
backup table/restore table
flush table
lock table

El comando elegido para la copia de seguridad de la base de datos fue "mysqldump", tanto
por su simplicidad como por su eficacia.
El comando "mysqldump" del sistema gestor de la base de datos MySQL sirve para
hacer copias de seguridad. Este comando permite hacer la copia de seguridad de una o
mltiples bases de datos. Adems, permite que estas copias de seguridad se puedan
restaurar en distintos tipos de gestores de bases de datos, sin la necesidad de que se trate
de un gestor de MySQL. Esto lo consigue creando unos ficheros que contienen todas las
sentencias SQL necesarias para poder restaurar la tabla, que incluyen desde la sentencia
de creacin de la tabla hasta una sentencia "insert" por cada uno de los registros que
forman parte de la misma.
El comando dispone de una amplia variedad de opciones que nos permitir realizar la
copia de la forma ms conveniente para el propsito de la misma. Para poder restaurar la
copia de seguridad, bastar con ejecutar todas las sentencias SQL que se encuentran
dentro del fichero, bien desde la lnea de comandos de MySQL o desde la pantalla de
creacin de sentencias SQL de cualquier entorno grfico como puede ser MySQL Control
Center.
Las limitaciones de la restauracin dependern de las opciones que se hayan
especificado a la hora de hacer la copia de seguridad. Por ejemplo, si se incluye la opcin
"--add-drop-table" al hacer la copia de seguridad, se podrn restaurar tablas que existen
actualmente en el servidor (borrndolas primero). Por lo que es necesario estudiar primero
los procedimientos que se utilizarn tanto en la copia como en la restauracin, para que todo
se haga de la forma correcta.
La sintaxis de este comando es la siguiente:
mysqldump -u [usuario] -p [password] [nombre_base_datos] > [backup.sql]

Hay que tener cuidado al realizar una copia de la base de datos, puesto que alguien
puede estar accediendo a la informacin y estar cambindola. Para ello, se puede "evitar"
un acceso inoportuno que pueda dejar el fichero volcado en un estado inconsistente a travs
de varias opciones, una de las cuales podra ser "--single-transaction", como se indica en el
siguiente ejemplo:

35

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


#mysqldump --single-transaction -u usuario -p password base_de_datos > base_de_datos_backup.sql

La base de datos as volcada se podra recuperar por medio de sentencias SQL en la


lnea de comandos de forma similar:
#mysql -u admin -p pass drupal < drupal_backup.sql

Algunas de las opciones del comando "mysqldump" se muestran a continuacin:

--add-locks:

Aade LOCK TABLES antes y UNLOCK TABLE despus de la copia de cada

tabla.

-A, --all-databases:
databases

Copia todas las bases de datos. Es lo mismo que utilizar --

seleccionando todas.

-a,--all:

Incluye todas las opciones de creacin especficas de MySQL.

--allow-keywords:

Permite la creacin de nombres de columnas que son palabras

clave. Esto se realiza poniendo de prefijo a cada nombre de columna el nombre de la


tabla.

-c, --complete-insert:

Utiliza "inserts" incluyendo los nombres de columna en cada

sentencia (incrementa bastante el tamao del fichero).

-B, --databases:

Para copiar varias bases de datos. En este caso, no se especifican

tablas. El nombre de los argumentos se refiere a los nombres de las bases de datos.
Se incluir "USE db_name" en la salida antes de cada base de datos.

--delayed:

Inserta las filas con el comando "INSERT DELAYED".

-e, --extended-insert:

Utiliza la sintaxis de "INSERT" multilnea (proporciona sentencias

de "insert" ms compactas y rpidas).

-#, --debug[=option_string]:

--help:

--fields-terminated-by...;

Utilizacin de la traza del programa (para depuracin).

Muestra mensaje de ayuda y termina.


--fields-enclosed-by=...;

escaped-by=...; --lines-terminated-by=...:

--fields-optionally-enclosed-by=...;

--fields-

Estas opciones se utilizan con la opcin -T, y

tienen el mismo significado que la correspondiente clusula LOAD DATA INFILE.

-F, --flush-logs:

-f, --force:

-h, --host=...:

Escribe en disco todos los logs antes de comenzar con la copia.

Contina aunque se produzca un error de SQL durante la copia.


Copia los datos del servidor de MySQL especificado. El servidor por

defecto es localhost.

36

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


-l, --lock-tables:

Bloquea todas las tablas antes de comenzar con la copia. Las

tablas se bloquean con "READ

LOCAL"

para permitir "inserts" concurrentes en caso de

tablas MyIsam. Cuando se realiza la copia de mltiples bases de datos, --lock-tables


bloquear la copia de cada base de datos por separado, de forma que esta opcin
no garantiza que las tablase sean consistentes lgicamente entre distintas bases de
datos. Las tablas en diferentes bases de datos se copiarn en estados
completamente distintos.
-K, --disable-keys:

"/*!40000

Se incluir en la salida "/*!40000 ALTER TABLE tb_name DISABLE KEYS */;" y

ALTER TABLE tb_name ENABLE KEYS */;".

Esto har que la carga de datos en un

servidor MySQL 4.0 se realice ms rpido debido a que los ndices se crearn
despus de que todos los datos hayan sido restaurados.
-n, --no-create-db:

db_name;".

No se incluir en la salida "CREATE DATABASE /*!32312 IF NOT EXISTS */

Esta lnea se incluye si la opcin "--databases" o "--all-databases" fue

seleccionada.
-t, --no-create-info:

No incluir la informacin de creacin de la tabla (sentencia

"CREATE TABLE").
-d, --no-data:

No incluir ninguna informacin sobre los registros de la tabla. Esta

opcin sirve para crear una copia solamente de la estructura de la base de datos.
--opt:

Lo mismo que "--quick

--add-drop-table --add-locks --extended-insert --lock-tables".

Esta opcin le debera permitir realizar la copia de seguridad de la base de datos de


la forma ms rpida y efectiva.
-p your_pass, --password[=your_pass]:

Contrasea utilizada cuando se conecta con el

servidor. Si no se especifica, "=your_pass", "mysqldump" preguntar la contrasea.

-P, --port=...:

Puerto utilizado para las conexiones TCP/IP.

--protocol=(TCP | SOCKET | PIPE | MEMORY):

Especifica el protocolo de conexin que se

utilizar.
-q, --quick:

No almacena en el buffer la sentencia, la copia directamente a la salida.

Utiliza "mysql_use_result()" para realizarlo.


-Q, --quote-names:

Entrecomilla las tablas y nombres de columna con los caracteres

'''.

37

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

-r, --result-file=...:

Redirecciona la salida al fichero especificado. Esta opcin se

debera utilizar en MS-DOS, porque previene la conversin de nueva lnea ' \n' en
nueva lnea y retorno de carro '\n\r'.

--single-transaction:

Utiliza el comando "BEGIN" antes de realizar la copia desde el

servidor. Es muy til con las tablas InnoDB y el nivel de transaccin "READ_COMMITTED",
porque en este modo realizar la copia de seguridad en un estado consistente sin
necesidad de bloquear las aplicaciones. Consultar el manual para ms detalles.

-S /path/to/socket, --socket=/path/to/socket:

El fichero de sockets que se especifica al

conectar a localhost (que es el host predeterminado).

--tables:

Sobreescribe la opcin "--databases" (-B).

-T, --tab=path-to-some-directory:

Crea un fichero "table_name.sql" que contiene la

sentencia de creacin de SQL, y un fichero "table_name.txt" que contiene los datos de


cada tabla. El formato del fichero '.txt' se realiza de acuerdo con las opciones "--fieldsxxx"

y "--lines--xxx". Nota: esta opcin slo funciona si el comando "mysqldump" se

ejecuta en la misma mquina que el demonio "mysqld"; adems, el usuario deber


tener permisos para crear y escribir el fichero en la ubicacin especificada.

-u nombre_usuario, --user=nombre_usuario:

El nombre de usuario que se utilizar cuando

se conecte con el servidor, el valor predeterminado es el del usuario actual.

-v, --verbose:

Va mostrando informacin sobre las acciones que se van realizando

(ms lento).

-w, --where='clusula where':

-X, --xml:

-x, --first-slave:

Sirve para realizar la copia de determinados registros.

Realizar la copia de seguridad en un documento xml.

3.2.5.2.2 R ESTAURACIN

Bloquea todas las tablas de todas las bases de datos.

DE LA

B ASE

DE

D ATOS

TRAVS

DE

M YSQLDUMP .

Del anlisis de los ficheros del sitio web del grupo de control predictivo se obtuvieron los
datos necesarios para el acceso local a la base de datos. Se procedi a la copia de la base
de datos del sitio con el siguiente comando:

38

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


# mysqldump --single-transaction --user=NOMBRE_USUARIO -password=PASSWORD
--host=NOMBRE_HOST NOMBRE_BASE_DATOS > FICHERO_BACKUP.SQL

Ntese que con esta forma de ejecucin del comando no se tiene en cuenta la
posibilidad de que ya exista una base de datos con ese mismo nombre en el lugar de
destino. Para solucionar este problema en caso de existencia de una base de datos con el
mismo nombre que la que se intenta restaurar existen distintas opciones: 1) borrar
manualmente la base de datos antes de restaurar la copia por medio de una herramienta de
administracin como MySQL Control Center, 2) borrar manualmente la base de datos a
travs de la lnea de comandos de MySQL o mediante un script, 3) tener en cuenta al
ejecutar "mysqldump" que existe esta base de datos y aadir la opcin "--opt" o "--add-droptable"

para que al recuperar la base de datos a partir de la copia se borre en primer lugar la

base de datos existente e insertar despus la copia.


Con la ejecucin del comando anterior, en el fichero " FICHERO_BACKUP.SQL" se hallan
almacenadas todas las sentencias necesarias para poder reconstruir la base de datos en
otro ordenador.
Antes de proceder a la restauracin, en el ordenador destino hay que crear el usuario de
MySQL tal y como ste exista en el host original. Para ello, se abre un terminal y se inicia
MySQL Control Center:
# cd /usr/local/mysqlcc/
# ./mysqlcc

Una vez abierto MySQL Control Center, pulsar con el botn derecho sobre "User
Administration"

y escoger la opcin "New User". Los datos a insertar en cada uno de los campos

son los siguientes:

Username: nombre del usuario

Host: nombre o direccin del host

Password: password del usuario

Con esto ya se ha creado el nuevo usuario en la base de datos. Podra pensarse que se
podra recuperar la base de datos empleando a otro usuario. En realidad podra hacerse,
pero entonces habra que modificar los datos almacenados en los ficheros de la pgina para
que se pudiera realizar la conexin con la base de datos, ya que sta se encontrara
orientada para el usuario original de MySQL. Por simplicidad, debido a que despus habr
que restaurarla en el servidor "nyquist.us.es", es preferible dar de alta a este nuevo usuario
con la misma configuracin que tena en el servidor nyquist.us.es en lugar de realizar las
modificaciones oportunas en los ficheros del sitio.

39

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


Para proceder a restaurar la base de datos, el comando a ejecutar sera:
# mysql --user= NOMBRE_USUARIO --password=PASSWORD
NOMBRE_BASE_DATOS < FICHERO_BACKUP.SQL

Con esto ya se encuentra el sistema en condiciones de empezar a modificar la base de


datos y lo ms importante, poder verla correctamente (ntese que el usuario debe incluir el
nombre de usuario y la clave correspondiente).

3.2.5.3 E STRUCTURA

DEL

S ITIO WEB.

El sitio web est desarrollado haciendo uso de las libreras "phphtmllib". Para la creacin
de cada pgina se ha usado una plantilla de ejemplo que traen dichas libreras, denominada
"MyLayoutPage". Esta plantilla genera una pgina web con 4 zonas de contenido bien
diferenciadas: el encabezado, el pie, el men de la izquierda y el contenido de la pgina.
Modificando el contenido de cada zona a travs de mtodos especficos heredados de la
clase padre se construye cada una de las pginas.

3.2.5.4 R ELACIN

ENTRE LAS

TABLAS

DE LA

B ASE

DE

D ATOS .

Para la actualizacin de las tablas de la base de datos haba distintas opciones:


1. Introducir cada una de las publicaciones manualmente, a travs del men de
insercin implementado en la propia web.
2. Entender la interrelacin entre las tablas y generar un script php que directamente
modifique las tablas pertinentes a partir del contenido de un fichero de texto.
Se escogi la segunda opcin, por ser ms generalizada y por ser reutilizable en un
futuro si fuera necesario actualizar de forma masiva la base de datos.
La base de datos "Groupweb" consta de 8 tablas, algunas de ellas interrelacionadas
entre s. Estas tablas son: authors, books, congress, journals, people, pfcs, phds, sent.

Books: contiene los libros publicados por autores del grupo.

Journals: contiene los artculos de autores del grupo publicados en revistas.

Congress: contiene las ponencias en congresos de autores del grupo.

Pfcs: contiene los proyectos fin de carrera de alumnos que han sido tutelados por
miembros del grupo.

40

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Phds: contiene las tesis de miembros del grupo de control predictivo.

Authors: tabla que contiene referencias a los autores de las publicaciones


almacenadas en las cuatro tablas anteriores.

People: almacena los datos de todas las personas pertenecientes al grupo que han
sido dadas de alta en el sistema de la pgina web.

Sent: tabla con un registro por cada publicacin enviada a una direccin de correo
electrnico.

A continuacin se describir con ms detalle cada una de las tablas as como sus
respectivos campos de informacin.

Tabla "Books":
Esta tabla almacena en cada registro una publicacin en formato libro de un miembro del
grupo. Los campos que se han de rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

Title: ttulo del libro.

Abstract: resumen del contenido del libro.

Reference: referencia de bsqueda bibliogrfica para el buscador de la web del grupo.


Esta referencia se forma con el primer apellido del autor principal, el tipo de publicacin
(en este caso libro, que se indica como "BOOK") y el ao de publicacin.

Publisher: editorial del libro.

Year: ao de publicacin.

ISBN: nmero nico del libro en el estndar internacional.

Code: puede ser 1 2 dependiendo del tipo de publicacin (libro de actas o libro de
texto, respectivamente).

Tabla "Journals":
Esta tabla almacena en cada registro un artculo de revista de un miembro del grupo. Los
campos que se han de rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

41

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Title: ttulo del artculo.

Abstract: resumen del artculo.

Reference: referencia de bsqueda bibliogrfica para el buscador de la web del grupo.


Esta referencia se forma con el primer apellido del autor principal, el tipo de publicacin
(en este caso sera una revista, que se indica con las siglas de la misma) y el ao de
publicacin.

Journal: revista.

Year: ao de publicacin.

Volume: volumen de la revista.

Pages: pginas de la revista en las que se public el artculo.

Tabla "Congress":
Esta tabla almacena en cada registro una ponencia de congreso de un miembro del
grupo. Los campos que se han de rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

Title: ttulo de la ponencia del congreso.

Abstract: resumen de la ponencia del congreso.

Reference: referencia de bsqueda bibliogrfica para el buscador de la web del grupo.


Esta referencia se forma con el primer apellido del autor principal, el tipo de publicacin
(en este caso seran se trata de un congreso, que se indica con las siglas del mismo) y el
ao de publicacin.

Booktitle: nombre del congreso.

Year: ao del congreso.

Month: mes del congreso.

Address: direccin fsica del congreso

Pages: pginas del libro de actas del congreso en que se encuentra publicada la
ponencia.

42

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


Tabla "Pfcs":
Esta tabla almacena en cada registro un proyecto fin de carrera de un alumno tutelado
por un miembro del grupo. Los campos que se han de rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

Title: ttulo del proyecto fin de carrera.

Author: autor del proyecto.

Abstract: resumen del proyecto.

Datepfc: fecha de publicacin del proyecto.

Reference: referencia de bsqueda bibliogrfica para el buscador de la web del grupo.


Esta referencia se forma con el primer apellido del autor principal, el tipo de publicacin
(en este caso sera un proyecto fin de carrera, que se indica con las siglas PFC) y el ao
de publicacin.

Tabla "Phds":
Esta tabla almacena en cada registro una tesis de un miembro del grupo. Los campos
que se han de rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

Title: ttulo de la tesis.

Abstract: resumen de la tesis.

Datephd: fecha de publicacin de la tesis.

Reference: referencia de bsqueda bibliogrfica para el buscador de la web del grupo.


Esta referencia se forma con el primer apellido del autor principal, el tipo de publicacin
(en este caso sera una tesis, que se indica con las siglas PHD) y el ao de publicacin.

Tabla "Authors":
Esta tabla almacena tantas entradas por publicacin como autores tenga la misma, sea
del tipo que sea. Los campos que se han de rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

People: campo "id" de la tabla "people" para el autor en cuestin (si ste pertenece al

43

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


grupo).

Name: nombre del autor en caso de que no pertenezca al grupo.

Publication: campo "id" de la tabla correspondiente a la publicacin almacenada.

Type: el tipo de la publicacin (revista=1, congreso=2, etc).

Numorder: relevancia del autor (autor principal=1, secundario=2, etc).

Jobcode: solamente se emplea si se trata de un pfc o un phd, con valor "a" en caso
de ser el autor de la publicacin o "s" en caso de ser un supervisor.

Tabla "People":
Esta tabla almacena en cada registro un miembro del grupo. Los campos que se han de
rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

Name: Nombre del miembro.

Surname: Apellidos del miembro.

Login: palabra empleada como "nick" en el sitio web.

Password: clave para entrar en el sitio web con el login citado anteriormente.

Bibtextname: Firma bibliogrfica del miembro.

Tabla "Sent":
Esta tabla almacena en cada registro un artculo de revista de un miembro del grupo. Los
campos que se han de rellenar son los siguientes:

Id: campo autoincremental, es la clave de la tabla y sirve para indexar los registros.

Name: nombre de la persona que solicita un documento.

Affiliation: afiliacin, institucin.

Email: correo electrnico.

Publication: campo "id" de la publicacin solicitada en la tabla en que se encuentre.

Type: tipo de publicacin (revista=1, congreso=2, etc).

44

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Date: fecha y hora de la solicitud.

3.3 C ONTROL R EMOTO

DE

P ROCESO S

EN

TIEMPO R EAL M EDIANTE M ATLAB /TCP /IP .

El objetivo que se persigue aqu es desarrollar una forma alternativa de control de


procesos a travs de internet, utilizando para ello protocolos como TCP/IP.
Hoy en da, la supervisin de procesos a gran escala se lleva a cabo mediante complejos
sistemas SCADA, que proporcionan una alta fiabilidad y seguridad. El problema que tienen
estos sistemas es que la compra de licencias es una limitacin debido a su coste.
Una forma ms eficiente de controlar procesos de menor envergadura de forma ms
simple podra radicar en el control de procesos a travs de Matlab (programa de clculo
matemtico de amplio uso en mbitos universitarios y educativos). Matlab proporciona
herramientas para realizar clculos a travs de interfaces web y realizar conexiones remotas
a sistemas, pero ninguna de estas utilidades cumplen los requisitos que aqu se imponen.
Si bien Matlab permite realizar clculos de forma remota a travs de navegadores web
mediante su herramienta Matlab Server, tambin es cierto que cada clculo solicitado
mediante esta herramienta se ejecuta en instancias distintas, de forma que los clculos
nunca se realizaran para un mismo proceso en estudio, por lo que esta herramienta no es
til en este caso.
Otra forma de control remoto reside en el modo externo de Simulink. Esta modalidad
permite la conexin desde otro ordenador a un modelo de Simulink, pero solamente permite
una conexin y no slo eso, sino que adems no permite ningn control sobre la conexin
desde ese ordenador, pudindose conectar cualquier usuario no deseado.
Es por esto que se necesita de un mtodo para realizar un control sobre una
determinada planta o proceso de forma segura, fiable y controlada.

3.4 R EQUISITOS P REVIOS

PARA EL

C ONTROL R EMOTO .

3.4.1 M ICROSOFT VISUAL .NET.


En lo que respecta a la interfaz web para el control remoto es necesaria una distribucin
de Microsoft Visual .NET, debido a que sta se encuentra en un fichero de extensin

45

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


.aspx, en el que se halla entremezclado cdigo ASP con Visual C#.
Es vlida cualquier versin, no es necesario que sea la ltima (Microsoft Visual .NET
2003). La instalacin a realizar puede ser la tpica, ya que no se emplean libreras inusuales.
Recurdese en la instalacin seleccionar tambin para su instalacin Internet Information
Server, y configurar adecuadamente el servidor para servir pginas ASP.

3.4.2 M ATLAB 6.5.


La versin probada de Matlab fue la 6.5. Puesto que esta parte del proyecto simplemente
incluye una librera de funcin S programada por el autor, no es necesaria una versin
reciente, puesto que utiliza funciones bsicas de C. No obstante, la versin con la que se
teste todo el sistema fue la versin 6.5 y no dio fallo alguno.
La instalacin de Matlab puede ser una instalacin bsica, esto es, no es necesario
instalar todos los paquetes, puesto que no se hace uso de ellos.

46

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

4 M ETODOLOGA .
4.1 A CTUALIZACIN A UTOMTICA

DE

B ASES

DE

D ATOS .

La actualizacin de la base de datos se lleva a cabo en 4 sencillos pasos:

En el primero de ellos, el usuario deber validarse como usuario con los

privilegios adecuados para poder actualizar la base de datos.

En el segundo, se seleccionarn los ficheros de texto con la informacin para

actualizar los campos de la base de datos, as como la tabla que actualizar cada
fichero. Aqu tambin se introducirn las direcciones de las pginas webs que se
emplearn en la actualizacin, as como los directorios que contienen los
documentos a subir al servidor.

En el tercero, se especificarn los campos que contiene cada fichero, as como

los caracteres que delimitan un campo de otro y los que separan una entrada de
otra. Tambin se mostrarn aqu las rutas especificadas en el paso anterior (tanto las
de pginas webs como los directorios) que sean vlidas y accesibles.

En el cuarto paso se mostrarn todas las entradas procesadas con toda la

informacin recogida. Cada entrada se mostrar como un conjunto de campos de


texto, rellenos con la informacin disponible (vacos si sta no se facilit), un campo
con el documento a subir (junto con un porcentaje de similitud en la bsqueda) y una
casilla de verificacin para indicar que la entrada se encuentra completa y se puede
proceder a su actualizacin. No se deber salir de este paso hasta que se hayan
completado todas las entradas y se hayan actualizado.
Es posible que en el cuarto paso no se tengan almacenados los datos de una
determinada publicacin, como una revista o un congreso. En ese caso, en dicho paso
tambin se facilitar un formulario para insertar los datos necesarios para que pueda
procederse a una correcta actualizacin.
En resumen, el esquema a seguir es el siguiente:

47

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Validacin
Seleccin de ficheros de actualizacin
Insercin de rutas adicionales
Seleccin de campos de actualizacin
Complecin de entrada para actualizacin
Proceder con actualizacin
S

Quedan entradas por procesar?


No
Fin

Ilustracin 1: Flujo del sistema de actualizacin de bases de datos

En los siguientes apartados se detallar cada uno de los pasos.


Existe un fichero de funciones general (functions.inc.php) que incluyen cada uno de los
pasos. En este fichero se definen variables cuyo significado se aclarar aqu, puesto que
interpretan un papel fundamental en el caso de que se desee modificar el script para
utilizarlo con otra base de datos:

$lista_campos_adicionales:

array que contiene los nombres de los campos

adicionales (campos fictios necesarios para una actualizacin colateral). Por ejemplo,
el campo "autores", que no existe como tal en ninguna tabla, pero que se emplea
para actualizar colateralmente la tabla de autores de las publicaciones. Este array se
utilizar para mostrar los nombres de los campos adicionales en las listas
desplegables.

$tabla_campos_adicionales:

array que contiene los nombres de las tablas que

actualizarn los campos adicionales contenidos en "$lista_campos_adicionales". Por


ejemplo, si el campo actualiza la tabla de las tesis, entonces valdr "phds", o si las
actualiza todas "all". Ntese que el nombre de la tabla debe ir en el mismo orden
que en "$lista_campos_adicionales".

$var_campos_adicionales:

array que contiene los nombres de las variables que

48

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


almacenan los campos adicionales. Por ejemplo, el campo "autores" se almacena en
la variable "$authors", por lo que en "$var_campos_adicionales" se introduce
"authors".

$lista_campos_undef:

array que contiene los nombres de otros campos que no se

utilizan para actualizar la base de datos en s, pero que son necesarios por alguna
razn. Por ejemplo, el campo "separador_campos", que es necesario para separar un
campo de otro dentro del fichero de actualizacin. Estos campos se distinguen de los
adicionales, adems, en que se conoce el campo que se va a actualizar, pero lo que
no se conoce es el valor.

$tabla_campos_undef:

al igual que "$tabla_campos_adicionales", este array se

utiliza para almacenar los nombres de las tablas en las que se utilizar este
parmetro. Por ejemplo, "separador_campos" se utiliza en todas las tablas, por lo que
se inserta "all" en este array en la posicin correspondiente.

$var_campos_undef:

array que contiene los nombres de las variables que

almacenan los valores de los campos no definidos. Por ejemplo, el separador de


campos se almacena en la variable de nombre "separador_campo".

$valores_campos_undef:

array con los valores de cada campo seleccionable en la

lista desplegable del campo no definido.

$desc_campos_undef:

array con la descripcin de cada campo seleccionable en la

lista desplegable del campo no definido. La razn de ser de este array y el anterior
es que normalmente los separadores son caracteres especiales, como nueva lnea
('\n') o tabulador ('\t'), que debido a una caracterstica de PHP se envan de forma
incorrecta al siguiente formulario (duplica las barras invertidas). Por ello, se enva un
entero que se utilizar en un array en el siguiente formulario para obtener el valor
correcto. Como mostrar el entero en la lista desplegable no ofrecera ninguna
informacin al usuario se introduce este array, que contiene una descripcin correcta
de cada uno de los campos no definidos.

4.1.1 P ASO 1 VALIDACIN .


El primer paso es el ms sencillo de todos. Consta de una pantalla en la que se
muestran dos campos de texto, uno para el login del usuario y otro para la contrasea de
ste.

49

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


La razn de ser de este paso es bien sencilla y fundamental: si no existiera este paso,
cualquier usuario podra acceder al sistema y causar destrozos o malfuncionamientos en la
base de datos. Es por ello que se antoja un requisito del sistema validar a los usuarios
permitidos al comienzo del proceso, de forma que se asegure el acceso a usuarios con los
permisos necesarios.
El fichero que implementa este paso es update.html.

Ilustracin 2: Captura del paso 1 (Validacin de usuario)

4.1.2 P ASO 2 S ELECCIN

DE FICHEROS E INSERCIN DE

R UTAS .

El segundo paso responde a la necesidad del sistema de conocer el origen de la


informacin que se usar para la actualizacin. Por ello, se muestra en pantalla un
formulario con tres partes bien diferenciadas:

Formulario de seleccin de ficheros y tablas: el usuario ha de seleccionar los

ficheros de texto que contienen los datos a partir de los cuales se actualizarn las
tablas de la base de datos y las tablas que stos actualizan.

50

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Formulario de insercin de rutas urls: el usuario insertar en este campo de texto

las distintas direcciones web que complementarn a los ficheros indicados en el paso
anterior.

Formulario de insercin de rutas locales: el usuario insertar aqu las rutas que se

encuentren en el ordenador desde el que se realiza la actualizacin que contengan


informacin complementaria para los casos del primer formulario (tablas a
actualizar).
El objetivo es complementar la actualizacin de todas las formas disponibles, para que el
resultado sea el ms completo y satisfactorio posible.
Las nicas formas de complementacin que no se han considerado son:

Actualizacin a travs del contenido de pginas web.

Actualizacin a travs de otra base de datos.

La razn de no tener en cuenta la actualizacin a partir de otra base de datos es bien


simple. Normalmente, los usuarios mantienen las bases de datos introduciendo datos en
stas a travs de formularios de pginas web, y por tanto, solamente tienen que validarse en
el sistema como usuarios para poder realizar estas modificaciones. Sin embargo, para poder
acceder a una base de datos de forma directa y obtener listados de datos de tablas de la
misma es necesaria la contrasea del usuario root o maestro, que normalmente es el mismo
usuario que cre la pgina web. Esta contrasea normalmente se encuentra bien protegida
y el acceso a la misma es muy limitado, de modo que slo lo conoce un grupo reducido de
usuarios, que no suele ser el mismo grupo que intenta actualizar otra base de datos distinta
en otra pgina distinta.
Respecto de no tener en cuenta el contenido de una pgina web para complementar los
datos, la razn radica en que, a pesar de haber muchos sistemas automatizados hoy en da
para mostrar informacin de bases de datos en pantalla (listados de los contenidos de bases
de datos en pginas webs), todava existen pginas que se programan manualmente, y
muchas veces ni siquiera acceden a bases de datos para la obtencin de la informacin que
muestran, sino que sta se encuentra embebida (incrustada) en el mismo cdigo de la
pgina. El problema que conlleva esto es que el error humano acta en casos como el
incorrecto cierre de etiquetas html, o errores tipogrficos, de modo que si, por ejemplo, se
buscara el volumen de una publicacin, habra pginas en las que ste se mostrara
precedido de "Vol.", mientras que en otras podra ser "Volumen", "Volume" o simplemente
"V.". Esto conlleva una casustica demasiado extensa como para tenerla en cuenta. Por otro

51

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


lado, si cada campo se encontrara embebido en una etiqueta de elemento "<li>" dentro de
una lista "<ul>", utilizando como separador de cada elemento, por ejemplo, ";", y al usuario
casualmente en algn caso se le olvidara insertar dicho separador, entonces resultara en
una actualizacin errnea, y lo mismo pasara si se le olvidara cerrar la etiqueta de elemento
con "</li>" si se utiliza sta para discriminar entre entradas distintas.
Por todas estas razones no se han tenido en cuenta estos mtodos de actualizacin.

52

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 3: Captura del paso 2 (Seleccin de ficheros)

4.1.3 P ASO 3 S ELECCIN

DE

C AMPOS

DE LA

A CTUALIZACIN .

La finalidad de este tercer paso es clara: el sistema necesita saber qu campos del
fichero de actualizacin facilitado se corresponden de forma directa con alguno de los

53

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


campos de las tablas de la base de datos y cules son campos a partir de los cuales se
construirn otros.
En este paso tambin se analizan las rutas facilitadas en el paso anterior, de forma que
se muestran en pantalla solamente aquellas a las que se ha podido acceder (comprobacin
previa antes de proceder a ciegas a su uso). Se analizan tanto las rutas correspondientes a
direcciones de internet para actualizacin mediante web como las correspondientes a rutas
locales para actualizacin mediante ficheros sitos en el mismo ordenador de la actualizacin
(o de la misma red).
El diagrama de flujo que recoge la secuencia de ejecucin de este paso se muestra a
continuacin:

Recoger informacin de base de datos

Subir ficheros de actualizacin al servidor

Para cada tabla

Mostrar campos de la tabla

Mostrar campos adicionales

Mostrar campos interactivos


Analizar urls del paso 2
Mostrar las correctas y accesibles

Mostrar directorios del paso 2


Ilustracin 4: Flujo del proceso de seleccin de campos (Paso 3)

54

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 5: Captura del paso 3 (Seleccin de campos)

4.1.4 P ASO 4 C OMPLECIN

DE

E NTRADAS

PARA

A CTUALIZACIN .

El paso 4 se repite cclicamente, mostrando en pantalla las entradas que restan por
actualizar en la base de datos. Inicialmente se muestran todas las entradas procesadas a
partir de los ficheros de actualizaciones, divididas en los campos finales que actualizarn la
tabla correspondiente. En la primera iteracin de este paso, el sistema procede al anlisis de
todos los ficheros facilitados, y durante este largo proceso, se va mostrando en pantalla un
mensaje indicando la entrada del documento que se est analizando, ya que el usuario
podra pensar que el sistema queda colgado en un estado inconsistente (vase ilustracin
6).
Por cada entrada de los ficheros se muestra un cajn de campos editables, entre los que
se encuentran los siguientes elementos:

55

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Tabla que actualizar.

Campos que se usarn para la actualizacin, mostrados mediante campos de

texto para una posible modificacin si fuera necesaria antes de proceder a la


actualizacin. La razn de hacer esto radica en que muchas veces existen errores
tipogrficos en las fuentes de la informacin, y con esto se quiere dar la opcin al
usuario de que corrija dichos fallos. Esto se puede ver fcilmente en el campo de
fichero pdf que se explica a continuacin, pues si se encuentra un documento que
tenga un porcentaje de coincidencia entre 95-100%, esto querr decir que vara en
alguna/s letra/s, de forma que estos errores son fcilmente identificables.

Fichero pdf que se subir al servidor: aqu se mostrarn el fichero pdf que mayor

coincidencia tenga con la publicacin buscada (siempre que tenga un porcentaje de


coincidencia superior al 95%), si se encuentra en alguna de los directorios o urls
facilitados en el paso 2, junto con el porcentaje de coincidencia entre parntesis. Si
no se ha encontrado ninguno, se puede indicar un fichero pdf manualmente,
insertando la ruta en el campo de texto o bien buscndolo en un directorio local
pulsando en el botn "examinar". En el caso de que la bsqueda devuelva varios
documentos con porcentajes de coincidencia superiores al 95%, entonces se
mostrarn en pantalla todos los resultados y se dar al usuario la posibilidad de
escoger el resultado correcto (esto suele ocurrir cuando un artculo y una ponencia
de congreso de un mismo autor sobre una misma temtica se encuentran a la vez en
la fuente de la informacin: normalmente coincidirn en el nombre del artculo, y al
sistema le ser imposible detectar cul es el correcto).

Casilla de verificacin de "no especificacin de pdf".

Casilla de verificacin de "entrada completa".

Casilla de verificacin de "entrada no deseada" (cuando no se desea aadir la

entrada a la base de datos).


El proceso de actualizacin tiene lugar en este paso de la siguiente forma: se mostrarn
todas las entradas contenidas en los ficheros de actualizacin; una vez una entrada est
completa, se marcar la casilla de verificacin de "entrada completa" y el sistema pasar a
actualizarla, de modo que al volver sobre este paso se mostrarn todas las entradas que
hubiere antes a excepcin de las ya actualizadas. Todo esto puede observarse en la
ilustracin 8.
En el proceso de actualizacin tambin se controla si existe una entrada igual en la base

56

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


de datos antes de actualizarla, con la finalidad de evitar duplicidades.
El fichero functions.step3.php es un fichero de funciones complementario para el paso
4, debido a que es bastante laborioso, y por claridad del cdigo principal se han extrado la
mayora de funciones independientes y se han incluido en este fichero.
Adems, hay un fichero proc_files.php que realiza todo lo correspondiente a la copia
de ficheros en el servidor. Puesto que la copia de ficheros es un proceso largo, el usuario
puede creer que en algn momento del proceso el sistema se ha quedado colgado, ha
quedado en un estado inconsistente. Para soslayar este incoveniente est este fichero.
Durante la copia de ficheros muestra en pantalla una barra de progreso (como se muestra
en la Ilustracin 7) que indica al usuario qu fichero se est copiando, el porcentaje copiado
y el porcentaje del total de ficheros a copiar. A su vez, en el fichero paso3.php est
programado que se muestre por pantalla cada una de las entradas que se van procesando.
Esto significa que en primer lugar se actualiza la base de datos y posteriormente se procede
a la copia de los ficheros.
Una vez actualizada por completo la base de datos, el sistema mostrar por pantalla un
mensaje de xito en la actualizacin, como se muestra en la figura 8.

Ilustracin 6: Captura del paso 4 - Analizando las entradas de los ficheros

57

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 7: Captura del paso 4 - Copiando ficheros

Ilustracin 8: Captura del paso 4 - Base de datos actualizada

58

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 9: Captura del paso 4 - Listado de los artculos encontrados

59

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

4.1.5 FICHERO

DE INCLUSIN

G ENERAL .

El fichero de inclusin general es un fichero que se incluye al comienzo de todos los


ficheros que componen el proceso de actualizacin. En primer lugar desempea una funcin
muy importante porque genera unos arrays a partir de la informacin de la base de datos
especificada que facilitan la migracin hacia otro sistema. Esto es, crea arrays con
informacin sobre los campos de las tablas de las bases de datos y otra informacin que se
emplea en los pasos iniciales de configuracin y que, al ser de carcter general, permiten a
un usuario avanzado que desee adaptar el sistema a otra base de datos modificar
solamente el procesado que se hace de los datos de la misma, sin tener que programar
nuevo cdigo para obtener esta informacin. Estos arrays son:

$lista_campos_adicionales:

almacena los campos que no aparecen como tales

en las tablas de la base de datos pero que son necesarios porque a partir de ellos se
generarn otros que s se encuentran en stas.

$tabla_campos_adicionales:

almacena los nombres de las tablas que modificarn

los campos adicionales recogidos en $lista_campos_adicionales.

$var_campos_adicionales:

indica los nombres de los arrays que almacenarn los

valores de los campos adicionales tras leerlos de las fuentes de informacin


indicadas.

$lista_campos_undef:

estos campos son campos no existentes en tablas y que no

son necesarios para obtener campos existentes en la tabla, pero que s son
necesarios para procesar stos. A modo de ejemplo, un campo de este array es
separador_campos, el cual indica qu separador se utilizar en los ficheros de texto
para separar los campos contenidos.

$tabla_campos_undef:

similar a $tabla_campos_adicionales pero referido a

$lista_campos_undef.

$var_campos_undef:

similar

$var_campos_adicionales

pero

referido

$lista_campos_undef.

$valores_campos_undef:

los campos definidos en $lista_campos_undef no

pueden ser ingresados por el usuario, y necesitan de unos valores definidos


previamente, permitiendo al usuario elegir uno u otro valor. Estos valores
predefinidos se almacenan en este array. Por ejemplo, para el caso del separador de
campos separador_campos, los valores pueden ser un retorno de carro, un carcter
nueva lnea, un tabulador, un punto y coma, ...

60

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

$desc_campos_undef:

son las descripciones que se mostrarn en la lista

desplegable del script de actualizacin, de modo que estas etiquetas almacenadas


en el array representarn lo que el usuario ver. Por ejemplo, en el caso de un
retorno de carro, aparecera en la lista desplegable \r.
Lo que resta de contenido de este fichero es un conjunto de funciones de carcter
general que son usadas en prcticamente todos los pasos del proceso de actualizacin.
El fichero que implementa estas funciones de carcter general es functions.inc.php.

4.2 C ONTROL R EMOTO

DE

P ROCESO S

EN

TIEMPO R EAL

MEDIANTE

M ATLAB /TCP/IP.

La finalidad de esta parte del proyecto es controlar un sistema a travs de Simulink, en


tiempo real haciendo uso del toolbox "Real Time Workshop" y de forma remota haciendo
uso del protocolo Tcp/Ip para transportar datos a travs de red e implementar un sistema
cliente/servidor.
Este sistema se pensaba emplear en la red de excelencia Hycon, y estaba destinado
para su uso en los experimentos sobre la planta solar de los laboratorios de la Universidad
de Sevilla, pero al final no se implement. Estos experimentos se realizaban desde
universidades situadas en otros pases, por lo que el control deba hacerse a travs de un
operario situado en el ordenador de control de la planta solar, llevando a cabo todas las
acciones deseadas por los usuarios remotos. El problema que tiene este planteamiento es
que hay que tener una persona dedicada ntegramente a insertar las rdenes de los
usuarios, puesto que stos no pueden acceder directamente al controlador.
Por ello, se pens en una forma alternativa de control, basndose en el protocolo Tcp/Ip.
Matlab dispone de un modo de ejecucin en Simulink denominado "modo externo".
Activando este modo, antes de la ejecucin Matlab compila el modelo de Simulink,
generando cdigo ejecutable. Este cdigo ejecutable no es ms que un servidor que
escucha peticiones en un puerto determinado. Para conectarse, un cliente simplemente
debe ejecutar el mismo fichero de modelo de Simulink con el que se compil el servidor en
Matlab, e indicar la direccin ip y el puerto en los que se encuentra corriendo el servidor.
Con este modo parece en principio que se puede solucionar el problema del control remoto,
pero no es as: con este modo, cualquier usuario puede conectarse a la planta y modificar
parmetros sin ningn tipo de supervisin, lo que podra redundar en malfuncionamientos de
los equipos, inhabilitacin de los mismos o incluso catstrofes. Por otra parte, solamente

61

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


puede conectarse un usuario al servidor.
Por tanto, el modo externo del Real Time Workshop ofrece ventajas e inconvenientes,
pero no sirve para solventar el problema en cuestin.
Tampoco se pudo utilizar el programa Matlab Server que implementa el propio Matlab,
debido a que, si bien permite la ejecucin remota de ficheros de Matlab sobre el ordenador
que implementa el servidor, sta se ejecuta en una instancia distinta por peticin, esto es, si
el usuario ejecutase el controlador en Matlab Server, se creara una nueva instancia de
ejecucin para el nuevo usuario, de forma que se crearan varias para distintos usuarios,
perdiendo el requisito del control en tiempo real, puesto que no se pueden aplicar varios
controladores a una misma planta simultneamente. Este modo de trabajo es til para
realizar simulaciones de forma externa, pero se necesita un mtodo que incluya la
exclusividad de la planta: solamente un usuario puede tener acceso a ella e implementar el
control que desee.
La solucin fue utilizar funciones S, que pueden ser programadas en C. La funcin S
diseada consta de un bloque con 1 entrada (que en realidad es irrelevante, pues no realiza
ninguna funcin, pero que podra tener su utilidad en una posterior facilidad del usuario, esto
es, siempre es ms cmodo facilitar las referencias iniciales a travs de bloques y
establecer su valor grficamente, de modo que una futura mejora podra ser establecer
tantas entradas como salidas y facilitar los valores iniciales de los parmetros a travs de
estas entradas en lugar de mediante la ventana de configuracin del bloque) y 10 salidas. El
objetivo es que el usuario pueda establecer los valores que desee a las salidas del bloque,
pudindolos usar como referencias de otros bloques o incluso para cambiar valores de
parmetros, como ganancias estticas. La funcin S lee peridicamente un fichero de
intercambio que almacena los valores a cambiar. Si el usuario desea modificar alguna de las
salidas del bloque, entonces una interfaz web acta de cliente con un servidor que se
encuentra en el mismo ordenador que el ejecutable servidor de Matlab. Este servidor recibe
la informacin con los parmetros a cambiar y modifica el fichero de intercambio para que al
leerlo el ejecutable servidor de Matlab obtenga los nuevos valores de las salidas.
Las ventajas que ofrece este sistema sobre el modo externo son varias:

Posibilidad de controlar el sistema desde cualquier ordenador va la interfaz web.

Posibilidad de implementar restricciones al control remoto mediante programacin

en la funcin S encargada de la lectura promiscua del fichero de intercambio.

Posibilidad de restringir qu parmetros se pueden modificar.

62

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Posibilidad de control simultneo mediante varios usuarios.

Las desventajas tambin son importantes:

El protocolo Tcp/Ip, a pesar de ser robusto, no es invulnerable a fallos en la red y

podran perderse las modificaciones de algunos usuarios.

Necesidad de implementar los bloques de Simulink como funciones S si se desea

cambiar parmetros de un bloque, como por ejemplo, la ganancia esttica de un


sistema de segundo orden (este problema se ver ms adelante).
En el siguiente apartado se describirn cada una de las partes que componen el sistema
completo.

4.2.1 E STRUCTURA G ENERAL

DEL

S ISTEMA

DE

C ONTROL R EMOTO .

La estructura de conexin del sistema se muestra a continuacin:

REMOTE PC
Web
Page

SERVIGAR

WWW
Server

NEOXITE
Server

Client
Ilustracin 10: Estructura general del sistema de control remoto

Los elementos involucrados son:

Ordenador remoto: se trata de un PC con conexin a internet que acceder a la

interfaz web de control remoto del sistema mediante un navegador cualquiera.

Servigar: es el servidor que aloja la interfaz web de control remoto. Implementa un

63

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


servidor IIS con sistema operativo Windows XP Professional. La interfaz web se
encuentra programada en Visual C# (la parte del servidor) y ASP (la parte de la
interfaz web). Esta interfaz web es la encargada de mostrar al usuario los valores
existentes en el modelo de Simulink que se encuentra corriendo actualmente en el
servidor Neoxite, as como de recibir los nuevos valores que los usuarios remotos
deseen modificar y enviar dichos datos a una aplicacin servidor que escucha en un
determinado puerto en Neoxite. Adems, tiene implementado una aplicacin servidor
que recibe de Neoxite una representacin del modelo de Simulink implementado,
para que se muestre al usuario en la interfaz web, el modelo de Simulink (fichero
.mdl) y el fichero con los valores de los parmetros.

Neoxite: es el ordenador que se encarga del control del sistema. Ser el que

implemente la ejecucin del modelo en Simulink para el control del sistema, por lo
que consta de una aplicacin en Matlab para generar una representacin del modelo
y enviar sta junto con el modelo a la aplicacin servidor en Servigar. Esta aplicacin
en Matlab invoca una aplicacin cliente que enva ambos ficheros a la aplicacin
servidor en Servigar. Tambin implementa una aplicacin servidor que recoge los
datos enviados por Servigar cuando se modifiquen los valores de los parmetros.
Esta aplicacin servidora modifica el fichero de intercambio en consecuencia,
permitiendo que en la siguiente lectura del bloque de funcin S Simulink modifique
los valores de sus salidas.

4.2.2 S ERVIGAR .
4.2.2.1 INTERFAZ WEB .
La interfaz web se encuentra programada en ASP y Visual C#, debido a que se tena
pensado implementarla en un principio en el Benchmark 2 de la red de excelencia Hycon,
que se encarga del control remoto de un sistema hbrido (una plataforma solar con 4 placas
solares, un sistema de refrigeracin y una caldera), y se necesitaba implementar ActiveX
para poder realizar el control va OPC.
Como se puede observar en la siguiente imagen, la interfaz web es simple: muestra dos
cuadros de texto por cada parmetro modificable (uno con el valor actual y otro para insertar
el nuevo valor), y debajo de estos cuadros se sita una representacin grfica del
controlador implementado, para que los usuarios sepan si el controlador implementado es el

64

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


suyo o no. Adems, de esta forma es ms fcil ver qu salida se corresponde con el
parmetro deseado, consiguiendo una modificacin de los parmetros ms fcil e intuitiva.

Ilustracin 11: Captura de la interfaz web del sistema de control remoto

La parte de ASP es bien simple. No ocurre as con la parte de Visual C#. Lo primero que
se hace es comprobar que el usuario posee los permisos necesarios para proceder con la
modificacin de parmetros (para ello tiene que estar dado de alta en el sistema, es decir,
en la web, y tener reservado un periodo de prueba sobre la planta o bien ser el
administrador). Posteriormente, se comprueba la existencia del fichero de modelo de
Simulink as como de su representacin grfica.
El siguiente paso es la lectura del fichero "nombre.mdl" (donde "nombre" indica el

65

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


nombre del fichero que se encuentre en el direcorio de la pgina), que contiene los valores
actuales de los parmetros. Esto se utilizar para mostrar los valores en los campos
sombreados en gris, que indican los valores actuales. Si el usuario desea un nuevo valor,
deber indicarlo en el cuadro blanco adjunto.
Asociado

al

botn

"Change

Parameters"

se

encuentra

el

mtodo

"ButtonChangeParams_Click", que implementa toda la parte cliente de la interfaz web, la


cual ser la que enve los datos cambiados a la aplicacin servidor sito en Neoxite. El primer
paso es establecer una conexin con el equipo destino, en este caso Neoxite.
Posteriormente, se crea el mensaje a enviar. Para ello se miran todos los campos de texto
de los parmetros. Si el campo no est vaco, entonces se introduce en el mensaje una
lnea con el texto "varX=valor\n", donde X es el nmero de la variable y valor es la cantidad
introducida en el campo de texto. Las lneas se separan unas de otras introduciendo un
carcter de nueva lnea "\n".
La construccin del mensaje inicial obedece a un protocolo bastante simple creado para
esta aplicacin. El formato de dicho mensaje es:
REQUEST*MODE*IP_ADDRESS*MSG_LENGTH*FILE_NAME
"REQUEST" indica el tipo de peticin. En este caso, siempre ser del tipo
"MOD_REQUEST", que indican que se trata de una peticin de modificacin del fichero de
intercambio.
"MODE" indica el modo de la peticin. En este caso, siempre ser "OVERWRITE", que
indica que en el lado servidor se crea un nuevo fichero, sobreescribiendo el anterior en caso
de que existiera.
"IP_ADDRESS" es la direccin a la que se enva el mensaje, es decir, la direccin de
NEOXITE.
"MSG_LENGTH" es el tamao del fichero que se va a enviar posteriormente. Este
mensaje ser el que incluya todos los datos necesarios para la modificacin del fichero de
intercambio.
"FILE_NAME" es el nombre del fichero que se va a modificar.
Una vez enviado este mensaje inicial de solicitud de modificacin del fichero de
intercambio se espera el ACK o mensaje de asentimiento. Este mensaje se caracteriza
porque simplemente se trata de una cadena de texto con el mensaje "PROCEED" en caso
de que se permita proceder con la modificacin. En caso de recibir cualquier otra cosa, se

66

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


aborta la operacin.
Una vez enviado los datos que se han de modificar, se modifica tambin el fichero
"nombre.log" (donde "nombre" indica el nombre del fichero que se encuentre en el directorio
de la pgina), que reside en Servigar y que se utiliza para leer los valores actuales de los
parmetros. Puesto que se modifican, se ha de actualizar. Para ste no es necesario
realizar una peticin, puesto que se encuentra en el mismo ordenador.
Por ltimo, se han de refrescar los campos de texto con los valores actuales, y vaciar el
contenido de los campos de texto que modifican los valores de los parmetros.
En todo momento existe una etiqueta para mostrar mensajes de error en caso de que los
hubiere. Los casos contemplados son los errores de conexin con la aplicacin servidor en
Neoxite.
El cdigo para la interfaz web se encuentra en el fichero tunning.aspx.cs.

4.2.2.2 A PLICACIN S ERVIDOR

EN

S ERVIGAR .

Esta aplicacin se encuentra programada en Visual C#. Su funcin principal es la


recepcin de tres ficheros, necesarios para el correcto funcionamiento de la interfaz web.
Estos tres ficheros son enviados por la aplicacin cliente en Neoxite, y son los siguientes
(donde "nombre" indica el nombre del fichero que se encuentre en el direcorio de la pgina):

nombre.log: fichero de texto plano que contiene los valores iniciales de los

parmetros.

nombre.mdl: fichero de modelo de Simulink que contiene el modelo implementado

en el control del sistema.

nombre.png: fichero de imagen que contiene una captura del modelo con la

finalidad de mostrarlo posteriormente en la interfaz web.


La aplicacin servidor es una aplicacin multihilo, pues implementa en un hilo un servidor
sncrono que se bloquea a la escucha de nuevas peticiones por un determinado puerto, y
por otro lado, un hilo que implementa el control de la aplicacin y permite en cualquier
momento salir de la misma.
La primera operacin que se realiza es la ejecucin del hilo de control de la aplicacin,
denominado "hilo_lector", por leer de forma promiscua la entrada de datos a travs del
teclado.

67

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


En segundo lugar se inicia el servidor en s, enlazndolo con el punto local
correspondiente a Servigar (193.147.161.89), y ponindolo a escuchar de forma promiscua
en un puerto (39854) dentro de un bucle de control. En este bucle, lo primero que se hace
es, como ya se ha dicho, poner el servidor a escuchar en un puerto especfico, y
posteriormente, cuando se recibe una conexin entrante, comienza el procesamiento de la
peticin.
En primer lugar se realiza un filtrado de las IPs, pues no se permite la conexin de
cualquier equipo. Si se trata de una direccin IP vlida y admitida, entonces se recibe el
mensaje y se procesa la solicitud. Existen distintos casos:

"COPY_REQUEST": solicitud de copia de ficheros remota.

"MOD_REQUEST": solicitud de modificacin remota de ficheros.

"ABORT": solicitud de abortar programa.

Todo esto se resume en el flujo de programa de la ilustracin 12.


Hay que mencionar que en una peticin de copia remota de ficheros (COPY_REQUEST)
se compara la extensin del fichero recibido. Si dicha extensin coincide con la extensin
propia de los ficheros de modelo de Simulink (.mdl), entonces se genera tambin el fichero
.log aqu. Este fichero se crea a partir de la lectura y el anlisis del fichero de modelado de
Simulink. Se busca la lnea de definicin de los parmetros del bloque que contiene la
funcin S que implementa el control remoto, se almacenan los valores de dichos parmetros
en un array y posteriormente se insertan en un fichero, de nombre el mismo que el fichero
de modelado, y extensin .log. Este fichero ser el que utilizarn ms adelante la interfaz
web y la aplicacin servidor de Servigar para la actualizacin de los valores modificados por
el usuario remotamente.
El hilo lector de teclado es ms simple en su concepcin y funcionamiento. Simplemente
lee la entrada del teclado a la espera de recibir la cadena "exit", momento en el cual
procede a enviarse a s mismo un mensaje "ABORT" para salir del bucle de escucha
promiscua de mensajes entrantes.
Todo el cdigo se encuentra embebido en estructuras try-catch para capturar todas las
excepciones posibles, con la finalidad de hacer seguro el cdigo.

68

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Port Listening

Read Keyboard Input

IP Filter
EXIT
Process Received Message

COPY REQ.

MOD REQ.

Exit

ABORT

Ilustracin 12: Flujo del programa multihilo servidor de Servigar

4.2.3 N EOXITE .

4.2.3.1 B LOQUE TUNNING (S-FUNCTION ).


El fichero tunning.c contiene el cdigo fuente del bloque que implementa la lectura del
fichero de intercambio.
Lo primero que debe hacerse es compilar este fichero para que Matlab genere una dll
que pueda usarse en los bloques de funciones S de Simulink. Para ello, desde la lnea de
comandos y siendo el directorio de trabajo el que contiene el fichero tunning.c, el usuario
ha de escribir en la lnea de comandos de Matlab:
mex tunning.c

Tras haber finalizado la compilacin, en el mismo directorio se encontrar el fichero


tunning.dll, que contendr la versin compilada del cdigo fuente de la funcin S.
Para utilizar esta dll, en el modelo de Simulink que implemente el controlador que se
desea testear remotamente el usuario debe insertar un bloque S-Function (en Simulink
Library Browser se encuentra en SimulinkUserDefined FunctionsS-Function), y

69

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


especificar en las propiedades del mismo lo siguiente:
S-function name: tunning
S-function parameters: 1,2,3,4,5,6,7,8,9,10

Entonces aparecer un bloque de Simulink de nombre tunning, con una entrada y diez
salidas. Ntese que el nombre de la funcin S que se especifica debe ser el de la dll. Si la dll
no se encuentra en el mismo directorio que el modelo de Simulink que la invoca, al intentar
ejecutar el modelo producir un error.
Los parmetros que se definen en las propiedades corresponden a los valores iniciales
de las salidas del bloque. Estos valores son los que posteriormente se modificarn a travs
de la interfaz web (se ha puesto del 1 al 10 por poner algn valor, pero el usuario deber
poner aqu las referencias iniciales que desea a la salida del bloque).
Por otro lado, tambin hay que tener en cuenta las distintas modificaciones de las
propiedades del modelo que hay que realizar previamente. Para que se genere el ejecutable
del modelo es necesario establecer la siguiente configuracin:

En ToolsReal-Time WorkshopOptions:

En la pestaa Real-Time Workshop:

Category: Target configuracion.

System target file: grt.tlc.

Template makefile: grt_default_tmf.

Make command: make_rtw.

Desmarcar Generate code only.

Category: General code generation options:

Marcar Verbose builds.

Marcar Local block outputs.

Category: GRT code generation options:

Marcar External mode.

En la pestaa Solver:

Solver options:

Type: Fixed-step, discrete (no continuous states).

70

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Fixed step size: auto.

Mode: Single Tasking.

En ToolsExternal mode control panel:

En Target interface:

MEX-file for external interface: ext_comm.

En la pestaa de la ventana de Simulink que muestra una lista desplegable hacia abajo y
que tiene seleccionada la opcin Normal, hay que seleccionar la opcin External.
Una vez creado el modelo de Simulink deseado para implementar el controlador, se ha
de compilar el modelo completo, y para ello se presiona en el botn Build All, que se
encuentra junto a la lista desplegable anterior.

4.2.3.2 A PLICACIN M ATLAB .


La finalidad de la aplicacin programada para Matlab es la establecer todos los requisitos
previos para un control remoto. Bsicamente se encarga de la generacin de la imagen del
controlador y el posterior envo de la misma junto con el fichero del controlador al servidor
web.
El flujo del programa se describe en el siguiente esquema:

Obtener nombre controlador

Almacenar imagen controlador

Enviar .mdl y .png

Eliminar ficheros intermedios

Fin
Ilustracin 13: Flujo del script de Matlab para el sistema
de control remoto

71

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Inicialmente el programa solicita al usuario el nombre del fichero que contiene el


controlador (con extensin .mdl o sin ella). A continuacin abre dicho controlador en una
nueva ventana de Simulink donde realiza una captura para generar el fichero de imagen.
Dicho fichero de imagen se crea haciendo uso del ejecutable "convert.exe" que se
distribuye con el paquete de software libre ImageMagick.
Matlab proporciona un fichero de imagen .bmp, pero para enviar imgenes a travs de
la red es conveniente convertir el formato a uno que ofrezca compresin y adems
proporcione ventajas adicionales, como la transparencia de fondo, para una mejor
integracin con la interfaz web. Por todo ello, el formato destino de la conversin es .png
(Portable Network Graphics), y es debido a esto la utilizacin de ImageMagick, ya que
proporciona un ejecutable en lnea de comandos que facilita en gran medida la conversin
de .bmp a .png.
Por

ltimo,

el

programa

invoca

la

aplicacin

cliente

de

Neoxite

(cp_client_neoxite.exe), que es la que se encarga del envo de ambos ficheros, el de


imagen y el de Simulink, a la aplicacin servidor sito en Servigar, que ubica ambos ficheros
en un directorio especfico para que la interfaz web sea capaz de generar correctamente los
datos en pantalla.
El fichero que contiene la aplicacin Matlab es "sendtoservigar.m".
NOTA: el fichero de parmetros se ha de crear manualmente antes de proceder a la
ejecucin del modelo de Simulink. Se ha de crear un fichero de texto. Su contenido puede
ser nulo, o si el usuario lo prefiere, puede insertar una lnea por variable, con la sintaxis
varX=val, donde X indica el ndice de la variable (var1, var2, etc) y val el valor de la
misma, aunque esto lo realiza el bloque de modificacin de parmetros automticamente
una vez se inicia su ejecucin, pero se ha de recalcar que dicho bloque NO crea el fichero.
El nombre del fichero deber ser tunning.txt.

4.2.3.3 A PLICACIN C LIENTE .


La aplicacin cliente de Neoxite es la que se encarga de la copia/modificacin de
ficheros remota en Servigar. Es invocada por el script programado para Matlab y, al igual
que los servidores programados tanto en Neoxite como en Servigar, dispone de un protocolo
de transferencia diseado para un mejor control y una mayor fiabilidad de las operaciones

72

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


remotas.
El protocolo posee un esquema de funcionamiento simple. En primer lugar el cliente
genera un mensaje de intercambio de informacin en el que indica al servidor el tipo de
peticin que desea realizar y adems le proporciona informacin diversa que es necesaria
para ste. El formato de este mensaje inicial es:
REQUEST*MODE*IP_ADDRESS*MSG_LENGTH*FILE_NAME
"REQUEST" indica el tipo de peticin. Puede ser del tipo "COPY_REQUEST" o
"MOD_REQUEST", que indican que se trata de una peticin de copia de fichero o de
modificacin de fichero respectivamente.
"MODE" indica el modo de la peticin. Puede tener los valores "CREATE" u
"OVERWRITE", que indica que en el lado servidor se crea un nuevo fichero, sin
sobreescritura en el primer caso, o sobreescribiendo el anterior en caso de que existiera en
el segundo caso.
"IP_ADDRESS" es la direccin a la que se enva el mensaje, es decir, la direccin de
NEOXITE.
"MSG_LENGTH" es el tamao del fichero que se va a enviar posteriormente. Este
mensaje ser el que incluya todos los datos necesarios para la modificacin del fichero de
intercambio.
"FILE_NAME" es el nombre del fichero que se va a modificar.
Una vez enviado este mensaje inicial de solicitud de modificacin del fichero de
intercambio se espera el ACK o mensaje de asentimiento. Este mensaje se caracteriza
porque simplemente se trata de una cadena de texto con el mensaje "PROCEED" en caso
de que se permita proceder con la modificacin. En caso de recibir cualquier otra cosa, se
aborta la operacin.
Una vez recibido el asentimiento positivo se procede al envo del fichero, que el servidor
recoger en el lado destino, creando un fichero similar en el sitio adecuado.
Existen distintos casos:

"COPY_REQUEST": solicitud de copia de ficheros remota.

"MOD_REQUEST": solicitud de modificacin remota de ficheros.

"ABORT": solicitud de abortar programa.

Los envos se realizan al puerto 39854 de Servigar, que es donde se encuentra

73

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


escuchando la aplicacin servidor.

4.2.3.4 A PLICACIN S ERVIDOR .


Esta aplicacin se encuentra programada en Visual C#. Su funcin principal es la
recepcin del fichero que contiene la actualizacin de los parmetros del bloque de control
remoto, modificados por el usuario remoto a travs de la interfaz web. Este fichero es
enviado por la interfaz web en Servigar, y tiene extensin .log (fichero de texto plano que
contiene los valores actualizados de los parmetros).
La aplicacin servidor es una aplicacin multihilo, pues implementa en un hilo un servidor
sncrono que se bloquea a la escucha de nuevas peticiones por un determinado puerto, y
por otro lado, un hilo que implementa el control de la aplicacin y permite en cualquier
momento salir de la misma.
La primera operacin que se realiza es la ejecucin del hilo de control de la aplicacin,
denominado "hilo_lector", por leer de forma promiscua la entrada de datos a travs del
teclado.
En segundo lugar se inicia el servidor en s, enlazndolo con el punto local
correspondiente a Neoxite (172.16.1.231), y ponindolo a escuchar de forma promiscua en
un puerto (32000) dentro de un bucle de control. En este bucle, lo primero que se hace es,
como ya se ha dicho, poner el servidor a escuchar en el puerto especfico, y posteriormente,
cuando se recibe una conexin entrante, comienza el procesamiento de la peticin.
En primer lugar se realiza un filtrado de las IPs, pues no se permite la conexin de
cualquier equipo. Si se trata de una direccin IP vlida y admitida, entonces se recibe el
mensaje y se procesa la solicitud. Existen distintos casos:

"COPY_REQUEST": solicitud de copia de ficheros remota.

"MOD_REQUEST": solicitud de modificacin remota de ficheros.

"ABORT": solicitud de abortar programa.

Todo esto se resume en el flujo de programa de la ilustracin 14:

74

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Port Listening

Read Keyboard Input

IP Filter
EXIT
Process Received Message

COPY REQ.

MOD REQ.

Exit

ABORT

Ilustracin 14: Flujo del programa multihilo servidor de Neoxite

El hilo lector de teclado es ms simple en su concepcin y funcionamiento. Simplemente


lee la entrada del teclado a la espera de recibir la cadena "exit", momento en el cual
procede a enviarse a s mismo un mensaje "ABORT" para salir del bucle de escucha
promiscua de mensajes entrantes.
Todo el cdigo se encuentra embebido en estructuras try-catch para capturar todas las
excepciones posibles, con la finalidad de hacer seguro el cdigo.

4.2.4 U BICACIN

P UESTA

P UNTO

DE LOS

P ROGRAMA S .

La ubicacin de cada uno de los programas es importante. Si no se tiene cuidado al


colocar los ejecutables se obtendrn errores adicionales. A continuacin se especifica la
puesta a punto de cada uno de ellos:

Aplicacin de conversin de formato grfico "convert.exe": debe encontrarse en el

mismo directorio que la aplicacin de Matlab "sendtoservigar.m".

Aplicacin

de

Matlab:

esta

aplicacin

es

un

fichero

con

nombre

"sendtoservigar.m". Debe situarse en el directorio de trabajo donde se encuentre el


fichero de modelo de Simulink que contiene el controlador a implementar el control

75

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


remoto. La ejecucin es muy simple. Basta con escribir "sendtoservigar" en la lnea
de comandos de Matlab (con cuidado de estar situados en el mismo directorio en
que se encuentra "sendtoservigar.m"), y la secuencia a seguir una vez invocado el
script es la siguiente:

Insercin del nombre del fichero de modelo de Simulink (con o sin extensin

".mdl").

Esperar a la finalizacin del programa.

Durante el transcurso de la ejecucin, la aplicacin ir mostrando por pantalla los


distintos avances que irn sucediendo, como son la deteccin del fichero de
modelado, la obtencin de su representacin, la conversin del formato grfico o el
envo sucesivo de los ficheros al servidor sito en Servigar.

Interfaz web en Servigar: es la pgina web que contiene la interfaz de

modificacin remota de los parmetros. El resultado de la compilacin de esta pgina


ha de ubicarse en el directorio web en el que se proporcione el servicio de hosting
de pginas (depende del servidor web instalado, por ejemplo, Apache Server o
Internet Information Server, y de su configuracin). En este punto hay que tener en
cuenta que la interfaz web se dise para su interfuncionamiento con el sitio web de
la Planta Solar encuadrada en el proyecto europeo Hycon. Este hecho indica que el
sistema de validacin es el que usaba dicho sitio web. Si se desea utilizar en otro
mbito, ser necesario modificar la programacin de dicha interfaz para adecuarla a
las nuevas condiciones de trabajo.

Aplicacin servidor en Servigar "cp_server_servigar.exe": debe ubicarse en la

misma carpeta que la pgina "tunning.aspx", que es la que implementa la interfaz


web para cambiar remotamente los parmetros. El funcionamiento de este servidor
es sencillo: una vez ejecutado, mostrar por pantalla un mensaje indicando que si se
escribe la palabra "exit" se detendr la ejecucin del mismo, dando a entender que
se ejecutar de forma indefinida si el usuario no escribe la orden correspondiente. El
servidor se quedar a la escucha de peticiones en el puerto designado y cuando
reciba alguna lo mostrar por pantalla.

Aplicacin cliente en Neoxite "cp_client_neoxite.exe": esta aplicacin debe

ubicarse en la misma carpeta que el script de Matlab "sendtoservigar.exe", ya que


ste lo utiliza para el envo de ficheros al servidor ubicado en Servigar. En teora el
usuario no necesita saber de la ejecucin de este cliente, puesto que lo invoca la

76

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


misma aplicacin "sendtoservigar.m".

Aplicacin servidor en Neoxite "cp_server_neoxite.exe": debe ubicarse en el

mismo directorio en que se est ejecutando el fichero del modelo de Simulink, puesto
que en dicho directorio se crear el fichero .log que se utilizar para alterar los
valores de los parmetros. El funcionamiento de este servidor es, al igual que el
situado en Servigar, bastante sencillo: una vez ejecutado, mostrar por pantalla un
mensaje indicando que si se escribe la palabra "exit" se detendr la ejecucin del
mismo, dando a entender que se ejecutar de forma indefinida si el usuario no
escribe la orden correspondiente. El servidor se quedar a la escucha de peticiones
en el puerto designado y cuando reciba alguna lo mostrar por pantalla.

4.2.5 E JEMPLO C OMPLETO

DE

C ONTROL R EMOTO .

A continuacin se mostrar un ejemplo completo que ilustrar el funcionamiento de la


utilidad de control remoto.
1) Se situarn los siguientes ficheros en el directorio %MATLAB_PATH%/work/ en el
ordenador Neoxite:

convert.exe
cp_client_neoxite.exe
cp_server_neoxite.exe
tunning.c
tunning.txt
params.mdl
sendtoservigar.m

El fichero tunning.txt es un fichero de texto que contiene una lista de asignacin de


valores a las variables cuyos valores se podr cambiar, con las asignaciones separadas por
retornos de carro. Un ejemplo del contenido podra ser:
var1=1
var2=2
var3=3

Se situarn los siguientes ficheros en el directorio /Files/Simulink/ del sitio web de la


planta solar en Servigar:

cp_server_servigar.exe

2) Lo siguiente a realizar es la compilacin del bloque de modificacin remota de


parmetros. Desde la lnea de comandos de Matlab se escribir:

77

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


mex tunning.c

Ilustracin 15: Compilado de la funcin S "tunning.c" en Matlab

A continuacin se configurar el fichero de modelo de Simulink tal y como se describe en


el punto 3.2.3.1. Una vez hecho esto, ya nos encontramos en condiciones de generar el
ejecutable. Para hacer esto, presionamos sobre el botn Build All de la ventana de
Simulink.

Una

vez

terminada

la

compilacin

se

habr

generado

una

carpeta

params_grt_rtw que contendr todo el cdigo fuente del ejecutable generado, mientras que
el ejecutable se encontrar en la misma carpeta que el modelo de Simulink.

78

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 16: Modelo de ejemplo de Simulink

Ilustracin 17: Compilacin del model de ejemplo de Simulink para su uso con RTW y el modo externo

3) Antes de proceder a la ejecucin del modelo, se han de arrancar los distintos


servidores que deben quedarse a la espera de peticiones en los puertos. Por tanto, en este
paso se ejecutan los ejecutables cp_server_neoxite.exe y cp_server_servigar.exe en

79

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


Neoxite y Servigar respectivamente.

Ilustracin 18: Servidor corriendo en Servigar

Ilustracin 19: Servidor corriendo en Neoxite

4) El operario encargado de ejecutar el controlador pondr en marcha el sistema,


invocando "sendtoservigar.m" desde la lnea de comandos de Matlab. Esta aplicacin se
comunicar con el servidor sito en Servigar y llevar a cabo la puesta a punto del sistema.
Una vez configurado el sistema, el operario ejecutar el controlador del usuario, no sin antes
haber arrancado el ejecutable servidor del modo externo generado en el paso 2. Para ello, el
operario abrir una ventana de comandos de Windows (una consola), se desplazar al
directorio donde se encuentra dicho ejecutable para el modo externo y una vez ubicado en
dicha carpeta ejecutar el siguiente comando:
params -tf inf -w

La opcin -tf establece el tiempo final de la ejecucin en tiempo real. Con inf se
indica que se desea que el tiempo de ejecucin sea infinito. La opcin -w se utiliza para
esperar el mensaje de bienvenida del host, esto es, que no se empieza a ejecutar hasta que
un cliente se conecta con el fichero del modo externo.

80

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 20: Ejecucin del modelo compilado de Simulink

Lo siguiente ser, como ya se dijo anteriormente, ejecutar el controlador del usuario.


Para ello, se abre el modelo del controlador en Simulink, se escoge el modo externo en la
lista desplegable superior y se presiona sobre el botn que hay justamente a la izquierda de
la lista, que muestra como ayuda emergente al posar el ratn sobre l Connect to target.
Esto conectar el modelo con el ejecutable que se ha arrancado antes. Una vez conectado,
ya solamente resta pulsar en el botn Start real-time code, situado a la izquierda del
anterior.

Ilustracin 21: Ejecucin del modelo de Simulink en modo


externo haciendo uso de RTW

81

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


SERVIGAR

WWW
Server

NEOXITE

Client
Ilustracin 22: Esquema del envo de ficheros de Neoxite a Servigar mediante
el script de Matlab

Ilustracin 23: Ejecucin del script de Matlab

82

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 24: Recepcin de los ficheros enviados por Matlab en el


servidor de Servigar

El usuario cuyo controlador se encuentra en funcionamiento, debido a que en la


supervisin de los resultados observa que stos no son los deseados, desea modificar
determinados aspectos de su controlador, y para ello accede a la interfaz web desde un
punto remoto a travs de internet:

REMOTE PC
Web
Page

SERVIGAR

WWW

Ilustracin 25: Acceso del usuario remoto a la interfaz web de Servigar

Ilustracin 26: Captura de la interfaz web

83

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Despus de validarse convenientemente, el usuario tendr acceso a la interfaz web y


ver los valores actuales de los parmetros de su controlador y modificar aquellos que no
le plazcan. En este momento, tras pulsar el botn de actualizar dichos valores, la interfaz
web se comunicar con el servidor sito en Neoxite para modificar el fichero de intercambio
de datos, de forma que el bloque de modificacin de parmetros pueda actualizar los
nuevos valores.

REMOTE PC
Web
Page

SERVIGAR

WWW

NEOXITE
Server

Ilustracin 27: Esquema del envo de datos de la interfaz web al servidor de Neoxite

Ilustracin 28: Recepcin de los parmetros modificados en el servidor de


Neoxite

84

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Ilustracin 30: Captura del valor del parmetro antes


del cambio

Ilustracin 29: Captura del valor del parmetro


despus del cambio

85

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

5 R ESULTADOS E XPERIMENTALES .
5.1 S ISTEMA

DE

A CTUALIZACIN

DE

B ASES

DE

D ATOS

Como batera de pruebas del sistema se utilizaron ficheros de texto con publicaciones
contenidas en la base de datos del SICA.
En estos ficheros, los campos se encontraban separados mediante tabuladores, mientras
que las entradas a aadir en la base de datos se encontraban separadas mediante retornos
de carro.
Cada uno de los ficheros se encargaba de actualizar una tabla distinta de la base de
datos, que para las pruebas fue la base de datos groupweb, emplazada en el servidor
Nyquist de los laboratorios de la Universidad de Sevilla, y que albergaba el sitio web del
grupo de control predictivo.
Inicialmente se realizaron pruebas de insercin manual de los datos contenidos en los
ficheros, y posteriormente se procedi a la actualizacin de la base de datos mediante el
sistema diseado en el presente proyecto.
Los tiempos de actualizacin se muestran en la siguiente tabla comparativa:

Nombre del
fichero

Nmero de Tiempo empleado Tiempo empleado Tiempo empleado


entradas
en insercin
en insercin
por el sistema en el
manual de datos automtica de datos anlsis de datos

journals.txt

75

3h15m

0h31m

0h15m

congress.txt

211

7h32m

1h20m

0h42m

phds.txt

10

0h23m

0h05m

0h02m

books.txt

0h18m

0h03m

0h01m

actas.txt

26

1h03m

0h07m

0h04m

TOTAL:

331

12h31m

2h06m

1h04m

Todos los experimentos se llevaron a cabo en condiciones ptimas, esto es, tomando
como conocida la existencia y localizacin de los documentos pdf complementarios a las
entradas existentes en los ficheros de texto, as como usando un operario con amplia

86

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


destreza en el uso de ordenadores con una velocidad de mecanografiado de 400 ppm.
En la siguiente tabla se muestran las estadsticas resultantes de la comparacin de
ambos mtodos:

Nombre de
fichero

Reduccin Tiempo efectivo Tiempo medio por


de tiempo
de trabajo
entrada manual

Tiempo medio por


entrada automtica

journals.txt

84.1 %

51.6 %

2.60m

0.41m

congress.txt

82.3 %

47.5 %

2.14m

0.38m

phds.txt

78.3 %

60.0 %

2.30m

0.50m

books.txt

83.3 %

66.6 %

2.00m

0.33m

actas.txt

88.9 %

42.9 %

2.42m

0.27m

TOTAL:

83.2 %

49.2 %

2.27m

0.38m

Como demuestran los resultados, el trabajo se reduce en casi la mitad, y el tiempo que
se tarda en actualizar el sistema disminuye alrededor de un 80 %, por lo que se deduce que
el sistema funciona produciendo los resultados esperados.

5.2 C ONTROL R EMOTO


M ATLAB .

DE

U NA P LANTA

TRAVS

DE

U NA INTERFAZ WEB U SANDO

Las pruebas llevadas a cabo con la funcin S programada dieron los resultados
esperados. No obstante, si el tiempo de muestreo del sistema es muy bajo, esto implicar
que se realizarn muchos accesos al disco duro para la lectura del fichero de texto que
almacena los valores de las variables. Por tanto, se recomienda programar una pequea
porcin de cdigo para que la lectura del fichero slo se lleve a cabo cada ciertos mltiplos
del tiempo de muestreo o mediante cualquier otro criterio del usuario.
Si no se tiene acceso al tiempo de muestreo, siempre es posible definir una variable
global de valor incremental conforme avanza la ejecucin del modelo. Cuando sta adquiera
un determinado valor, se reiniciara y ste sera el evento mediante el cual se llevara a cabo
la lectura del fichero de texto con los valores.
En lo que respecta a las pruebas, como caba esperar, se modificaron los valores de las
salidas del bloque, aunque el sistema en determinadas ocasiones se ralentizaba, sobretodo
cuando el tiempo de muestreo era bajo.

87

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

6 C ONCORDANCIA
R ESULTADOS Y O BJETIVOS .
6.1 S ISTEMA

DE

A CTUALIZACIN

DE

B ASES

DE

E NTRE

D ATOS .

Como se desprende del apartado anterior, los resultados obtenidos con el sistema son
bastante buenos. Se consigue reducir drsticamente el tiempo de actualizacin de un
sistema en torno al 80 %.
Por otra parte, tambin se alivia el trabajo realizado por el usuario encargado de la
actualizacin, pues ste realiza hasta un 50 % menos de trabajo empleando el sistema
diseado que si lo actualizase directamente.
En consecuencia, los objetivos son satisfechos completamente, puesto que permiten que
con un mnimo esfuerzo y una mnima dedicacin de tiempo se lleve a cabo la actualizacin
exitosa de la base de datos.

6.2 C ONTROL R EMOTO

DE

P LANTA M EDIANTE M ATLAB /TCP/IP.

Los resultados cumplen con los objetivos en tanto que permiten la manipulacin de datos
en Matlab a travs de una interfaz web. El mayor problema reside en la correcta
configuracin de las lecturas promiscuas del fichero de datos que almacena los valores
que se han de cambiar, pues puede llegar colapsar el sistema o actualizar con demasiada
lentitud el mismo.
No obstante, los objetivos fijados se cumplen.

88

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

7 C ONCLUSIONES .
7.1 A CTUALIZACIN A UTOMTICA

DE

B ASE

DE

D ATOS .

El sistema cumple de forma esperada todos los objetivos establecidos al comienzo del
mismo. No obstante, aqu se podran remarcar las ventajas e inconvenientes del sistema,
derivadas de la experimentacin con el mismo.
Ventajas:

La actualizacin se realiza de forma satisfactoria.

No se producen duplicidades de entradas en la base de datos debido a una

comprobacin anterior.

Aunque la copia de ficheros en el servidor no es inmediata, para no dar al usuario

la impresin de cuelgue del sistema se ha creado una barra de progreso que


muestra al usuario la progresin de la copia del fichero actual y la progresin total de
la copia de ficheros. Aunque esto no resuelve el problema de la lentitud de la subida
s sirve para evitar que el usuario tenga una falsa impresin de incomplecin de la
actualizacin y ste intente actualizar la pgina de actualizacin, lo que s podra
resultar en resultados incoherentes o duplicidades.

Igualmente, el anlisis de los ficheros de las publicaciones no es inmediato, y se

muestra una lnea de informacin que indica la lnea que se est analizando en el
momento con la finalidad de que el usuario vea que el sistema est funcionando y no
est colgado.

Se ofrece al usuario la posibilidad de corregir los posibles errores existentes antes

de proceder con la actualizacin, e incluso la posibilidad de complementar los


campos no disponibles en los ficheros de actualizacin.
Desventajas:

El anlisis de coincidencia de los nombres de las publicaciones y los nombres de

los documentos a subir al servidor disponibles en los hiperenlaces es demasiado


lento, y esta lentitud crece conforme ms aumente la diferencia de longitudes de las
cadenas a comparar. Es por esto que se ha limitado esta diferencia a un mximo de
5 caracteres, para no ralentizar en exceso el sistema.

89

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

La copia de ficheros en el servidor no es inmediata, y depende de la calidad de la

conexin de que se disponga para realizar la actualizacin.

La lentitud del sistema aumenta con el volumen de datos a actualizar, pero esto

es una consecuencia inevitable.

7.2 C ONTROL R EMOTO

DE

S ISTEMAS

MEDIANTE

M ATLAB /S IMULINK .

El sistema de control remoto funciona correctamente y de la forma esperada. Al igual que


en el apartado anterior, se sopesarn aqu sus ventajas e inconvenientes:
Ventajas:

Posibilidad de cambiar parmetros en un modelo de Simulink va internet en

cualquier momento y desde cualquier lugar.

Interfaz web simple y fcil de usar.

Desventajas:

Sistema complejo de servidores y clientes. Sera ms eficaz poder implementar

mecanismos tcp/ip dentro del bloque de la funcin S de Simulink, pues ahorrara un


servidor en Neoxite.

Para modificar parmetros hay que programar los bloques manualmente

mediantes funciones en C e implementarlos a travs de bloques de funciones S.

El sistema parece quedarse colgado en la simulacin a veces, pero no se cuelga

realmente.

El transporte de la informacin depende de un protocolo de internet, con todas las

desventajas que esto conlleva: posibilidad de ataques, prdida de los mensajes de


informacin.

90

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

8 FUTURAS M EJORAS (L NEAS


INVESTIGACIN ).

DE

En la parte de la actualizacin automtica de bases de datos:

Implementar un sistema inteligente de anlisis de datos en pginas web para

complementar la informacin con texto disponible en la misma, basando el anlisis


en etiquetas html o palabras claves.

Eliminar la interaccin del usuario con el sistema de actualizacin en la correccin

de errores tipogrficos implementando un diccionario propio y un sistema de


correccin.

En el caso de la subida de ficheros, analizar el contenido de los ficheros a subir

para asegurar al 100% la efectividad de la eleccin del fichero correcto.

Hacer que el sistema cumpla con las exigencias de la W3C.

Implementar un sistema de validacin de usuario que utilice SSH (Secure SHell),

con la finalidad de mejorar la seguridad del sistema mediante tcnicas de cifrado.

En la parte de control remoto:

Situar los campos de texto justo en las salidas del bloque de la funcin S, para

que sea todava ms directa la asociacin entre los campos de texto y las salidas del
bloque.

Automatizar todava ms la aplicacin de Matlab que genera los ficheros de

imagen y enva los ficheros a Servigar, para que compile directamente el modelo de
Simulink (en caso de que se vaya a usar el modo externo), lo ponga a ejecutar y se
quede a la espera de rdenes.

Intentar implementar el envo/recepcin de mensajes por tcp/ip en el mismo

Simulink (es bastante difcil, porque al intentar implementarlo Simulink se cuelga,


pero es posible definir un protocolo de envo para el modo externo compilando
libreras propias para las capas 1 y 2 del modelo OSI).

91

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Intentar la modificacin de parmetros en el Workspace en tiempo real (difcil

porque las funciones creadas por MathWorks con esta finalidad implementan el
fichero de cabecera "mex.h", mientras que si la aplicacin se ha de controlar en
tiempo real requiere de Real Time Workshop, y las libreras de este toolbox son
incompatibles con "mex.h".

Implementar un sistema de validacin de usuario que utilice SSH (Secure SHell),

con la finalidad de mejorar la seguridad del sistema mediante tcnicas de cifrado.

Robustecer el protocolo diseado con cdigos CRC de 16 31 bits para

verificacin de las transmisiones, a fin de desechar mensajes errneos que puedan


llegar al servidor o al cliente.

Implementar un sistema final de comprobacin de que realmente se han

modificado los datos.

92

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

9 B IBLIOGRAFA .
En la parte de control remoto se han utilizado los documentos publicados por The
MathWorks, empresa responsable de la creacin del programa Matlab y la ingente ayuda del
paquete de programacin Microsoft Visual .NET.
En la parte relativa al sistema de actualizacin de bases de datos, la documentacin
utilizada fue:

CONVERSE, TIM; PARK, JOYCE; MORGAN, CLARK. PHP5 and MySQL Bible. Wiley
Publishing Inc., 2004. ISBN: 0-7645-5746-7.
DUBOIS, PAUL. MySQL The definitive guide to using, programming, and
administering MySQL 4.1 and 5.0 3rd Edition. Sams, March 08, 2005. ISBN: 0-672-326736.
GOURLEY, DAVID; TOTTY, BRIAN; SAYER, MARJORIE; REDDY, SAILU; AGGARWAL,
ANSHU. HTTP: The Definitive Guide. O'Reilly, September 2002. ISBN: 1-56592-509-2.
GREENSPAN, JAY; BULGER, BRAD. MySQL/PHP Database Applications. M&T
Books, 2001. ISBN: 0-7645-3537-4.
HUNGER, STEVE. Debian GNU/Linux Bible. Hungry Minds Inc., 2001. ISBN: 0-76454710-0.
LAURI, BEN; LAURI, PETER. Apache The Definitive Guide, 3rd Edition. O'Reilly,
December 2002. ISBN: 0-596-00203-3.
NEGUS, CHRISTOPHER. Linux Bible 2005 Edition. Wiley Publishing Inc., 2005. ISBN:
0-7645-7949-5.
WONG, CLINTON. HTTP Pocket Reference, 1st Edition. O'Reilly, May 2000. ISBN: 156592-862-8.

Tambin se emple el sitio web de la World Wide Web Consortium Schools, que legisla
todo lo referente a la web (HTML, XHTML, etc) para documentacin:
http://www.w3schools.com/

93

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

10 A NEXOS
10.1 C ONTENIDOS

DEL

CD-R OM .

El contenido del cd-rom adjunto se desglosa a continuacin:

Final: contiene los ejecutables principales (versiones finales compiladas) que se

han de emplear para poner en funcionamiento el sistema.

Control.Remoto: contiene los ejecutables correspondientes a la parte de

control remoto del proyecto.

SQL.Update: contiene los ficheros finales del sistema de actualizacin de

bases de datos.

Artculos.Nyquist: contiene una copia de la web empleada para tomar los

ficheros pdf del grupo de control predictivo.

Final.Site: contiene una copia del directorio completo de la pgina.

New.Files: nuevos ficheros creados para la actualizacin.

Old.Modified.Files: antiguos ficheros del sitio web que han sido

actualizados.

Sources: contiene el cdigo fuente de los programas desarrollados.

Control.Remoto: contiene el cdigo fuente de los programas desarrollados

para la aplicacin de control remoto.

Aplicacion.Matlab: cdigo del programa sendtoservigar.m.

Cliente.Neoxite: cdigo fuente del cliente ubicado en Neoxite empleado por

sendtoservigar.m para el envo remoto de ficheros.

Image.Magick: programa de software libre que contiene diversas utilidades

para el tratamiento de imgenes.

Interfaz.Web: cdigo fuente de la interfaz web utilizada para el cambio de

los valores de los parmetros. Tambin se incluye en un fichero comprimido


el proyecto del sitio web desarrollado para la red de excelencia Hycon con
motivo de los experimentos sobre la planta solar de los laboratorios de la
Universidad de Sevilla.

94

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Servidor.Neoxite: cdigo fuente del servidor ubicado en Neoxite, empleado

para la recepcin de los nuevos valores de los parmetros modificados.

Servidor.Servigar: cdigo fuente del servidor ubicado en Servigar,

empleado para la recepcin de los ficheros de imagen y de modelo de


Simulink enviados por el cliente de Neoxite invocado por sendtoservigar.m.

Bloque.S-Function: cdigo fuente del bloque de modificacin remota de

parmetros.

Ejemplo.Controlador: controlador empleado en el ejemplo incluido en esta

memoria para el sistema de control remoto mediante Matlab y la interfaz web.

SQL.Update: cdigo fuente del sistema de actualizacin de bases de datos.

Original.Site: copia de la pgina web del grupo de control predictivo.

Articulos.Nyquist: ficheros originales del sitio web utilizado para obtener los

documentos .pdf para actualizar la base de datos.

Programas: contiene algunos los programas necesarios para el proyecto (que no

necesiten de licencia o sean software libre). En la mayora de las carpetas se


incluyen ficheros de ayuda para aprender a manejarlos:

Control Remoto: programas utilizados en el sistema de control remoto.

Image-Magick: paquete de software libre con herramientas y utilidades

relacionadas con los formatos grficos. Se utiliza para la conversin de


formatos.

SQL.Update: programas utilizados para la actualizacin de las bases de datos.

Apache.Server: servidor de pginas web Apache.

Compresores: algunos compresores para Linux.

Lectores.Ext2: permiten leer particiones de Linux desde sistemas

Windows.

MySQL: servidor de bases de datos SQL.

MySQL Administrator: gestor para mantenimiento de bases de datos

MySQL.

MySQL Control Center. Gestor para mantenimiento de bases de datos

MySQL.

95

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

PHP: lenguaje de programacin de pginas web.

PDF.Collection: coleccin de documentos .pdf necesarios para la actualizacin

de la base de datos del sitio web del grupo de control predictivo.

Docs: ficheros de documentacin empleados para el proyecto.

Control.Remoto: ficheros de documentacin de la parte relativa al control

remoto va web de procesos.

SQL.Update: ficheros de documentacin de la parte relativa a la actualizacin

de bases de datos.

10.2 M ANUAL

DE

U SO : S ISTEMA

DE

A CTUALIZACIN

DE

B ASES

DE

D ATOS .

10.2.1 INSTALACIN .
Los archivos situados en el directorio Final/SQL.Update/Final.Site constituyen la
nueva versin del sitio web del grupo de control predictivo. Basta con sobreescribir la
carpeta que contiene el antiguo sitio mediante una transferencia ftp/telnet o similar.
Si se desea copiar nicamente los ficheros correspondientes al sistema, entonces
simplemente se han de copiar en el directorio del sitio web del grupo de control predictivo los
ficheros de la carpeta Final/SQL.Update/New.Files.
El directorio en que se encuentra el antiguo sitio web del grupo de control predictivo es
/var/www/groupweb/, en el servidor Nyquist.

10.2.2 U SANDO

EL

S ISTEMA

DE

A CTUALIZACIN

DE

B ASES

DE

D ATOS .

La interfaz del sistema de actualizacin es bastante intuitiva. Para acceder al sistema


simplemente se ha de escribir la ruta en el navegador, empleando como fichero
update.html. Por ejemplo, si el root del servidor web es /var/www/, y el sitio web est en
la carpeta /var/www/groupweb/, y se ha realizado la instalacin indicada en el punto 10.2.1,
entonces se debera escribir la ruta http://nyquist.us.es/groupweb/update.html.
En pantalla se mostrarn cuatro opciones:

Actualizar base de datos.

96

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

Editar fichero de definicin de publicaciones.

Crear copia de seguridad de la base de datos.

Restaurar copia de seguridad de la base de datos.

En todos y cada uno de los cuatro pasos el usuario ha de ingresar el nombre y la


contrasea para poder validarse. En caso de no hacerlo, no podr acceder a ninguna de las
opciones presentadas.

10.2.2.1 A CTUALIZAR B ASE

DE

D ATOS .

En el primer paso de la actualizacin el usuario ha de seleccionar los ficheros de texto


que contengan las entradas a aadir a la base de datos, as como elegir la tabla de la base
de datos que actualizar dicho fichero. Los nombres de las tablas guardan relacin directa
con el contenido de las mismas. As, una tabla que almacena publicaciones en revistas se
llama journals, una que almacena ponencias en congresos se llama congress, etc.
Asimismo, se permite aadir direcciones web para buscar documentos en formato .pdf
con la finalidad de complementar las entradas de los ficheros de texto. Con esta misma
finalidad tambin se permite aadir rutas de directorios.

En el segundo paso el usuario debe indicar al sistema los campos de que constan las
entradas de los ficheros que indic en el paso anterior, as como los separadores que se
utilizan para distinguir campos y entradas (tabuladores, retornos de carro, etc). Mencin
especial tiene el campo authors o supervisors, que representan a los autores o
supervisores de una publicacin. Para ellos tambin es necesario indicar al sistema el tipo
de separadores usados. Los ms comunes para este caso son ; o ,.
Al final del documento se indica adems si las direcciones y directorios facilitados en el
paso anterior son lebles correctamente y se tiene acceso a ellos.
Hay que remarcar que los campos se han de indicar en el mismo orden con que
aparecen en los ficheros de texto, y de forma consecutiva. Caso aparte son los separadores,
que se muestran nicamente al final, ya que, al no existir como tales campos, entonces no
tienen necesidad de ir a continuacin de los campos de los ficheros.

En el tercer paso se procede al anlisis de los datos facilitados. El sistema mostrar un


breve mensaje por pantalla conforme vaya analizando entradas. Una vez finalice el anlisis,

97

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


mostrar sendos campos de edicin por cada entrada. Estos campos de edicin se
corresopnden con la totalidad de campos disponibles para una publicacin del tipo indicado,
mostrando el campo en blanco si no se inclua en los ficheros de texto iniciales.
En caso de que el sistema haya encontrado ficheros que se estimen coincidentes para la
publicacin, los mostrar en pantalla. Si se trata de varios ficheros, entonces los desglosar
en una lista con botones tipo radio para que el usuario seleccione el correcto. Si el usuario
no desea especificar fichero pdf alguno, entonces basta con que marque la casilla No
deseo especificar ningn fichero .pdf.
Tambin se muestran otras dos casillas de verificacin que son excluyentes: una la
marcar el usuario cuando desee actualizar la base de datos con esa publicacin (Active
esta casilla si la entrada ya est completa) y la otra la marcar cuando no desea incluirla en
la base de datos (En caso de no querer aadir esta entrada, active esta casilla).
Por supuesto, se permite al usuario cambiar el documento pdf en caso de que ninguno
de los encontrados sea correcto o en el caso de que no se haya encontrado ninguno.
Una vez el usuario haya realizado todas las modificaciones que desee, basta con que
pulse el botn Volver al paso 3 para que el sistema proceda con las actualizaciones. Este
paso se volver a mostrar tantas veces como sea necesario hasta que no queden entradas
que actualizar.

NOTA IMPORTANTE: se recomienda emplear ficheros de texto con no ms de 25


entradas. Aunque se ha modificado el tiempo de carga de las pginas a 30 minutos, los
datos generados por los formularios son excesivos y pueden generar un colapso del hilo
servidor que sirve las pginas.

10.2.2.2 E DITAR FICHERO

DE

D EFINICIN

DE

P UBLICACIONES .

Esta opcin del sistema permite al usuario acceder al fichero de definicin de


publicaciones. Este fichero es usado por el sistema para la generacin de referencias y para
la bsqueda de los documentos pdf.
Con esta opcin se presenta al usuario una caja de edicin de texto con el contenido de
dicho fichero, para que lo modifique a su conveniencia.
El fichero guarda un formato muy estricto. Existen dos zonas bien diferenciadas: la zona

98

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


de publicaciones de revistas y la zona de ponencias en congresos. El comienzo de cada una
de las zonas se encuentra indicado con ::JOURNALS y ::CONGRESS respectivamente.
En cada zona, el usuario puede definir tantas publicaciones como desee.
Cada publicacin requiere de dos lneas. La primera se utiliza para almacenar el nombre
completo de la publicacin. Esta lnea debe ir precedida de los caracteres de comentario //.
en la segunda lnea el usuario debe introducir las siglas o el acrnimo de la publicacin,
seguido de ; y un tabulador, y a continuacin debe escribir las palabras claves de la
publicacin separadas por tabuladores (las palabras claves son aquellas que se utilizarn en
la bsqueda de documentos posteriormente y en la generacin de referencias).
Una vez que se hayan realizado las modificaciones deseadas, basta con pulsar el botn
Actualizar fichero de definiciones y las modificaciones sern guardadas automticamente.

10.2.2.3 C REAR C OPIA

DE

S EGURIDAD

DE LA

B ASE

DE

D ATOS .

Esta opcin crea automticamente una copia de seguridad de la base de datos. Se


mostrar por pantalla un mensaje indicando la hora y la fecha en que se realiz la copia de
seguridad, as como el nombre del fichero que contiene la copia.

10.2.2.4 R ESTAURAR C OPIA

DE

S EGURIDAD

DE LA

B ASE

DE

D ATOS .

Aqu se presenta una tabla por pantalla que permite al usuario restaurar una copia de
seguridad creada previamente, as como borrarla. Para cada una de las copias de seguridad
se muestran la hora y la fecha de creacin, a fin de que el usuario proceda con la que ms
convenga.
La opcin Actualizar directorio de pdfs hace que el sistema, al actualizar la base de
datos, borre todos los documentos pdf que no se correspondan con entradas existentes en
la base de datos. Esto se incluye para prevenir futuros errores en que se actualicen entradas
que no tengan ficheros pdf y al no haber borrado los de una copia anterior se muestre un
fichero errneo.
En consecuencia, se recomienda restaurar una copia, y comprobar en el sitio web que se
ha restaurado la deseada. Si esto es as, entonces ya se puede proceder a restaurar esa
misma marcando la opcin de actualizacin del directorio de pdfs. Adems, tambin es
recomendable borrar las copias de seguridad con fecha y hora posterior a la restaurada, con

99

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


el fin de prevenir futuras complicaciones.

10.3 M ANUAL

DE

U SO : S ISTEMA

DE

C ONTROL R EMOTO .

10.3.1 INSTALACIN .
La ubicacin de cada uno de los programas es importante. Si no se tiene cuidado al
colocar los ejecutables se obtendrn errores adicionales. A continuacin se especifica la
correcta ubicacin de cada uno de ellos (NOTA: todos los ficheros aqu especificados se
encuentran en el directorio Final del CD-Rom que acompaa esta memoria):

Aplicacin de conversin de formato grfico "convert.exe": debe encontrarse en el

mismo directorio que la aplicacin de Matlab "sendtoservigar.m".

Aplicacin

de

Matlab:

esta

aplicacin

es

un

fichero

con

nombre

"sendtoservigar.m". Debe situarse en el directorio de trabajo donde se encuentre el


fichero de modelo de Simulink que contiene el controlador a implementar el control
remoto. La ejecucin es muy simple. Basta con escribir "sendtoservigar" en la lnea
de comandos de Matlab (con cuidado de estar situados en el mismo directorio en
que se encuentra "sendtoservigar.m"), y la secuencia a seguir una vez invocado el
script es la siguiente:

Insercin del nombre del fichero de modelo de Simulink (con o sin extensin

".mdl").

Esperar a la finalizacin del programa.

Durante el transcurso de la ejecucin, la aplicacin ir mostrando por pantalla los


distintos avances que irn sucediendo, como son la deteccin del fichero de
modelado, la obtencin de su representacin, la conversin del formato grfico o el
envo sucesivo de los ficheros al servidor sito en Servigar.

Interfaz web en Servigar: es la pgina web que contiene la interfaz de

modificacin remota de los parmetros. El resultado de la compilacin de esta pgina


ha de ubicarse en el directorio web en el que se proporcione el servicio de hosting
de pginas (depende del servidor web instalado, por ejemplo, Apache Server o
Internet Information Server, y de su configuracin). En este punto hay que tener en
cuenta que la interfaz web se dise para su interfuncionamiento con el sitio web de

100

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


la Planta Solar encuadrada en el proyecto europeo Hycon. Este hecho indica que el
sistema de validacin es el que usaba dicho sitio web. Si se desea utilizar en otro
mbito, ser necesario modificar la programacin de dicha interfaz para adecuarla a
las nuevas condiciones de trabajo.

Aplicacin servidor en Servigar "cp_server_servigar.exe": debe ubicarse en la

misma carpeta que la pgina "tunning.aspx", que es la que implementa la interfaz


web para cambiar remotamente los parmetros. El funcionamiento de este servidor
es sencillo: una vez ejecutado, mostrar por pantalla un mensaje indicando que si se
escribe la palabra "exit" se detendr la ejecucin del mismo, dando a entender que
se ejecutar de forma indefinida si el usuario no escribe la orden correspondiente. El
servidor se quedar a la escucha de peticiones en el puerto designado y cuando
reciba alguna lo mostrar por pantalla.

Aplicacin cliente en Neoxite "cp_client_neoxite.exe": esta aplicacin debe

ubicarse en la misma carpeta que el script de Matlab "sendtoservigar.exe", ya que


ste lo utiliza para el envo de ficheros al servidor ubicado en Servigar. En teora el
usuario no necesita saber de la ejecucin de este cliente, puesto que lo invoca la
misma aplicacin "sendtoservigar.m".

Aplicacin servidor en Neoxite "cp_server_neoxite.exe": debe ubicarse en el

mismo directorio en que se est ejecutando el fichero del modelo de Simulink, puesto
que en dicho directorio se crear el fichero .log que se utilizar para alterar los
valores de los parmetros. El funcionamiento de este servidor es, al igual que el
situado en Servigar, bastante sencillo: una vez ejecutado, mostrar por pantalla un
mensaje indicando que si se escribe la palabra "exit" se detendr la ejecucin del
mismo, dando a entender que se ejecutar de forma indefinida si el usuario no
escribe la orden correspondiente. El servidor se quedar a la escucha de peticiones
en el puerto designado y cuando reciba alguna lo mostrar por pantalla.

10.3.2 U SANDO

EL

C ONTROL R EMOTO .

1) Se situarn los siguientes ficheros en el directorio %MATLAB_PATH%/work/ en el


ordenador que implementar el controlador:

101

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

convert.exe
cp_client_neoxite.exe
cp_server_neoxite.exe
tunning.c
tunning.txt
params.mdl
sendtoservigar.m

El fichero tunning.txt es un fichero de texto que contiene una lista de asignacin de


valores a las variables cuyos valores se podr cambiar, con las asignaciones separadas por
retornos de carro.
Se situarn los siguientes ficheros en el directorio . /Files/Simulink/ de la interfaz web
diseada (en la ruta relativa al directorio en el que se encuentra el fichero de la interfaz) en
el ordenador que implementar la interfaz web:

cp_server_servigar.exe

2) Lo siguiente a realizar es la compilacin del bloque de modificacin remota de


parmetros. Desde la lnea de comandos de Matlab se escribir:
mex tunning.c

A continuacin se configurar el fichero de modelo de Simulink tal y como se describe en


el punto 3.2.3.1. Una vez hecho esto, ya nos encontramos en condiciones de generar el
ejecutable. Para hacer esto, presionamos sobre el botn Build All de la ventana de
Simulink.

Una

vez

terminada

la

compilacin

se

habr

generado

una

carpeta

params_grt_rtw que contendr todo el cdigo fuente del ejecutable generado, mientras que
el ejecutable se encontrar en la misma carpeta que el modelo de Simulink.
3) Antes de proceder a la ejecucin del modelo, se han de arrancar los distintos
servidores que deben quedarse a la espera de peticiones en los puertos. Por tanto, en este
paso se ejecutan los ejecutables cp_server_neoxite.exe y cp_server_servigar.exe en los
ordenadores que implementan el control con Matlab (en adelante, servidor matlab) y la
interfaz web (en adelante, servidor web) respectivamente.
4) El operario encargado de ejecutar el controlador pondr en marcha el sistema,
invocando "sendtoservigar.m" desde la lnea de comandos de Matlab. Esta aplicacin se
comunicar con el servidor web y llevar a cabo la puesta a punto del sistema. Una vez
configurado el sistema, el operario ejecutar el controlador del usuario, no sin antes haber
arrancado el ejecutable servidor del modo externo generado en el paso 2. Para ello, el
operario abrir una ventana de comandos de Windows (una consola) en el servidor Matlab,
se desplazar al directorio donde se encuentra dicho ejecutable para el modo externo y una
vez ubicado en dicha carpeta ejecutar el siguiente comando:

102

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


params -tf inf -w

La opcin -tf establece el tiempo final de la ejecucin en tiempo real. Con inf se
indica que se desea que el tiempo de ejecucin sea infinito. La opcin -w se utiliza para
esperar el mensaje de bienvenida del host, esto es, que no se empieza a ejecutar hasta que
un cliente se conecta con el fichero del modo externo.
Lo siguiente ser, como ya se dijo anteriormente, ejecutar el controlador del usuario.
Para ello, se abre el modelo del controlador en Simulink, se escoge el modo externo en la
lista desplegable superior y se presiona sobre el botn que hay justamente a la izquierda de
la lista, que muestra como ayuda emergente al posar el ratn sobre l Connect to target.
Esto conectar el modelo con el ejecutable que se ha arrancado antes. Una vez conectado,
ya solamente resta pulsar en el botn Start real-time code, situado a la izquierda del
anterior.
En caso de que el usuario desee modificar algn valor en el bloque de modificacin de
parmetros, debe validarse en la interfaz web, tras lo cual tendr acceso a la interfaz y ver
los valores actuales de los parmetros de su controlador, modifcando aquellos que no le
plazcan. En este momento, tras pulsar el botn de actualizar dichos valores, la interfaz web
se comunicar con el servidor Matlab para modificar el fichero de intercambio de datos, de
forma que el bloque de modificacin de parmetros pueda actualizar los nuevos valores.

10.4 C DIGO FUENTE .

10.4.1 S ISTEMA

DE

A CTUALIZACIN

DE

B ASE S

DE

D ATOS .

10.4.1.1 U PDATE .HTML


<html>
<head>
<script type="text/javascript">
function assign()
{
document.getElementById("login").value =
document.getElementById("user").value;
document.getElementById("pass").value =
document.getElementById("password").value;
}
function assign_pubs()
{
document.getElementById("login_pubs").value =

103

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


document.getElementById("user").value;
document.getElementById("pass_pubs").value =
document.getElementById("password").value;
}
</script>
</head>
<body>
<table align=center>
<form name="validacion" action="paso1.php" method="post">
<tr>
<td colspan=2 align="center"> <img src="images/backup.jpg"> </td>
</tr>
<tr>
<td colspan=2> <br> </br> </td>
</tr>
<tr>
<td width="50%" align=right>Login:&nbsp&nbsp&nbsp&nbsp&nbsp</td>
<td width="50%"><input type="text" id="user" name="user"></td>
</tr>
<tr>
<td width="50%" align=right>Contrasea:&nbsp&nbsp&nbsp&nbsp&nbsp</td>
<td width="50%">
<input type="password" id="password" name="password">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" id="update" name="update"
value="Actualizar base de datos">
</td>
</tr>
</form>
<form name="edit_pubs" action="pubs_editor.php" method="post">
<tr>
<td colspan=2 align="center">
<input type="submit" id="edit_pub_file" name="edit_pub_file"
value="Editar fichero de definicin de publicaciones"
onclick="assign_pubs();" />
<input type="hidden" id="login_pubs" name="login" value="" />
<input type="hidden" id="pass_pubs" name="pass" value="" />
</td>
</tr>
</form>
<form name="validacion" action="backup.php" method="post">
<tr>
<td colspan=2 align="center">
<input type="submit" id="create_backup" name="create_backup"
value="Crear copia de seguridad de la base de datos"
onclick="assign();" />
</td>
</tr>
<tr>
<td colspan=2 align="center">
<input type="submit" id="restore_backup" name="restore_backup"
value="Restaurar copia de seguridad de la base de datos"
onclick="assign();" />
<input type="hidden" id="login" name="login" value="" />
<input type="hidden" id="pass" name="pass" value="" />
</td>
</tr>
</form>
<tr>
<td colspan=2> <br> </br> </td>
</tr>

104

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


<tr>
<td colspan=2 align="center">
<img src="images/php_icon.png"> </img>
<img src="images/mysql_icon.gif"> </img>
<img src="images/apache_icon.gif" height="52"> </img>
</td>
</tr>
</table>
</body>
</html>

10.4.1.2 P ASO 1.PHP


<?php
include "functions.inc.php";
$conexion_mysql =& conecta_db();

// Conexin con la base de datos

if (valida_usuario($_POST["user"], $_POST["password"])) {
// Inicio de sesin y envo de los datos del usuario para validar en los
// subsiguientes pasos
session_start();
$_SESSION["user"] = $_POST["user"];
$_SESSION["password"] = $_POST["password"];
// Mensaje de bienvenida
print "\t<h2>Actualizacin automtica de la Base de Datos</h2><br />" .
"Hola, usuario \"" . $_POST["user"] . "\".<br />" .
"Bienvenido al script de actualizacin automtica de la base de datos " .
"del sitio web del Grupo de Control Predictivo.<br /><br />\n\t<h3>" .
"Paso 1: Introduccin de los ficheros de actualizacin y seleccin " .
"de las bases de datos a actualizar:</h3><br />";
$tablas_db = lista_tablas();
info_campos($tablas_db, $tipo_campos_tablas, $nombre_campos_tablas);
// Impresin del formulario de alta de ficheros y seleccin de tablas en el
// navegador
echo "\t<form name='upload' id='upload' action='paso2.php' " .
"ENCTYPE='multipart/form-data' method='POST'>\n";
echo "\t\t<table border='0'>\n";
$max_campos = 0;
for ($i=0;$i<count($tablas_db);$i++)
if ($max_campos < count($nombre_campos_tablas[$i]))
$max_campos = count($nombre_campos_tablas[$i]);
// Se imprime una fila de la tabla por cada tabla existente en la base de
// datos.
echo "\t\t\t<tr>\n";
echo "\t\t\t\t<td width='620px' align=center>Seleccione aqu los ficheros " .
"que contengan las actualizaciones:</td>\n";
echo "\t\t\t\t<td width='100px'>Tabla a actualizar:</td>\n";
echo "\t\t\t</tr>\n";
for ($i=0;$i<count($tablas_db);$i++) {
// Nueva fila
echo "\t\t\t<tr>\n";
// 1 columna => Campo de texto para escribir el nombre del fichero con las
// actualizaciones.
echo "\t\t\t\t<td width='620px'>\n";
echo "\t\t\t\t\t<input type='file' id='fichero" . $i .
"' name='fichero" . $i . "' size=80 />\n";
echo "\t\t\t\t</td>\n";
// 2 columna => Lista desplegable para seleccionar la base de datos que se
// actualizar.

105

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "\t\t\t\t<td>\n";
echo "\t\t\t\t\t<select name='tabla" . $i . "'>\n";
echo "\t\t\t\t\t\t<option value=''></option>\n";
for ($k=0;$k<count($tablas_db);$k++)
echo "\t\t\t\t\t\t<option value='" . $tablas_db[$k] . "'>"
. $tablas_db[$k] . "</option>\n";
echo "\t\t\t\t\t</select>\n";
echo "\t\t\t\t</td>\n";
// 3 columna => Lista desplegable para seleccionar el tipo de libro en caso
// de tener que modificarse la tabla "books".
echo "\t\t\t</tr>\n";
}
// Campo de texto para las urls
echo "\t\t\t<tr><td align=center colspan='" . $max_campos . "'><br>" .
"Inserte aqu las direcciones webs desde las que se pueden actualizar " .
"los campos:<br>(NOTA: Separe las rutas mediante retornos de carro)" .
"<textarea name=webs id=webs rows=10 cols=86></textarea></td></tr>\n";
// Campo de texto para los directorios
echo "\t\t\t<tr><td align=center colspan='" . $max_campos . "'><br>" .
"Inserte aqu los directorios que contengan ficheros .pdf para insertar " .
"en la base de datos:<br>(NOTA: Separe las rutas mediante retornos " .
"de carro)<textarea name=dirs id=dirs rows=10 cols=86></textarea>" .
"</td></tr>\n";
echo "\t\t\t<tr><td colspan='" . $max_campos . "'>(NOTA: Se buscarn " .
"ficheros que contengan en su nombre las tres partes clave de la " .
"referencia de la base de datos, esto es, el apellido del autor " .
"principal, las siglas de la publicacin y el ttulo del " .
"artculo/congreso).</td></tr>\n";
echo "\t\t</table>\n";
echo "\t\t<input type=submit value='Ir al paso 2' />\n";
echo "\t</form>\n";
desconecta_db($conexion_mysql);
}
else {
echo "Error en el nombre de usuario o en la contrasea.<br />Por favor, " .
"vuelva a la pantalla de validacin.<br />";
echo "<a href=\"./update.html\">Pgina de validacin</a>";
}
?>

10.4.1.3 P ASO 2.PHP


<?php
include "functions.inc.php";
session_start();
error_reporting(0);
$conexion_mysql =& conecta_db();

// No se reporta ningn tipo de error


// Conexin con la base de datos

// Validacin del usuario


if (valida_usuario($_SESSION["user"], $_SESSION["password"])) {
// Tamao, tipo y extensin permitidos para los ficheros a subir
//*******************************************************
$MAX_SIZE = 2000000;
$FILE_MIMES = array('text/plain');
$FILE_EXTS = array('.txt');
// Variables de configuracin
//*******************************************************
$site_name = $_SERVER['HTTP_HOST'];
$url_dir = "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
$url_this = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
$upload_dir = "temp/";

106

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$upload_url = $url_dir."/temp/";
$message = "";
// Obtencin de las variables necesarias de la base de datos
$tablas_db = lista_tablas();
info_campos($tablas_db, $tipo_campos_tablas, $nombre_campos_tablas);
$max_campos = 0;
$max_adds = 0;
for ($i=0;$i<count($tablas_db);$i++)
{
$num_campos_tabla = 0;
$encontrada = false;
for ($j=0; $j<count($tablas_db); $j++)
{
if ($tablas_db[$j] == $_POST["tabla".$i])
{
$encontrada = true;
$cont = $j;
}
}
if ($encontrada == true)
{
$num_campos_tabla = count($nombre_campos_tablas[$cont]);
$num_campos_adds = 0;
for ($j=0; $j<count($tabla_campos_adicionales); $j++)
if (($tabla_campos_adicionales[$j] == $tablas_db[$cont]) ||
($tabla_campos_adicionales[$j] == "all"))
$num_campos_adds++;
if ($max_campos < $num_campos_tabla + $num_campos_adds)
$max_campos = $num_campos_tabla + $num_campos_adds;
}
}
// Directorio temporal de subida para la copia local
if (!is_dir("temp")) {
if (!mkdir($upload_dir))
die ("Directorio de subida no existe y su creacin fall");
if (!chmod($upload_dir,0755))
die ("Cambio de permisos a 755 fallido.");
}
// Vaciado del directorio temporal
borra_dir_temp($upload_dir);
// Copia local de los ficheros de actualizacin en el directorio TEMP
for ($i=0;$i<count($tablas_db);$i++) {
if ($_FILES["fichero" . $i]) {
$file_type = $_FILES["fichero" . $i]["type"];
$file_name = $_FILES["fichero" . $i]["name"];
$file_ext = strtolower(substr($file_name,strrpos($file_name,".")));
//Comprobacin del tamao del fichero
if ( $_FILES["fichero" . $i]["size"] > $MAX_SIZE)
$message = "Los ficheros deben tener un tamao mximo de 2MB.";
//Comprobacin del tipo y extensin del fichero
else if (!in_array($file_type, $FILE_MIMES) &&
!in_array($file_ext, $FILE_EXTS) )
$message = "Lo sentimos mucho, no se permite subir " .
$file_name . "(" . $file_type . ").";
else
$message = do_upload("fichero".$i, $upload_dir, $upload_url);
}
else if (!$_FILES["fichero" . $i])
$message = "Fichero especificado no vlido.";
}

107

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Mensaje de bienvenida
print "<html>\n";
print "\t<head>\n";
print "\t</head>\n";
print "\t<body>\n";
print "\t\t<h2>Actualizacin automtica de la Base de Datos</h2><br />" .
"\n\t\t<h3>Paso 2: Seleccin de los campos que aparecen en los ficheros " .
"de actualizacin.</h3><br />\n\t\tA continuacin se muestran, separados " .
"mediante barras horizontales, los ficheros indicados en el paso 1, as " .
"como las tablas asociadas seleccionadas. En este paso el usuario deber " .
"seleccionar los campos que se detallan en el fichero de actualizacin, y" .
" en el mismo orden en que stos aparecen.<br />\n\t\tPor ltimo, se " .
"seleccionar el tipo de documento (en caso de que la tabla a modificar " .
"sea \"books\"), indicando si se trata de un libro normal o un libro de " .
"actas, as como los separadores de campos y de filas empleados en el " .
"fichero.<br /><br />\n";
// Impresin del formulario de seleccin de campos del fichero de
// actualizacin
//********************************************************************
echo "\t\t<form name='upload' id='upload' action='paso3.php' " .
"ENCTYPE='multipart/form-data' method='POST'>\n";
// Ahora se muestran los conjuntos de listas desplegables para seleccionar los
// campos que contienen los ficheros subidos al servidor
echo "\t\t\t<table width=100%>\n";
for ($i=0;$i<count($tablas_db);$i++) {
$num_campos_adicionales = 0;
$num_campos_undef = 0;
// Una nueva fila por cada fichero introducido y tabla seleccionada
if (($_FILES["fichero".$i]["name"] != "") && ($_POST["tabla".$i] != "")) {
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=" . $max_campos .
">Fichero \"" . $_FILES["fichero" . $i]["name"] .
"\" => Tabla \"" . $_POST["tabla" . $i] . "\"</td>\n";
// Se imprimen los campos adicionales que correspondan
for ($j=0; $j<count($lista_campos_adicionales); $j++)
if (($tabla_campos_adicionales[$j] == "all") ||
($tabla_campos_adicionales[$j] == $_POST["tabla".$i]))
$num_campos_adicionales++;
// Se imprimen los separadores que correspondan
for ($j=0; $j<count($lista_campos_undef); $j++)
{
if (($tabla_campos_undef[$j] == "all") ||
($tabla_campos_undef[$j] == $_POST["tabla".$i]))
{
echo "\t\t\t\t\t<td>" . ucwords($lista_campos_undef[$j]) .
"</td>\n";
$num_campos_undef++;
}
}
echo "\t\t\t\t</tr>\n";
echo "\t\t\t\t<tr>\n";
$indice_tabla = 0;
for ($j=0;$j<count($tablas_db);$j++)
if ($tablas_db[$j] == $_POST["tabla" . $i])
$indice_tabla = $j;
// Numero de campos de esta tabla (no se cuenta el id)
$n_campos = count($nombre_campos_tablas[$indice_tabla]) 1;
// Numero de campos adicionales de esta tabla
$n_adds = 0;
for ($j=0; $j<count($tabla_campos_adicionales); $j++)
if (($tabla_campos_adicionales[$j] == $tablas_db[$indice_tabla]) ||
($tabla_campos_adicionales[$j] == "all"))
$n_adds++;
for ($j=0; $j<$max_campos; $j++) {
// Se aaden los elementos de la tabla en cuestin (inclusive los

108

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// adicionales)
if ($j < $n_campos + $n_adds){
echo "\t\t\t\t\t<td>\n";
echo "\t\t\t\t\t\t<select name='campo" . $i . "-" . $j . "'>\n";
echo "\t\t\t\t\t\t\t<option value=''></option>\n";
for ($k=1;$k<=(count($nombre_campos_tablas[$indice_tabla]));$k++) {
if ($k < count($nombre_campos_tablas[$indice_tabla]))
echo "\t\t\t\t\t\t\t<option value='"
. $nombre_campos_tablas[$indice_tabla][$k] . "'>"
. $nombre_campos_tablas[$indice_tabla][$k] . "</option>\n";
else
for ($m=0; $m<count($lista_campos_adicionales); $m++)
if (($tabla_campos_adicionales[$m] == "all") ||
($tabla_campos_adicionales[$m] == $_POST["tabla".$i]))
{
echo "\t\t\t\t\t\t\t<option value='"
. $var_campos_adicionales[$m]
. "'>" . $var_campos_adicionales[$m]
. "</option>\n";
}
}
echo "\t\t\t\t\t\t</select>\n";
echo "\t\t\t\t\t</td>\n";
}
// Se aaden las celdas vacas que resten hasta el nmero mximo de
// campos
else
echo "\t\t\t\t\t<td>\n\t\t\t\t\t</td>\n";
}
// Se muestran los campos interactivos que correspondan
for ($j=0; $j<count($lista_campos_undef); $j++)
{
if (($tabla_campos_undef[$j] == "all") ||
($tabla_campos_undef[$j] == $_POST["tabla".$i]))
{
echo "\t\t\t\t\t<td>\n";
echo "\t\t\t\t\t\t<select name='" . $var_campos_undef[$j]
. $i . "'>\n";
echo "\t\t\t\t\t\t\t<option value=''></option>\n";
for ($k=0; $k<count($desc_campos_undef[$lista_campos_undef[$j]]);
$k++)
echo "\t\t\t\t\t\t\t<option value='" .
$valores_campos_undef[$lista_campos_undef[$j]][$k]
. "'>" . $desc_campos_undef[$lista_campos_undef[$j]][$k]
. "</option>\n";
echo "\t\t\t\t\t\t</select>\n";
echo "\t\t\t\t\t</td>\n";
}
}
// Lnea horizontal para separar los distintos ficheros de actualizacin
echo "\t\t\t\t</tr>\n";
$longitud = $max_campos+4;
for ($k=0;$k<count($tablas_db);$k++)
if ($_POST["tabla".$k] == "books")
$longitud++;
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=" . $longitud .
"><hr /></td>\n";
echo "\t\t\t\t</tr>\n";
}
}
//
//
//
//

Se muestran las direcciones que se insertaron en el paso previo (se


comprueba que son direcciones vlidas, esto es, que direccionen a un
documento html, php, ..., pero no un nombre de dominio, y que stas existan
y se puedan leer)

109

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=" . $longitud . ">\n";
echo "\t\t\t\t\t\tDirecciones que se utilizarn para actualizar la base de " .
"datos:\n";
$tok = strtok($_POST["webs"], "\n");
$i = 0;
echo "\t\t\t\t\t\t<ul>\n";
$exts = array(".html", ".htm", ".php", ".asp", ".aspx");
while ($tok !== false) {
// Comprobaciones previas
$error = "";
$address = trim($tok);
$pos_site = strlen($address);
$pos_barra = strrpos(substr($address, 0, $pos_site), "/");
// Caso en que la direccin termina en barra invertida => ERROR
if ($pos_barra == $pos_site)
$error = "La direccin debe apuntar a un documento, no un directorio " .
"o nombre de dominio.";
else {
$last_part = substr($address, $pos_barra + 1);
$found = false;
// Se busca una de las terminaciones permitidas
for ($j=0; $j<count($exts); $j++)
if (strpos($last_part, $exts[$j]) !== false)
$found = true;
// Si la direccin no apunta a un documento con extensin permitida
if ($found == false)
$error = "La direccin debe apuntar a un documento, no un " .
"directorio o nombre de dominio.";
else {
$desc_read = fopen($address, "rb");
if ($desc_read == FALSE)
$error = "La direccin indicada no existe o no se puede acceder " .
"a ella.";
}
}
// En caso de error se muestra un mensaje en pantalla pero no se enva como
// campo oculto la direccin facilitada
if ($error != "")
// En caso de xito, se muestra la direccin por pantalla y se enva como
// campo oculto
echo "\t\t\t\t\t\t\t<li>" . $address . "\n\t\t\t\t\t\t\t\t"
"<ul>\n\t\t\t\t\t\t\t\t\t<li>Error: ".$error."\n\t\t\t\t\t\t\t\t\t" .
"</li>\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</li>\n";
else {
echo "\t\t\t\t\t\t\t<li>" . $address . "</li>\n";
echo "\t\t\t\t\t\t\t<input type=hidden name='url" . $i . "' value='" .
$address . "' />\n";
$i++;
}
$tok = strtok("\n");
}
echo "\t\t\t\t\t\t</ul>\n";
echo "\t\t\t\t\t\tNOTA: Las pginas que hayan generado errores no se " .
"tendrn en cuenta para la actualizacin. Si desea que se tengan en " .
"cuenta, vuelva al paso anterior y solucione los problemas que " .
"puedan existir.\n";
echo "\t\t\t\t\t</td>\n";
echo "\t\t\t\t</tr>\n";
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=" . $longitud . "><hr /></td>\n";
// Se muestran los directorios insertados en el paso previo
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=" . $longitud . ">\n";
echo "\t\t\t\t\t\tDirectorios que se utilizarn para actualizar la base de" .
"datos:\n";
$tok = strtok($_POST["dirs"], "\n");
$i = 0;

110

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "\t\t\t\t\t\t<ul>\n";
while ($tok !== false) {
$directory = trim($tok);
if (is_dir($directory) == false)
echo "\t\t\t\t\t\t\t<li>" . stripslashes($directory) .
"\n\t\t\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t\t\t<li>Error: El " .
"directorio no existe o no se puede acceder a l.\n\t\t\t\t\t\t\t\t\t"
. "</li>\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t</li>\n";
else {
echo "\t\t\t\t\t\t\t<input type=hidden name='dir" . $i . "' value='" .
stripslashes($directory) . "' />\n";
echo "\t\t\t\t\t\t\t<li>" . stripslashes($directory) . "</li>\n";
$i++;
}
$tok = strtok("\n");
}
echo "\t\t\t\t\t\t</ul>\n";
echo "\t\t\t\t\t\tNOTA: Los directorios que hayan generado errores no se
" tendrn cuenta para la actualizacin. Si desea que se tengan en cuenta," .
" vuelva al paso anterior y solucione los problemas que puedan existir.\n";
echo "\t\t\t\t\t</td>\n";
echo "\t\t\t\t</tr>\n";
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=" . $longitud . "><hr /></td>\n";
echo "\t\t\t\t</tr>\n";
echo "\t\t\t</table>\n";
echo "\t\t\t<br />\n";
// Insertamos el conjunto de parmetros ocultos, a saber, los nombres de las
// tablas a actualizar y ficheros a utilizar
for ($i=0;$i<count($tablas_db);$i++) {
if (($_FILES["fichero".$i]["name"] != "") && ($_POST["tabla".$i] != "")) {
echo "\t\t\t<input type=hidden name='tabla" . $i . "' value='" .
$_POST["tabla".$i] . "' />\n";
echo "\t\t\t<input type=hidden name='fichero" . $i . "' value='" .
$_FILES["fichero".$i]["name"] . "' />\n";
}
}
echo "\t\t\t<input type=submit value='Ir al paso 3' />\n";
echo "\t\t\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n";
echo "\t\t\t<a href=\"/groupweb/help.html\" target=\"popup\" " .
"onClick=\"window.open('/groupweb/help.html', 'window', " .
"'width=600,height=400,resizable=1,scrollbars=1'); return " .
"false;\">Ayuda</a>\n";
echo "\t\t</form>\n";
echo "\t</body>\n";
echo "</html>\n";
desconecta_db($conexion_mysql);
}
else {
echo "Error en el nombre de usuario o en la contrasea.<br />Por favor, " .
"vuelva a la pantalla de validacin.<br />";
echo "<a href=\"./update.html\">Pgina de validacin</a>";
}
?>

10.4.1.4 P ASO 3.PHP


<?php
include "functions.inc.php";
include "functions.step3.php";
session_start();
$conexion_mysql =& conecta_db();
unset($sentencias_SQL);

// Conexin con la base de datos

111

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


unset($sentencia_SQL);
unset($congresos);
unset($revistas);
unset($table_type);
unset($titulo);
unset($ind_sql);
unset($referencia);
// Cambiamos el tiempo mximo de respuesta, porque esto tarda bastante
ini_set("max_execution_time", "1800");
// No se reporta ningn tipo de error
error_reporting(0);
// Validacin del usuario
if (valida_usuario($_SESSION["user"], $_SESSION["password"])) {
// Declaracin y definicin de variables
$pubs_file = "pubs.txt";
$log_file = "pdf_log.txt";
$campo_def_add = array(
"tabla" => 0,
// Tabla que actualizar esta entrada
"error" => 1,
"pdf" => 2,
// Direccin web del fichero pdf
// [0] => direccion
// [1] => porcentaje
"finished" => 3,
// Bandera para saber si se ha terminado esta entrada
"authors" => 4,
"sep_authors" => 5,
// Separador para los autores
"supervisors" => 6,
// Supervisores
"sep_supervisors" => 7); // Separador de los supervisores
$def_offset = count($campo_def_add);
// Array con los mensajes de error que se contemplan
$mensajes_error = array(
"congreso" => "No se ha podido completar el campo \"reference\" debido a " .
"que se desconoce el congreso.",
"revista" => "No se ha podido completar el campo \"reference\" debido a " .
"que se desconoce la revista.",
"fecha" => "Es obligatorio especificar al menos los campos \"authors\", " .
"\"title\", el nombre de publicacin/congreso y la fecha de " .
"publicacin. No se ha especificado la fecha de publicacin, por lo " .
"que no se puede generar el campo \"reference\".",
"autores" => "Es obligatorio especificar al menos los campos \"authors\"" .
", \"title\", el nombre de publicacin/congreso y la fecha de ".
"publicacin. No se han especificado los autores, por lo que no se " .
"puede generar el campo \"reference\".",
"titulo" => "Es obligatorio especificar al menos los campos \"authors\", " .
"\"title\", el nombre de publicacin/congreso y la fecha de " .
"publicacin. No se ha especificado el ttulo de la publicacin.");
// Array de nmeros romanos para los ttulos de artculos y ponencias, para
// ponerlos todos en maysculas
$numbers = array("I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X",
"XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX",
"XXI", "XXII", "XXIII", "XXIV", "XXV", "XXVI", "XXVII", "XXVIII", "XXIX",
"XXX", "XXXI", "XXXII", "XXXIII", "XXXIV", "XXXV", "XXXVI", "XXXVII",
"XXXVIII", "XXXIX", "XL", "XLI", "XLII", "XLIII", "XLIV", "XLV", "XLVI",
"XLVII", "XLVIII", "XLIX", "L");
$letra = array("b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
// Array de acrnimos y siglas que deben ir en maysculas
$mayusc = array("IEEE", "CD", "HTTP", "OPC", "ROM");
// Array asociativo del tipo de publicacin con el entero que le corresponde
$tipo_publicacion = array(
"congress" => 1,
"journals" => 2,
"pfcs" => 3,
"phds" => 4,
"books" => 5);

112

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$ind_sql = 0;
$temp_dir = "temp/";
$catalogo_sep = array("\n","\r","\r\n","\t",";",":",",",".");
//Comprobacin de la variable "FORMULARIO". Si sta se encuentra definida,
//quiere decir que se est redireccionando a esta pgina desde ella misma para
//actualizar el fichero de las publicaciones conocidas. Esta modificacin ha
//de hacerse antes que cualquier consulta al mismo.
$formulario = 0;
if (isset($_POST["formulario"]))
$formulario = $_POST["formulario"];
else
$formulario = 0;
// Recuperacin de informacin de la base de datos.
$conexion_mysql = conecta_db();
$tablas_db = lista_tablas();
info_campos($tablas_db, $tipo_campos_tablas, $nombre_campos_tablas);
info_campos_asoc($tablas_db, $tipo_campos, $campos_tablas);
// Insercin de los campos especificados en $lista_campos_undef en arrays con
// nombres especificados en $var_campos_undef
//**************************************************************************
$max_campos = 0; // Nmero mximo de campos
for ($i=0;$i<count($tablas_db);$i++)
if ($max_campos < count($nombre_campos_tablas[$i]))
$max_campos = count($nombre_campos_tablas[$i]);
for ($i=0;$i<count($tablas_db);$i++)
{
for ($k=0; $k<count($var_campos_undef); $k++)
{
$var_name = $var_campos_undef[$k];
$$var_name = array();
}
}
// Extraccin de los campos que se han de actualizar,
// los separadores e informacin diversa
$indice_tablas = 0; // ndice para recorrer todas las tablas de
// la base de datos
$campos_update[0][0] = "";
for ($i=0; $i<count($tablas_db); $i++) {
if (isset($_POST["tabla" . $i]) && isset($_POST["fichero" . $i]) &&
($_POST["tabla" . $i] != "") && ($_POST["fichero" . $i] != ""))
{
$nombre_tablas[$indice_tablas] = $_POST["tabla" . $i];
$nombre_ficheros[$indice_tablas] = $_POST["fichero" . $i];
if (($_POST["tabla" . $i] != "sent") &&
($_POST["tabla" . $i] != "authors") &&
($_POST["tabla" . $i] != "people"))
{
$dependencias[$indice_tablas] = "authors";
}
// Los separadores necesitan un procesado especial, y en realidad se pasa
// el ndice de una tabla en la que buscar el separador
for ($k=0; $k<count($var_campos_undef); $k++)
array_push($$var_campos_undef[$k],
$catalogo_sep[$_POST[$var_campos_undef[$k] . $i]]);
for ($j=0; $j<$max_campos; $j++) {
if ($_POST["campo" . $i . "-" . $j] != "") {
$campos_update[$indice_tablas][$j] =
$_POST["campo" . $i . "-" . $j];
}
}

113

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$indice_tablas++;
}
}
// ACTUALIZACIN DEL FICHERO DE PUBLICACIONES EN CASO DE REDIRECCIONAMIENTO DE
// LA PGINA
//****************************************************************************
if (isset($_POST["errores"]))
// Obtencin del nmero de publicaciones desconocidas
$n_unknown = $_POST["errores"];
else
$n_unknown = 0;
$added_entries = 0;
$mod_entries = 0;
$processed = 0;
$new_pubs[$added_entries]["tabla_modif"] = "";
$pubs_mod[0] = "";
if ($formulario == 1) {
// Editamos el fichero "pubs.txt" para aadir las revistas ingresadas
$j = 0;
unset($parte_nueva);
while ($processed < $n_unknown) {
$tabla_actual = $_POST["tabla_modif" . $j];
// Si los parmetros son correctos.... (esto es,
// que no hayan dejado ninguno de los campos vacos)
if (isset($_POST["comment" . $j]))
{
if (($_POST["comment" . $j] != "") &&
($_POST["abbrev" . $j] != "") &&
($_POST["keywords" . $j] != ""))
{
// Se almacenan los datos necesarios para actualizar
// otra publicacin cualquiera con el mismo error
$new_pubs[$added_entries]["tabla_modif"] =
$_POST["tabla_modif" . $j];
$indice = 0;
if ($tabla_actual == "journals")
for ($l=0; $l<count($campos_tablas[$tabla_actual]); $l++)
if ($campos_tablas[$tabla_actual][$l] == "journal")
$indice = $l;
else if ($tabla_actual == "congress") {
for ($l=0; $l<count($campos_tablas[$tabla_actual]); $l++)
if ($campos_tablas[$tabla_actual][$l] == "booktitle")
$indice = $l;
}
$new_pubs[$added_entries]["nombre"] =
$_POST["campos_def" . $j . "-" . ($indice + $def_offset)];
$new_pubs[$added_entries]["abbrev"] = $_POST["abbrev" . $j];
// Obtenemos los parmetros de la nueva publicacin
$comentario = $_POST["comment" . $j];
$siglas = $_POST["abbrev" . $j];
$claves = $_POST["keywords" . $j];
// ....se procede a realizar una copia del
// contenido del fichero de publicaciones
$archivo = fopen("pubs.txt", "r+t");
$contenido = fread($archivo, filesize("pubs.txt"));
fclose($archivo);
// Entrada a buscar en el contenido
$cadena = "::".strtoupper($_POST["tabla_modif".$j]);
// En caso de que se encuentre la entrada de
// insercin, se procede a crear la cadena a insertar
if (stripos(" ".$contenido, $cadena)) {
// Separamos las palabras claves mediante tabuladores
$palabra = quita_tildes(trim(strtolower(strtok($claves, " "))));
$k = -1;
unset($claves_separadas);

114

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


while ($palabra != FALSE) {
$k++;
$claves_separadas = $claves_separadas . "\t" . $palabra;
$palabra = strtok(" ");
}
// PARTE_NUEVA es la cadena referente a la nueva publicacin
$parte_nueva = "\n// " . $comentario . "\n" . strtoupper($siglas)
. ";" . $claves_separadas . "\n";
// Actualizamos el contenido total del fichero
$contenido = substr($contenido, 0, stripos(" " .
$contenido, $cadena) -1 + strlen($cadena)) . $parte_nueva .
substr($contenido, stripos(" " .
$contenido, $cadena) + strlen($cadena));
//Insertamos el nuevo contenido en el fichero de las
//publicaciones
$archivo = fopen("pubs.txt", "w+t");
fwrite($archivo, $contenido);
fclose($archivo);
// Actualizamos la referencia de la publicacin
$added_entries++;
$_POST["campos_def" . $j . "-" . $campo_def_add["error"]] = "";
$k = 0;
while ($campos_tablas[$tabla_actual][$k] != "reference")
$k++;
$l = 0;
while(!ctype_digit($_POST["campos_def" . $j .
"-" . ($k+$def_offset)][$l]))
{
$l++;
}
$cad = "campos_def" . $j . "-" . ($k+$def_offset);
$_POST[$cad] = substr($_POST[$cad], 0, $l) .
strtoupper($siglas) . substr($_POST[$cad], $l);
$_POST["field" . $j . "-" . ($k+$def_offset)] =
$_POST[$cad];
$pubs_mod[$mod_entries++] = $j;
}
}
else {
// Se busca el ndice para extraer
// el nombre de la publicacin
$indice = 0;
if ($tabla_actual == "journals") {
for ($l=0;$l<count($campos_tablas[$tabla_actual]);$l++)
if ($campos_tablas[$tabla_actual][$l] == "journal")
$indice = $l;
}
else if ($tabla_actual == "congress") {
for ($l=0;$l<count($campos_tablas[$tabla_actual]);$l++)
if ($campos_tablas[$tabla_actual][$l] == "congress")
$indice = $l;
}
$nombre = $_POST["campos_def" . $j . "-" .
($indice + $def_offset)];
$changed = false;
// Se busca una publicacin que tenga el mismo
// nombre y que modifique la misma tabla siempre
// y cuando no se haya modificado antes la referencia
for ($n=0; $n<count($new_pubs); $n++) {
if (($tabla_actual == $new_pubs[$n]["tabla_modif"]) &&
($nombre == $new_pubs[$n]["nombre"]) &&
($changed == false))
{
$_POST["campos_def" . $j . "-" .
$campo_def_add["error"]] = "";

115

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$k = 0;
while ($campos_tablas[$tabla_actual][$k] != "reference")
$k++;
$l = 0;
while(!ctype_digit($_POST["campos_def" . $j .
"-" . ($k+$def_offset)][$l]))
{
$l++;
}
$cad = "campos_def" . $j . "-" . ($k+$def_offset);
$_POST[$cad] = substr($_POST[$cad], 0, $l) .
strtoupper($new_pubs[$n]["abbrev"]) .
substr($_POST[$cad], $l);
$_POST["field" . $j . "-" . ($k+$def_offset)] =
$_POST[$cad];
$changed = true;
$pubs_mod[$mod_entries++] = $j;
}
}
}
$processed++;
}
$j++;
}
}
// APELLIDOS: contiene los apellidos de todos los autores
// pertenecientes al grupo.
$peticion_sql = "SELECT bibtexname FROM people";
$resultado = mysql_query($peticion_sql) or die("La consulta fall: " .
mysql_error());
$i = 0;
while ($linea = mysql_fetch_array($resultado, MYSQL_ASSOC)) {
$nombres_usuarios[$i] = $linea["bibtexname"];
$i++;
}
$apellidos = busca_apellido_reg($nombres_usuarios);
// AUTORES_GRUPO: array con los nombres de los autores del grupo
$resultado = mysql_query("SELECT name, surname FROM people");
$j = 0;
while ($row = mysql_fetch_assoc($resultado)) {
$autores_grupo[$j] = quita_tildes(strtolower(trim($row['name'] .
" " . $row['surname'])));
$j++;
}
// Mensaje de bienvenida
imprime_mensaje_bienvenida($formulario, $log_file);
// Mensaje de progreso
echo "\t\t<div id='progress' style='margin:20px 0px 0px " .
"0px;position:relative;padding:0px;width:700px;" .
"height:30px;left:25px;'></div>\n";
flush();
ob_flush();
// Apertura del fichero con los datos a actualizar
//*****************************************
// Primero se mira qu tablas se van a modificar, pues si se trata de
// "congress" o "journals", ha de crearse un array a partir de las
// publicaciones contenidas en el fichero auxiliar "pubs.txt".
genera_arrays($pubs_file, $tablas_db, $congresos, $siglas_congreso, $revistas,
$siglas_revista);
// Bucle principal -> una iteracin por cada tabla principal a modificar
$n_tablas = count($nombre_tablas); // N de tablas a modificar
unset($errores);

116

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


for ($i=0;$i<$n_tablas;$i++)
$errores[$i] = FALSE;
// Variable que indica si hay
// publicaciones desconocidas
// ndice para saber el nmero de errores en las entradas de la actualizacin
$n_errores = $n_unknown - $added_entries;
$entrado = FALSE;
$def_count = 0;
$mark[0] = 0;
// Obtencin de las direcciones
$i = 0;
while (isset($_POST["url" . $i])) {
$urls[$i] = $_POST["url" . $i];
$i++;
}
$html_contents = get_html_content($urls);
// Obtencin de los directorios
$i = 0;
while (isset($_POST["dir" . $i])) {
$dirs[$i] = $_POST["dir" . $i];
$i++;
}
if ($formulario == 0) {
// Bucle principal, se recorren todos los ficheros y se crea una entrada en
// $campos_def por cada publicacin. Esta entrada contendr toda la
// informacin necesaria para poder actualizar la BD posteriormente, sin
// necesidad de procesar
// otra vez toda la informacin.
$ini_msg = "<b>PROCESANDO FICHERO \"";
for ($i=0; $i<$n_tablas; $i++) {
// Apertura del fichero de actualizacin
$archivo = fopen($temp_dir.$nombre_ficheros[$i], "r");
$msg = $ini_msg . $nombre_ficheros[$i] . "\"</b>: ";
if ($archivo) {
unset($contenido);
unset($lineas);
unset($num_lineas);
$contenido = fread($archivo, filesize($temp_dir .
$nombre_ficheros[$i]));
$lineas = explode($separador_linea[$i], $contenido);
$num_lineas = count($lineas);
$l_count = 0;
$vacio = false;
$campos_erroneos = false;
for ($j=0; $j<count($campos_update[$i]); $j++) {
if ($campos_update[$i][$j] == "")
$vacio = true;
else if ($vacio == true)
$campos_erroneos = true;
}
if ($campos_erroneos == false) {
while ($l_count < $num_lineas) {
// Paso 1: Obtener una fila de la tabla
$linea = trim($lineas[$l_count]);
if ($linea != "") {
// Se muestra el mensaje de progreso
$ind_title = 0;
for ($j=0; $j<=count($campos_def[$def_count])-$def_offset;
$j++)
if
($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]][$j] == "title")
$ind_title = $j;
$progress_msg = $msg . "Procesando entrada " .

117

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


($def_count+1) . "...";
echo "\t\t<script type=\"text/javascript\"> " .
"document.getElementById(\"progress\").innerHTML " .
"= '" . $progress_msg . "' </script>\n";
flush();
ob_flush();
for ($j=0;
$j<(count($campos_tablas[$nombre_tablas[$i]])+$def_offset);
$j++)
{
// Contendr los campos finales de cada lnea,
// para generar la orden SQL
$campos_def[$def_count][$j] = "";
}
$campos_def[$def_count][$campo_def_add["tabla"]] =
$nombre_tablas[$i];
// Paso 2: Extraer cada uno de los campos (se insertan en
// "campos_temp")
$campo = strtok($linea, $separador_campo[$i]);
$j = -1;
while ($campo != FALSE) {
$j++;
$campos_temp[$j] = $campo;
$campo = strtok($separador_campo[$i]);
}
//Paso 3: Identificar campos e insertarlos en una tabla que se
//usar posteriormente para generar las rdenes SQL
// Bucle que se recorre una vez por cada campo de la tabla para
// rellenar los campos no especificados y los directamente
// asignables
for ($j=0; $j<count($campos_tablas[$nombre_tablas[$i]]); $j++)
{
$encontrado = FALSE;
$inserta = false;
// NOTA: Los campos de autores, fecha, ttulo y publicacin
// son obligatorios en todos los casos
switch ($campos_tablas[$nombre_tablas[$i]][$j]) {
// Si el campo en cuestin es la fecha de un PFC o un
// PHD, se usa la nomenclatura AO-MES-DA, con 4 dgitos
// de precisin el ao y dos dgitos el resto, separados
// por guiones
case "datephd":
case "datepfc":
for ($k=0; $k<count($campos_update[$i]); $k++) {
if ($campos_update[$i][$k] ==
$campos_tablas[$nombre_tablas[$i]][$j])
{
if (strpos($campos_temp[$k], "/") !== false)
$parts = explode("/", $campos_temp[$k]);
else if (strpos($campos_temp[$k], "-") !== false)
$parts = explode("-", $campos_temp[$k]);
else if (strpos($campos_temp[$k], ".") !== false)
$parts = explode(".", $campos_temp[$k]);
else if (strpos($campos_temp[$k], " ") !== false)
$parts = explode(" ", $campos_temp[$k]);
$field = $parts[2] . "-" . $parts[1] .
"-" . $parts[0];
$inserta = true;
}
}
break;
// Cdigo de libro: libro o actas
case "code":
$field = $_POST["tipo_libro".$i];

118

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$inserta = true;
break;
default:
for ($k=0; $k<count($campos_update[$i]); $k++)
{
if ($campos_update[$i][$k] ==
$campos_tablas[$nombre_tablas[$i]][$j])
{
$field = $campos_temp[$k];
$inserta = true;
}
}
break;
}
if ($inserta == true)
{
trata_texto($field, $siglas_congreso,
$siglas_revista, $mayusc, $numbers);
$campos_def[$def_count][$j + $def_offset] = $field;
$inserta = false;
}
}
// Bucle que procesa los casos particulares y los inserta en la
// tabla de campos para las rdenes SQL:
// * Campos ficticios a partir de los cuales se deben obtener
//
otros campos
// * Campos para actualizar otras tablas interrelacionadas
//
(authors, supervisors)
// * Campos que se obtienen de forma indirecta a partir de
//
otros campos (reference)
// AUTHORS:
for ($k=0; $k<count($campos_update[$i]); $k++) {
if ($campos_update[$i][$k] == "authors") {
$cad = $campos_temp[$k];
$cad = str_replace(". ", ".", $cad);
$cad = str_replace(".", ". ", $cad);
$cad = ucwords(strtolower($cad));
$campos_def[$def_count][$campo_def_add["authors"]] =
$cad;
}
}
// SEP_AUTHORS:
$campos_def[$def_count][$campo_def_add["sep_authors"]] =
$separador_autor[$i];
// SUPERVISORS:
for ($k=0; $k<count($campos_update[$i]); $k++)
if ($campos_update[$i][$k] == "supervisors")
$campos_def[$def_count][$campo_def_add["supervisors"]] =
$campos_temp[$k];
// SEP_AUTHORS:
$campos_def[$def_count][$campo_def_add["sep_supervisors"]] =
$separador_super[$i];
// REFERENCE:
$indice = 0;
for ($l=0;$l<count($campos_update[$i]);$l++)
if ($campos_update[$i][$l] == "authors")
$indice = $l;
// El primer campo de la referencia es el primer apellido del
// autor. Para insertarlo, se busca el primer apellido de todos
// los autores posibles del grupo en el grupo de autores. Se
// escoge el autor que aparezca en primer lugar.
$main_author = strtok($campos_temp[$indice],
$separador_autor[$i]);
$reference = busca_apellido_autor($main_author,
$apellidos);

119

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


unset($nombre);
// El segundo campo de la referencia es el tipo de publicacin.
switch ($nombre_tablas[$i]) {
case "books":
$reference = $reference . "BOOK";
$insertado = TRUE;
break;
case "phds":
$reference = $reference . "PHD";
$insertado = TRUE;
break;
case "pfcs":
$reference = $reference . "PFC";
$insertado = TRUE;
break;
case "journals":
$revista = busca_revista($campos_update[$i],
$campos_temp, $revistas, $siglas_revista, $insertado);
$reference = $reference . $revista;
if ($insertado == false) {
$campos_def[$def_count][$campo_def_add["error"]] .=
"revista*";
$n_errores++;
set_form($formulario);
}
break;
case "congress":
$congreso = busca_congreso($campos_update[$i],
$campos_temp, $congresos, $siglas_congreso,
$insertado);
$reference = $reference . $congreso;
if ($insertado == false) {
$campos_def[$def_count][$campo_def_add["error"]] .=
"congreso*";
$n_errores++;
set_form($formulario);
}
break;
}
// El tercer campo de la referencia es el ao
for ($k=0; $k<count($campos_update[$i]); $k++) {
switch ($campos_update[$i][$k]) {
case "year":
case "datepfc":
case "datephd":
$year = "";
if (strpos($campos_temp[$k], "-") !== false)
$parts = explode("-", $campos_temp[$k]);
else if (strpos($campos_temp[$k], "/") !== false)
$parts = explode("/", $campos_temp[$k]);
else if (strpos($campos_temp[$k], ".") !== false)
$parts = explode(".", $campos_temp[$k]);
else if (strpos($campos_temp[$k], " ") !== false)
$parts = explode(".", $campos_temp[$k]);
else
$year = $campos_temp[$k];
if ($year == "")
for ($n=0; $n<count($parts); $n++)
if (strlen($parts[$n]) == 4)
$year = $parts[$n];
$reference = $reference . $year;
break;
}
}
for ($j=0; $j<count($campos_tablas[$nombre_tablas[$i]]); $j++)

120

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


if ($campos_tablas[$nombre_tablas[$i]][$j] == "reference")
$campos_def[$def_count][$j + $def_offset] = $reference;
// Es necesario especificar el ao o la fecha de
// publicacin para poder generar la referencia
$especificado = false;
for ($j=0;
$j<count($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]]);
$j++)
{
switch
($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]][$j])
{
case "datepfc":
case "datephd":
case "year":
if ($campos_def[$def_count][$j+$def_offset] != "")
$especificado = true;
break;
}
}
if ($especificado == false) {
$campos_def[$def_count][$campo_def_add["error"]] .=
"fecha*";
set_form($formulario);
}
// Es necesario especificar el ttulo de la publicacin
$especificado = false;
for ($j=0;
$j<count($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]]);
$j++)
{
switch
($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]][$j])
{
case "title":
if ($campos_def[$def_count][$j+$def_offset] != "")
$especificado = true;
break;
}
}
if ($especificado == false) {
$campos_def[$def_count][$campo_def_add["error"]] .=
"titulo*";
set_form($formulario);
}
// Es necesario especificar los autores para poder generar la
// referencia
$especificado = false;
if ($campos_def[$def_count][$campo_def_add["authors"]] != "")
$especificado = true;
if ($especificado == false) {
$campos_def[$def_count][$campo_def_add["error"]] .=
"autores*";
set_form($formulario);
}
// Se mira en las pginas facilitadas si existe un hyperlink
// de un fichero pdf para la publicacin en cuestin
$ind_title = 0;
for ($j=0; $j<=count($campos_def[$def_count])-$def_offset;
$j++)
{

121

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


if
($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]][$j] == "title")
$ind_title = $j;
busca_publicacion_web($html_contents, $urls,
$campos_def[$def_count][$ind_title+$def_offset],
$siglas_congreso, $siglas_revista, $mayusc, $numbers,
$campos_def[$def_count][$campo_def_add["pdf"]]);
// Se busca en los directorios siempre
// que se tenga la referencia completa
if ((strpos($campos_def[$def_count][$campo_def_add["error"]],
"revista") === false) &&
(strpos($campos_def[$def_count][$campo_def_add["error"]],
"congreso") === false) &&
(strpos($campos_def[$def_count][$campo_def_add["error"]],
"autores") === false) &&
(strpos($campos_def[$def_count][$campo_def_add["error"]],
"fecha") === false))
{
// Solamente se mira en los directorios si el usuario ha
// incluido alguno
if (is_array($dirs)) {
$path = 0;
$percent = 1;
busca_publicacion_dir($dirs, $reference, $pubs_file,
$campos_def[$def_count][$campo_def_add["pdf"]]);
}
}
// Si no se ha encontrado nada, entonces se pone en blanco un
// campo de los pdfs para al menos dar la oportunidad de
// aadirlo
if (($campos_def[$def_count][$campo_def_add["pdf"]][0][0]== "")
||!isset($campos_def[$def_count][$campo_def_add["pdf"]][0][0]))
{
$campos_def[$def_count][$campo_def_add["pdf"]][0][0] = "";
$campos_def[$def_count][$campo_def_add["pdf"]][0][1] = "";
set_form($formulario);
}
// La primera vez todas las entradas se toman como incompletas
$campos_def[$def_count][$campo_def_add["finished"]] = 0;
$def_count++;
}
$l_count++;
unset($linea);
}
}
else
echo "Ha especificado incorrectamente los campos en el paso " .
"anterior. Por favor, reintente la operacin tras subsanar " .
"el error.";
fclose ($archivo);
} else die("Error al abrir el fichero (compruebe que el fichero " .
"existe y que se tienen los permisos necesarios para acceder al " .
"mismo.");
}
}
// Si no es la primera vez que se carga la pgina (esto es, se
// redirecciona a s misma)...
else
{
// Se obtiene la tabla $campos_def
$i = 0; // 1 dimensin de $campos_def
$j = 0; // 2 dimensin de $campos_def
// Una iteracin por cada entrada
while (isset($_POST["campos_def" . $i . "-" . $j]) ||

122

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


isset($_POST["campos_def" . $i . "-" . $j . "-0-0"]))
{
// Una iteracin por cada campo de cada entrada
while (isset($_POST["campos_def" . $i . "-" . $j]) ||
isset($_POST["campos_def" . $i . "-" . $j . "-0-0"]))
{
if ($j < $def_offset) {
if (($j != $campo_def_add["pdf"]) &&
($j != $campo_def_add["finished"]) &&
($j != $campo_def_add["authors"]))
{
$campos_def[$i][$j] = $_POST["campos_def" . $i . "-" . $j];
}
else if ($j == $campo_def_add["authors"])
$campos_def[$i][$j] = $_POST["field" . $i . "-" . $j];
else if ($j == $campo_def_add["pdf"]) {
unset($url); unset($mark);
$salir = false; // Bandera para salir del bucle
$k = 0;
// Contador para la totalidad de direcciones
$bad = 0;
// Contador para las direcciones errneas
// En caso de lista de ficheros, se obtiene cul
// de los fichero es el actualmente seleccionado
if (isset($_POST["pdf_check" . $i])) {
// Se obtiene el fichero pdf seleccionado
$m = $_POST["pdf_check" . $i];
// Se comprueba si ste se puede leer
$desc_read = fopen($_POST["url" . $i . "-" . $m], "rb");
if ($desc_read == false)
$checked = -1;
else {
$checked = $m;
fclose($desc_read);
}
}
// Bandera para saber si ya hay un fichero
// con el botn radio seleccionado
$marked = false;
while ($salir == false) {
$url = "";
// Caso en que el campo del fichero es de
// tipo texto y se encuentra en una web
if (isset($_POST["url" . $i . "-" . $k]) &&
($_POST["url" . $i . "-" . $k] != ""))
{
// En caso de que se haya cambiado el contenido del
// campo, se realizan las comprobaciones pertinentes
if (stripslashes($_POST["url" . $i . "-" . $k]) !=
stripslashes($_POST["campos_def" .
$i . "-" . $j . "-" . $k . "-0"]))
{
// Comprobacin de que se puede leer dicha direccin
$desc_read = fopen(stripslashes($_POST["url" .
$i . "-" . $k]), "rb");
if ($desc_read == true) {
// Se actualiza la direccin del fichero
$campos_def[$i][$j][$k-$bad][0] =
stripslashes($_POST["url" . $i .
"-" . $k]);
// Se actualiza el porcentaje
$campos_def[$i][$j][$k-$bad][1] = 0;
if (isset($_POST["pdf_check".$i])) {
if (($checked == $k) ||
(($marked == false) &&
($checked == -1)))
{

123

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$mark[$i][$j][$k-$bad] = 1;
$marked = true;
}
else
$mark[$i][$j][$k-$bad] = 0;
}
fclose($desc_read);
}
// Si no se puede leer, se incrementa el
// contador de direcciones errneas
else {
echo "mierda";
$bad++;
}
}
// En caso de que no se haya cambiado nada, se
// procede a la copia directa de la informacin
else {
// Se actualiza la direccin del fichero
$campos_def[$i][$j][$k-$bad][0] =
stripslashes($_POST["campos_def".
$i . "-" . $j . "-" . $k . "-0"]);
if (isset($_POST["pdf_check" . $i])) {
if (($checked == $k) ||
(($marked == false) && ($checked == -1)))
{
$mark[$i][$j][$k-$bad] = 1;
$marked = true;
}
else
$mark[$i][$j][$k-$bad] = 0;
}
// Se actualiza el porcentaje
$campos_def[$i][$j][$k-$bad][1] =
$_POST["campos_def". $i . "-" .$j . "-" . $k . "-1"];
}
}
// Caso en que el campo del fichero es
// de tipo texto y ste est en blanco
else if (isset($_POST["url" . $i . "-" . $k]) &&
($_POST["url" . $i . "-" . $k] == ""))
{
$bad++;
}
// Caso en que el campo del fichero es de
// tipo fichero y se encuentra en blanco
else if (isset($_FILES["url" . $i . "-" . $k]))
$bad++;
// Caso en que no hay ms ficheros
else
$salir = true;
$k++;
}
if (!isset($campos_def[$i][$campo_def_add['pdf']])) {
$campos_def[$i][$campo_def_add['pdf']][0][0] = "";
$campos_def[$i][$campo_def_add['pdf']][0][1] = "";
}
}
// El campo de entrada terminada (finished) se ha
// de obtener de otro campo oculto
else if ($j == $campo_def_add["finished"])
if (isset($_POST["finished" . $i]))
$campos_def[$i][$j] = 1;
else
$campos_def[$i][$j] = 0;

124

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
else {
$campos_def[$i][$j] = $_POST["field" . $i . "-" . $j];
}
$j++;
}
$i++;
$j = 0;
}
// Solamente se procesan los datos de las entradas
// que el usuario desea aadir, las dems se eliminan
for ($i=0; $i<count($campos_def); $i++)
if (isset($_POST["nondesired" . $i]))
$campos_def = elimina_entrada($campos_def, $i);
// Se procede a buscar en los directorios aquellas entradas
// que anteriormente dieron errores debido a la referencia
if (is_array($dirs)) {
if (isset($pubs_mod) && ($pubs_mod[0] != "")) {
for ($i=0; $i<count($pubs_mod); $i++) {
// Obtencin de la posicin de la referencia
$ref_ind = 0;
$tab_ind = $campos_def[$pubs_mod[$i]][$campo_def_add["tabla"]];
while ($campos_tablas[$tab_ind][$ref_ind] != "reference")
$ref_ind++;
$ref_ind += $def_offset;
$path = 0;
$percent = 1;
busca_publicacion_dir($dirs,
$campos_def[$pubs_mod[$i]][$ref_ind], $pubs_file,
$campos_def[$pubs_mod[$i]][$campo_def_add["pdf"]]);
}
}
}
// Se procede a procesar las entradas completas
$mostrado = false;
for ($i=0; $i<count($campos_def); $i++) {
flush();
ob_flush();
if ($campos_def[$i][$campo_def_add["finished"]] == 1) {
$mostrado = true;
if (procesa_entrada($campos_def[$i], $campo_def_add, $campos_tablas,
$tipo_publicacion, $autores_grupo, $id, $letra))
{
if (!isset($_POST["req_pdf".$i]))
{
if (isset($campos_def[$i][$campo_def_add["pdf"]]))
{
if (isset($_POST["pdf_check" . $i]))
$ind = $_POST["pdf_check" . $i];
else
$ind = 0;
if ($campos_def[$i][$campo_def_add["pdf"]][$ind][0] != "")
{
inserta_pdf($campos_def[$i][$campo_def_add["pdf"]][$ind][0],
$log_file,
$tipo_publicacion[$campos_def[$i][$campo_def_add["tabla"]]],
$id);
}
}
}
}
if (isset($delete))
$delete[count($delete)] = $i;
else

125

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$delete[0] = $i;
}
}
// Se borran las entradas ya procesadas
for ($i=(count($delete)-1); $i>=0; $i--)
$campos_def = elimina_entrada($campos_def, $delete[$i]);
// Se procede a la copia de los ficheros
$desc_read = fopen($log_file, "r");
if ($desc_read != false) {
// Obtencin del contenido del fichero
while (!feof($desc_read))
$content .= fread($desc_read, 8192);
fclose($desc_read);
if (trim($content) != "")
print "\n\t\t<script type=\"text/javascript\"> " .
"Abrir_Ventana('http://localhost/groupweb/proc_files.php', " .
"'600', '200') </script>\n";
}
if ($mostrado == true)
echo "\t\t<br /><br />\n";
}
echo "\t\t<script type=\"text/javascript\"> " .
"document.getElementById(\"progress\").style.display = 'none'</script>\n";
// Se procede a examinar las entradas disponibles para
// eliminar las ya existentes en la base de datos
for ($i=(count($campos_def)-1); $i>-1; $i--) {
$sentencia_SQL = crea_orden_sql($campos_def[$i], $campo_def_add,
$campos_tablas);
$query_sql = "SELECT title, reference FROM " .
$campos_def[$i][$campo_def_add["tabla"]];
$resultado = mysql_query($query_sql);
$num_refs = 0;
// Si la entrada ya existe en la base de datos
// se procede a su borrado de la tabla $campos_def
if (busca_entrada_similar($resultado, $campos_def[$i], $campo_def_add,
$campos_tablas, $num_refs))
{
$campos_def = elimina_entrada($campos_def, $i);
}
}
// Si existen entradas en la tabla $campos_def ha de
// presentarse nuevamente el formulario
if (count($campos_def) > 0) {
set_form($formulario);
abre_formulario();
// Si todava existen entradas incompletas en $campos_def,
// se muestran de nuevo los resultados por pantalla
imprime_resultados($campos_def, $campo_def_add, $campos_tablas,
$mensajes_error, $mark);
// Se envan los campos ocultos que se enviaban inicialmente
for ($i=0; $i<count($nombre_tablas); $i++) {
echo "\t\t\t<input type='hidden' name='tabla" . $i . "' value=\"" .
$nombre_tablas[$i] . "\" />\n";
echo "\t\t\t<input type='hidden' name='fichero" . $i . "' value=\"" .
$nombre_ficheros[$i] . "\" />\n";
}
for ($i=0; $i<count($campos_update); $i++)
for ($j=0;$j<count($campos_update[$i]);$j++)
echo "\t\t\t<input type='hidden' name='campo" . $i . "-" .
$j . "' value=\"" . $campos_update[$i][$j] . "\" />\n";
for ($i=0; $i<count($separador_campo); $i++)
echo "\t\t\t<input type='hidden' name='separador_campo" . $i .
"' value=\"" . $_POST["separador_campo" . $i] . "\" />\n";
for ($i=0; $i<count($separador_campo); $i++)

126

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "\t\t\t<input type='hidden' name='separador_linea" . $i .
"' value=\"" . $_POST["separador_linea" . $i] . "\" />\n";
// Se ha de pasar la lista de urls ...
for ($i=0; $i<count($urls); $i++)
echo "\t\t\t<input type='hidden' name='url" . $i . "' value=\"" .
$urls[$i] . "\" />\n";
// ... as como la lista de urls
for ($i=0; $i<count($dirs); $i++)
echo "\t\t\t<input type='hidden' name='dir" . $i . "' value=\"" .
stripslashes($dirs[$i]) . "\" />\n";
// FORMULARIO nos permitir discernir si se trata de un redireccionamiento
// a la propia pgina o es la primera vez que se llega a ella
echo "\t\t\t<input type='hidden' name='formulario' value=\"" .
$formulario . "\" />\n";
// ERRORES nos indica la cantidad de variables que hay que comprobar, esto
// es, el n de mini-formularios creados para cada publicacin no reconocida
echo "\t\t\t<input type='hidden' name='errores' value=\"" .
$n_errores . "\" />\n";
// Envo del array $campos_def
for ($i=0; $i<count($campos_def); $i++) {
for ($j=0; $j<count($campos_def[$i]); $j++) {
if (!is_array($campos_def[$i][$j]))
echo "\t\t\t<input type='hidden' name='campos_def" . $i . "-" .
$j . "' value=\"" . $campos_def[$i][$j] . "\" />\n";
else {
for ($k=0; $k<count($campos_def[$i][$j]); $k++) {
if (!is_array($campos_def[$i][$j][$k]))
echo "\t\t\t<input type='hidden' name='campos_def" . $i .
"-" . $j . "-" . $k . "' value=\"" .
$campos_def[$i][$j][$k] . "\" />\n";
else {
for ($m=0; $m<count($campos_def[$i][$j][$k]); $m++) {
echo "\t\t\t<input type='hidden' name='campos_def" .
$i . "-" . $j . "-" . $k . "-" . $m . "' value=\"" .
$campos_def[$i][$j][$k][$m] . "\" />\n";
}
}
}
}
}
}
echo "\t\t\t<input type='submit' value='Volver al paso 3' />\n";
cierra_formulario();
}
// Si ya no quedan entradas incompletas en $campos_def,
// se muestra el mensaje de actualizacin con xito
else {
echo "\t\tActualizacin de la base de datos completada.<br></br>";
echo "Muchas gracias por su colaboracin.<br></br>\n";
}
cierra_pagina();
desconecta_db($conexion_mysql);
}
else {
echo "Error en el nombre de usuario o en la contrasea.<br />Por favor, " .
"vuelva a la pantalla de validacin.<br />";
echo "<a href=\"./update.html\">Pgina de validacin</a>";
}
?>

10.4.1.5 P ROC _FILES .PHP


<?php

127

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


include "functions.step3.php";
set_time_limit (36000);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="imagetoolbar" content="no" />
<meta name="robots" content="noindex, nofollow" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<title>Barra progreso PHP/ PHP Progress bar</title>
</head>
<body>
<?php
// Nombre del fichero con la informacin de los pdfs a copiar
$log_file = "pdf_log.txt";
// Ruta de destino de los ficheros pdfs
$ruta = "./files/";
// Recuperacion de las rutas de los ficheros a partir del fichero pdf_log.txt
$desc_read = fopen($log_file, "r");
if ($desc_read == FALSE)
$read = false;
else {
// Obtencin del contenido del fichero de log
while (!feof($desc_read)) {
// Obtencin del contenido de la direccin
$log_content = fread($desc_read, 8192);
}
fclose($desc_read);
}
// Separacin de la informacin de cada fichero en lneas => $linea
$tok = strtok($log_content, "\n");
$i = 0;
while ($tok !== false) {
$linea[$i] = $tok;
$tok = strtok("\n");
$i++;
}
// Se realiza una iteracin por cada fichero que se ha de copiar
$i=0;
while ($i < count($linea)) {
// Extraccin de la informacin de cada lnea
$n_tok = 0;
$tok = strtok($linea[$i], "\t");
while ($tok !== false) {
// 1er campo: Ruta del fichero pdf
if ($n_tok == 0)
{
// URL del fichero
$urls[$i] = $tok;
// Tamao del fichero
$size[$i] = sprintf("%.2f", (trim(remote_file_size($urls[$i])))/1024);
if ($size[$i] == "0.00") {
$size[$i] = sprintf("%.2f", (trim(filesize($urls[$i])))/1024);
}
// Eliminacin de las barras invertidas
if (strpos($urls[$i], "\\") !== false)
$nombres[$i] = substr($urls[$i], strrpos($urls[$i], "\\"));
else if (strpos($urls[$i], "/") !== false)
$nombres[$i] = str_replace("%20", " ", substr($urls[$i],
strrpos($urls[$i], "/") + 1));
$n_tok++;
}

128

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// 2 y 3er campos: Tipo de publicacin e id del fichero
else if ($n_tok != 0)
{
$pub_type = $tok;
$tok = strtok("\t");
$id = $tok;
// Si existen el tipo de publicacin y la id de la entrada de
// la base de datos, se calcula la ruta del fichero
if (($pub_type !== false) && ($id !== false))
$ruta_fichero[$i] = $ruta . "t" . trim($pub_type) .
"i" . trim($id) . ".pdf";
// Si no, entonces se borra la entrada de la tabla de $urls
else
for ($j=$i; $j<(count($linea[$i])-1); $j++)
$linea[$j] = $linea[$j+1];
}
}
$i++;
}
// Impresin de los divs que mostrarn los progresos
echo "<div id='info_file' style='margin:20px 0px 0px 0px;position:relative;" .
"padding:0px;width:550px;height:30px;left:25px;'></div>\n";
echo "<div id='file_progress' style='position:relative;padding:0px;width:" .
"512px;height:27px;left:25px;" .
"background-image:url(images/pbar_background.gif)'></div>\n";
echo "<div id='info_total' style='margin:20px 0px 0px 0px;position:relative;" .
"padding:0px;width:550px;height:30px;left:25px;'></div>\n";
echo "<div id='total_progress' style='position:relative;padding:0px;width:" .
"512px;height:27px;left:25px;" .
"background-image:url(images/pbar_background.gif)'></div>\n";
$max_bars = 250;
// Mximo n de barras que se mostrarn
$total_transferred = 0;
// Tamao total transferido
$count_bars = 0;
$read_size = 8192;
// Tamao del bloque de lectura
$read_sizeKB = $read_size/1024; // Tamao del bloque de lectura en KB
$error = false;
$totalbar_size = array_sum($size)/$max_bars;
// Se muestra el total de KB a transferir
echo "<script type=\"text/javascript\"> document.getElementById" .
"(\"info_total\").innerHTML = \"Total a transferir: " . array_sum($size) .
"KB\" </script>\n";
// Para cada fichero se realiza una iteracin
// y se muestra el porcentaje de avance
for ($i=0; $i<count($nombres); $i++) {
$bar_size = $size[$i]/$max_bars;
$filesize_transferred = 0;
// Apertura del flujo de lectura
$desc_read = fopen($urls[$i], "rb");
if ($desc_read == false)
$error = true;
else {
// Apertura del flujo de escritura
$desc_write = fopen($ruta_fichero[$i], "wb");
if ($desc_write == false)
$error = true;
else {
// Se muestra el texto de progreso
echo "<script type=\"text/javascript\"> document.getElementById" .
"(\"info_file\").innerHTML = \"Copiando el fichero &quot;" .
$nombres[$i] . "&quot; [" . $size[$i] . " KB]\" </script>\n";
while (!feof($desc_read)) {
$pdf_content = fread($desc_read, $read_size);
fwrite($desc_write, $pdf_content);
// Actualizacin de la barra de progreso del fichero que se est
// copiando

129

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$filesize_transferred += strlen($pdf_content)/1024;
$num_bars = sprintf("%.0d", $filesize_transferred/$bar_size);
$bars = "<div style='float:left;margin:6px 0px 0px 6px;width:" .
($num_bars*2) . "px;height:12px;background:red;color:red;'> </div>";
echo "<script type=\"text/javascript\"> " .
"document.getElementById(\"file_progress\").innerHTML = \"" .
$bars . "\" </script>\n";
// Actualizacin de la barra de progreso del tamao total que se ha de
// transferir
$total_transferred += strlen($pdf_content)/1024;
$num_bars = sprintf("%.0d", $total_transferred/$totalbar_size);
$bars = "<div style='float:left;margin:6px 0px 0px 6px;width:" .
($num_bars*2) . "px;height:12px;background:red;color:red;'> </div>";
echo "<script type=\"text/javascript\"> " .
"document.getElementById(\"total_progress\").innerHTML = \"" .
$bars . "\" </script>\n";
flush();
ob_flush();
}
fclose($desc_read);
fclose($desc_write);
}
}
}
// Una vez copiados todos los ficheros, se procede a
// borrar el contenido del fichero de logeado de pdfs
$desc_write = fopen($log_file, "w");
if ($desc_write != false)
fclose($desc_write);
// Se retrasa 2 segundos el cierre de la ventana
sleep(2);
echo "<script type='text/javascript'> window.close() </script>\n";
?>

10.4.1.6 B ACKUP .PHP


<?php
include "functions.inc.php";
// Cambiamos el tiempo mximo de respuesta,
// porque hay que buscar el fichero "mysqldump"
ini_set("max_execution_time", "600");
// No se reporta ningn tipo de error
//error_reporting(0);
session_start();
?>
<html>
<head>
<script type="text/javascript">
function resize()
{
var width = window.screen.width;
var height = window.screen.availHeight;
var left = (parseInt(width) - 650)/2;
document.getElementById("table_div").style.left = left;
document.getElementById("table_div").style.top = 100;
}
</script>
</head>
<body>
<div id="table_div" name="table_div" style="position:absolute;width:610px;">
<?php

130

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$conexion_mysql =& conecta_db();
// Conexin con la base de datos
if (isset($_POST['login']) && isset($_POST['pass'])) {
$login = $_POST['login'];
$pass = $_POST['pass'];
$_SESSION['login'] = $login;
$_SESSION['pass'] = $pass;
}
else if (isset($_SESSION['login']) && isset($_SESSION['pass'])) {
$login = $_SESSION['login'];
$pass = $_SESSION['pass'];
}
if (($login != "") && ($pass != "")) {
if (valida_usuario($login, $pass)) {
// Obtener el root (C:/ en el caso de Windows o
// ./ en el caso de Linux)
$php_dir = str_replace("\\", "/", getcwd());
$dir = getcwd();
chdir('../');
$new_dir = getcwd();
while ($dir != $new_dir) {
$dir = $new_dir;
chdir('../');
$new_dir = getcwd();
}
$root = str_replace("\\", "/", $new_dir);
// Buscamos el fichero "mysqldump" en la
// ruta almacenada en el fichero de logeo
chdir($php_dir);
$dump_file = "dump_path.log";
$dump_path = "";
$dont_exists = false;
if (file_exists($dump_file)) {
if (($handler = fopen($dump_file, "r")) != false) {
$content = fread($handler, filesize($dump_file));
if ($content != "") {
if (file_exists($content)) {
$dump_path = $content;
}
else {
$dont_exists = true;
}
}
else {
$dont_exists = true;
}
}
else {
$dont_exists = true;
}
}
else {
$dont_exists = true;
}
// Si el fichero de logeo no existe, o no contiene
// una ruta vlida, se busca el fichero
if ($dont_exists == true) {
$found = false;
$path = $root;
$filename = array("Linux" => "mysqldump",
"WINNT" => "mysqldump.exe");
seek_file($path, $filename, $found);
$dump_path = $path;
if ($found == true) {
$dump_path = $path . "/" . $filename[PHP_OS];
chdir($php_dir);

131

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


if (($handler = fopen($dump_file, "w")) != false)
fwrite($handler, $dump_path);
$dont_exists = false;
}
}
// Si se ha encontrado el fichero se procede a mostrar
// el contenido de la pgina en funcin del botn pulsado
if ($dont_exists == false) {
// Caso de crear nueva copia de seguridad.
// Simplemente se informa de la creacin.
if (isset($_POST['create_backup'])) {
// Obtencin de la hora y la fecha
$hora = date("H.i.s");
$fecha = date("d-m-Y");
// Comprobacin de la existencia del directorio de backup
chdir($php_dir);
if (!file_exists("./db_backup/"))
mkdir("./db_backup");
chdir($php_dir . "/db_backup/");
// Creacin del registro del contenido del directorio de pdfs
if ($dir_handler = opendir($php_dir . "/files/")) {
if ($log_handler = fopen("pdf_" . $hora .
"_" . $fecha . ".log", "w"))
{
while (($res = readdir($dir_handler)) !== false)
{
if (is_file($php_dir . "/files/" . $res)) {
fwrite($log_handler, $res . "\n");
}
}
fclose($log_handler);
}
closedir($dir_handler);
}
chdir($dump_dir);
// Sustituir aqu el nombre de usuario, la clave y el nombre de la
// base de datos
exec("mysqldump --user=nombre_usuario --password=clave " .
"--add-drop-table base_datos > " . $php_dir . "/db_backup/" .
"backup_" . $fecha . "_" . $hora . ".sql");
if (file_exists($php_dir . "/db_backup/" .
"backup_" . $fecha . "_" . $hora . ".sql"))
{
echo "\t\t\tCreada copia de seguridad con hora " .
str_replace(".", ":", $hora) . " el da " .
str_replace("-", "/", $fecha) . " en el fichero " .
"backup_" . $fecha . "_" . $hora . ".sql<br />\n";
echo "\t\t\tVolver a la <a href=\"./update.html\">" .
"pgina principal</a>.\n";
}
}
// Caso de restauracin de copia de seguridad.
// Se muestra una tabla con todas las copias existentes.
else if (isset($_POST['restore_backup']) || isset($_POST['restore'])
|| isset($_POST['delete']))
{
// Caso de haber seleccionado una copia de seguridad
// para restauracin en el caso anterior.
if (isset($_POST['restore'])) {
chdir(dirname($dump_path));
// Sustituir aqu el nombre de usuario, la clave y el nombre de la
// base de datos
passthru("mysql --user=nombre_usuario --password=clave " .
"base_datos < " . str_replace("/", "\\", $php_dir) .
"\db_backup\\" . $_POST['filename']);

132

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Caso de haber marcado la casilla de actualizacin
// de directorio contenedor de los ficheros pdf
if (isset($_POST['update_pdf'])) {
// Lectura del contenido del fichero de registro de pdfs
$content = "";
$pdf_log_name = str_replace("backup", "pdf",
$_POST['filename']);
$pdf_log_name = str_replace(".sql", ".log",
$pdf_log_name);
if ($log_handler = fopen($php_dir . "/db_backup/" .
$pdf_log_name, "r"))
{
while (!feof($log_handler))
$content .= fread($log_handler, 8192);
fclose($log_handler);
}
// Apertura del directorio de pdfs para lectura
if ($dir_handler = opendir($php_dir . "/files/")) {
while (($res = readdir($dir_handler)) !== false)
if (is_file($php_dir . "/files/" . $res))
// Si el fichero que est siendo ledo no se encuentra
// en el fichero de registro, entonces debe borrarse
if (stripos($content, $res) === false)
unlink($php_dir . "/files/" . $res);
closedir($dir_handler);
}
}
}
// Caso de haber seleccionado una
// copia de seguridad para ser borrada.
if (isset($_POST['delete'])) {
if (file_exists($php_dir . "/db_backup/" . $_POST['filename']))
unlink($php_dir . "/db_backup/" . $_POST['filename']);
$pdf_log_name = str_replace("backup", "pdf", $_POST['filename']);
$pdf_log_name = str_replace(".sql", ".log", $pdf_log_name);
if (file_exists($php_dir . "/db_backup/" . $pdf_log_name))
unlink($php_dir . "/db_backup/" . $pdf_log_name);
}
chdir($php_dir . "/db_backup/");
if ($handler = opendir('.')) {
$found = false;
echo "\t\t\t<form action=\"backup.php\" method=\"post\">\n";
echo "\t\t\t\t<input type=\"hidden\" id=\"filename\" " .
"name=\"filename\" value=\"\" />\n";
echo "\t\t\t\t<table border=1>\n";
echo "\t\t\t\t\t<thead style=\"background-color:silver;\">\n";
echo "\t\t\t\t\t\t<tr>\n";
echo "\t\t\t\t\t\t\t<th>Fecha</th>\n";
echo "\t\t\t\t\t\t\t<th>Hora</th>\n";
echo "\t\t\t\t\t\t\t<th colspan=\"3\"></th>\n";
echo "\t\t\t\t\t\t</tr>\n";
echo "\t\t\t\t\t</thead>\n";
echo "\t\t\t\t\t<tbody>\n";
while (($res = readdir($handler)) !== false) {
$found = true;
$parts = pathinfo($res);
if (is_file($res) && ($parts["extension"] == "sql")) {
$tok = explode("_", $res);
$fecha = str_replace("-", "/", $tok[1]);
$hora= str_replace(".", ":", str_replace(".sql", "", $tok[2]));
echo "\t\t\t\t\t\t<tr>\n";
echo "\t\t\t\t\t\t\t<td width=\"90\" valign=\"center\" " .
"align=\"center\">\n";
echo "\t\t\t\t\t\t\t\t" . $fecha . "\n";
echo "\t\t\t\t\t\t\t</td>\n";

133

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "\t\t\t\t\t\t\t<td width=\"70\" valign=\"center\" " .
"align=\"center\">\n";
echo "\t\t\t\t\t\t\t\t" . $hora . "\n";
echo "\t\t\t\t\t\t\t</td>\n";
echo "\t\t\t\t\t\t\t<td width=\"110\" valign=\"center\" " .
"align=\"center\">\n";
echo "\t\t\t\t\t\t\t\t<input type=\"submit\" id=\"restore\" " .
"name=\"restore\" value=\"Restaurar copia\" " .
"onclick=\"document.getElementById('filename').value = " .
"'" . $res . "';\" />\n";
echo "\t\t\t\t\t\t\t</td>\n";
echo "\t\t\t\t\t\t\t<td width=\"90\" valign=\"center\" " .
"align=\"center\">\n";
echo "\t\t\t\t\t\t\t\t<input type=\"submit\" id=\"delete\" " .
"name=\"delete\" value=\"Borrar copia\" " .
"onclick=\"document.getElementById('filename').value = " .
"'" . $res . "';\" />\n";
echo "\t\t\t\t\t\t\t</td>\n";
echo "\t\t\t\t\t\t\t<td width=\"200\">\n";
echo "\t\t\t\t\t\t\t\t<input type=\"checkbox\" " .
"name=\"update_pdf\" value=\"1\" />\n";
echo "\t\t\t\t\t\t\t\t<label for=\"update_pdf\">" .
"Actualizar directorio de pdfs</label>\n";
echo "\t\t\t\t\t\t\t</td>\n";
echo "\t\t\t\t\t\t</tr>\n";
}
}
if ($found) {
echo "\t\t\t\t\t\t<tr>\n";
echo "\t\t\t\t\t\t\t<td colspan=\"5\">\n";
echo "\t\t\t\t\t\t\t\tNOTAS IMPORTANTES:\n";
echo "\t\t\t\t\t\t\t\t<ul>\n";
echo "\t\t\t\t\t\t\t\t\t<li>\n";
echo "\t\t\t\t\t\t\t\t\t\tUna vez que se proceda con la " .
"restauracin de una copia de seguridad y el resultado" .
"sea el deseado, procdase al borrado de las copias de" .
"seguridad posteriores a fin de evitar conflictos en " .
"futuro.\n";
echo "\t\t\t\t\t\t\t\t\t</li>\n";
echo "\t\t\t\t\t\t\t\t\t<li>\n";
echo "\t\t\t\t\t\t\t\t\t\tLa casilla \"Actualizar " .
"directorios\" utiliza un registro de seguridad para " .
"eliminar los ficheros pdfs aadidos con posterioridad " .
"a la copia de seguridad a restaurar. Se recomienda " .
"restaurar la copia primero con la casilla " .
"deseleccionada, y en caso de resultar exitosa la " .
"restauracin, proceder entonces restaurarla " .
"nuevamente con la casilla marcada, y por ltimo, " .
"eliminar las copias de seguridad posteriores.\n";
echo "\t\t\t\t\t\t\t\t\t</li>\n";
echo "\t\t\t\t\t\t\t\t</ul>\n";
echo "\t\t\t\t\t\t\t</td>\n";
echo "\t\t\t\t\t\t</tr>\n";
}
echo "\t\t\t\t\t</tbody>\n";
echo "\t\t\t\t</table>\n";
echo "\t\t\t</form>\n";
}
// Se muestra el mensaje de la restauracin de
// copia de seguridad cuando corresponda.
if (isset($_POST['restore'])) {
echo "\t\t\tRestaurada copia de seguridad <b>" .
$_POST['filename'] . "</b>.<br />\n";
if (isset($_POST['update_pdf']))
echo "\t\t\tActualizado sistema de archivos pdfs.<br />\n";

134

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "\t\t\tVolver a la <a href=\"./update.html\">pgina " .
"principal</a>.<br />\n";
}
// Se muestra el mensaje del borrado de
// copia de seguridad cuando corresponda.
if (isset($_POST['delete'])) {
echo "\t\t\tBorrada copia de seguridad <b>" .
$_POST['filename'] . "</b>.<br />\n";
echo "\t\t\tVolver a la <a href=\"./update.html\">" .
"pgina principal</a>.<br />\n";
}
}
}
}
// Caso de que el usuario no est validado correctamente se notifica por
// pantalla
else {
echo "El nombre de usuario y/o la contrasea introducido/s no son " .
"vlidos.\n<br />";
echo "<a href=\"./update.html\">Volver a la pgina de validacin</a>";
}
}
else {
echo "El nombre de usuario y/o la contrasea introducido/s no son " .
"vlidos.\n<br />";
echo "<a href=\"./update.html\">Volver a la pgina de validacin</a>";
}
?>
</div>
<script type="text/javascript"> resize(); </script>
</body>
</html>

10.4.1.7 P UBS _EDITOR .PHP


<?php
include "functions.inc.php";
// Cambiamos el tiempo mximo de respuesta,
// porque hay que buscar el fichero "mysqldump"
ini_set("max_execution_time", "600");
// No se reporta ningn tipo de error
//error_reporting(0);
session_start();
?>
<html>
<head>
</head>
<body>
<div id="table_div" name="table_div">
<?php
// Validacin de usuario
$conexion_mysql =& conecta_db();
// Conexin con la base de datos
if (isset($_POST['login_pubs']) && isset($_POST['pass_pubs'])) {
$login = $_POST['login_pubs'];
$pass = $_POST['pass_pubs'];
$_SESSION['login'] = $login;
$_SESSION['pass'] = $pass;
}
else if (isset($_SESSION['login']) && isset($_SESSION['pass'])) {
$login = $_SESSION['login'];
$pass = $_SESSION['pass'];
}
if (($login != "") && ($pass != "")) {

135

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


if (valida_usuario($login, $pass)) {
// Si el usuario entra por primera vez, entonces se muestra
// el editor con el contenido del fichero de definiciones
if (!isset($_POST["update_pubs"])) {
// Obtencin del contenido del fichero
$h_file = fopen("pubs.txt", "r");
$content = "";
while (!feof($h_file)) {
$content .= fread($h_file, 8192);
}
fclose($h_file);
// Mensaje de bienvenida
echo "\t\t\t<h2>Fichero de definicin de publicaciones:</h2><br />\n";
// Explicacin de las partes de una definicin
echo "\t\t\tEste fichero contiene las definiciones de las " .
"publicaciones, que incluyen los siguientes componentes por " .
"publicacin:<br />\n";
echo "\t\t\t<ul>\n";
echo "\t\t\t\t<li>\n";
echo "\t\t\t\t\t1 lnea: Comentario precedido por \"//\" que " .
"especifica el nombre completo de la publicacin.\n";
echo "\t\t\t\t</li>\n";
echo "\t\t\t\t<li>\n";
echo "\t\t\t\t\t2 lnea: Acrnimo o abreviatura de la publicacin, " .
"seguido de \";\" y un tabulador, tras lo cual siguen las palabras " .
"claves que se utilizarn para determinar la publicacin separadas " .
"por tabuladores.\n";
echo "\t\t\t\t</li>\n";
echo "\t\t\t</ul>\n";
// Explicacin de los grupos de definiciones
echo "\t\t\tExisten dos grupos definidos para cada tipo de publicacin:"
. "<br />\n";
echo "\t\t\t<ul>\n";
echo "\t\t\t\t<li>\n";
echo "\t\t\t\t\tLas publicaciones del tipo \"revista\" o \"journal\" " .
"se incluirn tras el identificador \"::JOURNALS\".\n";
echo "\t\t\t\t</li>\n";
echo "\t\t\t\t<li>\n";
echo "\t\t\t\t\tLas publicaciones del tipo \"ponencia en congreso\" " .
"se incluirn tras el identificador \"::CONGRESS\".\n";
echo "\t\t\t\t</li>\n";
echo "\t\t\t</ul>\n";
// Consejos de edicin
echo "\t\t\tConsejos:"
. "<br />\n";
echo "\t\t\t<ul>\n";
echo "\t\t\t\t<li>\n";
echo "\t\t\t\t\tAntes de incluir una publicacin asegrese de que ".
"realmente no se encuentra incluida en la lista existente.\n";
echo "\t\t\t\t</li>\n";
echo "\t\t\t\t<li>\n";
echo "\t\t\t\t\tTenga cuidado con las modificaciones que realice, " .
"pues el fichero de definiciones de publicaciones se actualizar " .
"con el contenido final que usted indique.\n";
echo "\t\t\t\t</li>\n";
echo "\t\t\t\t<li>\n";
echo "\t\t\t\t\tAbstngase de incluir preposiciones, artculos, " .
"conjunciones, etc. en las palabras claves. Incluya solamente las " .
"palabras que mejor definan la publicacin (sin tildes y en " .
"minsculas).\n";
echo "\t\t\t\t</li>\n";
echo "\t\t\t</ul>\n";
// Formulario con el editor
echo "\t\t\t<form id=\"editor_form\" name=\"editor_form\" " .
"method=\"post\" action=\"pubs_editor.php\"\n";

136

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "\t\t\t\t<textarea id=\"pubs_content\" name=\"pubs_content\" " .
"cols=\"120\" rows=\"30\">" . $content . "</textarea>\n";
echo "\t\t\t\t<input type=\"submit\" id=\"update_pubs\" " .
"name=\"update_pubs\" " .
"value=\"Actualizar fichero de definiciones\" />\n";
echo "\t\t\t</form>";
}
// Si no es la primera vez que se visita la pgina,
// entonces se ha de actualizar el fichero de definiciones
else {
$h_file = fopen("pubs.txt", "w");
if (fwrite($h_file, $_POST["pubs_content"]) === FALSE) {
echo "\t\t\tNo se puede escribir en el archivo de definiciones.";
}
else
echo "\t\t\tFichero de definiciones actualizado con xito.\n";
}
}
// Caso de que el usuario no est validado correctamente
// se notifica por pantalla
else {
echo "El nombre de usuario y/o la contrasea introducido/s no son " .
"vlidos.\n<br />";
echo "<a href=\"./update.html\">Volver a la pgina de validacin</a>";
}
}
else {
echo "El nombre de usuario y/o la contrasea introducido/s no son " .
"vlidos.\n<br />";
echo "<a href=\"./update.html\">Volver a la pgina de validacin</a>";
}
?>
</div>
</body>
</html>

10.4.1.8 FUNCTIONS .INC .PHP


<?php
// Estas variables se utilizan para indicar campos que se facilitan en el fichero
// de actualizacin y que no existen como tales en la tabla, es decir, que
// requieren de un procesado posterior
$lista_campos_adicionales = array('autores', 'supervisores');
$tabla_campos_adicionales = array('all', 'phds');
$var_campos_adicionales = array('authors', 'supervisors');
// Estas variables se utilizan para que el usuario seleccione un valor, pues no
// se facilitan en el fichero de actualizacin
$lista_campos_undef = array('separador campos', 'separador filas',
'separador autores', 'separador supervisores', 'tipo de libro');
$tabla_campos_undef= array('all', 'all', 'all', 'phds', 'books');
$var_campos_undef = array('separador_campo', 'separador_linea',
'separador_autor', 'separador_super', 'tipo_libro');
$valores_campos_undef = array(
$lista_campos_undef[0] => array (0,1,2,3,4,5,6,7),
$lista_campos_undef[1] => array (0,1,2,3,4,5,6,7),
$lista_campos_undef[2] => array (0,1,2,3,4,5,6,7),
$lista_campos_undef[3] => array (0,1,2,3,4,5,6,7),
$lista_campos_undef[4] => array ("1","2"));
$desc_campos_undef = array(
$lista_campos_undef[0] => array ("\\n","\\r","\\r\\n","\\t",";",":",",","."),
$lista_campos_undef[1] => array ("\\n","\\r","\\r\\n","\\t",";",":",",","."),
$lista_campos_undef[2] => array ("\\n","\\r","\\r\\n","\\t",";",":",",","."),
$lista_campos_undef[3] => array ("\\n","\\r","\\r\\n","\\t",";",":",",","."),

137

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$lista_campos_undef[4] => array ("Libro","Actas"));
//************************************************************************
// CONECTA_DB: realiza la conexin con la base de datos.
// Entrada:
- Ninguna
// Salida: - Identificador de la conexin con la base de datos => $conexion
//************************************************************************
function &conecta_db() {
// Conexin con el servidor MySQL
// El usuario deber modificar estos datos para acceder correctamente
$host = "nombre_host";
$user = "nombre_de_usuario";
$pass = "clave_de_usuario";
$db = "base_datos";
$conexion = mysql_connect($host, $user, $pass);
if (!$conexion) {
die("No se pudo conectar con la base de datos: " . mysql_error());
}
// Conexin con la base de datos
mysql_select_db("groupweb") or die("Error: " . mysql_error());
return $conexion;
}
//************************************************************************
// DESCONECTA_DB: realiza la desconexin con la base de datos
// Entrada:
- Identificador de la conexin con la base de datos => $conexion
// Salida: - Ninguna
//************************************************************************
function desconecta_db(&$conexion) {
mysql_close($conexion);
}
//*******************************************************************
// LIBERA_RECURSO: realiza la liberacin de los recursos
// Entrada:
- Identificador del recurso de la base de datos => $recurso
// Salida: - Ninguna
//*******************************************************************
function libera_recurso($recurso) {
mysql_free_result($recurso);
}
//******************************************************************
// VALIDA_USUARIO: realiza la validacin del usuario introducido
// Entrada:
- Login del usuario a validar => $login
//
- Contrasea del mismo => $password
// Salida: - Bandera con valor TRUE si el usuario se valid con xito
//
o FALSE en caso contrario => $validado
//******************************************************************
function valida_usuario($login, $password) {
$validado = FALSE;
$peticion_sql = "SELECT password FROM people WHERE login='" . $login . "'";
$resultado = mysql_query($peticion_sql) or die("Error, la consulta fall: "
. mysql_error());
while ($linea = mysql_fetch_array($resultado, MYSQL_ASSOC)) {
if ($linea["password"] == $password)
$validado = TRUE;
}
libera_recurso($resultado);
return $validado;
}
//**************************************************************************
// LISTA_TABLAS: almacena en un array todas las tablas existentes en la base
//
de datos

138

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Entrada:
- Ninguna
// Salida: - Array con las tablas de la base de datos => $tablas_db
//**************************************************************************
function lista_tablas() {
$resultado = mysql_list_tables("groupweb");
$i = 0;
while ($i < mysql_num_rows ($resultado)) {
$tablas_db[$i] = mysql_tablename ($resultado, $i);
$i++;
}
libera_recurso($resultado);
return $tablas_db;
}
//*******************************************************************************
// INFO_CAMPOS: devuelve el tipo y el nombre de cada campo de cada una de las
//
tablas de una base de
//
datos contenidas en el array pasado
// Entrada:
- Array con los nombres de las tablas de la base de datos => $tablas
//
- Array para almacenar los tipos de los campos de cada tabla =>
//
$tipo_campos
//
- Array para almacenar los nombres de los campos de cada tabla =>
//
$nombre_campos
// Salida: - Ninguna
//*******************************************************************************
function info_campos($tablas, &$tipo_campos, &$nombre_campos) {
$i = 0;
while ($i < count($tablas)) {
$resultado = mysql_query("SELECT * FROM " . $tablas[$i]);
$fields = mysql_num_fields($resultado);
$j = 0;
while ($j < $fields) {
$type = mysql_field_type ($resultado, $j);
$name = mysql_field_name ($resultado, $j);
$nombre_campos[$i][$j] = $name;
$tipo_campos[$i][$j] = $type;
$j++;
}
$i++;
}
libera_recurso($resultado);
}
//*******************************************************************************
// INFO_CAMPOS_ASOC: devuelve el tipo y el nombre de cada campo de cada una de
//
las tablas de una base de datos contenidas en el array pasado, pero
//
utilizando como ndices de la primera dimensin del array los nombres de
//
las tablas
// Entrada:
- Array con los nombres de las tablas de la base de datos => $tablas
//
- Array para almacenar los tipos de los campos de cada tabla =>
//
$tipo_campos
//
- Array para almacenar los nombres de los campos de cada tabla =>
//
$nombre_campos
// Salida: - Ninguna
//*******************************************************************************
function info_campos_asoc($tablas, &$tipo_campos, &$nombre_campos) {
$i = 0;
while ($i < count($tablas)) {
$resultado = mysql_query("SELECT * FROM " . $tablas[$i]);
$fields = mysql_num_fields($resultado);
$j = 0;
while ($j < $fields) {
$type = mysql_field_type ($resultado, $j);
$name = mysql_field_name ($resultado, $j);
$nombre_campos[$tablas[$i]][$j] = $name;

139

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$tipo_campos[$tablas[$i]][$j] = $type;
$j++;
}
$i++;
}
libera_recurso($resultado);
}
//***************************************************************************
// BORRA_DIR_TEMP: borra el contenido del directorio facilitado
// Entrada:
- Ruta del directorio cuyo contenido se desea borrar => $directorio
// Salida: - Ninguna.
//***************************************************************************
function borra_dir_temp($directorio) {
$manejador = opendir($directorio);
$lista = "";
while ($fichero = readdir($manejador))
if(!is_dir($fichero) && !is_link($fichero))
unlink($directorio."\/".$fichero);
}
//*******************************************************************************
// BUSCA_APELLIDO_REG: busca el apellido de la referencia bibliogrfica de las
//
personas registradas como usuarios del sitio web GROUPWEB
// Entrada:
- Array con los nombres de los autores registrados en el sistema =>
//
$nombres
// Salida:
- Array con los primeros apellidos de los autores => $apellidos
//*******************************************************************************
function busca_apellido_reg ($nombres) {
for ($i=0;$i<count($nombres);$i++) {
$nombres[$i] = trim($nombres[$i]);
if ($apellido = strtok($nombres[$i], ",")) {
if (stripos($apellido, " ")) {
$salir = FALSE;
$apellido = strtok($nombres[$i], " ");
while (($apellido != FALSE) && ($salir != TRUE)) {
if (($apellido != "el") && ($apellido != "la") &&
($apellido != "los") && ($apellido != "las") &&
($apellido != "de") && ($apellido != "da") &&
($apellido != "del") &&
(stripos($apellido, ".") == FALSE)) {
$apellidos[$i] = strtolower(quita_tildes($apellido));
$salir = TRUE;
}
}
}
else
$apellidos[$i] = strtolower(quita_tildes($apellido));
} else {
$apellido = strtok($nombres[$i], " ");
$apellidos[$i] = strtolower(quita_tildes($apellido));
}
}
return $apellidos;
}
//******************************************************************************
// QUITA_TILDES: elimina las tildes y el carcter "" de la cadena pasada como
//
argumento
// Entrada:
- Cadena de caracteres a la que se desea quitar las tildes =>
//
$cadena
// Salida:
- Cadena sin tildes => $cadena
//******************************************************************************
function quita_tildes($cadena)
{

140

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$cadena = str_replace("",
$cadena = str_replace("",
$cadena = str_replace("",
$cadena = str_replace("",
$cadena = str_replace("",
$cadena = str_replace("",
return $cadena;

"a",
"e",
"i",
"o",
"u",
"n",

$cadena);
$cadena);
$cadena);
$cadena);
$cadena);
$cadena);

}
//*******************************************************************************
// BUSCA_APELLIDO_AUTOR: busca el primer apellido del autor pasado en la cadena
//
$autor. Primero comprueba los autores registrados, que se encuentran en la
//
tabla $apellidos_reg.
// Entrada:
- Nombre del autor => $autor
//
- Array con los apellidos de los autores registrados =>
//
$apellidos_reg
// Salida: - Primer apellido del autor pasado => $reference
//*******************************************************************************
function busca_apellido_autor ($autor, $apellidos_reg) {
// La primera bsqueda es para los autores del grupo, que tienen
// su nombre bibliogrfico en la base de datos
$pos = -1;
$nombre_completo = quita_tildes(strtolower($autor));
for ($k=0;$k<count($apellidos_reg);$k++) {
$back = stripos(" " . $nombre_completo ,$apellidos_reg[$k]);
if ($back != FALSE)
$pos = $k;
}
if ($pos != - 1)
$reference = strtolower($apellidos_reg[$pos]);
// Si la bsqueda no ha tenido xito, es que el autor no
// pertenece al grupo. Se obtiene entonces el apellido.
else {
$palabra = strtok($nombre_completo, " ");
$k = -1;
// Insertamos en un array los nombres y apellidos
$nombre_completo = $nombre_completo . " ";
while ($palabra != FALSE) {
$k++;
$nombre[$k] = $palabra;
$palabra = strtok(" ");
}
// Buscamos una coma. Si sta existe en alguno de
// los campos, quiere decir que lo primero son los apellidos.
$coma = FALSE;
for ($k=0;$k<count($nombre);$k++) {
if (stripos($nombre[$k], ","))
$coma = TRUE;
}
if ($coma == TRUE) {
// Si existe coma, buscamos el primer
// apelllido que no se encuentre abreviado
$k = 0;
$encontrado = FALSE;
while (!$encontrado) {
if (stripos(" ".$nombre[$k], ".")) {
$k++;
} elseif (strlen($nombre[$k]) < 4) {
// Aqu se tienen en cuenta los artculos
// y preposiciones de los apellidos
switch (strtolower($nombre[$k])) {
case "de":
$k++;
break;

141

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


case "del":
$k++;
break;
case "la":
$k++;
break;
case "el":
$k++;
break;
case "las":
$k++;
break;
case "los":
$k++;
break;
case "da":
$k++;
break;
default:
$encontrado = $k;
break;
}
} else {
$encontrado = $k;
}
}
$reference = strtolower(rtrim(ltrim($nombre[$encontrado])));
}
// Si no existen comas, entonces se escoge la segunda palabra empezando
// por el final que tenga ms de 3 letras. Tambin hay que tener cuidado
// en esto, pues mucha gente suele poner el segundo apellido abreviado.
// Hay que buscar puntos, en consecuencia.
else {
$primer_apellido = FALSE;
$segundo_apellido = FALSE;
for ($k=(count($nombre) - 1);$k>-1;$k--) {
if (stripos(" ".$nombre[$k], ".") != FALSE) {
if ($segundo_apellido == FALSE)
$segundo_apellido = $nombre[$k];
else if ($primer_apellido == FALSE)
$primer_apellido = $nombre[$k];
} else if (strlen($nombre[$k]) < 4){
// Aqu se tienen en cuenta los artculos y
// preposiciones de los apellidos
switch (strtolower($nombre[$k])) {
case "de":
break;
case "del":
break;
case "la":
break;
case "el":
break;
case "las":
break;
case "los":
break;
case "da":
break;
default:
if ($segundo_apellido == FALSE)
$segundo_apellido = $nombre[$k];
else if ($primer_apellido == FALSE)
$primer_apellido = $nombre[$k];
break;

142

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
} else if ($segundo_apellido == FALSE) {
$segundo_apellido = $nombre[$k];
} else if ($primer_apellido == FALSE) {
$primer_apellido = $nombre[$k];
}
}
if ((stripos($primer_apellido, ".") == FALSE) && (count($nombre) > 2))
$reference = $primer_apellido;
else
$reference = $segundo_apellido;
$reference = quita_tildes(strtolower(rtrim(ltrim($reference))));
}
}
return $reference;
}
//******************************************************************************
// GENERA_ARRAYS: genera ararys que contienen las siglas de las publicaciones y
//
las palabras claves de stas para la ulterior bsqueda de la publicacin en
//
la entrada correspondiente del fichero de actualizacin.
// Entrada:
- Nombre del archivo que contiene la informacin de las revistas y
//
congresos => $pubs_file
//
- Array con los nombres de las tablas de la base de datos => $tablas_db
//
- Array para almacenar las palabras claves de los nombres de los
//
congresos => $congresos
//
- Array para almacenar las siglas de los nombres de los congresos =>
//
$siglas
//
- Array para almacenar las palabras claves de los nombres de las revistas
//
=> $revistas
//
- Array para almacenar las siglas de los nombres de las revistas =>
//
$siglas_rev
// Salida: - Ninguna
//******************************************************************************
function genera_arrays ($pubs_file, $tablas_db, &$congresos, &$siglas,
&$revistas, &$siglas_rev)
{
for ($i=0;$i<count($tablas_db);$i++) {
if ($tablas_db[$i] == "congress") {
$j = 0;
// ndice que se incrementa con cada congreso
// Se modifica la tabla "congress" => cargamos en arrays
// las abreviaturas y palabras claves de cada congreso.
$archivo = fopen($pubs_file, "r"); // Apertura del fichero
$inicio = FALSE;
$salir = FALSE;
if ($archivo) {
while (!feof($archivo)) {
// Paso 1: Obtener una fila de la tabla (NOTA 1: fgets lee
// hasta fin de fichero, fin de lnea o cuando haya ledo los
// bytes indicados; NOTA 2: Cuidado con la longitud de las lneas,
// porque pueden dar lugar a capturas errneas de datos.
unset($linea_nueva);
$linea_nueva = fgets($archivo, 1024);
// Buscamos el comienzo de los congresos => "::CONGRESS"
if (stripos(" ".$linea_nueva, "::CONGRESS")) {
$inicio = TRUE;
$salir = FALSE;
}
// Si se encuentra otra lnea que comience por "::" es que
// se trata de otro tipo de publicacin y dejamos de buscar datos
else if (stripos(" ".$linea_nueva, "::"))
$salir = TRUE;
// Aqu se realiza el relleno de la tabla
else if (($inicio == TRUE) && ($salir == FALSE)) {
// Proseguimos si no se trata de un comentario

143

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


if (stripos(" ".$linea_nueva, "//") == FALSE) {
// Obtencin de las siglas
$siglas[$j] = strtok($linea_nueva, ";");
// Obtencin de las palabras clave del congreso para la
// bsqueda del congreso
$offset = strpos($linea_nueva, ";");
$keywords = substr($linea_nueva, $offset+1);
$word = strtok($keywords, "\t");
$k = 0;
while ($word != FALSE) {
//print $word."&nbsp;";
$congresos[$j][$k] = $word;
$word = strtok("\t");
$k++;
}
//print "<br>";
$j++;
}
}
}
}
}
elseif ($tablas_db[$i] == "journals") {
$j = 0;
// ndice que se incrementa con cada congreso
// Se modifica la tabla "congress" => cargamos en arrays
// las abreviaturas y palabras claves de cada revista.
$archivo = fopen("pubs.txt", "r"); // Apertura del fichero
$inicio = FALSE;
$salir = FALSE;
if ($archivo) {
while (!feof($archivo)) {
// Paso 1: Obtener una fila de la tabla (NOTA1 : fgets lee
// hasta fin de fichero, fin de lnea o cuando haya ledo los
// bytes indicados; NOTA 2: Cuidado con la longitud de las lneas,
// porque pueden dar lugar a capturas errneas de datos.
$linea = fgets($archivo, 1024);
// Buscamos el comienzo de los congresos => "::JOURNALS"
if (stripos(" ".$linea, "::JOURNALS")) {
$inicio = TRUE;
$salir = FALSE;
}
// Si se encuentra otra lnea que comience por "::" es que
// se trata de otro tipo de publicacin y dejamos de buscar datos
elseif (stripos(" ".$linea, "::"))
$salir = TRUE;
// Aqu se realiza el relleno de la tabla
elseif (($inicio == TRUE) && ($salir == FALSE)) {
// Proseguimos si no se trata de un comentario
if (stripos(" ".$linea, "//") == FALSE) {
// Obtencin de las siglas
$siglas_rev[$j] = strtok($linea, ";");
// Obtencin de las palabras clave del congreso
// para la bsqueda de la revista
$offset = strpos($linea, ";");
$keywords = substr($linea, $offset+1);
$word = strtok($keywords, "\t");
$k = 0;
while ($word != FALSE) {
$revistas[$j][$k] = $word;
$word = strtok("\t");
$k++;
}
$j++;
}
}

144

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
}
}
}
}
//*****************************************************************
// DO_UPLOAD: realiza la copia en el servidor del fichero de actualizacin.
// Entrada:
- Nombre del fichero => $fichero
//
- Directorio de subida => $upload_dir
//
- Direccin del fichero a subir => $upload_url
//*****************************************************************
function do_upload($fichero, $upload_dir, $upload_url) {
$temp_name = $_FILES[$fichero]['tmp_name'];
$file_name = $_FILES[$fichero]['name'];
$file_name = str_replace("\\","",$file_name);
$file_name = str_replace("'","",$file_name);
$file_path = $upload_dir.$file_name;
//Comprobacin del nombre del fichero
if ( $file_name == "") {
$message = "Nombre de fichero especificado no vlido.";
return $message;
}
$result = move_uploaded_file($temp_name, $file_path);
if (!chmod($file_path,0777))
$message = "cambio de permisos a 777 fallido.";
else
$message = ($result)?"$file_name uploaded successfully." :
"Something is wrong with uploading a file.";
return $message;
}
//*****************************************************************
// SEEK_FILE: busca un fichero en una ruta determinada.
// Entrada:
- Ruta de bsqueda (en caso de encontrar el fichero,
//
se inserta en esta variable la ruta del mismo => $path
//
- Fichero a buscar => $file
//
- Bandera que indica si se ha encontrado => $found
//*****************************************************************
function seek_file(&$path, $file, &$found)
{
// Cambia al directorio de bsqueda
if (chdir($path)) {
// Si se consigue abrir....
if ($gestor = opendir('.')) {
// Mientras que no se haya encontrado el fichero
// y se pueda leer el siguiente tem del directorio....
while (($found == false) &&
(($res = readdir($gestor)) !== false))
{
if (is_dir($res) && ($res != ".") && ($res != "..")) {
$path = str_replace("\\", "/", getcwd()) . "/" . $res;
seek_file($path, $file, $found);
if ($found == false) {
chdir("../");
$path = str_replace("\\", "/", getcwd());
}
}
else if (is_executable($res)) {
if (strpos($res, $file[PHP_OS]) !== false) {
$found = true;
}
}

145

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
}
}
}
?>

10.4.1.9 FUNCTIONS .STEP 3.PHP


<?php
//************************************************************************
// CIERRA_PAGINA: cierra las etiquetas "body" y "html" del documento.
// Entrada:
- Ninguna
// Salida: - Ninguna
//************************************************************************
function cierra_pagina()
{
echo "\t</body>\n";
echo "</html>\n";
}
//************************************************************************
// TRATA_TEXTO: procesa una cadena de texto, pasando las siglas de congresos y
//
abreviaturas de cadenas a maysculas, al igual que los nmeros romanos y
//
otras palabras especiales
// Entrada:
- Cadena de texto que hay que tratar => $texto
//
- Array con las siglas de los congresos => $siglas_congreso
//
- Array con las siglas de las revistas => $siglas_revista
//
- Array con palabras especiales que deben ir en maysculas => $mayusc
//
- Array con nmeros romanos => $numbers
// Salida: - Cadena de texto tratada (por referencia) => $texto
//************************************************************************
function trata_texto(&$texto, $siglas_congreso, $siglas_revista, $mayusc,
$numbers)
{
// Se pone la primera letra de cada palabra en maysculas
$texto = trim(ucwords(strtolower(str_replace("\"", "'", $texto))));
// Se ponen en maysculas las siglas de los congresos
for ($p=0;$p<count($siglas_congreso);$p++) {
$pos = stripos(" ".$texto, $siglas_congreso[$p]);
if (($pos > 0) && !ctype_alpha($texto[$pos-2]) &&
!ctype_alpha($texto[$pos+strlen($siglas_congreso[$p])-1]))
{
$texto = substr($texto,0,$pos-1) . $siglas_congreso[$p] .
substr($texto,$pos+strlen($siglas_congreso[$p])-1,strlen($texto));
}
}
// Se ponen en maysculas las siglas de las revistas
for ($p=0;$p<count($siglas_revista);$p++) {
$pos = stripos(" ".$texto, $siglas_revista[$p]);
if (($pos > 0) && !ctype_alpha($texto[$pos-2]) &&
!ctype_alpha($texto[$pos+strlen($siglas_revista[$p])-1]) &&
(strlen($siglas_revista[$p]) > 1))
{
$texto = substr($texto,0,$pos-1) . $siglas_revista[$p] .
substr($texto,$pos+strlen($siglas_revista[$p])-1,strlen($texto));
}
}
// Se ponen en maysculas las palabras especiales que deben as
for ($p=0;$p<count($mayusc);$p++) {
$pos = stripos(" ".$texto, $mayusc[$p]);
if (($pos > 0) && !ctype_alpha($texto[$pos-2]) &&
!ctype_alpha($texto[$pos+strlen($mayusc[$p])-1]))
{

146

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$texto = substr($texto,0,$pos-1) . $mayusc[$p] .
substr($texto,$pos+strlen($mayusc[$p])-1,strlen($texto));
}
}
// Se ponen en maysculas los nmeros romanos
for ($p=0;$p<count($numbers);$p++) {
$pos = stripos(" ".$texto, $numbers[$p]);
if (($pos > 0) && !ctype_alpha($texto[$pos-2]) &&
!ctype_alpha($texto[$pos+strlen($numbers[$p])-1]))
{
$texto = substr($texto,0,$pos-1) . $numbers[$p] .
substr($texto,$pos+strlen($numbers[$p])-1,strlen($texto));
}
}
$texto = trim($texto);
}
//************************************************************************
// BUSCA_REVISTA: busca una publicacin en la coleccin de revistas disponible.
// Entrada:
- Nombres de los campos de la publicacin (tabla, nombre, etc) =>
//
$fields
//
- Valores de los campos contenidos en $fields => $fields_values
//
- Array con las palabras claves de los nombres de revistas => $journals
//
- Array con los acrnimos de las revistas => $journals_acr
//
- Bandera que se pone a 1 si se encuentra al menos una revista =>
//
$insertado
// Salida: - Cadena final para insertar en la referencia => $ref_journal
//
- Bandera que indica si se ha encontrado algn congreso
//
coincidente (por referencia) => $insertado
//************************************************************************
function busca_revista($fields, $fields_values, $journals,
$journals_acr, &$insertado)
{
unset($revista);
$insertado = false;
// Obtenemos el nombre de la revista
for ($k=0;$k < count($fields);$k++) {
if ($fields[$k] == "journal")
$revista = $fields_values[$k];
}
// Pasamos a minsculas y quitamos las tildes
$revista = quita_tildes(strtolower($revista));
// Se busca la revista en la lista de revistas de que se dispone.
$salir = FALSE;
$k = 0;
$ref_journal = "";
while ($salir == FALSE) {
unset($encontrado);
$encontrado = TRUE;
// Primero se buscan las palabras claves
for ($l=0;$l<count($journals[$k]);$l++)
{
if (!($encontrado &&
(stripos(" ".$revista." ", trim($journals[$k][$l])) != FALSE)))
{
$encontrado = FALSE;
}
}
if ($encontrado == TRUE) {
// Si ya se ha aadido alguna revista, se aade un guin separador
if ($insertado)
$ref_journal = $ref_journal . "-";
$insertado = TRUE;
$ref_journal = $ref_journal . strtoupper($journals_acr[$k]);
}

147

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


if ($k < (count($journals) - 1))
$k++;
else
$salir = TRUE;
}
return $ref_journal;
}
//************************************************************************
// BUSCA_CONGRESO: busca una publicacin en la coleccin de congresos disponible.
// Entrada:
- Nombres de los campos de la publicacin (tabla, nombre, etc) =>
//
$fields
//
- Valores de los campos contenidos en $fields => $fields_values
//
- Array con las palabras claves de los nombres de revistas => $congress
//
- Array con los acrnimos de las revistas => $congress_acr
//
- Bandera que se pone a 1 si se encuentra al menos una revista => $flag
// Salida: - Cadena final para insertar en la referencia => $ref_congress
//
- Bandera que se pone a 1 si se encuentra al menos una revista
//
(por referencia) => $flag
//************************************************************************
function busca_congreso($fields, $fields_values, $congress,
$congress_acr, &$flag)
{
unset($congreso);
// Obtenemos el nombre del congreso
for ($k=0;$k < count($fields);$k++) {
if ($fields[$k] == "booktitle")
$congreso = $fields_values[$k];
}
// Pasamos a minsculas y quitamos las tildes. Aadimos un espacio al comienzo
// porque si coincide la bsqueda justamente al comienzo de la cadena,
// "stripos" devuelve la posicin 0, que se interpreta como FALSE.
$congreso = quita_tildes(strtolower($congreso));
// Aqu se busca el congreso en la lista de congresos de que se dispone. Si no
// se encuentra el congreso de la entrada seleccionada, se muestra en pantalla
// un mensaje de error y un formulario de relleno del nuevo congreso
$salir = FALSE;
$flag = FALSE;
$k = 0;
$ref_congress = "";
while ($salir == FALSE) {
unset($encontrado);
$encontrado = TRUE;
// Primero se buscan las palabras claves
for ($l=0;$l<count($congress[$k]);$l++)
if (stripos(" ".$congreso, trim($congress[$k][$l])) == FALSE)
$encontrado = FALSE;
if ($encontrado == TRUE) {
// Si ya se ha aadido algn congreso, se aade un guin separador
if ($flag)
$ref_congress = $ref_congress . "-";
$flag = TRUE;
$ref_congress = $ref_congress . strtoupper($congress_acr[$k]);
}
if ($k < (count($congress) - 1))
$k++;
else
$salir = TRUE;
}
// Se realiza un filtrado por si hay siglas duplicadas
for ($l=0;$l<count($congress_acr);$l++) {
if ($congress_acr[$l] != "") {
// Si se encuentran dos o ms coincidencias...
if (substr_count($ref_congress, $congress_acr[$l]) > 1) {
$salir = FALSE;

148

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$subcadena = $ref_congress."-";
while ($salir == FALSE) {
// Hay que tener cuidado y eliminar solamente una de ellas
$pos = strripos($subcadena, $congress_acr[$l]);
$seccion = substr($ref_congress."-", $pos);
$sustituta = str_replace($congress_acr[$l]."-", "", $seccion);
if ($sustituta != $seccion) {
$salir = TRUE;
$sustituta = substr($subcadena, 0, $pos) . $sustituta;
} else {
$subcadena = substr($subcadena, 0, $pos);
}
}
if ($sustituta[strlen($sustituta)-1] == "-")
$ref_congress = substr($sustituta, 0, strlen($sustituta)-1);
}
}
}
return $ref_congress;
}
//************************************************************************
// GET_HTML_CONTENT: obtiene el contenido de una pgina web para un anlisis
//
posterior.
// Entrada:
- Array con las direcciones webs que se han de analizar => $urls
// Salida:
- Array con el contenido de texto que contienen las direcciones de
//
entrada => $contenido
//************************************************************************
function get_html_content($urls)
{
for ($p=0; $p<count($urls); $p++)
{
// Apertura del fichero con los hiperenlaces
$descriptor = fopen($urls[$p], "r");
$html_content = "";
while (!feof($descriptor)) {
// Obtencin del contenido de la direccin
$html_content .= fread($descriptor, 8192);
}
fclose($descriptor);
$contenido[$p] = $html_content;
}
return $contenido;
}
//************************************************************************
// GET_PDF: busca una publicacin en la coleccin de revistas disponible.
// Entrada:
- Url del pdf capturada del hiperenlace => $url_pdf
//
- Url del sitio web que contiene el hiperenlace => $url_site
// Salida: - Ruta del fichero pdf => $final_pdf_url
//************************************************************************
function get_pdf($url_pdf, $url_site)
{
// Hay que preparar la direccin del fichero
$num_levels = substr_count($url_pdf, "../");
$pos_site = strlen($url_site);
$pos_site = strrpos(substr($url_site, 0, $pos_site), "/");
for ($k=0; $k<$num_levels; $k++)
$pos_site = strrpos(substr($url_site, 0, $pos_site), "/");
if ($num_levels > 0)
$pos_pdf = strrpos($url_pdf, "../") + 3;
else
$pos_pdf = 0;
$final_pdf_url = substr($url_site, 0, $pos_site+1) .

149

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


substr($url_pdf, $pos_pdf);
// Si se ha encontrado una direccin adecuada....
if ($final_pdf_url != "")
{
// El fichero pdf se debe poder leer; en caso contrario,
// se eliminar la ruta
$desc_read = fopen($final_pdf_url, "rb");
if ($desc_read == FALSE)
$final_pdf_url = "";
}
return $final_pdf_url;
}
//************************************************************************
// BUSCA_PUBLICACION_WEB: busca una publicacin en la coleccin de revistas
//
disponible
// Entrada:
- Contenido de las direcciones web facilitadas => $html_contents
//
- Array con las direcciones webs facilitadas por el usuario => $urls
//
- Nombre de la publicacin => $titulo
//
- Siglas de los congresos => $siglas_congreso
//
- Acrnimos de las revistas => $siglas_revista
//
- Array con palabras especiales que deben ir en maysculas => $mayusc
//
- Array con nmeros romanos que deben ir en maysculas => $numbers
//
- Array en el que se insertarn las rutas y porcentajes de los
//
ficheros pdfs que se encuentren => $pdf
// Salida: - Array con las rutas de los ficheros pdf => $pdf
//************************************************************************
function busca_publicacion_web($html_contents, $urls, $titulo,
$siglas_congreso, $siglas_revista, $mayusc, $numbers, &$pdf)
{
$found = false;
$n_pdf = 0;
$html_tags = array("<b>", "</b>", "<i>", "</i>", "<ul>", "</ul>", "<ol>",
"</ol>", "<li>", "</font>", "<br />", "<br />");
$html_chars = array(9, 10, 13);
$p = 0;
while ($p < count($html_contents))
{
$pos_ini = 0;
// Bucle de bsqueda del hiperlink del pdf
do {
// Primera ocurrencia del inicio de la etiqueta hyperlink
$pos_ini = stripos($html_contents[$p], "<a href=\"", $pos_ini);
if ($pos_ini !== false) {
// Primera ocurrencia del final de la etiqueta hyperlink
$pos_fin = stripos($html_contents[$p], "</a>", $pos_ini);
if ($pos_fin !== false) {
// Se extrae la etiqueta de hyperlink
$hyperlink = substr($html_contents[$p], $pos_ini,
$pos_fin-$pos_ini);
// Se decodifican los caracteres html especiales (p.e., &quot;)
$hyperlink = htmlspecialchars_decode($hyperlink);
// Se quitan los retornos de carro y otros caracteres especiales
for ($i=0; $i<count($html_chars); $i++)
$hyperlink = str_replace(chr($html_chars[$i]), "", $hyperlink);
// Se quitan las etiquetas de formato de texto html
for ($i=0; $i<count($html_tags); $i++) {
if ($html_tags[$i] == "</font") {
if (($posicion1 = stripos($hyperlink, "<font")) !== false) {
$posicion2 = strpos($hyperlink, ">", $posicion+1);
$hyperlink = substr($hyperlink, 0, $posicion1) .
substr($hyperlink, $posicion2+1,
strlen($hyperlink)-$posicion2);
}

150

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
$hyperlink = str_replace($html_tags[$i], "", $hyperlink);
}
// Se quitan los espacios repetidos
$espacio = false;
for ($i=0; $i<strlen($hyperlink); $i++) {
if (($hyperlink[$i] == " ") && ($espacio == true))
$hyperlink = substr($hyperlink, 0, $i-1) .
substr($hyperlink, $i+1);
else if ($hyperlink[$i] == " ")
$espacio = true;
else
$espacio = false;
}
// Se busca el comienzo del nombre de la publicacin
$pos_i_tit = strpos($hyperlink, ">");
while(($pos_i_tit < strlen($hyperlink)) &&
!ctype_alnum($hyperlink[$pos_i_tit]) &&
($hyperlink[$pos_i_tit] != "<"))
{
$pos_i_tit++;
}
// Se busca el fin del nombre de la publicacin
$pos_f_tit = strlen($hyperlink);
while(($pos_i_tit < strlen($hyperlink)) &&
!ctype_alnum($hyperlink[$pos_f_tit]) &&
($hyperlink[$pos_f_tit] != ">"))
{
$pos_f_tit--;
}
$hyperlink_titulo = trim(substr($hyperlink, $pos_i_tit,
$pos_f_tit-$pos_i_tit+1));
// Se permite un error mximo de 5 letras
if (abs(strlen($hyperlink_titulo)-strlen($titulo)) < 5) {
$porcentaje = 0;
trata_texto($hyperlink_titulo, $siglas_congreso,
$siglas_revista, $mayusc, $numbers);
similar_text($titulo, $hyperlink_titulo, $porcentaje);
//Si se encuentra el ttulo en esta etiqueta...
if ((stripos($hyperlink, $titulo) > 0) || ($porcentaje > 90)) {
//... obtenemos la ruta completa del pdf...
$pos_ini += 9;
$pos_fin = stripos($html_contents[$p], "\"", $pos_ini);
$pdf_url = substr($html_contents[$p], $pos_ini,
$pos_fin - $pos_ini);
$pdf_url = get_pdf($pdf_url, $urls[$p]);
// ... y en caso de que ste sea accesible
if ($pdf_url != "") {
// ... asignamos la nueva ruta
$pdf[$n_pdf][0] = $pdf_url;
// ... y obtenemos el porcentaje de similitud
$pdf[$n_pdf][1] = $porcentaje;
$found = true;
$n_pdf++;
}
}
}
$pos_ini = $pos_fin;
}
else
$pos_ini++;
}
} while ($pos_ini > 0);
$p++;

151

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
if ($found == false) {
$pdf[$n_pdf][0] = "";
$pdf[$n_pdf][1] = "";
}
}
//************************************************************************
// REMOTE_FILE_SIZE: obtiene el tamao de un fichero
// Entrada:
- Url del fichero cuyo tamao se desea obtener => $url
// Salida: - Cadena con el tamao del fichero => $return
//************************************************************************
function remote_file_size ($url)
{
$head = "";
$url_p = parse_url($url);
$host = $url_p["host"];
$path = $url_p["path"];
$fp = fsockopen($host, 80, $errno, $errstr, 20);
if(!$fp)
{ return false; }
else
{
fputs($fp, "HEAD ".$url." HTTP/1.1\r\n");
fputs($fp, "HOST: dummy\r\n");
fputs($fp, "Connection: close\r\n\r\n");
$headers = "";
while (!feof($fp)) {
$headers .= fgets ($fp, 128);
}
}
fclose ($fp);
$return = false;
$arr_headers = explode("\n", $headers);
foreach($arr_headers as $header) {
$s = "Content-Length: ";
if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
$return = substr($header, strlen($s));
break;
}
}
return $return;
}
//************************************************************************
// ABRE_FORMULARIO: inserta la etiqueta HTML de apertura de un formulario
// Entrada:
- Ninguna
// Salida: - Ninguna
//************************************************************************
function abre_formulario()
{
echo "\t\t<form name='upload' id='upload' action='paso3.php' "
. "ENCTYPE='multipart/form-data' method='POST'>\n";
}
//************************************************************************
// CIERRA_FORMULARIO: inserta la etiqueta HTML de cierre de un formulario
// Entrada:
- Ninguna
// Salida: - Ninguna
//************************************************************************
function cierra_formulario()
{
echo "\t\t</form>\n";
}

152

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


//************************************************************************
// IMPRIME_RESULTADOS: imprime en el documento actual del navegador los
//
resultados de la bsqueda del sistema, esto es, cada una de las entradas
//
analizadas junto con los datos extrados.
// Entrada:
- Array con los valores de los campos devueltos del anlisis de
//
todos los datos facilitados por el usuario => $campos_def
//
- Array con los valores de los campos adicionales resultado del
//
anlisis de todos los datos facilitados por el usuario =>
//
$campo_def_add
//
- Array con los nombres de los campos de las tablas de la base de datos
//
=> $campos_tablas
//
- Array con los mensajes de error que se pueden mostrar =>
//
$mensajes_error
//
- Array que indica cul de las urls de pdfs es la que se encuentra
//
seleccionada actualmente => $mark
// Salida: - Ninguna
//************************************************************************
function imprime_resultados($campos_def, $campo_def_add,
$campos_tablas, $mensajes_error, $mark)
{
$def_offset = count($campo_def_add);
for ($def_count=0; $def_count<count($campos_def); $def_count++)
{
echo "\t\t\t<table border='0' width='100%' >\n";
// Impresin del nombre de la tabla
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td>Tabla:</td>\n\t\t\t\t\t<td>" .
$campos_def[$def_count][$campo_def_add["tabla"]] .
"</td>\n\t\t\t\t</tr>\n";
// Impresin de los campos que pertenecen lcitamente a la tabla
for ($j=0; $j<count($campos_def[$def_count])-$def_offset; $j++)
{
if
($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]][$j] != "id")
{
echo "\t\t\t\t<tr>\n";
echo "\t\t\t\t\t<td valign=\"top\">" .
ucwords($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]][$j])
. ":</td>\n";
echo "\t\t\t\t\t<td>";
if
($campos_tablas[$campos_def[$def_count][$campo_def_add["tabla"]]][$j] ==
"abstract")
{
echo "<textarea name='field" . $def_count . "-" .
($j+$def_offset) . "' cols=\"90\" rows=\"5\">" .
$campos_def[$def_count][$j+$def_offset] . "</textarea>";
}
else
echo "<input type='text' name='field" . $def_count . "-" .
($j+$def_offset) . "' size='120' value=\"" .
$campos_def[$def_count][$j+$def_offset] . "\" />";
echo "</td>\n";
echo "\t\t\t\t</tr>\n";
}
}
// Impresin del campo "autores"
echo "\t\t\t\t<tr>\n";
echo "\t\t\t\t\t<td>Autores:</td>\n";
echo "\t\t\t\t\t<td>";
echo "<input type='text' name='field" . $def_count . "-" .
$campo_def_add["authors"] . "' size='120' value=\"" .
ucwords(strtolower($campos_def[$def_count][$campo_def_add["authors"]])) .
"\" />";

153

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


echo "</td>\n";
echo "\t\t\t\t</tr>\n";
// Impresin del campo correspondiente al fichero pdf
echo "\t\t\t\t<tr>\n";
echo "\t\t\t\t\t<td valign=top>PDF File:</td>\n";
$n_pdfs = count($campos_def[$def_count][$campo_def_add["pdf"]]);
echo "\t\t\t\t\t<td>\n";
$porcentaje = 0;
$pos = -1;
if ($n_pdfs > 1) {
if (!isset($mark[$def_count][$campo_def_add["pdf"]][0])) {
for ($k=0; $k<$n_pdfs; $k++)
{
if ($campos_def[$def_count][$campo_def_add["pdf"]][$k][1] >
$porcentaje)
{
$porcentaje =
$campos_def[$def_count][$campo_def_add["pdf"]][$k][1];
$pos = $k;
}
}
}
else {
for ($k=0; $k<$n_pdfs; $k++)
{
if ($mark[$def_count][$campo_def_add["pdf"]][$k] == 1) {
$pos = $k;
}
}
}
}
for ($k=0; $k<$n_pdfs; $k++) {
$mensaje = "";
// Si hay varios enlaces de ficheros, entonces
// se muestran botones tipo radio
if ($n_pdfs > 1) {
$mensaje = "\t\t\t\t\t\t<input type='radio' id='pdf_check" .
$def_count . "-" . $k . "' name='pdf_check" . $def_count .
"' value='" . $k . "'";
if ($k == $pos)
$mensaje .= " checked";
$mensaje .= " />\n";
}
// Se aade el campo de texto con la direccin del pdf
$mensaje .= "\t\t\t\t\t\t<input type='text' id='url" . $def_count .
"-" . $k . "' name='url" . $def_count . "-" . $k . "' value=\"" .
str_replace("\\\\", "\\",
$campos_def[$def_count][$campo_def_add["pdf"]][$k][0])
. "\" size='95' onclick=\"change('" . $def_count . "', '" .
$k . "', 'url');\" />\n";
// En caso de tratarse de un fichero que facilita el usuario
// manualmente no se muestra porcentaje de coincidencia alguno
if ($campos_def[$def_count][$campo_def_add["pdf"]][$k][1] == "0") {
$mensaje .= "\t\t\t\t\t\t<span id='percent_" . $def_count .
"_" . $k . "'>(&nbsp;&nbsp;Custom&nbsp;&nbsp;)</span>\n";
$mensaje .= "\t\t\t\t\t\t<input type='button' id='change_pdf_bt_" .
$def_count . "_" . $k . "' " . "value='Cambiar' " .
"onclick=\"change_pdf_file('" . $def_count . "', '" .
$k . "', 'url');\" />" . "<br />\n";
}
// En cualquier otro caso, se muestra el porcentaje de coincidencia
else {
$mensaje .= "\t\t\t\t\t\t<span id='percent_" .
$def_count . "_" . $k . "'>(" .
sprintf("%.2f",

154

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$campos_def[$def_count][$campo_def_add["pdf"]][$k][1]) .
" %)</span>\n";
$mensaje .= "\t\t\t\t\t\t<input type='button' id='change_pdf_bt_" .
$def_count . "_" . $k . "' " . "value='Cambiar' " .
"onclick=\"change_pdf_file('" . $def_count . "', '" .
$k . "', 'url');\" />" . "<br />\n";
}
echo $mensaje;
}
echo "\t\t\t\t\t\t<input type='checkbox' id='req_pdf" . $def_count .
"' name='req_pdf" . $def_count
. "' value='1' ";
if (isset($_POST["req_pdf" . $def_count]))
echo "checked ";
echo "/>No deseo especificar ningn fichero .pdf<br />\n";
echo "\t\t\t\t\t</td>\n";
echo "\t\t\t\t</tr>\n";
set_form($formulario);
// Si ha habido errores, entonces se muestran los
// campos de texto correspondientes ms los fallos
$contador = 0;
$tok = strtok($campos_def[$def_count][$campo_def_add["error"]], "*");
while ($tok !== false) {
$tokens[$contador] = $tok;
$contador++;
$tok = strtok("*");
}
if ($campos_def[$def_count][$campo_def_add["error"]] != "") {
for ($n=0; $n<count($tokens); $n++) {
switch ($tokens[$n]) {
case "revista":
case "congreso":
echo "\t\t\t\t<tr>\n";
echo "\t\t\t\t\t<td valign=top>Error:</td>\n";
echo "\t\t\t\t\t<td bgcolor=red>" .
$mensajes_error[$tokens[$n]] . "</td>\n";
echo "\t\t\t\t</tr>\n";
echo "\t\t\t\t\t<td></td>\n";
echo "\t\t\t\t\t<td>\n\t\t\t\t\t<table>\n";
echo "\t\t\t\t\t\t\t<tr>\n";
echo "\t\t\t\t\t\t\t\t<td>Descripcin:</td>\n";
echo "\t\t\t\t\t\t\t\t<td><input type='text' name='comment" .
$def_count . "' size='80' /><br /></td>\n";
echo "\t\t\t\t\t\t\t</tr>\n";
echo "\t\t\t\t\t\t\t<tr>\n";
echo "\t\t\t\t\t\t\t\t<td>Palabras clave:</td>\n";
echo "\t\t\t\t\t\t\t\t<td><input type='text' name='keywords" .
$def_count . "' size='80' /><br /></td>\n";
echo "\t\t\t\t\t\t\t</tr>\n";
echo "\t\t\t\t\t\t\t<tr>\n";
echo "\t\t\t\t\t\t\t\t<td>Siglas:</td>\n";
echo "\t\t\t\t\t\t\t\t<td><input type='text' name='abbrev" .
$def_count . "' size='80' /><br /></td>\n";
echo "\t\t\t\t\t\t\t</tr>\n";
echo "\t\t\t\t\t\t\t<tr>\n";
echo "\t\t\t\t\t\t\t\t<td colspan=2><input type=hidden " .
"name='tabla_modif" . $def_count."' value='" .
$campos_def[$def_count][$campo_def_add["tabla"]].
"' /><br /></td>\n";
echo "\t\t\t\t\t\t\t</tr>\n";
echo "\t\t\t\t\t\t</table>\n\t\t\t\t\t</td>\n";
break;
case "fecha":
case "autores":

155

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


case "titulo":
echo "\t\t\t\t<tr>\n";
echo "\t\t\t\t\t<td valign=top>Error:</td>\n";
echo "<td bgcolor=red>" . $mensajes_error[$tokens[$n]] .
"</td>\n";
echo "\t\t\t\t</tr>\n";
break;
default:
break;
}
}
}
unset($tokens);
if ($campos_def[$def_count][$campo_def_add["error"]] == "") {
// Solamente se muestra la posibilidad de "entrada completa"
// si no hay errores
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=2><input " .
"type='checkbox' id='finished" . $def_count . "' name='finished" .
$def_count . "' /><label for=\"finished" . $def_count .
"\">Active esta casilla si esta entrada ya est completa" .
"</label></td>\n";
echo "\t\t\t\t</tr>\n";
// Tambin se muestra una casilla para el caso en que no se
// quiera aadir una entrada
echo "\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=2><input " .
"type='checkbox' id='nondesired" . $def_count . "' name='nondesired" .
$def_count . "' /><label for=\"nondesired" . $def_count .
"\">En caso de no querer aadir esta entrada, active esta casilla" .
"</label></td>\n";
echo "\t\t\t\t</tr>\n";
}
echo "\t\t\t</table>\n\t\t\t<br />\n";
echo "\t\t\t<hr noshade size='8' />\n";
}
}
//************************************************************************
// SET_FORM: activa una bandera que indica si hay que mostrar el formulario de
//
actualizacin de la base de datos o no.
// Entrada:
- Bandera => $formulario
// Salida: - Ninguna
//************************************************************************
function set_form(&$formulario)
{
if ($formulario == 0)
$formulario = 1;
}
//************************************************************************
// CODIGO_JAVASCRIPT: inserta funciones javascript (una abre la nueva ventana
//
de copia de ficheros, y las restantes se utilizan para cambiar la
//
naturaleza del campo de entrada de seleccin de fichero).
// Entrada:
- Bandera que indica si el formulario de actualizacin de la base de
//
datos se ha de mostrar => $formulario
//
- Ruta del fichero que almacena los nombres de los ficheros pdf a
//
subir al servidor => $log_file
// Salida: - Ninguna
//************************************************************************
function codigo_javascript($formulario, $log_file)
{
print "\t\t<script type=\"text/javascript\">";
print "\n\t\t\tvar winName=\"Progreso de la copia de ficheros\"";
print "\n\t\t\tvar sec_window;";
print "\n\t\t\tfunction Abrir_Ventana(theURL, w, h) {" .
"\n\t\t\t\tvar winl = (screen.width-w)/2;" .

156

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


"\n\t\t\t\tvar wint = (screen.height-h)/2;" .
"\n\t\t\t\tif (winl < 0) winl = 0;" .
"\n\t\t\t\tif (wint < 0) wint = 0;" .
"\n\t\t\t\tvar windowprops =\"top=\"+wint+\",left=\"+winl+\"," .
"toolbar=no,location=no,status=no, " .
"menubar=no,scrollbars=no, resizable=no,width=\" + w + \",height=\" + h;" .
"\n\t\t\t\tsec_window = window.open(theURL,winName,windowprops);" .
"\n\t\t\t}\n";
print "\t\t\tfunction change_pdf_file(id1, id2, str)\n" .
"\t\t\t{\n" .
"\t\t\t\tvar name = str + id1 + \"-\" + id2;\n" .
"\t\t\t\tvar object = document.getElementById(name);\n" .
"\t\t\t\tobject.type = \"file\";\n" .
"\t\t\t\tobject.size = \"107\";\n" .
"\t\t\t\tdocument.getElementById(\"change_pdf_bt_\" + id1 + \"_\" + id2)." .
"style.visibility = \"hidden\";\n" .
"\t\t\t\tdocument.getElementById(\"percent_\" + id1 + \"_\" + id2)." .
"innerHTML = \"\";\n" .
"\t\t\t}\n";
print "\t\t\tfunction change(id1, id2, str)\n" .
"\t\t\t{\n" .
"\t\t\t\tvar name = str + id1 + \"-\" + id2;\n" .
"\t\t\t\tvar object = document.getElementById(name);\n" .
"\t\t\t\tdocument.getElementById(name).onChange = change;\n" .
"\t\t\t\tif (object.type == \"file\")\n" .
"\t\t\t\t{\n" .
"\t\t\t\t\tvar url = object.value;\n" .
"\t\t\t\t\tobject.type = \"text\";\n" .
"\t\t\t\t\tobject.value = url;\n" .
"\t\t\t\t\tdocument.getElementById(\"change_pdf_bt_\" + id1 + \"_\" + " .
"id2).style.visibility = \"visible\";\n" .
"\t\t\t\t}\n" .
"\t\t\t}\n";
print "\t\t</script>\n";
// En caso de que sea la primera vez que se ejecuta la aplicacin, se procede
// al borrado del contenido del fichero que contiene la informacin de los
// nombres de los pdfs
if ($formulario == 0) {
$desc_write = fopen($log_file, "w");
if ($desc_write != false)
fclose($desc_write);
}
}
//************************************************************************
// IMPRIME_MENSAJE_BIENVENIDA: muestra informacin concerniente al paso
//
3 de la actualizacin de la base de datos.
// Entrada:
- Bandera que indica si el formulario de actualizacin de la base de
//
datos se ha de mostrar => $formulario
//
- Ruta del fichero que almacena los nombres de los ficheros pdf a
//
subir al servidor => $log_file
// Salida: - Ninguna
//************************************************************************
function imprime_mensaje_bienvenida($formulario, $log_file)
{
print "<html>\n";
print "\t<head>\n";
codigo_javascript($formulario, $log_file);
print "\t</head>\n";
print "\t<body>\n";
print "\t\t<h2>Actualizacin automtica de la Base de Datos</h2><br />" .
"\n\t\t<h3>Paso 3: Introduccin de los datos de las publicaciones en caso" .
" de no tener constancia de las mismas.</h3><br />A continuacin se " .
"muestran, separados mediante barras horizontales, las entradas de los " .
"ficheros indicados en el paso 1 que no concuerdan con ninguna de las " .

157

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


"publicaciones de que se disponen en este momento.<br />Asimismo, se le " .
"facilita un formulario justo debajo de la entrada no registrada para " .
"que aada el nombre de la publicacin, sus siglas y el conjunto de " .
"palabras claves que se emplearn en la bsqueda posteriormente.<br />" .
"<br />";
print "NOTA 1: si la publicacin aparece repetida varias veces, solamente " .
"debe introducir una vez los datos en los formularios.<br />";
print "NOTA 2: inserte las palabras clave separadas por espacios simples " .
"(ni tabuladores ni retornos de carro).<br />";
print "NOTA 3: para registrar una nueva publicacin se requieren los tres " .
"campos citados anteriormente OBLIGATORIAMENTE.<br />";
print "NOTA 4: si modifica el nombre de los autores, el ao o el ttulo de " .
"la publicacin, asegrese de modificar tambin la referencia, as como " .
"de verificar la exactitud de los ficheros pdfs encontrados, pues se " .
"realizaron con la referencia errnea.<br />";
print "NOTA 5: no aada letras al final de las referencias. En caso de que " .
"ya exista una entrada similar, el sistema aadir la letra pertinente " .
"al final de la referencia en cuestin.<br /><br /><br />\n";
}
//************************************************************************
// ELIMINA_ENTRADA: borra una fila del array que contiene los valores de los
//
campos correspondientes a las entradas que se han de insertar en la base
//
de datos.
// Entrada:
- Array con los valores de los campos para la actualizacin =>
//
$campos_def
//
- ndice de la entrada que se ha de eliminar => $entrada
// Salida:
- Array con la entrada eliminada
//************************************************************************
function elimina_entrada($campos_def, $entrada)
{
$new_ind = 0;
for ($i=0; $i<count($campos_def); $i++) {
if ($i != $entrada) {
$nueva_tabla[$new_ind] = $campos_def[$i];
$new_ind++;
}
}
return $nueva_tabla;
}
//************************************************************************
// CREA_ORDEN_SQL: crea una cadena con una sentencia SQL para actualizar una
//
nueva entrada de la base de datos.
// Entrada:
- Array con los valores de los campos de la entrada a actualizar =>
//
$entrada
//
- Campos adicionales necesarios para la actualizacin => $campo_def_add
//
- Nombres de los campos de la tabla a actualizar => $campos_tablas
// Salida: - Cadena con la orden SQL => $sentencia_SQL
//************************************************************************
function crea_orden_sql($entrada, $campo_def_add, $campos_tablas)
{
// Creacin de la orden SQL
$sentencia_SQL = "INSERT INTO " . $entrada[$campo_def_add["tabla"]] . " (";
$valores = "";
for ($k=0; $k<count($campos_tablas[$entrada[$campo_def_add["tabla"]]]); $k++)
{
if ($campos_tablas[$entrada[$campo_def_add["tabla"]]][$k] != "id")
{
$sentencia_SQL .= $campos_tablas[$entrada[$campo_def_add["tabla"]]][$k];
$valores .= "\"" . $entrada[$k+count($campo_def_add)] . "\"";
if ($k != (count($campos_tablas[$entrada[$campo_def_add["tabla"]]]) - 1))
{
$sentencia_SQL .= ",";
$valores .= ",";

158

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
}
}
$sentencia_SQL .= ") VALUES (" . $valores . ");";
return $sentencia_SQL;
}
//************************************************************************
// BUSCA_ENTRADA_SIMILAR: busca una entrada dada en la tabla que se va a
//
actualizar para comprobar si ya existe otra entrada idntica.
// Entrada:
- Objeto con los resultados de una consulta SQL solicitando todos
//
los ttulos y referencias de las publicaciones de la tabla => $resultado
//
- Array con los valores de los campos de la entrada a actualizar =>
//
$entrada
//
- Campos adicionales necesarios para la actualizacin => $campo_def_add
//
- Nombres de los campos de la tabla a actualizar => $campos_tablas
//
- Nmero de referencias similares a la buscada => $num_refs
// Salida: - Bandera que indica si se han encontrado entradas similares en
//
la base de datos => $salir
//
- Nmero de referencias encontradas similares a la buscada
//
(por referencia) => $num_refs
//************************************************************************
function busca_entrada_similar($resultado, $entrada,
$campo_def_add, $campos_tablas, &$num_refs)
{
$ind_title = -1;
$ind_ref = -1;
$salir = false;
// Se buscan las posiciones del ttulo y la referencia
for ($k=0; $k<count($campos_tablas[$entrada[$campo_def_add["tabla"]]]); $k++)
{
if ($campos_tablas[$entrada[$campo_def_add["tabla"]]][$k] == "title")
$ind_title = $k + count($campo_def_add);
if ($campos_tablas[$entrada[$campo_def_add["tabla"]]][$k] == "reference")
$ind_ref = $k + count($campo_def_add);
}
while ($row = mysql_fetch_assoc($resultado)) {
if (strcasecmp(trim($row["title"]), $entrada[$ind_title]) == 0)
{
// Se toma la referencia de la BD y se quitan las posibles
// letras al final debidas a referencias repetidas
$terminar = FALSE;
$m = strlen($row["reference"]);
while (($terminar != TRUE) && ($m > 0)) {
if (ctype_digit($row["reference"][$m]))
$terminar = TRUE;
else
$m--;
}
$ref_db = substr($row["reference"], 0, $m + 1);
// En caso de que coincidan el ttulo y la referencia
// se toma como entrada idntica
if (strcasecmp(trim($ref_db),
trim($entrada[$ind_ref])) == 0)
{
$salir = TRUE;
}
}
if (stripos(trim($row["reference"]),
trim($entrada[$ind_ref])) !== false)
{
$num_refs++;
}
}
// Devuelve TRUE en caso de que exista una entrada

159

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// similar en la base de datos; FALSE en caso contrario
return $salir;
}
//************************************************************************
// OBTAIN_AUTHORS: separa los nombres de los autores en palabras sueltas y las
//
inserta en un array.
// Entrada:
- Cadena con los nombres de los autores => $autores
//
- Separador de los nombres de autores => $separador
// Salida: - Array con los nombres de los autores separados y a su vez cada
//
nombre separado en palabras => $authors
//************************************************************************
function obtain_authors($autores, $separador)
{
$tok = strtok ($autores, $separador);
$num_tok = 0;
while ($tok !== false) {
$token[$num_tok] = $tok;
$num_tok++;
$tok = strtok($separador);
}
// Se obtiene el nmero de autores ===> $num_tok
// Para cada autor, se separan todas las palabras del
// nombre en tokens ===> $autores
$num_autores = $num_tok;
for ($j=0;$j<$num_autores;$j++) {
$tok = strtok ($token[$j]," ");
$num_tok = 0;
while ($tok !== false) {
$authors[$j][$num_tok] = quita_tildes(strtolower(trim($tok)));
$num_tok++;
$tok = strtok(" ");
}
}
return $authors;
}
//************************************************************************
// BUSCA_AUTOR: busca un autor determinado en el conjunto de autores
//
pertenecientes al grupo de control predictivo.
// Entrada:
- Autor de la publicacin => $autor
//
- Autores del grupo de control predictivo => $autores_grupo
// Salida:
- ndice para buscar el autor en el array de autores del grupo
//
(vale -1 si no se encuentra) => $people
//************************************************************************
function busca_autor($autor, $autores_grupo)
{
$fin_busqueda = false;
$encontrado = true;
$people = -1;
$k = 0;
while (($fin_busqueda == FALSE) && ($k < count($autores_grupo))) {
$encontrado = TRUE;
// Bucle para cada palabra del nombre del autor de la publicacin
// "autor" -> autor de la publicacin;
// "autores_grupo" -> autores del grupo de control predictivo
for ($l=0;$l<count($autor);$l++) {
// Buscamos la palabra
if (($encontrado == TRUE) &&
(stripos(" ".$autores_grupo[$k], $autor[$l]) == FALSE))
{
// Si no se ha encontrado, se comprueba si hay alguna abreviatura
if (stripos($autor[$l], ".")) {
// Abreviatura en el autor de la publicacin
// Obtencin de la inicial de la abreviatura

160

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


$inicial = strtok($autor[$l], ".");
$word = strtok ($autores_grupo[$k]," ");
$salir = FALSE;
while (($word !== false) && ($salir != TRUE)) {
if (trim($word) == ($inicial."."))
$salir = TRUE;
$word = strtok(" ");
}
if ($salir !== TRUE)
$encontrado = FALSE;
} elseif (stripos($autores_grupo[$k], ".")) {
// Abreviatura en el autor del grupo
$word = strtok ($autores_grupo[$k]," ");
$salir = FALSE;
while (($word !== false) && ($salir != TRUE)) {
if (stripos($word, "."))
$salir = TRUE;
$word = strtok(" ");
}
// Obtencin de la inicial de la abreviatura
$inicial = trim($word);
if ($autor[$l] != ($inicial."."))
$encontrado = FALSE;
} else {
// Si no hay abreviaturas y no se ha encontrado
// la palabra, es que no se trata de este autor
$encontrado = FALSE;
}
}
}
if ($encontrado == TRUE) {
$people = $k + 1;
$fin_busqueda = TRUE;
}
$k++;
}
return $people;
}
//************************************************************************
// CREA_ORDEN_SQL_AUTOR: crea la orden SQL para actualizar la tabla de autores
//
tras haber actualizado la tabla de la publicacin.
// Entrada:
- Orden SQL correspondiente a la actualizacin de la publicacin
//
de este autor => $orden_SQL
//
- Tipo de la publicacin => $tipo
//
- Id del autor en la tabla "people" de autores del grupo => $people
//
- Id devuelto al insertar la publicacin en la tabla => $id
//
- Orden del autor => $i
//
- Nombre del autor en caso que no pertenezca al grupo => $autor
//
- Jobcode (solamente cuando sea PHD PFC) => $jobcode
// Salida: - Orden SQL para actualizar la tabla de autores => $autor_SQL
//************************************************************************
function crea_orden_sql_autor($orden_SQL, $tipo, $people,
$id, $i, $autor, $jobcode)
{
// Autor pertenece al grupo
if ($people != -1) {
// Caso PFC PHD => Hay que insertar el JOBCODE
if ((stripos(" ".$orden_SQL, "INSERT INTO pfcs") != 0) ||
(stripos(" ".$orden_SQL, "INSERT INTO phds") != 0) ||
(stripos(" ".$orden_SQL, "INSERT INTO books") != 0))
{
$autor_SQL = "INSERT INTO authors (people,publication,type," .
"numorder,jobcode) VALUES (\"".$people."\",\"" . $id .
"\",\"" . $tipo . "\",\"" . ($i+1) . "\",\"". $jobcode .

161

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


"\");";
}
// Cualquier otro caso
else
$autor_SQL = "INSERT INTO authors (people,publication," .
"type,numorder) VALUES (\"" . $people . "\",\"" .
$id . "\",\"" . $tipo . "\",\"" . ($i+1) . "\");";
}
// Autor NO pertenece al grupo
else {
$name = "";
// Obtencin del nombre del autor no perteneciente al grupo
for ($p=0; $p<count($autor); $p++)
$name .= $autor[$p] . " ";
$name = ucwords(strtolower(trim($name)));
// Caso PFC PHD => Hay que insertar el JOBCODE
if ((stripos(" ".$orden_SQL, "INSERT INTO pfcs") != 0) ||
(stripos(" ".$orden_SQL, "INSERT INTO phds") != 0) ||
(stripos(" ".$orden_SQL, "INSERT INTO books") != 0))
{
$autor_SQL = "INSERT INTO authors (name,publication,type," .
"numorder,jobcode) VALUES (\"" . $name . "\",\"" . $id .
"\",\"" . $tipo . "\",\"" . ($i+1) . "\",\"" . $jobcode .
"\");";
}
// Cualquier otro caso
else
$autor_SQL = "INSERT INTO authors (name,publication," .
"type,numorder) VALUES (\"" . $name . "\",\"" .
$id . "\",\"" . $tipo . "\",\"" . ($i+1) . "\");";
}
return $autor_SQL;
}
//************************************************************************
// BARRA_PROGRESO: inserta el div para mostrar la informacin de progreso en
//
el anlisis de informacin que se hace la primera vez que se llega al
//
paso 3.
// Entrada:
- Ninguna
// Salida: - Ninguna
//************************************************************************
function barra_progreso()
{
echo "\t<div id='progress' style='position:relative;padding:" .
"0px;width:450px;height:60px;left:25px;'>";
for ($i=1; $i<=10; $i++) {
echo "\t<div style='float:left;margin:5px 0px 0px 1px;width:2px;" .
"height:12px;background:red;color:red;'> </div>";
flush();
ob_flush();
}
echo "</div>";
echo "<script>document.getElementById('progress').style.display = " .
"'none'</script>";
}
//************************************************************************
// PROCESA_ENTRADA: procesa una nueva entrada para aadir en la base de datos,
//
generando todas las rdenes SQL necesarias para llevar a cabo con xito
//
la actualizacin.
// Entrada:
- Valores de los campos de la entrada a actualizar => $entrada
//
- Campos adicionales de la entrada a actualizar => $campo_def_add
//
- Nombres de los campos de las tablas de la base de datos =>
//
$campos_tablas
//
- Tipo de la publicacin => $tipo

162

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


//
- Array con los autores del grupo => $autores_grupo
//
- Id devuelto en la actualizacin de la publicacin en la tabla
//
=> $id
// Salida:
- Bandera que indica si se ha actualizado con xito la entrada o
//
no => $salir
//
- Id devuelto en la actualizacin de la publicacin en la tabla
//
(por referencia) => $id
//************************************************************************
function procesa_entrada($entrada, $campo_def_add, $campos_tablas,
$tipo, $autores_grupo, &$id, $letra)
{
// 1 PARTE: ACTUALIZACIN DE LA ENTRADA CORRESPONDIENTE EN LA TABLA INDICADA
//****************************************************************************
$sentencia_SQL = crea_orden_sql($entrada, $campo_def_add,
$campos_tablas);
$query_sql = "SELECT title, reference FROM " .
$entrada[$campo_def_add["tabla"]];
$resultado = mysql_query($query_sql);
$num_refs = 0;
$duplicada = false;
$salir = busca_entrada_similar($resultado, $entrada,
$campo_def_add, $campos_tablas, $num_refs);
// Si hay varias referencias iguales, entonces se aade
// la letra correspondiente (WARNING: mx. n de letras => abecedario)
if ($num_refs != 0) {
// Se buscan las posiciones del ttulo y la referencia
for ($k=0;$k<count($campos_tablas[$entrada[$campo_def_add["tabla"]]]);$k++)
{
if ($campos_tablas[$entrada[$campo_def_add["tabla"]]][$k] == "reference")
$ind_ref = $k + count($campo_def_add);
}
$entrada[$ind_ref] .= $letra[$num_refs-1];
$sentencia_SQL = crea_orden_sql($entrada, $campo_def_add,
$campos_tablas);
}
if ($salir == FALSE) {
// Ejecutar la actualizacin de la entrada
$resultado = mysql_query($sentencia_SQL);
if ($resultado == FALSE)
echo "<h1>ERROR</h1><br />" . mysql_error() . "<br />";
$id = mysql_insert_id(); // ndice de la ltima insercin de la tabla
}
else {
for ($k=0;$k<count($campos_tablas[$entrada[$campo_def_add["tabla"]]]);$k++)
if ($campos_tablas[$entrada[$campo_def_add["tabla"]]][$k] == "title")
$ind_title = $k;
echo "\t<ul><li>No se ha aadido la entrada correspondiente a " .
"la publicacin con ttulo \"" .
$entrada[$ind_title + count($campo_def_add)] .
"\" porque ya existe una entrada similar en la base de datos." .
"<br /></li></ul>\n";
$duplicada = true;
}
// 2 PARTE: ACTUALIZACIONES COLATERALES EN OTRAS TABLAS (DEPENDENCIAS)
//***************************************************************************
if ($salir == FALSE) {
// Paso 4: Aadir/actualizar los autores
$delete_SQL = "DELETE FROM authors WHERE publication=\"" . $id .
"\" AND type=\"" . $tipo[$entrada[$campo_def_add["tabla"]]] . "\";";
$resultado = mysql_query($delete_SQL);
if ($resultado == FALSE)
echo "<h1>ERROR</h1><br />" . mysql_error() . "<br />";
$autores = obtain_authors($entrada[$campo_def_add["authors"]],
$entrada[$campo_def_add["sep_authors"]]);
// Bucle para cada autor

163

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


for ($i=0;$i<count($autores);$i++) {
$people = busca_autor($autores[$i], $autores_grupo);
$autores_SQL[$i] = crea_orden_sql_autor($sentencia_SQL,
$tipo[$entrada[$campo_def_add["tabla"]]], $people, $id, $i,
$autores[$i], "a");
$resultado = mysql_query($autores_SQL[$i]);
if ($resultado == FALSE)
echo "<h1>ERROR</h1><br />" . mysql_error() . "<br />";
}
// En caso de PFC PHD, hay que procesar tambin los supervisores
if ((stripos($sentencia_SQL, "INSERT INTO pfcs") !== false) ||
(stripos($sentencia_SQL, "INSERT INTO phds") !== false))
{
$supervisores = obtain_authors($entrada[$campo_def_add["supervisors"]],
$entrada[$campo_def_add["sep_supervisors"]]);
// Bucle para cada supervisor
for ($i=0;$i<count($supervisores);$i++) {
$people = busca_autor($supervisores[$i], $autores_grupo);
$supervisores_SQL[$i] = crea_orden_sql_autor($sentencia_SQL,
$tipo[$entrada[$campo_def_add["tabla"]]], $people, $id, $i,
$autores[$i], "s");
$resultado = mysql_query($supervisores_SQL[$i]);
if ($resultado == FALSE)
echo "<h1>ERROR</h1><br />" . mysql_error() . "<br />";
}
}
}
$ind_title = 0;
for ($j=0; $j<=count($entrada)-count($campo_def_add); $j++)
if ($campos_tablas[$entrada[$campo_def_add["tabla"]]][$j] == "title")
$ind_title = $j;
if ($duplicada == false)
echo "\t\tActualizada entrada '" .
$entrada[$ind_title + count($campo_def_add)] . "'.<br />";
// Devuelve TRUE en caso de error, FALSE en caso de
// que se haya podido actualizar la base de datos
return !$salir;
}
//************************************************************************
// INSERTA_PDF: aade los datos necesarios para copiar posteriormente un fichero
//
pdf y renombrarlo con las reglas del sitio web del grupo de control
//
predictivo al final de un fichero de texto del sistema de actualizacin.
// Entrada:
- Url del fichero pdf a copiar => $url
//
- Url del fichero de texto a modificar => $log_file
//
- Tipo de la publicacin contenida en el pdf => $tipo_publicacion
//
- Id devuelto al actualizar la tabla con la informacin de la
//
publicacin => $id
// Salida: - Ninguna
//************************************************************************
function inserta_pdf($url, $log_file, $tipo_publicacion, $id)
{
$descriptor = fopen($log_file, "a");
$final = $url."\t".$tipo_publicacion."\t".$id."\n";
fwrite($descriptor, $final, strlen($final));
fclose($descriptor);
}
//************************************************************************
// BUSCA_PUBLICACION_DIR: busca una publicacin en un directorio facilitado por
//
el usuario. Si encuentra en la ruta del fichero todas las partes que
//
componen la referencia, entonces se toma como fichero vlido de la
//
publicacin (pdf).
// Entrada:
- Array con los directorios facilitados por el usuario => $dirs
//
- Referencia de la publicacin buscada => $referencia

164

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


//
- Url del fichero que contiene las siglas y acrnimos de las revistas y
//
congresos => $pubs_file
//
- Array para insertar las rutas y porcentajes de los ficheros
//
encontrados => $pdfs
// Salida - Array con las rutas y porcentajes de los ficheros encontrados
//
(por referencia) => $pdfs
//************************************************************************
function busca_publicacion_dir($dirs, $referencia, $pubs_file, &$pdfs)
{
$path = 0;
$percent = 1;
// Obtencin del ao, primer apellido y publicacin a
// partir de la referencia => array $token
$i = 0;
$pos2 = 0;
$pos1 = $pos2;
while (!ctype_upper($referencia[$pos2]))
$pos2++;
$token[$i] = substr($referencia, $pos1, $pos2);
$i++;
$pos2;
$pos1 = $pos2;
while (!ctype_digit($referencia[$pos2]))
$pos2++;
$token[$i] = substr($referencia, $pos1, $pos2-$pos1);
$i++;
$pos2 +=2;
$token[$i] = substr($referencia, $pos2);
$keywords = get_keywords($pubs_file, $token[1]);
for ($i=0; $i<count($dirs); $i++) {
if (is_dir($dirs[$i])) {
// Se obtiene un listado de todos los directorios
// y ficheros bajo este directorio
$content = scandir($dirs[$i]);
// Para cada entrada del array se comprueba si es fichero,
// enlace simblico o directorio
for ($j=0; $j<count($content); $j++) {
$ruta = $dirs[$i] . "\\\\" . $content[$j];
// Caso de ser directorio se almacena en otro array
// para llamar recursivamente esta funcin
if ((is_dir($ruta)) && ($content[$j] != ".") &&
($content[$j] != ".."))
{
$coincidencias = busca_publicacion_dir(array($ruta),
$referencia, $pubs_file, $pdfs);
}
// Caso de ser fichero, se mira si se trata del buscado o no
// REQUISITO: se debe encontrar SIEMPRE el apellido, el ao
// Y las siglas de la publicacin o un % > 0.6 en las palabras claves
else if (is_file($ruta)) {
$filename = quita_tildes($content[$j]);
$nueva_ruta = $dirs[$i] . "\\\\" . $filename;
$valido = true;
// Bsqueda del primer apellido del autor principal
if (stripos($nueva_ruta, $token[0]) === false)
$valido = false;
// Bsqueda de la publicacin
$num_cases = 0;
if (stripos($nueva_ruta, $token[1]) === false) {
// Si la bsqueda de las siglas falla, entonces
// se buscan las palabras claves
for ($k=0; $k<count($keywords); $k++) {
if (stripos($nueva_ruta, $keywords[$k]) !== false)
$num_cases++;
}

165

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
else
$num_cases = count($keywords);
// Aqu se tiene en cuenta un porcentaje de similitud,
// esto es, que se encuentren como mnimo un determinado
// nmero de palabras claves
if (($num_cases/count($keywords)) < 0.6)
$valido = false;
// Bsqueda del ao
if (stripos($nueva_ruta, $token[2]) === false)
$valido = false;
if ($valido) {
$n_pdfs = count($pdfs);
if (!isset($pdfs[$n_pdfs-1][0]))
$n_pdfs = 0;
else if ($pdfs[$n_pdfs-1][0] == "")
$n_pdfs--;
$pdfs[$n_pdfs][0] = stripslashes($ruta);
$pdfs[$n_pdfs][1] = ($num_cases/count($keywords))*100;
}
}
}
}
}
}
//************************************************************************
// GET_KEYWORDS: obtiene las palabras clave de una publicacin a partir de sus
//
siglas. Esto es til para la bsqueda de ficheros pdf en los directorios, ya
//
que algunas veces usan las siglas y otras los nombres completos.
// Entrada:
- Url del fichero que contiene las siglas y acrnimos de las
//
revistas y
congresos => $pubs_file
//
- Siglas de la publicacin => $siglas
// Salida:
- Palabras clave de la publicacin => $keywords
//************************************************************************
function get_keywords($pubs_file, $siglas)
{
// Se buscan las palabras clave de la publicacin basndose en las siglas
$pubs = "";
$archivo = fopen($pubs_file, "r"); // Apertura del fichero
if ($archivo) {
while (!feof($archivo))
$pubs .= fread($archivo, 8192);
$pos_siglas = stripos($pubs, $siglas.";") + strlen($siglas) + 1;
$cadena = trim(substr($pubs, $pos_siglas,
strpos(substr($pubs, $pos_siglas), "\n")));
$parte = strtok($cadena, "\t");
$i = 0;
$empezado = false;
for ($j=0; $j<strlen($cadena); $j++) {
if ((ctype_alnum($cadena[$j])) && (!$empezado)) {
$empezado = true;
$pos_ini = $j;
}
else if (!ctype_alnum($cadena[$j]) && $empezado) {
$empezado = false;
$pos_fin = $j;
$keywords[$i] = trim(substr($cadena, $pos_ini, $pos_fin-$pos_ini));
$i++;
}
else if (ctype_alnum($cadena[$j]) &&
$empezado && ($j == (strlen($cadena)-1)))
{
$keywords[$i] = trim(substr($cadena, $pos_ini));
}

166

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
}
return $keywords;
}
?>

10.4.1.10 H ELP .HTML


<html>
<body>
A continuacin se muestran las distintas tablas y sus correspondientes campos,
junto con una descripcin de cada uno:<br></br>
<table cellspacing=10>
<caption><h3>Tabla CONGRESS</h3></caption>
<thead>
<tr>
<th>Nombre del campo</th>
<th>Descripcin</th>
</tr>
</thead>
</tbody>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TITLE
<td> Ttulo de la ponencia del congreso
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ABSTRACT
<td> Resumen de la ponencia
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE
<td> Referencia de la publicacin
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOKTITLE
<td> Nombre del congreso
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;YEAR
<td> Ao de publicacin de la ponencia
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MONTH
<td> Mes de publicacin de la ponencia
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADDRESS
<td> Direccin
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PAGES
<td> Pginas del documento de publicacin de la ponencia
</tr>
</tbody>
</table>
<table cellspacing=10>
<caption><h3>Tabla JOURNALS</h3></caption>
<thead>
<tr>
<th>Nombre del campo</th>
<th>Descripcin</th>

167

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


</tr>
</thead>
</tbody>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TITLE
<td> Ttulo del artculo
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ABSTRACT
<td> Resumen del artculo
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE
<td> Referencia de la publicacin
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JOURNAL
<td> Nombre de la revista o publicacin
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;YEAR
<td> Ao de publicacin del artculo
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VOLUME
<td> Volumen de publicacin
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PAGES
<td> Pginas del artculo en la publicacin
</tr>
</tbody>
</table>

<table cellspacing=10>
<caption><h3>Tabla BOOKS</h3></caption>
<thead>
<tr>
<th>Nombre del campo</th>
<th>Descripcin</th>
</tr>
</thead>
</tbody>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TITLE
<td> Ttulo del libro
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ABSTRACT
<td> Resumen del libro
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE
<td> Referencia de la publicacin
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PUBLISHER
<td> Editorial
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;YEAR
<td> Ao de publicacin del libro
</tr>

168

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISBN
<td> ISBN del libro
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CODE
<td> Cdigo del documento: 1) Libro de texto 2) Libro de actas
</tr>
</tbody>
</table>

<table cellspacing=10>
<caption><h3>Tabla PFCS</h3></caption>
<thead>
<tr>
<th>Nombre del campo</th>
<th>Descripcin</th>
</tr>
</thead>
</tbody>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TITLE
<td> Ttulo del libro
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AUTHOR
<td> Autor del proyecto fin de carrera
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ABSTRACT
<td> Resumen del libro
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE
<td> Referencia de la publicacin
</tr>
</tbody>
</table>

<table cellspacing=10>
<caption><h3>Tabla PHDS</h3></caption>
<thead>
<tr>
<th>Nombre del campo</th>
<th>Descripcin</th>
</tr>
</thead>
</tbody>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TITLE
<td> Ttulo del libro
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ABSTRACT
<td> Resumen del libro
</tr>
<tr>
<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DATEPHD
<td> Fecha de finalizacion del doctorado
</tr>
<tr>

169

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


<td width="30%" align=right>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE
<td> Referencia de la publicacin
</tr>
</tbody>
</table>

NOTAS:
<ul>
<li>
No se facilita el campo de insercin de documentos. Se ha de hacer mediante
modificacin manual desde el sitio web del grupo de control predictivo.
</li>
<li>
Existe en la pgina de actualizacin un campo no existente en ninguna de las
tablas, "authors", ya que se suele almacenar el conjunto de autores al
completo, y no de forma separada. El script de actualizacin se encarga de
separarlos posteriormente.
</li>
<li>
En condiciones normales no es necesario modificar la tabla "authors", ya que
los cambios los realiza automticamente el programa de actualizacin.
</li>
</ul>
</body>
</html>

10.4.2 C ONTROL R EMOTO

DE

P ROCESO S

MEDIANTE

M ATLAB /TCP/IP.

10.4.2.1 TUNNING .ASPX .CS


using
using
using
using
using
using
using
using
using
using
using
using
using
using
using
using
using

System;
System.Collections;
System.ComponentModel;
System.Data;
System.Data.Odbc;
System.Drawing;
System.Globalization;
System.IO;
System.Net;
System.Net.Sockets;
System.Text;
System.Web;
System.Web.SessionState;
System.Web.UI;
System.Web.UI.WebControls;
System.Web.UI.HtmlControls;
Solar.Classes;

namespace Solar.RemoteTunning
{
/// <summary>
/// Esta clase define los mtodos necesarios para proporcionar el control remoto
///
de la planta a un usuario logeado en el sistema
/// </summary>
public class RemoteTunning : System.Web.UI.Page
{

170

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


protected System.Web.UI.WebControls.Label Parameter_1_name;
protected System.Web.UI.WebControls.Label Parameter_2_name;
protected System.Web.UI.WebControls.Label Parameter_3_name;
protected System.Web.UI.WebControls.Label Parameter_4_name;
protected System.Web.UI.WebControls.Label Parameter_5_name;
protected System.Web.UI.WebControls.Label Parameter_6_name;
protected System.Web.UI.WebControls.Label Parameter_7_name;
protected System.Web.UI.WebControls.Label Parameter_8_name;
protected System.Web.UI.WebControls.Label Parameter_9_name;
protected System.Web.UI.WebControls.Label Parameter_10_name;
protected System.Web.UI.WebControls.TextBox Parameter_1_value;
protected System.Web.UI.WebControls.TextBox Parameter_2_value;
protected System.Web.UI.WebControls.TextBox Parameter_3_value;
protected System.Web.UI.WebControls.TextBox Parameter_4_value;
protected System.Web.UI.WebControls.TextBox Parameter_5_value;
protected System.Web.UI.WebControls.TextBox Parameter_6_value;
protected System.Web.UI.WebControls.TextBox Parameter_7_value;
protected System.Web.UI.WebControls.TextBox Parameter_8_value;
protected System.Web.UI.WebControls.TextBox Parameter_9_value;
protected System.Web.UI.WebControls.TextBox Parameter_10_value;
protected System.Web.UI.WebControls.Button ButtonChangeParams;
protected System.Web.UI.WebControls.Label LabelError;
protected System.Web.UI.WebControls.TextBox Old_value1;
protected System.Web.UI.WebControls.TextBox Old_value5;
protected System.Web.UI.WebControls.TextBox Old_value2;
protected System.Web.UI.WebControls.TextBox Old_value3;
protected System.Web.UI.WebControls.TextBox Old_value4;
protected System.Web.UI.WebControls.TextBox Old_value6;
protected System.Web.UI.WebControls.TextBox Old_value7;
protected System.Web.UI.WebControls.TextBox Old_value8;
protected System.Web.UI.WebControls.TextBox Old_value9;
protected System.Web.UI.WebControls.TextBox Old_value10;
protected System.Web.UI.WebControls.Label LabelOld1;
protected System.Web.UI.WebControls.Label LabelNew1;
protected System.Web.UI.WebControls.Label LabelNew2;
protected System.Web.UI.WebControls.Label LabelOld2;
protected System.Web.UI.WebControls.Image ModeloSimulink;
private UserInfo ui = new UserInfo();
//private System.Windows.Forms.Button();
private void Page_Load(object sender, System.EventArgs e)
{
try
{
//solamente se permite el acceso a usuarios logados
//con privilegio de administrador
if (ui.UserLogged())
{
if ((ui.GetHasTest()=="True") || (ui.GetTypeOfUser()=="root"))
{
int NUM_PARAMS = 10;
bool fallo = false;
string dir_path =
@"C:\Inetpub\ProyectoFC\Solar\Tests\Files\Simulink";
string[] files = null;
// Obtain name and path of the model file
files = Directory.GetFiles(dir_path, "*.mdl");
string mdl_name = null;
string mdl_path = null;
if (files.Length != 0)
{
mdl_name = files[0].Substring(files[0].LastIndexOf("\\") + 1);
mdl_path = files[0];

171

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
else
fallo = true;
// Obtain name and path of the image file
files = Directory.GetFiles(dir_path, "*.png");
string png_name = null;
string png_path = null;
if (files.Length != 0)
{
png_name = files[0].Substring(files[0].LastIndexOf("\\") + 1);
png_path = files[0];
}
else
fallo = true;
// Obtain name and path of the log file
files = Directory.GetFiles(dir_path, "*.log");
string log_name = null;
string log_path = null;
if (files.Length != 0)
{
log_name = files[0].Substring(files[0].LastIndexOf("\\") + 1);
log_path = files[0];
}
else
fallo = true;
// Check if the file exists
if (!fallo && (File.Exists(@mdl_path)))
{
Bitmap imagen = new Bitmap(png_path);
int height = imagen.Height;
int width = imagen.Width;
ModeloSimulink.Height = height;
ModeloSimulink.Width = width;
using (StreamReader sr = new StreamReader(log_path))
{
string line = null;
int i = 0;
while ((line = sr.ReadLine()) != null)
{
string[] parts = line.Split(new Char [] {'='});
switch (parts[0])
{
case "var0":
Old_value1.ReadOnly = false;
Old_value1.Text = parts[1];
Old_value1.ReadOnly = true;
i++;
break;
case "var1":
Old_value2.Text = parts[1];
i++;
break;
case "var2":
Old_value3.Text = parts[1];
i++;
break;
case "var3":
Old_value4.Text = parts[1];
i++;
break;
case "var4":
Old_value5.Text = parts[1];
i++;

172

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


break;
case "var5":
Old_value6.Text = parts[1];
i++;
break;
case "var6":
Old_value7.Text = parts[1];
i++;
break;
case "var7":
Old_value8.Text = parts[1];
i++;
break;
case "var8":
Old_value9.Text = parts[1];
i++;
break;
case "var9":
Old_value10.Text = parts[1];
i++;
break;
}
}
if (i != NUM_PARAMS)
{
LabelError.Text += "You must specify " + NUM_PARAMS +
" parameters" + " in your .mdl file.";
LabelError.Visible = true;
}
}
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
string url = "http://servigar2.us.es/Solar/Tests/Files/Simulink/"
+ png_name;
ModeloSimulink.ImageUrl = url;
}
else if (fallo == true)
{
LabelError.Text="There is no controller availabe at this "+
"moment. If you have booked a period and it is running now,"+
" please, contact the web administrator "+
"(soladmin@cartuja.us.es) or the solar plant supervisor "+
"(solarplant@hotmail.com).";
LabelError.Visible = true;
ModeloSimulink.Visible = false;
}
}
else
Response.Redirect("../LogInOut/ForbiddenAccess.aspx");
}
else
Response.Redirect("../LogInOut/LogExpired.aspx");
}
catch (Exception exc)
{
LabelError.Text = "Exception caught: " + e.ToString();
LabelError.Visible = true;
ModeloSimulink.Visible = false;
}
}
#region Cdigo generado por el Diseador de Web Forms
override protected void OnInit(EventArgs e)

173

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


{
//
// CODEGEN: llamada requerida por el Diseador de Web Forms ASP.NET.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Mtodo necesario para admitir el Diseador. No se puede modificar
/// el contenido del mtodo con el editor de cdigo.
/// </summary>
private void InitializeComponent()
{
this.ButtonChangeParams.Click += new
System.EventHandler(this.ButtonChangeParams_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void ButtonChangeParams_Click(object sender, System.EventArgs e)
{
Socket s = null;
// Socket descriptor
int SERVICE_PORT = 32000; // Port to send the data to the server
IPHostEntry iphe = Dns.Resolve("193.147.161.89");
// Obtain name and path of the log file
string dir_path = @"C:\Inetpub\ProyectoFC\Solar\Tests\Files\Simulink";
string[] files = Directory.GetFiles(dir_path, "*.log");
string log_name = files[0].Substring(files[0].LastIndexOf("\\") + 1);
string log_path = files[0];
try
{
foreach(IPAddress ipad in iphe.AddressList)
{
IPEndPoint ipe = new IPEndPoint(ipad, SERVICE_PORT);
// Open the socket
Socket tmpS = new Socket(ipe.AddressFamily, SocketType.Stream,
ProtocolType.Tcp);
// Connect the socket
tmpS.Connect(ipe);
if(tmpS.Connected)
{
s = tmpS;
break;
}
else
continue;
}
if (s == null)
{
Console.WriteLine("Cannot connect the socket to the specified " +
"address.\n");
}
else
{
string Texto1 = Parameter_1_value.Text;
string Texto2 = Parameter_2_value.Text;
string Texto3 = Parameter_3_value.Text;
string Texto4 = Parameter_4_value.Text;
string Texto5 = Parameter_5_value.Text;

174

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


string Texto6 = Parameter_6_value.Text;
string Texto7 = Parameter_7_value.Text;
string Texto8 = Parameter_8_value.Text;
string Texto9 = Parameter_9_value.Text;
string Texto10 = Parameter_10_value.Text;
string muestra = Texto1 + Texto2 + Texto3 + Texto4 + Texto5 + Texto6 +
Texto7 + Texto8 + Texto9 + Texto10;
// Creacion del mensaje
string content = "";
if (Texto1 != "")
content += "var0=" +
else
content += "var0=" +
if (Texto2 != "")
content += "var1=" +
else
content += "var1=" +
if (Texto3 != "")
content += "var2=" +
else
content += "var2=" +
if (Texto4 != "")
content += "var3=" +
else
content += "var3=" +
if (Texto5 != "")
content += "var4=" +
else
content += "var4=" +
if (Texto6 != "")
content += "var5=" +
else
content += "var5=" +
if (Texto7 != "")
content += "var6=" +
else
content += "var6=" +
if (Texto8 != "")
content += "var7=" +
else
content += "var7=" +
if (Texto9 != "")
content += "var8=" +
else
content += "var8=" +
if (Texto10 != "")
content += "var9=" +
else
content += "var9=" +

con el contenido del fichero a modificar


Texto1 + "\n";
Old_value1.Text + "\n";
Texto2 + "\n";
Old_value2.Text + "\n";
Texto3 + "\n";
Old_value3.Text + "\n";
Texto4 + "\n";
Old_value4.Text + "\n";
Texto5 + "\n";
Old_value5.Text + "\n";
Texto6 + "\n";
Old_value6.Text + "\n";
Texto7 + "\n";
Old_value7.Text + "\n";
Texto8 + "\n";
Old_value8.Text + "\n";
Texto9 + "\n";
Old_value9.Text + "\n";
Texto10 + "\n";
Old_value10.Text + "\n";

// Send the remote modify request


// Cambiar aqui la direccion del neoxite
string msg = "MOD_REQUEST*OVERWRITE*193.147.161.89*" +
content.Length + "*tunning.txt";
s.Send(ASCIIEncoding.ASCII.GetBytes(msg));
// Receiving the ack message
string data = null;
byte[] bytes = new byte[1024];
int bytesRec = s.Receive(bytes);
data += Encoding.ASCII.GetString(bytes,0,bytesRec);
if (data.CompareTo("PROCEED") == 0)
s.Send(ASCIIEncoding.ASCII.GetBytes(content));

175

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Once we receive the MODIFY_ACK, we update the log file with new
// values
using (StreamWriter sw = new StreamWriter(log_path, false))
{
sw.Write(content);
}
// Refresh info boxes with new values
if (Texto1 != "")
Old_value1.Text = Texto1;
if (Texto2 != "")
Old_value2.Text = Texto2;
if (Texto3 != "")
Old_value3.Text = Texto3;
if (Texto4 != "")
Old_value4.Text = Texto4;
if (Texto5 != "")
Old_value5.Text = Texto5;
if (Texto6 != "")
Old_value6.Text = Texto6;
if (Texto7 != "")
Old_value7.Text = Texto7;
if (Texto8 != "")
Old_value8.Text = Texto8;
if (Texto9 != "")
Old_value9.Text = Texto9;
if (Texto10 != "")
Old_value10.Text = Texto10;
// Delete content of the other text boxes
Parameter_1_value.Text = null;
Parameter_2_value.Text = null;
Parameter_3_value.Text = null;
Parameter_4_value.Text = null;
Parameter_5_value.Text = null;
Parameter_6_value.Text = null;
Parameter_7_value.Text = null;
Parameter_8_value.Text = null;
Parameter_9_value.Text = null;
Parameter_10_value.Text = null;
}
}
catch (SocketException ex)
{
LabelError.Text += "No se pudo establecer la conexin con el servidor." +
"Lamentamos las molestias.";
LabelError.Visible = true;
}
}
}
}

10.4.2.2
using
using
using
using
using
using

CP _SERVER _SERVIGAR

System;
System.IO;
System.Net;
System.Net.Sockets;
System.Text;
System.Threading;

namespace cp_server_servigar
{

176

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


/// <summary>
/// Class Servidor_Servigar: This class implements a server which can copy
/// remote files and modify files with remote parameters
/// </summary>
class Servidor_Servigar
{
/// <summary>
/// The main entry point for the application.
/// The server receive first a message containing the operation it has to do:
///
*) COPY_REQUEST: remote copy of a file, transfer over IP and create
///
new
///
*) MOD_REQUEST: remote modification of a file on the server, do not
///
create a new file
///
*) ABORT: self message for exiting the program and stop listening
/// The server has two threads: the main thread listen at a specific port for
/// incoming requests, and the secondary thread is only for terminating
/// purposes (it reads the command line and when user enters "exit" it
/// finishes the program.
/// </summary>
[STAThread]
static void Main(string[] args)
{
string server_address = "servigar2.us.es";
int server_port = 39854;
try
{
// Welcome message
Console.WriteLine("Server running at " +
SERVIGAR:\n===========================");
// Just after that message, we start the secondary thread for aborting
Reader lector = new Reader();
Thread hilo_lector = new Thread(new ThreadStart(lector.KeyboardRead));
hilo_lector.Start();
// Allowed IPs for requesting
string[] allowed_ips = {"193.147.161.89", "193.147.160.155",
"172.16.1.4", "127.0.0.1"};
bool salir = false;
// Flag for exiting the main loop
string data = null;
// Incoming data from the client.
byte[] bytes = new Byte[1024];
// Data buffer for incoming data.
// Create the local endpoint
IPHostEntry ipHostInfo = Dns.Resolve("servigar2.us.es");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, server_port);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Bind the socket to the local endpoint and listen for incoming
// connections.
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (salir == false)
{
Console.WriteLine("\n\nWaiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
data = null;

177

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Filtering remote IP
string remoteIP =
((IPEndPoint)handler.RemoteEndPoint).Address.ToString();
Console.WriteLine("Incoming request from " + remoteIP);
bool allowed = false;
foreach (string ip in allowed_ips)
{
if (ip.CompareTo(remoteIP) == 0)
{
Console.WriteLine("Allowed IP => Processing request");
allowed = true;
break;
}
}
// If it is an allowed ip address (white list), go on...
if (allowed)
{
// Receiving the request message
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes,0,bytesRec);
// What does the user want to do?
String[] tokens = data.Split(new Char [] {'*'});
data = null;
FileStream fs_write = null;
BinaryWriter w = null;
long size = 0;
switch (tokens[0])
{
case "COPY_REQUEST":
#region COPY REQUEST: remote copy of a file
// Check the existence of the file to create.
// If it does not exist, create the new, empty data file.
string ack_msg = null;
int flag = 0;
if (File.Exists(tokens[4]))
{
if (tokens[1].CompareTo("CREATE") == 0)
{
flag = 1;
ack_msg = "DENIED*Destiny file already exists. " +
"Remote copy denied.\n";
Console.WriteLine("Destiny file already exists. " +
"Remote copy denied.\n");
}
else if (tokens[1].CompareTo("OVERWRITE") == 0)
{
flag = 2;
ack_msg = "PROCEED";
}
}
else
{
flag = 3;
ack_msg = "PROCEED";
}
// Sending the ack message
handler.Send(ASCIIEncoding.ASCII.GetBytes(ack_msg));

178

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// If the ack_msg is PROCEED, go on with the writing
if (flag > 1)
{
Console.WriteLine("Received COPY request. " +
"Waiting for the data...");
// First, see if there exist files with the same
// extension. In affirmative case, delete them all
String[] partes = tokens[4].Split(new Char [] {'.'});
string dir_path =
@"C:\Inetpub\ProyectoFC\Solar\Tests\Files\Simulink";
string[] dirs =
Directory.GetFiles(dir_path, "*." + partes[1]);
if (dirs.Length != 0)
foreach (string dir in dirs)
File.Delete(dir);
// Create the writer for data.
if (flag == 2)
// File will be overwrited
fs_write = new FileStream(tokens[4],
FileMode.Create);
else if (flag == 3)
// File does not exist
fs_write = new FileStream(tokens[4],
FileMode.CreateNew);
else
Console.WriteLine("Internal error.\n");
w = new BinaryWriter(fs_write);
// Receiving the data (file)
size = 0;
string data_mod = "";
Console.WriteLine("Starting receiving data...");
while (true)
{
bytes = new byte[1024];
bytesRec = handler.Receive(bytes);
size += bytesRec;
w.Write(bytes, 0, bytesRec);
data_mod += Encoding.ASCII.GetString(bytes,
0, bytesRec);
if (size == Convert.ToInt64(tokens[3]))
break;
}
Console.WriteLine("File \"" + tokens[4] +
"\" has been created");
fs_write.Close();
w.Close();
// If this is a model file, we create a log file for
// variables storage purposes
if (partes[1].CompareTo("mdl") == 0)
{
int pos = data_mod.IndexOf("Block {");
pos = data_mod.IndexOf("BlockType", pos + 1);
pos = data_mod.IndexOf("\"S-Function\"", pos + 1);
pos = data_mod.IndexOf("Parameters", pos + 1);
int pos2 = data_mod.IndexOf("}", pos + 1);
pos = data_mod.IndexOf("\"", pos + 1);
if (pos < pos2)
{
pos2 = data_mod.IndexOf("\"", pos + 1);
string[] parameters = (data_mod.Substring(pos+1,
pos2-pos-1)).Split(new Char [] {','});

179

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Before creating log file, we delete all
// log files
dirs = Directory.GetFiles(dir_path, "*.log");
if (dirs.Length != 0)
foreach (string dir in dirs)
File.Delete(dir);
// Creating the log file
StreamWriter sr = File.CreateText(partes[0] +
".log");
for (int i=0; i<10; i++)
sr.WriteLine("var" + i + "=" +
parameters[i] + "\n");
sr.Close();
}
}
}
break;
#endregion
case "MOD_REQUEST":
#region MODIFY REQUEST: remote modification of a file
// Sending the ack message
ack_msg = "PROCEED";
handler.Send(ASCIIEncoding.ASCII.GetBytes(ack_msg));
// Create the writer for data.
fs_write = new FileStream(tokens[4], FileMode.Append,
FileAccess.Write);
w = new BinaryWriter(fs_write);
// Receiving the data to be added to the file
size = 0;
while (true)
{
bytes = new byte[1024];
bytesRec = handler.Receive(bytes);
size += bytesRec;
w.Write(bytes, 0, bytesRec);
if (size == Convert.ToInt64(tokens[3]))
break;
}
fs_write.Close();
w.Close();
break;
#endregion
case "ABORT":
salir = true;
break;
default:
Console.WriteLine("Request of the user is not allowed.\n");
break;
}
}
}
}
# region Specific CATCHS
// Thrown by: Thread (Constructor), Dns.Resolve, Socket.Bind,
//
Socket.Receive, ASCIIEncoding.GetString, Socket.Send,
//
Directory.GetFiles, File.Delete, FileStream (Constructor),

180

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


//
BinaryWriter (Constructor), BinaryWriter.Write,
//
String.IndexOf, File.CreateText
catch (System.ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start
catch (System.Threading.ThreadStateException e)
{
Console.WriteLine("ThreadStateException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start, Dns.Resolve, Socket.Bind, Socket.Receive,
//
FileStream (Constructor)
catch (System.Security.SecurityException e)
{
Console.WriteLine("SecurityException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start
catch (System.OutOfMemoryException e)
{
Console.WriteLine("OutOfMemoryException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start
catch (System.NullReferenceException e)
{
Console.WriteLine("NullReferenceException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Dns.Resolve, Socket (Constructor), Socket.Bind, Socket.Listen,
//
Socket.Accept, Socket.RemoteEndPoint, Socket.Receive, Socket.Send
catch (System.Net.Sockets.SocketException e)
{
Console.WriteLine("SocketException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPEndPoint (Constructor), ASCIIEncoding.GetString,
//
FileStream (Constructor), BinaryWriter.Write, String.IndexOf,
//
String.Substring
catch (System.ArgumentOutOfRangeException e)
{
Console.WriteLine("ArgumentOutOfRangeException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Socket.Bind, Socket.Listen, Socket.Accept,
//
Socket.RemoteEndPoint, Socket.Receive, Socket.Send,
//
BinaryWriter.Write, StreamWriter.WriteLine
catch (System.ObjectDisposedException e)
{
Console.WriteLine("ObjectDisposedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Socket.Accept
catch (System.InvalidOperationException e)

181

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


{
Console.WriteLine("InvalidOperationException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, File.CreateText
catch (System.UnauthorizedAccessException e)
{
Console.WriteLine("UnauthorizedAccessException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, FileStream (Constructor),
//
BinaryWriter (Constructor), BinaryWriter.Write, Convert.ToInt64,
//
File.CreateText
catch (System.ArgumentException e)
{
Console.WriteLine("ArgumentException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, FileStream (Constructor),
//
File.CreateText
catch (System.IO.PathTooLongException e)
{
Console.WriteLine("PathTooLongException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, FileStream (Constructor),
//
File.CreateText
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine("DirectoryNotFoundException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: File.Delete, File.CreateText
catch (System.NotSupportedException e)
{
Console.WriteLine("NotSupportedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: FileStream (Constructor)
catch (System.IO.FileNotFoundException e)
{
Console.WriteLine("FileNotFoundException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Console.WriteLine, File.Delete, FileStream (Constructor),
//
BinaryWriter.Write, StreamWriter.WriteLine
catch (System.IO.IOException e)
{
Console.WriteLine("IOException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Convert.ToInt64
catch (System.FormatException e)
{
Console.WriteLine("FormatException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);

182

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
// Thrown by: Convert.ToInt64
catch (System.OverflowException e)
{
Console.WriteLine("OverflowException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
#endregion
// Thrown by: any
catch (Exception e)
{
Console.WriteLine("Exception caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
}
/// <summary>
/// Class Reader: this class implements a keyboard reader for exiting the
///
executable program. When user writes a line, it reads the command line
///
and if the sentence is "exit", the class sends a message to the listening
///
port on this machine to exit the socket loop of the class
///
Servidor_Servigar
/// </summary>
internal class Reader
{
public void KeyboardRead()
{
int server_port = 39854;
// Server port for sending the data
string server_address = "193.147.161.89";
// Servigar2.us.es IP address
string opt = null;
// Line entered
Socket s = null;
// Socket descriptor
bool salir = false;
// Flag for exiting the loop
IPHostEntry iphe = null;
while (salir == false)
{
try
{
Console.Write("(You can type \"exit\" at any moment to exit " +
"the program)\n");
opt = Console.ReadLine();
// If the user writes "exit", proceed with the termination process
if (opt.ToLower() == "exit")
{
// Format check of the IP address
IPAddress address = IPAddress.Parse(server_address);
if(address.AddressFamily == AddressFamily.InterNetwork)
{
// Check if the IP address is valid
iphe = Dns.Resolve(server_address);
foreach(IPAddress ipad in iphe.AddressList)
{
IPEndPoint ipe = new IPEndPoint(ipad, server_port);
// Open the socket
Socket tmpS =
new Socket(ipe.AddressFamily, SocketType.Stream,
ProtocolType.Tcp);

183

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Connect the socket
tmpS.Connect(ipe);
if(tmpS.Connected)
{
s = tmpS;
break;
}
else
continue;
}
if (s == null)
{
Console.WriteLine("Cannot connect the socket to the " +
"specified address.\n");
}
else
{
string msg = "ABORT";
s.Send(ASCIIEncoding.ASCII.GetBytes(msg));
salir = true;
}
}
}
}
#region Specific CATCHs
// Thrown by: Console.ReadLine, Console.WriteLine
catch(System.IO.IOException e)
{
Console.WriteLine("IOException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Console.ReadLine
catch(System.OutOfMemoryException e)
{
Console.WriteLine("OutOfMemoryException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPAddress.Parse, Dns.Resolve, Socket.Connect,
//
ASCIIEncoding.GetBytes, Socket.Send
catch(System.ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPAddress.Parse
catch(System.FormatException e)
{
Console.WriteLine("FormatException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Dns.Resolve, Socket (Constructor), Socket.Connect,
//
Socket.Send
catch(System.Net.Sockets.SocketException e)
{
Console.WriteLine("SocketException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Dns.Resolve, Socket.Connect

184

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


catch(System.Security.SecurityException e)
{
Console.WriteLine("SecurityException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPEndPoint (Constructor)
catch(System.ArgumentOutOfRangeException e)
{
Console.WriteLine("ArgumentOutOfRangeException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Socket.Connect, Socket.Send
catch(System.ObjectDisposedException e)
{
Console.WriteLine("ObjectDisposedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
#endregion
// Thrown by: any
catch(Exception e)
{
Console.WriteLine("Exception caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
}
}
}
}

10.4.2.3 TUNNING .C
/*
* sfuntmpl_basic.c: Basic 'C' template for a level 2 S-function.
*
* ------------------------------------------------------------------------* | See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template |
* ------------------------------------------------------------------------*
* Copyright 1990-2002 The MathWorks, Inc.
* $Revision: 1.27 $
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NUM_VARS 10
FILE *pfile;
//Exchange file descriptor
char s[255];
//Global variable to store the read lines from the exchange file
char var_name[255];
//Global variable to store the name of a variable
char var_value[255]; //Global variable to store the value of a variable
int changed_var;
//Temporal index for selecting the changed variable
int allowed;
//Flag indicating if a variable value is an allowed value
int valid;
//Flag indicating if a variable name is a valid name
int i;
//Loops counter
int count_orig;
//Counter for the originating string
int count_dest;
//Counter for the destiny string
int prueba = 0;

185

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


//Allowed variable names for tunning parameters
const char* valid_vars[NUM_VARS] =
{"var0","var1","var2","var3","var4","var5","var6","var7","var8","var9"};
//Array for the new values
double change_value[10];
int changed_value[10] = {0,0,0,0,0,0,0,0,0,0};
/*
* You must specify the S_FUNCTION_NAME as the name of your S-function
* (i.e. replace sfuntmpl_basic with the name of your S-function).
*/
#define S_FUNCTION_NAME tunning
#define S_FUNCTION_LEVEL 2
/*
* Need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
/* Error handling
* -------------*
* You should use the following technique to report errors encountered within
* an S-function:
*
*
ssSetErrorStatus(S,"Error encountered due to ...");
*
return;
*
* Note that the 2nd argument to ssSetErrorStatus must be persistent memory.
* It cannot be a local variable. For example the following will cause
* unpredictable errors:
*
*
mdlOutputs()
*
{
*
char msg[256];
{ILLEGAL: to fix use "static char msg[256];"}
*
sprintf(msg,"Error due to %s", string);
*
ssSetErrorStatus(S,msg);
*
return;
*
}
*
* See matlabroot/simulink/src/sfuntmpl_doc.c for more details.
*/
/*====================*
* S-function methods *
*====================*/
/* Function: mdlInitializeSizes ===============================================
* Abstract:
*
The sizes information is used by Simulink to determine the S-function
*
block's characteristics (number of inputs, outputs, states, etc.).
*/
static void mdlInitializeSizes(SimStruct *S)
{
/* See sfuntmpl_doc.c for more details on the macros below */
ssSetNumSFcnParams(S, 10); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Return if number of expected != number of actual parameters */
return;
}

186

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, 1);
ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/
/*
* Set direct feedthrough flag (1=yes, 0=no).
* A port has direct feedthrough if the input is used in either
* the mdlOutputs or mdlGetTimeOfNextVarHit functions.
* See matlabroot/simulink/src/sfuntmpl_directfeed.txt.
*/
ssSetInputPortDirectFeedThrough(S, 0, 1);
if (!ssSetNumOutputPorts(S, NUM_VARS)) return;
ssSetOutputPortWidth(S, 0, 1);
ssSetOutputPortWidth(S, 1, 1);
ssSetOutputPortWidth(S, 2, 1);
ssSetOutputPortWidth(S, 3, 1);
ssSetOutputPortWidth(S, 4, 1);
ssSetOutputPortWidth(S, 5, 1);
ssSetOutputPortWidth(S, 6, 1);
ssSetOutputPortWidth(S, 7, 1);
ssSetOutputPortWidth(S, 8, 1);
ssSetOutputPortWidth(S, 9, 1);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0);
ssSetNumModes(S, 0);
ssSetNumNonsampledZCs(S, 0);
ssSetOptions(S, 0);
}

/* Function: mdlInitializeSampleTimes =========================================


* Abstract:
*
This function is used to specify the sample time(s) for your
*
S-function. You must register the same number of sample times as
*
specified in ssSetNumSampleTimes.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}

#define MDL_INITIALIZE_CONDITIONS
/* Change to #undef to remove function */
#if defined(MDL_INITIALIZE_CONDITIONS)
/* Function: mdlInitializeConditions ========================================
* Abstract:
*
In this function, you should initialize the continuous and discrete
*
states for your S-function block. The initial states are placed
*
in the state vector, ssGetContStates(S) or ssGetRealDiscStates(S).
*
You can also perform any other initialization activities that your
*
S-function may require. Note, this routine will be called at the
*
start of simulation and if it is present in an enabled subsystem
*
configured to reset states, it will be call when the enabled subsystem

187

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


*
restarts execution to reset the states.
*/
static void mdlInitializeConditions(SimStruct *S)
{
}
#endif /* MDL_INITIALIZE_CONDITIONS */

#define MDL_START /* Change to #undef to remove function */


#if defined(MDL_START)
/* Function: mdlStart =======================================================
* Abstract:
*
This function is called once at start of model execution. If you
*
have states that should be initialized once, this is the place
*
to do it.
*/
static void mdlStart(SimStruct *S)
{
}
#endif /* MDL_START */

/* Function: mdlOutputs =======================================================


* Abstract:
*
In this function, you compute the outputs of your S-function
*
block. Generally outputs are placed in the output vector, ssGetY(S).
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
int nOutputPorts = ssGetNumOutputPorts(S);
int i,j;
prueba = prueba + 1;
for (i = 0; i < nOutputPorts; i++) {
real_T *y
= (real_T *) ssGetOutputPortSignal(S,i);
real_T *pr;
int_T
ny
= ssGetOutputPortWidth(S,i);
for (j = 0; j < ny; j++) {
//SomeFunctionToFillInOutput(y[j]);
if (changed_value[i] == 1)
y[j] = change_value[i];
else
{
if (mxIsEmpty(
ssGetSFcnParam(S,i)) ||
mxIsSparse(
ssGetSFcnParam(S,i)) ||
mxIsComplex( ssGetSFcnParam(S,i)) ||
!mxIsNumeric( ssGetSFcnParam(S,i)) )
{
ssSetErrorStatus(S,"Parameters must be real finite vectors");
return;
}
else
{
pr
= mxGetPr(ssGetSFcnParam(S,i));
y[j] = *pr;
}
}
}
}
pfile = fopen("tunning.txt","r");
if (pfile != NULL)
{
// The file exist. We must check if there are new values.

188

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


Do
{
fgets (s, 255, pfile);
//Read a new line
count_orig = 0;
if (s[0] != '\0')
{
//New line character terminating a line or a variable assignment
while ((s[count_orig] != '\n') && (s[count_orig] != '\0'))
{
count_dest = 0;
//Extracting the variable name
while (s[count_orig] != '=')
{
var_name[count_dest] = s[count_orig];
count_dest++;
count_orig++;
}
var_name[count_dest] = '\0';
count_orig++;
count_dest = 0;
//Extracting the value of the variable
//New line can finish with '\0' if only one variable is wanted to
//change or with '\n' or ';' if more than one variable are needed
while ((s[count_orig] != ';') && (s[count_orig] != '\n')
&& (s[count_orig] ! '\0'))
{
var_value[count_dest] = s[count_orig];
count_dest++;
count_orig++;
}
var_value[count_dest] = '\0';
/************************************/
/*Processing the variable assignment*/
/************************************/
//First, we check if the variable name is a valid name
valid = 0;
for (i=0;i<NUM_VARS;i++)
{
if (strcmp(var_name, valid_vars[i]) == 0)
{
valid = 1;
changed_var = i;
}
}
//If the name is valid, then check the value restrictions
//(Limitations about the changing range)
allowed = 1;
//If the restrictions are accomplished, then proceed with the
//new value assignment
if (allowed && valid)
{
change_value[changed_var] = atof(var_value);
changed_value[changed_var] = 1;
}
}
}
s[0] = '\0';
} while (!feof(pfile) && !ferror(pfile));
}
// Once we have read the file, we delete the contents
fclose(pfile);
pfile = fopen("tunning.txt","w");
if (pfile != NULL)
{
fclose(pfile);

189

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
// The file does not exist, so we create an empty file here
/*fclose(pfile);
pfile = fopen("prueba.txt","w");
if (pfile != NULL)
{
fprintf(pfile, "%d", prueba);
fclose(pfile);
}*/
}

#define MDL_UPDATE /* Change to #undef to remove function */


#if defined(MDL_UPDATE)
/* Function: mdlUpdate ======================================================
* Abstract:
*
This function is called once for every major integration time step.
*
Discrete states are typically updated here, but this function is useful
*
for performing any tasks that should only take place once per
*
integration step.
*/
static void mdlUpdate(SimStruct *S, int_T tid)
{
}
#endif /* MDL_UPDATE */

#define MDL_DERIVATIVES /* Change to #undef to remove function */


#if defined(MDL_DERIVATIVES)
/* Function: mdlDerivatives =================================================
* Abstract:
*
In this function, you compute the S-function block's derivatives.
*
The derivatives are placed in the derivative vector, ssGetdX(S).
*/
static void mdlDerivatives(SimStruct *S)
{
}
#endif /* MDL_DERIVATIVES */

/* Function: mdlTerminate =====================================================


* Abstract:
*
In this function, you should perform any actions that are necessary
*
at the termination of a simulation. For example, if memory was
*
allocated in mdlStart, this is the place to free it.
*/
static void mdlTerminate(SimStruct *S)
{
}
/*======================================================*
* See sfuntmpl_doc.c for the optional S-function methods *
*======================================================*/
/*=============================*
* Required S-function trailer *
*=============================*/
#define RT
#ifdef MATLAB_MEX_FILE
#include "simulink.c"

/* Is this file being compiled as a MEX-file? */


/* MEX-file interface mechanism */

190

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


#else
#include "cg_sfun.h"
#endif

/* Code generation registration function */

10.4.2.4 S ENDTOSERVIGAR .M
ip_address = '193.147.161.89';

%193.147.161.89 == servigar2.us.es
%172.16.1.231 == neoxite
clear nombre ok str_name pos filename file_contents descriptor caracter coords;
clear tokens new_contents x1 x2 y1 y2 nombre_mod orden s w comando fichero ans;
nombre = input('Introduzca el nombre del fichero que contiene el modelo de
Simulink:\n>>>>>
','s');
% Se comprueba el formato del nombre y si existe el fichero
ok = 0;
% Si existe un fichero mdl con ese nombre (es irrelevante si incluye extension o
% no)
if (exist(nombre) == 4)
str_name = java.lang.String(nombre);
pos = str_name.lastIndexOf('.');
if (pos > 0)
% Caso en que se especifica '.mdl'
if ((nombre(pos+2) == 'm') && (nombre(pos+3) == 'd') && (nombre(pos+4) == 'l'))
disp('Fichero de modelo de Simulink encontrado...')
str_name = str_name.substring(0, pos);
nombre = char(str_name.toString);
pos = str_name.indexOf('.');
if (pos > 0)
disp('Error: El nombre del modelo de simulink no debe contener el carcter
"."')
ok = 1;
end
% Caso en que el nombre contiene '.' pero no se trata de la extension '.mdl'
else
disp('Error: El nombre del modelo de simulink no debe contener el carcter
"."')
ok = 1;
end
else
disp('Fichero de modelo de Simulink encontrado...')
end
else
disp('Error: No se encuentra el fichero especificado')
ok = 1;
end
if (ok == 0)
% Posicionado de la ventana de modelo en la esquina superior izquierda
% Por que? Porque si se tapa parte del controlador, no se ve en la imagen
filename = java.lang.StringBuffer(nombre);
filename = filename.append('.mdl');
descriptor = java.io.FileReader(filename.toString);
file_contents = java.lang.StringBuffer('');
caracter = descriptor.read;
while (caracter ~= -1)
file_contents.append(char(caracter));
caracter = descriptor.read;
end
descriptor.close;
pos = file_contents.toString.indexOf('System {');
pos = file_contents.toString.indexOf('Location', pos + 1);
pos = file_contents.toString.indexOf('[', pos + 1);
coords = file_contents.substring(pos +

191

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


1,file_contents.toString.indexOf(']',pos+1));
tokens = java.util.StringTokenizer(coords, ',');
x1 = str2num(tokens.nextToken.toString.trim);
y1 = str2num(tokens.nextToken.toString.trim);
x2 = str2num(tokens.nextToken.toString.trim);
y2 = str2num(tokens.nextToken.toString.trim);
new_contents = java.lang.StringBuffer(file_contents.substring(0, pos + 1));
new_contents.append('0, 0, ');
new_contents.append(num2str(x2-x1));
new_contents.append(', ');
new_contents.append(num2str(y2-y1));
new_contents.append(file_contents.substring(file_contents.toString.indexOf(']',
pos + 1)));
descriptor = java.io.FileWriter(strcat(nombre,'modified.mdl'));
descriptor.write(new_contents.toString);
descriptor.close;
nombre_mod = strcat(nombre, 'modified');
% Apertura del modelo se Simulink facilitado
if (exist(nombre_mod) ~= 0)
evalin('base', nombre_mod);
else
disp('Error')
end
% Almacenado de la imagen en formato BMP
disp('Generando fichero de imagen del modelo...')
orden = java.lang.StringBuffer('print -s');
orden.append(nombre_mod);
orden.append(' -dbitmap ');
orden.append(nombre_mod);
orden = char(orden.toString);
evalin('base', orden);
bdclose(nombre_mod);
% Almacenado de la imagen en formato PNG
disp('Convirtiendo formato de imagen...')
orden = java.lang.StringBuffer('convert ');
orden = orden.append(nombre_mod);
orden.append('.bmp -transparent "#FFFFFF" ');
orden.append(nombre_mod);
orden.append('.png');
orden = char(orden.toString);
[s, w] = dos(orden);
if (s == 0)
% Caso en que no se ha producido error alguno
disp('Modelo de Simulink almacenado en fichero .png para visionado en web.')
% Copia del fichero de imagen al servidor
comando = java.lang.StringBuffer('cp_client_neoxite OVERWRITE ');
comando.append(nombre_mod);
comando.append('.png ');
comando.append(ip_address);
comando.append(' ');
comando.append(nombre);
comando.append('.png');
comando = char(comando.toString);
[s, w] = dos(comando);
if (s ~= 0)
% Caso en que se ha producido algun error
ok = 1;
disp(w)
else
% Se procede a la copia del modelo de Simulink

192

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


comando = java.lang.StringBuffer('cp_client_neoxite OVERWRITE ');
comando.append(nombre);
comando.append('.mdl ');
comando.append(ip_address);
comando.append(' ');
comando.append(nombre);
comando.append('.mdl');
comando = char(comando.toString);
[s, w] = dos(comando);
if (s ~= 0)
% Caso en que se ha producido algun error
ok = 1;
disp(w)
end
end
else
ok = 1;
disp(w)
disp('Asegurese de que el fichero "convert.exe" se encuentra en el directorio
de trabajo')
end
end
if (ok == 1)
disp('***********************************************************************')
disp('Se produjo un error en el proceso. Corrija los errores con ayuda de los')
disp('mensajes anteriores y vuelva a ejecutar el proceso.')
end
% Borrado de todos los ficheros intermedios creados en el proceso
disp('Borrando los ficheros intermedios generados...')
fichero = strcat(nombre_mod, '.mdl');
if (exist(fichero) ~= 0)
delete(fichero);
end
fichero = strcat(nombre_mod, '.bmp');
if (exist(fichero) ~= 0)
delete(fichero);
end
fichero = strcat(nombre_mod, '.png');
if (exist(fichero) ~= 0)
delete(fichero);
end
% Borrado de todas las variables intermedias creadas en el proceso
disp('Eliminando las variables intermedias generadas...')
clear nombre ok str_name pos filename file_contents descriptor caracter coords ans;
clear tokens new_contents x1 x2 y1 y2 nombre_mod orden s w comando fichero
ip_address;
disp('Listo')
disp(sprintf('\n\n'))

10.4.2.5
using
using
using
using
using

CP _CLIENT _NEOXITE

System;
System.IO;
System.Net;
System.Net.Sockets;
System.Text;

namespace cp_client_neoxite
{

193

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


/// <summary>
/// Class Cliente_Neoxite: implements a tcp/ip client for remote
///
copy/modification of files from NEOXITE computer to any other.
/// </summary>
class Cliente_Neoxite
{
/* Method Main: main method of the class Cliente_Neoxite.
* ======================================================
* Exit codes:
*
0: No error
*
1: Insufficient parameters at the command line
*
2: Socket error
*
3: File does not exist
*
4: The IP address does not have the correct format
*/
[STAThread]
static int Main(string[] args)
{
int exit_code = 0;
// Returned value
int SERVICE_PORT = 39854; // Server port for sending the data
// User calls the program with the correct number of parameters
if (args.Length == 4)
{
Socket s = null;
// Socket descriptor
IPHostEntry iphe = null;
try
{
// Format check of the IP address
IPAddress address = IPAddress.Parse(args[2]);
if(address.AddressFamily == AddressFamily.InterNetwork)
{
// Check if the IP address is valid
iphe = Dns.Resolve(args[2]);
foreach(IPAddress ipad in iphe.AddressList)
{
IPEndPoint ipe = new IPEndPoint(ipad, SERVICE_PORT);
// Open the socket
Socket tmpS =
new Socket(ipe.AddressFamily, SocketType.Stream,
ProtocolType.Tcp);
// Connect the socket
tmpS.Connect(ipe);
if(tmpS.Connected)
{
s = tmpS;
break;
}
else
continue;
}
if (s == null)
{
Console.WriteLine("Cannot connect the socket to the specified" +
" address.\n");
exit_code = 2;
}

194

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


else
{
// First of all, check the existence of the file
FileInfo userfile = new FileInfo(args[1]);
if (userfile.Exists)
{
long filelength = userfile.Length;
// Send the remote copy request
String[] tokens = args[1].Split(new Char [] {'\\'});
string filename = tokens[tokens.Length-1];
string msg = "COPY_REQUEST*" + args[0] + "*" + filename +
"*" + filelength + "*" + args[3];
s.Send(ASCIIEncoding.ASCII.GetBytes(msg));
// Receive the ack message
string data = null;
byte[] bytes = new byte[1024];
int bytesRec = s.Receive(bytes);
data += Encoding.ASCII.GetString(bytes,0,bytesRec);
Console.WriteLine(data);
// Create the reader for data.
FileStream fs_read = new FileStream(args[1], FileMode.Open,
FileAccess.Read);
BinaryReader r = new BinaryReader(fs_read);
// Read data from the specified file.
byte[] buffer = new byte[255];
do
{
buffer = r.ReadBytes(255);
s.Send(buffer);
}
while (buffer.Length != 0);
// Close the streams
r.Close();
fs_read.Close();
}
else
{
Console.WriteLine("The specified file does not exist.\n");
exit_code = 3;
}
s.Close();
}
}
else
{
Console.WriteLine("Incorrect format of the remote machine IP " +
"address.\n");
exit_code = 4;
}
}
#region Specific CATCHs
// Thrown by: FileStream (Constructor)
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine("DirectoryNotFoundException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: FileInfo (Constructor), FileStream (Constructor)
catch (System.IO.FileNotFoundException e)

195

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


{
Console.WriteLine("FileNotFoundException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: FileInfo (Constructor), FileStream (Constructor)
catch (System.UnauthorizedAccessException e)
{
Console.WriteLine("UnauthorizedAccessException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: FileInfo (Constructor), FileStream (Constructor)
catch (System.IO.PathTooLongException e)
{
Console.WriteLine("PathTooLongException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: FileInfo (Constructor)
catch (System.NotSupportedException e)
{
Console.WriteLine("NotSupportedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Console.WriteLine, FileInfo.Length, FileStream
//
(Constructor), BinaryReader.ReadBytes, FileStream.Close
catch (System.IO.IOException e)
{
Console.WriteLine("IOException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Socket.Connect, Socket.Send, Socket.Receive,
//
BinaryReader.ReadBytes
catch(System.ObjectDisposedException e)
{
Console.WriteLine("ObjectDisposedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPEndPoint (Constructor), Encoding.GetString,
//
FileStream (Constructor), BinaryReader.ReadBytes
catch(System.ArgumentOutOfRangeException e)
{
Console.WriteLine("ArgumentOufOfRangeException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPAddress.Parse
catch(System.FormatException e)
{
Console.WriteLine("FormatException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPAddress.Parse, DNS.Resolve, Socket.Connect,
//
FileInfo (Constructor), Socket.Send, Encoding.GetBytes,
//
Socket.Receive, Encoding.GetString, FileStream (Constructor)
catch(System.ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);

196

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
// Thrown by: DNS.Resolve, Socket (Constructor), Socket.Connect,
//
Socket.Send, Socket.Receive
catch(System.Net.Sockets.SocketException e)
{
Console.WriteLine("SocketException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
exit_code = 2;
}
// Thrown by: DNS.Resolve, Socket.Connect, FileInfo (Constructor),
//
Socket.Receive, FileStream (Constructor)
catch(System.Security.SecurityException e)
{
Console.WriteLine("SecurityException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
exit_code = 2;
}
// Thrown by: FileInfo (Constructor), FileStream (Constructor),
//
BinaryReader (Constructor)
catch (System.ArgumentException e)
{
Console.WriteLine("ArgumentException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
#endregion
// Thrown by: any
catch(Exception e)
{
Console.WriteLine("Exception caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
}
// Show how call the program
else
{
Console.WriteLine("Syntax:\n" +
"\tcp_client_neoxite COPY_MODE local_filename remote_ip_address " +
"remote_filename\n\nCOPY_MODE:\n" +
"\tCREATE: Create the file only if it does not exist.\n" +
"\tOVERWRITE: Create the file in any case.\n" +
"local_filename: name of the file at the local side (client side). " +
"Ex:\n\tc:\\mydir\\myfile.ext (full path)\n" +
"\tmyfile.ext (only the filename, local path)\n" +
"remote_ip_address: IP address of the remote machine. Ex:\n" +
"\t127.0.0.1 (local copy)\n" +
"\t165.35.2.98 (remote copy)\n" +
"remote_filename: name of the file at the remote side (server " +
"side). Ex:\n\t\\..\\..\\myfile2.ext (copy the file two levels " +
"up from the server dir\n" +
"\tmyfile2.ext (copy the file in the dir in which the server is\n");
exit_code = 1;
}
return exit_code;
}
}
}

197

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET

10.4.2.6
using
using
using
using
using
using

CP _SERVER _NEOXITE

System;
System.IO;
System.Net;
System.Net.Sockets;
System.Text;
System.Threading;

namespace cp_server_neoxite
{
/// <summary>
/// Class Servidor_Neoxite: This class implements a server which can copy remote
///
files and modify files with remote parameters
/// </summary>
class Servidor_Neoxite
{
/// <summary>
/// The main entry point for the application.
/// The server receive first a message containing the operation it has to do:
///
*) COPY_REQUEST: remote copy of a file, transfer over IP and create
///
new
///
*) MOD_REQUEST: remote modification of a file on the server, do not
///
create a new file
///
*) ABORT: self message for exiting the program and stop listening
/// The server has two threads: the main thread listen at a specific port for
/// incoming requests, and the secondary thread is only for terminating
/// purposes (it reads the command line and when user enters "exit" it
/// finishes the program.
/// </summary>
[STAThread]
static void Main(string[] args)
{
string server_address = "servigar2.us.es"; // NEOXITE: 172.16.1.231
int server_port = 32000;
try
{
// Welcome message
Console.WriteLine("Server running at
NEOXITE:\n===========================");
// Just after that message, we start the secondary thread for aborting
Reader lector = new Reader();
Thread hilo_lector = new Thread(new ThreadStart(lector.KeyboardRead));
hilo_lector.Start();
// Allowed IPs for requesting
string[] allowed_ips = {"193.147.161.89", "193.147.160.155",
"172.16.1.4", "127.0.0.1", "172.16.1.231"};
bool salir = false;
// Flag for exiting the main loop
string data = null;
// Incoming data from the client.
byte[] bytes = new Byte[1024];
// Data buffer for incoming data.
// Create the local endpoint
IPHostEntry ipHostInfo = Dns.Resolve(server_address);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, server_port);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Bind the socket to the local endpoint and listen for incoming
// connections.

198

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (salir == false)
{
Console.WriteLine("\n\nWaiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
data = null;
// Filtering remote IP
string remoteIP =
((IPEndPoint)handler.RemoteEndPoint).Address.ToString();
Console.WriteLine("Incoming request from " + remoteIP);
bool allowed = false;
foreach (string ip in allowed_ips)
{
if (ip.CompareTo(remoteIP) == 0)
{
Console.WriteLine("Allowed IP => Processing request");
allowed = true;
break;
}
}
// If it is an allowed ip address (white list), go on...
if (allowed)
{
// Receiving the request message
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes,0,bytesRec);
// What does the user want to do?
String[] tokens = data.Split(new Char [] {'*'});
data = null;
FileStream fs_write = null;
BinaryWriter w = null;
long size = 0;
switch (tokens[0])
{
case "COPY_REQUEST":
#region COPY REQUEST: remote copy of a file
// Check the existence of the file to create.
// If it does not exist, create the new, empty data file.
string ack_msg = null;
int flag = 0;
if (File.Exists(tokens[4]))
{
if (tokens[1].CompareTo("CREATE") == 0)
{
flag = 1;
ack_msg = "DENIED*Destiny file already exists. " +
"Remote copy denied.\n";
Console.WriteLine("Destiny file already exists. " +
"Remote copy denied.\n");
}
else if (tokens[1].CompareTo("OVERWRITE") == 0)
{
flag = 2;
ack_msg = "PROCEED";

199

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
}
else
{
flag = 3;
ack_msg = "PROCEED";
}
// Sending the ack message
handler.Send(ASCIIEncoding.ASCII.GetBytes(ack_msg));
// If the ack_msg is PROCEED, go on with the writing
if (flag > 1)
{
Console.WriteLine("Received COPY request. " +
"Waiting for the data...");
// Create the writer for data.
// File will be overwrited
if (flag == 2)
fs_write = new FileStream(tokens[4], FileMode.Create);
// File does not exist
else if (flag == 3)
fs_write = new FileStream(tokens[4], FileMode.CreateNew);
else
Console.WriteLine("Internal error.\n");
w = new BinaryWriter(fs_write);
// Receiving the data (file)
size = 0;
Console.WriteLine("Starting receiving data...");
while (true)
{
bytes = new byte[1024];
bytesRec = handler.Receive(bytes);
size += bytesRec;
w.Write(bytes, 0, bytesRec);
if (size == Convert.ToInt64(tokens[3]))
break;
}
Console.WriteLine("File \"" + tokens[4] + "\" has " +
"been overwrited");
fs_write.Close();
w.Close();
}
break;
#endregion
case "MOD_REQUEST":
#region MODIFY REQUEST: remote modification of a file
Console.WriteLine("Received MODIFY request. " +
"Waiting for the data...");
// Sending the ack message
ack_msg = "PROCEED";
handler.Send(ASCIIEncoding.ASCII.GetBytes(ack_msg));
// Receiving the data to be added to the file
size = 0;
string text_modif = "";
Console.WriteLine("Starting receiving data...");
while (text_modif.Length != Convert.ToInt64(tokens[3]))
{
bytes = new byte[1024];

200

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


bytesRec = handler.Receive(bytes);
text_modif += Encoding.ASCII.GetString(bytes,0,bytesRec);
}
using (StreamWriter sw = new StreamWriter(tokens[4]))
{
sw.Write(text_modif);
}
break;
Console.WriteLine("File \"" + tokens[4] + "\" has " +
"been modified");
#endregion
case "ABORT":
salir = true;
break;
default:
Console.WriteLine("Request of the user is not allowed.\n");
break;
}
}
}
}
# region Specific CATCHS
// Thrown by: Thread (Constructor), Dns.Resolve, Socket.Bind,
//
Socket.Receive, ASCIIEncoding.GetString, Socket.Send,
//
Directory.GetFiles, File.Delete, FileStream (Constructor),
//
BinaryWriter (Constructor), BinaryWriter.Write,
//
String.IndexOf, File.CreateText, StreamWriter (Constructor)
catch (System.ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start
catch (System.Threading.ThreadStateException e)
{
Console.WriteLine("ThreadStateException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start, Dns.Resolve, Socket.Bind, Socket.Receive,
//
FileStream (Constructor), StreamWriter (Constructor)
catch (System.Security.SecurityException e)
{
Console.WriteLine("SecurityException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start
catch (System.OutOfMemoryException e)
{
Console.WriteLine("OutOfMemoryException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Thread.Start
catch (System.NullReferenceException e)
{
Console.WriteLine("NullReferenceException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Dns.Resolve, Socket (Constructor), Socket.Bind, Socket.Listen,

201

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


//
Socket.Accept, Socket.RemoteEndPoint, Socket.Receive, Socket.Send
catch (System.Net.Sockets.SocketException e)
{
Console.WriteLine("SocketException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPEndPoint (Constructor), ASCIIEncoding.GetString,
//
FileStream (Constructor), BinaryWriter.Write, String.IndexOf,
//
String.Substring
catch (System.ArgumentOutOfRangeException e)
{
Console.WriteLine("ArgumentOutOfRangeException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Socket.Bind, Socket.Listen, Socket.Accept,
//
Socket.RemoteEndPoint, Socket.Receive, Socket.Send,
//
BinaryWriter.Write, StreamWriter.WriteLine,
//
StreamWriter.Write
catch (System.ObjectDisposedException e)
{
Console.WriteLine("ObjectDisposedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Socket.Accept
catch (System.InvalidOperationException e)
{
Console.WriteLine("InvalidOperationException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, File.CreateText,
//
StreamWriter (Constructor)
catch (System.UnauthorizedAccessException e)
{
Console.WriteLine("UnauthorizedAccessException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, FileStream (Constructor),
//
BinaryWriter (Constructor), BinaryWriter.Write, Convert.ToInt64,
//
File.CreateText, StreamWriter (Constructor)
catch (System.ArgumentException e)
{
Console.WriteLine("ArgumentException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, FileStream (Constructor),
//
File.CreateText, StreamWriter (Constructor)
catch (System.IO.PathTooLongException e)
{
Console.WriteLine("PathTooLongException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Directory.GetFiles, File.Delete, FileStream (Constructor),
//
File.CreateText, StreamWriter (Constructor)
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine("DirectoryNotFoundException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);

202

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


}
// Thrown by: File.Delete, File.CreateText, StreamWriter.Write
catch (System.NotSupportedException e)
{
Console.WriteLine("NotSupportedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: FileStream (Constructor)
catch (System.IO.FileNotFoundException e)
{
Console.WriteLine("FileNotFoundException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Console.WriteLine, File.Delete, FileStream (Constructor),
//
BinaryWriter.Write, StreamWriter.WriteLine, StreamWriter
//
(Constructor), StreamWriter.Write
catch (System.IO.IOException e)
{
Console.WriteLine("IOException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Convert.ToInt64
catch (System.FormatException e)
{
Console.WriteLine("FormatException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Convert.ToInt64
catch (System.OverflowException e)
{
Console.WriteLine("OverflowException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
#endregion
// Thrown by: any
catch (Exception e)
{
Console.WriteLine("Exception caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
}
/// <summary>
/// Class Reader: this class implements a keyboard reader for exiting the
///
executable program. When user writes a line, it reads the command
///
line and if the sentence is "exit", the class sends a message to the
///
listening port on this machine to exit the socket loop of the class
///
Servidor_Servigar
/// </summary>
internal class Reader
{
public void KeyboardRead()
{
int server_port = 32000;
// Server port for sending the data
string server_address = "193.147.161.89";
// Servigar2.us.es IP address

203

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


string opt = null;
Socket s = null;
bool salir = false;
IPHostEntry iphe = null;

// Line entered
// Socket descriptor
// Flag for exiting the loop

while (salir == false)


{
try
{
Console.Write("(You can type \"exit\" at any moment to exit " +
"the program)\n");
opt = Console.ReadLine();
// If the user writes "exit", proceed with the termination process
if (opt.ToLower() == "exit")
{
// Format check of the IP address
IPAddress address = IPAddress.Parse(server_address);
if(address.AddressFamily == AddressFamily.InterNetwork)
{
// Check if the IP address is valid
iphe = Dns.Resolve(server_address);
foreach(IPAddress ipad in iphe.AddressList)
{
IPEndPoint ipe = new IPEndPoint(ipad, server_port);
// Open the socket
Socket tmpS =
new Socket(ipe.AddressFamily, SocketType.Stream,
ProtocolType.Tcp);
// Connect the socket
tmpS.Connect(ipe);
if(tmpS.Connected)
{
s = tmpS;
break;
}
else
continue;
}
if (s == null)
{
Console.WriteLine("Cannot connect the socket to the " +
"specified address.\n");
}
else
{
string msg = "ABORT";
s.Send(ASCIIEncoding.ASCII.GetBytes(msg));
salir = true;
}
}
}
}
#region Specific CATCHs
// Thrown by: Console.ReadLine, Console.WriteLine
catch(System.IO.IOException e)
{
Console.WriteLine("IOException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}

204

SISTEMA DE GESTIN DOCUMENTAL A TRAVS DE INTERNET


// Thrown by: Console.ReadLine
catch(System.OutOfMemoryException e)
{
Console.WriteLine("OutOfMemoryException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPAddress.Parse, Dns.Resolve, Socket.Connect,
//
ASCIIEncoding.GetBytes, Socket.Send
catch(System.ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPAddress.Parse
catch(System.FormatException e)
{
Console.WriteLine("FormatException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Dns.Resolve, Socket (Constructor), Socket.Connect,
//
Socket.Send
catch(System.Net.Sockets.SocketException e)
{
Console.WriteLine("SocketException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Dns.Resolve, Socket.Connect
catch(System.Security.SecurityException e)
{
Console.WriteLine("SecurityException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: IPEndPoint (Constructor)
catch(System.ArgumentOutOfRangeException e)
{
Console.WriteLine("ArgumentOutOfRangeException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
// Thrown by: Socket.Connect, Socket.Send
catch(System.ObjectDisposedException e)
{
Console.WriteLine("ObjectDisposedException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
#endregion
// Thrown by: any
catch(Exception e)
{
Console.WriteLine("Exception caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
}
}
}
}

205